diff --git a/GUIs/DQ_Spectra_GUI.fig b/GUIs/DQ_Spectra_GUI.fig old mode 100644 new mode 100755 diff --git a/GUIs/DQ_Spectra_GUI.m b/GUIs/DQ_Spectra_GUI.m old mode 100644 new mode 100755 diff --git a/GUIs/DQ_Table_GUI.fig b/GUIs/DQ_Table_GUI.fig old mode 100644 new mode 100755 diff --git a/GUIs/DQ_Table_GUI.m b/GUIs/DQ_Table_GUI.m old mode 100644 new mode 100755 diff --git a/GUIs/DQ_preavg.fig b/GUIs/DQ_preavg.fig old mode 100644 new mode 100755 diff --git a/GUIs/DQ_preavg.m b/GUIs/DQ_preavg.m old mode 100644 new mode 100755 diff --git a/GUIs/averagerGUI.fig b/GUIs/averagerGUI.fig old mode 100644 new mode 100755 diff --git a/GUIs/averagerGUI.m b/GUIs/averagerGUI.m old mode 100644 new mode 100755 diff --git a/GUIs/averagerxGUI.fig b/GUIs/averagerxGUI.fig old mode 100644 new mode 100755 diff --git a/GUIs/averagerxGUI.m b/GUIs/averagerxGUI.m old mode 100644 new mode 100755 diff --git a/GUIs/avg_data_quality.fig b/GUIs/avg_data_quality.fig old mode 100644 new mode 100755 diff --git a/GUIs/avg_data_quality.m b/GUIs/avg_data_quality.m old mode 100644 new mode 100755 diff --git a/GUIs/binoperGUI.fig b/GUIs/binoperGUI.fig index 445a7099..ce824d86 100755 Binary files a/GUIs/binoperGUI.fig and b/GUIs/binoperGUI.fig differ diff --git a/GUIs/binoperGUI.m b/GUIs/binoperGUI.m index dc380b4d..56b3c7b7 100755 --- a/GUIs/binoperGUI.m +++ b/GUIs/binoperGUI.m @@ -96,19 +96,19 @@ function varargout = binoperGUI(varargin) gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... - 'gui_Singleton', gui_Singleton, ... - 'gui_OpeningFcn', @binoperGUI_OpeningFcn, ... - 'gui_OutputFcn', @binoperGUI_OutputFcn, ... - 'gui_LayoutFcn', [] , ... - 'gui_Callback', []); + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @binoperGUI_OpeningFcn, ... + 'gui_OutputFcn', @binoperGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); if nargin && ischar(varargin{1}) - gui_State.gui_Callback = str2func(varargin{1}); + gui_State.gui_Callback = str2func(varargin{1}); end if nargout - [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else - gui_mainfcn(gui_State, varargin{:}); + gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT @@ -117,30 +117,30 @@ function binoperGUI_OpeningFcn(hObject, eventdata, handles, varargin) % Choose default command line output for binoperGUI handles.output = []; try - ERP = varargin{1}; - % - % Prepare List of current Bins - % - listb = []; - nbinmax = ERP.nbin; - for b=1:nbinmax - listb{b} = ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; - end - chanlocs = ERP.chanlocs; - bindescr = ERP.bindescr; + ERP = varargin{1}; + % + % Prepare List of current Bins + % + listb = []; + nbinmax = ERP.nbin; + for b=1:nbinmax + listb{b} = ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; + end + chanlocs = ERP.chanlocs; + bindescr = ERP.bindescr; catch - ERP = []; - listb = ''; - nbinmax = 1; - chanlocs = []; + ERP = []; + listb = ''; + nbinmax = 1; + chanlocs = []; end try - def = varargin{2}; - formulas = def{1}; - wbmsgon = def{2}; + def = varargin{2}; + formulas = def{1}; + wbmsgon = def{2}; catch - formulas = []; - wbmsgon = 1; + formulas = []; + wbmsgon = 1; end example{1} = 'b$ = (b1+b3)/2 label attended left'; @@ -156,14 +156,42 @@ function binoperGUI_OpeningFcn(hObject, eventdata, handles, varargin) handles.example = example; handles.exacounter = 0; handles.listname = []; -handles.chanlocs = chanlocs; -handles.bindescr = bindescr; +handles.chanlocs = chanlocs; +handles.bindescr = bindescr; % % Name & version % -version = geterplabversion; -set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - Bin Operation GUI']) +% version = geterplabversion; +% set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - Bin Operation GUI']) + +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + else + Toolabel = 0; + end +else + Toolabel = 1; +end + +if Toolabel + erplab_studio_default_values; + version = erplabstudiover; + set(handles.gui_chassis,'Name', ['EStudio',version,' - Bin Operation > Advanced GUI for ']) + handles = painterplabstudio(handles); + handles = setfonterplabestudio(handles); + handles.RUN.String = 'OK'; +else + + version = geterplabversion; + set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - Bin Operation GUI ']) + % + handles = painterplab(handles); + + handles = setfonterplab(handles); +end %formulas = erpworkingmemory('binformulas'); @@ -178,66 +206,66 @@ function binoperGUI_OpeningFcn(hObject, eventdata, handles, varargin) binopGUI = erpworkingmemory('binopGUI'); if isempty(binopGUI) - set(handles.button_recursive,'Value', 1); % default is Modify existing ERPset (recursive updating) - set(handles.button_savelist, 'Enable','off') - - % - % File List - % - set(handles.edit_filelist,'String',''); - set(handles.checkbox_sendfile2history,'Value',0) + set(handles.button_recursive,'Value', 1); % default is Modify existing ERPset (recursive updating) + set(handles.button_savelist, 'Enable','off') + + % + % File List + % + set(handles.edit_filelist,'String',''); + set(handles.checkbox_sendfile2history,'Value',0) else - if binopGUI.emode==0 - set(handles.button_recursive,'Value', 1); - set(handles.button_no_recu,'Value', 0); - else - set(handles.button_recursive,'Value', 0); - set(handles.button_no_recu,'Value', 1); - end - if binopGUI.hmode==0 - set(handles.checkbox_sendfile2history,'Value', 0); - else - set(handles.checkbox_sendfile2history,'Value', 1); - end - set(handles.edit_filelist,'String', binopGUI.listname ); + if binopGUI.emode==0 + set(handles.button_recursive,'Value', 1); + set(handles.button_no_recu,'Value', 0); + else + set(handles.button_recursive,'Value', 0); + set(handles.button_no_recu,'Value', 1); + end + if binopGUI.hmode==0 + set(handles.checkbox_sendfile2history,'Value', 0); + else + set(handles.checkbox_sendfile2history,'Value', 1); + end + set(handles.edit_filelist,'String', binopGUI.listname ); end if isempty(formulas) - set(handles.editor,'String',''); + set(handles.editor,'String',''); else - if iscell(formulas) - set(handles.editor, 'String', formulas) - else - try - fid_formula = fopen( formulas ); - - formcell = textscan(fid_formula, '%s','delimiter', '\r'); - formulas = char(formcell{:}); - compacteditor(hObject, eventdata, handles); - set(handles.editor,'String',formulas); - fclose(fid_formula); - set(handles.button_savelist, 'Enable','on') - catch - end + if iscell(formulas) + set(handles.editor, 'String', formulas) + else + try + fid_formula = fopen( formulas ); + + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); + compacteditor(hObject, eventdata, handles); + set(handles.editor,'String',formulas); + fclose(fid_formula); + set(handles.button_savelist, 'Enable','on') + catch end + end end %wbmsgon = erpworkingmemory('wbmsgon'); if isempty(wbmsgon) || wbmsgon==0 - set(handles.bwarning,'Value', 0) + set(handles.bwarning,'Value', 0) elseif wbmsgon==1 - set(handles.bwarning,'Value', 1) + set(handles.bwarning,'Value', 1) else - set(handles.bwarning,'Value', 1) + set(handles.bwarning,'Value', 1) end % % Color GUI % -handles = painterplab(handles); +% handles = painterplab(handles); % % Set font size % -handles = setfonterplab(handles); +% handles = setfonterplab(handles); % Update handles structure guidata(hObject, handles); @@ -270,7 +298,7 @@ function editor_Callback(hObject, eventdata, handles) %-------------------------------------------------------------------------- function editor_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) - set(hObject,'BackgroundColor','white'); + set(hObject,'BackgroundColor','white'); end %-------------------------------------------------------------------------- @@ -287,60 +315,60 @@ function RUN_Callback(hObject, eventdata, handles) wbmsgon = get(handles.bwarning,'Value'); if strcmp(formulalist,'') - msgboxText = 'You have not yet written a formula!'; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(msgboxText, title); - return + msgboxText = 'You have not yet written a formula!'; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(msgboxText, title); + return end if size(formulalist,2)>256 - msgboxText = ['Formulas length exceed 256 characters.\n'... - 'Be sure to press [Enter] after you have entered each formula.']; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(sprintf(msgboxText), title); - return + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return end % % Check formulas % if get(handles.button_recursive,'Value') - editormode = 0; + editormode = 0; else - editormode = 1; + editormode = 1; end [option, recall, goeson] = checkformulas(cellstr(formulalist), 'binoperGUI', editormode); if goeson==0 - return + return end if isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1 - BackERPLABcolor = [ 1 1 0]; - question = ['Equations at editor window have not been saved yet.\n'... - 'What would you like to do?']; - title = 'WARNING: Save List of edited bins'; - oldcolor = get(0,'DefaultUicontrolBackgroundColor'); - set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) - button = questdlg(sprintf(question), title,'Save and run','Run without saving', 'Cancel','Run without saving'); - set(0,'DefaultUicontrolBackgroundColor',oldcolor) - - if strcmpi(button,'Save and run') - fullname = savelist(hObject, eventdata, handles); - listname = fullname; - handles.output = {listname, wbmsgon}; % sent filenam string) - elseif strcmpi(button,'Run without saving') - handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) - elseif strcmpi(button,'Cancel') || strcmpi(button,'') - handles.output = []; - handles.listname = []; - % Update handles structure - guidata(hObject, handles); - return - end -elseif isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 + BackERPLABcolor = [ 1 1 0]; + question = ['Equations at editor window have not been saved yet.\n'... + 'What would you like to do?']; + title = 'WARNING: Save List of edited bins'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Save and run','Run without saving', 'Cancel','Run without saving'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Save and run') + fullname = savelist(hObject, eventdata, handles); + listname = fullname; + handles.output = {listname, wbmsgon}; % sent filenam string) + elseif strcmpi(button,'Run without saving') handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) + elseif strcmpi(button,'Cancel') || strcmpi(button,'') + handles.output = []; + handles.listname = []; + % Update handles structure + guidata(hObject, handles); + return + end +elseif isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 + handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1 - handles.output = {listname, wbmsgon}; % sent filename string + handles.output = {listname, wbmsgon}; % sent filename string elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 - handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) + handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) end % erpworkingmemory('binformulas', formulalist); @@ -386,29 +414,29 @@ function button_saveaslist_Callback(hObject, eventdata, handles) fulltext = strtrim(get(handles.editor,'String')); if size(fulltext,2)>256 - msgboxText = ['Formulas length exceed 256 characters.\n'... - 'Be sure to press [Enter] after you have entered each formula.']; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(sprintf(msgboxText), title); - return + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return end if ~strcmp(fulltext,'') - fullname = savelist(hObject, eventdata, handles); - if isempty(fullname) - return - end - set(handles.edit_filelist, 'String', fullname ) - set(handles.button_savelist, 'Enable', 'on') - handles.listname = fullname; - % Update handles structure - guidata(hObject, handles); -else - set(handles.button_saveaslist,'Enable','off') - msgboxText = 'You have not yet written a formula!'; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(msgboxText, title); - set(handles.button_saveaslist,'Enable','on') + fullname = savelist(hObject, eventdata, handles); + if isempty(fullname) return + end + set(handles.edit_filelist, 'String', fullname ) + set(handles.button_savelist, 'Enable', 'on') + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); +else + set(handles.button_saveaslist,'Enable','off') + msgboxText = 'You have not yet written a formula!'; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_saveaslist,'Enable','on') + return end %-------------------------------------------------------------------------- @@ -416,32 +444,32 @@ function button_loadlist_Callback(hObject, eventdata, handles) [filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file'); if isequal(filename,0) - disp('User selected Cancel') - return + disp('User selected Cancel') + return else - fullname = fullfile(filepath, filename); - disp(['pop_binoperation(): For formulas-file, user selected ', fullname]) + fullname = fullfile(filepath, filename); + disp(['pop_binoperation(): For formulas-file, user selected ', fullname]) end set(handles.edit_filelist,'String',fullname); fid_formula = fopen( fullname ); try - formcell = textscan(fid_formula, '%s','delimiter', '\r'); - formulas = char(formcell{:}); + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); catch - serr = lasterror; - msgboxText = ['Please, check your file:\n '... - fullname '\n'... - serr.message]; - title = 'ERPLAB: pop_binoperation() error:'; - errorfound(sprintf(msgboxText), title); - return + serr = lasterror; + msgboxText = ['Please, check your file:\n '... + fullname '\n'... + serr.message]; + title = 'ERPLAB: pop_binoperation() error:'; + errorfound(sprintf(msgboxText), title); + return end if size(formulas,2)>256 - msgboxText = ['Formulas length exceed 256 characters.\n'... - 'Be sure to press [Enter] after you have entered each formula.']; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(sprintf(msgboxText), title); - return + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return end compacteditor(hObject, eventdata, handles); @@ -458,11 +486,11 @@ function listbox_bin_Callback(hObject, eventdata, handles) numbin = get(hObject, 'Value'); if isempty(numbin) - return + return end linet = get(handles.editor, 'Value'); if linet == 0 - linet = 1; + linet = 1; end formulas = cellstr(get(handles.editor, 'String')); formulas{linet} = [formulas{linet} 'b' num2str(numbin)]; @@ -471,7 +499,7 @@ function listbox_bin_Callback(hObject, eventdata, handles) %-------------------------------------------------------------------------- function listbox_bin_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) - set(hObject,'BackgroundColor','white'); + set(hObject,'BackgroundColor','white'); end %-------------------------------------------------------------------------- @@ -482,22 +510,22 @@ function button_example_Callback(hObject, eventdata, handles) exacounter = exacounter + 1; if get(handles.button_no_recu,'Value') - prechar = 'n'; + prechar = 'n'; else - prechar = ''; + prechar = ''; end text = cellstr(get(handles.editor, 'String')); if isempty([text{:}]) || exacounter>length(example) - exacounter = 1; + exacounter = 1; end if length(text)==1 && strcmp(text{1}, '') - exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter))); - text{1} = [prechar exacurr]; + exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter))); + text{1} = [prechar exacurr]; else - exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter))); - text{end+1} = [prechar exacurr]; + exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter))); + text{end+1} = [prechar exacurr]; end set(handles.editor, 'String', char(text)); @@ -509,7 +537,7 @@ function button_example_Callback(hObject, eventdata, handles) function fullname = savelist(hObject, eventdata, handles) fulltext = char(get(handles.editor,'String')); if isempty(fulltext) - return + return end fullnamepre = get(handles.edit_filelist,'String'); @@ -519,38 +547,38 @@ function button_example_Callback(hObject, eventdata, handles) [filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save formulas-file as', fullnamepre); if isequal(filename,0) - disp('User selected Cancel') - fullname = []; - return + disp('User selected Cancel') + fullname = []; + return else - [px, fname, ext] = fileparts(filename); + [px, fname, ext] = fileparts(filename); + + if strcmp(ext,'') - if strcmp(ext,'') - - if filterindex==1 || filterindex==3 - ext = '.txt'; - else - ext = '.dat'; - end - end - - fname = [ fname ext]; - fullname = fullfile(filepath, fname); - fid_list = fopen( fullname , 'w'); - - for i=1:size(fulltext,1) - fprintf(fid_list,'%s\n', fulltext(i,:)); + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; end - - fclose(fid_list); - set(handles.button_savelist, 'Enable','on') + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); + set(handles.button_savelist, 'Enable','on') end %-------------------------------------------------------------------------- function compacteditor(hObject, eventdata, handles) texteditor = strtrim(get(handles.editor,'String')); if isempty(texteditor) - return + return end formul = cellstr(texteditor); @@ -559,10 +587,10 @@ function compacteditor(hObject, eventdata, handles) formulalist = cell(1); for i=1:nfl - if ~strcmp(formul{i},'') - formulalist{k} = formul{i}; - k = k+1; - end + if ~strcmp(formul{i},'') + formulalist{k} = formul{i}; + k = k+1; + end end formulalist = strtrimx(formulalist); @@ -573,38 +601,38 @@ function button_savelist_Callback(hObject, eventdata, handles) compacteditor(hObject, eventdata, handles); fulltext = strtrim(get(handles.editor,'String')); if size(fulltext,2)>256 - msgboxText = ['Formulas length exceed 256 characters.\n'... - 'Be sure to press [Enter] after you have entered each formula.']; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(sprintf(msgboxText), title); - return + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return end if ~strcmp(fulltext,'') - fullname = get(handles.edit_filelist, 'String'); - if ~strcmp(fullname,'') - - fid_list = fopen( fullname , 'w'); - - for i=1:size(fulltext,1) - fprintf(fid_list,'%s\n', fulltext(i,:)); - end - - fclose(fid_list); - handles.listname = fullname; - % Update handles structure - guidata(hObject, handles); - disp(['Saving equation list at ' fullname '']) - else - button_saveaslist_Callback(hObject, eventdata, handles) - return + fullname = get(handles.edit_filelist, 'String'); + if ~strcmp(fullname,'') + + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); end -else - set(handles.button_saveaslist,'Enable','off') - msgboxText = 'You have not yet written a formula!'; - title = 'ERPLAB: binoperGUI few inputs'; - errorfound(msgboxText, title); - set(handles.button_saveaslist,'Enable','on') + + fclose(fid_list); + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); + disp(['Saving equation list at ' fullname '']) + else + button_saveaslist_Callback(hObject, eventdata, handles) return + end +else + set(handles.button_saveaslist,'Enable','off') + msgboxText = 'You have not yet written a formula!'; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_saveaslist,'Enable','on') + return end %-------------------------------------------------------------------------- @@ -616,7 +644,7 @@ function edit_filelist_Callback(hObject, eventdata, handles) %-------------------------------------------------------------------------- function edit_filelist_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) - set(hObject,'BackgroundColor','white'); + set(hObject,'BackgroundColor','white'); end %-------------------------------------------------------------------------- @@ -627,19 +655,19 @@ function button_clearfile_Callback(hObject, eventdata, handles) %-------------------------------------------------------------------------- function button_recursive_Callback(hObject, eventdata, handles) if get(hObject,'Value') - set(handles.button_no_recu,'Value',0) - val = testsyntaxtype(hObject, eventdata, handles, 'recu'); - - if val==0; - set(handles.button_recursive, 'Value', 0) - set(handles.button_no_recu, 'Value', 1) - end - - %%% handles = editorbackup(hObject, eventdata, handles); - %%% Update handles structure - %%guidata(hObject, handles); + set(handles.button_no_recu,'Value',0) + val = testsyntaxtype(hObject, eventdata, handles, 'recu'); + + if val==0; + set(handles.button_recursive, 'Value', 0) + set(handles.button_no_recu, 'Value', 1) + end + + %%% handles = editorbackup(hObject, eventdata, handles); + %%% Update handles structure + %%guidata(hObject, handles); else - set(hObject,'Value',1) + set(hObject,'Value',1) end % % % if get(hObject,'Value')==0 @@ -651,17 +679,17 @@ function button_recursive_Callback(hObject, eventdata, handles) %-------------------------------------------------------------------------- function button_no_recu_Callback(hObject, eventdata, handles) if get(hObject,'Value') - set(handles.button_recursive,'Value',0) - val = testsyntaxtype(hObject, eventdata, handles, 'norecu'); - if val==0 - set(handles.button_recursive, 'Value', 1) - set(handles.button_no_recu, 'Value', 0) - end - %%% handles = editorbackup(hObject, eventdata, handles); - %%% Update handles structure - %%%guidata(hObject, handles); + set(handles.button_recursive,'Value',0) + val = testsyntaxtype(hObject, eventdata, handles, 'norecu'); + if val==0 + set(handles.button_recursive, 'Value', 1) + set(handles.button_no_recu, 'Value', 0) + end + %%% handles = editorbackup(hObject, eventdata, handles); + %%% Update handles structure + %%%guidata(hObject, handles); else - set(hObject,'Value',1) + set(hObject,'Value',1) end % % % if get(hObject,'Value')==0 @@ -676,9 +704,9 @@ function button_no_recu_Callback(hObject, eventdata, handles) formulaArray = get(handles.editor,'String'); if isempty(formulaArray) - return + return else - formulaArray = strtrim(cellstr(formulaArray)); + formulaArray = strtrim(cellstr(formulaArray)); end nformulas = length(formulaArray); [expspliter parts] = regexp(formulaArray, '=','match','split'); @@ -686,82 +714,82 @@ function button_no_recu_Callback(hObject, eventdata, handles) wantfix = 0; newnumbin = 1; -for t=1:nformulas - fcomm = formulaArray{t}; - tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013) +for t=1:nformulas + fcomm = formulaArray{t}; + tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013) + + if isempty(tokcommentb) % skip comment symbol + pleft = regexpi(parts{t}{1}, '(\s*nb[in]*\d+)', 'tokens'); + plcom = regexpi(parts{t}{1}, '(\s*b[in]*\d+)', 'tokens'); - if isempty(tokcommentb) % skip comment symbol - pleft = regexpi(parts{t}{1}, '(\s*nb[in]*\d+)', 'tokens'); - plcom = regexpi(parts{t}{1}, '(\s*b[in]*\d+)', 'tokens'); + if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For non recursive mode, left side of equation\nmust be define as a new bin.\n'... + 'For instance, nbin1 = ...\n\n'... + 'Do you want that ERPLAB corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for non recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) - if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu') - if ask4fix - BackERPLABcolor = [1 0.9 0.3]; % yellow - question = ['For non recursive mode, left side of equation\nmust be define as a new bin.\n'... - 'For instance, nbin1 = ...\n\n'... - 'Do you want that ERPLAB corrects the syntax for you?']; - title = 'WARNING: Syntax is not proper for non recursive mode'; - oldcolor = get(0,'DefaultUicontrolBackgroundColor'); - set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) - button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); - set(0,'DefaultUicontrolBackgroundColor',oldcolor) - - if strcmpi(button,'Yes') - ask4fix = 0; - wantfix = 1; - elseif strcmpi(button,'Cancel') - val = 0; % cancel - break - else - ask4fix = 0; - wantfix = 0; - end - %else - % wantfix =1; - end - elseif ~isempty(pleft) && strcmpi(whocall,'recu') - if ask4fix - BackERPLABcolor = [1 0.9 0.3]; % yellow - question = ['For recursive mode, left side of equation cannot\nbe define as a new bin.\n'... - 'For instance, you must write bin1 = ...\n\n'... - 'Do you want that ERPLAB corrects the syntax for you?']; - title = 'WARNING: Syntax is not proper for recursive mode'; - oldcolor = get(0,'DefaultUicontrolBackgroundColor'); - set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) - button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); - set(0,'DefaultUicontrolBackgroundColor',oldcolor) - - if strcmpi(button,'Yes') - ask4fix = 0; - wantfix =1; - elseif strcmpi(button,'Cancel') - val = 0; % cancel - break - else - ask4fix = 0; - wantfix = 0; - end - %else - % wantfix =1; - end - %else - % wantfix = 0; - + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix = 1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; end - if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC - fprintf('WARNING: equation %s ', formulaArray{t}) - if strcmpi(whocall,'recu') % for recursive mode delete the n in nch - formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2})); - else - formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*b(\D*)(\d*)',['nb$1' num2str(newnumbin)],'ignorecase')), strtrim(parts{t}{2})); - newnumbin = newnumbin+1; - end - fprintf('was changed to equation %s \n', formulaArray{t}) + %else + % wantfix =1; + end + elseif ~isempty(pleft) && strcmpi(whocall,'recu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For recursive mode, left side of equation cannot\nbe define as a new bin.\n'... + 'For instance, you must write bin1 = ...\n\n'... + 'Do you want that ERPLAB corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix =1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; end + %else + % wantfix =1; + end + %else + % wantfix = 0; + end + if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC + fprintf('WARNING: equation %s ', formulaArray{t}) + if strcmpi(whocall,'recu') % for recursive mode delete the n in nch + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2})); + else + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*b(\D*)(\d*)',['nb$1' num2str(newnumbin)],'ignorecase')), strtrim(parts{t}{2})); + newnumbin = newnumbin+1; + end + fprintf('was changed to equation %s \n', formulaArray{t}) + end + end end if val==1 - set(handles.editor,'String', char(formulaArray)); + set(handles.editor,'String', char(formulaArray)); end %-------------------------------------------------------------------------- @@ -781,7 +809,7 @@ function bwarning_Callback(hObject, eventdata, handles) %-------------------------------------------------------------------------- function pushbutton_contraipsi_assistant_Callback(hObject, eventdata, handles) -chanlocs = handles.chanlocs; +chanlocs = handles.chanlocs; bindescr = handles.bindescr; % @@ -789,8 +817,8 @@ function pushbutton_contraipsi_assistant_Callback(hObject, eventdata, handles) % formcell = contraipsiGUI(chanlocs, bindescr); if isempty(formcell) - disp('User selected Cancel') - return + disp('User selected Cancel') + return end formulas = char(formcell{:}); set(handles.editor,'String',formulas); @@ -845,16 +873,16 @@ function pushbutton_export_bin_list_Callback(hObject, eventdata, handles) list_of_bins = get(handles.listbox_bin,'String'); nlob = length(list_of_bins); for i=1:nlob - fprintf('%s\n',list_of_bins{i}); + fprintf('%s\n',list_of_bins{i}); end fprintf('\n\nEnd of list.\n\n') %-------------------------------------------------------------------------- function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') - % The GUI is still in UIWAIT, us UIRESUME - uiresume(handles.gui_chassis); + % The GUI is still in UIWAIT, us UIRESUME + uiresume(handles.gui_chassis); else - % The GUI is no longer waiting, just close it - delete(handles.gui_chassis); + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); end diff --git a/GUIs/chanoperGUI.fig b/GUIs/chanoperGUI.fig index 1dea21e6..274c65c8 100755 Binary files a/GUIs/chanoperGUI.fig and b/GUIs/chanoperGUI.fig differ diff --git a/GUIs/chanoperGUI.m b/GUIs/chanoperGUI.m index 5fab7165..3617c69c 100755 --- a/GUIs/chanoperGUI.m +++ b/GUIs/chanoperGUI.m @@ -75,8 +75,34 @@ function chanoperGUI_OpeningFcn(hObject, eventdata, handles, varargin) % % Name & version % -version = geterplabversion; +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + else + Toolabel = 0; + end +else + Toolabel = 1; +end + +if Toolabel + erplab_studio_default_values; + version = erplabstudiover; + set(handles.gui_chassis,'Name', ['EStudio',version,' - Channel Operation > Advanced GUI for ',typedata]) + handles = painterplabstudio(handles); + handles = setfonterplabestudio(handles); + handles.pushbutton_RUN.String = 'OK'; +else + version = geterplabversion; set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - Channel Operation GUI for ' typedata]) + % + handles = painterplab(handles); + handles = setfonterplab(handles); +end + + + % formulas = erpworkingmemory(formtype); @@ -172,12 +198,12 @@ function chanoperGUI_OpeningFcn(hObject, eventdata, handles, varargin) % % Color GUI % -handles = painterplab(handles); +% handles = painterplab(handles); % % Set font size % -handles = setfonterplab(handles); +% handles = setfonterplab(handles); % Update handles structure guidata(hObject, handles); diff --git a/GUIs/continuousFFT.fig b/GUIs/continuousFFT.fig old mode 100644 new mode 100755 diff --git a/GUIs/continuousFFT.m b/GUIs/continuousFFT.m old mode 100644 new mode 100755 diff --git a/GUIs/continuousartifactGUI.m b/GUIs/continuousartifactGUI.m old mode 100644 new mode 100755 diff --git a/GUIs/f_ERP_simulation_GUI.fig b/GUIs/f_ERP_simulation_GUI.fig new file mode 100644 index 00000000..d2a344ad Binary files /dev/null and b/GUIs/f_ERP_simulation_GUI.fig differ diff --git a/GUIs/f_ERP_simulation_GUI.m b/GUIs/f_ERP_simulation_GUI.m new file mode 100644 index 00000000..69d9eb62 --- /dev/null +++ b/GUIs/f_ERP_simulation_GUI.m @@ -0,0 +1,2617 @@ +function varargout = f_ERP_simulation_GUI(varargin) +% F_ERP_SIMULATION_GUI MATLAB code for f_ERP_simulation_GUI.fig +% F_ERP_SIMULATION_GUI, by itself, creates a new F_ERP_SIMULATION_GUI or raises the existing +% singleton*. +% +% H = F_ERP_SIMULATION_GUI returns the handle to a new F_ERP_SIMULATION_GUI or the handle to +% the existing singleton*. +% +% F_ERP_SIMULATION_GUI('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_SIMULATION_GUI.M with the given input arguments. +% +% F_ERP_SIMULATION_GUI('Property','Value',...) creates a new F_ERP_SIMULATION_GUI or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_simulation_GUI_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_simulation_GUI_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_simulation_GUI + +% Last Modified by GUIDE v2.5 26-Mar-2023 21:17:26 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_simulation_GUI_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_simulation_GUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_simulation_GUI is made visible. +function f_ERP_simulation_GUI_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_simulation_GUI + +try + def = varargin{1}; +catch + def = {1,1,100,50,1000,-200,799,1,1000,0,1,0,1,0,1,10,0}; + %%Basic option, amp, mean, SD, Tau, epoch start, epoch + %%stop, sample rate option, srate value, whitenoiseop, + %%ampwhite, pinkop,amppink,sinop,sinamp,sinfre,random number generator +end +if isempty(def) + def = {1,1,100,50,1000,-200,799,1,1000,0,1,0,1,0,1,10,0}; +end + +try + ALLERP = varargin{2}; +catch + ALLERP = []; +end + +try + CURRENTERP = varargin{3}; +catch + CURRENTERP = []; +end + + +try + ChanArray = varargin{4}; +catch + ChanArray = []; +end + +try + BinArray = varargin{5}; +catch + BinArray = []; +end + + +% handles.erpnameor = erpname; +handles.output = []; +handles.ALLERP = ALLERP; +handles.CURRENTERP = CURRENTERP; +handles.ChanArray = ChanArray; +handles.BinArray = BinArray; + +% erpmenu = findobj('tag', 'erpsets'); + +% if ~isempty(erpmenu) +% handles.menuerp = get(erpmenu); +% set(handles.menuerp.Children, 'Enable','off'); +% end + +erplab_studio_default_values; +version = geterplabversion; + +set(handles.gui_chassis,'Name', ['ERPLAB', version, ' - Create artificial ERP waveform GUI']) +% set(handles.edit_erpname, 'String', '_processed'); + +handles = painterplab(handles); + +handles = setfonterplab(handles); + +Bacfunc_Flag = def{1}; +if Bacfunc_Flag ==2%%Select Impulse signal + %%Exgaussian + set(handles.radiobutton_exgaus,'Value',0); + set(handles.radiobutton_exgaus,'Enable','on'); + set(handles.edit5_exgau_amp,'Enable','off'); + set(handles.edit_exgau_mean,'Enable','off'); + set(handles.edit_exgau_sd,'Enable','off'); + set(handles.edit8_exgua_tau,'Enable','off'); + + %%Impulse + set(handles.radiobutton_impulse,'Value',1); + + set(handles.edit_impulse_peak_amp,'Enable','on'); + Amp = def{2}; + if ~isnumeric(Amp) || numel(Amp)>1 + Amp = []; + end + set(handles.edit_impulse_peak_amp,'String',num2str(Amp)); + + set(handles.edit_impulse_lat,'Enable','on'); + Lat_im = def{3}; + if ~isnumeric(Lat_im) || numel(Lat_im)>1 + Lat_im = []; + end + set(handles.edit_impulse_lat,'String',num2str(Lat_im)); + + %%Square signal + set(handles.radiobutton_square,'Value',0); + set(handles.edit_square_peak_amp,'Enable','off'); + set(handles.edit_square_onset,'Enable','off'); + set(handles.edit_square_offset,'Enable','off'); +elseif Bacfunc_Flag ==3%%select boxcar function + + set(handles.radiobutton_exgaus,'Value',0); + set(handles.radiobutton_exgaus,'Enable','on'); + set(handles.edit5_exgau_amp,'Enable','off'); + set(handles.edit_exgau_mean,'Enable','off'); + set(handles.edit_exgau_sd,'Enable','off'); + set(handles.edit8_exgua_tau,'Enable','off'); + + %%Impulse + set(handles.radiobutton_impulse,'Value',0); + set(handles.edit_impulse_peak_amp,'Enable','off'); + set(handles.edit_impulse_lat,'Enable','off'); + + %%Square signal + set(handles.radiobutton_square,'Value',1); + Amp = def{2}; + if ~isnumeric(Amp) || numel(Amp)>1 + Amp = []; + end + set(handles.edit_square_peak_amp,'String',num2str(Amp)); + set(handles.edit_square_peak_amp,'Enable','on'); + set(handles.edit_square_onset,'Enable','on'); + + Lat_onset = def{3}; + if ~isnumeric(Lat_onset) || numel(Lat_onset)>1 + Lat_onset = []; + end + set(handles.edit_square_onset,'String',num2str(Lat_onset)); + + Lat_offset = def{4}; + if ~isnumeric(Lat_offset) || numel(Lat_offset)>1 + Lat_offset = []; + end + set(handles.edit_square_offset,'Enable','on'); + set(handles.edit_square_offset,'String',num2str(Lat_offset)); +else + %%Exgaussian + set(handles.radiobutton_exgaus,'Value',1); + set(handles.radiobutton_exgaus,'Enable','on'); + set(handles.edit5_exgau_amp,'Enable','on'); + set(handles.edit_exgau_mean,'Enable','on'); + set(handles.edit_exgau_sd,'Enable','on'); + set(handles.edit8_exgua_tau,'Enable','on'); + Amp = def{2}; + if ~isnumeric(Amp) || numel(Amp)>1 + Amp = []; + end + set(handles.edit5_exgau_amp,'String',num2str(Amp)); + + Mean = def{3}; + if ~isnumeric(Mean) || numel(Mean)>1 + Mean = []; + end + set(handles.edit_exgau_mean,'String',num2str(Mean)); + + Exg_SD = def{4}; + if ~isnumeric(Exg_SD) || numel(Exg_SD)>1 + Exg_SD = []; + end + set(handles.edit_exgau_sd,'String',num2str(Exg_SD)); + + Exg_tau = def{5}; + if ~isnumeric(Exg_tau) || numel(Exg_tau)>1 + Exg_tau = []; + end + set(handles.edit8_exgua_tau,'String',num2str(Exg_tau)); + %%Impulse + set(handles.radiobutton_impulse,'Value',0); + set(handles.edit_impulse_peak_amp,'Enable','off'); + set(handles.edit_impulse_lat,'Enable','off'); + + %%Square signal + set(handles.radiobutton_square,'Value',0); + set(handles.edit_square_peak_amp,'Enable','off'); + set(handles.edit_square_onset,'Enable','off'); + set(handles.edit_square_offset,'Enable','off'); + +end + +%%set for epoch +EpochStart = def{6}; +if ~isnumeric(EpochStart) || numel(EpochStart)>1 + EpochStart = []; +end + +EpochStop = def{7}; +if ~isnumeric(EpochStop) || numel(EpochStop)>1 + EpochStop = []; +end + +srate = def{9}; +if ~isnumeric(srate) || numel(srate)>1 || srate<=0 + srate = []; +end + +if ~isempty(ALLERP) + if ~isempty(CURRENTERP) && CURRENTERP>0 && CURRENTERP<= length(ALLERP) + ERP = ALLERP(CURRENTERP); + else + ERP = ALLERP(length(ALLERP)); + handles.CURRENTERP = length(ALLERP); + end + try + EpochStart = ERP.times(1); + EpochStop = ERP.times(end); + srate = ERP.srate; + catch + end +end +set(handles.edit_epoch_start,'String',num2str(EpochStart)); +set(handles.edit_epochstop,'String',num2str(EpochStop)); + +srateValue = def{8}; +if srateValue==1 + set(handles.radiobutton_srate,'Value',1); + set(handles.edit_srate,'Enable','on'); + set(handles.edit_srate,'String',num2str(srate)); + if ~isempty(srate) + set(handles.edit_speriod,'String',num2str(1000/srate)); + end + set(handles.radiobutton_speriod,'Value',0); + set(handles.edit_speriod,'Enable','off'); +else + set(handles.radiobutton_srate,'Value',0); + set(handles.edit_srate,'Enable','off'); + set(handles.radiobutton_speriod,'Value',1); + set(handles.edit_speriod,'Enable','on'); + set(handles.edit_speriod,'String',num2str(srate)); + if ~isempty(srate) + set(handles.edit_srate,'String',num2str(1000/srate)); + end +end + + +%%--------------------------Noise------------------------------------------ +%white noise +try + WhiteNoiseop = def{10}; +catch + WhiteNoiseop =0; +end +if WhiteNoiseop==1 + set(handles.radiobutton_whitenoise,'Value',1); + set(handles.edit_whitenoise_amp,'Enable','on'); +else + set(handles.radiobutton_whitenoise,'Value',0); + set(handles.edit_whitenoise_amp,'Enable','off'); +end +try + WhiteNoiseamp = def{11}; +catch + WhiteNoiseamp = []; +end +if isempty(WhiteNoiseamp)|| ~isnumeric(WhiteNoiseamp) || numel(WhiteNoiseamp)~=1 + WhiteNoiseamp = []; +end +set(handles.edit_whitenoise_amp,'String',num2str(WhiteNoiseamp)); + +%%pinknoise +try + pinkNoiseop = def{12}; +catch + pinkNoiseop =0; +end +if pinkNoiseop==1 + set(handles.radiobutton_pink_niose,'Value',1); + set(handles.edit_pinknoise_amp,'Enable','on'); +else + set(handles.radiobutton_pink_niose,'Value',0); + set(handles.edit_pinknoise_amp,'Enable','off'); +end + +try + pinkNoiseamp = def{13}; +catch + pinkNoiseamp = []; +end +if isempty(pinkNoiseamp)|| ~isnumeric(pinkNoiseamp) || numel(pinkNoiseamp)~=1 + pinkNoiseamp = []; +end +set(handles.edit_pinknoise_amp,'String',num2str(pinkNoiseamp)); + +%%sin noise +try + sinNoiseop = def{14}; +catch + sinNoiseop =0; +end +if sinNoiseop==1 + set(handles.radiobutton_siniose,'Value',1); + set(handles.edit_siniose_amp,'Enable','on'); + set(handles.edit_siniose_Hz,'Enable','on'); +else + set(handles.radiobutton_siniose,'Value',0); + set(handles.edit_siniose_amp,'Enable','off'); + set(handles.edit_siniose_Hz,'Enable','off'); +end +try + sinAmp = def{15}; +catch + sinAmp = []; +end +if isempty(sinAmp)|| ~isnumeric(sinAmp) || numel(sinAmp)~=1 + sinAmp = []; +end +set(handles.edit_siniose_amp,'String',num2str(sinAmp)); +try + sinFre = def{16}; +catch + sinFre = []; +end +if isempty(sinFre) || ~isnumeric(sinFre) || numel(sinFre)~=1 + sinFre = []; +end +set(handles.edit_siniose_Hz,'String',num2str(sinFre)); + +if ~isempty(ALLERP) + handles.checkbox_ERP_op.Value =1; + handles.edit_epoch_start.Enable = 'off'; + handles.edit_epochstop.Enable = 'off'; + handles.radiobutton_srate.Enable = 'off'; + handles.edit_srate.Enable = 'off'; + handles.radiobutton_speriod.Enable = 'off'; + handles.edit_speriod.Enable = 'off'; + + if ~isempty(CURRENTERP) && isnumeric(CURRENTERP) + if numel(CURRENTERP)~=1 + CURRENTERP = CURRENTERP(1); + end + if CURRENTERP>0 && CURRENTERP<= length(ALLERP) + else + CURRENTERP = length(ALLERP); + end + else + CURRENTERP = length(ALLERP); + end + handles.edit_erpset.String = num2str(CURRENTERP); + handles.CURRENTERP = CURRENTERP; + + ERP = ALLERP(CURRENTERP); + if ~isempty(ChanArray) && isnumeric(ChanArray) + if numel(ChanArray)~=1 + ChanArray = ChanArray(1); + end + if ChanArray>0 && ChanArray<=ERP.nchan + else + ChanArray =1; + end + else + ChanArray =1; + end + handles.ChanArray = ChanArray; + handles.edit_channel.String = num2str(ChanArray); + + %%bin for real ERPset + if ~isempty(BinArray) && isnumeric(BinArray) + if numel(BinArray)~=1 + BinArray = BinArray(1); + end + if BinArray>1 && BinArray<= ERP.nbin + else + BinArray =1; + end + else + BinArray =1; + end + + handles.BinArray = BinArray; + handles.edit_bin.String = num2str(BinArray); +else + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; +end + + +%%seeds for white and pink noise +SimulationSeed = erpworkingmemory('SimulationSeed'); +handles.SimulationSeed = SimulationSeed; + +rng(0,'twister'); +SimulationSeed = rng; +erpworkingmemory('SimulationSeed',SimulationSeed); +%phase for sin noise +SimulationPhase = erpworkingmemory('SimulationPhase'); +handles.SimulationPhase = SimulationPhase; + +SimulationPhase = 0; +erpworkingmemory('SimulationPhase',SimulationPhase); + + +plotsimulationwave(hObject, eventdata, handles); + + +% set(handles.current_erp_label,'String', ['Enter suffix, which will be added onto the name of each selected ERPset'],... +% 'FontWeight','Bold', 'FontSize', 16); + +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +handles.checkbox_newnoise.BackgroundColor = [1 1 1]; +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_simulation_GUI_OutputFcn(hObject, eventdata, handles) +varargout{1} = []; +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% beep; +% disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) + +BasicFunOp = 1; +Amp_bas = []; +Mean_bas = []; +SD_bas = []; +Tau_bas = []; +EpochStart = []; +EpochStop = []; +srateOp = 1; +srate = []; +WhiteOp = 0; +WhiteAmp = []; +pinkOp = 0; +pinkAmp = []; +sinOp = 0; +sinAmp = []; +sinFre = []; + + +EpochStart = str2num(handles.edit_epoch_start.String); +EpochStop = str2num(handles.edit_epochstop.String); +if handles.radiobutton_srate.Value + srateOp = 1; + srate = str2num(handles.edit_srate.String); + if isempty(srate) || numel(srate)~=1 + msgboxText = 'Please define one numeric for sampling rate!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if srate<=0 + msgboxText = 'Sampling rate must be a positive numeric!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end +else%% sampling period + srateOp=2; + Speriod = str2num(handles.edit_speriod.String); + + if isempty(Speriod) || numel(Speriod)~=1 + msgboxText = 'Please define one numeric for sampling period!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if Speriod<=0 + msgboxText = 'Sampling period must be a positive numeric!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + srate = 1000/Speriod; +end + +if isempty(EpochStart) || numel(EpochStart)~=1 + msgboxText = 'Please define one numeric for epoch start!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + +if isempty(EpochStop) || numel(EpochStop)~=1 + msgboxText = 'Please define one numeric for epoch stop!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + +if EpochStop<=EpochStart + msgboxText = 'Please start time of epoch must be smaller than stop time of epoch!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + + +if 1000/srate>= (EpochStop-EpochStart) + msgboxText = ['Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)]; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + + +Times = []; +if EpochStart>=0 + count =0; + tIndex(1,1) =0; + for ii = 1:10000 + count = count+1000/srate; + if count<=EpochStop + tIndex(1,ii) = count; + else + break; + end + end + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + Times = tIndex(latsamp(1):end); + if Times(1)=EpochStart + tIndex(1,ii) = count; + else + break; + end + end + tIndex = sort(tIndex); + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + + Times = tIndex(1:latsamp(2)); + if Times(end)> EpochStop + Times(end) = []; + end +elseif EpochStart<0 && EpochStop>0 + tIndex1(1,1) = 0; + count =0; + for ii = 1:10000 + count = count-1000/srate; + if count>=EpochStart + tIndex1(1,ii+1) = count; + else + break; + end + end + tIndex2=[]; + count1 =1000/srate; + for ii = 1:10000 + count1 = count1+1000/srate; + if count1<=EpochStop + tIndex2(1,ii) = count1; + else + break; + end + end + Times = [sort(tIndex1),tIndex2]; +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%---------------------------Basic function-------------------------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if handles.radiobutton_exgaus.Value ==1 + BasicFunOp =1; + PeakAmp = str2num(handles.edit5_exgau_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "peak amplitude" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + Meanamp = str2num(handles.edit_exgau_mean.String); + if isempty(Meanamp) || numel(Meanamp)~=1 + msgboxText = 'Please define one numeric for "mean" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + Tau = str2num(handles.edit8_exgua_tau.String); + if isempty(Tau) || numel(Tau)~=1 + msgboxText = 'Please define one numeric for "Tau" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + SD_exgau = str2num(handles.edit_exgau_sd.String); + if isempty(SD_exgau) || numel(SD_exgau)~=1 + msgboxText = 'Please define one numeric for "SD" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + Amp_bas = PeakAmp; + Mean_bas = Meanamp; + SD_bas = SD_exgau; + Tau_bas = Tau; + +elseif handles.radiobutton_impulse.Value==1 + BasicFunOp=2; + PeakAmp = str2num(handles.edit_impulse_peak_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "peak amplitude" of impulse function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + Latency = str2num(handles.edit_impulse_lat.String); + if isempty(Latency) || numel(Latency)~=1 + msgboxText = 'Please define one numeric for "latency" of impulse function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if LatencyTimes(end) + Latency=Times(end); + end + Amp_bas = PeakAmp; + Mean_bas = Latency; +elseif handles.radiobutton_square.Value ==1 + BasicFunOp=3; + PeakAmp = str2num(handles.edit_square_peak_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "peak amplitude" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + onsetLat = str2num(handles.edit_square_onset.String); + if isempty(onsetLat) || numel(onsetLat)~=1 + msgboxText = 'Please define one numeric for "onset" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + offsetLat = str2num(handles.edit_square_offset.String); + if isempty(offsetLat) || numel(offsetLat)~=1 + msgboxText = 'Please define one numeric for "offset" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if offsetLat<= onsetLat + msgboxText = 'Please "offset" should be larger than "onset" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + Amp_bas = PeakAmp; + Mean_bas = onsetLat; + SD_bas = offsetLat; +end + + + +%%---------------------------Noise signal---------------------------------- +if handles.radiobutton_siniose.Value + sinOp = 1; + PeakAmp = str2num(handles.edit_siniose_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "amplitude" of sinusoidal noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + FreHz = str2num(handles.edit_siniose_Hz.String); + if isempty(FreHz) || numel(FreHz)~=1 + msgboxText = 'Please define one numeric for "frequency" of sinusoidal noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + sinAmp =PeakAmp; + sinFre = FreHz; +else + sinOp = 0; +end + +%%white noise +if handles.radiobutton_whitenoise.Value==1 + WhiteOp = 1; + PeakAmp = str2num(handles.edit_whitenoise_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "amplitude" of white noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + WhiteAmp =PeakAmp; +else + WhiteOp = 0; +end + +if handles.radiobutton_pink_niose.Value==1 + pinkOp =1; + PeakAmp = str2num(handles.edit_pinknoise_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "amplitude" of pink noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + pinkAmp =PeakAmp; +else + pinkOp =0; +end + +NewnoiseFlag = handles.checkbox_newnoise.Value; + +handles.output = {BasicFunOp,Amp_bas,Mean_bas,SD_bas,Tau_bas,EpochStart,EpochStop,... + srateOp,srate,WhiteOp,WhiteAmp,pinkOp,pinkAmp,sinOp,sinAmp,sinFre,NewnoiseFlag}; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes during object deletion, before destroying properties. + +% hObject handle to edit_erpname (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in radiobutton_exgaus. +function radiobutton_exgaus_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +%%Exgaussian +set(handles.radiobutton_exgaus,'Value',1); +set(handles.radiobutton_exgaus,'Enable','on'); +set(handles.edit5_exgau_amp,'Enable','on'); +set(handles.edit_exgau_mean,'Enable','on'); +set(handles.edit_exgau_sd,'Enable','on'); +set(handles.edit8_exgua_tau,'Enable','on'); + +%%Impulse +set(handles.radiobutton_impulse,'Value',0); +set(handles.edit_impulse_peak_amp,'Enable','off'); +set(handles.edit_impulse_lat,'Enable','off'); + +%%Square signal +set(handles.radiobutton_square,'Value',0); +set(handles.edit_square_peak_amp,'Enable','off'); +set(handles.edit_square_onset,'Enable','off'); +set(handles.edit_square_offset,'Enable','off'); +plotsimulationwave(hObject, eventdata, handles); + + + +function edit5_exgau_amp_Callback(hObject, eventdata, handles) +Amp = str2num(handles.edit5_exgau_amp.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit5_exgau_amp.String = ''; +end +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit5_exgau_amp_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit5_exgau_amp (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_exgau_mean_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_exgau_mean.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_exgau_mean.String = ''; +end + + +EpochStart = str2num(handles.edit_epoch_start.String); +if isempty(EpochStart) + msgboxText = 'Please define a value for epoch start first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_exgau_mean.String = ''; + return; + +end +EpochStop =str2num(handles.edit_epochstop.String); +if isempty(EpochStop) + msgboxText = 'Please define a value for epoch stop first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_exgau_mean.String = ''; + return; +end + +if Amp< EpochStart + msgboxText = ['Gaussian mean should be larger than',32,num2str(EpochStart),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_exgau_mean.String = ''; + return; +end + +if Amp > EpochStop + msgboxText = ['Gaussian mean should be smaller than',32,num2str(EpochStop),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_exgau_mean.String = ''; + return; +end + +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit_exgau_mean_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_exgau_mean (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_exgau_sd_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_exgau_sd.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_exgau_sd.String = ''; +end + +if Amp<=0 + msgboxText = 'SD for Ex-Gaussian function should be a positive value!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_exgau_sd.String = ''; + return; +end + +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit_exgau_sd_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_exgau_sd (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit8_exgua_tau_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit8_exgua_tau.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit8_exgua_tau.String = ''; +end +plotsimulationwave(hObject, eventdata, handles); + + + + +% --- Executes during object creation, after setting all properties. +function edit8_exgua_tau_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit8_exgua_tau (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_impulse. +function radiobutton_impulse_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +%%Exgaussian +set(handles.radiobutton_exgaus,'Value',0); +set(handles.radiobutton_exgaus,'Enable','on'); +set(handles.edit5_exgau_amp,'Enable','off'); +set(handles.edit_exgau_mean,'Enable','off'); +set(handles.edit_exgau_sd,'Enable','off'); +set(handles.edit8_exgua_tau,'Enable','off'); + +%%Impulse +set(handles.radiobutton_impulse,'Value',1); +set(handles.edit_impulse_peak_amp,'Enable','on'); +set(handles.edit_impulse_lat,'Enable','on'); + +%%Square signal +set(handles.radiobutton_square,'Value',0); +set(handles.edit_square_peak_amp,'Enable','off'); +set(handles.edit_square_onset,'Enable','off'); +set(handles.edit_square_offset,'Enable','off'); +plotsimulationwave(hObject, eventdata, handles); + + +function edit_impulse_peak_amp_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_impulse_peak_amp.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_impulse_peak_amp.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit_impulse_peak_amp_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_impulse_lat_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Lat = str2num(handles.edit_impulse_lat.String); +if isempty(Lat) || numel(Lat)~=1 + handles.edit_impulse_lat.String = ''; + return; +end + +EpochStart = str2num(handles.edit_epoch_start.String); +if isempty(EpochStart) + msgboxText = 'Please define a value for epoch start first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_impulse_lat.String = ''; + return; + +end +EpochStop =str2num(handles.edit_epochstop.String); +if isempty(EpochStop) + msgboxText = 'Please define a value for epoch stop first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_impulse_lat.String = ''; + return; +end + +if Lat< EpochStart + msgboxText = ['Latency for Impulse function should be larger than',32,num2str(EpochStart),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_impulse_lat.String = ''; + return; +end + +if Lat > EpochStop + msgboxText = ['Latency for Impulse function should be smaller than',32,num2str(EpochStop),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_impulse_lat.String = ''; + return; +end + + +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit_impulse_lat_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_square. +function radiobutton_square_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +%%Exgaussian +set(handles.radiobutton_exgaus,'Value',0); +set(handles.radiobutton_exgaus,'Enable','on'); +set(handles.edit5_exgau_amp,'Enable','off'); +set(handles.edit_exgau_mean,'Enable','off'); +set(handles.edit_exgau_sd,'Enable','off'); +set(handles.edit8_exgua_tau,'Enable','off'); + +%%Impulse +set(handles.radiobutton_impulse,'Value',0); +set(handles.edit_impulse_peak_amp,'Enable','off'); +set(handles.edit_impulse_lat,'Enable','off'); + +%%Square signal +set(handles.radiobutton_square,'Value',1); +set(handles.edit_square_peak_amp,'Enable','on'); +set(handles.edit_square_onset,'Enable','on'); +set(handles.edit_square_offset,'Enable','on'); +plotsimulationwave(hObject, eventdata, handles); + + + +function edit_square_peak_amp_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_square_peak_amp.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_square_peak_amp.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit_square_peak_amp_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_square_onset_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +LatencyOnset = str2num(handles.edit_square_onset.String); +if isempty(LatencyOnset) || numel(LatencyOnset)~=1 + handles.edit_square_onset.String = ''; + return; +end + + +EpochStart = str2num(handles.edit_epoch_start.String); +if isempty(EpochStart) + msgboxText = 'Please define a value for epoch start first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_onset.String = ''; + return; + +end +EpochStop =str2num(handles.edit_epochstop.String); +if isempty(EpochStop) + msgboxText = 'Please define a value for epoch stop first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_onset.String = ''; + return; +end + +if LatencyOnset< EpochStart + msgboxText = ['Onset for Boxcar for Impulse function should be larger than',32,num2str(EpochStart),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_onset.String = ''; + return; +end + +if LatencyOnset > EpochStop + msgboxText = ['Onset for Boxcar function should be smaller than',32,num2str(EpochStop),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_onset.String = ''; + return; +end + + +LatencyOffset = str2num(handles.edit_square_offset.String); +if LatencyOnset> LatencyOffset + msgboxText = 'Offset for Boxcar should be larger than Onset!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_onset.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + +% --- Executes during object creation, after setting all properties. +function edit_square_onset_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_square_onset (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_square_offset_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +LatencyOffset = str2num(handles.edit_square_offset.String); +if isempty(LatencyOffset) || numel(LatencyOffset)~=1 + handles.edit_square_offset.String = ''; + return; +end + +EpochStart = str2num(handles.edit_epoch_start.String); +if isempty(EpochStart) + msgboxText = 'Please define a value for epoch start first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_offset.String = ''; + return; + +end +EpochStop =str2num(handles.edit_epochstop.String); +if isempty(EpochStop) + msgboxText = 'Please define a value for epoch stop first!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_offset.String = ''; + return; +end + +if LatencyOffset< EpochStart + msgboxText = ['Offset for Boxcar for Impulse function should be larger than',32,num2str(EpochStart),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_offset.String = ''; + return; +end + +if LatencyOffset > EpochStop + msgboxText = ['Offset for Boxcar function should be smaller than',32,num2str(EpochStop),'ms']; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_square_offset.String = ''; + return; +end + + + + +LatencyOnset = str2num(handles.edit_square_onset.String); +if LatencyOnset>LatencyOffset + msgboxText = 'Offset for Boxcar should be larger than Onset!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + + + handles.edit_square_offset.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + +% --- Executes during object creation, after setting all properties. +function edit_square_offset_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_square_offset (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes on button press in radiobutton_siniose. +function radiobutton_siniose_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +%%sin noise +Value = handles.radiobutton_siniose.Value; +if Value==1 + Enable = 'on'; +else + Enable = 'off'; +end +% set(handles.radiobutton_siniose,'Enable',Enable); +set(handles.edit_siniose_Hz,'Enable',Enable); +set(handles.edit_siniose_amp,'Enable',Enable); +plotsimulationwave(hObject, eventdata, handles); + + + +function edit_siniose_Hz_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +FreValue = str2num(handles.edit_siniose_Hz.String); +if isempty(FreValue) || numel(FreValue)~=1 || FreValue<=0 + msgboxText = 'Please define a positive numeric for frequency of sinusoidal noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + + handles.edit_siniose_Hz.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + +% --- Executes during object creation, after setting all properties. +function edit_siniose_Hz_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_siniose_amp_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_siniose_amp.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_siniose_amp.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + +% --- Executes during object creation, after setting all properties. +function edit_siniose_amp_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_siniose_amp (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_whitenoise. +function radiobutton_whitenoise_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Value = handles.radiobutton_whitenoise.Value; +if Value==1 + Enable = 'on'; +else + Enable = 'off'; +end + +% set(handles.radiobutton_whitenoise,'Enable',Enable); +set(handles.edit_whitenoise_amp,'Enable',Enable); +plotsimulationwave(hObject, eventdata, handles); + + +function edit_whitenoise_amp_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_whitenoise_amp.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_whitenoise_amp.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + +% --- Executes during object creation, after setting all properties. +function edit_whitenoise_amp_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_whitenoise_amp (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_pink_niose. +function radiobutton_pink_niose_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Value = handles.radiobutton_pink_niose.Value; +if Value==1 + Enable = 'on'; +else + Enable = 'off'; +end +% set(handles.radiobutton_pink_niose,'Enable',Enable); +set(handles.edit_pinknoise_amp,'Enable',Enable); +plotsimulationwave(hObject, eventdata, handles); + + + + +function edit_pinknoise_amp_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +Amp = str2num(handles.edit_pinknoise_amp.String); +if isempty(Amp) || numel(Amp)~=1 + handles.edit_pinknoise_amp.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + +% --- Executes during object creation, after setting all properties. +function edit_pinknoise_amp_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_pinknoise_amp (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_epoch_start_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +EpochStart =str2num(handles.edit_epoch_start.String); +if ~isnumeric(EpochStart) || numel(EpochStart)>1 + handles.edit_epoch_start.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + +% --- Executes during object creation, after setting all properties. +function edit_epoch_start_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_epoch_start (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_epochstop_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +EpochStop =str2num(handles.edit_epochstop.String); +if ~isnumeric(EpochStop) || numel(EpochStop)>1 + handles.edit_epochstop.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + +% --- Executes during object creation, after setting all properties. +function edit_epochstop_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_srate. +function radiobutton_srate_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +set(handles.radiobutton_srate,'Value',1); +set(handles.edit_srate,'Enable','on'); +set(handles.radiobutton_speriod,'Value',0); +set(handles.edit_speriod,'Enable','off'); +srate = str2num(handles.edit_srate.String); +plotsimulationwave(hObject, eventdata, handles); + + +function edit_srate_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; +srate = str2num(handles.edit_srate.String); +if ~isempty(srate) && numel(srate)==1 && srate>0 + set(handles.edit_speriod,'String',num2str(1000/srate)); +elseif isempty(srate) || srate<=0 + handles.edit_srate.String = ''; + msgboxText = 'Sampling rate should be a positive numeric!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + +% --- Executes during object creation, after setting all properties. +function edit_srate_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_speriod. +function radiobutton_speriod_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +set(handles.radiobutton_srate,'Value',0); +set(handles.edit_srate,'Enable','off'); +set(handles.radiobutton_speriod,'Value',1); +set(handles.edit_speriod,'Enable','on'); +plotsimulationwave(hObject, eventdata, handles); + + + +function edit_speriod_Callback(hObject, eventdata, handles) +handles.text_message.String = ''; + +speriod = str2num(handles.edit_speriod.String); +if ~isempty(speriod) && numel(speriod)==1 && speriod>0 + set(handles.edit_srate,'String',num2str(1000/speriod)); +elseif isempty(speriod)|| speriod<=0 + handles.edit_srate.String = ''; + msgboxText = 'Sampling period should be a positive numeric!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_speriod.String = ''; + return; +end +plotsimulationwave(hObject, eventdata, handles); + +% --- Executes during object creation, after setting all properties. +function edit_speriod_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_speriod (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +% --- Executes during object creation, after setting all properties. +function edit_exgua_onset_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_exgua_onset (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + + +function ERP = plotsimulationwave(hObject, eventdata, handles); + +%%------------------match with real ERPset?-------------------------------- +MatchFlag = handles.checkbox_ERP_op.Value; +ALLERP = handles.ALLERP; +ERP = []; +ERPArray = []; +ChannelArray = []; +binArray = []; +% NoiseupdateFlag = handles.checkbox_newnoise.Value; + +if MatchFlag==1 && ~isempty(ALLERP) + %%check ERPset + ERPArray = str2num(handles.edit_erpset.String); + if ~isempty(ERPArray) + if numel(ERPArray)~=1 + ERPArray = ERPArray(1); + end + if ERPArray>0 && ERPArray <=length(ALLERP) + else + ERPArray = length(ALLERP); + end + else + ERPArray = length(ALLERP); + end + handles.edit_erpset.String= num2str(ERPArray); + ERP = ALLERP(ERPArray); + %%check channels + ChannelArray = str2num(handles.edit_channel.String); + if isempty(ChannelArray) + ChannelArray =1; + else + if numel(ChannelArray)~=1 + ChannelArray = ChannelArray(1); + end + if ChannelArray>0 && ChannelArray<= ERP.nchan + else + ChannelArray =1; + end + end + handles.edit_channel.String = num2str(ChannelArray); + %%check bins + binArray = str2num(handles.edit_bin.String); + if isempty(binArray) + binArray =1; + else + if numel(binArray)~=1 + binArray = binArray(1); + end + if binArray>0 && binArray<=ERP.nbin + else + binArray =1; + end + end + handles.edit_bin.String = num2str(binArray); +end + +EpochStart = str2num(handles.edit_epoch_start.String); +EpochStop = str2num(handles.edit_epochstop.String); +if handles.radiobutton_srate.Value + srate = str2num(handles.edit_srate.String); + if isempty(srate) || numel(srate)~=1 + msgboxText = 'Please define one numeric for sampling rate!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if srate<=0 + msgboxText = 'Sampling rate must be a positive numeric!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end +else%% sampling period + Speriod = str2num(handles.edit_speriod.String); + + if isempty(Speriod) || numel(Speriod)~=1 + msgboxText = 'Please define one numeric for sampling period!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if Speriod<=0 + msgboxText = 'Sampling period must be a positive numeric!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + srate = 1000/Speriod; +end + +if isempty(EpochStart) || numel(EpochStart)~=1 + msgboxText = 'Please define one numeric for epoch start!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + +if isempty(EpochStop) || numel(EpochStop)~=1 + msgboxText = 'Please define one numeric for epoch stop!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + +if EpochStop<=EpochStart + msgboxText = 'Start time of epoch must be smaller than stop time of epoch!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + + +if 1000/srate>= (EpochStop-EpochStart) + msgboxText = ['Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)]; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end + +Times = []; +if ~isempty(ERP) && ~isempty(ChannelArray) && ~isempty(binArray) + Times = ERP.times; +else + if EpochStart>=0 + count =0; + tIndex(1,1) =0; + for ii = 1:10000 + count = count+1000/srate; + if count<=EpochStop + tIndex(1,ii) = count; + else + break; + end + end + + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + Times = tIndex(latsamp(1):end); + if Times(1)=EpochStart + tIndex(1,ii) = count; + else + break; + end + end + tIndex = sort(tIndex); + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + + Times = tIndex(1:latsamp(2)); + if Times(end)> EpochStop + Times(end) = []; + end + elseif EpochStart<0 && EpochStop>0 + tIndex1(1,1) = 0; + count =0; + for ii = 1:10000 + count = count-1000/srate; + if count>=EpochStart + tIndex1(1,ii+1) = count; + else + break; + end + end + tIndex2=[]; + count1 =0; + for ii = 1:10000 + count1 = count1+1000/srate; + if count1<=EpochStop + tIndex2(1,ii) = count1; + else + break; + end + end + Times = [sort(tIndex1),tIndex2]; + end +end + +[x1,y1] = find(roundn(Times,-3)==roundn(EpochStart,-3)); + + +[x2,y2] = find(roundn(Times,-3)==roundn(EpochStop,-3)); +if isempty(y1) || isempty(y2) + Mesg = 'Warning: The exact time periods you have specified cannot be exactly created with the specified sampling rate. We will round to the nearest possible time values when the ERPset is created.'; + handles.text_message.String = Mesg; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; +else + handles.text_message.String = ''; +end + +Desiredsignal = zeros(1,numel(Times)); +Desirednosizesin = zeros(1,numel(Times)); +Desirednosizewhite = zeros(1,numel(Times)); +Desirednosizepink = zeros(1,numel(Times)); +RealData = nan(1,numel(Times)); + +% plot(handles.axes1,Times,Desiredsignal,'k','linewidth',1.5); + +%%---------------------------Simulated signal------------------------------ +if handles.radiobutton_exgaus.Value ==1 + Gua_PDF = zeros(1,numel(Times)); + PeakAmp = str2num(handles.edit5_exgau_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "peak amplitude" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + Meanamp = str2num(handles.edit_exgau_mean.String); + if isempty(Meanamp) || numel(Meanamp)~=1 + msgboxText = 'Please define one numeric for "mean" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + + Tau = str2num(handles.edit8_exgua_tau.String); + if isempty(Tau) || numel(Tau)~=1 + msgboxText = 'Please define one numeric for "Tau" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + + SD = str2num(handles.edit_exgau_sd.String); + if isempty(SD) || numel(SD)~=1 + msgboxText = 'Please define one numeric for "SD" of Ex-Gaussian function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + SD = SD/100; + Tau = Tau/1000; + if Tau~=0 + Mu = Meanamp/100-Times(1)/100; + if Mu<0 + Mu = Meanamp/100; + end + if Tau<0 + Mu = abs((Times(end)/100-Times(1)/100)-Mu); + end + LegthSig = (Times(end)-Times(1))/100; + Sig = 0: LegthSig/numel(Times):LegthSig-LegthSig/numel(Times); + Gua_PDF = f_exgauss_pdf(Sig, Mu, SD, abs(Tau)); + if Tau<0 + Gua_PDF = fliplr(Gua_PDF); + end + + elseif Tau==0 %%Gaussian signal + Times_new = Times/1000; + Gua_PDF = f_gaussian(Times_new,abs(PeakAmp),Meanamp/1000,SD/10); + end + + Max = max(abs( Gua_PDF(:))); + Gua_PDF = PeakAmp*Gua_PDF./Max; + if PeakAmp~=0 + Desiredsignal = Gua_PDF; + end + +elseif handles.radiobutton_impulse.Value==1 + PeakAmp = str2num(handles.edit_impulse_peak_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "peak amplitude" of impulse function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + Latency = str2num(handles.edit_impulse_lat.String); + if isempty(Latency) || numel(Latency)~=1 + msgboxText = 'Please define one numeric for "latency" of impulse function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if LatencyTimes(end) + Latency=Times(end); + end + [xxx, latsamp, latdiffms] = closest(Times, Latency); + Desiredsignal(latsamp) = PeakAmp; + +elseif handles.radiobutton_square.Value ==1 + PeakAmp = str2num(handles.edit_square_peak_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "peak amplitude" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + onsetLat = str2num(handles.edit_square_onset.String); + if isempty(onsetLat) || numel(onsetLat)~=1 + msgboxText = 'Please define one numeric for "onset" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + offsetLat = str2num(handles.edit_square_offset.String); + if isempty(offsetLat) || numel(offsetLat)~=1 + msgboxText = 'Please define one numeric for "offset" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + if offsetLat< onsetLat + msgboxText = 'Please "offset" should be larger than "onset" of boxcar function!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + [xxx, latsamp, latdiffms] = closest(Times, [onsetLat,offsetLat]); + Desiredsignal(latsamp(1):latsamp(2)) = PeakAmp; +end + + + +%%---------------------------Noise signal---------------------------------- +SimulationSeed = handles.SimulationSeed; +try + SimulationSeed_Type = SimulationSeed.Type; + SimulationSeed_seed=SimulationSeed.Seed; +catch + SimulationSeed_Type = 'twister'; + SimulationSeed_seed = 0; +end +%phase for sin noise +SimulationPhase = handles.SimulationPhase; +if isempty(SimulationPhase) || ~isnumeric(SimulationPhase) + SimulationPhase = 0; +end +if numel(SimulationPhase)~=1 + SimulationPhase = SimulationPhase(1); +end +if SimulationPhase<0 || SimulationPhase>1 + SimulationPhase = 0; +end + +if handles.radiobutton_siniose.Value + PeakAmp = str2num(handles.edit_siniose_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "amplitude" of sinusoidal noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + FreHz = str2num(handles.edit_siniose_Hz.String); + if isempty(FreHz) || numel(FreHz)~=1 || FreHz<=0 + msgboxText = 'Please define one positive numeric for "frequency" of sinusoidal noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + X = Times/1000; + + Desirednosizesin = PeakAmp*sin(2*FreHz*pi*(X)+2*pi*SimulationPhase); +end + + +if handles.radiobutton_whitenoise.Value==1 + PeakAmp = str2num(handles.edit_whitenoise_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "amplitude" of white noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + try + rng(SimulationSeed_seed,SimulationSeed_Type); + catch + rng(0,'twister'); + end + Desirednosizewhite = randn(1,numel(Times));%%white noise + Desirednosizewhite = PeakAmp*Desirednosizewhite; +end + +if handles.radiobutton_pink_niose.Value==1 + PeakAmp = str2num(handles.edit_pinknoise_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = 'Please define one numeric for "amplitude" of pink noise!'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + try + rng(SimulationSeed_seed,SimulationSeed_Type); + catch + rng(0,'twister'); + end + Desirednosizepink = f_pinknoise(numel(Times)); + + Desirednosizepink = reshape(Desirednosizepink,1,numel(Desirednosizepink)); + Desirednosizepink = PeakAmp*Desirednosizepink; +end + + +Sig = Desirednosizesin+Desiredsignal+Desirednosizepink+Desirednosizewhite; +if ~isempty(ERP) && ~isempty(ChannelArray) && ~isempty(binArray) + try + RealData = squeeze(ERP.bindata(ChannelArray,:,binArray)); + plot(handles.axes1,Times,[Sig;RealData],'linewidth',1.5); + legend({'Simulated data',['Real data at',32,ERP.chanlocs(ChannelArray).labels]},'fontsize',14); + legend('boxoff'); + catch + end +else + plot(handles.axes1,Times,Sig,'k','linewidth',1.5); + legend({'Simulated data'},'fontsize',14); + legend('boxoff'); +end + +xlim([Times(1),Times(end)]); +xlabel(['Time/ms']); +% Update handles structure +guidata(hObject, handles); + + +% --- Executes during object deletion, before destroying properties. +function edit_exgua_onset_DeleteFcn(hObject, eventdata, handles) +% hObject handle to edit_exgua_onset (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in checkbox_ERP_op. +function checkbox_ERP_op_Callback(hObject, eventdata, handles) +Value = handles.checkbox_ERP_op.Value; +if Value==1 + handles.edit_erpset.Enable = 'on'; + handles.pushbutton_erpset.Enable = 'on'; + handles.edit_channel.Enable = 'on'; + handles.pushbutton_channel.Enable = 'on'; + handles.edit_bin.Enable = 'on'; + handles.pushbutton_bin.Enable = 'on'; + + ALLERP = handles.ALLERP; + CURRENTERP = handles.CURRENTERP; + if isempty(ALLERP) + msgboxText = 'ALLERP is empty and cannot match simulation with real data'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + %%disable "Basic information for simulation". That is, the parameters + %%must be the same to the real ERPset + handles.edit_epoch_start.Enable = 'off'; + handles.edit_epochstop.Enable = 'off'; + handles.radiobutton_srate.Enable = 'off'; + handles.edit_srate.Enable = 'off'; + handles.radiobutton_speriod.Enable = 'off'; + handles.edit_speriod.Enable = 'off'; + + %%change the epoch start, epoch stop, and sampling rate based on the + %%changed ERPsets + EpochStart =[]; + EpochStop = []; + srate =[]; + if ~isempty(ALLERP) + if ~isempty(CURRENTERP) && CURRENTERP>0 && CURRENTERP<= length(ALLERP) + ERP = ALLERP(CURRENTERP); + else + ERP = ALLERP(length(ALLERP)); + handles.CURRENTERP = length(ALLERP); + end + try + EpochStart = ERP.times(1); + EpochStop = ERP.times(end); + srate = ERP.srate; + catch + end + end + + if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate) + handles.edit_epoch_start.String = num2str(EpochStart); + handles.edit_epochstop.String = num2str(EpochStop); + if srate~=0 + handles.edit_srate.String = num2str(srate); + handles.edit_speriod.String = num2str(1000/srate); + end + end +else + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + + handles.edit_epoch_start.Enable = 'on'; + handles.edit_epochstop.Enable = 'on'; + handles.radiobutton_srate.Enable = 'on'; + handles.edit_srate.Enable = 'on'; + handles.radiobutton_speriod.Enable = 'on'; + handles.edit_speriod.Enable = 'on'; + + if handles.radiobutton_srate.Value==1 + set(handles.radiobutton_srate,'Value',1); + set(handles.edit_srate,'Enable','on'); + set(handles.radiobutton_speriod,'Value',0); + set(handles.edit_speriod,'Enable','off'); + else + set(handles.radiobutton_srate,'Value',0); + set(handles.edit_srate,'Enable','off'); + set(handles.radiobutton_speriod,'Value',1); + set(handles.edit_speriod,'Enable','on'); + end + +end +plotsimulationwave(hObject, eventdata, handles); + + +function edit_erpset_Callback(hObject, eventdata, handles) +ERPsetArray = str2num(handles.edit_erpset.String); +if ~isempty(handles.ALLERP) + if isempty(ERPsetArray) + msgboxText = 'Real ERP: Index of ERPset should be a positive numeric'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + else + if numel(ERPsetArray)~=1 + ERPsetArray = ERPsetArray(1); + end + if ERPsetArray> length(handles.ALLERP) + ERPsetArray = length(handles.ALLERP); + msgboxText = 'Real ERP: Input should be smaller than the length of ALLERP.'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_erpset.String = num2str(handles.CURRENTERP); + return; + end + CURRENTERP = ERPsetArray; + ALLERP = handles.ALLERP; + handles.CURRENTERP = ERPsetArray; + ERP =handles.ALLERP(ERPsetArray); + EpochStart =[]; + EpochStop = []; + srate =[]; + if ~isempty(ALLERP) + if ~isempty(CURRENTERP) && CURRENTERP>0 && CURRENTERP<= length(ALLERP) + ERP = ALLERP(CURRENTERP); + else + ERP = ALLERP(length(ALLERP)); + handles.CURRENTERP = length(ALLERP); + end + try + EpochStart = ERP.times(1); + EpochStop = ERP.times(end); + srate = ERP.srate; + catch + end + end + + if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate) + handles.edit_epoch_start.String = num2str(EpochStart); + handles.edit_epochstop.String = num2str(EpochStop); + if srate~=0 + handles.edit_srate.String = num2str(srate); + handles.edit_speriod.String = num2str(1000/srate); + end + end + + end +else + handles.checkbox_ERP_op.Value =0; + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + + msgboxText = 'Real ERP: ALLERPset is empty and cannot match simulation with it'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + + +% --- Executes during object creation, after setting all properties. +function edit_erpset_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_erpset. +function pushbutton_erpset_Callback(hObject, eventdata, handles) + +if ~isempty(handles.ALLERP) + ERPsetArray = handles.CURRENTERP; + if isempty(ERPsetArray) + msgboxText = 'Real ERP: Index of ERPset is empty'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + else + if numel(ERPsetArray)~=1 + ERPsetArray = ERPsetArray(1); + end + if ERPsetArray> length(handles.ALLERP) + ERPsetArray = length(handles.ALLERP); + msgboxText = 'Real ERP: Input should be smaller than the length of ALLERP.'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + handles.edit_erpset.String = num2str(handles.CURRENTERP); + return; + end + ALLERP = handles.ALLERP; + for Numoferpset = 1:length(ALLERP) + listname{Numoferpset} = char(strcat(num2str(Numoferpset),'.',ALLERP(Numoferpset).erpname)); + end + indxlistb =ERPsetArray; + + titlename = 'Select one ERPset:'; + ERPsetArray = browsechanbinGUI(listname, indxlistb, titlename); + + if ~isempty(ERPsetArray) + if numel(ERPsetArray)~=1 + ERPsetArray =ERPsetArray(1); + end + CURRENTERP = ERPsetArray; + ALLERP = handles.ALLERP; + handles.CURRENTERP = ERPsetArray; + ERP =handles.ALLERP(ERPsetArray); + EpochStart =[]; + EpochStop = []; + srate =[]; + if ~isempty(CURRENTERP) && CURRENTERP >0 && CURRENTERP<= length(ALLERP) + ERP = ALLERP(CURRENTERP); + else + ERP = ALLERP(length(ALLERP)); + handles.CURRENTERP = length(ALLERP); + end + try + EpochStart = ERP.times(1); + EpochStop = ERP.times(end); + srate = ERP.srate; + catch + end + if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate) + handles.edit_epoch_start.String = num2str(EpochStart); + handles.edit_epochstop.String = num2str(EpochStop); + if srate~=0 + handles.edit_srate.String = num2str(srate); + handles.edit_speriod.String = num2str(1000/srate); + end + end + handles.edit_erpset.String = num2str(CURRENTERP); + else%%the user did not select one ERPset + msgboxText = 'Real ERP: User selected cancel.'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + end +else + handles.checkbox_ERP_op.Value =0; + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + + msgboxText = 'Real ERP: ALLERPset is empty and cannot match simulation with it'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + + +%%edit channels +function edit_channel_Callback(hObject, eventdata, handles) +if ~isempty(handles.ALLERP) + channelArray = str2num(handles.edit_channel.String); + if isempty(channelArray) + msgboxText = 'Real ERP: Please input one positive numeric for "Channel".'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + if numel(channelArray)~=1 + channelArray = channelArray(1); + end + if channelArray<=0 + msgboxText = 'Real ERP: Please input one positive numeric for "Channel".'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + ALLERP = handles.ALLERP; + CURRENTERP= handles.CURRENTERP; + if isempty(CURRENTERP) + CURRENTERP = length(ALLERP); + end + if numel(CURRENTERP)~=1 + CURRENTERP = CURRENTERP(1); + end + if CURRENTERP> length(ALLERP) || CURRENTERP<=0 + CURRENTERP = length(ALLERP); + end + handles.CURRENTERP=CURRENTERP; + handles.edit_erpset.String = num2str(CURRENTERP); + ERP = ALLERP(CURRENTERP); + if channelArray > ERP.nchan + channelArray =1; + end + handles.edit_channel.String = num2str(channelArray); +else + handles.checkbox_ERP_op.Value =0; + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + msgboxText = 'Real ERP: ALLERPset is empty and cannot match simulation with it'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + +% --- Executes during object creation, after setting all properties. +function edit_channel_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_channel. +function pushbutton_channel_Callback(hObject, eventdata, handles) + +if ~isempty(handles.ALLERP) + ALLERP = handles.ALLERP; + CURRENTERP= handles.CURRENTERP; + if isempty(CURRENTERP) + CURRENTERP = length(ALLERP); + end + if numel(CURRENTERP)~=1 + CURRENTERP = CURRENTERP(1); + end + if CURRENTERP> length(ALLERP) || CURRENTERP<=0 + CURRENTERP = length(ALLERP); + end + handles.CURRENTERP=CURRENTERP; + handles.edit_erpset.String = num2str(CURRENTERP); + ERP = ALLERP(CURRENTERP); + channelArray = str2num(handles.edit_channel.String); + if isempty(channelArray) + channelArray=1; + end + if numel(channelArray)~=1 + channelArray = channelArray(1); + end + if channelArray<=0 + channelArray=1; + end + if max(channelArray(:)) >ERP.nchan + channelArray =1; + end + + for Numofchan = 1:ERP.nchan + listb{Numofchan}= strcat(num2str(Numofchan),'.',ERP.chanlocs(Numofchan).labels); + end + titlename = 'Select One Channel:'; + channelArray = browsechanbinGUI(listb, channelArray, titlename); + if ~isempty(channelArray) + if numel(channelArray)~=1 + channelArray = channelArray(1); + end + handles.edit_channel.String = num2str(channelArray); + else + msgboxText = 'Real ERP: User selected cancel.'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end +else + handles.checkbox_ERP_op.Value =0; + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + msgboxText = 'Real ERP: ALLERPset is empty and cannot match simulation with it'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + +function edit_bin_Callback(hObject, eventdata, handles) + +if ~isempty(handles.ALLERP) + binArray = str2num(handles.edit_bin.String); + if isempty(binArray) + msgboxText = 'Real ERP: Please input one positive numeric for "Bin".'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + + if numel(binArray)~=1 + binArray = binArray(1); + end + if binArray<=0 + msgboxText = 'Real ERP: Please input one positive numeric for "Bin".'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end + ALLERP = handles.ALLERP; + CURRENTERP= handles.CURRENTERP; + if isempty(CURRENTERP) + CURRENTERP = length(ALLERP); + end + if numel(CURRENTERP)~=1 + CURRENTERP = CURRENTERP(1); + end + if CURRENTERP> length(ALLERP) || CURRENTERP<=0 + CURRENTERP = length(ALLERP); + end + handles.CURRENTERP=CURRENTERP; + handles.edit_erpset.String = num2str(CURRENTERP); + ERP = ALLERP(CURRENTERP); + if binArray > ERP.nbin + binArray =1; + end + handles.edit_bin.String = num2str(binArray); +else + handles.checkbox_ERP_op.Value =0; + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + msgboxText = 'Real ERP: ALLERPset is empty and cannot match simulation with it'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + + + + +% --- Executes during object creation, after setting all properties. +function edit_bin_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_bin. +function pushbutton_bin_Callback(hObject, eventdata, handles) +if ~isempty(handles.ALLERP) + ALLERP = handles.ALLERP; + CURRENTERP= handles.CURRENTERP; + if isempty(CURRENTERP) + CURRENTERP = length(ALLERP); + end + if numel(CURRENTERP)~=1 + CURRENTERP = CURRENTERP(1); + end + if CURRENTERP> length(ALLERP) || CURRENTERP<=0 + CURRENTERP = length(ALLERP); + end + handles.CURRENTERP=CURRENTERP; + handles.edit_erpset.String = num2str(CURRENTERP); + ERP = ALLERP(CURRENTERP); + binArray = str2num(handles.edit_bin.String); + if isempty(binArray) + binArray=1; + end + if numel(binArray)~=1 + binArray = binArray(1); + end + if binArray<=0 + binArray=1; + end + if max(binArray(:)) >ERP.nchan + binArray =1; + end + + for Numofchan = 1:ERP.nbin + listb{Numofchan}= strcat(num2str(Numofchan),'.',ERP.bindescr{Numofchan}); + end + titlename = 'Select One Bin:'; + binArray = browsechanbinGUI(listb, binArray, titlename); + if ~isempty(binArray) + if numel(binArray)~=1 + binArray = binArray(1); + end + handles.edit_bin.String = num2str(binArray); + else + msgboxText = 'Real ERP: User selected cancel.'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; + end +else + handles.checkbox_ERP_op.Value =0; + handles.checkbox_ERP_op.Enable = 'off'; + handles.edit_erpset.Enable = 'off'; + handles.pushbutton_erpset.Enable = 'off'; + handles.edit_channel.Enable = 'off'; + handles.pushbutton_channel.Enable = 'off'; + handles.edit_bin.Enable = 'off'; + handles.pushbutton_bin.Enable = 'off'; + msgboxText = 'Real ERP: ALLERPset is empty and cannot match simulation with it'; + handles.text_message.String = msgboxText; + handles.text_message.ForegroundColor = 'k'; + handles.text_message.FontSize = 12; + return; +end +plotsimulationwave(hObject, eventdata, handles); + + +% --- Executes on button press in pushbutton_loaderpset. +% function pushbutton_loaderpset_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton_loaderpset (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in checkbox_newnoise. +function checkbox_newnoise_Callback(hObject, eventdata, handles) + +%%reset the phase for sin signal +SimulationPhase = rand(1); +erpworkingmemory('SimulationPhase',SimulationPhase); + +%%reset seeds for white or pink noise +SimulationSeed = erpworkingmemory('SimulationSeed'); +try + SimulationSeed.Type = 'twister'; + SimulationSeed.Seed = SimulationSeed.Seed+1; +catch + SimulationSeed.Type = 'twister'; + SimulationSeed.Seed = 0; +end +erpworkingmemory('SimulationSeed',SimulationSeed); +handles.SimulationSeed = SimulationSeed; +handles.SimulationPhase = SimulationPhase; + +plotsimulationwave(hObject, eventdata, handles); diff --git a/GUIs/gui_erplabShiftEventCodes.fig b/GUIs/gui_erplabShiftEventCodes.fig index a1a324d8..f94ff02a 100755 Binary files a/GUIs/gui_erplabShiftEventCodes.fig and b/GUIs/gui_erplabShiftEventCodes.fig differ diff --git a/GUIs/gui_remove_response_mistakes.fig b/GUIs/gui_remove_response_mistakes.fig old mode 100644 new mode 100755 diff --git a/GUIs/importERPSS_GUI.m b/GUIs/importERPSS_GUI.m index a3170300..22fb762a 100755 --- a/GUIs/importERPSS_GUI.m +++ b/GUIs/importERPSS_GUI.m @@ -27,18 +27,48 @@ function importERPSS_GUI_OpeningFcn(hObject, eventdata, handles, varargin) % % Name & version % -version = geterplabversion; -set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - IMPORT ERP from ERPSS (ASCII) GUI']) +% version = geterplabversion; +% set(handles.gui_chassis,'Name', ['Estudio 2022.1 - IMPORT ERP from ERPSS (ASCII) GUI']) + +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + else + Toolabel = 0; + end +else + Toolabel = 1; +end + +if Toolabel + erplab_studio_default_values; + version = erplabstudiover; + set(handles.gui_chassis,'Name', ['EStudio',version,' - IMPORT ERP from ERPSS (ASCII) GUI']) + handles = painterplabstudio(handles); + % + % % + % % Set font size + % % + handles = setfonterplabestudio(handles); +else + version = geterplabversion; + set(handles.gui_chassis,'Name', ['ERPLAB',version,' - IMPORT ERP from ERPSS (ASCII) GUI']) + % + handles = painterplab(handles); + + handles = setfonterplab(handles); +end % % Color GUI % -handles = painterplab(handles); +% handles = painterplab(handles); % % Set font size % -handles = setfonterplab(handles); +% handles = setfonterplab(handles); % Update handles structure guidata(hObject, handles); diff --git a/GUIs/importerpGUI.fig b/GUIs/importerpGUI.fig index e011239c..301fe9ca 100755 Binary files a/GUIs/importerpGUI.fig and b/GUIs/importerpGUI.fig differ diff --git a/GUIs/importerpGUI.m b/GUIs/importerpGUI.m index ba404321..23e8d1eb 100755 --- a/GUIs/importerpGUI.m +++ b/GUIs/importerpGUI.m @@ -3,19 +3,19 @@ % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... - 'gui_Singleton', gui_Singleton, ... - 'gui_OpeningFcn', @importerpGUI_OpeningFcn, ... - 'gui_OutputFcn', @importerpGUI_OutputFcn, ... - 'gui_LayoutFcn', [] , ... - 'gui_Callback', []); + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @importerpGUI_OpeningFcn, ... + 'gui_OutputFcn', @importerpGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); if nargin && ischar(varargin{1}) - gui_State.gui_Callback = str2func(varargin{1}); + gui_State.gui_Callback = str2func(varargin{1}); end if nargout - [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else - gui_mainfcn(gui_State, varargin{:}); + gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT @@ -28,9 +28,9 @@ function importerpGUI_OpeningFcn(hObject, eventdata, handles, varargin) %{filename, pathname, ftype,includetime,timeunit,elabel,transpose,fs,xlim}); try - def = varargin{1}; + def = varargin{1}; catch - def = {'','','',0,1,0,0,1000,[-200 800]}; + def = {'','','',0,1,0,0,1000,[-200 800]}; end filename = def{1}; @@ -50,62 +50,82 @@ function importerpGUI_OpeningFcn(hObject, eventdata, handles, varargin) fulltext = cell(1); if nfile>0 - for i=1:nfile - fulltext{i} = fullfile(pathname{i},filename{i}); - end - fulltext = cat(1, fulltext', {'new erpset'}); - set(handles.listbox_erpnames, 'String', fulltext'); + for i=1:nfile + fulltext{i} = fullfile(pathname{i},filename{i}); + end + fulltext = cat(1, fulltext', {'new erpset'}); + set(handles.listbox_erpnames, 'String', fulltext'); else - set(handles.listbox_erpnames, 'String', {'new erpset'}); + set(handles.listbox_erpnames, 'String', {'new erpset'}); end set(handles.checkbox_time, 'Value', includetime) % time exists by default set(handles.edit_srate,'String', num2str(fs)) set(handles.edit_xlim,'String', num2str(xlim)) if includetime && timeunit==1 - set(handles.radiobutton_time_sec,'Value',1) - set(handles.radiobutton_time_msec,'Value',0) + set(handles.radiobutton_time_sec,'Value',1) + set(handles.radiobutton_time_msec,'Value',0) elseif includetime && timeunit==1E-3 - set(handles.radiobutton_time_sec,'Value',0) - set(handles.radiobutton_time_msec,'Value',1) + set(handles.radiobutton_time_sec,'Value',0) + set(handles.radiobutton_time_msec,'Value',1) elseif ~includetime - set(handles.radiobutton_time_sec,'Value',0) - set(handles.radiobutton_time_msec,'Value',0) - set(handles.radiobutton_time_sec,'Enable', 'off') - set(handles.radiobutton_time_msec,'Enable', 'off') + set(handles.radiobutton_time_sec,'Value',0) + set(handles.radiobutton_time_msec,'Value',0) + set(handles.radiobutton_time_sec,'Enable', 'off') + set(handles.radiobutton_time_msec,'Enable', 'off') else - msgboxText = ['No valid time unit.\n'... - 'Only 1 (sec) and 1E-3 (msec) are allowed.']; - title = 'ERPLAB: importerpGUI() -> wrong input'; - errorfound(sprintf(msgboxText), title); - return + msgboxText = ['No valid time unit.\n'... + 'Only 1 (sec) and 1E-3 (msec) are allowed.']; + title = 'ERPLAB: importerpGUI() -> wrong input'; + errorfound(sprintf(msgboxText), title); + return end set(handles.checkbox_elabels, 'Value', elabel) % time exists by default if transpose==1 - set(handles.radiobutton_er_pc,'Value',0) - set(handles.radiobutton_pr_ec,'Value',1) + set(handles.radiobutton_er_pc,'Value',0) + set(handles.radiobutton_pr_ec,'Value',1) else - set(handles.radiobutton_er_pc,'Value',1) - set(handles.radiobutton_pr_ec,'Value',0) + set(handles.radiobutton_er_pc,'Value',1) + set(handles.radiobutton_pr_ec,'Value',0) end % % Name & version % -version = geterplabversion; -set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - IMPORT AVERAGED ERP DATA GUI']) -% -% Color GUI -% -handles = painterplab(handles); - -% -% Set font size -% -handles = setfonterplab(handles); +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + + else + Toolabel = 0; + end +else + Toolabel = 1; +end + +if Toolabel + erplab_studio_default_values; + version = erplabstudiover; + set(handles.gui_chassis,'Name', ['EStudio',version,' - IMPORT AVERAGED ERP DATA GUI']) + handles = painterplabstudio(handles); + % + % % + % % Set font size + % % + handles = setfonterplabestudio(handles); +else + + version = geterplabversion; + set(handles.gui_chassis,'Name', ['ERPLAB',version,' - IMPORT AVERAGED ERP DATA GUI']) + % + handles = painterplab(handles); + + handles = setfonterplab(handles); +end % Update handles structure guidata(hObject, handles); @@ -133,7 +153,7 @@ function listbox_erpnames_Callback(hObject, eventdata, handles) function listbox_erpnames_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) - set(hObject,'BackgroundColor','white'); + set(hObject,'BackgroundColor','white'); end % ------------------------------------------------------------------------- @@ -148,60 +168,60 @@ function pushbutton_adderpfile_Callback(hObject, eventdata, handles) [erpfname, erppathname, findex] = uigetfile({'*.txt','Universal text format(*.txt)'; ... - '*.*', 'All Files (*.*)'}, ... - 'Select an edited file', ... - 'MultiSelect', 'on'); + '*.*', 'All Files (*.*)'}, ... + 'Select an edited file', ... + 'MultiSelect', 'on'); if isequal(erpfname,0) - disp('User selected Cancel') - return + disp('User selected Cancel') + return else - iniftype = handles.iniftype; - if ~isempty(iniftype) - if findex~= iniftype - fprintf('\nWARNING: You are putting together different formats of averaged files.\n\n') - end - else - handles.iniftype = findex; - end - - - if ~iscell(erpfname) - erpfname = {erpfname}; - end - - nerpn = length(erpfname); - - for i=1:nerpn - - newline = fullfile(erppathname, erpfname{i}); % new member - currline = get(handles.listbox_erpnames, 'Value'); % current position at the list - fulltext = get(handles.listbox_erpnames, 'String'); % current list - indxline = length(fulltext); % last line (virtual) - - if currline==indxline % is the current line the last line? - % extra line forward - fulltext = cat(1, fulltext, {'new erpset'}); - set(handles.listbox_erpnames, 'Value', currline+1) - else - set(handles.listbox_erpnames, 'Value', currline) - resto = fulltext(currline:indxline); - fulltext = cat(1, fulltext, {'new erpset'}); - set(handles.listbox_erpnames, 'Value', currline+1) - [fulltext{currline+1:indxline+1}] = resto{:}; - end - - fulltext{currline} = sprintf('Bin %g\t@\t%s',currline, newline); - set(handles.listbox_erpnames, 'String', fulltext) - end - - indxline = length(fulltext); - handles.indxline = indxline; - handles.fulltext = fulltext; - handles.listname = []; - %set(handles.edit_filelist,'String',''); - % Update handles structure - guidata(hObject, handles); + iniftype = handles.iniftype; + if ~isempty(iniftype) + if findex~= iniftype + fprintf('\nWARNING: You are putting together different formats of averaged files.\n\n') + end + else + handles.iniftype = findex; + end + + + if ~iscell(erpfname) + erpfname = {erpfname}; + end + + nerpn = length(erpfname); + + for i=1:nerpn + + newline = fullfile(erppathname, erpfname{i}); % new member + currline = get(handles.listbox_erpnames, 'Value'); % current position at the list + fulltext = get(handles.listbox_erpnames, 'String'); % current list + indxline = length(fulltext); % last line (virtual) + + if currline==indxline % is the current line the last line? + % extra line forward + fulltext = cat(1, fulltext, {'new erpset'}); + set(handles.listbox_erpnames, 'Value', currline+1) + else + set(handles.listbox_erpnames, 'Value', currline) + resto = fulltext(currline:indxline); + fulltext = cat(1, fulltext, {'new erpset'}); + set(handles.listbox_erpnames, 'Value', currline+1) + [fulltext{currline+1:indxline+1}] = resto{:}; + end + + fulltext{currline} = sprintf('Bin %g\t@\t%s',currline, newline); + set(handles.listbox_erpnames, 'String', fulltext) + end + + indxline = length(fulltext); + handles.indxline = indxline; + handles.fulltext = fulltext; + handles.listname = []; + %set(handles.edit_filelist,'String',''); + % Update handles structure + guidata(hObject, handles); end % ------------------------------------------------------------------------- @@ -213,32 +233,32 @@ function pushbutton_delerpset_Callback(hObject, eventdata, handles) currline = get(handles.listbox_erpnames, 'Value'); % current pos if currline>=1 && currline1 - fulltext = regexprep(fulltext,'Bin.*?@','', 'ignorecase'); - fulltext = strtrim(fulltext); - - for i=1:nfile-1; - fulltext{i} = sprintf('Bin %g\t@\t%s',i, fulltext{i}); - end - else - handles.iniftype = []; - end - - set(handles.listbox_erpnames, 'String', fulltext); - listbox_erpnames_Callback(hObject, eventdata, handles) - - handles.fulltext = fulltext; - %indxline = length(fulltext); - %handles.listname = []; - %set(handles.edit_filelist,'String',''); - - % Update handles structure - %guidata(hObject, handles); + + fulltext(currline,:) = []; + fulltext = cellstr(fulltext); % cell string + nfile = length(fulltext); + + if nfile>1 + fulltext = regexprep(fulltext,'Bin.*?@','', 'ignorecase'); + fulltext = strtrim(fulltext); + + for i=1:nfile-1; + fulltext{i} = sprintf('Bin %g\t@\t%s',i, fulltext{i}); + end + else + handles.iniftype = []; + end + + set(handles.listbox_erpnames, 'String', fulltext); + listbox_erpnames_Callback(hObject, eventdata, handles) + + handles.fulltext = fulltext; + %indxline = length(fulltext); + %handles.listname = []; + %set(handles.edit_filelist,'String',''); + + % Update handles structure + %guidata(hObject, handles); end % ------------------------------------------------------------------------- @@ -249,27 +269,27 @@ function pushbutton_up_Callback(hObject, eventdata, handles) currline = get(handles.listbox_erpnames, 'Value'); % current pos if currline>1 && currline=1 && currline1 - msgboxText = 'You must specify a unique value for sampling rate in Hz'; - title = 'ERPLAB: importerpGUI() -> wrong input'; - errorfound(sprintf(msgboxText), title); - return - end - if srate<=0 - msgboxText = 'You must specify a positive integer (no zero) value for sampling rate in Hz'; - title = 'ERPLAB: importerpGUI() -> wrong input'; - errorfound(sprintf(msgboxText), title); - return - end + if numel(srate)>1 + msgboxText = 'You must specify a unique value for sampling rate in Hz'; + title = 'ERPLAB: importerpGUI() -> wrong input'; + errorfound(sprintf(msgboxText), title); + return + end + if srate<=0 + msgboxText = 'You must specify a positive integer (no zero) value for sampling rate in Hz'; + title = 'ERPLAB: importerpGUI() -> wrong input'; + errorfound(sprintf(msgboxText), title); + return + end end if ~isempty(xlim) - if numel(xlim)~=2 - msgboxText = 'You must specify two values for time range [xmin xmax] in msec'; - title = 'ERPLAB: importerpGUI() -> wrong input'; - errorfound(sprintf(msgboxText), title); - return - end - if xlim(1)>=xlim(2) - msgboxText = ['Time range is incorrect.\n'... - 'xmin must be lesser than xmax']; - title = 'ERPLAB: importerpGUI() -> wrong input'; - errorfound(sprintf(msgboxText), title); - return - end - if xlim(1)>0 || xlim(2)<0 - msgboxText = 'time zero must be included within the time range.'; - title = 'ERPLAB: importerpGUI() -> wrong input'; - errorfound(sprintf(msgboxText), title); - return - end + if numel(xlim)~=2 + msgboxText = 'You must specify two values for time range [xmin xmax] in msec'; + title = 'ERPLAB: importerpGUI() -> wrong input'; + errorfound(sprintf(msgboxText), title); + return + end + if xlim(1)>=xlim(2) + msgboxText = ['Time range is incorrect.\n'... + 'xmin must be lesser than xmax']; + title = 'ERPLAB: importerpGUI() -> wrong input'; + errorfound(sprintf(msgboxText), title); + return + end + if xlim(1)>0 || xlim(2)<0 + msgboxText = 'time zero must be included within the time range.'; + title = 'ERPLAB: importerpGUI() -> wrong input'; + errorfound(sprintf(msgboxText), title); + return + end end handles.output = {filename pathname filetype istime tunit iselabel transpose srate xlim}; @@ -416,7 +436,7 @@ function edit1_Callback(hObject, eventdata, handles) function edit1_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) - set(hObject,'BackgroundColor','white'); + set(hObject,'BackgroundColor','white'); end % ------------------------------------------------------------------------- @@ -426,7 +446,7 @@ function edit2_Callback(hObject, eventdata, handles) function edit2_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) - set(hObject,'BackgroundColor','white'); + set(hObject,'BackgroundColor','white'); end % ------------------------------------------------------------------------- @@ -435,43 +455,43 @@ function pushbutton_CL_Callback(hObject, eventdata, handles) fulltext = get(handles.listbox_erpnames, 'String'); % current list indxline = length(fulltext); % last line -if indxline>1 - BackERPLABcolor = [1 0.9 0.3]; % yellow - question = ['Current list will be deleted.\n\n'... - 'Are you sure?']; - title = 'List of averaged files for importing'; - oldcolor = get(0,'DefaultUicontrolBackgroundColor'); - set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) - button = questdlg(sprintf(question), title,'Cancel','Yes', 'Cancel'); - set(0,'DefaultUicontrolBackgroundColor',oldcolor) - - if ~strcmpi(button,'Yes') - return - end - - set(handles.listbox_erpnames, 'Value', 1); - set(handles.listbox_erpnames, 'String', {'new erpset'}); - handles.fulltext = []; - handles.iniftype = []; - - % Update handles structure - guidata(hObject, handles); +if indxline>1 + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Current list will be deleted.\n\n'... + 'Are you sure?']; + title = 'List of averaged files for importing'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','Yes', 'Cancel'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if ~strcmpi(button,'Yes') + return + end + + set(handles.listbox_erpnames, 'Value', 1); + set(handles.listbox_erpnames, 'String', {'new erpset'}); + handles.fulltext = []; + handles.iniftype = []; + + % Update handles structure + guidata(hObject, handles); end % ------------------------------------------------------------------------- function radiobutton_er_pc_Callback(hObject, eventdata, handles) if get(hObject,'Value') - set(handles.radiobutton_pr_ec,'value', 0) + set(handles.radiobutton_pr_ec,'value', 0) else - set(handles.radiobutton_er_pc,'value', 1) + set(handles.radiobutton_er_pc,'value', 1) end % ------------------------------------------------------------------------- function radiobutton_pr_ec_Callback(hObject, eventdata, handles) if get(hObject,'Value') - set(handles.radiobutton_er_pc,'value', 0) + set(handles.radiobutton_er_pc,'value', 0) else - set(handles.radiobutton_pr_ec,'value', 1) + set(handles.radiobutton_pr_ec,'value', 1) end % ------------------------------------------------------------------------- @@ -481,19 +501,19 @@ function checkbox_elabels_Callback(hObject, eventdata, handles) function checkbox_time_Callback(hObject, eventdata, handles) if get(hObject,'Value') - %set(handles.edit_srate,'Enable','off') - %set(handles.edit_xlim,'Enable','off') - set(handles.radiobutton_time_sec,'Enable','on') - set(handles.radiobutton_time_msec,'Enable','on') - set(handles.edit_srate, 'Enable', 'off') - set(handles.edit_xlim, 'Enable', 'off') + %set(handles.edit_srate,'Enable','off') + %set(handles.edit_xlim,'Enable','off') + set(handles.radiobutton_time_sec,'Enable','on') + set(handles.radiobutton_time_msec,'Enable','on') + set(handles.edit_srate, 'Enable', 'off') + set(handles.edit_xlim, 'Enable', 'off') else - %set(handles.edit_srate,'Enable','on') - %set(handles.edit_xlim,'Enable','on') - set(handles.radiobutton_time_sec,'Enable','off') - set(handles.radiobutton_time_msec,'Enable','off') - set(handles.edit_srate, 'Enable', 'on') - set(handles.edit_xlim, 'Enable', 'on') + %set(handles.edit_srate,'Enable','on') + %set(handles.edit_xlim,'Enable','on') + set(handles.radiobutton_time_sec,'Enable','off') + set(handles.radiobutton_time_msec,'Enable','off') + set(handles.edit_srate, 'Enable', 'on') + set(handles.edit_xlim, 'Enable', 'on') end % ------------------------------------------------------------------------- @@ -520,17 +540,17 @@ function edit_xlim_CreateFcn(hObject, eventdata, handles) function radiobutton_time_sec_Callback(hObject, eventdata, handles) if get(hObject,'Value') - set(handles.radiobutton_time_msec,'value',0) + set(handles.radiobutton_time_msec,'value',0) else - set(handles.radiobutton_time_sec,'value',1) + set(handles.radiobutton_time_sec,'value',1) end % ------------------------------------------------------------------------- function radiobutton_time_msec_Callback(hObject, eventdata, handles) if get(hObject,'Value') - set(handles.radiobutton_time_sec,'value',0) + set(handles.radiobutton_time_sec,'value',0) else - set(handles.radiobutton_time_msec,'value',1) + set(handles.radiobutton_time_msec,'value',1) end % ------------------------------------------------------------------------- @@ -541,25 +561,25 @@ function pushbutton_take_a_look_Callback(hObject, eventdata, handles) currline = get(handles.listbox_erpnames, 'Value'); % current pos if currline>=1 && currline1 - - fullname = savelist(hObject, eventdata, handles); - - if isempty(fullname) - return - end - - set(handles.edit5, 'String', fullname ) - set(handles.button_savelist, 'Enable', 'on') - handles.listname = fullname; - % Update handles structure - guidata(hObject, handles); -else - set(handles.button_savelistas,'Enable','off') - msgboxText = 'You have not specified any erpset!'; - title = 'ERPLAB: averager GUI few inputs'; - errorfound(msgboxText, title); - set(handles.button_savelistas,'Enable','on') + + fullname = savelist(hObject, eventdata, handles); + + if isempty(fullname) return + end + + set(handles.edit5, 'String', fullname ) + set(handles.button_savelist, 'Enable', 'on') + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); +else + set(handles.button_savelistas,'Enable','off') + msgboxText = 'You have not specified any erpset!'; + title = 'ERPLAB: averager GUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_savelistas,'Enable','on') + return end %-------------------------------------------------------------------------- @@ -615,32 +635,32 @@ function button_savelistas_Callback(hObject, eventdata, handles) [filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save erpset list as', pre_fname); if isequal(filename,0) - disp('User selected Cancel') - fullname =[]; - return + disp('User selected Cancel') + fullname =[]; + return else + + [px, fname, ext] = fileparts(filename); + + if strcmp(ext,'') - [px, fname, ext] = fileparts(filename); - - if strcmp(ext,'') - - if filterindex==1 || filterindex==3 - ext = '.txt'; - else - ext = '.dat'; - end - end - - fname = [ fname ext]; - fullname = fullfile(filepath, fname); - disp(['For saving erpset list, user selected ' fullname '']) - fid_list = fopen( fullname , 'w'); - - for i=1:size(fulltext,1)-1 - fprintf(fid_list,'%s\n', fulltext(i,:)); + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; end - - fclose(fid_list); + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + disp(['For saving erpset list, user selected ' fullname '']) + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1)-1 + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); end % ------------------------------------------------------------------------- @@ -648,59 +668,59 @@ function button_savelist_Callback(hObject, eventdata, handles) fulltext = char(strtrim(get(handles.listbox_erpnames,'String'))); if length(fulltext)>1 + + fullname = get(handles.edit5, 'String'); + + if ~strcmp(fullname,'') - fullname = get(handles.edit5, 'String'); + fid_list = fopen( fullname , 'w'); - if ~strcmp(fullname,'') - - fid_list = fopen( fullname , 'w'); - - for i=1:size(fulltext,1) - fprintf(fid_list,'%s\n', fulltext(i,:)); - end - - fclose(fid_list); - handles.listname = fullname; - - % Update handles structure - guidata(hObject, handles); - disp(['Saving equation list at ' fullname '']) - else - button_savelistas_Callback(hObject, eventdata, handles) - return + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); end -else - set(handles.button_savelistas,'Enable','off') - msgboxText = 'You have not written any formula yet!'; - title = 'ERPLAB: chanoperGUI few inputs'; - errorfound(msgboxText, title); - set(handles.button_savelistas,'Enable','on') + + fclose(fid_list); + handles.listname = fullname; + + % Update handles structure + guidata(hObject, handles); + disp(['Saving equation list at ' fullname '']) + else + button_savelistas_Callback(hObject, eventdata, handles) return + end +else + set(handles.button_savelistas,'Enable','off') + msgboxText = 'You have not written any formula yet!'; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_savelistas,'Enable','on') + return end % ------------------------------------------------------------------------- function button_loadlist_Callback(hObject, eventdata, handles, optionx) if nargin<4 - optionx=0; + optionx=0; end if optionx==0 - [listname, lispath] = uigetfile({ '*.txt','Text File (*.txt)'; ... - '*.*', 'All Files (*.*)'}, ... - 'Select an edited list', ... - 'MultiSelect', 'off'); - - if isequal(listname,0) - disp('User selected Cancel') - return - else - fullname = fullfile(lispath, listname); - disp(['For erpset list user selected ' fullname '']) - end + [listname, lispath] = uigetfile({ '*.txt','Text File (*.txt)'; ... + '*.*', 'All Files (*.*)'}, ... + 'Select an edited list', ... + 'MultiSelect', 'off'); + + if isequal(listname,0) + disp('User selected Cancel') + return + else + fullname = fullfile(lispath, listname); + disp(['For erpset list user selected ' fullname '']) + end else - fullname = handles.erpset; - if isnumeric(fullname) - fullname = ''; - end + fullname = handles.erpset; + if isnumeric(fullname) + fullname = ''; + end end fid_list = fopen( fullname ); @@ -712,22 +732,22 @@ function button_loadlist_Callback(hObject, eventdata, handles, optionx) fclose(fid_list); if lentext>1 - set(handles.listbox_erpnames,'String',lista); - set(handles.edit5,'String',fullname); - handles.listname = fullname; - set(handles.button_savelist, 'Enable','on') - - % Update handles structure - guidata(hObject, handles); + set(handles.listbox_erpnames,'String',lista); + set(handles.edit5,'String',fullname); + handles.listname = fullname; + set(handles.button_savelist, 'Enable','on') + + % Update handles structure + guidata(hObject, handles); else - msgboxText = 'This list is empty!'; - title = 'ERPLAB: geterpvaluesGUI inputs'; - errorfound(msgboxText, title); - handles.listname = []; - set(handles.button_savelist, 'Enable','off') - - % Update handles structure - guidata(hObject, handles); + msgboxText = 'This list is empty!'; + title = 'ERPLAB: geterpvaluesGUI inputs'; + errorfound(msgboxText, title); + handles.listname = []; + set(handles.button_savelist, 'Enable','off') + + % Update handles structure + guidata(hObject, handles); end set(handles.listbox_erpnames,'String',lista); @@ -747,12 +767,12 @@ function edit5_CreateFcn(hObject, eventdata, handles) function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') - %The GUI is still in UIWAIT, us UIRESUME - handles.output = []; - %Update handles structure - guidata(hObject, handles); - uiresume(handles.gui_chassis); + %The GUI is still in UIWAIT, us UIRESUME + handles.output = []; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); else - % The GUI is no longer waiting, just close it - delete(handles.gui_chassis); + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); end diff --git a/GUIs/splinefileGUI.fig b/GUIs/splinefileGUI.fig index 413485aa..eb00ff4c 100755 Binary files a/GUIs/splinefileGUI.fig and b/GUIs/splinefileGUI.fig differ diff --git a/GUIs/splinefileGUI.m b/GUIs/splinefileGUI.m index 8b09c913..97172674 100755 --- a/GUIs/splinefileGUI.m +++ b/GUIs/splinefileGUI.m @@ -3,15 +3,15 @@ % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... - 'gui_Singleton', gui_Singleton, ... - 'gui_OpeningFcn', @splinefileGUI_OpeningFcn, ... - 'gui_OutputFcn', @splinefileGUI_OutputFcn, ... - 'gui_LayoutFcn', [] , ... - 'gui_Callback', []); + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @splinefileGUI_OpeningFcn, ... + 'gui_OutputFcn', @splinefileGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); if nargin && ischar(varargin{1}) - if ~isempty(varargin{1}) - gui_State.gui_Callback = str2func(varargin{1}); - end + if ~isempty(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); + end end if nargout @@ -25,18 +25,39 @@ % --- Executes just before splinefileGUI is made visible. function splinefileGUI_OpeningFcn(hObject, eventdata, handles, varargin) + handles.output = []; try - splinefile = varargin{1}; - splinefile = splinefile{:}; + splinefile = varargin{1}; + splinefile = splinefile{:}; +catch + splinefile = ''; +end + +try + ERP = varargin{2};%%GH 2022 catch - splinefile = ''; + ERP = {}; + end -if isempty(splinefile) - mainmsg = 'Your ERPset does not have a spline file info.\n A spline file is needed for 3d plotting.'; +try + erpname = ERP.erpname; +catch + erpname = ''; +end +if ~isempty(erpname) + if isempty(splinefile) + mainmsg = ['#',erpname,32,' does not have a spline file info.\n A spline file is needed for 3d plotting.'];%% GH 2022 + else + mainmsg = ['Load a spline file for 3d plotting for #', erpname];%%GH 2022 + end else - mainmsg = 'Load a spline file for 3d plotting.'; + if isempty(splinefile) + mainmsg = [' Current ERPset does not have a spline file info.\n A spline file is needed for 3d plotting.'];%% GH 2022 + else + mainmsg = ['Load a spline file for 3d plotting.'];%%GH 2022 + end end set(handles.text_main, 'String', sprintf(mainmsg)) set(handles.edit_splinepath, 'String', splinefile) @@ -47,12 +68,40 @@ function splinefileGUI_OpeningFcn(hObject, eventdata, handles, varargin) % % Color GUI % -handles = painterplab(handles); +% handles = painterplab(handles); +% +% % +% % Set font size +% % +% handles = setfonterplab(handles); +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + else + Toolabel = 0; + end +else + Toolabel = 1; +end + +if Toolabel +% erplab_studio_default_values; +% version = erplabstudiover; +% set(handles.gui_chassis,'Name', ['EStudio',version,' - Bin Operation > Advanced GUI for ']) + handles = painterplabstudio(handles); + handles = setfonterplabestudio(handles); +% handles.RUN.String = 'OK'; +else + +% version = geterplabversion; +% set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - Bin Operation GUI ']) + % + handles = painterplab(handles); + + handles = setfonterplab(handles); +end -% -% Set font size -% -handles = setfonterplab(handles); % Update handles structure guidata(hObject, handles); @@ -74,25 +123,25 @@ function splinefileGUI_OpeningFcn(hObject, eventdata, handles, varargin) %-------------------------------------------------------------------------- function radiobutton_path_Callback(hObject, eventdata, handles) if get(hObject, 'Value') - set(handles.radiobutton_newspline, 'Value', 0); - set(handles.edit_splinepath, 'Enable', 'on'); - set(handles.pushbutton_browse, 'Enable', 'on'); - set(handles.edit_saveas, 'Enable', 'off'); - set(handles.pushbutton_browse_saves_as, 'Enable', 'off'); + set(handles.radiobutton_newspline, 'Value', 0); + set(handles.edit_splinepath, 'Enable', 'on'); + set(handles.pushbutton_browse, 'Enable', 'on'); + set(handles.edit_saveas, 'Enable', 'off'); + set(handles.pushbutton_browse_saves_as, 'Enable', 'off'); else - set(hObject, 'Value', 1) + set(hObject, 'Value', 1) end %-------------------------------------------------------------------------- function radiobutton_newspline_Callback(hObject, eventdata, handles) if get(hObject, 'Value') - set(handles.radiobutton_path, 'Value', 0); - set(handles.edit_splinepath, 'Enable', 'off'); - set(handles.pushbutton_browse, 'Enable', 'off'); - set(handles.edit_saveas, 'Enable', 'on'); - set(handles.pushbutton_browse_saves_as, 'Enable', 'on'); + set(handles.radiobutton_path, 'Value', 0); + set(handles.edit_splinepath, 'Enable', 'off'); + set(handles.pushbutton_browse, 'Enable', 'off'); + set(handles.edit_saveas, 'Enable', 'on'); + set(handles.pushbutton_browse_saves_as, 'Enable', 'on'); else - set(hObject, 'Value', 1) + set(hObject, 'Value', 1) end %-------------------------------------------------------------------------- @@ -115,44 +164,44 @@ function pushbutton_browse_Callback(hObject, eventdata, handles) [blfilename, blpathname, filterindex] = uigetfile({'*.*'},'Load spline file '); if isequal(blfilename,0) - disp('User selected Cancel') - return + disp('User selected Cancel') + return else - [px, fname, ext] = fileparts(blfilename); - fname = [ fname ext]; - fullsplinename = fullfile(blpathname, fname); - set(handles.edit_splinepath,'String', fullsplinename); - disp(['Spline file will be loaded from ' fullsplinename]) + [px, fname, ext] = fileparts(blfilename); + fname = [ fname ext]; + fullsplinename = fullfile(blpathname, fname); + set(handles.edit_splinepath,'String', fullsplinename); + disp(['Spline file will be loaded from ' fullsplinename]) end %-------------------------------------------------------------------------- function pushbutton_OK_Callback(hObject, eventdata, handles) if get(handles.radiobutton_path, 'Value') - splineinfo.path = get(handles.edit_splinepath,'String'); - splineinfo.new = 0; - %splineinfo.newname = []; + splineinfo.path = get(handles.edit_splinepath,'String'); + splineinfo.new = 0; + %splineinfo.newname = []; else - if get(handles.radiobutton_newspline, 'Value') - splineinfo.path = get(handles.edit_saveas,'String'); - splineinfo.new = 1; - %splineinfo.newname = get(handles.edit_saveas,'String'); - else - splineinfo.path = []; - splineinfo.new = []; - %splineinfo.newname = []; - end -end -if isempty(splineinfo.path) - msgboxText = 'You must specify a name for the spline file.'; - title = 'ERPLAB: spline file for 3D maps'; - errorfound(msgboxText, title); - return + if get(handles.radiobutton_newspline, 'Value') + splineinfo.path = get(handles.edit_saveas,'String'); + splineinfo.new = 1; + %splineinfo.newname = get(handles.edit_saveas,'String'); + else + splineinfo.path = []; + splineinfo.new = []; + %splineinfo.newname = []; + end +end +if isempty(splineinfo.path) + msgboxText = 'You must specify a name for the spline file.'; + title = 'ERPLAB: spline file for 3D maps'; + errorfound(msgboxText, title); + return end if get(handles.checkbox_savespline, 'Value') - splineinfo.save = 1; + splineinfo.save = 1; else - splineinfo.save = 0; + splineinfo.save = 0; end handles.output = splineinfo; @@ -180,13 +229,13 @@ function pushbutton_cancel_Callback(hObject, eventdata, handles) function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') - handles.output = []; - %Update handles structure - guidata(hObject, handles); - uiresume(handles.gui_chassis); + handles.output = []; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); else - % The GUI is no longer waiting, just close it - delete(handles.gui_chassis); + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); end %-------------------------------------------------------------------------- @@ -208,11 +257,11 @@ function pushbutton_browse_saves_as_Callback(hObject, eventdata, handles) [blfilename, blpathname, filterindex] = uiputfile({'*.*'},'Save new spline file as ', prename); if isequal(blfilename,0) - disp('User selected Cancel') - return + disp('User selected Cancel') + return else - [px, fname, ext] = fileparts(blfilename); - fname = [ fname ext]; - fullsplinename = fullfile(blpathname, fname); - set(handles.edit_saveas,'String', fullsplinename); + [px, fname, ext] = fileparts(blfilename); + fname = [ fname ext]; + fullsplinename = fullfile(blpathname, fname); + set(handles.edit_saveas,'String', fullsplinename); end diff --git a/README.md b/README.md old mode 100644 new mode 100755 index a38ffdf3..963c024b --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ERPLAB Toolbox is a free, open-source Matlab package for analyzing ERP data. It is tightly integrated with [EEGLAB Toolbox](http://sccn.ucsd.edu/eeglab/), extending EEGLAB’s capabilities to provide robust, industrial-strength tools for ERP processing, visualization, and analysis. A graphical user interface makes it easy for beginners to learn, and Matlab scripting provides enormous power for intermediate and advanced users. Click the Wiki icon at the top of the page for documentation, tutorials, and FAQs. -## ERPLAB v9.10 +## ERPLAB v9.20

@@ -11,7 +11,7 @@ ERPLAB Toolbox is a free, open-source Matlab package for analyzing ERP data. It

-To install ERPLAB v9.10, download the zip file (linked above), unzip and place the folder in the 'plugins' folder of your existing [EEGLAB](https://sccn.ucsd.edu/eeglab/download.php) installation (e.g. `/Users/Steve/Documents/MATLAB/eeglab2019_1/plugins/erplab/`). More [installation help can be found here](https://github.com/lucklab/erplab/wiki/Installation). +To install ERPLAB v9.20, download the zip file (linked above), unzip and place the folder in the 'plugins' folder of your existing [EEGLAB](https://sccn.ucsd.edu/eeglab/download.php) installation (e.g. `/Users/Steve/Documents/MATLAB/eeglab2019_1/plugins/erplab/`). More [installation help can be found here](https://github.com/lucklab/erplab/wiki/Installation). To run ERPLAB, ensure that the correct EEGLAB folder is in your current Matlab path, and run `eeglab` as a command from the Matlab Command Window. [Find our tutorial here.](https://github.com/lucklab/erplab/wiki/Tutorial) @@ -54,6 +54,18 @@ ERPLAB should work with most modern OSs, Matlab versions, and EEGLAB releases. L ## Release Notes + +## ERPLABv9.20 Release Notes +Now Includes: +Create Artificial Waveform Viewer routine: Users can simulate a variety of waveforms to be saved as ERP files (.erp). See documentation [here](https://github.com/lucklab/erplab/wiki/Create-an-Artificial-ERP-Waveform). + +New options for adding noise to data via EEG and ERP channel operations (see [here](https://github.com/lucklab/erplab/wiki/EEG-and-ERP-Channel-Operations#example-of-adding-simulated-noise)). + +Users may now shift string event codes in time in addtion to numeric event codes (see Preprocess EEG > Shift Event Codes (continuous EEG)). + +Various bug fixes across ERPLAB. + + ### ERPLAB v9.10 Release Notes Now includes: Updated Data Quality (DQ) metrics specifications on averaged ERP waveforms, including a new metric: SD across trials. diff --git a/eegplugin_erplab.m b/eegplugin_erplab.m old mode 100644 new mode 100755 index 4c03338a..4c17d863 --- a/eegplugin_erplab.m +++ b/eegplugin_erplab.m @@ -1,9 +1,10 @@ -% Author: Andrew X Stewart, Javier Lopez-Calderon & Steven Luck +% Author: Guanghui Zhang, Aaron Matthew Simmons, +% Andrew X Stewart, Javier Lopez-Calderon & Steven Luck % Center for Mind and Brain % University of California, Davis, % Davis, CA % 2007-2020 -% Version 9.10 +% Version 9.20 %b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b % @@ -28,11 +29,12 @@ function currvers = eegplugin_erplab(fig, trystrs, catchstrs) -erplab_default_values % script -currvers = ['erplab' erplabver]; + + + if nargin < 3 - error('eegplugin_erplab requires 3 arguments'); + error('eegplugin_erplab requires 3 arguments'); end % @@ -40,7 +42,7 @@ % p = which('eegplugin_erplab','-all'); if length(p)>1 - fprintf('\nERPLAB WARNING: More than one ERPLAB folder was found.\n\n'); + fprintf('\nERPLAB WARNING: More than one ERPLAB folder was found.\n\n'); end p = p{1}; p = p(1:findstr(p,'eegplugin_erplab.m')-1); @@ -48,6 +50,31 @@ addpath(genpath(p)) + +try + clearvars observe_ERPDAT; + clearvars v_ERPDAT; +catch +end + +erplab_default_values % script +currvers = ['erplab' erplabver]; + +erplab_running_version('Version',erplabver,'tooltype','ERPLAB');%%GH,Mar 2023 +%global needed for ERPLAB viewer +global observe_ERPDAT; +observe_ERPDAT = o_ERPDAT; +observe_ERPDAT.Two_GUI = 0; +observe_ERPDAT.ALLERP = []; +observe_ERPDAT.CURRENTERP = []; +observe_ERPDAT.ERP = []; +observe_ERPDAT.Count_ERP = 0; +observe_ERPDAT.Count_currentERP = 0; +observe_ERPDAT.Process_messg = 0;%%change end + + + + % % CHECK VERSION NUMBER & FOLDER NAME % Grab the end of the path, like '7.0' @@ -70,19 +97,19 @@ % CHECK EEGLAB Version % if exist('memoryerp.erpm','file')==2 - iserpmem = 1; % file for memory exists + iserpmem = 1; % file for memory exists else - iserpmem = 0; % does not exist file for memory + iserpmem = 0; % does not exist file for memory end egv = regexp(eeg_getversion,'^(\d+)\.+','tokens','ignorecase'); eegversion = str2num(char(egv{:})); check_matlab_version; if eegversion==11 - if iserpmem==1 - warning('ERPLAB:Warning', 'ERPLAB is not compatible with EEGLAB 11. Please try either a newer or an older version of EEGLAB.') - else - warndlg(sprintf('ERPLAB is not compatible with EEGLAB 11.\nPlease try either a newer or an older version of EEGLAB.'),'!! Warning !!', 'modal') - end + if iserpmem==1 + warning('ERPLAB:Warning', 'ERPLAB is not compatible with EEGLAB 11. Please try either a newer or an older version of EEGLAB.') + else + warndlg(sprintf('ERPLAB is not compatible with EEGLAB 11.\nPlease try either a newer or an older version of EEGLAB.'),'!! Warning !!', 'modal') + end end % @@ -93,13 +120,13 @@ filenames = {filst.name}; if length(filenames)>3 % '.' '..' 'erplab_box_readme.md' - recycle on; - delete(fullfile(dirBox,'*')) - fprintf('\nERPLAB WARNING: Temporary files (from your last session) within erplab_Box folder were sent to recycle bin.\n\n') - - file_id = fopen(fullfile(dirBox, 'erplab_box_readme.md'), 'w'); - fprintf(file_id, 'This is a placeholder file, so that git does not delete the `erplab_Box` folder.'); - fclose(file_id); + recycle on; + delete(fullfile(dirBox,'*')) + fprintf('\nERPLAB WARNING: Temporary files (from your last session) within erplab_Box folder were sent to recycle bin.\n\n') + + file_id = fopen(fullfile(dirBox, 'erplab_box_readme.md'), 'w'); + fprintf(file_id, 'This is a placeholder file, so that git does not delete the `erplab_Box` folder.'); + fclose(file_id); end % @@ -108,52 +135,51 @@ % Check erpmem version matches current version if iserpmem - oldmem = load(fullfile(p,'memoryerp.erpm'), '-mat'); - memver = oldmem.erplabver; - if strcmp(memver,erplabver) == 0 - disp('Updating erpmem with current version number') - mshock = oldmem.mshock; - save(fullfile(p,'memoryerp.erpm'),'erplabrel','erplabver','ColorB','ColorF','errorColorB', 'errorColorF','fontsizeGUI','fontunitsGUI','mshock'); - end + oldmem = load(fullfile(p,'memoryerp.erpm'), '-mat'); + memver = oldmem.erplabver; + if strcmp(memver,erplabver) == 0 + disp('Updating erpmem with current version number') + mshock = oldmem.mshock; + save(fullfile(p,'memoryerp.erpm'),'erplabrel','erplabver','ColorB','ColorF','errorColorB', 'errorColorF','fontsizeGUI','fontunitsGUI','mshock'); + end end if iserpmem==0 - mshock = 0; - try - % saves memory file - % - % IMPORTANT: If this file (saved variables inside memoryerp.erpm) is modified then also must be modified the same line at erplabamnesia.m - % - save(fullfile(p,'memoryerp.erpm'),'erplabrel','erplabver','ColorB','ColorF','errorColorB', 'errorColorF','fontsizeGUI','fontunitsGUI','mshock'); - catch - % saves memory variable at workspace - msgboxText = ['\nERPLAB could not find a file for storing its GUI memory or \n'... - 'does not have permission for writting on it.\n\n'... - 'Therefore, ERPLAB''s memory will be stored at Matlab''s workspace and will last 1 session.\n\n']; - - % message on command window - fprintf('%s\n', repmat('*',1,50)); - fprintf('"Houston, we''ve had a problem here": \n %s\n', sprintf(msgboxText)); - bottomline = 'If you think this is a bug, please report the error to erplabtoolbox@gmail.com and not to the EEGLAB developers.'; - disp(bottomline) - fprintf('%s\n', repmat('*',1,50)); - - % - % IMPORTANT: If this strucure (vmemoryerp) is modified then also must be modified the same line at erplabamnesia.m - % - vmemoryerp = struct('erplabrel',erplabrel,'erplabver',erplabver,'ColorB',ColorB,'ColorF',ColorF,'fontsizeGUI',fontsizeGUI,... - 'fontunitsGUI',fontunitsGUI,'mshock',mshock, 'errorColorF', errorColorF, 'errorColorB', errorColorB); - assignin('base','vmemoryerp',vmemoryerp); - end + mshock = 0; + try + % saves memory file + % + % IMPORTANT: If this file (saved variables inside memoryerp.erpm) is modified then also must be modified the same line at erplabamnesia.m + % + save(fullfile(p,'memoryerp.erpm'),'erplabrel','erplabver','ColorB','ColorF','errorColorB', 'errorColorF','fontsizeGUI','fontunitsGUI','mshock'); + catch + % saves memory variable at workspace + msgboxText = ['\nERPLAB could not find a file for storing its GUI memory or \n'... + 'does not have permission for writting on it.\n\n'... + 'Therefore, ERPLAB''s memory will be stored at Matlab''s workspace and will last 1 session.\n\n']; + + % message on command window + fprintf('%s\n', repmat('*',1,50)); + fprintf('"Houston, we''ve had a problem here": \n %s\n', sprintf(msgboxText)); + bottomline = 'If you think this is a bug, please report the error to erplabtoolbox@gmail.com and not to the EEGLAB developers.'; + disp(bottomline) + fprintf('%s\n', repmat('*',1,50)); + + % + % IMPORTANT: If this strucure (vmemoryerp) is modified then also must be modified the same line at erplabamnesia.m + % + vmemoryerp = struct('erplabrel',erplabrel,'erplabver',erplabver,'ColorB',ColorB,'ColorF',ColorF,'fontsizeGUI',fontsizeGUI,... + 'fontunitsGUI',fontunitsGUI,'mshock',mshock, 'errorColorF', errorColorF, 'errorColorB', errorColorB); + assignin('base','vmemoryerp',vmemoryerp); + end end % % ERPLAB's VARIABLES TO WORKSPACE % + ERP = []; % Start ERP Structure on workspace -%ALLERP = []; %Start ALLERP Structure on workspace -ALLBEST = []; ALLERPCOM = []; CURRENTERP = 0; BEST = []; %Start BEST structure on workspace @@ -161,22 +187,24 @@ plotset.ptime = []; plotset.pscalp = []; plotset.pfrequ = []; -MVPA = []; +MVPC = []; +CURRENTMVPC = 0; assignin('base','ERP',ERP); -%assignin('base','ALLERP', ALLERP); -assignin('base','ALLBEST', ALLBEST); +assignin('base','BEST',BEST); +assignin('base','MVPC',MVPC); assignin('base','ALLERPCOM', ALLERPCOM); assignin('base','CURRENTERP', CURRENTERP); assignin('base','CURRENTBEST', CURRENTBEST); -assignin('base','BEST',BEST); +assignin('base','CURRENTMVPC', CURRENTMVPC); + assignin('base','plotset', plotset); -assignin('base','MVPA', MVPA); % ALLERP should be created with EEGLAB Globals in eeg_globals.m -global ALLERP -%global ALLBEST -ALLERP = []; +global ALLERP +global ALLBEST +global ALLMVPC + %--------------------------------------------------------------------------------------------------- % | % @@ -186,7 +214,7 @@ e_catch = 'catch, eeglab_error; LASTCOM= ''''; clear EEGTMP ALLEEGTMP STUDYTMP; end;'; nocheck = e_try; storeallcall = [ 'if ~isempty(ALLEEG) & ~isempty(ALLEEG(1).data), ALLEEG = eeg_checkset(ALLEEG);' ... - 'EEG = eeg_retrieve(ALLEEG, CURRENTSET); eegh(''ALLEEG = eeg_checkset(ALLEEG); EEG = eeg_retrieve(ALLEEG, CURRENTSET);''); end;' ]; + 'EEG = eeg_retrieve(ALLEEG, CURRENTSET); eegh(''ALLEEG = eeg_checkset(ALLEEG); EEG = eeg_retrieve(ALLEEG, CURRENTSET);''); end;' ]; ifeeg = 'if ~isempty(LASTCOM) & ~isempty(EEG),'; e_storeall_nh = [e_catch 'eegh(LASTCOM);' ifeeg storeallcall 'disp(''Done.''); end; eeglab(''redraw'');']; % cb_loaderplabset = [ nocheck '[ALLEEG EEG CURRENTSET LASTCOM] = pop_loadmerplabset(ALLEEG, EEG);' e_storeall_nh]; @@ -204,14 +232,14 @@ % ERPLAB NEST-MENU (ERPLAB at the EEGLAB's Main Menu) % if ispc % windows - wfactor1 = 1.20; - wfactor2 = 1.21; + wfactor1 = 1.20; + wfactor2 = 1.21; elseif ismac % Mac OSX - wfactor1 = 1.45; - wfactor2 = 1.46; + wfactor1 = 1.45; + wfactor2 = 1.46; else - wfactor1 = 1.30; - wfactor2 = 1.31; + wfactor1 = 1.30; + wfactor2 = 1.31; end posmainfig = get(gcf,'Position'); hframe = findobj('parent', gcf,'tag','Frame1'); @@ -319,14 +347,14 @@ comDQQsave = ['save_data_quality(ERP);']; comDQQprint = ['dataquality_measure = print_data_quality(ERP);']; comDQQinfo = ['erpset_summary;']; -comDQQpreavg = ['pop_DQ_preavg(ALLEEG)']; +comDQQpreavg = ['pop_DQ_preavg(ALLEEG)']; %% MVPA callbacks -%comExtractBest = ['[BEST] = pop_extractbest(ALLEEG);']; -%comSpatDecode = ['[MVPA] = pop_decoding('''');']; +%comExtractBest = ['[BEST] = pop_extractbest(ALLEEG);']; +%comSpatDecode = ['[MVPA] = pop_decoding('''');']; %comSaveBEST = ['[BEST] = pop_savemybest(BEST, ''gui'', ''saveas'');']; -%comLoadBEST = ['[BEST, ALLBEST] = pop_loadbest('''');']; +%comLoadBEST = ['[BEST, ALLBEST] = pop_loadbest('''');']; @@ -353,6 +381,7 @@ comBOP = ['[ERP, ERPCOM] = pop_binoperator(ERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; comCHOP2 = ['[ERP, ERPCOM] = pop_erpchanoperator(ERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; comPLOT = ['[ERP, ERPCOM] = pop_ploterps(ERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; +comPLOTV =['ERPLAB_ERP_Viewer(ALLERP,CURRENTERP);']; comSCALP = ['[ERP, ERPCOM] = pop_scalplot(ERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; comCHLOCTABLE= ['[ERP] = chanloc(ERP);']; comCHLOC = ['[ERP, ERPCOM] = pop_erpchanedit(ERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; @@ -382,7 +411,7 @@ comGAVG = ['[ERP, ERPCOM] = pop_gaverager(ALLERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; comERPMT = ['[ALLERP, Amp, Lat, ERPCOM] = pop_geterpvalues(ALLERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; comERPView = ['[ALLERP, Amp, Lat, ERPCOM] = pop_geterpvalues(ALLERP,[],[],[],''Erpsets'', 0,''Viewer'', ''on'');' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; - +comERPSL = ['[ERP, ERPCOM] = pop_ERP_simulation(ALLERP);' ];%'[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);' %% export figure comEXPPDF = ['[ERP, ERPCOM] = pop_exporterplabfigure(ERP);' '[ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM);']; @@ -416,16 +445,16 @@ erpverMenu = uimenu( submenu, ... 'Label' , [' *** ERPLAB v' erplabver ' ***'], ... - 'tag' , 'erpver', ... - 'separator', 'off', ... + 'tag' , 'erpver', ... + 'separator', 'off', ... 'userdata' , 'startup:off;continuous:off;epoch:off;study:off;erpset:off'); %% Continuous EEG Preprocessing Submenu preProcMenu = uimenu( submenu, ... 'Label' , 'Preprocess EEG', ... - 'tag' , 'PreprocessContinuousEEG', ... - 'separator', 'on', ... + 'tag' , 'PreprocessContinuousEEG', ... + 'separator', 'on', ... 'userdata' , [ ... 'startup:on;' ... 'continuous:on;' ... @@ -447,7 +476,7 @@ 'userdata' , preProcFunctions_userdata); % Shift Event Codes uimenu( preProcMenu, ... - 'Label' , 'Shift Event Codes (continuous EEG)', ... + 'Label' , 'Shift Event Codes (continuous EEG)', ... 'CallBack', comShiftEvents, ... 'userdata', preProcFunctions_userdata); % Delete Time Segments @@ -463,13 +492,13 @@ % Selective Electrode Interpolation uimenu( preProcMenu, ... 'Label' , 'Selective Electrode Interpolation', ... - 'CallBack', comInterpolateElectrodes, ... + 'CallBack', comInterpolateElectrodes, ... 'userdata', preProcFunctions_userdata); %Continuous Spectral EEG Data Quality uimenu( preProcMenu, ... 'Label', 'Spectral Data Quality (continuous EEG)', ... 'CallBack', comDFT, ... - 'userdata', preProcFunctions_userdata); + 'userdata', preProcFunctions_userdata); @@ -545,17 +574,17 @@ uimenu(submenu,'Label','Compute data quality metrics (without averaging)', 'CallBack', comDQQpreavg,'separator','on','userdata','startup:off;continuous:off;epoch:on;study:off;erpset:off'); -%% BIN-EPOCHED Data (BEST sets) +%% BIN-EPOCHED Data (BEST sets) %uimenu(submenu,'Label','Extract Bin-Epoched Single Trial (BEST) Data','CallBack',comExtractBest,'separator','on','userdata','startup:off;continuous:off;epoch:on;study:off;erpset:on'); -%uimenu(submenu,'Label','Save current BESTset as','CallBack',comSaveBEST,'userdata','startup:off;continuous:off;epoch:on;study:off;erpset:on'); -%uimenu(submenu,'Label','Load BEST','CallBack',comLoadBEST,'userdata','startup:on;continuous:on;epoch:on;study:off;erpset:on'); +%uimenu(submenu,'Label','Save current BESTset as','CallBack',comSaveBEST,'userdata','startup:off;continuous:off;epoch:on;study:off;erpset:on'); +%uimenu(submenu,'Label','Load BEST','CallBack',comLoadBEST,'userdata','startup:on;continuous:on;epoch:on;study:off;erpset:on'); %% Multivariate Pattern Analysis %MVPAmenu = uimenu( submenu,'Label','MVPA','separator','on','tag','MVPAset','userdata','startup:on;continuous:on;epoch:on;study:off;erpset:off'); % BESTmenu = uimenu(MVPAmenu,'Label','Currently loaded BESTsets','tag','LoadedBEST','separator','on','userdata','startup:off;continuous:off;epoch:off;study:off;erpset:off'); -%uimenu(MVPAmenu,'Label','ERP Decoding','separator','on','CallBack',comSpatDecode,'userdata','startup:on;continuous:on;epoch:on;study:off;erpset:off'); -%set(MVPAmenu, 'enable','off'); +%uimenu(MVPAmenu,'Label','ERP Decoding','separator','on','CallBack',comSpatDecode,'userdata','startup:on;continuous:on;epoch:on;study:off;erpset:off'); +%set(MVPAmenu, 'enable','off'); @@ -580,6 +609,7 @@ % mERPLOT = uimenu( submenu,'Label','Plot ERP','tag','ERPlot','separator','on','userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); uimenu( mERPLOT,'Label','Plot ERP waveforms ','CallBack', comPLOT,'userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); +% uimenu( mERPLOT,'Label','ERP Waveform Viewer ','CallBack', comPLOTV,'userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); uimenu( mERPLOT,'Label','Plot ERP scalp maps ','CallBack', comSCALP,'userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); uimenu( mERPLOT,'Label','Print plotted figure(s) to a file','CallBack', comEXPPDF,'separator','on','userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); uimenu( mERPLOT,'Label','Edit ERP channel location table','CallBack', comCHLOCTABLE,'separator','on','userdata','startup:on;continuous:on;epoch:on;study:off;erpset:on'); @@ -617,6 +647,7 @@ %% GRAND AVERAGE % uimenu( submenu,'Label','Average across ERPsets (Grand Average) ','CallBack', comGAVG,'separator','on','userdata','startup:on;continuous:on;epoch:on;study:off;erpset:on'); +uimenu( submenu,'Label','Create Artificial ERP Waveform','CallBack', comERPSL,'userdata','startup:on;continuous:on;epoch:on;study:off;erpset:on'); @@ -656,7 +687,7 @@ uimenu( mUTI,'Label','Reset event code bytes','CallBack', comRECB,'separator','on','userdata','startup:off;continuous:on;epoch:off;study:off;erpset:off'); uimenu( mUTI,'Label','Save current ERPset history for scripting','CallBack', comSaveH,'separator','on','userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); uimenu( mUTI,'Label','Find more here! (for scripting) ','CallBack','web(''https://github.com/lucklab/erplab/wiki/Scripting-Guide'',''-browser'');','separator','on',... - 'userdata','startup:on;continuous:on;epoch:on;study:on;erpset:on'); + 'userdata','startup:on;continuous:on;epoch:on;study:on;erpset:on'); uimenu( mUTI,'Label','Simulate EEG/ERP data (alpha version)','CallBack',comESIM,'separator','on' ); @@ -707,7 +738,7 @@ %set(erpmenu,'position', 9); % Requesting a specific postion confuses the EEGLAB file menu order as of Matlab R2020a. Let's leave this off for now. AXS Nov 2020 set(erpmenu,'enable','off'); -%% Create BEST Main Menu +%% Create BEST Main Menu %bestmenu = uimenu( menuERPLAB,'Label','BESTsets','separator','on','tag','bestsets','userdata','startup:off;continuous:off;epoch:off;study:off;erpset:on'); %set(erpmenu,'position', 9); % Requesting a specific postion confuses the EEGLAB file menu order as of Matlab R2020a. Let's leave this off for now. AXS Nov 2020 @@ -716,7 +747,7 @@ %% Create MVPA MAIN MENU -% % +% % diff --git a/erplab_default_values.m b/erplab_default_values.m old mode 100644 new mode 100755 index c95ac782..f885ce66 --- a/erplab_default_values.m +++ b/erplab_default_values.m @@ -1,5 +1,5 @@ -erplabver = '9.10'; % current erplab version -erplabrel = '16-Feb-2023'; % DOB +erplabver = '9.20'; % current erplab version +erplabrel = '16-May-2023'; % DOB erplabdeveloper = 'Simmons&Zhang'; %ColorB = [170 180 195]/255; % old background color (until version 3) %ColorB = [0.9216 0.8353 0.6078]; % background color for version 4 diff --git a/functions/averager.m b/functions/averager.m old mode 100644 new mode 100755 diff --git a/functions/chaddnoise.m b/functions/chaddnoise.m new file mode 100644 index 00000000..ff9f1397 --- /dev/null +++ b/functions/chaddnoise.m @@ -0,0 +1,743 @@ +% PURPOSE: add white/pink/line noise to EEG/ERP data with specific +% channels. Different types of noise are also allowed to add simultaneously. +% +% FORMAT: +% +% [ERPOUT cherror] = chaddnoise(EEGin,EEGout,formula,errormsgtype,warningme) +% However syntax is chaddnoise(formula) in eegchanoperator. +% +% INPUT: +% +% EEGin - input dataset +% EEGout - output dataset (for recursiveness...) +% formula - algebraic expression for the (virtual) reference channel +% warningme - display warnings. 1 yes; 0 no +% errormsgtype - 1-use popup on error messages, 0-error in red at +% command window +% +% +% OUTPUT +% +% ERPout - re-referenced dataset or erpset +% cherror - error checking. 0 means no error; 1 means error found +% +% + +% EXAMPLE : +% +% 1. [EEGout cherror] = chaddnoise(EEGin,EEGout,'nch1 = ch1 + 2*whitenoise(1)'); for whitenoise +% 2. [EEGout cherror] = chaddnoise(EEGin,EEGout,'nch1 = ch1 + 2*pinknoise(1)'); for pinknoise + +% 3. [EEGout cherror] = chaddnoise(EEGin,EEGout,"nch1 = ch1 + 2*linenoise(10,'fixed',60)"); +% Setting for linenoise, 10 is used to generage 10Hz signal; 60 is phase shifting that will be fixed across trials or bins. + +% Using 'random' instead of 'fixed' if you want to set phase shifting across trials/bins +% [EEGout cherror] = chaddnoise(EEGin,EEGout,"nch1 = ch1 + 2*linenoise(10,'random',1)"); Note that 1 is the seed that is used to generate phase randomly +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Guanghui Zhang and Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% Apr 2023 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function [EEGout cherror] = chaddnoise(EEGin,EEGout,formula,errormsgtype,warningme) +cherror = 0; + +if nargin<3 + help chaddnoise; + return; +end +if nargin<4 + errormsgtype =1; + warningme=0; +end + +if nargin<5 + warningme=0; +end + +if ~iserpstruct(EEGin) && ~iseegstruct(EEGin) + error('EEGin says: chaddnoise() only works with ERP and EEG structure.') +end +if iseegstruct(EEGin) % EEG + ntrial = EEGin.trials; + nchan = EEGin.nbchan; + datafield = 'data'; + EEGinaux = []; + ntrial = EEGin.trials; +else % ERP + ntrial = EEGin.nbin; + nchan = EEGin.nchan; + datafield = 'bindata'; + EEGinaux = buildERPstruct([]); + ntrial = EEGin.nbin; +end +% add a dot for .*, ./ and .^ operations +expression = regexprep(formula, '([*/^])', '','ignorecase');%%remove * or ^ +formula = regexprep(formula, '([*/^])', '','ignorecase');%%remove * or ^ +% looking for eraser command +[materase] = regexpi(expression, '[n]*ch[an]*\d+\s*=\s*\[\]', 'match'); + +% +% looking for label +% +% EEGin = EEGin; +[matlabel, toklabel] = regexpi(expression, '\s*label\s*\=*\s*(.*)', 'match', 'tokens'); +if ~isempty(toklabel) && ~isempty(EEGin.chanlocs) + newlabel = toklabel{:}{1}; + + % + % erase label from expression + % + expression = strrep(expression, matlabel{:}, ''); +elseif isempty(toklabel) && ~isempty(EEGin.chanlocs) + newlabel = 'no_label'; +end + + +% +% Add noise (line,pink, and white)? +% +toklinenoise = regexpi(expression, 'linenoise', 'match','ignorecase'); +tokwhitenoise = regexpi(expression, 'whitenoise', 'match','ignorecase'); +tokpinknoise = regexpi(expression, 'pinknoise', 'match','ignorecase'); + +NoiseFlagline = []; +NoiseFlagwhite = []; +NoiseFlagpink = []; +if ~isempty(toklinenoise) + NoiseFlagline = 1; +end +if ~isempty(tokwhitenoise) + NoiseFlagwhite = 1; +end +if ~isempty(tokpinknoise) + NoiseFlagpink = 1; +end + +if isempty(NoiseFlagline) && isempty(NoiseFlagwhite) && isempty(NoiseFlagpink) + msgboxText= '\n Please define any one of linenoise, whitenoise, or pinknoise.\n'; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(msgboxText, title); + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + return; +end + + +if isempty(toklinenoise) && isempty(tokwhitenoise) && isempty(tokpinknoise) + ischaddnoise = 1; +else + ischaddnoise = 0; +end +if isempty(materase) + + % looking for ":" + matint = regexpi(expression, ':ch[an]*', 'match'); + + if ~isempty(matint) + error('ERPLAB says: errot at chaddnoise(). Interval of channels is not allowed for deleting process.') + end + + % + % looking for channel indices + % + [mat tok] = regexpi(expression, '[n]*ch[an]*(\d+)', 'match', 'tokens'); + + if isempty(mat) %&& isavgchan == 0 + + % + % ONLY for variable setting (no chans) ---> send to workspace + % + + % + % Matlab 7.3 and higher %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + [expspliter, formulasp] = regexp(strtrim(expression), '=','match','split'); + leftsize = formulasp{1}; + + [mater, tok2] = regexpi(leftsize, '(\w+)', 'match', 'tokens'); + + if isempty(mater) + error(['ERPLAB says: errot at chaddnoise(). Formula ' expression ' contains errors.']) + end + + % + % Sends to workspace your channel definition + % + eval(expression) + + for j=1:length(mater) + outvar = char(tok2{j}); + assignin('base', outvar, eval(outvar)); + end + conti = 1; + return + end + + nindices = size(tok,2); + + if nindices==0 + msgboxText= '\nChannel indices were not found.\n'; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(msgboxText, title); + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + + chanpos = zeros(1,nindices); + realchanpos = chanpos; + tf = zeros(1,nindices); + + for tk=1:nindices + + % + % indices of channels at the formula + % + chanpos(tk) = str2num(tok{1,tk}{1,1}); + + if tk>1 + if iseegstruct(EEGin) + [tf(tk), realchanpos(tk)] = ismember_bc2(chanpos(tk), 1:EEGin.nbchan); + else + [tf(tk), realchanpos(tk)] = ismember_bc2(chanpos(tk), 1:EEGin.nchan); + end + else + if iseegstruct(EEGout) + [tf(1), realchanpos(1)] = ismember_bc2(chanpos(1), 1:EEGout.nbchan); + else + [tf(1), realchanpos(1)] = ismember_bc2(chanpos(1), 1:EEGout.nchan); + end + end + end + + % + % Check right side + % + nonexistingchanpos = find([realchanpos(2:end)]==0); + + if ~isempty(nonexistingchanpos) + msgboxText = ['\nChannel(s) [%s] does not exist!\n'... + 'Only use channels from the list on the right \n']; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(sprintf(msgboxText, num2str(chanpos(nonexistingchanpos+1))), title); + if errormsgtype == 1 + errorfound(sprintf(msgboxText, num2str(chanpos(nonexistingchanpos+1))), title); + else + cprintf('red',msgboxText); + end + conti = 0; % No more bin processing... + return + end + + % + % Keep label (temporary solution...) + % + if length(realchanpos(2:end))==1 && strcmp(newlabel, 'no_label') + newlabel = EEGin.chanlocs(realchanpos(2)).labels; + end + + newchan = chanpos(1); %this is the formula's left side channel index. + eraser = 0; + + +else + % + % Test nchan sintax (for erasing!?) + % + [nchanerase] = regexpi(expression, 'nch[an]*', 'match'); + + if ~isempty(nchanerase) + msgboxText= '\nYou cannot delete a channel using "nchan" sintax\n'; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(msgboxText, title); + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + if ischaddnoise % (?) + msgboxText = '\nSorry. Adding noise is not yet available for this mode.\n'; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(msgboxText, title); + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + + % + % look for channel index(ices) + % + [mat, tok] = regexpi(expression, 'ch[an]*(\d+)', 'match', 'tokens'); % looking for channel index + nindices = size(tok,2); + + if nindices>2 || nindices<=1 + error('ERPLAB says: errot at chaddnoise(). Two elements of channel index are only included in the Eq. E.g, ch1 = ch1 + whitenoise(1) label FP1'); + + end + + chanpos = zeros(1,nindices); + + for tk=1:nindices + chanpos(tk) = str2double(tok{1,tk}{1,1}); % conteins index of channels in the formula + [tf, realchanpos(tk)] = ismember_bc2(chanpos(tk), 1:EEGin.nbchan); %#ok + + if ~tf(tk) + msgboxText= ['\nChannel ' num2str(chanpos(tk)) ' does not exist yet! \n']; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(msgboxText, title) + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + end + if tk>1 + newchan = chanpos(1):chanpos(2); + else + newchan = chanpos(1); + end + + eraser = 1; +end + +if isempty(realchanpos) || numel(realchanpos)~=2 + msgboxText = ['ERPLAB says: Please check your formula:',expression,'.\n\n', ... + 'Two elements of channel index are only included,E.g, ch1 = ch1 + whitenoise(1) label FP1']; + % msgboxText = ['\nPlease, check your formula: \n\n'... + % expression '\n' serr.message '\n']; + title = 'ERPLAB: chaddnoise() error:'; + %errorfound(msgboxText, title) + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return +end +% +% Test New Channel +% +if iseegstruct(EEGout) + lastslot = EEGout.nbchan; +else + lastslot = EEGout.nchan; +end + +if isempty(lastslot) + lastslot= 0; +end +if tf(1) && newchan(1)>=1 + if ~eraser + + % % % + % % % Gui memory + % % % + % % wchmsgon = erpworkingmemory('wchmsgon'); + % % + % % if isempty(wchmsgon) + % % wchmsgon = 1; + % % erpworkingmemory('wchmsgon',1); + % % end + + % % if wchmsgon==0 + % % button = 'yes'; + % % else + % % question = ['Channel %s already exist!\n\n'... + % % 'Would you like to overwrite it?']; + % % title = 'ERPLAB: Overwriting Channel Confirmation'; + % % button = askquest(sprintf(question, num2str(newchan)), title); + % % end + + if warningme==0 + button = 'yes'; + else + question = ['Channel %s already exist!\n\n'... + 'Would you like to overwrite it?']; + title = 'ERPLAB: Overwriting Channel Confirmation'; + button = askquest(sprintf(question, num2str(newchan)), title); + end + + if strcmpi(newlabel,'no_label') + newlabel = EEGin.chanlocs(newchan).labels; % keep the original label + end + else + question = ['Channel %s will be erased!\n\n'... + 'Are you completely sure about this?']; + title = 'ERPLAB: Channel Erasing Confirmation'; + button = askquest(sprintf(question, num2str(newchan)), title); + end + if strcmpi(button,'no') + confirma = 0; + conti = 0; + disp(['Channel ' num2str(newchan) ' was not modified']) + elseif strcmpi(button,'yes') + confirma = 1; + %fprintf(['\nWARNING: Channel ' num2str(newchan) ' was overwritten.\n\n']) + else + disp('User selected Cancel') + conti = 0; + return + end +elseif (~tf(1) && newchan(1)>=1 && newchan(1) <= lastslot+1) + confirma = 1; % Everything is ok! + realchanpos(1) = lastslot+1; +else + msgboxText = ['\nError: Channel ' num2str(newchan) ' is out of order!\n\n'... + '"chan#" equations must be define in ascending order.\n\n'... + '"nchan#" equations must be define in ascending order, from 1 to the highest channel. \n']; + title = 'ERPLAB: chaddnoise:'; + %errorfound(sprintf(msgboxText), title); + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; % No more bin processing... + return +end +if confirma + try + trialNum = ntrial;%EEGin.trials; + sampleNum = EEGin.pnts; + formula = regexprep(formula, '([\s])', '','ignorecase'); + %%----------------------------------------------------------------- + %%---------------------------------white noise--------------------- + %%----------------------------------------------------------------- + if ~isempty(NoiseFlagwhite) + + [mattypewhite toktypewhite] = regexpi(formula, '\s*[+-]?[\d+]*(whitenoise)', 'match','tokens'); + if isempty(mattypewhite) || isempty(toktypewhite) + msgboxText = ['\nPlease, check your formula: \n\n'... + char(formula) '\n']; + title = 'ERPLAB: chaddnoise() error:'; + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + %Get the amplitude for noise signal + AmpNoisewhite = str2num(regexprep(char(mattypewhite{1,1}), char(toktypewhite{1,1}), '','ignorecase')); + if isempty(AmpNoisewhite) + AmpNoisewhite = 1; + end + WhiteNoiseedstr = regexpi(formula, ['\s*',char(toktypewhite{1,1}),'\((\d)?\)'], 'tokens','ignorecase'); + + if isempty(WhiteNoiseedstr) + Noiseedwhite = 0; + else + Noiseedwhite = str2num(char(WhiteNoiseedstr{1,1}{1,1})); + end + if ~isempty(Noiseedwhite) + if Noiseedwhite>=0 + try + rng(Noiseedwhite,'twister'); + catch + rng(0,'twister'); + end + end + end + Desiredwhitenoise = randn(sampleNum,trialNum);%%white noise + Desiredwhitenoise = reshape(Desiredwhitenoise,sampleNum*trialNum,1); + if trialNum==1%%one trial + Desiredwhitenoise = AmpNoisewhite*Desiredwhitenoise; + Desiredwhitenoise = reshape(Desiredwhitenoise,sampleNum,trialNum); + if trialNum==1 + Desiredwhitenoise = reshape(Desiredwhitenoise,1,sampleNum); + end + EEGout.(datafield)(realchanpos(1),:,1:trialNum) = squeeze(EEGin.(datafield)(realchanpos(2),:,1:trialNum))+Desiredwhitenoise; + else%%multiple trials or bins + Desiredwhitenoise = reshape(Desiredwhitenoise,sampleNum,trialNum); + for Numoftrial = 1:trialNum + Noisinglewhite = Desiredwhitenoise(:,Numoftrial); + + Noisinglewhite = AmpNoisewhite*Noisinglewhite; + Noisinglewhite = reshape(Noisinglewhite,1,sampleNum); + EEGout.(datafield)(realchanpos(1),:,Numoftrial) = squeeze(EEGin.(datafield)(realchanpos(2),:,Numoftrial))+Noisinglewhite; + end + end + end + + + + %%----------------------------------------------------------------- + %%---------------------------------pink noise---------------------- + %%----------------------------------------------------------------- + if ~isempty(NoiseFlagpink) + [mattypepink toktypepink] = regexpi(formula, '\s*[+-]?[\d+]*(pinknoise)', 'match','tokens'); + if isempty(mattypepink) || isempty(toktypepink) + msgboxText = ['\nPlease, check your formula: \n\n'... + char(formula) '\n']; + title = 'ERPLAB: chaddnoise() error:'; + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + %Get the amplitude for noise signal + AmpNoisepink = str2num(regexprep(char(mattypepink{1,1}), char(toktypepink{1,1}), '','ignorecase')); + if isempty(AmpNoisepink) + AmpNoisepink = 1; + end + PinkNoiseedstr = regexpi(formula, ['\s*',char(toktypepink{1,1}),'\((\d+)?\)'], 'tokens','ignorecase'); + + if isempty(PinkNoiseedstr) + Noiseedpink = []; + else + Noiseedpink = str2num(char(PinkNoiseedstr{1,1}{1,1})); + end + if ~isempty(Noiseedpink) + if Noiseedpink>=0%% use the default generator to get noise + try + rng(Noiseedpink,'twister'); + catch + rng(0,'twister'); + end + end + end + Desiredpinknoise = f_pinknoise(sampleNum*trialNum); + Desiredpinknoise = reshape(Desiredpinknoise,sampleNum*trialNum,1); + if trialNum==1%%one trial + + Desiredpinknoise = AmpNoisepink*Desiredpinknoise; + Desiredpinknoise = reshape(Desiredpinknoise,sampleNum,trialNum); + if trialNum==1 + Desiredpinknoise = reshape(Desiredpinknoise,1,sampleNum); + end + EEGout.(datafield)(realchanpos(1),:,1:trialNum) = squeeze(EEGin.(datafield)(realchanpos(2),:,1:trialNum))+Desiredpinknoise; + else%%multiple trials or bins + Desiredpinknoise = reshape(Desiredpinknoise,sampleNum,trialNum); + for Numoftrial = 1:trialNum + Noisinglepink = Desiredpinknoise(:,Numoftrial); + Noisinglepink = AmpNoisepink*Noisinglepink; + Noisinglepink = reshape(Noisinglepink,1,sampleNum); + EEGout.(datafield)(realchanpos(1),:,Numoftrial) = squeeze(EEGin.(datafield)(realchanpos(2),:,Numoftrial))+Noisinglepink; + end + end + end + + + %%----------------------------------------------------------------- + %%---------------------------------line noise---------------------- + %%----------------------------------------------------------------- + if ~isempty(NoiseFlagline)%%line noise + + splitStr = regexp(formula,'\=|+|-','split'); + for ii = 1:length(splitStr) + toklinenoise = regexpi(splitStr{ii}, 'linenoise', 'match','ignorecase'); + if ~isempty(toklinenoise) + formula = splitStr{ii}; + break; + end + end + + % [mattypeline toktypeline] = regexpi(formula, '\s+[\d+]*(linenoise)', 'match','tokens');\s+[+-]?[\d+]* + [mattypeline toktypeline] = regexpi(formula, '\s*[+-]?[\d+]*(linenoise)', 'match','tokens'); + if isempty(mattypeline) || isempty(toktypeline) + msgboxText = ['\nPlease, check your formula: \n\n'... + char(formula) '\n']; + title = 'ERPLAB: chaddnoise() error:'; + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end + %Get the amplitude for noise signal + AmpNoise = str2num(regexprep(char(mattypeline{1,1}), char(toktypeline{1,1}), '','ignorecase')); + if isempty(AmpNoise) + AmpNoise = 1; + end + + Periodconstr = regexpi(formula, ['\s*','linenoise','\((.*)?\)'], 'tokens','ignorecase'); + if isempty(Periodconstr) + msgboxText = ["\nPlease check Formula for line noise, the correct one likes, e.g., ch1 = ch1 + 2*linenoise(60,'fixed',90) label FP1;"]; + title = 'ERPLAB: chaddnoise() error:'; + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + return; + end + + PeriodPhase = regexpi(Periodconstr{1,1}, '[\d.]+', 'match');%%get period and phaseshifting/seed + + if isempty(PeriodPhase) + msgboxText = ["\nPlease check Formula for line noise, the correct one likes, e.g., ch1 = ch1 + 2*linenoise(60,'fixed',90) label FP1;"]; + title = 'ERPLAB: chaddnoise() error:'; + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + return; + end + try + PeriodValue = str2num(char(PeriodPhase{1,1}{1}));%% period + catch + PeriodValue = []; + end + + if isempty(PeriodValue) + msgboxText = ["\nPlease check Formula for line noise, the correct one likes, e.g., ch1 = ch1 + 2*linenoise(60,'fixed',90) label FP1;"]; + title = 'ERPLAB: chaddnoise() error:'; + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + return; + end + + [GenType,toktype] = regexpi(formula, '(fixed|random)', 'match','tokens'); + if isempty(GenType) + isGenType = 2; + else + if strcmpi(char(GenType),'fixed') + isGenType =1;%% fixed phase shifting + else + isGenType = 2;%% seed for generating phase randomly + end + end + if isGenType==1 + try + PhaseShit = str2num(char(PeriodPhase{1,1}{2}));%%phase shifting + catch + PhaseShit = 0; + end + else + try + PhaseShit = str2num(char(PeriodPhase{1,1}{2}));%%phase shifting + catch + PhaseShit =[]; + end + end + timeStart = EEGin.xmin; + timeEnd = EEGin.xmax; + + Times = [timeStart:1/EEGin.srate:timeEnd]; + Desirednoise =[]; + if isGenType==1 %% fixed phase shifting mode + PhaseShit = deg2rad(PhaseShit);%%Convert angles from degrees to radians. + for Numoftrial = 1:trialNum + Desirednoise(:,Numoftrial) = AmpNoise*sin(2*PeriodValue*pi*Times+PhaseShit); + end + else + if ~isempty(PhaseShit)%% define one seed for "random" mode + PhaseShit = ceil(PhaseShit); + if PhaseShit<0 + PhaseShit = 0; + end + try + rng(PhaseShit,'twister'); + catch + rng(0,'twister'); + end + end + Phasemtrial = rand(1,trialNum)*2*pi; + for Numoftrial = 1:trialNum + Desirednoise(:,Numoftrial) = AmpNoise*sin(2*PeriodValue*pi*Times+Phasemtrial(Numoftrial)); + end + + end + if trialNum==1 + Desirednoise = reshape(Desirednoise,1,sampleNum); + end + EEGout.(datafield)(realchanpos(1),:,1:trialNum) = squeeze(EEGin.(datafield)(realchanpos(2),:,1:trialNum))+Desirednoise; + end + + + % + % New Label + % + if ~isempty(newlabel) + EEGout.chanlocs(realchanpos(1)).labels = newlabel; + end + if iseegstruct(EEGout) + EEGout.nbchan = size(EEGout.data, 1); + EEGout = eeg_checkset( EEGout ); + disp(['Channel ' num2str(newchan) ' was created']) + EEGout = update_rejEfields(EEGin,EEGout,realchanpos); % update reject fields + else + EEGout.nchan = size(EEGout.bindata, 1); + disp(['Channel ' num2str(newchan) ' was created']) + end + + if eraser && ~iseegstruct(EEGout) + EEGout.bindata(newchan,:,:) = []; + EEGout.binerror(newchan,:,:)= []; + EEGout.nchan = size(EEGout.bindata, 1); + labaux = {EEGin.chanlocs.labels}; + labaux{newchan}=[]; + indxl = ~cellfun(@isempty, labaux); + labelout = labaux(indxl); + [EEGout.chanlocs(1:EEGout.nchan).labels] = labelout{:}; + disp(['Channel ' num2str(newchan) ' was erased']) + end + + catch + serr = lasterror; + msgboxText = ['\nPlease, check your formula: \n\n'... + expression '\n' serr.message '\n']; + title = 'ERPLAB: chaddnoise() error:'; + + if errormsgtype == 1 + errorfound(sprintf(msgboxText), title); + else + cprintf('red',msgboxText); + end + conti = 0; + return + end +end \ No newline at end of file diff --git a/functions/chanlocs_matcherEEG.m b/functions/chanlocs_matcherEEG.m old mode 100644 new mode 100755 diff --git a/functions/checkeegzerolat.m b/functions/checkeegzerolat.m old mode 100644 new mode 100755 diff --git a/functions/displayEquiComERP.m b/functions/displayEquiComERP.m index 21b5712e..9e7f5dff 100755 --- a/functions/displayEquiComERP.m +++ b/functions/displayEquiComERP.m @@ -1,47 +1,74 @@ function displayEquiComERP(xcom, nline2end) if nargin<2 - nline2end = 140; % max line length - nd = nline2end; % number of dashed lines + nline2end = 140; % max line length + nd = nline2end; % number of dashed lines end + +%%changed by Guanghui Mar 2023 +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + else + Toolabel = 0; + end +else + Toolabel = 1; +end + + fprintf([repmat('-', 1,nd) '\n']); -try +if Toolabel==0 + try cprintf([0.1333 0.5451 0.1333], '%%Equivalent command:\n'); -catch + catch fprintf('%%Equivalent command:\n'); + end +elseif Toolabel==1 + + try + cprintf([0.1333 0.5451 0.1333], '%%EStudio:Equivalent command:\n'); + catch + fprintf('%%EStudio:Equivalent command:\n'); + end end if length(xcom)nline2end) - if isempty(indxcomx) - fprintf('%s\n', xcom); % as it is... - else - N = round((length(xcom)/nline2end)); - Npos = nline2end:nline2end:N*nline2end; - Apos = unique_bc2(closest(indxcomx,Npos)); - if length(Apos)>1 && (length(xcom)-Apos(end-1))<=nline2end - Apos = Apos(1:end-1); - elseif length(Apos)==1 && (length(xcom)-Apos)< 0.1*length(xcom) - fprintf('%s\n', xcom); % as it is... - fprintf([repmat('-', 1,nd) '\n']); - return - end - for kk=1:length(xcom) - if ~ismember_bc2(kk, Apos) - fprintf('%s', xcom(kk)); - elseif ismember_bc2(kk, Apos) && kknline2end) + if isempty(indxcomx) + fprintf('%s\n', xcom); % as it is... + else + N = round((length(xcom)/nline2end)); + Npos = nline2end:nline2end:N*nline2end; + Apos = unique_bc2(closest(indxcomx,Npos)); + if length(Apos)>1 && (length(xcom)-Apos(end-1))<=nline2end + Apos = Apos(1:end-1); + elseif length(Apos)==1 && (length(xcom)-Apos)< 0.1*length(xcom) + fprintf('%s\n', xcom); % as it is... + fprintf([repmat('-', 1,nd) '\n']); + return + end + for kk=1:length(xcom) + if ~ismember_bc2(kk, Apos) + fprintf('%s', xcom(kk)); + elseif ismember_bc2(kk, Apos) && kkGo back to ERPLAB menu'); + + +if Toolabel~=1%%Changed by Guanghui August 2022 + disp('Go back to ERPLAB menu'); +end fprintf('\n'); \ No newline at end of file diff --git a/functions/dq_baseline.m b/functions/dq_baseline.m old mode 100644 new mode 100755 diff --git a/functions/dq_sdacrosstrials.m b/functions/dq_sdacrosstrials.m old mode 100644 new mode 100755 diff --git a/functions/dq_summary.m b/functions/dq_summary.m old mode 100644 new mode 100755 diff --git a/functions/eegchanoperator.m b/functions/eegchanoperator.m index b3b6ca39..2f1a0080 100755 --- a/functions/eegchanoperator.m +++ b/functions/eegchanoperator.m @@ -97,6 +97,22 @@ return end +%%---------------changed GH Apr 2023----Add sin/white/pink noise------------ +% +% noise? +% +% toklinenoise = regexpi(expression, '\s*linenoise\((.*)?\)', 'tokens','ignorecase');%%this used to take the value +toklinenoise = regexpi(expression, 'linenoise', 'match','ignorecase'); +tokwhitenoise = regexpi(expression, 'whitenoise', 'match','ignorecase'); +tokpinknoise = regexpi(expression, 'pinknoise', 'match','ignorecase'); + +if ~isempty(toklinenoise) || ~isempty(tokwhitenoise) || ~isempty(tokpinknoise) + EEGout = chaddnoise(EEGin,EEGout,expression,errormsgtype); + return; +end +%%-----------------------------change end---------------------------------- + + % add a dot for .*, ./ and .^ operations expression = regexprep(expression, '([*/^])', '.$1','ignorecase'); diff --git a/functions/erp2memory.m b/functions/erp2memory.m index 4392a8ca..3b6ca3a3 100755 --- a/functions/erp2memory.m +++ b/functions/erp2memory.m @@ -39,23 +39,23 @@ % along with this program. If not, see . function erp2memory(ERP, indx) - +global observe_ERPDAT; erpm = findobj('tag', 'linerp'); nerpset = length(erpm); -for s=1:nerpset - if s == nerpset-indx+1 % bottom-up to top-down counting - set(erpm(s), 'checked', 'on' ); - menutitle = ['Erpset '... - num2str(nerpset-s+1) ': ' ERP.erpname '']; - set( erpm(s), 'Label', menutitle); - else - set(erpm(s), 'checked', 'off' ); - currname = get(erpm(s),'Label'); - menutitle = regexprep(currname,'|','', 'ignorecase'); - menutitle = regexprep(menutitle, '\s+', ' '); - menutitle = regexprep(menutitle,'Erpset \d+',['Erpset ' num2str(nerpset-s+1)], 'ignorecase'); - set( erpm(s), 'Label', menutitle); - end +for s=1:nerpset + if s == nerpset-indx+1 % bottom-up to top-down counting + set(erpm(s), 'checked', 'on' ); + menutitle = ['Erpset '... + num2str(nerpset-s+1) ': ' ERP.erpname '']; + set( erpm(s), 'Label', menutitle); + else + set(erpm(s), 'checked', 'off' ); + currname = get(erpm(s),'Label'); + menutitle = regexprep(currname,'|','', 'ignorecase'); + menutitle = regexprep(menutitle, '\s+', ' '); + menutitle = regexprep(menutitle,'Erpset \d+',['Erpset ' num2str(nerpset-s+1)], 'ignorecase'); + set( erpm(s), 'Label', menutitle); + end end CURRENTERP = indx; assignin('base','CURRENTERP', CURRENTERP); % save to workspace @@ -64,49 +64,64 @@ function erp2memory(ERP, indx) % check ploterps GUI perpgui = findobj('Tag', 'ploterp_fig'); if ~isempty(perpgui) - close(perpgui) - pause(0.1) - pop_ploterps(ERP); + close(perpgui) + pause(0.1) + pop_ploterps(ERP); else - fprintf('\n------------------------------------------------------\n'); - fprintf('ERPSET #%g is ACTIVE\n', indx); - fprintf('------------------------------------------------------\n'); - ERP + fprintf('\n------------------------------------------------------\n'); + fprintf('ERPSET #%g is ACTIVE\n', indx); + fprintf('------------------------------------------------------\n'); + ERP + + %%changed by GZ Mar 2023 + + CURRENTERP = indx; + ALLERP = observe_ERPDAT.ALLERP; + if ~isempty(ALLERP) + if isempty(CURRENTERP) || CURRENTERP<=0 || CURRENTERP> length(ALLERP) + CURRENTERP= length(ALLERP); + end + observe_ERPDAT.CURRENTERP = CURRENTERP; + observe_ERPDAT.ERP = ALLERP(CURRENTERP); + observe_ERPDAT.Two_GUI = 1; + end + + end -% %% check DQ options of erpset & make changes to ERPlab menu -% -% erplabmenu = findobj('tag', 'ERPLAB'); +% %% check DQ options of erpset & make changes to ERPlab menu +% +% erplabmenu = findobj('tag', 'ERPLAB'); % %W_MAIN = findobj('tag', 'EEGLAB'); % allmenus = findobj( erplabmenu, 'type', 'uimenu'); % allstrs = get(allmenus, 'Label'); option1 = findobj('Label', 'Show Data Quality measures in table'); -option2 = findobj('Label', 'Summarize Data Quality (min, median, max)'); -option3 = findobj('Label', 'Save Data Quality measures to file'); +option2 = findobj('Label', 'Summarize Data Quality (min, median, max)'); +option3 = findobj('Label', 'Save Data Quality measures to file'); if isfield(ERP,'dataquality') & ~strcmp(ERP.dataquality(1).type,'empty') - %if there is dataquality measures, make DQ menu options available + %if there is dataquality measures, make DQ menu options available set(option1, 'enable', 'on'); set(option2, 'enable', 'on'); - set(option3, 'enable', 'on'); - + set(option3, 'enable', 'on'); + else set(option1, 'enable', 'off'); set(option2, 'enable', 'off'); - set(option3, 'enable', 'off'); + set(option3, 'enable', 'off'); end -% -% -% if any(strcmp(menustatus, 'erp_dataset')) -% eval('indmatchvar = cellfun(@(x)(~isempty(findstr(num2str(x), ''erpset:on''))), allstrs);'); +% +% +% if any(strcmp(menustatus, 'erp_dataset')) +% eval('indmatchvar = cellfun(@(x)(~isempty(findstr(num2str(x), ''erpset:on''))), allstrs);'); % set(allmenus(indmatchvar), 'enable', 'on'); % end -% mainerplab = findobj(W_MAIN, 'tag', submenu); -% erpmenu = findobj('erpmenu','type', 'uimenu'); +% mainerplab = findobj(W_MAIN, 'tag', submenu); +% erpmenu = findobj('erpmenu','type', 'uimenu'); end diff --git a/functions/erpAutoYLim.m b/functions/erpAutoYLim.m index 1a82e14a..a26c067a 100755 --- a/functions/erpAutoYLim.m +++ b/functions/erpAutoYLim.m @@ -130,7 +130,7 @@ % % in case of flatlined ERPs % - if yylim(1)<1E-6 && yylim(2)<1E-6 + if abs(yylim(1))<1E-6 && abs(yylim(2))<1E-6 %%GH May 2023 if strcmpi(datatype, 'ERP') yylim(1:2) = [-1 1]; fprintf('WARNING: It seems like erpAutoYLim() found flatlined ERPs. So auto Y-limit was set to [-1 1].\n'); diff --git a/functions/erpchanoperator.m b/functions/erpchanoperator.m index 2b17f14e..6c8aa6dc 100755 --- a/functions/erpchanoperator.m +++ b/functions/erpchanoperator.m @@ -90,6 +90,24 @@ return end + +%%---------------changed GH Apr 2023----Add sin/white/pink noise------------ +% +% noise? +% +% toklinenoise = regexpi(expression, '\s*linenoise\((.*)?\)', 'tokens','ignorecase');%%this used to take the value +toklinenoise = regexpi(expression, 'linenoise', 'match','ignorecase'); +tokwhitenoise = regexpi(expression, 'whitenoise', 'match','ignorecase'); +tokpinknoise = regexpi(expression, 'pinknoise', 'match','ignorecase'); + +if ~isempty(toklinenoise) || ~isempty(tokwhitenoise) || ~isempty(tokpinknoise) + ERPout = chaddnoise(ERPin,ERPout,expression,wchmsgon); + return; +end +%%-----------------------------change end---------------------------------- + + + % % Reref chans? % diff --git a/functions/erphistory.m b/functions/erphistory.m old mode 100644 new mode 100755 diff --git a/functions/f_exgauss_pdf.m b/functions/f_exgauss_pdf.m new file mode 100644 index 00000000..3a8ca2d3 --- /dev/null +++ b/functions/f_exgauss_pdf.m @@ -0,0 +1,42 @@ +% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% Mar. 2023 + + + +%%Adpated from:https://www.mathworks.com/matlabcentral/fileexchange/66575-exponentially-modified-gaussian-ex-gaussian-distributions + + +function pdf = f_exgauss_pdf(x, mu, sigma, tau) + if license('test', 'Symbolic_Toolbox') + useVPA = 1; % compute with additional precision + else + useVPA = 0; + end + if tau >0 && sigma > 0 %check for correctness + % preliminary computations + if useVPA + sigmaPerTau = vpa(sigma./tau); + else + sigmaPerTau = sigma./tau; + end + muMinusX = mu - x; + normalPart = 1 - normcdf(muMinusX./sigma + sigmaPerTau); + + expPart = muMinusX./tau + (sigmaPerTau.^2)./2; + if (useVPA) + pdf = double((1/tau).*normalPart.*exp(expPart)); + else + if (expPart > 25) + warning('The combination of the input values may result in numerical instability. Please change your units to make (mu-x)/tau < 25 and sigma/tau < 5. Then please re-run the script') + end + pdf = (1/tau).*normalPart.*exp(expPart); + end +% pdf = abs(pdf); + else + pdf = zeros(length(x), 1); + end + pdf(pdf==Inf) = 0; +end \ No newline at end of file diff --git a/functions/f_gaussian.m b/functions/f_gaussian.m new file mode 100644 index 00000000..2e491af0 --- /dev/null +++ b/functions/f_gaussian.m @@ -0,0 +1,30 @@ +% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% Mar. 2023 + + + + +% 'a' specifies the amplitude +% 'b' specifies the x-coordinate of the center +% 'c' specifies the width +% 'x' is a vector of x inputs + + + +function Sig = f_gaussian(x,a,b,c) +if isempty(a) %%Mean amplitude + a = 1; +end + +if isempty(b) + b= 0; +end +if isempty(c) + c = 0.5; +end +Sig =[]; +Sig = a*exp(-(((x-b).^2)/(2*c.^2))); +end \ No newline at end of file diff --git a/functions/f_pinknoise.m b/functions/f_pinknoise.m new file mode 100644 index 00000000..7732da6f --- /dev/null +++ b/functions/f_pinknoise.m @@ -0,0 +1,66 @@ +% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% Mar. 2023 + + + +%%Thanks for Hristo Zhivomirov function, Mar 2023 Davis CA USA +%%https://github.com/cortex-lab/MATLAB-tools/blob/master/pinknoise.m +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Pink Noise Generation with MATLAB Implementation % +% % +% Author: M.Sc. Eng. Hristo Zhivomirov 07/30/13 % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function y = f_pinknoise(N) + +% function: y = pinknoise(N) +% N - number of samples to be returned in row vector +% y - row vector of pink (flicker) noise samples + +% The function generates a sequence of pink (flicker) noise samples. +% Pink noise has equal energy in all octaves (or similar log bundles) of frequency. +% In terms of power at a constant bandwidth, pink noise falls off at 3 dB per octave. + +% define the length of the vector +% ensure that the M is even +if rem(N,2) + M = N+1; +else + M = N; +end + +% generate white noise +x = randn(1, M); + +% FFT +X = fft(x); + +% prepare a vector for 1/f multiplication +NumUniquePts = M/2 + 1; +n = 1:NumUniquePts; +n = sqrt(n); + +% multiply the left half of the spectrum so the power spectral density +% is proportional to the frequency by factor 1/f, i.e. the +% amplitudes are proportional to 1/sqrt(f) +X(1:NumUniquePts) = X(1:NumUniquePts)./n; + +% prepare a right half of the spectrum - a copy of the left one, +% except the DC component and Nyquist frequency - they are unique +X(NumUniquePts+1:M) = real(X(M/2:-1:2)) -1i*imag(X(M/2:-1:2)); + +% IFFT +y = ifft(X); + +% prepare output vector y +y = real(y(1, 1:N)); + +% ensure unity standard deviation and zero mean value +y = y - mean(y); +yrms = sqrt(mean(y.^2)); +y = y/yrms; + +end \ No newline at end of file diff --git a/functions/fourieeg.m b/functions/fourieeg.m index a23f0af0..65ec4e0b 100755 --- a/functions/fourieeg.m +++ b/functions/fourieeg.m @@ -333,7 +333,7 @@ set(gca,'XScale','log') set(gca,'XTick',[1 10 60 100]) if f1 == 0 - xstart = 0.1 + xstart = 0.1; else xstart = f1; end diff --git a/functions/lindetrend.m b/functions/lindetrend.m index 0f9c38b5..959fa1d9 100755 --- a/functions/lindetrend.m +++ b/functions/lindetrend.m @@ -1,142 +1,144 @@ -% PURPOSE: Removes the best straight-line fit from epoched-EEG or averaged ERP data. -% Matlab: detrend() computes the least-squares fit of a straight line to the data -% (whole epoch or interval) and subtracts the resulting function from the data -% (whole epoch). To obtain the equation of the straight-line fit, use polyfit. -% -% -% FORMAT: -% -% ERP = lindetrend( ERP, interv); -% -% or -% -% EEG = lindetrend( EEG, interv); -% -% -% INPUTS: -% -% EEG/ERP - epoched dataset or erpset -% interv - time interval in ms to compute the least-square fit of a straight line to the data in this interval. -% The fitted straight line will be extrapolated until having as many points as that whole data, then -% this straight line will be substracted from the whole data. -% "interval" can also be a string like 'pre', 'post' or 'all' -% -% OUTPUT -% -% EEG/ERP - epoched dataset or erpset linearly detrended -% -% -% Examples: -% -% EEG = lindetrend( EEG, 'pre'); % detrend each whole epoch accordind the trend at the pre-stimulus interval -% ERP = lindetrend( ERP, 'post'); % detrend each whole epoch accordind the trend at the post-timulus interval -% EEG = lindetrend( EEG, 'all'); % detrend each whole epoch accordind the trend at the whole epoch -% ERP = lindetrend( ERP, '-500 300'); % detrend each whole epoch accordind the trend between -500 and 300 ms -% -% -% *** This function is part of ERPLAB Toolbox *** -% Author: Javier Lopez-Calderon -% Center for Mind and Brain -% University of California, Davis, -% Davis, CA -% January 25th, 2011 - -%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b -% -% ERPLAB Toolbox -% Copyright 2007 The Regents of the University of California -% Created by Javier Lopez-Calderon and Steven Luck -% Center for Mind and Brain, University of California, Davis, -% javlopez@ucdavis.edu, sjluck@ucdavis.edu -% -% This program is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this program. If not, see . - -function ERPLAB = lindetrend( ERPLAB, interv) - -if nargin<1 - help lindetrend -end -if iseegstruct(ERPLAB) - if isempty(ERPLAB.epoch) - error('ERPLAB says: lindetrend() only works with epoched data!') - end - ntrial = ERPLAB.trials; - pnts = ERPLAB.pnts; - datafield = 'data'; -elseif iserpstruct(ERPLAB) - ntrial = ERPLAB.nbin; - pnts = ERPLAB.pnts; - datafield = 'bindata'; -else - error('ERPLAB says: error at lindetrend(). Invalid inputs') -end -if isfield(ERPLAB, 'datatype') - datatype = ERPLAB.datatype; -else % FFT - datatype = 'ERP'; -end -if strcmpi(datatype, 'ERP') - kktime = 1000; -else - kktime = 1; -end - -if strcmpi(interv,'pre') - bb = find(ERPLAB.times==0); % zero-time locked - aa =1; -elseif strcmpi(interv,'post') - aa = find(ERPLAB.times==0); % zero-time locked - bb = pnts; -elseif strcmpi(interv,'all') - bb = pnts; % full epoch - aa = 1; -else - toffsa = abs(round(ERPLAB.xmin*ERPLAB.srate)) + 1; - - if ischar(interv) - inte2num = str2num(interv); % interv in ms - else - inte2num = interv; - end - - aa = round(inte2num(1)*ERPLAB.srate/kktime) + toffsa ; % ms to samples - bb = round(inte2num(2)*ERPLAB.srate/kktime) + toffsa ; % ms to samples - - if (bb-aa<5 && bb-aa>pnts) || aa<1 || bb>pnts - msgboxText = ['Unappropriated time interval: [%g %g]\n'... - 'lindetrend() was ended.\n']; - title = 'ERPLAB: lindetrend() error'; - errorfound(sprintf(msgboxText,a,b), title); - return - end -end - -fprintf('linear detrending...\n'); - -if aa==1 && bb==length(ERPLAB.times) - for i = 1:ntrial - auxdata = ERPLAB.(datafield)(:,:,i); - ERPLAB.(datafield)(:,:,i) = detrend(auxdata')'; % fast full interval detrending - end -else - for i = 1:ntrial - datadet = detrend(ERPLAB.(datafield)(:,aa:bb,i)', 'linear')'; % data detrended by segments - difdata = ERPLAB.(datafield)(:,aa:bb,i) - datadet; % recovers straight lines - recutrend = interp1(aa:bb,difdata',1:pnts,'pchip'); % extrapolates from interval-based trending for all channel - if size(recutrend,1)>1 - recutrend = recutrend'; - end - ERPLAB.(datafield)(:,:,i) = ERPLAB.(datafield)(:,:,i)-recutrend; % detrends full epochs - end -end +% PURPOSE: Removes the best straight-line fit from epoched-EEG or averaged ERP data. +% Matlab: detrend() computes the least-squares fit of a straight line to the data +% (whole epoch or interval) and subtracts the resulting function from the data +% (whole epoch). To obtain the equation of the straight-line fit, use polyfit. +% +% +% FORMAT: +% +% ERP = lindetrend( ERP, interv); +% +% or +% +% EEG = lindetrend( EEG, interv); +% +% +% INPUTS: +% +% EEG/ERP - epoched dataset or erpset +% interv - time interval in ms to compute the least-square fit of a straight line to the data in this interval. +% The fitted straight line will be extrapolated until having as many points as that whole data, then +% this straight line will be substracted from the whole data. +% "interval" can also be a string like 'pre', 'post' or 'all' +% +% OUTPUT +% +% EEG/ERP - epoched dataset or erpset linearly detrended +% +% +% Examples: +% +% EEG = lindetrend( EEG, 'pre'); % detrend each whole epoch accordind the trend at the pre-stimulus interval +% ERP = lindetrend( ERP, 'post'); % detrend each whole epoch accordind the trend at the post-timulus interval +% EEG = lindetrend( EEG, 'all'); % detrend each whole epoch accordind the trend at the whole epoch +% ERP = lindetrend( ERP, '-500 300'); % detrend each whole epoch accordind the trend between -500 and 300 ms +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% January 25th, 2011 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function ERPLAB = lindetrend( ERPLAB, interv) + +if nargin<1 + help lindetrend +end +if iseegstruct(ERPLAB) + if isempty(ERPLAB.epoch) + error('ERPLAB says: lindetrend() only works with epoched data!') + end + ntrial = ERPLAB.trials; + pnts = ERPLAB.pnts; + datafield = 'data'; +elseif iserpstruct(ERPLAB) + ntrial = ERPLAB.nbin; + pnts = ERPLAB.pnts; + datafield = 'bindata'; +else + error('ERPLAB says: error at lindetrend(). Invalid inputs') +end +if isfield(ERPLAB, 'datatype') + datatype = ERPLAB.datatype; +else % FFT + datatype = 'ERP'; +end +if strcmpi(datatype, 'ERP') + kktime = 1000; +else + kktime = 1; +end + +if strcmpi(interv,'pre') +% bb = find(ERPLAB.times==0); % zero-time locked + [xxx, bb, latdiffms] = closest(ERPLAB.times, 0);%%GH 2022 + aa =1; +elseif strcmpi(interv,'post') +% aa = find(ERPLAB.times==0); % zero-time locked + [xxx, aa, latdiffms] = closest(ERPLAB.times, 0);%%GH 2022 + bb = pnts; +elseif strcmpi(interv,'all') + bb = pnts; % full epoch + aa = 1; +else + toffsa = abs(round(ERPLAB.xmin*ERPLAB.srate)) + 1; + + if ischar(interv) + inte2num = str2num(interv); % interv in ms + else + inte2num = interv; + end + + aa = round(inte2num(1)*ERPLAB.srate/kktime) + toffsa ; % ms to samples + bb = round(inte2num(2)*ERPLAB.srate/kktime) + toffsa ; % ms to samples + + if (bb-aa<5 && bb-aa>pnts) || aa<1 || bb>pnts + msgboxText = ['Unappropriated time interval: [%g %g]\n'... + 'lindetrend() was ended.\n']; + title = 'ERPLAB: lindetrend() error'; + errorfound(sprintf(msgboxText,a,b), title); + return + end +end + +fprintf('linear detrending...\n'); + +if aa==1 && bb==length(ERPLAB.times) + for i = 1:ntrial + auxdata = ERPLAB.(datafield)(:,:,i); + ERPLAB.(datafield)(:,:,i) = detrend(auxdata')'; % fast full interval detrending + end +else + for i = 1:ntrial + datadet = detrend(ERPLAB.(datafield)(:,aa:bb,i)', 'linear')'; % data detrended by segments + difdata = ERPLAB.(datafield)(:,aa:bb,i) - datadet; % recovers straight lines + recutrend = interp1(aa:bb,difdata',1:pnts,'pchip'); % extrapolates from interval-based trending for all channel + if size(recutrend,1)>1 + recutrend = recutrend'; + end + ERPLAB.(datafield)(:,:,i) = ERPLAB.(datafield)(:,:,i)-recutrend; % detrends full epochs + end +end diff --git a/functions/make_DQ_spec.m b/functions/make_DQ_spec.m old mode 100644 new mode 100755 diff --git a/functions/make_bootstrap_ERPSETs.m b/functions/make_bootstrap_ERPSETs.m old mode 100644 new mode 100755 diff --git a/functions/ploterps.m b/functions/ploterps.m old mode 100644 new mode 100755 diff --git a/functions/save_data_quality.m b/functions/save_data_quality.m old mode 100644 new mode 100755 index a6b3ac6c..cbf2b93a --- a/functions/save_data_quality.m +++ b/functions/save_data_quality.m @@ -1,249 +1,215 @@ -% write data quality substructure to file -% part of the ERPLAB Toolbox -% axs Apr 2019 -% ams Jan 2023 (updated with SD across Trials) -% -% Format: -% save_data_quality(ERP, 'dq.mat') -% or save_data_quality(ERP,filename,format_flag) -% -% INPUT: * - mandatory -% * ERP - an ERP structure, which must contain a ERP.dataquality substruct -% filename - a string which will specify the filename of the new saved -% file. This can optionally contain a full path, and/or extension. -% Default of ERP.filepath -% format - String of 'mat', 'xls', or 'xlsx', specifying the requsted -% format for the new save files. Default of 'mat'. -% dq_subfield - which entry of the dq substructure to write. -% default of 1 -% -% -function save_data_quality(ERP, filename, format, dq_subfield) - -% Check input -try - assert(isfield(ERP,'dataquality')) - assert(isempty(ERP.dataquality(1).data)==0) -catch - - warning('Problem saving ERP data quality. Missing info?') - beep - return -end - -format_was_empty = 0; -if exist('format','var') == 0 || isempty(format) - format_was_empty = 1; - format = 'mat'; -end - - - - -if exist('dq_subfield','var') == 0 || isempty(dq_subfield) - dq_measures = numel(ERP.dataquality); - if dq_measures == 1 - dq_subfield = 1; - else - for i=1:dq_measures - dq_names{i} = ERP.dataquality(i).type; - end - [s,v] = listdlg('Name','Which DQ','PromptString','Pick measure to write:','SelectionMode','single','ListString',dq_names); - if s>0 - dq_subfield = s; - else - disp('User cancelled Data Quality write') - return - end - end -end - -if exist('filename','var') == 0 || isempty(filename) - % if path missing, prompt from user - %format_options = {'*.xls' ; '*.mat'}; - format_options = {['*.' format];'*.xlsx';'*.mat'}; - pick_str = 'Save Data Quality to file. Pick path:'; - [picked_file, picked_path] = uiputfile(format_options,pick_str); - filename = [picked_path picked_file]; - if isequal(picked_path,0) - disp('File path selected is not valid. Cancelling file write.') - return - end - %filename = [ERP.filepath filesep ERP.erpname '_dataquality.' format]; - [fpath, fname, ext] = fileparts(filename); - - - format = ext(isstrprop(ext,'alpha')); % with picked file, set format to letters of chosen type - -end - - - -[fpath, fname, ext] = fileparts(filename); - - -% check path exists, not overwrite -if isempty(fpath) - filename = [ERP.filepath filesep fname ext]; - [fpath, fname, ext] = fileparts(filename); -end - -if isempty(ext) - filename = [filename '.' format]; -end - - -try - assert(exist(fpath,'dir')==7) % check path is valid -catch - warning('Problem saving ERP data quality - this path does not exist') - return -end - -write_spreadsheet = 0; -spreadsheet_like_formats = {'xls','xlsx'}; -if ismember(format, spreadsheet_like_formats) - write_spreadsheet = 1; -end - -% Try dummy XLS write -if write_spreadsheet - try - blank_cell = {''}; - blank_T = table(blank_cell); - writetable(blank_T, filename); - catch - beep - warning('Excel XLS write server unavailible on this computer?'); - disp('We suggest exporting to a Matlab *.mat file instead.'); - return - end -end - -% write section - -if write_spreadsheet - % set up data to write to spreadsheet - dq = ERP.dataquality(dq_subfield); - dq_fields = fieldnames(ERP.dataquality(dq_subfield)); -% if dq_subfield == 4 -% if sdcorrection == 0 -% dq_datasize = size(ERP.dataquality(dq_subfield).data.SD_bias); -% else -% dq_datasize = size(ERP.dataquality(dq_subfield).data.SD_unbias); -% end -% else -% dq_datasize = size(ERP.dataquality(dq_subfield).data); -% end - - if strcmp(dq.type, 'Point-wise SEM (Corrected)') | strcmp(dq.type, 'Point-wise SEM') - dq_datasize = size(ERP.binerror) - dq.data = ERP.binerror; - dq.times = [repmat(1:dq_datasize(2),[2,1])]'; - dq.time_window_labels = cellstr([repmat('Timepoint ',[dq_datasize(2),1]) num2str(dq.times(:,1))])'; - else - dq_datasize = size(ERP.dataquality(dq_subfield).data); - end - dq_size_str = ''; - for i=1:numel(dq_datasize) - dq_size_str = [dq_size_str ' ' num2str(dq_datasize(i))]; - end - - xls_info = ... - {'ERP Data Quality info from ERPLAB',' '; - ' ', ' '; - 'DQ measure type',dq.type; - 'Data shown on subsequent sheets', ''; - 'Data size:',dq_size_str;}; - - xls_info_T = table(xls_info); - - writetable(xls_info_T,filename,'Sheet',1,'Range','A1','WriteVariableNames',false); - - - - - % Write a list of labels for rows, cols, sheets -% if dq_subfield == 4 -% maxlen = max(size(dq.data.SD_bias)); -% else -% maxlen = max(size(dq.data)); -% end - maxlen = max(size(dq.data)); - Rows = cell(maxlen,1); - Cols = cell(maxlen,1); - Sheets = cell(maxlen,1); - - try - for i=1:ERP.nchan - Rows{i} = ERP.chanlocs(i).labels; - end - for i=1:length(dq.times) - Cols{i} = [num2str(dq.times(i,1)) ' : ' num2str(dq.times(i,2))]; - end - -% if dq_subfield == 4 -% for b=1:size(dq.data.SD_bias,3) -% Sheets{b} = ['Bin ' num2str(b) ' on Sheet ' num2str(b+1)]; -% end -% else - for b=1:size(dq.data,3) - Sheets{b} = ['Bin ' num2str(b) ' on Sheet ' num2str(b+1)]; - end - - - catch - disp('Problem with DQ labels?'); - end - - label_T = table(Rows,Cols,Sheets); - writetable(label_T,filename,'Sheet',1,'Range','A10','WriteVariableNames',true) - - line_start = ['A' num2str(10+3+maxlen)]; - - if any(strcmpi(dq_fields,'time_window_labels')) - time_name = {'Submeasure_Time_window_ranges'}; - xls_times = table(dq.time_window_labels','VariableNames',time_name); - writetable(xls_times,filename,'Sheet',1,'Range',line_start,'WriteVariableNames',true); - %writetable(xls_info_T,filename,'Sheet',1,'Range','A1','WriteVariableNames',false); % write again to sort col widths - end -% - % Bin-like data written to subsequent sheets - Elec = Rows; - for i = 1:dq_datasize(3) - sheet_label = ['Bin ' num2str(i)]; - - for j = 1:size(dq.times,1) - sheet_label = [sheet_label, dq.time_window_labels(j) ]; - end - - - sheet_label_T = table(sheet_label); - writetable(sheet_label_T,filename,'Sheet',i+1,'Range','A1','WriteVariableNames',false); % writecell is introduced in R2019a, so another hacky Table here - Submeasure = nan(maxlen); % square matrix of NaNs at maxlen for table to rectangular with labels. NaNs are not written to Excel file. -% if dq_subfield == 4 -% if sdcorrection == 0 -% Submeasure(1:ERP.nchan,1:size(dq.data.SD_bias,2)) = dq.data.SD_bias(:,:,i); -% else -% Submeasure(1:ERP.nchan,1:size(dq.data.SD_unbias,2)) = dq.data.SD_unbias(:,:,i); -% end -% else -% Submeasure(1:ERP.nchan,1:size(dq.data,2)) = dq.data(:,:,i); -% end - Submeasure(1:ERP.nchan,1:size(dq.data,2)) = dq.data(:,:,i); - xls_d = table(Elec,Submeasure); - writetable(xls_d,filename,'Sheet',1+i,'Range','A2','WriteVariableNames',false); % write data - end - -else - % assume Matlab format - dataquality = ERP.dataquality(dq_subfield); - save(filename,'dataquality') - -end - -conf_str = ['Successfully wrote file ' filename]; -disp(conf_str); - - - +% write data quality substructure to file +% part of the ERPLAB Toolbox +% axs Apr 2019 +% +% Format: +% save_data_quality(ERP, 'dq.mat') +% or save_data_quality(ERP,filename,format_flag) +% +% INPUT: * - mandatory +% * ERP - an ERP structure, which must contain a ERP.dataquality substruct +% filename - a string which will specify the filename of the new saved +% file. This can optionally contain a full path, and/or extension. +% Default of ERP.filepath +% format - String of 'mat', 'xls', or 'xlsx', specifying the requsted +% format for the new save files. Default of 'mat'. +% dq_subfield - which entry of the dq substructure to write. +% default of 1 +function save_data_quality(ERP, filename, format, dq_subfield) + +% Check input +try + assert(isfield(ERP,'dataquality')) + assert(isempty(ERP.dataquality(1).data)==0) +catch + + warning('Problem saving ERP data quality. Missing info?') + beep + return +end + +format_was_empty = 0; +if exist('format','var') == 0 || isempty(format) + format_was_empty = 1; + format = 'mat'; +end + + + + +if exist('dq_subfield','var') == 0 || isempty(dq_subfield) + dq_measures = numel(ERP.dataquality); + if dq_measures == 1 + dq_subfield = 1; + else + for i=1:dq_measures + dq_names{i} = ERP.dataquality(i).type; + end + if isempty(ERP.erpname)%%changed by GH 2022 + title = 'Pick measure to write'; + else + title = {['ERPset:',ERP.erpname],'Pick one measure to write' }; + end + + [s,v] = listdlg('Name','Which DQ?','PromptString',title,'SelectionMode','single','ListString',dq_names,... + 'ListSize',[250,340]);%%changed by GH 2022 + if s>0 + dq_subfield = s; + else + disp('User cancelled Data Quality write') + return + end + end +end + +if exist('filename','var') == 0 || isempty(filename) + % if path missing, prompt from user + %format_options = {'*.xls' ; '*.mat'}; + format_options = {['*.' format];'*.xls';'*.mat'}; + pick_str = 'Save Data Quality to file. Pick path:'; + [picked_file, picked_path] = uiputfile(format_options,pick_str); + filename = [picked_path picked_file]; + if isequal(picked_path,0) + disp('File path selected is not valid. Cancelling file write.') + return + end + %filename = [ERP.filepath filesep ERP.erpname '_dataquality.' format]; + [fpath, fname, ext] = fileparts(filename); + + + format = ext(isstrprop(ext,'alpha')); % with picked file, set format to letters of chosen type + +end + + + +[fpath, fname, ext] = fileparts(filename); + + +% check path exists, not overwrite +if isempty(fpath) + filename = [ERP.filepath filesep fname ext]; + [fpath, fname, ext] = fileparts(filename); +end + +if isempty(ext) + filename = [filename '.' format]; +end + + +try + assert(exist(fpath,'dir')==7) % check path is valid +catch + warning('Problem saving ERP data quality - this path does not exist') + return +end + +write_spreadsheet = 0; +spreadsheet_like_formats = {'xls','xlsx'}; +if ismember(format, spreadsheet_like_formats) + write_spreadsheet = 1; +end + +% Try dummy XLS write +if write_spreadsheet + try + blank_cell = {''}; + blank_T = table(blank_cell); + writetable(blank_T, filename); + catch + beep + warning('Excel XLS write server unavailible on this computer?'); + disp('We suggest exporting to a Matlab *.mat file instead.'); + return + end +end + +% write section + +if write_spreadsheet + % set up data to write to spreadsheet + dq = ERP.dataquality(dq_subfield); + dq_fields = fieldnames(ERP.dataquality(dq_subfield)); + dq_datasize = size(ERP.dataquality(dq_subfield).data); + dq_size_str = ''; + for i=1:numel(dq_datasize) + dq_size_str = [dq_size_str ' ' num2str(dq_datasize(i))]; + end + + xls_info = ... + {'ERP Data Quality info from ERPLAB',' '; + ' ', ' '; + 'DQ measure type',dq.type; + 'Data shown on subsequent sheets', ''; + 'Data size:',dq_size_str;}; + + xls_info_T = table(xls_info); + + writetable(xls_info_T,filename,'Sheet',1,'Range','A1','WriteVariableNames',false); + + + + + % Write a list of labels for rows, cols, sheets + maxlen = max(size(dq.data)); + Rows = cell(maxlen,1); + Cols = cell(maxlen,1); + Sheets = cell(maxlen,1); + + try + for i=1:ERP.nchan + Rows{i} = ERP.chanlocs(i).labels; + end + for i=1:length(dq.times) + Cols{i} = [num2str(dq.times(i,1)) ' : ' num2str(dq.times(i,2))]; + end + for b=1:size(dq.data,3) + Sheets{b} = ['Bin ' num2str(b) ' on Sheet ' num2str(b+1)]; + end + + catch + disp('Problem with DQ labels?'); + end + + label_T = table(Rows,Cols,Sheets); + writetable(label_T,filename,'Sheet',1,'Range','A10','WriteVariableNames',true) + + line_start = ['A' num2str(10+3+maxlen)]; + + if any(strcmpi(dq_fields,'time_window_labels')) + time_name = {'Submeasure_Time_window_ranges'}; + xls_times = table(dq.time_window_labels','VariableNames',time_name); + writetable(xls_times,filename,'Sheet',1,'Range',line_start,'WriteVariableNames',true); + %writetable(xls_info_T,filename,'Sheet',1,'Range','A1','WriteVariableNames',false); % write again to sort col widths + end + + % Bin-like data written to subsequent sheets + Elec = Rows; + for i = 1:dq_datasize(3) + sheet_label = ['Bin ' num2str(i)]; + + for j = 1:size(dq.times,1) + sheet_label = [sheet_label, dq.time_window_labels(j) ]; + end + + + sheet_label_T = table(sheet_label); + writetable(sheet_label_T,filename,'Sheet',i+1,'Range','A1','WriteVariableNames',false); % writecell is introduced in R2019a, so another hacky Table here + Submeasure = nan(maxlen); % square matrix of NaNs at maxlen for table to rectangular with labels. NaNs are not written to Excel file. + Submeasure(1:ERP.nchan,1:size(dq.data,2)) = dq.data(:,:,i); + xls_d = table(Elec,Submeasure); + writetable(xls_d,filename,'Sheet',1+i,'Range','A2','WriteVariableNames',false); % write data + end + +else + % assume Matlab format + dataquality = ERP.dataquality(dq_subfield); + save(filename,'dataquality') + +end + +conf_str = ['Successfully wrote file ' filename]; +disp(conf_str); + + + diff --git a/functions/save_spectral_dq.m b/functions/save_spectral_dq.m old mode 100644 new mode 100755 diff --git a/functions/sme_analytic.m b/functions/sme_analytic.m old mode 100644 new mode 100755 diff --git a/functions/updatemenuerp.m b/functions/updatemenuerp.m index a6094894..cb391a78 100755 --- a/functions/updatemenuerp.m +++ b/functions/updatemenuerp.m @@ -11,7 +11,7 @@ % % % *** This function is part of ERPLAB Toolbox *** -% Author: Javier Lopez-Calderon +% Author: Javier Lopez-Calderon % Center for Mind and Brain % University of California, Davis, % Davis, CA @@ -40,109 +40,132 @@ function updatemenuerp(ALLERP, overw) if nargin<2 - overw=0; % overwrite erpset menu? 0=no; 1=yes; -1=delete + overw=0; % overwrite erpset menu? 0=no; 1=yes; -1=delete end % % Checks ERPpsets menu status % +global observe_ERPDAT; + + erpmenu = findobj('tag', 'erpsets'); staterpm = get(erpmenu, 'Enable'); if strcmp(staterpm,'off') - set(erpmenu, 'Enable', 'on'); % activates erpsets menu + set(erpmenu, 'Enable', 'on'); % activates erpsets menu end maxindexerp = length(ALLERP); ERPSETMENU = zeros(1,maxindexerp); erpsetlist = findobj('tag', 'linerp'); % size of the list at erpset menu if isempty(erpsetlist) - nerpset = 0; - overw = 0; % add a new erpset + nerpset = 0; + overw = 0; % add a new erpset elseif length(erpsetlist)>maxindexerp %10-25-11 - nerpset = length(erpsetlist); - overw=-1; % delete erpset + nerpset = length(erpsetlist); + overw=-1; % delete erpset elseif length(erpsetlist)Erpset ' num2str(indexerp) ': ' erpn '']; - set( ERPSETMENU(indexerp), 'Label', menutitle); - set( ERPSETMENU(indexerp), 'CallBack', ferp ); - set( ERPSETMENU(indexerp), 'Enable', 'on' ); - indexerp = indexerp + 1; - end - if maxindexerp~=0 - erp2memory(ALLERP(maxindexerp), maxindexerp); - end + if overw==0 % add a new erpset to the erpset menu + indexerp = nerpset + 1; + else % delete erpset from the menu + menux = findobj(0, 'tag', 'erpsets'); + h = get(menux); + delete(h.Children); + indexerp = 1; + if maxindexerp==0 + assignin('base','CURRENTERP', 0); % save to workspace + set(erpmenu, 'enable', 'off'); + %%changed by GH Apr 2023 + observe_ERPDAT.ALLERP = []; + observe_ERPDAT.Two_GUI = 1; + cprintf('red',['\n ERP Wave Viewer will be closed because ALLERP is empty.\n\n']); + %%change end + + return + end + end + while indexerp <= maxindexerp + ERPSETMENU(indexerp) = uimenu( erpmenu, 'tag', 'linerp'); + ferp = [ 'erp2memory(ALLERP(' num2str(indexerp) '),' num2str(indexerp) ');' ]; + erpn = ALLERP(indexerp).erpname; + if iscell(erpn) + erpn = ''; + end + menutitle = ['Erpset ' num2str(indexerp) ': ' erpn '']; + set( ERPSETMENU(indexerp), 'Label', menutitle); + set( ERPSETMENU(indexerp), 'CallBack', ferp ); + set( ERPSETMENU(indexerp), 'Enable', 'on' ); + indexerp = indexerp + 1; + end + if maxindexerp~=0 + erp2memory(ALLERP(maxindexerp), maxindexerp); + end else - error('ERPLAB says: Wrong input parameter') + error('ERPLAB says: Wrong input parameter') end eeglab redraw; -%% check DQ options of erpset & make changes to ERPlab menu +%% check DQ options of erpset & make changes to ERPlab menu -% erplabmenu = findobj('tag', 'ERPLAB'); +% erplabmenu = findobj('tag', 'ERPLAB'); % %W_MAIN = findobj('tag', 'EEGLAB'); % allmenus = findobj( erplabmenu, 'type', 'uimenu'); % allstrs = get(allmenus, 'Label'); option1 = findobj('Label', 'Show Data Quality measures in table'); -option2 = findobj('Label', 'Summarize Data Quality (min, median, max)'); -option3 = findobj('Label', 'Save Data Quality measures to file'); +option2 = findobj('Label', 'Summarize Data Quality (min, median, max)'); +option3 = findobj('Label', 'Save Data Quality measures to file'); -ERP = ALLERP(maxindexerp); +ERP = ALLERP(maxindexerp); if isfield(ERP,'dataquality') & ~strcmp(ERP.dataquality(1).type,'empty') - %if there is dataquality measures, make DQ menu options available + %if there is dataquality measures, make DQ menu options available set(option1, 'enable', 'on'); set(option2, 'enable', 'on'); - set(option3, 'enable', 'on'); - + set(option3, 'enable', 'on'); + else set(option1, 'enable', 'off'); set(option2, 'enable', 'off'); - set(option3, 'enable', 'off'); - + set(option3, 'enable', 'off'); end - + + +%%changed GZ Mar. 2023 +CURRENTERP = maxindexerp; +if ~isempty(ALLERP)%%if + observe_ERPDAT.ALLERP =ALLERP; + if isempty(CURRENTERP) || CURRENTERP<=0 || CURRENTERP> length(ALLERP) + CURRENTERP= length(ALLERP); + end + observe_ERPDAT.CURRENTERP = CURRENTERP; + observe_ERPDAT.ERP = ALLERP(CURRENTERP); + observe_ERPDAT.Two_GUI = 1; +else + observe_ERPDAT.ALLERP = []; + observe_ERPDAT.Two_GUI = 1; end - - - - - +end + + + + + diff --git a/images/colormap_lic/colormap_lic_viridis.txt b/images/colormap_lic/colormap_lic_viridis.txt old mode 100644 new mode 100755 diff --git a/images/viridis.m b/images/viridis.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_DQ_preavg.m b/pop_functions/pop_DQ_preavg.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_ERP_simulation.m b/pop_functions/pop_ERP_simulation.m new file mode 100644 index 00000000..e792c9f1 --- /dev/null +++ b/pop_functions/pop_ERP_simulation.m @@ -0,0 +1,832 @@ +%%This function is to create simulated ERPset with single channel and bin + +%Format: +% [ERP, erpcom] = pop_ERP_simulation(ALLERP,BasFuncName,'EpochStart',EpochStart,'EpochStop',EpochStop,'Srate',Srate,'BasPeakAmp',... +% BasPeakAmp,'MeanLatencyOnset',MeanLatOnset,'SDOffset',SDOffset,'ExGauTau',ExGauTau,'SinoiseAmp',SinoiseAmp,'SinoiseFre',SinoiseFre,... +% 'WhiteAmp',WhiteAmp,'PinkAmp',PinkAmp,'Saveas', 'off','History', 'gui'); + +% Inputs: +% +%ALLERP - structure array of ERP structures (ERPsets) +% To read the ERPset from a list in a text file, +% replace ALLERP by the whole filename. If there is no +% ALLERP, please use [] instead. +%BasFuncName -Name for basic function. We, here, provide three +% options, "Exgaussian", "Impulse", and "Boxcar". + +%The available parameters are as follows: +%EpochStart - epoch start in millisecond e.g., -200 +%EpochStop - epoch stop in millisecond e.g., 800 +%Srate - sampling rate. e.g., 1000Hz +%BasPeakAmp - peak amplitude for basic function e.g., 1 +%MeanLatencyOnset - gaussian mean for Ex-Guassian function, Latency for impulse +% function, and onset for boxcar +%SDOffset - SD for Ex-Guassian function and off set for boxcar +%ExGauTau -Exponential tau for ex-Gaussian function in ms +%SinoiseAmp -Peak amplitude for sinusoidal function +%SinoiseFre -Frequency for sinusoidal function +%WhiteAmp -peak amplitude for white noise e.g., 1 +%PinkAmp -peak amplitude for pink noise e.g., 1 +%NewnoiseFlag -1. create a new seed for the random number generator +% 0. Use the same seed as before + +% Author: Guanghui Zhang & Steve J. Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% Mar. 2023 + + + +function [ERP, erpcom] = pop_ERP_simulation(ALLERP,BasFuncName, varargin) +erpcom = []; +ERP = []; + +if nargin < 1 + help pop_ERP_simulation + return; +end + +if nargin==1 || nargin==2 %with GUI to get other parameters + if nargin==1 + BasFuncName = 'Exgaussian'; + end + + def = erpworkingmemory('pop_ERP_simulation'); + if isempty(def) + def = {1,1,100,50,1000,-200,799,1,1000,0,1,0,1,0,1,10,0}; + end + + if isempty(BasFuncName) || ~ischar(BasFuncName) + BasFunLabel = 1; + else + if strcmpi(BasFuncName,'Impulse') + BasFunLabel = 2; + elseif strcmpi(BasFuncName,'Boxcar') + BasFunLabel = 3; + else + BasFunLabel = 1; + end + end + def{1} = BasFunLabel; + def = f_ERP_simulation_GUI(def,ALLERP); + + if isempty(def) + disp('User selected Cancel') + return + end + erpworkingmemory('pop_ERP_simulation',def); + BasFunLabel = def{1}; + + if BasFunLabel==2 + BasFuncName = 'Impulse'; + elseif BasFunLabel==3 + BasFuncName = 'Boxcar'; + else + BasFuncName = 'Exgaussian'; + end + + try + BasPeakAmp = def{2}; + catch + BasPeakAmp =1; + end + if isempty(BasPeakAmp) + BasPeakAmp =1; + end + + %%Mean/onset + try + MeanLatOnset = def{3}; + catch + MeanLatOnset =100; + end + if isempty(MeanLatOnset) + MeanLatOnset =100; + end + + %%SD/offset + try + SDOffset= def{4}; + catch + SDOffset =50; + end + if isempty(SDOffset) + SDOffset =50; + end + + %%ExGauTau + try + ExGauTau = def{5}; + catch + ExGauTau =1; + end + if isempty(ExGauTau) + ExGauTau =1; + end + + %%epoch start + try + EpochStart = def{6}; + catch + EpochStart = -200; + end + if isempty(EpochStart) + EpochStart = -200; + end + + %%epoch stop + try + EpochStop = def{7}; + catch + EpochStop = 800; + end + if isempty(EpochStop) + EpochStop = 800; + end + + %%sampling rate + try + Srate = def{9}; + catch + Srate = 1000; + end + if isempty(Srate) + Srate = 1000; + end + + %%Amplitude for sin noise + try + SinoiseFlag = def{14}; + catch + SinoiseFlag =0; + end + + if SinoiseFlag==0 + SinoiseAmp = 0; + else + try + SinoiseAmp =def{15}; + catch + SinoiseAmp=1; + end + end + + try + SinoiseFre = def{16}; + catch + SinoiseFre =10; + end + + %%white noise + try + whitenoiseFlag = def{10}; + catch + whitenoiseFlag =0; + end + + if whitenoiseFlag==0 + WhiteAmp =0; + else + try + WhiteAmp = def{11}; + catch + WhiteAmp=1; + end + end + + %%pink noise + try + pinknoiseFlag = def{12}; + catch + pinknoiseFlag =0; + end + if pinknoiseFlag==0 + PinkAmp =0; + else + try + PinkAmp = def{13}; + catch + PinkAmp=1; + end + end + + NewnoiseFlag = 0; + try + NewnoiseFlag = def{17}; + catch + end + + [ERP, erpcom] = pop_ERP_simulation(ALLERP,BasFuncName,'EpochStart',EpochStart,'EpochStop',EpochStop,'Srate',Srate,'BasPeakAmp',... + BasPeakAmp,'MeanLatencyOnset',MeanLatOnset,'SDOffset',SDOffset,'ExGauTau',ExGauTau,'SinoiseAmp',SinoiseAmp,'SinoiseFre',SinoiseFre,... + 'WhiteAmp',WhiteAmp,'PinkAmp',PinkAmp,'NewnoiseFlag',NewnoiseFlag,'Saveas', 'on','History', 'gui'); + pause(0.1); + return; +end + + + +% +% Parsing inputs +% +p = inputParser; +p.FunctionName = mfilename; +p.CaseSensitive = false; +p.addRequired('ALLERP'); +p.addRequired('BasFuncName',@ischar); + + +% option(s) +p.addParamValue('EpochStart',[],@isnumeric); +p.addParamValue('EpochStop',[],@isnumeric); +p.addParamValue('Srate',[],@isnumeric); +p.addParamValue('BasPeakAmp', [],@isnumeric); +p.addParamValue('MeanLatencyOnset', [],@isnumeric); +p.addParamValue('SDOffset', [],@isnumeric); +p.addParamValue('ExGauTau', [],@isnumeric); + +p.addParamValue('SinoiseAmp', [],@isnumeric);%%sinusoidal noise in Amplitude +p.addParamValue('SinoiseFre', [],@isnumeric);%%sinusoidal noise in Hz +p.addParamValue('WhiteAmp', [],@isnumeric);%%sinusoidal noise in Hz +p.addParamValue('PinkAmp', [],@isnumeric);%%sinusoidal noise in Hz +p.addParamValue('NewnoiseFlag', [],@isnumeric); + +p.addParamValue('Saveas', 'off', @ischar); +p.addParamValue('History', 'script', @ischar); + +% Parsing +p.parse(ALLERP,BasFuncName,varargin{:}); + +if strcmpi(p.Results.History,'implicit') + shist = 3; % implicit +elseif strcmpi(p.Results.History,'script') + shist = 2; % script +elseif strcmpi(p.Results.History,'gui') + shist = 1; % gui +else + shist = 0; % off +end + +ImpluseFlag = ''; +BoxCarFlag = ''; +GaussianFlag = ''; +qBasFuncName = p.Results.BasFuncName; +if strcmpi(qBasFuncName,'Impulse') + qBasFunLabel = 2; + ImpluseFlag = 'on'; +elseif strcmpi(qBasFuncName,'Boxcar') + qBasFunLabel = 3; + BoxCarFlag = 'on'; +else + qBasFunLabel = 1; + GaussianFlag = 'on'; +end + +%%peak amplitude for basic function +qBasPeakAmp = p.Results.BasPeakAmp; +if isempty(qBasPeakAmp) + qBasPeakAmp = 0; +else + if numel(qBasPeakAmp)~=1 + qBasPeakAmp =qBasPeakAmp(1); + end +end + +%%Mean/latency/onset for basic function +qMeanLatOnset = p.Results.MeanLatencyOnset; +if isempty(qMeanLatOnset) + qMeanLatOnset =100; +else + if numel(qMeanLatOnset)~=1 + qMeanLatOnset = qMeanLatOnset(1); + end +end + + +%%SD or offset for basic function +qSDOffset = p.Results.SDOffset; +if isempty(qSDOffset) + qSDOffset=50; +else + if numel(qSDOffset)~=1 + qSDOffset = qSDOffset(1); + end +end + +%%Tau for exGuassian +ExGauTau = p.Results.ExGauTau; +if isempty(ExGauTau) + ExGauTau =0; +else + if numel(ExGauTau)~=1 + ExGauTau = ExGauTau(1); + end +end +ExGauTau =ExGauTau/1000; + +%%Epoch start +EpochStart = p.Results.EpochStart; +if isempty(EpochStart) + EpochStart = -200; +else + if numel(EpochStart)~=1 + EpochStart = EpochStart(1); + end +end + +%%Epoch Stop +EpochStop = p.Results.EpochStop; +if isempty(EpochStop) + EpochStop = 799; +else + if numel(EpochStop)~=1 + EpochStop = EpochStop(1); + end +end + + +if EpochStop<=EpochStart + msgboxText = 'Start time of epoch must be smaller than stop time of epoch!'; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; +end + +if qMeanLatOnset< EpochStart + msgboxText = [' "MeanLatencyOnset" should be larger than',32,num2str(EpochStop),'ms']; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; +end + + +if qMeanLatOnset > EpochStop + msgboxText = [' "MeanLatencyOnset" should be smaller than',32,num2str(EpochStop),'ms']; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; +end +if strcmpi(BasFuncName,'Exgaussian') + if qSDOffset<=0 + msgboxText = [' "SDOffset" for EX-Gaussian function should be a positive number.']; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + end +end + +if strcmpi(BasFuncName,'Boxcar') + if qSDOffset > EpochStop + msgboxText = [' "SDOffset" for Boxcar function should be smaller than',32,num2str(EpochStop),'ms']; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; + end + + if qMeanLatOnset>qSDOffset + msgboxText = [' "MeanLatencyOnset" for Boxcar function should be smaller than',32, num2str(qSDOffset),'ms']; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; + end +end + + + +%%Sampling rate +Srate = p.Results.Srate; +if isempty(Srate) + Srate = 1000; +else + if numel(Srate)~=1 + Srate = Srate(1); + end +end + +if 1000/Srate>= (EpochStop-EpochStart) + msgboxText = ['Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)]; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; +end + + +Times = []; + +if EpochStart>=0 + count =0; + tIndex(1,1) =0; + for ii = 1:10000 + count = count+1000/Srate; + if count<=EpochStop + tIndex(1,ii) = count; + else + break; + end + end + + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + Times = tIndex(latsamp(1):end); + if Times(1)=EpochStart + tIndex(1,ii) = count; + else + break; + end + end + tIndex = sort(tIndex); + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + + Times = tIndex(1:latsamp(2)); + if Times(end)> EpochStop + Times(end) = []; + end +elseif EpochStart<0 && EpochStop>0 + tIndex1(1,1) = 0; + count =0; + for ii = 1:10000 + count = count-1000/Srate; + if count>=EpochStart + tIndex1(1,ii+1) = count; + else + break; + end + end + tIndex2=[]; + count1 =0; + for ii = 1:10000 + count1 = count1+1000/Srate; + if count1<=EpochStop + tIndex2(1,ii) = count1; + else + break; + end + end + Times = [sort(tIndex1),tIndex2]; +end + +[x1,y1] = find(roundn(Times,-3)==roundn(EpochStart,-3)); + + +[x2,y2] = find(roundn(Times,-3)==roundn(EpochStop,-3)); +if isempty(y1) || isempty(y2) + msgboxText = 'Warning: The exact time periods you have specified cannot be exactly created with the specified sampling rate. We will round to the nearest possible time values when the ERPset is created.'; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + % return; +end + +%%Amplitude for basic function +qBasPeakAmp = p.Results.BasPeakAmp; + +if isempty(qBasPeakAmp) + qBasPeakAmp =0; +else + if numel(qBasPeakAmp)~=1 + qBasPeakAmp = qBasPeakAmp(1); + end +end + + +%%mean/latency/onset for basic function +qMeanLatencyOnset = p.Results.MeanLatencyOnset; +if isempty(qMeanLatencyOnset) + qMeanLatencyOnset=100; +else + if numel(qMeanLatencyOnset)~=1 + qMeanLatencyOnset =qMeanLatencyOnset(1); + end +end + + +%%SD/offset for basic function +qSD_Offset = p.Results.SDOffset; +if isempty(qSD_Offset) + qSD_Offset =50; +else + if numel(qSD_Offset)~=1 + qSD_Offset =qSD_Offset(1); + end +end + +%%Tau for ex-Gaussian function +qExGauTau = p.Results.ExGauTau; +if isempty(qExGauTau) + qExGauTau =1; +else + if numel(qExGauTau)~=1 + qExGauTau = qExGauTau(1); + end +end + +%%Amplitude for sin noise +qSinoiseAmp = p.Results.SinoiseAmp; +if isempty(qSinoiseAmp) + qSinoiseAmp =0; +else + if numel(qSinoiseAmp)~=1 + qSinoiseAmp = qSinoiseAmp(1); + end +end + +qSinoiseFre = p.Results.SinoiseFre; +if isempty(p.Results.SinoiseFre) + qSinoiseFre =10; +else + if numel(qSinoiseFre)~=1 + qSinoiseFre = qSinoiseFre(1); + end +end + + +%%Amplitude for white noise +qWhiteAmp = p.Results.WhiteAmp; +if isempty(qWhiteAmp) + qWhiteAmp =0; +else + if numel(qWhiteAmp)~=1 + qWhiteAmp = qWhiteAmp(1); + end +end + + +%%Amplitude for pink noise +qPinkAmp = p.Results.PinkAmp; +if isempty(qPinkAmp) + qPinkAmp =0; +else + if numel(qPinkAmp)~=1 + qPinkAmp =qPinkAmp(1); + end +end + + +qNewnoiseFlag = p.Results.NewnoiseFlag; +if isempty(qNewnoiseFlag) + qNewnoiseFlag =0; +end +if numel(qNewnoiseFlag)~=1 + qNewnoiseFlag = qNewnoiseFlag(1); +end +%%------------------------------the data for basic function---------------- +Desiredsignal = zeros(1,numel(Times)); +Desirednosizesin = zeros(1,numel(Times)); +Desirednosizewhite = zeros(1,numel(Times)); +Desirednosizepink = zeros(1,numel(Times)); + +if qBasFunLabel==1 + Gua_PDF = zeros(1,numel(Times)); + qSDOffset = qSDOffset/100; + if ExGauTau~=0 + Mu = qMeanLatOnset/100-Times(1)/100; + if Mu<0 + Mu = qMeanLatOnset/100; + end + if ExGauTau<0 + Mu = abs((Times(end)/100-Times(1)/100)-Mu); + end + LegthSig = (Times(end)-Times(1))/100; + Sig = 0:LegthSig/numel(Times):LegthSig-LegthSig/numel(Times); + Gua_PDF = f_exgauss_pdf(Sig, Mu, qSDOffset, abs(ExGauTau)); + if ExGauTau<0 + Gua_PDF = fliplr(Gua_PDF); + end + elseif ExGauTau==0 %%Gaussian signal + Times_new = Times/1000; + Gua_PDF = f_gaussian(Times_new,abs(qBasPeakAmp),qMeanLatOnset/1000,qSDOffset/10); + end + Max = max(abs( Gua_PDF(:))); + Gua_PDF = qBasPeakAmp*Gua_PDF./Max; + if qBasPeakAmp~=0 + Desiredsignal = Gua_PDF; + end +elseif qBasFunLabel==2 + + if qMeanLatOnsetTimes(end) + qMeanLatOnset=Times(end); + end + [xxx, latsamp, latdiffms] = closest(Times, qMeanLatOnset); + Desiredsignal(latsamp) = qBasPeakAmp; +elseif qBasFunLabel==3 + if qMeanLatOnset> qSDOffset + msgboxText = 'Please "offset" should be larger than "onset" of boxcar function!'; + title = 'ERPLAB: pop_ERP_simulation() error'; + errorfound(msgboxText, title); + return; + end + [xxx, latsamp, latdiffms] = closest(Times, [qMeanLatOnset,qSDOffset]); + Desiredsignal(latsamp(1):latsamp(2)) = qBasPeakAmp; +end + +%%----------------------Noise---------------------------------------------- +SimulationSeed = erpworkingmemory('SimulationSeed'); +try + SimulationSeed_Type = SimulationSeed.Type; + SimulationSeed_seed=SimulationSeed.Seed; +catch + SimulationSeed_Type = 'twister'; + SimulationSeed_seed = 1; +end +%phase for sin noise +SimulationPhase = erpworkingmemory('SimulationPhase'); +if isempty(SimulationPhase) || ~isnumeric(SimulationPhase) + SimulationPhase = 0; +end +if numel(SimulationPhase)~=1 + SimulationPhase = SimulationPhase(1); +end +if SimulationPhase<0 || SimulationPhase>1 + SimulationPhase = 0; +end + +if qNewnoiseFlag==1 + %%reset the phase + SimulationPhase = rand(1); + + %%reset the seed + SimulationSeed_Type = 'twister'; + SimulationSeed_seed = SimulationSeed_seed+1; +end + +%%sin Noise +X = Times/1000; +Desirednosizesin = qSinoiseAmp*sin(2*qSinoiseFre*pi*X+2*pi*SimulationPhase); + +%%white noise +try + rng(SimulationSeed_seed,SimulationSeed_Type); +catch + rng(0,'twister'); +end +Desirednosizewhite = randn(1,numel(Times));%%white noise +Desirednosizewhite = qWhiteAmp*Desirednosizewhite; + +%%pink noise +try + rng(SimulationSeed_seed,SimulationSeed_Type); +catch + rng(0,'twister'); +end + +Desirednosizepink = f_pinknoise(numel(Times)); +Desirednosizepink = reshape(Desirednosizepink,1,numel(Desirednosizepink)); +Desirednosizepink = qPinkAmp*Desirednosizepink; + +Sig = Desirednosizesin+Desiredsignal+Desirednosizepink+Desirednosizewhite; +ERPautx = buildERPstruct([]); +ERPautx.bindata = zeros(1,numel(Times),1); +ERPautx.bindata(1,1:numel(Sig),1)=Sig; +ERPautx.bindescr{1} = 'Artificial ERP wave'; +ERPautx.chanlocs(1).labels = 'Artificial ERP wave'; + +ERPautx.xmin = Times(1)/1000; +ERPautx.xmax = Times(end)/1000; +ERPautx.times = Times; +ERPautx.nchan = 1; +ERPautx.nbin = 1; +ERPautx.pnts = numel(Times); +ERPautx.erpname ='Cretedartificialwave'; +ERPautx.srate = Srate; +ERPautx.saved = 'no'; + +% +% History +% +% +% Completion statement +% +msg2end + +% History command +% +fn = fieldnames(p.Results); + +skipfields = {'ALLERP','BasFuncName'}; + +EpochStartstr = num2str(EpochStart); +EpochStopStr = num2str(EpochStop); +Sratestr = num2str(Srate); +% PLOTORGstr = vect2colon(qPLOTORG); +erpcom = sprintf( 'ERP = pop_ERP_simulation( %s, %s','ALLERP',[char(39),BasFuncName,char(39)]); + +if strcmpi(BoxCarFlag,'on') + skipfields = {'ALLERP','BasFuncName','ExGauTau'}; +end +if strcmpi(ImpluseFlag,'on') + skipfields = {'ALLERP','BasFuncName','ExGauTau','SDOffset'}; +end + +def = erpworkingmemory('pop_ERP_simulation'); +try + SinoiseFlag = def{14}; +catch + SinoiseFlag =0; +end + +try + whitenoiseFlag = def{10}; +catch + whitenoiseFlag =0; +end + +try + pinknoiseFlag = def{12}; +catch + pinknoiseFlag =0; +end +if SinoiseFlag==0 + skipfields{length(skipfields)+1} ='SinoiseAmp'; + skipfields{length(skipfields)+1} ='SinoiseFre'; +end +if whitenoiseFlag==0 + skipfields{length(skipfields)+1} = 'WhiteAmp'; +end + +if pinknoiseFlag==0 + skipfields{length(skipfields)+1} = 'PinkAmp'; +end + +if pinknoiseFlag==0 + skipfields{length(skipfields)+1} = 'NewnoiseFlag'; +end + +for q=1:length(fn) + fn2com = fn{q}; % inputname + if ~ismember_bc2(fn2com, skipfields) + fn2res = p.Results.(fn2com); % input value + if ~isempty(fn2res) + if isnumeric(fn2res) + erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, vect2colon(fn2res,'Repeat','on')); + else + % if ~ismember_bc2(fn2com,{'xscale','yscale'}) + % erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, vect2colon(fn2res,'Repeat','on')); + % else + % xyscalestr = sprintf('[ %.1f %.1f %s ]', fn2res(1), fn2res(2), vect2colon(fn2res(3:end),'Delimiter','off')); + % erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, xyscalestr); + % end + end + end + end +end +erpcom = sprintf( '%s );', erpcom); + + +if strcmpi(p.Results.Saveas,'on') + issaveas = 1; +else + issaveas = 0; +end +% +% Save ERPset from GUI +% +if issaveas + [ERP, issave, erpcom_save] = pop_savemyerp(ERPautx,'gui','erplab', 'History', 'off'); + if issave>0 + % erpcom = sprintf( '%s = pop_filterp( %s, %s, %s, %s, %s, ''%s'', %s);', inputname(1), inputname(1),... + % chanArraystr, num2str(locutoff), num2str(hicutoff),... + % num2str(filterorder), lower(fdesign), num2str(remove_dc)); + % erpcom = sprintf('%s\n%s', erpcom, erpcom_save); + if issave==2 + erpcom = sprintf('%s\n%s', erpcom, erpcom_save); + msgwrng = '*** Your ERPset was saved on your hard drive.***'; + %mcolor = [0 0 1]; + else + msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; + %mcolor = [1 0.52 0.2]; + end + else + ERP = ERPautx; + msgwrng = 'ERPLAB Warning: Your changes were not saved'; + %mcolor = [1 0.22 0.2]; + end + try cprintf([1 0.52 0.2], '%s\n\n', msgwrng); catch,fprintf('%s\n\n', msgwrng);end ; +else + ERP = ERPautx; +end + + +% get history from script. ERP +% shist = 1; +switch shist + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + ERP = erphistory(ERP, [], erpcom, 1); + case 3 + % implicit + otherwise %off or none + erpcom = ''; +end + + +end \ No newline at end of file diff --git a/pop_functions/pop_averager.m b/pop_functions/pop_averager.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_basicfilter.m b/pop_functions/pop_basicfilter.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_blcerp.m b/pop_functions/pop_blcerp.m index 01d858bf..c14cb03f 100755 --- a/pop_functions/pop_blcerp.m +++ b/pop_functions/pop_blcerp.m @@ -1,6 +1,6 @@ % PURPOSE : Removes ERP baseline -% -% FORMAT : +% +% FORMAT : % % ERP = pop_blcerp(ERP, blc) % @@ -14,13 +14,13 @@ % >> ERP = pop_blcerp( ERP , [-400 2000], 'post'); % % INPUTS : -% +% % ERP - ERPLAB structure -% blc - window for baseline correction in msec or either a string like +% blc - window for baseline correction in msec or either a string like % 'none', 'pre', 'post', or 'whole' -% +% % OUTPUTS : -% +% % - updated (output) ERPset % % *** This function is part of ERPLAB Toolbox *** @@ -33,7 +33,7 @@ %b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b % % ERPLAB Toolbox -% Copyright 2007 The Regents of the University of California +% Copyright © 2007 The Regents of the University of California % Created by Javier Lopez-Calderon and Steven Luck % Center for Mind and Brain, University of California, Davis, % javlopez@ucdavis.edu, sjluck@ucdavis.edu @@ -54,48 +54,48 @@ function [ERP, erpcom] = pop_blcerp(ERP, varargin) erpcom = ''; if nargin < 1 - help pop_blcerp - return + help pop_blcerp + return end datatype = checkdatatype(ERP); % % Gui is working... % if nargin==1 - title_msg = 'ERPLAB: pop_blcerp() error:'; + title_msg = 'ERPLAB: pop_blcerp() error:'; + if isempty(ERP) + ERP = preloadERP; if isempty(ERP) - ERP = preloadERP; - if isempty(ERP) - msgboxText = 'No ERPset was found!'; - errorfound(msgboxText, title_msg); - return - end - end - if isempty(ERP.bindata) - msgboxText = 'cannot work with an empty erpset!'; - errorfound(msgboxText, title_msg); - return - end - if ~strcmpi(datatype, 'ERP') - msgboxText = 'Cannot baseline Power Spectrum waveforms. Sorry'; - errorfound(msgboxText, title_msg); - return + msgboxText = 'No ERPset was found!'; + errorfound(msgboxText, title_msg); + return end - - titlegui = 'Baseline Correction'; - answer = blcerpGUI(ERP, titlegui ); % open GUI - - if isempty(answer) - disp('User selected Cancel') - return - end - blcorr = answer{1}; - - % - % Somersault - % - [ERP, erpcom] = pop_blcerp(ERP, 'Baseline', blcorr, 'Saveas', 'on', 'History', 'gui'); + end + if isempty(ERP.bindata) + msgboxText = 'cannot work with an empty erpset!'; + errorfound(msgboxText, title_msg); return + end + if ~strcmpi(datatype, 'ERP') + msgboxText = 'Cannot baseline Power Spectrum waveforms. Sorry'; + errorfound(msgboxText, title_msg); + return + end + + titlegui = 'Baseline Correction'; + answer = blcerpGUI(ERP, titlegui ); % open GUI + + if isempty(answer) + disp('User selected Cancel') + return + end + blcorr = answer{1}; + + % + % Somersault + % + [ERP, erpcom] = pop_blcerp(ERP, 'Baseline', blcorr, 'Saveas', 'on', 'History', 'gui'); + return end % @@ -111,6 +111,9 @@ p.addParamValue('History', 'script', @ischar); % history from scripting p.parse(ERP, varargin{:}); + + + if strcmpi(datatype, 'ERP') kktime = 1000; else @@ -118,71 +121,72 @@ end blcorr = p.Results.Baseline; if strcmpi(p.Results.History,'implicit') - shist = 3; % implicit + shist = 3; % implicit elseif strcmpi(p.Results.History,'script') - shist = 2; % script + shist = 2; % script elseif strcmpi(p.Results.History,'gui') - shist = 1; % gui + shist = 1; % gui else - shist = 0; % off + shist = 0; % off end if ismember_bc2({p.Results.Saveas}, {'on','yes'}) - issaveas = 1; + issaveas = 1; else - issaveas = 0; + issaveas = 0; end if ischar(blcorr) - if ~ismember_bc2(lower(blcorr),{'all' 'pre' 'post' 'none'}) - internum = str2double(blcorr); - if length(internum) ~=2 - msgboxText = ['pop_blcerp will not be performed.\n'... - 'Check out your baseline correction values']; - title = 'ERPLAB: pop_blcerp() base line'; - errorfound(sprintf(msgboxText), title); - return - end - if internum(1)>=internum(2)|| internum(1)>ERP.xmax || internum(2)=internum(2)|| internum(1)>ERP.xmax || internum(2)=blcorr(2)|| blcorr(1)>ERP.xmax*kktime || blcorr(2)=blcorr(2)|| blcorr(1)>ERP.xmax*kktime || blcorr(2)0 - % generate text command - if issave==2 - erpcom = sprintf('%s\n%s', erpcom, erpcom_save); - msgwrng = '*** Your ERPset was saved on your hard drive.***'; - else - msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; - end - fprintf('\n%s\n\n', msgwrng) - try cprintf([0 0 1], 'COMPLETE\n\n');catch,fprintf('COMPLETE\n\n');end ; - else - ERP = ERPaux; - msgwrng = 'ERPLAB Warning: Your changes were not saved'; - try cprintf([1 0.52 0.2], '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; - end +if issaveas + + + [ERP, issave, erpcom_save] = pop_savemyerp(ERP,'gui','erplab', 'History', 'implicit'); + if issave>0 + % generate text command + if issave==2 + erpcom = sprintf('%s\n%s', erpcom, erpcom_save); + msgwrng = '*** Your ERPset was saved on your hard drive.***'; + else + msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; + end + fprintf('\n%s\n\n', msgwrng) + try cprintf([0 0 1], 'COMPLETE\n\n');catch,fprintf('COMPLETE\n\n');end ; + else + ERP = ERPaux; + msgwrng = 'ERPLAB Warning: Your changes were not saved'; + try cprintf([1 0.52 0.2], '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; + end + + + + + end % get history from script. ERP switch shist - case 1 % from GUI - displayEquiComERP(erpcom); - case 2 % from script - ERP = erphistory(ERP, [], erpcom, 1); - case 3 - % implicit - otherwise %off or none - erpcom = ''; + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + ERP = erphistory(ERP, [], erpcom, 1); + case 3 + % implicit + otherwise %off or none + erpcom = ''; end % diff --git a/pop_functions/pop_continuousFFT.m b/pop_functions/pop_continuousFFT.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_currentsourcedensity.m b/pop_functions/pop_currentsourcedensity.m index a3c3be97..40f26ef5 100755 --- a/pop_functions/pop_currentsourcedensity.m +++ b/pop_functions/pop_currentsourcedensity.m @@ -21,7 +21,7 @@ %b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b % % ERPLAB Toolbox -% Copyright 2016 The Regents of the University of California +% Copyright © 2016 The Regents of the University of California % Created by Javier Lopez-Calderon and Steven Luck % Center for Mind and Brain, University of California, Davis, % javlopez@ucdavis.edu, sjluck@ucdavis.edu @@ -51,7 +51,7 @@ end % check input dataset -try +try elec_num = length(EEG.chanlocs); assert(elec_num >= 1) catch @@ -66,7 +66,7 @@ has_loc = zeros(EEG.nbchan,1); end -try +try for i = 1:numel(has_loc) has_loc(i) = EEG.chanlocs(i).X; end @@ -82,11 +82,11 @@ % check CSD tool in path csd_path = which('MapMontage'); if numel(csd_path) == 0 - msgboxText = 'Current Source Density error: Do you have the Jrgen Kayser CSD toolbox in your path?'; + msgboxText = 'Current Source Density error: Do you have the Jürgen Kayser CSD toolbox in your path?'; title = 'ERPLAB: CSD path problems?'; errorfound(msgboxText, title); return - + end @@ -123,16 +123,27 @@ % visually check montage MapMontage(M) -%%% -% Run CSD GUI to get 3 CSD parameters -[csd_param] = csd_generate; +%%%changed by Guanghui August 10 2022 +csd_param = erpworkingmemory('csd_param'); + +ERPtooltype = erpgettoolversion('tooltype'); +if strcmpi(ERPtooltype,'EStudio') + csd_param(4) = 0; + erpworkingmemory('csd_param',csd_param); + csd_param = csd_param(1:3); + savepref=0; +else + [csd_param] = csd_generate; + csd_param(4) = 1; + erpworkingmemory('csd_param',csd_param); +end%%Changing end % check if user cancelled GUI. If so, end here. if numel(csd_param) == 0 display('User selected cancel') return end - + % generate transform matrices [csd_G, csd_H] = GetGH(M, csd_param(1)); diff --git a/pop_functions/pop_eegchanoperator.m b/pop_functions/pop_eegchanoperator.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_erp2asc.m b/pop_functions/pop_erp2asc.m index 11cfd3af..da8fb54d 100755 --- a/pop_functions/pop_erp2asc.m +++ b/pop_functions/pop_erp2asc.m @@ -30,7 +30,7 @@ %b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b % % ERPLAB Toolbox -% Copyright 2007 The Regents of the University of California +% Copyright © 2007 The Regents of the University of California % Created by Javier Lopez-Calderon and Steven Luck % Center for Mind and Brain, University of California, Davis, % javlopez@ucdavis.edu, sjluck@ucdavis.edu @@ -76,8 +76,10 @@ % % Save ascii file - % - [filenamei, pathname] = uiputfile({'*.txt';'*.*'},'Save Exported Averaged file as'); + %Changed by Guanghui August 2022 + [pathx, erpfilename, ext] = fileparts(ERP.filename); + + [filenamei, pathname] = uiputfile({'*.txt';'*.*'},['Save "',ERP.erpname, '" as'],[erpfilename,'.txt']); if isequal(filenamei,0) disp('User selected Cancel') diff --git a/pop_functions/pop_erpchanoperator.m b/pop_functions/pop_erpchanoperator.m index a3543eab..4143d37e 100755 --- a/pop_functions/pop_erpchanoperator.m +++ b/pop_functions/pop_erpchanoperator.m @@ -57,71 +57,71 @@ function [ERP, erpcom] = pop_erpchanoperator(ERP, formulas, varargin) erpcom = ''; if nargin < 1 - help pop_erpchanoperator - return + help pop_erpchanoperator + return end if nargin==1 + if isempty(ERP) + ERP = preloadERP; if isempty(ERP) - ERP = preloadERP; - if isempty(ERP) - msgboxText = 'No ERPset was found!'; - title_msg = 'ERPLAB: pop_erpchanoperator() error:'; - errorfound(msgboxText, title_msg); - return - end - end - if ~iserpstruct(ERP) - msgboxText = 'Invalid ERP structure!'; - title_msg = 'ERPLAB: pop_erpchanoperator() error:'; - errorfound(msgboxText, title_msg); - return - end - if ~isfield(ERP,'bindata') %(ERP.bindata) - msgboxText = 'Cannot work on an empty ERPset!'; - title_msg = 'ERPLAB: pop_erpchanoperator() error:'; - errorfound(msgboxText, title_msg); - return - end - if isempty(ERP.bindata) %(ERP.bindata) - msgboxText = 'Cannot work on an empty ERPset!'; - title_msg = 'ERPLAB: pop_erpchanoperator() error:'; - errorfound(msgboxText, title_msg); - return - end - - def = erpworkingmemory('pop_erpchanoperator'); - if isempty(def) - def = { [], 1}; - end - - % - % Call GUI - % - answer = chanoperGUI(ERP, def); - - if isempty(answer) - disp('User selected Cancel') - return - end - formulas = answer{1}; - wchmsgon = answer{2}; - keeplocs = answer{3}; - def = {formulas, wchmsgon}; - erpworkingmemory('pop_erpchanoperator', def); - - if wchmsgon==1 - wchmsgonstr = 'on'; - else - wchmsgonstr = 'off'; + msgboxText = 'No ERPset was found!'; + title_msg = 'ERPLAB: pop_erpchanoperator() error:'; + errorfound(msgboxText, title_msg); + return end - - ERP.erpname = [ERP.erpname '_chop']; - - % - % Somersault - % - [ERP, erpcom] = pop_erpchanoperator(ERP, formulas, 'Warning', wchmsgonstr, 'Saveas', 'on','ErrorMsg', 'popup','KeepLocations',keeplocs, 'History', 'gui'); - return + end + if ~iserpstruct(ERP) + msgboxText = 'Invalid ERP structure!'; + title_msg = 'ERPLAB: pop_erpchanoperator() error:'; + errorfound(msgboxText, title_msg); + return + end + if ~isfield(ERP,'bindata') %(ERP.bindata) + msgboxText = 'Cannot work on an empty ERPset!'; + title_msg = 'ERPLAB: pop_erpchanoperator() error:'; + errorfound(msgboxText, title_msg); + return + end + if isempty(ERP.bindata) %(ERP.bindata) + msgboxText = 'Cannot work on an empty ERPset!'; + title_msg = 'ERPLAB: pop_erpchanoperator() error:'; + errorfound(msgboxText, title_msg); + return + end + + def = erpworkingmemory('pop_erpchanoperator'); + if isempty(def) + def = { [], 1}; + end + + % + % Call GUI + % + answer = chanoperGUI(ERP, def); + + if isempty(answer) + disp('User selected Cancel') + return + end + formulas = answer{1}; + wchmsgon = answer{2}; + keeplocs = answer{3}; + def = {formulas, wchmsgon}; + erpworkingmemory('pop_erpchanoperator', def); + + if wchmsgon==1 + wchmsgonstr = 'on'; + else + wchmsgonstr = 'off'; + end + + ERP.erpname = [ERP.erpname '_chop']; + + % + % Somersault + % + [ERP, erpcom] = pop_erpchanoperator(ERP, formulas, 'Warning', wchmsgonstr, 'Saveas', 'on','ErrorMsg', 'popup','KeepLocations',keeplocs, 'History', 'gui'); + return end % @@ -149,49 +149,49 @@ keeplocs = 0; end if strcmpi(p.Results.Warning,'on') - wchmsgon = 1; + wchmsgon = 1; else - wchmsgon = 0; + wchmsgon = 0; end if ismember_bc2({p.Results.Saveas}, {'on','yes'}) - issaveas = 1; + issaveas = 1; else - issaveas = 0; + issaveas = 0; end if strcmpi(p.Results.History,'implicit') - shist = 3; % implicit + shist = 3; % implicit elseif strcmpi(p.Results.History,'script') - shist = 2; % script + shist = 2; % script elseif strcmpi(p.Results.History,'gui') - shist = 1; % gui + shist = 1; % gui else - shist = 0; % off + shist = 0; % off end if strcmpi(p.Results.ErrorMsg,'popup') - errormsgtype = 1; % open popup window + errormsgtype = 1; % open popup window else - errormsgtype = 0; % error in red at command window + errormsgtype = 0; % error in red at command window end if iscell(formulas) - formulaArray = formulas'; - opcom = 1; % save extended command history (cell string with all equations ) + formulaArray = formulas'; + opcom = 1; % save extended command history (cell string with all equations ) else - if isnumeric(formulas) - error('ERPLAB says: Error, formulas must be a cell string or a filename') - end - if strcmp(formulas,'') - error('ERPLAB says: Error, formulas were not found.') - end - disp(['For list of formulas, user selected ' formulas '']) - fid_formulas = fopen( formulas ); - formulaArray = textscan(fid_formulas, '%[^\n]', 'CommentStyle','#', 'whitespace', ''); - formulaArray = strtrim(cellstr(formulaArray{:})'); - fclose(fid_formulas); - - if isempty(formulaArray) - error('ERPLAB says: Error, file was empty. No formulas were found.') - end - opcom = 2; % save short command history (string with the name of the file containing all equations ) + if isnumeric(formulas) + error('ERPLAB says: Error, formulas must be a cell string or a filename') + end + if strcmp(formulas,'') + error('ERPLAB says: Error, formulas were not found.') + end + disp(['For list of formulas, user selected ' formulas '']) + fid_formulas = fopen( formulas ); + formulaArray = textscan(fid_formulas, '%[^\n]', 'CommentStyle','#', 'whitespace', ''); + formulaArray = strtrim(cellstr(formulaArray{:})'); + fclose(fid_formulas); + + if isempty(formulaArray) + error('ERPLAB says: Error, file was empty. No formulas were found.') + end + opcom = 2; % save short command history (string with the name of the file containing all equations ) end % @@ -205,57 +205,57 @@ % ERP_tempo = ERP; if modeoption==1 % new ERP - ERPin = ERP; - % New ERP - ERPout = ERP; - ERPout.bindata = []; - ERPout.binerror = []; - ERPout.nchan = []; - ERPout.chanlocs = []; + ERPin = ERP; + % New ERP + ERPout = ERP; + ERPout.bindata = []; + ERPout.binerror = []; + ERPout.nchan = []; + ERPout.chanlocs = []; elseif modeoption==0 % append ERP - ERPin = ERP; - ERPout= ERPin; + ERPin = ERP; + ERPout= ERPin; end h=1; while h<=nformulas && conti - expr = formulaArray{h}; - tokcommentb = regexpi(formulaArray{h}, '^#', 'match'); % comment - if isempty(tokcommentb) - - % - % subroutine - % - [ERPout, conti] = erpchanoperator(ERPin, ERPout, expr, wchmsgon,keeplocs); - - if conti==0 - recall = 1; - break - end - if isempty(ERPout) - error('Something happens...') - end - if modeoption==0 - ERPin = ERPout; % recursive - end + expr = formulaArray{h}; + tokcommentb = regexpi(formulaArray{h}, '^#', 'match'); % comment + if isempty(tokcommentb) + + % + % subroutine + % + [ERPout, conti] = erpchanoperator(ERPin, ERPout, expr, wchmsgon,keeplocs); + + if conti==0 + recall = 1; + break end - h = h + 1; + if isempty(ERPout) + error('Something happens...') + end + if modeoption==0 + ERPin = ERPout; % recursive + end + end + h = h + 1; end if ~isfield(ERPout, 'binerror') - ERPout.binerror = []; + ERPout.binerror = []; end if recall && issaveas - ERP = ERP_tempo; - [ERP, erpcom] = pop_erpchanoperator(ERP); % try again... - return + ERP = ERP_tempo; + [ERP, erpcom] = pop_erpchanoperator(ERP); % try again... + return elseif recall && ~issaveas - msgboxText = 'Error at formula(s).'; - title = sprintf('ERPLAB: %s() error:', mfilename); - errorfound(msgboxText, title); - return + msgboxText = 'Error at formula(s).'; + title = sprintf('ERPLAB: %s() error:', mfilename); + errorfound(msgboxText, title); + return end ERP = ERPout; -ERP.datatype = datatype; +ERP.datatype = datatype; % % % Creates com history % % if opcom==1 @@ -274,82 +274,82 @@ skipfields = {'ERP', 'formulas', 'Saveas', 'History'}; fn = fieldnames(p.Results); if opcom==1 - erpcom = sprintf('%s = pop_erpchanoperator( %s, { ', inputname(1), inputname(1)); - for j=1:nformulas; - erpcom = sprintf('%s ''%s'', ', erpcom, formulaArray{j} ); - end - erpcom = sprintf('%s } ', erpcom); - erpcom = regexprep(erpcom, ',\s*}','}'); + erpcom = sprintf('%s = pop_erpchanoperator( %s, { ', inputname(1), inputname(1)); + for j=1:nformulas; + erpcom = sprintf('%s ''%s'', ', erpcom, formulaArray{j} ); + end + erpcom = sprintf('%s } ', erpcom); + erpcom = regexprep(erpcom, ',\s*}','}'); else - erpcom = sprintf('%s = pop_erpchanoperator( %s, ''%s'' ', inputname(1), inputname(1),... - formulas); + erpcom = sprintf('%s = pop_erpchanoperator( %s, ''%s'' ', inputname(1), inputname(1),... + formulas); end for q=1:length(fn) - fn2com = fn{q}; - if ~ismember_bc2(fn2com, skipfields) - fn2res = p.Results.(fn2com); - if ~isempty(fn2res) - if ischar(fn2res) - if ~strcmpi(fn2res,'off') - erpcom = sprintf( '%s, ''%s'', ''%s''', erpcom, fn2com, fn2res); - end - else - if iscell(fn2res) - if ischar([fn2res{:}]) - fn2resstr = sprintf('''%s'' ', fn2res{:}); - else - fn2resstr = vect2colon(cell2mat(fn2res), 'Sort','on'); - end - fnformat = '{%s}'; - else - fn2resstr = vect2colon(fn2res, 'Sort','on'); - fnformat = '%s'; - end - if strcmpi(fn2com,'Criterion') - if p.Results.Criterion<100 - erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); - end - else - erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); - end - end + fn2com = fn{q}; + if ~ismember_bc2(fn2com, skipfields) + fn2res = p.Results.(fn2com); + if ~isempty(fn2res) + if ischar(fn2res) + if ~strcmpi(fn2res,'off') + erpcom = sprintf( '%s, ''%s'', ''%s''', erpcom, fn2com, fn2res); end + else + if iscell(fn2res) + if ischar([fn2res{:}]) + fn2resstr = sprintf('''%s'' ', fn2res{:}); + else + fn2resstr = vect2colon(cell2mat(fn2res), 'Sort','on'); + end + fnformat = '{%s}'; + else + fn2resstr = vect2colon(fn2res, 'Sort','on'); + fnformat = '%s'; + end + if strcmpi(fn2com,'Criterion') + if p.Results.Criterion<100 + erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); + end + else + erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); + end + end end + end end erpcom = sprintf( '%s );', erpcom); if issaveas && modeoption==1 % only for GUI and nchan (new ERP) - [ERP, issave, erpcom_save] = pop_savemyerp(ERP,'gui','erplab', 'History', 'off'); - if issave>0 - if issave==2 - erpcom = sprintf('%s\n%s', erpcom, erpcom_save); - msgwrng = '*** Your ERPset was saved on your hard drive.***'; - mcolor = [0 0 1]; - else - msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; - mcolor = [1 0.52 0.2]; - end + [ERP, issave, erpcom_save] = pop_savemyerp(ERP,'gui','erplab', 'History', 'off'); + if issave>0 + if issave==2 + erpcom = sprintf('%s\n%s', erpcom, erpcom_save); + msgwrng = '*** Your ERPset was saved on your hard drive.***'; + mcolor = [0 0 1]; else - ERP = ERP_tempo; % recover unmodified ERP - msgwrng = 'ERPLAB Warning: Your changes were not saved'; - mcolor = [1 0.22 0.2]; + msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; + mcolor = [1 0.52 0.2]; end - try cprintf(mcolor, '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; + else + ERP = ERP_tempo; % recover unmodified ERP + msgwrng = 'ERPLAB Warning: Your changes were not saved'; + mcolor = [1 0.22 0.2]; + end + try cprintf(mcolor, '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; elseif issaveas && modeoption==0 % overwrite current ERPset at erpset menu (no GUI) - ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'overwriteatmenu', 'yes', 'History', 'off'); - msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; - mcolor = [1 0.52 0.2]; - try cprintf(mcolor, '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; + ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'overwriteatmenu', 'yes', 'History', 'off'); + msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; + mcolor = [1 0.52 0.2]; + try cprintf(mcolor, '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; end % get history from script. ERP switch shist - case 1 % from GUI - displayEquiComERP(erpcom); - case 2 % from script - ERP = erphistory(ERP, [], erpcom, 1); - case 3 - % implicit - otherwise %off or none - erpcom = ''; + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + ERP = erphistory(ERP, [], erpcom, 1); + case 3 + % implicit + otherwise %off or none + erpcom = ''; end % % Completion statement diff --git a/pop_functions/pop_erplabDeleteTimeSegments.m b/pop_functions/pop_erplabDeleteTimeSegments.m old mode 100644 new mode 100755 diff --git a/pop_functions/pop_importerpss_studio.m b/pop_functions/pop_importerpss_studio.m new file mode 100755 index 00000000..f6d07818 --- /dev/null +++ b/pop_functions/pop_importerpss_studio.m @@ -0,0 +1,337 @@ +% PURPOSE : Import ERP from ERPSS Text file format +% +% FORMAT : +% +% ERP = pop_importerpss_studio(parameters); +% +% The available parameters are as follows: +% +% 'Filename' - ERPSS Text file +% 'Format' - 'explicit'/'implicit' +% 'Pointat' - 'col'/'row' +% 'Saveas' - 'on'/'off' +% +% EXAMPLE 1 : Load a single ERPset +% +% ERP = pop_importerpss_studio('Filename', {'/Users/etfoo/Documents/MATLAB/ERP_ERPSS_test.txt'}, 'Format', 'implicit', 'Pointat', 'row'); +% +% EXAMPLE 2 : Load two ERPsets (ALLERP will store both; ERP will store the last one) +% +% [ ERP ALLERP ] = pop_importerpss_studio('Filename', {'/Users/etfoo/Documents/MATLAB/ERP_ERPSS_test1.txt' '/Users/etfoo/Documents/MATLAB/ERP_ERPSS_test2.txt'},... +% 'Format', 'implicit', 'Pointat', 'row'); +% +% +% OUTPUTS : +% +% ERP and/or ALLERP +% +% +% See also importERPSS_GUI.m importerpss2.m +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon & Eric Foo & Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 & 2022 + +function [ERP, ALLERP, erpcom] = pop_importerpss_studio(varargin) +erpcom = ''; +ERP = preloadERP; +errorf = 0; +ALLERP = preloadALLERP; +preindex = length(ALLERP); +if nargin<1 + + % + % call GUI + % + answer = importERPSS_GUI; %(gui was modified) + + if isempty(answer) + disp('User selected Cancel') + return + end + + fname = answer{1}; % filename (+ whole path) + dformat = answer{2}; % data format + dtranspose = answer{3}; % transpose data (Fixed) + + if dformat==0 + dformatstr = 'explicit'; % points at columns + else + dformatstr = 'implicit'; % points at rows + end + if dtranspose==0 + orienpoint = 'column'; % points at columns + else + orienpoint = 'row'; % points at rows + end + + % + % Somersault + % + [ERP, ALLERP, erpcom] = pop_importerpss_studio('Filename', fname, 'Format', dformatstr, 'Pointat', orienpoint, 'History', 'gui'); + pause(0.1); + return +end + +% +% Parsing inputs +% +p = inputParser; +p.FunctionName = mfilename; +p.CaseSensitive = false; +% option(s) +p.addParamValue('Filename', ''); +p.addParamValue('Format', 'explicit', @ischar); +p.addParamValue('Pointat', 'col', @ischar); +p.addParamValue('History', 'script', @ischar); % history from scripting +p.parse(varargin{:}); + +filename = p.Results.Filename; + +if strcmpi(p.Results.Format, 'explicit'); + dformat = 0; +else + dformat = 1; +end +if ismember_bc2({lower(p.Results.Pointat)}, {'col','column','columns'}); + dtranspose = 0; +elseif ismember_bc2({lower(p.Results.Pointat)}, {'row','rows'}); + dtranspose = 1; +else + error('ERPLAB says: ?') +end +if strcmpi(p.Results.History,'implicit') + shist = 3; % implicit +elseif strcmpi(p.Results.History,'script') + shist = 2; % script +elseif strcmpi(p.Results.History,'gui') + shist = 1; % gui +else + shist = 0; % off +end +if iscell(filename) % filename fixed. JLC + nfile = length(filename); +else + nfile = 1; + filename = cellstr(filename); +end +auxALLERP = ALLERP; +ERPaux = ERP; + +% +% load ERPsets(s) +% +fprintf('\n'); +for i=1:nfile + try + fname = filename{i}; % pointer "i" fixed. JLC + fprintf('%g) Importing ''%s'' into ERPLAB...Please wait...\n', i, fname); + + % + % subroutine + % + [ERP, serror] = importerpss2(fname, dformat, dtranspose); + + try%Remove the bin with Caliration GH 2022 + if strcmp(ERP.bindescr{1},'Calibration') + for Numofbin =2:ERP.nbin + Bindescr{Numofbin-1} = ERP.bindescr{Numofbin}; + end + ERP.bindescr =Bindescr; + ERP.nbin = ERP.nbin-1; + ERP.bindata = ERP.bindata(:,:,[2:end]); + end + catch + ERP =ERP; + end + + if serror + break + end + catch %#ok<*CTCH> + serror =1; + break + end + checking = checkERP(ERP); + try + if checking + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + try + try + ALLERPCOM = evalin('base', 'ALLERPCOM'); + catch + ALLERPCOM =[]; + end + Answer = f_ERP_save_single_file(ERP.erpname,ERP.filename,length(ALLERP)+1); + + if isempty(Answer) + beep; + disp('User selected cancel!!!'); + return; + end + if ~isempty(Answer{1}) + ERP.erpname = char(Answer{1}); + end + try + if ~isempty(Answer{2}) + fileName_full = Answer{2}; + [pathstr, file_name, ext] = fileparts(fileName_full); + + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,'.erp']; + ERP.filepath = pathstr; + %%----------save the current sdata as-------------------- + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + else + ERP.filename = ERP.erpname; + % ERP =ERP; + end + catch + beep; + disp('There exists error when save current ERP in pop_importerpss_studio()'); + return; + end%%End changed by Guanghui + + if i==1 && isempty(ALLERP) + ALLERP = buildERPstruct([]); %#ok + ALLERP = ERP; + else + ALLERP(i+preindex) = ERP; + end + assignin('base','ALLERP',ALLERP); % save to workspace + % updatemenuerp(ALLERP); + catch + beep; + disp('There exists error when save current ERP in pop_importerpss_studio()'); + return; + + end + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % if i==1 && isempty(ALLERP); + % ALLERP1 = buildERPstruct([]); %#ok + % ALLERP = ERP; + % else + % ALLERP(i+preindex) = ERP; + % end + else + errorf = 1; + break + end + catch %#ok + errorf = 1; % fatal error + break + end +end +if serror + msgboxText = ['Oops! Something went wrong reading your file.\n'... + 'Please verify the ascii file or double check your settings for importing.']; + title = 'ERPLAB: pop_importerpss_studio() inputs'; + errorfound(sprintf(msgboxText), title); + ALLERP = auxALLERP; + ERP = ERPaux; + return +elseif errorf + msgboxText = ['Your erpset %s is not compatible at all with the current ERPLAB version.\n'... + 'Please, try upgrading your ERP structure.']; + title = 'ERPLAB: pop_importerpss_studio() Error'; + errorfound(sprintf(msgboxText, ERP.filename), title); + ALLERP = auxALLERP; + ERP = ERPaux; + return +end +fprintf('\n'); + +if shist==1 % update erpset menu at main gui. JLC. For Antigona M. + assignin('base','ALLERP',ALLERP); % save to workspace + % updatemenuerp(ALLERP); % add a new erpset to the erpset menu +end + +% +% Completion statement +% +% msg2end + +% +% History +% +skipfields = {'Saveas','History'}; +fn = fieldnames(p.Results); +erpcom = sprintf( ' ERP = pop_importerpss_studio('); +for q=1:length(fn) + fn2com = fn{q}; + if ~ismember_bc2(fn2com, skipfields) + fn2res = p.Results.(fn2com); + if ~isempty(fn2res) + if ischar(fn2res) + if ~strcmpi(fn2res,'off') + erpcom = sprintf( '%s, ''%s'', ''%s''', erpcom, fn2com, fn2res); + end + else + if iscell(fn2res) + if ischar([fn2res{:}]) + fn2resstr = sprintf('''%s'' ', fn2res{:}); + else + fn2resstr = vect2colon(cell2mat(fn2res), 'Sort','on'); + end + fnformat = '{%s}'; + else + fn2resstr = vect2colon(fn2res, 'Sort','on'); + fnformat = '%s'; + end + if strcmpi(fn2com,'Criterion') + if p.Results.Criterion<100 + erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); + end + else + erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); + end + end + end + end +end +erpcom = sprintf( '%s );', erpcom); +erpcom = strrep(erpcom, '(,','('); +% if issaveas +% [ERP, issave, erpcom_save] = pop_savemyerp(ERP,'gui','erplab', 'History', 'implicit'); +% if issave>0 +% % generate text command +% if issave==2 +% erpcom = sprintf('%s\n%s', erpcom, erpcom_save); +% msgwrng = '*** Your ERPset was saved on your hard drive.***'; +% else +% msgwrng = '*** Warning: Your ERPset was only saved on the workspace.***'; +% end +% fprintf('\n%s\n\n', msgwrng) +% try cprintf([0 0 1], 'COMPLETE\n\n');catch,fprintf('COMPLETE\n\n');end ; +% else +% ALLERP = auxALLERP; +% ERP = ERPaux; +% msgwrng = 'ERPLAB Warning: Your changes were not saved'; +% try cprintf([1 0.52 0.2], '%s\n\n', msgwrng);catch,fprintf('%s\n\n', msgwrng);end ; +% end + +% get history from script. ERP +switch shist + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + ERP = erphistory(ERP, [], erpcom, 1); + case 3 + % implicit + otherwise %off or none + erpcom = ''; + return +end +% +% Completion statement +% +msg2end +return + diff --git a/pop_functions/pop_scalplot.m b/pop_functions/pop_scalplot.m index f152cb63..384598cc 100755 --- a/pop_functions/pop_scalplot.m +++ b/pop_functions/pop_scalplot.m @@ -114,273 +114,273 @@ function [ERP, erpcom] = pop_scalplot(ERP, binArray, latencyArray, varargin) erpcom = ''; if nargin < 1 - help pop_scalplot - return + help pop_scalplot + return end if nargin==1 + if isempty(ERP) + ERP = preloadERP; if isempty(ERP) - ERP = preloadERP; - if isempty(ERP) - msgboxText = 'No ERPset was found!'; - title_msg = 'ERPLAB: pop_scalplot() error:'; - errorfound(msgboxText, title_msg); - return - end - end - if ~isfield(ERP, 'bindata') - msgboxText = 'Error: pop_scalplot cannot operate an empty ERP dataset'; - title_msg = 'ERPLAB: pop_scalplot() error:'; - errorfound(msgboxText, title_msg); - return - end - if isempty(ERP.bindata) - msgboxText = 'Error: pop_scalplot cannot operate an empty ERP dataset'; - title_msg = 'ERPLAB: pop_scalplot() error:'; - errorfound(msgboxText, title_msg); - return - end - - % - % Searching channel location - % - if isfield(ERP.chanlocs, 'theta') && ~isempty([ERP.chanlocs.theta]) - [ERP, serror] = borrowchanloc(ERP); - else - question = ['This averaged ERP has not channel location info.\n'... - 'Would you like to load it now?']; - title_msg = 'ERPLAB: Channel location'; - button = askquest(sprintf(question), title_msg); - if ~strcmpi(button,'yes') - disp('User selected Cancel') - return - else - [ERP, serror] = borrowchanloc(ERP); - end - if ~isempty(serror) && serror==0 - ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); - end - end - if isempty(serror) - disp('User selected Cancel') - return - end - if serror~=0 - msgboxText = ['pop_scalplot could not find channel locations info.\n\n'... - 'Hint: Identify channel(s) without location looking at '... - 'command window comments (Channel lookup). Try again excluding this(ese) channel(s).']; - tittle = 'pop_scalplot: error:'; - errorfound(sprintf(msgboxText), tittle); - return - end - - % - % Call GUI - % - [plotset, ERP] = scalplotGUI(ERP, ERP.chanlocs); %GUI - - if isempty(plotset.pscalp) - disp('User selected Cancel') - return - elseif strcmpi(plotset.pscalp,'pdf') - %erpcom2 = pop_fig2pdf; - [ERP, erpcom2] = pop_exporterplabfigure(ERP); - % if countp>0 - disp('pop_exporterplabfigure was called') - % else - % disp('WARNING: Matlab figure(s) might have been generated during a previous round....') - % end - erpcom = [erpcom ' ' erpcom2]; - return - elseif strcmpi(plotset.pscalp,'time') - disp('User called pop_ploterps()') - return + msgboxText = 'No ERPset was found!'; + title_msg = 'ERPLAB: pop_scalplot() error:'; + errorfound(msgboxText, title_msg); + return end - - plotset.pscalp.binArray = plotset.pscalp.binArray(plotset.pscalp.binArray<=ERP.nbin); - - if ~isfield(plotset.pscalp, 'posfig') - plotset.pscalp.posfig = []; - end - - findplot = findobj('Tag','Scalp_figure'); - - if ~isempty(findplot) - lastfig = figure(findplot(1)); - posfx = get(lastfig,'Position'); - plotset.pscalp.posfig = [posfx(1)+10 posfx(2)-15 posfx(3) posfx(4) ]; - end - - % - % read plotset into variables - % - binArray = plotset.pscalp.binArray; - latencyArray = plotset.pscalp.latencyArray; - measurestr = plotset.pscalp.measurement; - baseline = plotset.pscalp.baseline; - maplimit = plotset.pscalp.cscale; - ismoviex = plotset.pscalp.agif.value; - FPS = plotset.pscalp.agif.fps; - fullgifname = plotset.pscalp.agif.fname; - posfig = plotset.pscalp.posfig; - mtype = plotset.pscalp.mtype; % map type: 2D or 3D - smapstyle = plotset.pscalp.smapstyle; % map style: 'fill' 'both' - mapoutside = plotset.pscalp.mapoutside; - mapview = plotset.pscalp.mapview; - splineinfo = plotset.pscalp.splineinfo; - plegend = plotset.pscalp.plegend; - binleg = plegend.binnum; % show bin number at legend - bindesc = plegend.bindesc; % show bin description at legend - vtype = plegend.type ; % show type of measurement at legend - vlatency = plegend.latency; % show latency(ies) at legend - showelec = plegend.electrodes; % show electrodes on scalp - elestyle = plegend.elestyle ; % - elec3D = plegend.elec3D; - clrbar = plegend.colorbar; % show color bar - ismaxim = plegend.maximize; % show color bar - clrmap = plegend.colormap; % show color bar - - if strcmpi(mtype, '3d') - % if isempty(ERP.splinefile) - % if isempty(splineinfo.path) - % splinefile = fullfile(cd(), 'temp_splinefile');%default temp spline - % else - % splinefile = splineinfo.path; - % end - % else - % splinefile = ERP.splinefile; - % end - if isempty(ERP.splinefile) && isempty(splineinfo.path) - %disp('A') - msgboxText = ['Current ERPset is not linked to any spline file.\n'... - 'At the Scal plot GUI, use "spline file" button, under the Map type menu, to find/create one.']; - title_msg = 'ERPLAB: pop_scalplot() missing info:'; - errorfound(sprintf(msgboxText), title_msg); - return - elseif isempty(ERP.splinefile) && ~isempty(splineinfo.path) - %if splineinfo.new==1 - headplot('setup', ERP.chanlocs, splineinfo.path); %Builds the new spline file. - % splineinfo.new = 0; - %plotset.pscalp.splineinfo = splineinfo; - %end - %if splineinfo.save - % ERP.splinefile = splineinfo.path; - % ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); - % erplab redraw - % splineinfo.save = 0; - % %plotset.pscalp.splineinfo = splineinfo; - %end - splinefile = splineinfo.path; - %disp('A2') - elseif ~isempty(ERP.splinefile) && ~isempty(splineinfo.path) - headplot('setup', ERP.chanlocs, splineinfo.path); %Builds the new spline file. - splinefile = splineinfo.path; - %disp('B') - - % if splineinfo.new==1 - % headplot('setup', ERP.chanlocs, splineinfo.path); %Builds the new spline file. - % splineinfo.new = 0; - % %plotset.pscalp.splineinfo = splineinfo; - % end - % if splineinfo.save - % question = ['This ERPset already has spline file info.\n'... - % 'Would you like to replace it?']; - % title_msg = 'ERPLAB: spline file'; - % button = askquest(sprintf(question), title_msg); - % - % if ~strcmpi(button,'yes') - % disp('User selected Cancel') - % return - % else - % ERP.splinefile = splineinfo.path; - % ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); - % erplab redraw - % end - % end - % splinefile = splineinfo.path; - else - %disp('C') - splinefile = ERP.splinefile; - end - else - %splinefile = ''; - splinefile = ERP.splinefile; - %disp('D') - end - - % - % save plotset at command window - % - assignin('base','plotset', plotset); - - if clrbar==1 - colorbari = 'on'; - else - colorbari = 'off'; - end - if mapoutside==1 % 'plotrad',mplotrad, - mplotrad = []; - else - mplotrad = 0.55; - end - - %'jet|hsv|hot|cool|gray' - switch clrmap - case 1 - cmap = 'jet'; - case 2 - cmap = 'hsv'; - case 3 - cmap = 'hot'; - case 4 - cmap = 'cool'; - case 5 - cmap = 'gray'; - case 6 - cmap = 'viridis'; - otherwise - cmap = 'jet'; - end - if ismoviex==0 - ismoviexx = 'off'; - aff = 'off'; % adjust first frame (aff) + end + if ~isfield(ERP, 'bindata') + msgboxText = 'Error: pop_scalplot cannot operate an empty ERP dataset'; + title_msg = 'ERPLAB: pop_scalplot() error:'; + errorfound(msgboxText, title_msg); + return + end + if isempty(ERP.bindata) + msgboxText = 'Error: pop_scalplot cannot operate an empty ERP dataset'; + title_msg = 'ERPLAB: pop_scalplot() error:'; + errorfound(msgboxText, title_msg); + return + end + + % + % Searching channel location + % + if isfield(ERP.chanlocs, 'theta') && ~isempty([ERP.chanlocs.theta]) + [ERP, serror] = borrowchanloc(ERP); + else + question = ['This averaged ERP has not channel location info.\n'... + 'Would you like to load it now?']; + title_msg = 'ERPLAB: Channel location'; + button = askquest(sprintf(question), title_msg); + if ~strcmpi(button,'yes') + disp('User selected Cancel') + return else - if ismoviex==1 - aff = 'off'; % adjust first frame (aff) - else - aff = 'on'; - end - ismoviexx = 'on'; + [ERP, serror] = borrowchanloc(ERP); end - if binleg==1 - binlegx = 'on'; - else - binlegx = 'off'; + if ~isempty(serror) && serror==0 + ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); end - if showelec==1 - showelecx = elestyle; + end + if isempty(serror) + disp('User selected Cancel') + return + end + if serror~=0 + msgboxText = ['pop_scalplot could not find channel locations info.\n\n'... + 'Hint: Identify channel(s) without location looking at '... + 'command window comments (Channel lookup). Try again excluding this(ese) channel(s).']; + tittle = 'pop_scalplot: error:'; + errorfound(sprintf(msgboxText), tittle); + return + end + + % + % Call GUI + % + [plotset, ERP] = scalplotGUI(ERP, ERP.chanlocs); %GUI + + if isempty(plotset.pscalp) + disp('User selected Cancel') + return + elseif strcmpi(plotset.pscalp,'pdf') + %erpcom2 = pop_fig2pdf; + [ERP, erpcom2] = pop_exporterplabfigure(ERP); + % if countp>0 + disp('pop_exporterplabfigure was called') + % else + % disp('WARNING: Matlab figure(s) might have been generated during a previous round....') + % end + erpcom = [erpcom ' ' erpcom2]; + return + elseif strcmpi(plotset.pscalp,'time') + disp('User called pop_ploterps()') + return + end + + plotset.pscalp.binArray = plotset.pscalp.binArray(plotset.pscalp.binArray<=ERP.nbin); + + if ~isfield(plotset.pscalp, 'posfig') + plotset.pscalp.posfig = []; + end + + findplot = findobj('Tag','Scalp_figure'); + + if ~isempty(findplot) + lastfig = figure(findplot(1)); + posfx = get(lastfig,'Position'); + plotset.pscalp.posfig = [posfx(1)+10 posfx(2)-15 posfx(3) posfx(4) ]; + end + + % + % read plotset into variables + % + binArray = plotset.pscalp.binArray; + latencyArray = plotset.pscalp.latencyArray; + measurestr = plotset.pscalp.measurement; + baseline = plotset.pscalp.baseline; + maplimit = plotset.pscalp.cscale; + ismoviex = plotset.pscalp.agif.value; + FPS = plotset.pscalp.agif.fps; + fullgifname = plotset.pscalp.agif.fname; + posfig = plotset.pscalp.posfig; + mtype = plotset.pscalp.mtype; % map type: 2D or 3D + smapstyle = plotset.pscalp.smapstyle; % map style: 'fill' 'both' + mapoutside = plotset.pscalp.mapoutside; + mapview = plotset.pscalp.mapview; + splineinfo = plotset.pscalp.splineinfo; + plegend = plotset.pscalp.plegend; + binleg = plegend.binnum; % show bin number at legend + bindesc = plegend.bindesc; % show bin description at legend + vtype = plegend.type ; % show type of measurement at legend + vlatency = plegend.latency; % show latency(ies) at legend + showelec = plegend.electrodes; % show electrodes on scalp + elestyle = plegend.elestyle ; % + elec3D = plegend.elec3D; + clrbar = plegend.colorbar; % show color bar + ismaxim = plegend.maximize; % show color bar + clrmap = plegend.colormap; % show color bar + + if strcmpi(mtype, '3d') + % if isempty(ERP.splinefile) + % if isempty(splineinfo.path) + % splinefile = fullfile(cd(), 'temp_splinefile');%default temp spline + % else + % splinefile = splineinfo.path; + % end + % else + % splinefile = ERP.splinefile; + % end + if isempty(ERP.splinefile) && isempty(splineinfo.path) + %disp('A') + msgboxText = ['Current ERPset is not linked to any spline file.\n'... + 'At the Scal plot GUI, use "spline file" button, under the Map type menu, to find/create one.']; + title_msg = 'ERPLAB: pop_scalplot() missing info:'; + errorfound(sprintf(msgboxText), title_msg); + return + elseif isempty(ERP.splinefile) && ~isempty(splineinfo.path) + %if splineinfo.new==1 + headplot('setup', ERP.chanlocs, splineinfo.path); %Builds the new spline file. + % splineinfo.new = 0; + %plotset.pscalp.splineinfo = splineinfo; + %end + %if splineinfo.save + % ERP.splinefile = splineinfo.path; + % ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); + % erplab redraw + % splineinfo.save = 0; + % %plotset.pscalp.splineinfo = splineinfo; + %end + splinefile = splineinfo.path; + %disp('A2') + elseif ~isempty(ERP.splinefile) && ~isempty(splineinfo.path) + headplot('setup', ERP.chanlocs, splineinfo.path); %Builds the new spline file. + splinefile = splineinfo.path; + %disp('B') + + % if splineinfo.new==1 + % headplot('setup', ERP.chanlocs, splineinfo.path); %Builds the new spline file. + % splineinfo.new = 0; + % %plotset.pscalp.splineinfo = splineinfo; + % end + % if splineinfo.save + % question = ['This ERPset already has spline file info.\n'... + % 'Would you like to replace it?']; + % title_msg = 'ERPLAB: spline file'; + % button = askquest(sprintf(question), title_msg); + % + % if ~strcmpi(button,'yes') + % disp('User selected Cancel') + % return + % else + % ERP.splinefile = splineinfo.path; + % ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); + % erplab redraw + % end + % end + % splinefile = splineinfo.path; else - showelecx = 'off'; + %disp('C') + splinefile = ERP.splinefile; end - if ismaxim==1 - maxim = 'on'; + else + %splinefile = ''; + splinefile = ERP.splinefile; + %disp('D') + end + + % + % save plotset at command window + % + assignin('base','plotset', plotset); + + if clrbar==1 + colorbari = 'on'; + else + colorbari = 'off'; + end + if mapoutside==1 % 'plotrad',mplotrad, + mplotrad = []; + else + mplotrad = 0.55; + end + + %'jet|hsv|hot|cool|gray' + switch clrmap + case 1 + cmap = 'jet'; + case 2 + cmap = 'hsv'; + case 3 + cmap = 'hot'; + case 4 + cmap = 'cool'; + case 5 + cmap = 'gray'; + case 6 + cmap = 'viridis'; + otherwise + cmap = 'jet'; + end + if ismoviex==0 + ismoviexx = 'off'; + aff = 'off'; % adjust first frame (aff) + else + if ismoviex==1 + aff = 'off'; % adjust first frame (aff) else - maxim = 'off'; + aff = 'on'; end - - % legend - logstring = ['bn'*binleg '-'*binleg 'bd'*bindesc '-'*bindesc 'me'*vtype '-'*vtype 'la'*vlatency]; - logstring = nonzeros(logstring)'; - mapleg = strtrim(char(logstring)); - - % - % Somersault - % - [ERP, erpcom] = pop_scalplot(ERP, binArray, latencyArray, 'Value', measurestr, 'Blc', baseline, 'Maplimit', maplimit, 'Colorbar', colorbari,... - 'Colormap', cmap,'Animated', ismoviexx, 'AdjustFirstFrame', aff, 'FPS', FPS, 'Filename', fullgifname, 'Legend', mapleg, 'Electrodes', showelecx,... - 'Position', posfig, 'Maptype', mtype, 'Mapstyle', smapstyle, 'Plotrad', mplotrad,'Mapview', mapview, 'Splinefile', splinefile,... - 'Maximize', maxim, 'Electrodes3d', elec3D,'History', 'gui'); - pause(0.1) - return + ismoviexx = 'on'; + end + if binleg==1 + binlegx = 'on'; + else + binlegx = 'off'; + end + if showelec==1 + showelecx = elestyle; + else + showelecx = 'off'; + end + if ismaxim==1 + maxim = 'on'; + else + maxim = 'off'; + end + + % legend + logstring = ['bn'*binleg '-'*binleg 'bd'*bindesc '-'*bindesc 'me'*vtype '-'*vtype 'la'*vlatency]; + logstring = nonzeros(logstring)'; + mapleg = strtrim(char(logstring)); + + % + % Somersault + % + [ERP, erpcom] = pop_scalplot(ERP, binArray, latencyArray, 'Value', measurestr, 'Blc', baseline, 'Maplimit', maplimit, 'Colorbar', colorbari,... + 'Colormap', cmap,'Animated', ismoviexx, 'AdjustFirstFrame', aff, 'FPS', FPS, 'Filename', fullgifname, 'Legend', mapleg, 'Electrodes', showelecx,... + 'Position', posfig, 'Maptype', mtype, 'Mapstyle', smapstyle, 'Plotrad', mplotrad,'Mapview', mapview, 'Splinefile', splinefile,... + 'Maximize', maxim, 'Electrodes3d', elec3D,'History', 'gui'); + pause(0.1) + return end % @@ -411,7 +411,7 @@ p.addParamValue('Legend', 'bn-la', @ischar); % all -> 'bn-bd-me-lat' (at legend:bin number (bn), bin desc (bd), measure (me), latency (la)) p.addParamValue('Maximize', 'off', @ischar); % off | on p.addParamValue('Position', [], @isnumeric); -p.addParamValue('Maptype', '2D', @ischar); % +p.addParamValue('Maptype', '2D', @ischar); % p.addParamValue('Mapstyle', 'both', @ischar); % 'fill' 'both' p.addParamValue('Plotrad', 0.55, @isnumeric); % 'fill' 'both' p.addParamValue('Mapview', '+X'); @@ -423,11 +423,11 @@ datatype = checkdatatype(ERP); if strcmpi(datatype, 'ERP') - kktime = 1000; - srate = ERP.srate; + kktime = 1000; + srate = ERP.srate; else - kktime = 1; - srate = ERP.pnts/ERP.xmax; + kktime = 1; + srate = ERP.pnts/ERP.xmax; end % @@ -436,32 +436,32 @@ serror = 0; chanlocfile = p.Results.Chanlocfile; if isempty(chanlocfile) - if isfield(ERP.chanlocs, 'theta') - [ERP, serror] = borrowchanloc(ERP); - else - msgboxText = 'No channel location found.'; - error(msgboxText); - end + if isfield(ERP.chanlocs, 'theta') + [ERP, serror] = borrowchanloc(ERP); + else + msgboxText = 'No channel location found.'; + error(msgboxText); + end else - [ERP, serror] = borrowchanloc(ERP, chanlocfile); + [ERP, serror] = borrowchanloc(ERP, chanlocfile); end if serror~=0 - msgboxText = 'ERPLAB says: pop_scalplot could not load channel locations info.'; - error(msgboxText); + msgboxText = 'ERPLAB says: pop_scalplot could not load channel locations info.'; + error(msgboxText); end if length(latencyArray)>ERP.pnts - msgboxText = 'ERPLAB says: latency array cannot be longer than number of points'; - error(msgboxText) + msgboxText = 'ERPLAB says: latency array cannot be longer than number of points'; + error(msgboxText) end if max(binArray)>ERP.nbin - msgboxText = ['Bin(s) %g do(es) not exist within this erpset.\n'... - 'Please, check your bin list']; - error(sprintf(msgboxText, chanArray(chanArray>ERP.nchan))); + msgboxText = ['Bin(s) %g do(es) not exist within this erpset.\n'... + 'Please, check your bin list']; + error(sprintf(msgboxText, chanArray(chanArray>ERP.nchan))); end if min(binArray)<1 - msgboxText = ['Invalid bin indexing.\n'... - 'Bin index(ices) must be positive integer(s) but zero.']; - error(sprintf(msgboxText, ERP.erpname)); + msgboxText = ['Invalid bin indexing.\n'... + 'Bin index(ices) must be positive integer(s) but zero.']; + error(sprintf(msgboxText, ERP.erpname)); end measurestr = p.Results.Value; @@ -477,34 +477,34 @@ vname = p.Results.VideoIntro; if strcmpi(colorbari,'on') - clrbar = 1; + clrbar = 1; else - clrbar = 0; + clrbar = 0; end if strcmpi(ismoviexx,'on') - ismoviex = 1; - if strcmpi(p.Results.AdjustFirstFrame,'on') - %ismoviex = 2; - adj1frame = 1; - else - %ismoviex = 1; - adj1frame = 0; - end - - [pth, fn, ext] = fileparts(fullgifname); - if strcmpi(ext,'.gif') - movtype = 'gif'; - elseif strcmpi(ext,'.mat') - movtype = 'mat'; - elseif strcmpi(ext,'.avi') - movtype = 'avi'; - else - error('invalid file format') - end -else - ismoviex = 0; - movtype = ''; + ismoviex = 1; + if strcmpi(p.Results.AdjustFirstFrame,'on') + %ismoviex = 2; + adj1frame = 1; + else + %ismoviex = 1; adj1frame = 0; + end + + [pth, fn, ext] = fileparts(fullgifname); + if strcmpi(ext,'.gif') + movtype = 'gif'; + elseif strcmpi(ext,'.mat') + movtype = 'mat'; + elseif strcmpi(ext,'.avi') + movtype = 'avi'; + else + error('invalid file format') + end +else + ismoviex = 0; + movtype = ''; + adj1frame = 0; end elestyle = p.Results.Electrodes; @@ -524,9 +524,9 @@ fontnamel = p.Results.FontName; if strcmpi(p.Results.Maximize,'on') - ismaxim = 1; + ismaxim = 1; else - ismaxim = 0; + ismaxim = 0; end legstr = p.Results.Legend; @@ -535,58 +535,58 @@ [binleg, bindesc, vtype, vlatency] = deal(bb{:}); if isempty(ERP.splinefile) && isempty(splinefile) && strcmpi(mtype, '3d') - error('ERPLAB says: no spline file info was found.') + error('ERPLAB says: no spline file info was found.') end indxh = find(latencyArray>ERP.xmax*kktime,1); if ~isempty(indxh) - msgboxText = ['Latency of ' num2str(latencyArray(indxh)) ' is greater than ERP.xmax = ' num2str(ERP.xmax*kktime) ' msec!']; - error(msgboxText); + msgboxText = ['Latency of ' num2str(latencyArray(indxh)) ' is greater than ERP.xmax = ' num2str(ERP.xmax*kktime) ' msec!']; + error(msgboxText); end indxl = find(latencyArray> Plot ERP map by Bins x latency'],... - 'NumberTitle','on', 'Tag','Scalp_figure');erplab_figtoolbar(hsig, mtype); + hsig = figure('Position',pos1, 'Name',['<< ' fnamet ' >> Plot ERP map by Bins x latency'],... + 'NumberTitle','on', 'Tag','Scalp_figure'); else % FFT - hsig = figure('Position',pos1, 'Name',['<< ' fnamet ' >> Plot ERP map by Bins x frequency'],... - 'NumberTitle','on', 'Tag','Scalp_figure');erplab_figtoolbar(hsig, mtype); + hsig = figure('Position',pos1, 'Name',['<< ' fnamet ' >> Plot ERP map by Bins x frequency'],... + 'NumberTitle','on', 'Tag','Scalp_figure'); end - - if ~isempty(posfig) - set(hsig, 'Position', posfig) - end - nadj = 1; - if ismaxim == 1; - maximize(hsig) + else + if strcmpi(datatype, 'ERP') + hsig = figure('Position',pos1, 'Name',['<< ' fnamet ' >> Plot ERP map by Bins x latency'],... + 'NumberTitle','on', 'Tag','Scalp_figure');erplab_figtoolbar(hsig, mtype); + else % FFT + hsig = figure('Position',pos1, 'Name',['<< ' fnamet ' >> Plot ERP map by Bins x frequency'],... + 'NumberTitle','on', 'Tag','Scalp_figure');erplab_figtoolbar(hsig, mtype); end + end + if ~isempty(posfig) + set(hsig, 'Position', posfig) + end + nadj = 1; + if ismaxim == 1; + maximize(hsig) + end else - secondframe = 1; - fra = 1; - if adj1frame==1 % adjust first frame size - nadj = 2; - else - nadj = 1; - end - - hsig = figure('Position',pos2, 'Name',['<< Frame ' num2str(fra) ' >>'],... - 'NumberTitle','off', 'Tag','Scalp_figure'); - if ~isempty(posfig) - set(hsig, 'Position', posfig) - end + secondframe = 1; + fra = 1; + if adj1frame==1 % adjust first frame size + nadj = 2; + else + nadj = 1; + end + + hsig = figure('Position',pos2, 'Name',['<< Frame ' num2str(fra) ' >>'],... + 'NumberTitle','off', 'Tag','Scalp_figure'); + if ~isempty(posfig) + set(hsig, 'Position', posfig) + end end set(hsig,'Color', [1 1 1]) % set(hsig, 'Renderer', 'painters'); @@ -689,9 +703,9 @@ clrmap = cmap; % cmap is an m-by-3 matrix of real numbers between 0.0 and 1.0. end if ischar(maplimit) - clrbarcustom = 0; % + clrbarcustom = 0; % else - clrbarcustom = 1; % for plotting just 1 colorbar when custom scale is specified + clrbarcustom = 1; % for plotting just 1 colorbar when custom scale is specified end % @@ -700,307 +714,307 @@ iadj = 1; continueplot = 1; while iadj<=nadj && continueplot - ksub = 1; - for ilat =1:nlat - if ismoviex>0 && fra>secondframe - %disp('creando figura') - hsig = figure('Position',pos2, 'Name',['<< Frame ' num2str(fra) ' >>'],... - 'NumberTitle','off', 'Tag','Scalp_figure'); - set(hsig,'Color', [1 1 1]) - if ~isempty(posfig) - set(hsig, 'Position', posfig) - end - %set(hsig, 'Renderer', 'painters'); + ksub = 1; + for ilat =1:nlat + if ismoviex>0 && fra>secondframe + %disp('creando figura') + hsig = figure('Position',pos2, 'Name',['<< Frame ' num2str(fra) ' >>'],... + 'NumberTitle','off', 'Tag','Scalp_figure'); + set(hsig,'Color', [1 1 1]) + if ~isempty(posfig) + set(hsig, 'Position', posfig) + end + %set(hsig, 'Renderer', 'painters'); + end + for ibin=1:nbin + if ismoviex>0 + axes('position',[0.05 0.05+hi*(nbin-ibin) 0.9 hi]) + else + axes('position',[0.05+wi*(ilat-1) 0.05+hi*(nbin-ibin) wi hi]) + end + if nlat>=1 && ~strcmp(measurestr, 'insta') && ~strcmp(measurestr, 'instalapla') + latetitle = [num2str(latencyArray(ilat,1)) '-' num2str(latencyArray(ilat,2))]; + else + latetitle = num2str(latencyArray(ilat)); + end + if ~isnumeric(baseline) + if ismember_bc2(baseline, {'pre' 'post' 'all' 'none'}) + for c=1:ERP.nchan + blv = blvalue(ERP, c, binArray(ibin), baseline); + datap(c,:) = ERP.bindata(c,:,binArray(ibin)) - blv; + end + else + error(['ERPLAB says: error at pop_scalplot(). Invalid option: ' baselin]) end - for ibin=1:nbin - if ismoviex>0 - axes('position',[0.05 0.05+hi*(nbin-ibin) 0.9 hi]) - else - axes('position',[0.05+wi*(ilat-1) 0.05+hi*(nbin-ibin) wi hi]) - end - if nlat>=1 && ~strcmp(measurestr, 'insta') && ~strcmp(measurestr, 'instalapla') - latetitle = [num2str(latencyArray(ilat,1)) '-' num2str(latencyArray(ilat,2))]; - else - latetitle = num2str(latencyArray(ilat)); - end - if ~isnumeric(baseline) - if ismember_bc2(baseline, {'pre' 'post' 'all' 'none'}) - for c=1:ERP.nchan - blv = blvalue(ERP, c, binArray(ibin), baseline); - datap(c,:) = ERP.bindata(c,:,binArray(ibin)) - blv; - end - else - error(['ERPLAB says: error at pop_scalplot(). Invalid option: ' baselin]) - end - else - if length(baseline)==2 - for c=1:ERP.nchan - blv = blvalue(ERP, c, binArray(ibin), baseline); - datap(c,:) = ERP.bindata(c,:,binArray(ibin)) - blv; - end - else - error(['ERPLAB says: error at pop_scalplot(). Invalid option: ' num2str(baseline)]) - end - end - - % - % Measurement setting - % - switch measurestr - case 'insta' - data2plot = datap(:,latArray(ilat));% ERP.bindata(:,latArray(ilat),binArray(ibin)); - case 'mean' - data2plot = mean(datap(:,latArray(ilat,1):latArray(ilat,2)), 2); - case 'rms' - data2plot = sqrt(mean(datap(:,latArray(ilat,1):latArray(ilat,2)).^2, 2)); - case {'area','areat','areap','arean','ninteg'} - data2plot = geterpvalues(ERP, [latArray(ilat,1) latArray(ilat,2)],... - binArray(ibin), 1:ERP.nchan, measurestr, baseline, 1)'; - case 'instalapla' - data2plot = del2map( datap(:,latArray(ilat)), ERP.chanlocs); - case 'meanlapla' - data2plot = mean(datap(:,latArray(ilat,1):latArray(ilat,2)), 2); - data2plot = del2map(data2plot, ERP.chanlocs); - end - if ischar(maplimit) - if strcmpi(maplimit,'auto') && ilat==1 - maplimit = [min(data2plot) max(data2plot)]; - end - end - - % - % Legend - % - titulo = titlemaker(ERP, binleg, bindesc, vtype, vlatency, binArray, measurestr, latetitle, ibin); - - % - % Plot head(s) - % - % try - if strcmpi(mtype, '3d') - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Plot 3D scalp map, at current latency, current bin % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - if strcmpi(elestyle, 'off') - auxelestyle = 'off'; - elclbls = 0; - else - auxelestyle = 'on'; - switch elestyle - case 'on' - elclbls = 0; - case {'numbers','ptsnumbers'} - elclbls = 1; - case {'labels','ptslabels'} - elclbls = 2; - otherwise - elclbls = 0; - end - - end - - % colorbar and plot - cb3d = 0; - % - % Plot ERP on a 3D head - % - [HeadAxes(ksub), ColorbarHandle] = headplot_erp(data2plot, splinefile, 'electrodes', auxelestyle, 'view', mview,... - 'maplimits', maplimit, 'cbar', cb3d,'colormap', clrmap, 'title', titulo, 'electrodes3d', elec3D, 'labels', elclbls); %Plots the 3d scalp plot. - - - if clrbar==1 && clrbarcustom==1 - %colorbar('hide'); - erpsinglecolorbar(HeadAxes, ColorbarHandle, nlat) - drawnow - elseif clrbar==0 - set(ColorbarHandle, 'Visible','off') - set(get(ColorbarHandle, 'Children'), 'Visible','off') - drawnow - end - - % - % Title - % - httle = get(gca,'Title'); - set(httle,'FontSize', fontsizel) - set(httle,'FontName', fontnamel) - %pttle = get(httle,'position'); - %set(httle,'position',[pttle(1) pttle(2) pttle(3)]*0.9) - - % - % Copy object when click on axes - % - if ismoviex==0 - axcopy_modified(gca) - end - elseif strcmpi(mtype, '2d') - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Plot 2D scalp map, at current latency, current bin % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % - % Plot ERP on a 2D map - % - mapnumcontour = 12; - mheadrad = 0.5; - topoplot( data2plot, ERP.chanlocs,... - 'style', smapstyle, 'plotrad',mplotrad, 'headrad', mheadrad,'emarker', {'.','k',[],1},... - 'numcontour', mapnumcontour, 'maplimits', maplimit, 'colormap', clrmap,'electrodes', elestyle, 'nosedir', mapview); - - HeadAxes(ksub) = gca; - - % Color Bar - if clrbar==0 || (clrbar==1 && clrbarcustom==1) - ColorbarHandle = []; - else - clrpos = 'EastOutSide'; - ColorbarHandle = colorbar('location', clrpos); - %set(ColorbarHandle,'Visible','off') - end - - % - % Axes Title (Position) - % - httle = title(titulo , 'FontSize', fontsizel, 'FontName', fontnamel); % Two line title - %set(httle,'Position', [-0.004 0.55 4]) % above - set(httle,'Position', [-0.004 -0.58 4]) % below - %set(httle,'Position', [-0.588 -0.004 4], 'rotation',90) % vertical left - %set(httle,'Position', [0.588 -0.004 4], 'rotation',90) % vertical right - %set(httle,'Position', [-0.42 0.4 4], 'rotation',45) % 45 deg - - if nbin>1 && nlat<=2 % shrink a little bit the haeds for minimizing the overlap with the title - PP = get(HeadAxes(ksub), 'Position'); - set(HeadAxes(ksub), 'Position', [PP(1) PP(2) PP(3) PP(4)*0.9]) - end - if ismoviex==0 - axcopy_modified(gca) - end - else - close(hsig) - msgboxText = 'pop_scalplot cannot plot a map in %s.'; - title_msg = 'ERPLAB: pop_scalplot() error:'; - errorfound(sprintf(msgboxText, upper(mtype)), title_msg); - return - end - % catch - % close(hsig) - % serr = lasterror; - % msgboxText = ['Something went wrong: \n\n'... - % serr.message '\n']; - % title_msg = 'ERPLAB: pop_scalplot() error:'; - % errorfound(sprintf(msgboxText), title_msg); - % return - % end - - ksub = ksub + 1; + else + if length(baseline)==2 + for c=1:ERP.nchan + blv = blvalue(ERP, c, binArray(ibin), baseline); + datap(c,:) = ERP.bindata(c,:,binArray(ibin)) - blv; + end + else + error(['ERPLAB says: error at pop_scalplot(). Invalid option: ' num2str(baseline)]) + end + end + + % + % Measurement setting + % + switch measurestr + case 'insta' + data2plot = datap(:,latArray(ilat));% ERP.bindata(:,latArray(ilat),binArray(ibin)); + case 'mean' + data2plot = mean(datap(:,latArray(ilat,1):latArray(ilat,2)), 2); + case 'rms' + data2plot = sqrt(mean(datap(:,latArray(ilat,1):latArray(ilat,2)).^2, 2)); + case {'area','areat','areap','arean','ninteg'} + data2plot = geterpvalues(ERP, [latArray(ilat,1) latArray(ilat,2)],... + binArray(ibin), 1:ERP.nchan, measurestr, baseline, 1)'; + case 'instalapla' + data2plot = del2map( datap(:,latArray(ilat)), ERP.chanlocs); + case 'meanlapla' + data2plot = mean(datap(:,latArray(ilat,1):latArray(ilat,2)), 2); + data2plot = del2map(data2plot, ERP.chanlocs); + end + if ischar(maplimit) + if strcmpi(maplimit,'auto') && ilat==1 + maplimit = [min(data2plot) max(data2plot)]; + end + end + + % + % Legend + % + titulo = titlemaker(ERP, binleg, bindesc, vtype, vlatency, binArray, measurestr, latetitle, ibin); + + % + % Plot head(s) + % + % try + if strcmpi(mtype, '3d') + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Plot 3D scalp map, at current latency, current bin % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if strcmpi(elestyle, 'off') + auxelestyle = 'off'; + elclbls = 0; + else + auxelestyle = 'on'; + switch elestyle + case 'on' + elclbls = 0; + case {'numbers','ptsnumbers'} + elclbls = 1; + case {'labels','ptslabels'} + elclbls = 2; + otherwise + elclbls = 0; + end + end - %set(gcf,'Color', [1 1 1]) - drawnow + % colorbar and plot + cb3d = 0; % - % Stack for AGIF + % Plot ERP on a 3D head % - if ismoviex>0 - if clrbar==1 && clrbarcustom==1 && strcmpi(mtype, '2d') - % - % When single colorbar is requiered (custom scale) - % - try - if isempty(ColorbarHandle) - ColorbarHandle = colorbar('Visible', 'off'); - end - erpsinglecolorbar(HeadAxes(end), ColorbarHandle, 1) - catch - end - drawnow - end - if adj1frame==1 && iadj==1 % agif --> Adjust frame size - BackERPLABcolor = [1 0.9 0.3]; % yellow - question = 'Press OK when ready to continue.'; - titlet = 'Adjusting frame size'; - oldcolor = get(0,'DefaultUicontrolBackgroundColor'); - set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) - button = questdlg(question, titlet,'OK', 'OK'); - set(0,'DefaultUicontrolBackgroundColor', oldcolor) - - if ~strcmpi(button,'OK') - disp('User selected Cancel') - continueplot = 0; - ismoviex = 0; - else - findplot = findobj('Tag','Scalp_figure'); - if ~isempty(findplot) - lastfig = figure(findplot(1)); - posfig = get(lastfig,'Position'); - plotset = evalin('base', 'plotset'); - plotset.pscalp.posfig = posfig; - assignin('base','plotset', plotset); - end - %fra = fra + 1; - end - secondframe = 0; - close(hsig) - HeadAxes = []; - break - end - if strcmpi(movtype,'gif') % gif - if fra==1 - f = getframe(hsig); - pause(0.01) - [im,map] = rgb2ind(f.cdata,256,'nodither'); - pause(0.01) - im(1,1,1,nlat) = 0; - end - - fra = fra + 1; - f = getframe(hsig); - pause(0.01) - im(:,:,1,fra) = rgb2ind(f.cdata, map,'nodither'); - pause(0.02) - close(hsig) - else % movie - if fra==1 - % Preallocate movie structure. - im(1:nlat) = struct('cdata', [],... - 'colormap', []); - pause(0.01) - im(1) = getframe(hsig); - pause(0.01) - end - - fra = fra + 1; - im(fra) = getframe(hsig); - pause(0.01) - close(hsig) - end - HeadAxes = []; + [HeadAxes(ksub), ColorbarHandle] = headplot_erp(data2plot, splinefile, 'electrodes', auxelestyle, 'view', mview,... + 'maplimits', maplimit, 'cbar', cb3d,'colormap', clrmap, 'title', titulo, 'electrodes3d', elec3D, 'labels', elclbls); %Plots the 3d scalp plot. + + + if clrbar==1 && clrbarcustom==1 + %colorbar('hide'); + erpsinglecolorbar(HeadAxes, ColorbarHandle, nlat) + drawnow + elseif clrbar==0 + set(ColorbarHandle, 'Visible','off') + set(get(ColorbarHandle, 'Children'), 'Visible','off') + drawnow end - %ksub = ksub + 1; - end - iadj = iadj+1; - if clrbar==1 && clrbarcustom==1 && ismoviex==0 && strcmpi(mtype, '2d') + % + % Title + % + httle = get(gca,'Title'); + set(httle,'FontSize', fontsizel) + set(httle,'FontName', fontnamel) + %pttle = get(httle,'position'); + %set(httle,'position',[pttle(1) pttle(2) pttle(3)]*0.9) + + % + % Copy object when click on axes + % + if ismoviex==0 + axcopy_modified(gca) + end + elseif strcmpi(mtype, '2d') + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Plot 2D scalp map, at current latency, current bin % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % + % Plot ERP on a 2D map + % + mapnumcontour = 12; + mheadrad = 0.5; + topoplot( data2plot, ERP.chanlocs,... + 'style', smapstyle, 'plotrad',mplotrad, 'headrad', mheadrad,'emarker', {'.','k',[],1},... + 'numcontour', mapnumcontour, 'maplimits', maplimit, 'colormap', clrmap,'electrodes', elestyle, 'nosedir', mapview); + + HeadAxes(ksub) = gca; + + % Color Bar + if clrbar==0 || (clrbar==1 && clrbarcustom==1) + ColorbarHandle = []; + else + clrpos = 'EastOutSide'; + ColorbarHandle = colorbar('location', clrpos); + %set(ColorbarHandle,'Visible','off') + end + + % + % Axes Title (Position) + % + httle = title(titulo , 'FontSize', fontsizel, 'FontName', fontnamel); % Two line title + %set(httle,'Position', [-0.004 0.55 4]) % above + set(httle,'Position', [-0.004 -0.58 4]) % below + %set(httle,'Position', [-0.588 -0.004 4], 'rotation',90) % vertical left + %set(httle,'Position', [0.588 -0.004 4], 'rotation',90) % vertical right + %set(httle,'Position', [-0.42 0.4 4], 'rotation',45) % 45 deg + + if nbin>1 && nlat<=2 % shrink a little bit the haeds for minimizing the overlap with the title + PP = get(HeadAxes(ksub), 'Position'); + set(HeadAxes(ksub), 'Position', [PP(1) PP(2) PP(3) PP(4)*0.9]) + end + if ismoviex==0 + axcopy_modified(gca) + end + else + close(hsig) + msgboxText = 'pop_scalplot cannot plot a map in %s.'; + title_msg = 'ERPLAB: pop_scalplot() error:'; + errorfound(sprintf(msgboxText, upper(mtype)), title_msg); + return + end + % catch + % close(hsig) + % serr = lasterror; + % msgboxText = ['Something went wrong: \n\n'... + % serr.message '\n']; + % title_msg = 'ERPLAB: pop_scalplot() error:'; + % errorfound(sprintf(msgboxText), title_msg); + % return + % end + + ksub = ksub + 1; + end + %set(gcf,'Color', [1 1 1]) + drawnow + + % + % Stack for AGIF + % + if ismoviex>0 + if clrbar==1 && clrbarcustom==1 && strcmpi(mtype, '2d') % % When single colorbar is requiered (custom scale) % - if isempty(ColorbarHandle) + try + if isempty(ColorbarHandle) ColorbarHandle = colorbar('Visible', 'off'); + end + erpsinglecolorbar(HeadAxes(end), ColorbarHandle, 1) + catch end - erpsinglecolorbar(HeadAxes, ColorbarHandle, nlat) drawnow + end + if adj1frame==1 && iadj==1 % agif --> Adjust frame size + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = 'Press OK when ready to continue.'; + titlet = 'Adjusting frame size'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(question, titlet,'OK', 'OK'); + set(0,'DefaultUicontrolBackgroundColor', oldcolor) + + if ~strcmpi(button,'OK') + disp('User selected Cancel') + continueplot = 0; + ismoviex = 0; + else + findplot = findobj('Tag','Scalp_figure'); + if ~isempty(findplot) + lastfig = figure(findplot(1)); + posfig = get(lastfig,'Position'); + plotset = evalin('base', 'plotset'); + plotset.pscalp.posfig = posfig; + assignin('base','plotset', plotset); + end + %fra = fra + 1; + end + secondframe = 0; + close(hsig) + HeadAxes = []; + break + end + if strcmpi(movtype,'gif') % gif + if fra==1 + f = getframe(hsig); + pause(0.01) + [im,map] = rgb2ind(f.cdata,256,'nodither'); + pause(0.01) + im(1,1,1,nlat) = 0; + end + + fra = fra + 1; + f = getframe(hsig); + pause(0.01) + im(:,:,1,fra) = rgb2ind(f.cdata, map,'nodither'); + pause(0.02) + close(hsig) + else % movie + if fra==1 + % Preallocate movie structure. + im(1:nlat) = struct('cdata', [],... + 'colormap', []); + pause(0.01) + im(1) = getframe(hsig); + pause(0.01) + end + + fra = fra + 1; + im(fra) = getframe(hsig); + pause(0.01) + close(hsig) + end + HeadAxes = []; end + %ksub = ksub + 1; + end + iadj = iadj+1; + if clrbar==1 && clrbarcustom==1 && ismoviex==0 && strcmpi(mtype, '2d') + + % + % When single colorbar is requiered (custom scale) + % + if isempty(ColorbarHandle) + ColorbarHandle = colorbar('Visible', 'off'); + end + erpsinglecolorbar(HeadAxes, ColorbarHandle, nlat) + drawnow + end end assignin('base','scalpicture', hsig); binArraystr = vect2colon(binArray); if size(latencyArray,1)==1 - latencystr = vect2colon(latencyArray); + latencystr = vect2colon(latencyArray); else - latencystr = mat2colon(latencyArray); + latencystr = mat2colon(latencyArray); end fprintf('Mapped Channels: '); for j=1:ERP.nchan - fprintf('%s - ', char(ERP.chanlocs(j).labels)); + fprintf('%s - ', char(ERP.chanlocs(j).labels)); end fprintf('\n'); @@ -1008,18 +1022,18 @@ % Create final Animation % if ismoviex>0 - if strcmpi(movtype,'gif') - pause(0.1) - imwrite(im, map, fullgifname,'DelayTime',1/FPS,'LoopCount',inf);% save animated gif file - elseif strcmpi(movtype,'mat') - pause(0.1) - save(fullgifname, 'im', '-mat'); % save the MATLAB movie to a file - elseif strcmpi(movtype,'avi') - pause(0.1) - movie2avi(im, fullgifname, 'compression', compression, 'fps', FPS, 'quality', quality, 'videoname', vname); % Create AVI file. - else - error('invalid file format') - end + if strcmpi(movtype,'gif') + pause(0.1) + imwrite(im, map, fullgifname,'DelayTime',1/FPS,'LoopCount',inf);% save animated gif file + elseif strcmpi(movtype,'mat') + pause(0.1) + save(fullgifname, 'im', '-mat'); % save the MATLAB movie to a file + elseif strcmpi(movtype,'avi') + pause(0.1) + movie2avi(im, fullgifname, 'compression', compression, 'fps', FPS, 'quality', quality, 'videoname', vname); % Create AVI file. + else + error('invalid file format') + end end % @@ -1027,55 +1041,55 @@ % skipfields = {'ERP','binArray','latencyArray','History'}; if ismoviex==0 - skipfields = [skipfields {'FPS','Filename','Quality','Compression','VideoIntro'}]; + skipfields = [skipfields {'FPS','Filename','Quality','Compression','VideoIntro'}]; end if strcmpi(mtype, '2d') - skipfields = [skipfields {'Electrodes3d'}]; + skipfields = [skipfields {'Electrodes3d'}]; end fn = fieldnames(p.Results); erpcom = sprintf( '%s = pop_scalplot( %s, %s, %s ', inputname(1), inputname(1), binArraystr, latencystr); for q=1:length(fn) - fn2com = fn{q}; % inputname - if ~ismember_bc2(fn2com, skipfields) - fn2res = p.Results.(fn2com); % input value - if ~isempty(fn2res) - if ischar(fn2res) - if ~strcmpi(fn2res,'off') - erpcom = sprintf( '%s, ''%s'', ''%s''', erpcom, fn2com, fn2res); - end - elseif iscell(fn2res) - nn = length(fn2res); - erpcom = sprintf( '%s, ''%s'', {''%s'' ', erpcom, fn2com, fn2res{1}); - for ff=2:nn - erpcom = sprintf( '%s, ''%s'' ', erpcom, fn2res{ff}); - end - erpcom = sprintf( '%s}', erpcom); - else - if ~ismember_bc2(fn2com,{'Maplimit','Mapview'}) - erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, vect2colon(fn2res,'Repeat','on')); - else - xyscalestr = sprintf('[ %.1f %.1f %s ]', fn2res(1), fn2res(2), vect2colon(fn2res(3:end),'Delimiter','off')); - erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, xyscalestr); - end - end + fn2com = fn{q}; % inputname + if ~ismember_bc2(fn2com, skipfields) + fn2res = p.Results.(fn2com); % input value + if ~isempty(fn2res) + if ischar(fn2res) + if ~strcmpi(fn2res,'off') + erpcom = sprintf( '%s, ''%s'', ''%s''', erpcom, fn2com, fn2res); end + elseif iscell(fn2res) + nn = length(fn2res); + erpcom = sprintf( '%s, ''%s'', {''%s'' ', erpcom, fn2com, fn2res{1}); + for ff=2:nn + erpcom = sprintf( '%s, ''%s'' ', erpcom, fn2res{ff}); + end + erpcom = sprintf( '%s}', erpcom); + else + if ~ismember_bc2(fn2com,{'Maplimit','Mapview'}) + erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, vect2colon(fn2res,'Repeat','on')); + else + xyscalestr = sprintf('[ %.1f %.1f %s ]', fn2res(1), fn2res(2), vect2colon(fn2res(3:end),'Delimiter','off')); + erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, xyscalestr); + end + end end + end end erpcom = sprintf( '%s );', erpcom); % get history from script. ERP switch shist - case 1 % from GUI - displayEquiComERP(erpcom); - case 2 % from script - ERP = erphistory(ERP, [], erpcom, 1); - case 3 - % implicit - % ERP = erphistory(ERP, [], erpcom, 1); - % fprintf('%%Equivalent command:\n%s\n\n', erpcom); - otherwise %off or none - erpcom = ''; - return + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + ERP = erphistory(ERP, [], erpcom, 1); + case 3 + % implicit + % ERP = erphistory(ERP, [], erpcom, 1); + % fprintf('%%Equivalent command:\n%s\n\n', erpcom); + otherwise %off or none + erpcom = ''; + return end % @@ -1088,37 +1102,37 @@ %-----------------base line mean value-------------------------------------------------------------- function blv = blvalue(ERP, chan, bin, bl) if isfield(ERP, 'datatype') - datatype = ERP.datatype; + datatype = ERP.datatype; else - datatype = 'ERP'; + datatype = 'ERP'; end if strcmpi(datatype, 'ERP') - kktime = 1000; - srate = ERP.srate; + kktime = 1000; + srate = ERP.srate; else - kktime = 1; - srate = ERP.pnts/ERP.xmax; + kktime = 1; + srate = ERP.pnts/ERP.xmax; end if isnumeric(bl) - toffsa = abs(round(ERP.xmin*srate))+1; - baseline = round((bl/kktime)*srate) + toffsa; %msec to samples - p1 = baseline(1); - p2 = baseline(2); + toffsa = abs(round(ERP.xmin*srate))+1; + baseline = round((bl/kktime)*srate) + toffsa; %msec to samples + p1 = baseline(1); + p2 = baseline(2); else - switch bl - case 'none' - blv = 0; - return - case 'pre' - p1=1; - p2 = find(ERP.times==0); % zero-time locked sample - case 'post' - p1 = find(ERP.times==0); % zero-time locked sample - p2 = ERP.pnts; - case 'all' - p1 = 1; - p2 = ERP.pnts; - end + switch bl + case 'none' + blv = 0; + return + case 'pre' + p1=1; + p2 = find(ERP.times==0); % zero-time locked sample + case 'post' + p1 = find(ERP.times==0); % zero-time locked sample + p2 = ERP.pnts; + case 'all' + p1 = 1; + p2 = ERP.pnts; + end end blv = mean(ERP.bindata(chan,p1:p2, bin)); @@ -1127,9 +1141,9 @@ %----------------- legend -------------------------------------------------------------- function titulo = titlemaker(ERP, binleg, bindesc, vtype, vlatency, binArray, measurestr, latetitle, ibin) if isfield(ERP, 'datatype') - datatype = ERP.datatype; + datatype = ERP.datatype; else - datatype = 'ERP'; + datatype = 'ERP'; end strbinnum = ['Bin' num2str(binArray(ibin))]; @@ -1140,12 +1154,12 @@ strvtype = ['''' measurestr '''']; strcomma2 = ','; if strcmpi(datatype, 'ERP') - strvlate = [latetitle ' ms']; + strvlate = [latetitle ' ms']; else %FFT - strvlate = [latetitle ' Hz']; + strvlate = [latetitle ' Hz']; end t = [strbinnum*binleg strequal*binleg*bindesc strbindes*bindesc strcomma1*(vtype&(binleg|bindesc))... - strvtype*vtype strcomma2*(vlatency&(binleg|bindesc|vtype)) strvlate*vlatency]; + strvtype*vtype strcomma2*(vlatency&(binleg|bindesc|vtype)) strvlate*vlatency]; t = nonzeros(t)'; titulo = strtrim(char(t)); diff --git a/pop_functions/pop_summary_AR_erp_detection.m b/pop_functions/pop_summary_AR_erp_detection.m index 2e5f5a92..69cbb978 100755 --- a/pop_functions/pop_summary_AR_erp_detection.m +++ b/pop_functions/pop_summary_AR_erp_detection.m @@ -27,7 +27,7 @@ %b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b % % ERPLAB Toolbox -% Copyright 2007 The Regents of the University of California +% Copyright © 2007 The Regents of the University of California % Created by Javier Lopez-Calderon and Steven Luck % Center for Mind and Brain, University of California, Davis, % javlopez@ucdavis.edu, sjluck@ucdavis.edu @@ -52,75 +52,79 @@ histoflags = []; if nargin<1 - help erp_summary_AR_detection - return + help erp_summary_AR_detection + return end if nargin==1 - if isempty(ERP) - msgboxText = 'No ERPset was found!'; - title_msg = 'ERPLAB: pop_summary_AR_erp_detection() error:'; - errorfound(msgboxText, title_msg); - return - end - if ~isfield(ERP, 'bindata') - msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; - title = 'ERPLAB: pop_summary_AR_erp_detection error'; - errorfound(msgboxText, title); - return - end - if isempty(ERP.bindata) - msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; - title = 'ERPLAB: pop_summary_AR_erp_detection error'; - errorfound(msgboxText, title); - return - end - BackERPLABcolor = [1 0.9 0.3]; % ERPLAB main window background - question = 'In order to see your summary, What would you like to do?'; + if isempty(ERP) + msgboxText = 'No ERPset was found!'; + title_msg = 'ERPLAB: pop_summary_AR_erp_detection() error:'; + errorfound(msgboxText, title_msg); + return + end + if ~isfield(ERP, 'bindata') + msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; + title = 'ERPLAB: pop_summary_AR_erp_detection error'; + errorfound(msgboxText, title); + return + end + if isempty(ERP.bindata) + msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; + title = 'ERPLAB: pop_summary_AR_erp_detection error'; + errorfound(msgboxText, title); + return + end + BackERPLABcolor = [1 0.9 0.3]; % ERPLAB main window background + question = 'In order to see your summary, What would you like to do?'; + if isempty(ERP.erpname)%%changed by GH 2022 title = 'Artifact detection summary'; - oldcolor = get(0,'DefaultUicontrolBackgroundColor'); - set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) - button = questdlg(question, title,'Save in a file','Show at Command Window', 'Cancel','Show at Command Window'); - set(0,'DefaultUicontrolBackgroundColor',oldcolor) + else + title = ['Artifact detection summary for ',ERP.erpname]; + end + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(question, title,'Save in a file','Show at Command Window', 'Cancel','Show at Command Window'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Show at Command Window') + fullname = ''; + elseif strcmpi(button,'Save in a file') - if strcmpi(button,'Show at Command Window') - fullname = ''; - elseif strcmpi(button,'Save in a file') - - % - % Save OUTPUT file - % - [filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save Artifact Detection Summary as', ['AR_summary_' ERP.erpname]); + % + % Save OUTPUT file + % + [filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save Artifact Detection Summary as', ['AR_summary_' ERP.erpname]); + + if isequal(filename,0) + disp('User selected Cancel') + return + else + [px, fname, ext] = fileparts(filename); + + if strcmp(ext,'') - if isequal(filename,0) - disp('User selected Cancel') - return + if filterindex==1 || filterindex==3 + ext = '.txt'; else - [px, fname, ext] = fileparts(filename); - - if strcmp(ext,'') - - if filterindex==1 || filterindex==3 - ext = '.txt'; - else - ext = '.dat'; - end - end - - fname = [ fname ext]; - fullname = fullfile(filepath, fname); - disp(['For saving artifact detection summary, user selected ' fullname '']) - + ext = '.dat'; end - elseif strcmpi(button,'Cancel') || strcmpi(button,'') - disp('User selected Cancel') - return + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + disp(['For saving artifact detection summary, user selected ' fullname '']) + end - - % - % Somersault - % - [ERP, acce, rej, histoflags, erpcom] = pop_summary_AR_erp_detection(ERP, fullname, 'History', 'gui'); + elseif strcmpi(button,'Cancel') || strcmpi(button,'') + disp('User selected Cancel') return + end + + % + % Somersault + % + [ERP, acce, rej, histoflags, erpcom] = pop_summary_AR_erp_detection(ERP, fullname, 'History', 'gui'); + return end % @@ -136,25 +140,25 @@ p.parse(ERP, fullname, varargin{:}); if isempty(ERP) - msgboxText = 'No ERPset was found!'; - error('prog:input', ['ERPLAB says: ' msgboxText]); + msgboxText = 'No ERPset was found!'; + error('prog:input', ['ERPLAB says: ' msgboxText]); end if ~isfield(ERP, 'bindata') - msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; - error('prog:input', ['ERPLAB says: ' msgboxText]); + msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; + error('prog:input', ['ERPLAB says: ' msgboxText]); end if isempty(ERP.bindata) - msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; - error('prog:input', ['ERPLAB says: ' msgboxText]); + msgboxText = 'pop_summary_AR_erp_detection() cannot work with an empty erpset.'; + error('prog:input', ['ERPLAB says: ' msgboxText]); end if strcmpi(p.Results.History,'implicit') - shist = 3; % implicit + shist = 3; % implicit elseif strcmpi(p.Results.History,'script') - shist = 2; % script + shist = 2; % script elseif strcmpi(p.Results.History,'gui') - shist = 1; % gui + shist = 1; % gui else - shist = 0; % off + shist = 0; % off end % if isempty(strtrim(fullname)) % fidsumm = 1; % to command window @@ -162,13 +166,13 @@ % fidsumm = fopen( fullname , 'w'); % to a file % end if isempty(strtrim(fullname)) - fidsumm = 1; % to command window + fidsumm = 1; % to command window else - if strcmpi(strtrim(fullname), 'none') - fidsumm = -99; - else - fidsumm = fopen( fullname , 'w'); % to a file - end + if strcmpi(strtrim(fullname), 'none') + fidsumm = -99; + else + fidsumm = fopen( fullname , 'w'); % to a file + end end % @@ -180,8 +184,8 @@ % Table % if fidsumm~=-99 - hdr = {'Bin' '#(%) accepted' '#(%) rejected' '# F2' '# F3' '# F4' '# F5' '# F6' '# F7' '# F8' }; - fprintf(fidsumm, '%s %15s %15s %7s %7s %7s %7s %7s %7s %7s\n', hdr{:}); + hdr = {'Bin' '#(%) accepted' '#(%) rejected' '# F2' '# F3' '# F4' '# F5' '# F6' '# F7' '# F8' }; + fprintf(fidsumm, '%s %15s %15s %7s %7s %7s %7s %7s %7s %7s\n', hdr{:}); end s = warning('off','MATLAB:divideByZero'); rej = ERP.ntrials.rejected; @@ -190,11 +194,11 @@ prej = 100-pacce; if fidsumm~=-99 - for i=1:ERP.nbin - paccestr{i} = sprintf('%.1f', pacce(i)); - prejstr{i} = sprintf('%.1f', prej(i)); - fprintf(fidsumm, '%g %9g(%5s) %8g(%5s) %7g %7g %7g %7g %7g %7g %7g\n', i,acce(i), paccestr{i}, rej(i), prejstr{i}, histoflags(i,2:8)); - end + for i=1:ERP.nbin + paccestr{i} = sprintf('%.1f', pacce(i)); + prejstr{i} = sprintf('%.1f', prej(i)); + fprintf(fidsumm, '%g %9g(%5s) %8g(%5s) %7g %7g %7g %7g %7g %7g %7g\n', i,acce(i), paccestr{i}, rej(i), prejstr{i}, histoflags(i,2:8)); + end end trej = sum(rej); tacce = sum(acce); @@ -202,34 +206,34 @@ tprej = 100-tpacce; % this is MPD if fidsumm~=-99 - tpaccestr = sprintf('%.1f', tpacce); - tprejstr = sprintf('%.1f', tprej); - thistoflags = sum(histoflags,1); - fprintf(fidsumm, [repmat('_',1,100) '\n']); - fprintf(fidsumm, 'Total %6g(%5s) %8g(%5s) %7g %7g %7g %7g %7g %7g %7g\n', tacce, tpaccestr, trej, tprejstr, thistoflags(2:8)); + tpaccestr = sprintf('%.1f', tpacce); + tprejstr = sprintf('%.1f', tprej); + thistoflags = sum(histoflags,1); + fprintf(fidsumm, [repmat('_',1,100) '\n']); + fprintf(fidsumm, 'Total %6g(%5s) %8g(%5s) %7g %7g %7g %7g %7g %7g %7g\n', tacce, tpaccestr, trej, tprejstr, thistoflags(2:8)); end if fidsumm>1 - fclose(fidsumm); - erpcom = sprintf('pop_summary_AR_erp_detection(ERP, ''%s'');', fullname); + fclose(fidsumm); + erpcom = sprintf('pop_summary_AR_erp_detection(ERP, ''%s'');', fullname); else - erpcom = sprintf('pop_summary_AR_erp_detection(ERP);'); + erpcom = sprintf('pop_summary_AR_erp_detection(ERP);'); end warning(s) % restore state % get history from script. ERP switch shist - case 1 % from GUI - displayEquiComERP(erpcom); - case 2 % from script - ERP = erphistory(ERP, [], erpcom, 1); - case 3 - % implicit - %ERP = erphistory(ERP, [], erpcom, 1); - %fprintf('%%Equivalent command:\n%s\n\n', erpcom); - otherwise %off or none - erpcom = ''; - return + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + ERP = erphistory(ERP, [], erpcom, 1); + case 3 + % implicit + %ERP = erphistory(ERP, [], erpcom, 1); + %fprintf('%%Equivalent command:\n%s\n\n', erpcom); + otherwise %off or none + erpcom = ''; + return end % % Completion statement diff --git a/studio_functions/Functions/EEGLAB/CSD/eeg_checkchanlocs.m b/studio_functions/Functions/EEGLAB/CSD/eeg_checkchanlocs.m new file mode 100755 index 00000000..4ff19e7a --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eeg_checkchanlocs.m @@ -0,0 +1,276 @@ +% eeg_checkchanlocs() - Check the consistency of the channel locations structure +% of an EEGLAB dataset. +% +% Usage: +% >> EEG = eeg_checkchanlocs(EEG); +% >> [chanlocs chaninfo] = eeg_checkchanlocs( chanlocs, chaninfo); +% +% Inputs: +% EEG - EEG dataset +% chanlocs - EEG.chanlocs structure +% chaninfo - EEG.chaninfo structure +% +% Outputs: +% EEG - new EEGLAB dataset with updated channel location structures +% EEG.chanlocs, EEG.urchanlocs, EEG.chaninfo +% chanlocs - updated channel location structure +% chaninfo - updated chaninfo structure +% +% Author: Arnaud Delorme, SCCN/INC/UCSD, March 2, 2011 + +% Copyright (C) SCCN/INC/UCSD, March 2, 2011, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% Hey Arno -- this is a quick fix to make an analysis work for Makoto +% I think the old version had a bug... + +function [chans, chaninfo, chanedit]= eeg_checkchanlocs(chans, chaninfo); + +if nargin < 1 + help eeg_checkchanlocs; + return; +end + +if nargin < 2 + chaninfo = []; +end + +processingEEGstruct = 0; +if isfield(chans, 'data') + processingEEGstruct = 1; + tmpEEG = chans; + chans = tmpEEG.chanlocs; + chaninfo = tmpEEG.chaninfo; +end + +if ~isfield(chans, 'datachan') + [chanedit,dummy,complicated] = insertchans(chans, chaninfo); +else + chanedit = chans; + complicated = true; +end + +nosevals = { '+X' '-X' '+Y' '-Y' }; +if ~isfield(chaninfo, 'plotrad'), chaninfo.plotrad = []; end +if ~isfield(chaninfo, 'shrink'), chaninfo.shrink = []; end +if ~isfield(chaninfo, 'nosedir'), chaninfo.nosedir = nosevals{1}; end + +% handles deprecated fields +% ------------------------- +plotrad = []; +if isfield(chanedit, 'plotrad'), + plotrad = chanedit(1).plotrad; + chanedit = rmfield(chanedit, 'plotrad'); + if ischar(plotrad) && ~isempty(str2num(plotrad)), plotrad = str2num(plotrad); end + chaninfo.plotrad = plotrad; +end +if isfield(chanedit, 'shrink') && ~isempty(chanedit(1).shrink) + shrinkorskirt = 1; + if ~ischar(chanedit(1).shrink) + plotrad = 0.5/(1-chanedit(1).shrink); % convert old values + end + chanedit = rmfield(chanedit, 'shrink'); + chaninfo.plotrad = plotrad; +end + +% set non-existent fields to [] +% ----------------------------- +fields = { 'labels' 'theta' 'radius' 'X' 'Y' 'Z' 'sph_theta' 'sph_phi' 'sph_radius' 'type' 'ref' 'urchan' }; +fieldtype = { 'str' 'num' 'num' 'num' 'num' 'num' 'num' 'num' 'num' 'str' 'str' 'num' }; +check_newfields = true; %length(fieldnames(chanedit)) < length(fields); +if ~isempty(chanedit) + for index = 1:length(fields) + if check_newfields && ~isfield(chanedit, fields{index}) + % new field + % --------- + if strcmpi(fieldtype{index}, 'num') + chanedit = setfield(chanedit, {1}, fields{index}, []); + else + for indchan = 1:length(chanedit) + chanedit = setfield(chanedit, {indchan}, fields{index}, ''); + end + end + else + % existing fields + % --------------- + allvals = {chanedit.(fields{index})}; + if strcmpi(fieldtype{index}, 'num') + if ~all(cellfun('isclass',allvals,'double')) + numok = cellfun(@isnumeric, allvals); + if any(numok == 0) + for indConvert = find(numok == 0) + chanedit = setfield(chanedit, {indConvert}, fields{index}, []); + end + end + end + else + strok = cellfun('isclass', allvals,'char'); + if strcmpi(fields{index}, 'labels'), prefix = 'E'; else prefix = ''; end + if any(strok == 0) + for indConvert = find(strok == 0) + try + strval = [ prefix num2str(getfield(chanedit, {indConvert}, fields{index})) ]; + chanedit = setfield(chanedit, {indConvert}, fields{index}, strval); + catch + chanedit = setfield(chanedit, {indConvert}, fields{index}, ''); + end + end + end + end + end + end +end +if ~isequal(fieldnames(chanedit)',fields) + try + chanedit = orderfields(chanedit, fields); + catch, end +end + + +% check channel labels +if isfield(chanedit, 'labels') + % prefix (EDF format specification)? + if strfind([chanedit.labels], 'EEG') % `contains() is not back compatible + disp('Detected/removing ''EEG'' prefix from channel labels') + chanprefixes = {'EEG-', 'EEG ', 'EEG'}; % order matters + tmp = {chanedit.labels}; + for idx = 1:length(chanprefixes) + tmp = strrep(tmp, chanprefixes(idx), ''); + end + [chanedit.labels] = deal(tmp{:}); + end + + % duplicate labels? + tmp = sort({chanedit.labels}); + if any(strcmp(tmp(1:end-1),tmp(2:end))) + disp('Warning: some channels have the same label'); + end + + % empty labels? + indEmpty = find(cellfun(@isempty, {chanedit.labels})); + if ~isempty(indEmpty) + tmpWarning = warning('backtrace'); + warning backtrace off; + warning('channel labels should not be empty, creating unique labels'); + warning(tmpWarning); + for index = indEmpty + chanedit(index).labels = sprintf('E%d', index); + end + end +end + +% remove fields +% ------------- +if isfield(chanedit, 'sph_phi_besa' ), chanedit = rmfield(chanedit, 'sph_phi_besa'); end +if isfield(chanedit, 'sph_theta_besa'), chanedit = rmfield(chanedit, 'sph_theta_besa'); end + +% Populating channel location fields with all coordinates systems +if (any( cellfun('isempty',{ chanedit.X })) || any( cellfun('isempty', { chanedit.theta})) || any( cellfun('isempty', { chanedit.sph_theta}))) &&... + (any(~cellfun('isempty',{ chanedit.X })) || any(~cellfun('isempty', { chanedit.theta})) || any(~cellfun('isempty', { chanedit.sph_theta}))) + try + chanedit = convertlocs(chanedit,'auto'); + if isfield(chanedit, 'sph_theta_besa') chanedit = rmfield(chanedit, 'sph_theta_besa'); end + if isfield(chanedit, 'sph_phi_besa' ) chanedit = rmfield(chanedit, 'sph_phi_besa' ); end + catch + disp('eeg_checkchanlocs: Unable to convert electrode locations between coordinate systems'); + end +end + +% reconstruct the chans structure +% ------------------------------- +if complicated + [chans chaninfo.nodatchans] = getnodatchan( chanedit ); + if ~isfield(chaninfo, 'nodatchans'), chaninfo.nodatchans = []; end + if isempty(chanedit) + for iField = 1:length(fields) + chanedit = setfield(chanedit, fields{iField}, []); + end + end +else + chans = rmfield(chanedit,'datachan'); + chaninfo.nodatchans = []; +end + +if processingEEGstruct + tmpEEG.chanlocs = chans; + tmpEEG.chaninfo = chaninfo; + chans = tmpEEG; +end + +% --------------------------------------------- +% separate data channels from non-data channels +% --------------------------------------------- +function [chans, fidsval] = getnodatchan(chans) +if isfield(chans,'datachan') + [chans(cellfun('isempty',{chans.datachan})).datachan] = deal(0); + fids = [chans.datachan] == 0; + fidsval = chans(fids); + chans = rmfield(chans(~fids),'datachan'); +else + fids = []; +end + +% ---------------------------------------- +% fuse data channels and non-data channels +% ---------------------------------------- +function [chans, chaninfo,complicated] = insertchans(chans, chaninfo, nchans) +if nargin < 3, nchans = length(chans); end +[chans.datachan] = deal(1); +complicated = false; % whether we need complicated treatment of datachans & co further down the road..... + +if isfield(chans,'type') + mask = strcmpi({chans.type},'FID') | strcmpi({chans.type},'IGNORE'); + if any(mask) + [chans(mask).datachan] = deal(0); + complicated = true; + end +end +if length(chans) > nchans && nchans ~= 0 % reference at the end of the structure + chans(end).datachan = 0; + complicated = true; +end +if isfield(chaninfo, 'nodatchans') + if ~isempty(chaninfo.nodatchans) && isstruct(chaninfo.nodatchans) + chanlen = length(chans); + for index = 1:length(chaninfo.nodatchans) + fields = fieldnames( chaninfo.nodatchans ); + ind = chanlen+index; + for f = 1:length( fields ) + chans = setfield(chans, { ind }, fields{f}, getfield( chaninfo.nodatchans, { index }, fields{f})); + end + chans(ind).datachan = 0; + complicated = true; + end + chaninfo = rmfield(chaninfo, 'nodatchans'); + + % put these channels first + % ------------------------ + % tmp = chans(chanlen+1:end); + % chans(length(tmp)+1:end) = chans(1:end-length(tmp)); + % chans(1:length(tmp)) = tmp; + end +end diff --git a/studio_functions/Functions/EEGLAB/CSD/eeg_checkset.m b/studio_functions/Functions/EEGLAB/CSD/eeg_checkset.m new file mode 100755 index 00000000..832df7d4 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eeg_checkset.m @@ -0,0 +1,1414 @@ +% eeg_checkset() - check the consistency of the fields of an EEG dataset +% Also: See EEG dataset structure field descriptions below. +% +% Usage: >> [EEGOUT,changes] = eeg_checkset(EEG); % perform all checks +% except 'makeur' +% >> [EEGOUT,changes] = eeg_checkset(EEG, 'keyword'); % perform 'keyword' check(s) +% +% Inputs: +% EEG - EEGLAB dataset structure or (ALLEEG) array of EEG structures +% +% Optional keywords: +% 'icaconsist' - if EEG contains several datasets, check whether they have +% the same ICA decomposition +% 'epochconsist' - if EEG contains several datasets, check whether they have +% identical epoch lengths and time limits. +% 'chanconsist' - if EEG contains several datasets, check whether they have +% the same number of channels and channel labels. +% 'data' - check whether EEG contains data (EEG.data) +% 'loaddata' - load data array (if necessary) +% 'savedata' - save data array (if necessary - see EEG.saved below) +% 'contdata' - check whether EEG contains continuous data +% 'epoch' - check whether EEG contains epoched or continuous data +% 'ica' - check whether EEG contains an ICA decomposition +% 'besa' - check whether EEG contains component dipole locations +% 'event' - check whether EEG contains an event array +% 'makeur' - remake the EEG.urevent structure +% 'checkur' - check whether the EEG.urevent structure is consistent +% with the EEG.event structure +% 'chanlocsize' - check the EEG.chanlocs structure length; show warning if +% necessary. +% 'chanlocs_homogeneous' - check whether EEG contains consistent channel +% information; if not, correct it.This option +% calls eeg_checkchanlocs. +% 'eventconsistency' - check whether EEG.event information are consistent; +% rebuild event* subfields of the 'EEG.epoch' structure +% (can be time consuming). +% Outputs: +% EEGOUT - output EEGLAB dataset or dataset array +% changes - change code: 'no' = no changes; 'yes' = the EEG +% structure was modified +% +% =========================================================== +% The structure of an EEG dataset under EEGLAB (as of v5.03): +% +% Basic dataset information: +% EEG.setname - descriptive name|title for the dataset +% EEG.filename - filename of the dataset file on disk +% EEG.filepath - filepath (directory/folder) of the dataset file(s) +% EEG.trials - number of epochs (or trials) in the dataset. +% If data are continuous, this number is 1. +% EEG.pnts - number of time points (or data frames) per trial (epoch). +% If data are continuous (trials=1), the total number +% of time points (frames) in the dataset +% EEG.nbchan - number of channels +% EEG.srate - data sampling rate (in Hz) +% EEG.xmin - epoch start latency|time (in sec. relative to the +% time-locking event at time 0) +% EEG.xmax - epoch end latency|time (in seconds) +% EEG.times - vector of latencies|times in milliseconds (one per time point) +% EEG.ref - ['common'|'averef'|integer] reference channel type or number +% EEG.history - cell array of ascii pop-window commands that created +% or modified the dataset +% EEG.comments - comments about the nature of the dataset (edit this via +% menu selection Edit > About this dataset) +% EEG.etc - miscellaneous (technical or temporary) dataset information +% EEG.saved - ['yes'|'no'] 'no' flags need to save dataset changes before exit +% +% The data: +% EEG.data - two-dimensional continuous data array (chans, frames) +% ELSE, three-dim. epoched data array (chans, frames, epochs) +% +% The channel locations sub-structures: +% EEG.chanlocs - structure array containing names and locations +% of the channels on the scalp +% EEG.urchanlocs - original (ur) dataset chanlocs structure containing +% all channels originally collected with these data +% (before channel rejection) +% EEG.chaninfo - structure containing additional channel info +% EEG.ref - type of channel reference ('common'|'averef'|+/-int] +% EEG.splinefile - location of the spline file used by headplot() to plot +% data scalp maps in 3-D +% +% The event and epoch sub-structures: +% EEG.event - event structure containing times and nature of experimental +% events recorded as occurring at data time points +% EEG.urevent - original (ur) event structure containing all experimental +% events recorded as occurring at the original data time points +% (before data rejection) +% EEG.epoch - epoch event information and epoch-associated data structure array (one per epoch) +% EEG.eventdescription - cell array of strings describing event fields. +% EEG.epochdescription - cell array of strings describing epoch fields. +% --> See the http://sccn.ucsd.edu/eeglab/maintut/eeglabscript.html for details +% +% ICA (or other linear) data components: +% EEG.icasphere - sphering array returned by linear (ICA) decomposition +% EEG.icaweights - unmixing weights array returned by linear (ICA) decomposition +% EEG.icawinv - inverse (ICA) weight matrix. Columns gives the projected +% topographies of the components to the electrodes. +% EEG.icaact - ICA activations matrix (components, frames, epochs) +% Note: [] here means that 'compute_ica' option has been set +% to 0 under 'File > Memory options' In this case, +% component activations are computed only as needed. +% EEG.icasplinefile - location of the spline file used by headplot() to plot +% component scalp maps in 3-D +% EEG.chaninfo.icachansind - indices of channels used in the ICA decomposition +% EEG.dipfit - array of structures containing component map dipole models +% +% Variables indicating membership of the dataset in a studyset: +% EEG.subject - studyset subject code +% EEG.group - studyset group code +% EEG.condition - studyset experimental condition code +% EEG.run - studyset run number +% EEG.session - studyset session number +% +% Variables used for manual and semi-automatic data rejection: +% EEG.specdata - data spectrum for every single trial +% EEG.specica - data spectrum for every single trial +% EEG.stats - statistics used for data rejection +% EEG.stats.kurtc - component kurtosis values +% EEG.stats.kurtg - global kurtosis of components +% EEG.stats.kurta - kurtosis of accepted epochs +% EEG.stats.kurtr - kurtosis of rejected epochs +% EEG.stats.kurtd - kurtosis of spatial distribution +% EEG.reject - statistics used for data rejection +% EEG.reject.entropy - entropy of epochs +% EEG.reject.entropyc - entropy of components +% EEG.reject.threshold - rejection thresholds +% EEG.reject.icareject - epochs rejected by ICA criteria +% EEG.reject.gcompreject - rejected ICA components +% EEG.reject.sigreject - epochs rejected by single-channel criteria +% EEG.reject.elecreject - epochs rejected by raw data criteria +% +% Author: Arnaud Delorme, CNL / Salk Institute, 2001 +% +% See also: eeglab() + +% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% 01-25-02 reformated help & license -ad +% 01-26-02 chandeg events and trial condition format -ad +% 01-27-02 debug when trial condition is empty -ad +% 02-15-02 remove icawinv recompute for pop_epoch -ad & ja +% 02-16-02 remove last modification and test icawinv separatelly -ad +% 02-16-02 empty event and epoch check -ad +% 03-07-02 add the eeglab options -ad +% 03-07-02 corrected typos and rate/point calculation -ad & ja +% 03-15-02 add channel location reading & checking -ad +% 03-15-02 add checking of ICA and epochs with pop_up windows -ad +% 03-27-02 recorrected rate/point calculation -ad & sm + +function [EEG, res] = eeg_checkset( EEG, varargin ); +msg = ''; +res = 'no'; +com = sprintf('EEG = eeg_checkset( EEG );'); + +if nargin < 1 + help eeg_checkset; + return; +end + +if isempty(EEG), return; end +if ~isfield(EEG, 'data'), return; end + +% checking multiple datasets +% -------------------------- +if length(EEG) > 1 + + if nargin > 1 + switch varargin{1} + case 'epochconsist', % test epoch consistency + % ---------------------- + res = 'no'; + datasettype = unique_bc( [ EEG.trials ] ); + if datasettype(1) == 1 && length(datasettype) == 1, return; % continuous data + elseif datasettype(1) == 1, return; % continuous and epoch data + end + + allpnts = unique_bc( [ EEG.pnts ] ); + allxmin = unique_bc( [ EEG.xmin ] ); + if length(allpnts) == 1 && length(allxmin) == 1, res = 'yes'; end + return; + + case 'chanconsist' % test channel number and name consistency + % ---------------------------------------- + res = 'yes'; + chanlen = unique_bc( [ EEG.nbchan ] ); + anyempty = unique_bc( cellfun( 'isempty', { EEG.chanlocs }) ); + if length(chanlen) == 1 && all(anyempty == 0) + tmpchanlocs = EEG(1).chanlocs; + channame1 = { tmpchanlocs.labels }; + for i = 2:length(EEG) + tmpchanlocs = EEG(i).chanlocs; + channame2 = { tmpchanlocs.labels }; + if length(intersect(channame1, channame2)) ~= length(channame1), res = 'no'; end + end + else res = 'no'; + end + + % Field 'datachan in 'urchanlocs' is removed, if exist + if isfield(EEG, 'urchanlocs') && ~all(cellfun(@isempty,{EEG.urchanlocs})) && isfield([EEG.urchanlocs], 'datachan') + [EEG.urchanlocs] = deal(rmfield([EEG.urchanlocs], 'datachan')); + end + return; + + case 'icaconsist' % test ICA decomposition consistency + % ---------------------------------- + res = 'yes'; + anyempty = unique_bc( cellfun( 'isempty', { EEG.icaweights }) ); + if length(anyempty) == 1 && anyempty(1) == 0 + ica1 = EEG(1).icawinv; + for i = 2:length(EEG) + if ~isequal(EEG(1).icawinv, EEG(i).icawinv) + res = 'no'; + end + end + else res = 'no'; + end + return; + + end + end + +end + +% reading these option take time because +% of disk access +% -------------- +eeglab_options; + +% standard checking +% ----------------- +ALLEEG = EEG; +for inddataset = 1:length(ALLEEG) + + EEG = ALLEEG(inddataset); + + % additional checks + % ----------------- + res = -1; % error code + if ~isempty( varargin) + for index = 1:length( varargin ) + switch varargin{ index } + case 'data',; % already done at the top + case 'contdata',; + if EEG.trials > 1 + errordlg2(strvcat('Error: function only works on continuous data'), 'Error'); + return; + end + case 'ica', + if isempty(EEG.icaweights) + errordlg2(strvcat('Error: no ICA decomposition. use menu "Tools > Run ICA" first.'), 'Error'); + return; + end + case 'epoch', + if EEG.trials == 1 + errordlg2(strvcat('Extract epochs before running that function', 'Use Tools > Extract epochs'), 'Error'); + return + end + case 'besa', + if ~isfield(EEG, 'sources') + errordlg2(strvcat('No dipole information', '1) Export component maps: Tools > Localize ... BESA > Export ...' ... + , '2) Run BESA to localize the equivalent dipoles', ... + '3) Import the BESA dipoles: Tools > Localize ... BESA > Import ...'), 'Error'); + return + end + case 'event', + if isempty(EEG.event) + errordlg2(strvcat('Requires events. You need to add events first.', ... + 'Use "File > Import event info" or "File > Import epoch info"', ... + 'Install plugin VidEd to manually add events as you scroll the data.' ), 'Error'); + return; + end + case 'chanloc', + tmplocs = EEG.chanlocs; + if isempty(tmplocs) || ~isfield(tmplocs, 'theta') || all(cellfun('isempty', { tmplocs.theta })) + errordlg2( strvcat('This functionality requires channel location information.', ... + 'Enter the channel file name via "Edit > Edit dataset info".', ... + 'For channel file format, see ''>> help readlocs'' from the command line.'), 'Error'); + return; + end + case 'chanlocs_homogeneous', + tmplocs = EEG.chanlocs; + if isempty(tmplocs) || ~isfield(tmplocs, 'theta') || all(cellfun('isempty', { tmplocs.theta })) + errordlg2( strvcat('This functionality requires channel location information.', ... + 'Enter the channel file name via "Edit > Edit dataset info".', ... + 'For channel file format, see ''>> help readlocs'' from the command line.'), 'Error'); + return; + end + if ~isfield(EEG.chanlocs, 'X') || isempty(EEG.chanlocs(1).X) + EEG = eeg_checkchanlocs(EEG); + % EEG.chanlocs = convertlocs(EEG.chanlocs, 'topo2all'); + res = ['EEG = eeg_checkset(EEG, ''chanlocs_homogeneous''); ' ]; + end + case 'chanlocsize', + if ~isempty(EEG.chanlocs) + if length(EEG.chanlocs) > EEG.nbchan + questdlg2(strvcat('Warning: there is one more electrode location than', ... + 'data channels. EEGLAB will consider the last electrode to be the', ... + 'common reference channel. If this is not the case, remove the', ... + 'extra channel'), 'Warning', 'Ok', 'Ok'); + end + end + case 'makeur', + if ~isempty(EEG.event) + if isfield(EEG.event, 'urevent'), + EEG.event = rmfield(EEG.event, 'urevent'); + disp('eeg_checkset note: re-creating the original event table (EEG.urevent)'); + else + disp('eeg_checkset note: creating the original event table (EEG.urevent)'); + end + EEG.urevent = EEG.event; + for index = 1:length(EEG.event) + EEG.event(index).urevent = index; + end + end + case 'checkur', + if ~isempty(EEG.event) + if isfield(EEG.event, 'urevent') && ~isempty(EEG.urevent) + urlatencies = [ EEG.urevent.latency ]; + [newlat tmpind] = sort(urlatencies); + if ~isequal(newlat, urlatencies) + EEG.urevent = EEG.urevent(tmpind); + [tmp tmpind2] = sort(tmpind); + for index = 1:length(EEG.event) + EEG.event(index).urevent = tmpind2(EEG.event(index).urevent); + end + end + end + end + case 'eventconsistency', + [EEG res] = eeg_checkset(EEG); + if isempty(EEG.event), return; end + + % check events (slow) + % ------------ + if isfield(EEG.event, 'type') + eventInds = arrayfun(@(x)isempty(x.type), EEG.event); + if any(eventInds) + if all(arrayfun(@(x)isnumeric(x.type), EEG.event)) + for ind = find(eventInds), EEG.event(ind).type = NaN; end + else for ind = find(eventInds), EEG.event(ind).type = 'empty'; end + end + end + if ~all(arrayfun(@(x)ischar(x.type), EEG.event)) && ~all(arrayfun(@(x)isnumeric(x.type), EEG.event)) + disp('Warning: converting all event types to strings'); + for ind = 1:length(EEG.event) + EEG.event(ind).type = num2str(EEG.event(ind).type); + end + EEG = eeg_checkset(EEG, 'eventconsistency'); + end + + end + + % Removing events with NaN latency + % -------------------------------- + if isfield(EEG.event, 'latency') + nanindex = find(isnan([ EEG.event.latency ])); + if ~isempty(nanindex) + EEG.event(nanindex) = []; + trialtext = ''; + for inan = 1:length(nanindex) + trialstext = [trialtext ' ' num2str(nanindex(inan))]; + end + disp(sprintf(['eeg_checkset: Event(s) with NaN latency were deleted \nDeleted event index(es):[' trialstext ']'])); + end + end + + % remove the events which latency are out of boundary + % --------------------------------------------------- + if isfield(EEG.event, 'latency') + if isfield(EEG.event, 'type') && ischar(EEG.event(1).type) + if strcmpi(EEG.event(1).type, 'boundary') && isfield(EEG.event, 'duration') + if EEG.event(1).duration < 1 + EEG.event(1) = []; + elseif EEG.event(1).latency > 0 && EEG.event(1).latency < 1 + EEG.event(1).latency = 0.5; + end + end + end + + try, tmpevent = EEG.event; alllatencies = [ tmpevent.latency ]; + catch, error('Checkset: error empty latency entry for new events added by user'); + end + I1 = find(alllatencies < 0.5); + I2 = find(alllatencies > EEG.pnts*EEG.trials+1); % The addition of 1 was included + % because, if data epochs are extracted from -1 to + % time 0, this allow to include the last event in + % the last epoch (otherwise all epochs have an + % event except the last one + if (length(I1) + length(I2)) > 0 + fprintf('eeg_checkset warning: %d/%d events had out-of-bounds latencies and were removed\n', ... + length(I1) + length(I2), length(EEG.event)); + EEG.event(union(I1, I2)) = []; + end + end + if isempty(EEG.event), return; end + + % save information for non latency fields updates + % ----------------------------------------------- + difffield = []; + if ~isempty(EEG.event) && isfield(EEG.event, 'epoch') + % remove fields with empty epochs + % ------------------------------- + removeevent = []; + try + tmpevent = EEG.event; + allepochs = [ tmpevent.epoch ]; + removeevent = find( allepochs < 1 | allepochs > EEG.trials); + if ~isempty(removeevent) + disp([ 'eeg_checkset warning: ' int2str(length(removeevent)) ' event had invalid epoch numbers and were removed']); + end + catch + for indexevent = 1:length(EEG.event) + if isempty( EEG.event(indexevent).epoch ) || ~isnumeric(EEG.event(indexevent).epoch) ... + || EEG.event(indexevent).epoch < 1 || EEG.event(indexevent).epoch > EEG.trials + removeevent = [removeevent indexevent]; + disp([ 'eeg_checkset warning: event ' int2str(indexevent) ' has an invalid epoch number: removed']); + end + end + end + EEG.event(removeevent) = []; + end + if isempty(EEG.event), return; end + + % Duration set to 0 if empty + % -------------------------- + if isfield(EEG.event, 'duration') + emptyDur = cellfun(@isempty, { EEG.event.duration }); + if any(emptyDur) + for indexevent = find(emptyDur) + EEG.event(indexevent).duration = 0; + end + end + end + + % uniformize fields (str or int) if necessary + % ------------------------------------------- + fnames = fieldnames(EEG.event); + for fidx = 1:length(fnames) + fname = fnames{fidx}; + if ~strcmpi(fname, 'mffkeys') && ~strcmpi(fname, 'mffkeysbackup') + tmpevent = EEG.event; + allvalues = { tmpevent.(fname) }; + try + % find indices of numeric values among values of this event property + valreal = ~cellfun('isclass', allvalues, 'char'); + catch + valreal = mycellfun('isclass', allvalues, 'double'); + end + + format = 'ok'; + if ~all(valreal) % all valreal ok + format = 'str'; + if all(valreal == 0) % all valreal=0 ok + format = 'ok'; + end + end + if strcmp(format, 'str') + fprintf('eeg_checkset note: event field format ''%s'' made uniform\n', fname); + allvalues = cellfun(@num2str, allvalues, 'uniformoutput', false); + [EEG.event(valreal).(fname)] = deal(allvalues{find(valreal)}); + end + end + end + + % check boundary events + % --------------------- + tmpevent = EEG.event; + if isfield(tmpevent, 'type') && ~isnumeric(tmpevent(1).type) + allEventTypes = { tmpevent.type }; + boundsInd = strmatch('boundary', allEventTypes); + if ~isempty(boundsInd), + bounds = [ tmpevent(boundsInd).latency ]; + % remove last event if necessary + if EEG.trials==1;%this if block added by James Desjardins (Jan 13th, 2014) + if round(bounds(end)-0.5+1) >= size(EEG.data,2), EEG.event(boundsInd(end)) = []; bounds(end) = []; end; % remove final boundary if any + end + % The first boundary below need to be kept for + % urevent latency calculation + % if bounds(1) < 0, EEG.event(bounds(1)) = []; end; % remove initial boundary if any + indDoublet = find(bounds(2:end)-bounds(1:end-1)==0); + if ~isempty(indDoublet) + disp('Warning: duplicate boundary event removed'); + if isfield(EEG.event, 'duration') + for indBound = 1:length(indDoublet) + EEG.event(boundsInd(indDoublet(indBound)+1)).duration = EEG.event(boundsInd(indDoublet(indBound)+1)).duration+EEG.event(boundsInd(indDoublet(indBound))).duration; + end + end + EEG.event(boundsInd(indDoublet)) = []; + end + end + end + if isempty(EEG.event), return; end + + % check that numeric format is double (Matlab 7) + % ----------------------------------- + allfields = fieldnames(EEG.event); + if ~isempty(EEG.event) + for index = 1:length(allfields) + tmpval = EEG.event(1).(allfields{index}); + if isnumeric(tmpval) && ~isa(tmpval, 'double') + for indexevent = 1:length(EEG.event) + tmpval = getfield(EEG.event, { indexevent }, allfields{index} ); + EEG.event = setfield(EEG.event, { indexevent }, allfields{index}, double(tmpval)); + end + end + end + end + + % check duration field, replace empty by 0 + % ---------------------------------------- + if isfield(EEG.event, 'duration') + tmpevent = EEG.event; + try, valempt = cellfun('isempty' , { tmpevent.duration }); + catch, valempt = mycellfun('isempty', { tmpevent.duration }); + end + if any(valempt), + for index = find(valempt) + EEG.event(index).duration = 0; + end + end + end + + % resort events + % ------------- + if isfield(EEG.event, 'latency') + try, + if isfield(EEG.event, 'epoch') + TMPEEG = pop_editeventvals(EEG, 'sort', { 'epoch' 0 'latency' 0 }); + else + TMPEEG = pop_editeventvals(EEG, 'sort', { 'latency' 0 }); + end + if ~isequal(TMPEEG.event, EEG.event) + EEG = TMPEEG; + disp('Event resorted by increasing latencies.'); + end + catch, + disp('eeg_checkset: problem when attempting to resort event latencies.'); + end + end + + % check latency of first event + % ---------------------------- + if ~isempty(EEG.event) + if isfield(EEG.event, 'latency') + if EEG.event(1).latency < 0.5 + EEG.event(1).latency = 0.5; + end + end + end + + % build epoch structure + % --------------------- + try, + if EEG.trials > 1 && ~isempty(EEG.event) + % erase existing event-related fields + % ------------------------------ + if ~isfield(EEG,'epoch') + EEG.epoch = []; + end + if ~isempty(EEG.epoch) + if length(EEG.epoch) ~= EEG.trials + disp('Warning: number of epoch entries does not match number of dataset trials;'); + disp(' user-defined epoch entries will be erased.'); + EEG.epoch = []; + else + fn = fieldnames(EEG.epoch); + EEG.epoch = rmfield(EEG.epoch,fn(strncmp('event',fn,5))); + end + end + + % set event field + % --------------- + tmpevent = EEG.event; + eventepoch = [tmpevent.epoch]; + epochevent = cell(1,EEG.trials); + destdata = epochevent; + EEG.epoch(length(epochevent)).event = []; + for k=1:length(epochevent) + epochevent{k} = find(eventepoch==k); + end + tmpepoch = EEG.epoch; + [tmpepoch.event] = epochevent{:}; + EEG.epoch = tmpepoch; + maxlen = max(cellfun(@length,epochevent)); + + % copy event information into the epoch array + % ------------------------------------------- + eventfields = fieldnames(EEG.event)'; + eventfields = eventfields(~strcmp(eventfields,'epoch')); + tmpevent = EEG.event; + for k = 1:length(eventfields) + fname = eventfields{k}; + switch fname + case 'latency' + sourcedata = round(eeg_point2lat([tmpevent.(fname)],[tmpevent.epoch],EEG.srate, [EEG.xmin EEG.xmax]*1000, 1E-3) * 10^8 )/10^8; + sourcedata = num2cell(sourcedata); + case 'duration' + sourcedata = num2cell([tmpevent.(fname)]/EEG.srate*1000); + otherwise + sourcedata = {tmpevent.(fname)}; + end + if maxlen == 1 + destdata = cell(1,length(epochevent)); + destdata(~cellfun('isempty',epochevent)) = sourcedata([epochevent{:}]); + else + for l=1:length(epochevent) + destdata{l} = sourcedata(epochevent{l}); + end + end + tmpepoch = EEG.epoch; + [tmpepoch.(['event' fname])] = destdata{:}; + EEG.epoch = tmpepoch; + end + end + catch, + errordlg2(['Warning: minor problem encountered when generating' 10 ... + 'the EEG.epoch structure (used only in user scripts)']); return; + end + case { 'loaddata' 'savedata' 'chanconsist' 'icaconsist' 'epochconsist' }, res = ''; + otherwise, error('eeg_checkset: unknown option'); + end + end + end + + res = []; + + % check name consistency + % ---------------------- + if ~isempty(EEG.setname) + if ~ischar(EEG.setname) + EEG.setname = ''; + else + if size(EEG.setname,1) > 1 + disp('eeg_checkset warning: invalid dataset name, removed'); + EEG.setname = ''; + end + end + else + EEG.setname = ''; + end + + % checking history and convert if necessary + % ----------------------------------------- + if isfield(EEG, 'history') && size(EEG.history,1) > 1 + allcoms = cellstr(EEG.history); + EEG.history = deblank(allcoms{1}); + for index = 2:length(allcoms) + EEG.history = [ EEG.history 10 deblank(allcoms{index}) ]; + end + end + + % read data if necessary + % ---------------------- + if ischar(EEG.data) && nargin > 1 + if strcmpi(varargin{1}, 'loaddata') + + EEG.data = eeg_getdatact(EEG); + + end + end + + % save data if necessary + % ---------------------- + if nargin > 1 + + % datfile available? + % ------------------ + datfile = 0; + if isfield(EEG, 'datfile') + if ~isempty(EEG.datfile) + datfile = 1; + end + end + + % save data + % --------- + if strcmpi(varargin{1}, 'savedata') && option_storedisk + error('eeg_checkset: cannot call savedata any more'); + + % the code below is deprecated + if ~ischar(EEG.data) % not already saved + disp('Writing previous dataset to disk...'); + + if datfile + tmpdata = reshape(EEG.data, EEG.nbchan, EEG.pnts*EEG.trials); + floatwrite( tmpdata', fullfile(EEG.filepath, EEG.datfile), 'ieee-le'); + EEG.data = EEG.datfile; + end + EEG.icaact = []; + + % saving dataset + % -------------- + filename = fullfile(EEG(1).filepath, EEG(1).filename); + if ~ischar(EEG.data) && option_single, EEG.data = single(EEG.data); end + v = version; + if str2num(v(1)) >= 7, save( filename, '-v6', '-mat', 'EEG'); % Matlab 7 + else save( filename, '-mat', 'EEG'); + end + if ~ischar(EEG.data), EEG.data = 'in set file'; end + + % res = sprintf('%s = eeg_checkset( %s, ''savedata'');', inputname(1), inputname(1)); + res = ['EEG = eeg_checkset( EEG, ''savedata'');']; + end + end + end + + % numerical format + % ---------------- + if isnumeric(EEG.data) + v = version; + EEG.icawinv = double(EEG.icawinv); % required for dipole fitting, otherwise it crashes + EEG.icaweights = double(EEG.icaweights); + EEG.icasphere = double(EEG.icasphere); + if ~isempty(findstr(v, 'R11')) || ~isempty(findstr(v, 'R12')) || ~isempty(findstr(v, 'R13')) + EEG.data = double(EEG.data); + EEG.icaact = double(EEG.icaact); + else + try, + if isa(EEG.data, 'double') && option_single + EEG.data = single(EEG.data); + EEG.icaact = single(EEG.icaact); + end + catch, + disp('WARNING: EEGLAB ran out of memory while converting dataset to single precision.'); + disp(' Save dataset (preferably saving data to a separate file; see File > Memory options).'); + disp(' Then reload it.'); + end + end + end + + % verify the type of the variables + % -------------------------------- + % data dimensions ------------------------- + if isnumeric(EEG.data) && ~isempty(EEG.data) + if ~isequal(size(EEG.data,1), EEG.nbchan) + disp( [ 'eeg_checkset warning: number of columns in data (' int2str(size(EEG.data,1)) ... + ') does not match the number of channels (' int2str(EEG.nbchan) '): corrected' ]); + res = com; + EEG.nbchan = size(EEG.data,1); + end + + if (ndims(EEG.data)) < 3 && (EEG.pnts > 1) + if mod(size(EEG.data,2), EEG.pnts) ~= 0 + fprintf(2, 'eeg_checkset error: binary data file likely truncated, importing anyway...\n'); + if EEG.trials > 1 + EEG.trials = floor(size(EEG.data,2)/EEG.pnts); + EEG.data(:,EEG.trials*EEG.pnts+1:end) = []; + res = com; + else + EEG.pnts = size(EEG.data,2); + res = com; + end + else + if EEG.trials > 1 + disp( 'eeg_checkset note: data array made 3-D'); + res = com; + end + if size(EEG.data,2) ~= EEG.pnts + EEG.data = reshape(EEG.data, EEG.nbchan, EEG.pnts, size(EEG.data,2)/EEG.pnts); + end + end + end + + % size of data ----------- + if size(EEG.data,3) ~= EEG.trials + disp( ['eeg_checkset warning: 3rd dimension size of data (' int2str(size(EEG.data,3)) ... + ') does not match the number of epochs (' int2str(EEG.trials) '), corrected' ]); + res = com; + EEG.trials = size(EEG.data,3); + end + if size(EEG.data,2) ~= EEG.pnts + disp( [ 'eeg_checkset warning: number of columns in data (' int2str(size(EEG.data,2)) ... + ') does not match the number of points (' int2str(EEG.pnts) '): corrected' ]); + res = com; + EEG.pnts = size(EEG.data,2); + end + end + + % parameters consistency + % ------------------------- + if round(EEG.srate*(EEG.xmax-EEG.xmin)+1) ~= EEG.pnts + fprintf( 'eeg_checkset note: upper time limit (xmax) adjusted so (xmax-xmin)*srate+1 = number of frames\n'); + if EEG.srate == 0 + EEG.srate = 1; + end + EEG.xmax = (EEG.pnts-1)/EEG.srate+EEG.xmin; + res = com; + end + + % deal with event arrays + % ---------------------- + if ~isfield(EEG, 'event'), EEG.event = []; res = com; end + if ~isempty(EEG.event) + if EEG.trials > 1 && ~isfield(EEG.event, 'epoch') + if popask( [ 'eeg_checkset error: the event info structure does not contain an ''epoch'' field.' ... + 'Should EEGLAB attempt to abort operation ?' 10 '(press Cancel to fix the problem from the commandline)']) + error('eeg_checkset error(): user abort'); + %res = com; + %EEG.event = []; + %EEG = eeg_checkset(EEG); + %return; + else + res = com; + return; + %error('eeg_checkset error: no epoch field in event structure'); + end + end + else + EEG.event = []; + end + if isempty(EEG.event) + EEG.eventdescription = {}; + end + if ~isfield(EEG, 'eventdescription') || ~iscell(EEG.eventdescription) + EEG.eventdescription = cell(1, length(fieldnames(EEG.event))); + res = com; + else + if ~isempty(EEG.event) + if length(EEG.eventdescription) > length( fieldnames(EEG.event)) + EEG.eventdescription = EEG.eventdescription(1:length( fieldnames(EEG.event))); + elseif length(EEG.eventdescription) < length( fieldnames(EEG.event)) + EEG.eventdescription(end+1:length( fieldnames(EEG.event))) = {''}; + end + end + end + % create urevent if continuous data + % --------------------------------- + %if ~isempty(EEG.event) && ~isfield(EEG, 'urevent') + % EEG.urevent = EEG.event; + % disp('eeg_checkset note: creating the original event table (EEG.urevent)'); + % for index = 1:length(EEG.event) + % EEG.event(index).urevent = index; + % end + %end + if isfield(EEG, 'urevent') && isfield(EEG.urevent, 'urevent') + EEG.urevent = rmfield(EEG.urevent, 'urevent'); + end + + % deal with epoch arrays + % ---------------------- + if ~isfield(EEG, 'epoch'), EEG.epoch = []; res = com; end + + % check if only one epoch + % ----------------------- + if EEG.trials == 1 + if isfield(EEG.event, 'epoch') + EEG.event = rmfield(EEG.event, 'epoch'); res = com; + end + if ~isempty(EEG.epoch) + EEG.epoch = []; res = com; + end + end + + if ~isfield(EEG, 'epochdescription'), EEG.epochdescription = {}; res = com; end + if ~isempty(EEG.epoch) + if isstruct(EEG.epoch), l = length( EEG.epoch); + else l = size( EEG.epoch, 2); + end + if l ~= EEG.trials + if popask( [ 'eeg_checkset error: the number of epoch indices in the epoch array/struct (' ... + int2str(l) ') is different from the number of epochs in the data (' int2str(EEG.trials) ').' 10 ... + 'Should EEGLAB attempt to abort operation ?' 10 '(press Cancel to fix the problem from the commandline)']) + error('eeg_checkset error: user abort'); + %res = com; + %EEG.epoch = []; + %EEG = eeg_checkset(EEG); + %return; + else + res = com; + return; + %error('eeg_checkset error: epoch structure size invalid'); + end + end + else + EEG.epoch = []; + end + + % check ica + % --------- + if ~isfield(EEG, 'icachansind') + if isempty(EEG.icaweights) + EEG.icachansind = []; res = com; + else + EEG.icachansind = [1:EEG.nbchan]; res = com; + end + elseif isempty(EEG.icachansind) + if isempty(EEG.icaweights) + EEG.icachansind = []; res = com; + else + EEG.icachansind = [1:EEG.nbchan]; res = com; + end + end + if ~isempty(EEG.icasphere) + if ~isempty(EEG.icaweights) + if size(EEG.icaweights,2) ~= size(EEG.icasphere,1) + if popask( [ 'eeg_checkset error: number of columns in weights array (' int2str(size(EEG.icaweights,2)) ')' 10 ... + 'does not match the number of rows in the sphere array (' int2str(size(EEG.icasphere,1)) ')' 10 ... + 'Should EEGLAB remove ICA information ?' 10 '(press Cancel to fix the problem from the commandline)']) + res = com; + EEG.icasphere = []; + EEG.icaweights = []; + EEG = eeg_checkset(EEG); + return; + else + error('eeg_checkset error: user abort'); + res = com; + return; + %error('eeg_checkset error: invalid weight and sphere array sizes'); + end + end + if isnumeric(EEG.data) + if length(EEG.icachansind) ~= size(EEG.icasphere,2) + if popask( [ 'eeg_checkset error: number of elements in ''icachansind'' (' int2str(length(EEG.icachansind)) ')' 10 ... + 'does not match the number of columns in the sphere array (' int2str(size(EEG.icasphere,2)) ')' 10 ... + 'Should EEGLAB remove ICA information ?' 10 '(press Cancel to fix the problem from the commandline)']) + res = com; + EEG.icasphere = []; + EEG.icaweights = []; + EEG = eeg_checkset(EEG); + return; + else + error('eeg_checkset error: user abort'); + res = com; + return; + %error('eeg_checkset error: invalid weight and sphere array sizes'); + end + end + if isempty(EEG.icaact) || (size(EEG.icaact,1) ~= size(EEG.icaweights,1)) || (size(EEG.icaact,2) ~= size(EEG.data,2)) + EEG.icaweights = double(EEG.icaweights); + EEG.icawinv = double(EEG.icawinv); + + % scale ICA components to RMS microvolt + if option_scaleicarms + if ~isempty(EEG.icawinv) + if mean(mean(abs(pinv(EEG.icaweights * EEG.icasphere)-EEG.icawinv))) < 0.0001 + disp('Scaling components to RMS microvolt'); + scaling = repmat(sqrt(mean(EEG(1).icawinv(:,:).^2))', [1 size(EEG.icaweights,2)]); + EEG.etc.icaweights_beforerms = EEG.icaweights; + EEG.etc.icasphere_beforerms = EEG.icasphere; + + EEG.icaweights = EEG.icaweights .* scaling; + EEG.icawinv = pinv(EEG.icaweights * EEG.icasphere); + end + end + end + + if ~isempty(EEG.data) && option_computeica + fprintf('eeg_checkset: recomputing the ICA activation matrix ...\n'); + res = com; + % Make compatible with Matlab 7 + if any(isnan(EEG.data(:))) + tmpdata = EEG.data(EEG.icachansind,:); + fprintf('eeg_checkset: recomputing ICA ignoring NaN indices ...\n'); + tmpindices = find(~sum(isnan(tmpdata))); % was: tmpindices = find(~isnan(EEG.data(1,:))); + EEG.icaact = zeros(size(EEG.icaweights,1), size(tmpdata,2)); EEG.icaact(:) = NaN; + EEG.icaact(:,tmpindices) = (EEG.icaweights*EEG.icasphere)*tmpdata(:,tmpindices); + else + EEG.icaact = (EEG.icaweights*EEG.icasphere)*EEG.data(EEG.icachansind,:); % automatically does single or double + end + EEG.icaact = reshape( EEG.icaact, size(EEG.icaact,1), EEG.pnts, EEG.trials); + end + end + end + if isempty(EEG.icawinv) + EEG.icawinv = pinv(EEG.icaweights*EEG.icasphere); % a priori same result as inv + res = com; + end + else + disp( [ 'eeg_checkset warning: weights matrix cannot be empty if sphere matrix is not, correcting ...' ]); + res = com; + EEG.icasphere = []; + end + if option_computeica + if ~isempty(EEG.icaact) && ndims(EEG.icaact) < 3 && (EEG.trials > 1) + disp( [ 'eeg_checkset note: independent component made 3-D' ]); + res = com; + EEG.icaact = reshape(EEG.icaact, size(EEG.icaact,1), EEG.pnts, EEG.trials); + end + else + if ~isempty(EEG.icaact) + fprintf('eeg_checkset: removing ICA activation matrix (as per edit options) ...\n'); + end + EEG.icaact = []; + end + else + if ~isempty( EEG.icaweights ), EEG.icaweights = []; res = com; end + if ~isempty( EEG.icawinv ), EEG.icawinv = []; res = com; end + if ~isempty( EEG.icaact ), EEG.icaact = []; res = com; end + end + if isempty(EEG.icaact) + EEG.icaact = []; + end + + % ------------- + % check chanlocs + % ------------- + if ~isfield(EEG, 'chaninfo') + EEG.chaninfo = []; + end + if ~isempty( EEG.chanlocs ) + + % reference (use EEG structure) + % --------- + if ~isfield(EEG, 'ref') + EEG.ref = ''; + end + if isfield(EEG.chanlocs, 'ref') && ~isempty(EEG.chanlocs(1).ref) + if ~isequal(EEG.chanlocs(1).ref, EEG.ref) + EEG.ref = EEG.chanlocs(1).ref; + res = com; + end + end + if strcmpi(EEG.ref, 'averef') + ref = 'average'; + else ref = ''; + end + if ~isfield( EEG.chanlocs, 'ref') + EEG.chanlocs(1).ref = ref; + end + charrefs = cellfun('isclass',{EEG.chanlocs.ref},'char'); + if any(charrefs) ref = ''; end + for tmpind = find(~charrefs) + EEG.chanlocs(tmpind).ref = ref; + end + if ~isstruct( EEG.chanlocs) + if exist( EEG.chanlocs ) ~= 2 + disp( [ 'eeg_checkset warning: channel file does not exist or is not in Matlab path: filename removed from EEG struct' ]); + EEG.chanlocs = []; + res = com; + else + res = com; + try, EEG.chanlocs = readlocs( EEG.chanlocs ); + disp( [ 'eeg_checkset: channel file read' ]); + catch, EEG.chanlocs = []; end + end + else + if ~isfield(EEG.chanlocs,'labels') + disp('eeg_checkset warning: no field label in channel location structure, removing it'); + EEG.chanlocs = []; + res = com; + end + end + if isstruct( EEG.chanlocs) + if length( EEG.chanlocs) ~= EEG.nbchan && length( EEG.chanlocs) ~= EEG.nbchan+1 && ~isempty(EEG.data) + disp( [ 'eeg_checkset warning: number of channels different in data and channel file/struct: channel file/struct removed' ]); + EEG.chanlocs = []; + res = com; + end + end + + % force Nosedir to +X (done here because of DIPFIT) + % ------------------- + if isfield(EEG.chaninfo, 'nosedir') + if ~strcmpi(EEG.chaninfo.nosedir, '+x') && all(isfield(EEG.chanlocs,{'X','Y','theta','sph_theta'})) + disp(['Note for expert users: Nose direction is now set from ''' upper(EEG.chaninfo.nosedir) ''' to default +X in EEG.chanlocs']); + [tmp chaninfo chans] = eeg_checkchanlocs(EEG.chanlocs, EEG.chaninfo); % Merge all channels for rotation (FID and data channels) + if strcmpi(chaninfo.nosedir, '+y') + rotate = 270; + elseif strcmpi(chaninfo.nosedir, '-x') + rotate = 180; + else + rotate = 90; + end + for index = 1:length(chans) + rotategrad = rotate/180*pi; + coord = (chans(index).Y + chans(index).X*sqrt(-1))*exp(sqrt(-1)*-rotategrad); + chans(index).Y = real(coord); + chans(index).X = imag(coord); + + if ~isempty(chans(index).theta) + chans(index).theta = chans(index).theta -rotate; + chans(index).sph_theta = chans(index).sph_theta+rotate; + if chans(index).theta <-180, chans(index).theta =chans(index).theta +360; end + if chans(index).sph_theta>180 , chans(index).sph_theta=chans(index).sph_theta-360; end + end + end + + if isfield(EEG, 'dipfit') + if isfield(EEG.dipfit, 'coord_transform') + if isempty(EEG.dipfit.coord_transform) + EEG.dipfit.coord_transform = [0 0 0 0 0 0 1 1 1]; + end + EEG.dipfit.coord_transform(6) = EEG.dipfit.coord_transform(6)+rotategrad; + end + end + + chaninfo.nosedir = '+X'; + [EEG.chanlocs EEG.chaninfo] = eeg_checkchanlocs(chans, chaninfo); % Update FID in chaninfo and remove them from chanlocs + end; + end + + % general checking of channels + % ---------------------------- + EEG = eeg_checkchanlocs(EEG); + if EEG.nbchan ~= length(EEG.chanlocs) + EEG.chanlocs = []; + EEG.chaninfo = []; + disp('Warning: the size of the channel location structure does not match with'); + disp(' number of channels. Channel information have been removed.'); + end + end + EEG.chaninfo.icachansind = EEG.icachansind; % just a copy for programming convenience + + %if ~isfield(EEG, 'urchanlocs') + % EEG.urchanlocs = EEG.chanlocs; + % for index = 1:length(EEG.chanlocs) + % EEG.chanlocs(index).urchan = index; + % end + % disp('eeg_checkset note: creating backup chanlocs structure (urchanlocs)'); + %end + + % Field 'datachan in 'urchanlocs' is removed, if exist + if isfield(EEG, 'urchanlocs') && ~isempty(EEG.urchanlocs) && isfield(EEG.urchanlocs, 'datachan') + EEG.urchanlocs = rmfield(EEG.urchanlocs, 'datachan'); + end + + % check reference + % --------------- + if ~isfield(EEG, 'ref') + EEG.ref = 'common'; + end + if ischar(EEG.ref) && strcmpi(EEG.ref, 'common') + if length(EEG.chanlocs) > EEG.nbchan + disp('Extra common reference electrode location detected'); + EEG.ref = EEG.nbchan+1; + end + end + + % DIPFIT structure + % ---------------- + if ~isfield(EEG,'dipfit') || isempty(EEG.dipfit) + EEG.dipfit = []; res = com; + else + try + % check if dipfitdefs is present + dipfitdefs; + if isfield(EEG.dipfit, 'vol') && ~isfield(EEG.dipfit, 'hdmfile') + if exist('pop_dipfit_settings') + disp('Old DIPFIT structure detected: converting to DIPFIT 2 format'); + EEG.dipfit.hdmfile = template_models(1).hdmfile; + EEG.dipfit.coordformat = template_models(1).coordformat; + EEG.dipfit.mrifile = template_models(1).mrifile; + EEG.dipfit.chanfile = template_models(1).chanfile; + EEG.dipfit.coord_transform = []; + EEG.saved = 'no'; + res = com; + end + end + if isfield(EEG.dipfit, 'hdmfile') + if length(EEG.dipfit.hdmfile) > 8 + if strcmpi(EEG.dipfit.hdmfile(end-8), template_models(1).hdmfile(end-8)), EEG.dipfit.hdmfile = template_models(1).hdmfile; end + if strcmpi(EEG.dipfit.hdmfile(end-8), template_models(2).hdmfile(end-8)), EEG.dipfit.hdmfile = template_models(2).hdmfile; end + end + if length(EEG.dipfit.mrifile) > 8 + if strcmpi(EEG.dipfit.mrifile(end-8), template_models(1).mrifile(end-8)), EEG.dipfit.mrifile = template_models(1).mrifile; end + if strcmpi(EEG.dipfit.mrifile(end-8), template_models(2).mrifile(end-8)), EEG.dipfit.mrifile = template_models(2).mrifile; end + end + if length(EEG.dipfit.chanfile) > 8 + if strcmpi(EEG.dipfit.chanfile(end-8), template_models(1).chanfile(end-8)), EEG.dipfit.chanfile = template_models(1).chanfile; end + if strcmpi(EEG.dipfit.chanfile(end-8), template_models(2).chanfile(end-8)), EEG.dipfit.chanfile = template_models(2).chanfile; end + end + end + + if isfield(EEG.dipfit, 'coord_transform') + if isempty(EEG.dipfit.coord_transform) + EEG.dipfit.coord_transform = [0 0 0 0 0 0 1 1 1]; + end + elseif ~isempty(EEG.dipfit) + EEG.dipfit.coord_transform = [0 0 0 0 0 0 1 1 1]; + end + catch + e = lasterror; + if ~strcmp(e.identifier,'MATLAB:UndefinedFunction') + % if we got some error aside from dipfitdefs not being present, rethrow it + rethrow(e); + end + end + end + + % check events (fast) + % ------------ + if isfield(EEG.event, 'type') + tmpevent = EEG.event(1:min(length(EEG.event), 100)); + if ~all(cellfun(@ischar, { tmpevent.type })) && ~all(cellfun(@isnumeric, { tmpevent.type })) + disp('Warning: converting all event types to strings'); + for ind = 1:length(EEG.event) + EEG.event(ind).type = num2str(EEG.event(ind).type); + end + EEG = eeg_checkset(EEG, 'eventconsistency'); + end + end + + % EEG.times (only for epoched datasets) + % --------- + if ~isfield(EEG, 'times') || isempty(EEG.times) || length(EEG.times) ~= EEG.pnts + EEG.times = linspace(EEG.xmin*1000, EEG.xmax*1000, EEG.pnts); + end + + if ~isfield(EEG, 'history') EEG.history = ''; res = com; end + if ~isfield(EEG, 'splinefile') EEG.splinefile = ''; res = com; end + if ~isfield(EEG, 'icasplinefile') EEG.icasplinefile = ''; res = com; end + if ~isfield(EEG, 'saved') EEG.saved = 'no'; res = com; end + if ~isfield(EEG, 'subject') EEG.subject = ''; res = com; end + if ~isfield(EEG, 'condition') EEG.condition = ''; res = com; end + if ~isfield(EEG, 'group') EEG.group = ''; res = com; end + if ~isfield(EEG, 'run') EEG.run = []; res = com; end + if ~isfield(EEG, 'session') EEG.session = []; res = com; end + if ~isfield(EEG, 'urchanlocs') EEG.urchanlocs = []; res = com; end + if ~isfield(EEG, 'specdata') EEG.specdata = []; res = com; end + if ~isfield(EEG, 'specicaact') EEG.specicaact = []; res = com; end + if ~isfield(EEG, 'comments') EEG.comments = ''; res = com; end + if ~isfield(EEG, 'etc' ) EEG.etc = []; res = com; end + if ~isfield(EEG, 'urevent' ) EEG.urevent = []; res = com; end + if ~isfield(EEG, 'ref') || isempty(EEG.ref) EEG.ref = 'common'; res = com; end + + % create fields if absent + % ----------------------- + if ~isfield(EEG, 'reject') EEG.reject.rejjp = []; res = com; end + + listf = { 'rejjp' 'rejkurt' 'rejmanual' 'rejthresh' 'rejconst', 'rejfreq' ... + 'icarejjp' 'icarejkurt' 'icarejmanual' 'icarejthresh' 'icarejconst', 'icarejfreq'}; + for index = 1:length(listf) + name = listf{index}; + elecfield = [name 'E']; + if ~isfield(EEG.reject, elecfield), EEG.reject.(elecfield) = []; res = com; end + if ~isfield(EEG.reject, name) + EEG.reject.(name) = []; + res = com; + elseif ~isempty(EEG.reject.(name)) && isempty(EEG.reject.(elecfield)) + % check if electrode array is empty with rejection array is not + nbchan = fastif(strcmp(name, 'ica'), size(EEG.icaweights,1), EEG.nbchan); + EEG.reject = setfield(EEG.reject, elecfield, zeros(nbchan, length(getfield(EEG.reject, name)))); res = com; + end + end + if ~isfield(EEG.reject, 'rejglobal') EEG.reject.rejglobal = []; res = com; end + if ~isfield(EEG.reject, 'rejglobalE') EEG.reject.rejglobalE = []; res = com; end + + % track version of EEGLAB + % ----------------------- + tmpvers = eeg_getversion; + if ~isfield(EEG.etc, 'eeglabvers') || ~isequal(EEG.etc.eeglabvers, tmpvers) + EEG.etc.eeglabvers = tmpvers; + EEG = eeg_hist( EEG, ['EEG.etc.eeglabvers = ''' tmpvers '''; % this tracks which version of EEGLAB is being used, you may ignore it'] ); + res = com; + end + + % default colors for rejection + % ---------------------------- + if ~isfield(EEG.reject, 'rejmanualcol') EEG.reject.rejmanualcol = [1.0000 1 0.783]; res = com; end + if ~isfield(EEG.reject, 'rejthreshcol') EEG.reject.rejthreshcol = [0.8487 1.0000 0.5008]; res = com; end + if ~isfield(EEG.reject, 'rejconstcol') EEG.reject.rejconstcol = [0.6940 1.0000 0.7008]; res = com; end + if ~isfield(EEG.reject, 'rejjpcol') EEG.reject.rejjpcol = [1.0000 0.6991 0.7537]; res = com; end + if ~isfield(EEG.reject, 'rejkurtcol') EEG.reject.rejkurtcol = [0.6880 0.7042 1.0000]; res = com; end + if ~isfield(EEG.reject, 'rejfreqcol') EEG.reject.rejfreqcol = [0.9596 0.7193 1.0000]; res = com; end + if ~isfield(EEG.reject, 'disprej') EEG.reject.disprej = { }; end + + if ~isfield(EEG, 'stats') EEG.stats.jp = []; res = com; end + if ~isfield(EEG.stats, 'jp') EEG.stats.jp = []; res = com; end + if ~isfield(EEG.stats, 'jpE') EEG.stats.jpE = []; res = com; end + if ~isfield(EEG.stats, 'icajp') EEG.stats.icajp = []; res = com; end + if ~isfield(EEG.stats, 'icajpE') EEG.stats.icajpE = []; res = com; end + if ~isfield(EEG.stats, 'kurt') EEG.stats.kurt = []; res = com; end + if ~isfield(EEG.stats, 'kurtE') EEG.stats.kurtE = []; res = com; end + if ~isfield(EEG.stats, 'icakurt') EEG.stats.icakurt = []; res = com; end + if ~isfield(EEG.stats, 'icakurtE') EEG.stats.icakurtE = []; res = com; end + + % component rejection + % ------------------- + if ~isfield(EEG.stats, 'compenta') EEG.stats.compenta = []; res = com; end + if ~isfield(EEG.stats, 'compentr') EEG.stats.compentr = []; res = com; end + if ~isfield(EEG.stats, 'compkurta') EEG.stats.compkurta = []; res = com; end + if ~isfield(EEG.stats, 'compkurtr') EEG.stats.compkurtr = []; res = com; end + if ~isfield(EEG.stats, 'compkurtdist') EEG.stats.compkurtdist = []; res = com; end + if ~isfield(EEG.reject, 'threshold') EEG.reject.threshold = [0.8 0.8 0.8]; res = com; end + if ~isfield(EEG.reject, 'threshentropy') EEG.reject.threshentropy = 600; res = com; end + if ~isfield(EEG.reject, 'threshkurtact') EEG.reject.threshkurtact = 600; res = com; end + if ~isfield(EEG.reject, 'threshkurtdist') EEG.reject.threshkurtdist = 600; res = com; end + if ~isfield(EEG.reject, 'gcompreject') EEG.reject.gcompreject = []; res = com; end + if length(EEG.reject.gcompreject) ~= size(EEG.icaweights,1) + EEG.reject.gcompreject = zeros(1, size(EEG.icaweights,1)); + end + + % remove old fields + % ----------------- + if isfield(EEG, 'averef'), EEG = rmfield(EEG, 'averef'); end + if isfield(EEG, 'rt' ), EEG = rmfield(EEG, 'rt'); end + + % store in new structure + % ---------------------- + if isstruct(EEG) + if ~exist('ALLEEGNEW','var') + ALLEEGNEW = EEG; + else + ALLEEGNEW(inddataset) = EEG; + end + end +end + +% recorder fields +% --------------- +fieldorder = { 'setname' ... + 'filename' ... + 'filepath' ... + 'subject' ... + 'group' ... + 'condition' ... + 'session' ... + 'comments' ... + 'nbchan' ... + 'trials' ... + 'pnts' ... + 'srate' ... + 'xmin' ... + 'xmax' ... + 'times' ... + 'data' ... + 'icaact' ... + 'icawinv' ... + 'icasphere' ... + 'icaweights' ... + 'icachansind' ... + 'chanlocs' ... + 'urchanlocs' ... + 'chaninfo' ... + 'ref' ... + 'event' ... + 'urevent' ... + 'eventdescription' ... + 'epoch' ... + 'epochdescription' ... + 'reject' ... + 'stats' ... + 'specdata' ... + 'specicaact' ... + 'splinefile' ... + 'icasplinefile' ... + 'dipfit' ... + 'history' ... + 'saved' ... + 'etc' }; + +for fcell = fieldnames(EEG)' + fname = fcell{1}; + if ~any(strcmp(fieldorder,fname)) + fieldorder{end+1} = fname; + end +end + +try + ALLEEGNEW = orderfields(ALLEEGNEW, fieldorder); + EEG = ALLEEGNEW; +catch + disp('Couldn''t order data set fields properly.'); +end + +if exist('ALLEEGNEW','var') + EEG = ALLEEGNEW; +end + +if ~isa(EEG, 'eegobj') && option_eegobject + EEG = eegobj(EEG); +end + +return; + +function num = popask( text ) +ButtonName=questdlg2( text, ... + 'Confirmation', 'Cancel', 'Yes','Yes'); +switch lower(ButtonName), + case 'cancel', num = 0; + case 'yes', num = 1; +end + +function res = mycellfun(com, vals, classtype); +res = zeros(1, length(vals)); +switch com + case 'isempty', + for index = 1:length(vals), res(index) = isempty(vals{index}); end + case 'isclass' + if strcmp(classtype, 'double') + for index = 1:length(vals), res(index) = isnumeric(vals{index}); end + else + error('unknown cellfun command'); + end + otherwise error('unknown cellfun command'); +end + + diff --git a/studio_functions/Functions/EEGLAB/CSD/eeg_emptyset.m b/studio_functions/Functions/EEGLAB/CSD/eeg_emptyset.m new file mode 100755 index 00000000..94e950eb --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eeg_emptyset.m @@ -0,0 +1,104 @@ +% eeg_emptyset() - Initialize an EEG dataset structure with default values. +% +% Usage: +% >> EEG = eeg_emptyset(); +% +% Outputs: +% EEG - empty dataset structure with default values. +% +% Author: Arnaud Delorme, CNL / Salk Institute, 2001 +% +% See also: eeglab() + +% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% 01-25-02 reformated help & license -ad + +function EEG = eeg_emptyset(); + +EEG.setname = ''; +EEG.filename = ''; +EEG.filepath = ''; +EEG.subject = ''; +EEG.group = ''; +EEG.condition = ''; +EEG.session = []; +EEG.comments = ''; +EEG.nbchan = 0; +EEG.trials = 0; +EEG.pnts = 0; +EEG.srate = 1; +EEG.xmin = 0; +EEG.xmax = 0; +EEG.times = []; +EEG.data = []; +EEG.icaact = []; +EEG.icawinv = []; +EEG.icasphere = []; +EEG.icaweights = []; +EEG.icachansind = []; +EEG.chanlocs = []; +EEG.urchanlocs = []; +EEG.chaninfo = []; +EEG.ref = []; +EEG.event = []; +EEG.urevent = []; +EEG.eventdescription = {}; +EEG.epoch = []; +EEG.epochdescription = {}; +EEG.reject = []; +EEG.stats = []; +EEG.specdata = []; +EEG.specicaact = []; +EEG.splinefile = ''; +EEG.icasplinefile = ''; +EEG.dipfit = []; +EEG.history = ''; +EEG.saved = 'no'; +EEG.etc = []; + +%EEG.reject.threshold = [1 0.8 0.85]; +%EEG.reject.icareject = []; +%EEG.reject.compreject = []; +%EEG.reject.gcompreject= []; +%EEG.reject.comptrial = []; +%EEG.reject.sigreject = []; +%EEG.reject.elecreject = []; + +%EEG.stats.kurta = []; +%EEG.stats.kurtr = []; +%EEG.stats.kurtd = []; +%EEG.stats.eegentropy = []; +%EEG.stats.eegkurt = []; +%EEG.stats.eegkurtg = []; +%EEG.stats.entropy = []; +%EEG.stats.kurtc = []; +%EEG.stats.kurtt = []; +%EEG.stats.entropyc = []; + +return; diff --git a/studio_functions/Functions/EEGLAB/CSD/eeg_eval.m b/studio_functions/Functions/EEGLAB/CSD/eeg_eval.m new file mode 100755 index 00000000..e6b9e137 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eeg_eval.m @@ -0,0 +1,164 @@ +% eeg_eval() - apply eeglab function to a collection of input datasets +% +% Usage: +% >> OUTEEG = eeg_eval(funcname, INEEG, 'key1', value1, 'key2', value2 ...); +% +% Inputs: +% funcname - [string] name of the function +% INEEG - EEGLAB input dataset(s) +% +% Optional inputs +% 'params' - [cell array] funcname parameters. +% 'warning' - ['on'|'off'] warning pop-up window if several dataset +% stored on disk that will be automatically overwritten. +% Default is 'on'. +% +% Outputs: +% OUTEEG - output dataset(s) +% +% Author: Arnaud Delorme, SCCN, INC, UCSD, 2005 +% +% see also: eeglab() + +% Copyright (C) 2005 Arnaud Delorme, Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [EEG, com] = eeg_eval( funcname, EEG, varargin) + + com = ''; + if nargin < 2 + help eeg_eval; + return; + end + + % check input parameters + % ---------------------- + g = finputcheck( varargin, { 'params' 'cell' {} {}; + 'warning' 'string' { 'on','off' } 'off' }, 'eeg_eval'); + if ischar(g), error(g); end + + % warning pop up + % -------------- + eeglab_options; + if strcmpi(g.warning, 'on') + if ~option_storedisk + res = questdlg2(strvcat( 'When processing multiple datasets, it is not', ... + 'possible to enter new names for the newly created', ... + 'datasets and old datasets are overwritten.', ... + 'You may still cancel this operation though.'), ... + 'Multiple dataset warning', 'Cancel', 'Proceed', 'Proceed'); + else + res = questdlg2( [ 'Data files on disk will be automatically overwritten.' 10 ... + 'Are you sure you want to proceed with this operation?' ], ... + 'Confirmation', 'Cancel', 'Proceed', 'Proceed'); + end + switch lower(res) + case 'cancel', return; + case 'proceed' + end + vPar = ver('parallel'); + if option_parallel && ~isempty(vPar) + res = questdlg2(strvcat( 'You have selected to use the parallel toolbox,', ... + 'to process multiple datasets. If you saturate the ', ... + 'memory, this could cause your computer to become.', ... + 'unresponsive or even crash.'), ... + 'Multiple dataset warning', 'Cancel', 'Proceed', 'Proceed'); + end + switch lower(res) + case 'cancel', return; + case 'proceed' + end + end + + % execute function + % ---------------- + v = version; + if str2num(v(1)) == '5' % Matlab 5 + command = [ 'TMPEEG = ' funcname '( TMPEEG, ' vararg2str(g.params) ');' ]; + elseif isstr(funcname) + eval( [ 'func = @' funcname ';' ] ); + else + func = funcname; + end + +% notCompatibleFunc = { +% @clean_artifacts +% }; + + NEWEEG = EEG; + if option_parallel + disp('Using the parallel toolbox to process multiple datasets (change in File > Preferences)'); + myPool = gcp; + tmpoptions_store = option_storedisk; + parfor i = 1:length(EEG) + fprintf('Processing group dataset %d of %d named: %s ****************\n', i, length(EEG), EEG(i).setname); + TMPEEG = eeg_retrieve(EEG, i); + TMPEEG = feval(func, TMPEEG, g.params{:}); + TMPEEG = eeg_checkset(TMPEEG); + TMPEEG.saved = 'no'; + if tmpoptions_store + TMPEEG = pop_saveset(TMPEEG, 'savemode', 'resave'); + TMPEEG = update_datafield(TMPEEG); + NEWEEG(i) = TMPEEG; + NEWEEG(i).saved = 'yes'; % eeg_store by default set it to no + else + NEWEEG(i) = TMPEEG; + end + end + else + for i = 1:length(EEG) + fprintf('Processing group dataset %d of %d named: %s ****************\n', i, length(EEG), EEG(i).setname); + TMPEEG = eeg_retrieve(EEG, i); + TMPEEG = feval(func, TMPEEG, g.params{:}); + TMPEEG = eeg_checkset(TMPEEG); + TMPEEG.saved = 'no'; + if option_storedisk + TMPEEG = pop_saveset(TMPEEG, 'savemode', 'resave'); + TMPEEG = update_datafield(TMPEEG); + end + NEWEEG = eeg_store(NEWEEG, TMPEEG, i); + if option_storedisk + NEWEEG(i).saved = 'yes'; % eeg_store by default set it to no + end + end + end + EEG = NEWEEG; + + % history + % ------- + if nargout > 1 + com = sprintf('%s = %s( %s,%s);', inputname(2), char(funcname), inputname(2), vararg2str(g.params)); + end + +function EEG = update_datafield(EEG) + if ~isfield(EEG, 'datfile'), EEG.datfile = ''; end + if ~isempty(EEG.datfile) + EEG.data = EEG.datfile; + else + EEG.data = 'in set file'; + end + EEG.icaact = []; diff --git a/studio_functions/Functions/EEGLAB/CSD/eeg_retrieve.m b/studio_functions/Functions/EEGLAB/CSD/eeg_retrieve.m new file mode 100755 index 00000000..b330055f --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eeg_retrieve.m @@ -0,0 +1,96 @@ +% eeg_retrieve() - Retrieve an EEG dataset from the variable +% containing all datasets (standard: ALLEEG). +% +% Usage: >> EEG = eeg_retrieve( ALLEEG, index ); +% +% Inputs: +% ALLEEG - variable containing all datasets +% index - index of the dataset to retrieve +% +% Outputs: +% EEG - output dataset. The workspace variable EEG is also updated +% ALLEEG - updated ALLEEG structure +% CURRENTSET - workspace variable index of the current dataset +% +% Note: The function performs >> EEG = ALLEEG(index); +% It also runs eeg_checkset() on it. +% +% Author: Arnaud Delorme, CNL / Salk Institute, 2001 +% +% See also: eeg_store(), eeglab() + +% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [EEG, ALLEEG, CURRENTSET] = eeg_retrieve( ALLEEG, CURRENTSET); + +if nargin < 2 + help eeg_retrieve; + return; +end; + +%try + eeglab_options; + + try, % check whether recent changes to this dataset have been saved or not + %-------------------------------------------------------------------- + tmpsaved = { ALLEEG.saved }; + tmpsaved = tmpsaved(CURRENTSET); + catch, tmpsaved = 'no'; + end + + if length(CURRENTSET) > 1 && option_storedisk + [ EEG tmpcom ] = eeg_checkset(ALLEEG(CURRENTSET)); % do not load data if several datasets + if length(CURRENTSET) ~= length(ALLEEG) + [ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET); + else + ALLEEG = EEG; + end + else + if CURRENTSET ~= 0 + [ EEG tmpcom ] = eeg_checkset(ALLEEG(CURRENTSET), 'loaddata'); + [ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET); + else + EEG = eeg_emptyset; % empty dataset + return; + end + end + + % retain saved field + % ------------------ + for index = 1:length(CURRENTSET) + ALLEEG(CURRENTSET(index)).saved = tmpsaved{index}; + EEG(index).saved = tmpsaved{index}; + end + +%catch +% fprintf('Warning: cannot retrieve dataset with index %d\n', CURRENTSET); +% return; +%end + +return; + diff --git a/studio_functions/Functions/EEGLAB/CSD/eeg_store.m b/studio_functions/Functions/EEGLAB/CSD/eeg_store.m new file mode 100755 index 00000000..13211ab9 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eeg_store.m @@ -0,0 +1,176 @@ +% eeg_store() - store specified EEG dataset(s) in the ALLEEG variable +% containing all current datasets, after first checking +% dataset consistency using eeg_checkset(). +% +% Usage: >> [ALLEEG EEG index] = eeg_store(ALLEEG, EEG); +% >> [ALLEEG EEG index] = eeg_store(ALLEEG, EEG, index); +% +% Inputs: +% ALLEEG - variable containing all current EEGLAB datasets +% EEG - dataset(s) to store - usually the current dataset. +% May also be an array of datasets; these will be +% checked and stored separately in ALLEEG. +% index - (optional), ALLEEG index (or indices) to use to store +% the new dataset(s). If no index is given, eeg_store() +% uses the lowest empty slot(s) in the ALLEEG array. +% Outputs: +% ALLEEG - array of all current datasets +% EEG - EEG dataset (after syntax checking) +% index - index of the new dataset +% +% Note: When 3 arguments are given, after checking the consistency of +% the input dataset structures this function simply performs +% >> ALLEEG(index) = EEG; +% +% Typical use: +% >> [ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG); +% creates a new dataset in variable ALLEEG. +% >> [ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET); +% overwrites the current dataset in variable ALLEEG. +% +% Author: Arnaud Delorme, CNL / Salk Institute, 2001 +% +% See also: eeglab(), eeg_checkset(), eeg_retrieve() + +% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% store set +% ------------------ +function [ALLEEG, EEG, storeSetIndex] = eeg_store(ALLEEG, EEG, storeSetIndex, varargin) + +% check parameter consistency +% ------------------------------ +if nargin >= 3 + if length(EEG) ~= length(storeSetIndex) && storeSetIndex(1) ~= 0 + error('Length of input dataset structure must equal the length of the index array'); + end +end + +% considering multiple datasets +% ----------------------------- +if length(EEG) > 1 + TMPEEG = EEG; + if nargin >= 3 && storeSetIndex(1) ~= 0 + for index=1:length(TMPEEG) + EEG = TMPEEG(index); + tmpsaved = EEG.saved; + if strcmpi(tmpsaved, 'justloaded'), tmpsaved = 'yes'; end + [ALLEEG, EEG] = eeg_store(ALLEEG, EEG, storeSetIndex(index), varargin{:}); + ALLEEG(storeSetIndex(index)).saved = tmpsaved; + TMPEEG(index).saved = tmpsaved; + end + else + for index=1:length(TMPEEG) + EEG = TMPEEG(index); + tmpsaved = EEG.saved; + if strcmpi(tmpsaved, 'justloaded'), tmpsaved = 'yes'; end + [ALLEEG, EEG, storeSetIndex(index)] = eeg_store(ALLEEG, EEG); + ALLEEG(storeSetIndex(index)).saved = tmpsaved; + TMPEEG(index).saved = tmpsaved; + end + end + EEG = TMPEEG; + return +end + +if nargin < 3 + % creating new dataset + % -> erasing file information + % --------------------------- + EEG.filename = ''; + EEG.filepath = ''; + EEG.datfile = ''; +end + +if isempty(varargin) % no text output and no check (study loading) + [ EEG, com ] = eeg_checkset(EEG); +else + com = ''; +end +if nargin > 2 + if storeSetIndex == 0 || strcmpi(EEG.saved, 'justloaded') + EEG.saved = 'yes'; % just loaded + else + EEG.saved = 'no'; + end +elseif strcmpi(EEG.saved, 'justloaded') + EEG.saved = 'yes'; +else + EEG.saved = 'no'; +end +EEG = eeg_hist(EEG, com); + +% find first free index +% --------------------- +findindex = 0; +if nargin < 3, findindex = 1; +elseif storeSetIndex == 0, findindex = 1; +end + +if findindex + i = 1; + while (i<10000) + try + if isempty(ALLEEG(i).data) + storeSetIndex = i; i = 10000; + end + i = i+1; + catch + storeSetIndex = i; i = 10000; + end + end + if isempty(varargin) % no text output and no check + fprintf('Creating a new ALLEEG dataset %d\n', storeSetIndex); + end +else + if isempty(storeSetIndex) || storeSetIndex == 0 + storeSetIndex = 1; + end +end + +if ~isempty( ALLEEG ) + try + ALLEEG(storeSetIndex) = EEG; + catch + allfields = fieldnames( EEG ); + for i=1:length( allfields ) + ALLEEG(storeSetIndex).(allfields{i}) = EEG.(allfields{i}); + end + if ~isfield(EEG, 'datfile') && isfield(ALLEEG, 'datfile') + ALLEEG(storeSetIndex).datfile = ''; + end + end +else + ALLEEG = EEG; + if storeSetIndex ~= 1 + ALLEEG(storeSetIndex+1) = EEG; + ALLEEG(1) = ALLEEG(storeSetIndex); % empty + ALLEEG(storeSetIndex) = ALLEEG(storeSetIndex+1); + ALLEEG = ALLEEG(1:storeSetIndex); + end +end diff --git a/studio_functions/Functions/EEGLAB/CSD/eegobj.m b/studio_functions/Functions/EEGLAB/CSD/eegobj.m new file mode 100755 index 00000000..3ebd8942 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/eegobj.m @@ -0,0 +1,14 @@ +function this = eegobj(EEG); + + if nargin == 1 + if isa(EEG, 'eegobj') + this = EEG; + return; + end + for index = 1:length(EEG) + TMP(index).EEG = EEG(index); + end + else + TMP.EEG = eeg_emptyset; + end + this = class(TMP, 'eegobj'); \ No newline at end of file diff --git a/studio_functions/Functions/EEGLAB/CSD/pop_writelocs.m b/studio_functions/Functions/EEGLAB/CSD/pop_writelocs.m new file mode 100755 index 00000000..1827fc7f --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/pop_writelocs.m @@ -0,0 +1,190 @@ +% pop_writelocs() - load a EGI EEG file (pop out window if no arguments). +% +% Usage: +% >> EEG = pop_writelocs(chanstruct); % a window pops up +% >> EEG = pop_writelocs(chanstruct, filename, 'key', val, ...); +% +% Inputs: +% chanstruct - channel structure. See readlocs() +% filename - Electrode location file name +% 'key',val - same as writelocs() +% +% Author: Arnaud Delorme, CNL / Salk Institute, 17 Dec 2002 +% +% See also: writelocs() + +% Copyright (C) Arnaud Delorme, Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function com = pop_writelocs(chans, filename, varargin); + +com = ''; +if nargin < 1 + help pop_writelocs; + return; +end + +if isfield(chans, 'shrink') + chans = rmfield(chans, 'shrink'); + disp('Warning: shrink factor ignored'); +end + +disp('WARNING: ELECTRODE COORDINATES MUST BE WITH NOSE ALONG THE +X DIMENSION TO BE EXPORTED') +disp(' IF NOT, THE EXPORTED FILE COORDINATES MAY BE INACURATE') + +% get infos from readlocs +% ----------------------- +[chanformat, listcolformat] = readlocs('getinfos'); +chanformat(end) = []; +indformat = []; +for index = 1:length(chanformat) + if ~ischar(chanformat(index).importformat) + indformat = [ indformat index ]; + end + if isempty(chanformat(index).skipline), chanformat(index).skipline = 0; end +end +listtype = { chanformat(indformat).type }; +formatinfo = { chanformat(indformat).importformat }; +formatskip = [ chanformat(indformat).skipline ]; + +%[listtype formatinfo listcolformat formatskip] = readlocs('getinfoswrite'); + +% GUI support of `custom` filetype, removed until `custom` can pass readlocs() check +%listtype{end+1} = 'custom'; +%formatinfo{end+1} = {}; +%formatskip = [ formatskip 0]; + + +if nargin < 2 + updatefields = [ 'tmpdata = get(gcf, ''userdata'');' ... + 'tmpobj = findobj(gcf, ''tag'', ''list2'');' ... + 'set(tmpobj, ''string'', strvcat(tmpdata{2}));' ... + 'clear tmpobj tmpdata;' ]; + addfieldcom = [ 'tmpdata = get(gcbf, ''userdata'');' ... + 'tmpobj = findobj(gcf, ''tag'', ''list1'');' ... + 'tmpdata{2}{end+1} = tmpdata{1}{get(tmpobj, ''value'')};' ... + 'set(gcbf, ''userdata'', tmpdata);' ... + updatefields ]; + rmfieldcom = [ 'tmpdata = get(gcbf, ''userdata'');' ... + 'tmpobj = findobj(gcbf, ''tag'', ''list2'');' ... + 'try, tmpdata{2}(get(tmpobj, ''value'')) = [];' ... + ' set(tmpobj, ''value'', 1);' ... + 'catch, end;' ... + 'set(gcbf, ''userdata'', tmpdata);' ... + updatefields ]; + filetypecom = [ 'tmpdata = get(gcf, ''userdata'');' ... + 'tmpobj = findobj(gcf, ''tag'', ''formatlist'');' ... + 'tmpval = get(tmpobj, ''value'');' ... + 'try, tmpdata{2} = tmpdata{3}{tmpval}; catch, end;' ... %try and catch for custom + 'set(gcf, ''userdata'', tmpdata);' ... + updatefields ... + 'tmpdata = get(gcf, ''userdata'');' ... + 'tmpobj1 = findobj(gcf, ''tag'', ''insertcol'');' ... % the lines below + 'tmpobj2 = findobj(gcf, ''tag'', ''inserttext'');' ... % update the checkbox + 'try, ' ... % and the edit text box + ' if tmpdata{4}(tmpval) == 2,' ... + ' set(tmpobj1, ''value'', 1);' ... + ' else,' ... + ' set(tmpobj1, ''value'', 0);' ... + ' end;' ... + ' if tmpval == 1,' ... % besa only + ' set(tmpobj2, ''string'', ''' int2str(length(chans)) ''');' ... + ' else,' ... + ' set(tmpobj2, ''string'', '''');' ... + ' end;' ... + 'catch, end;' ... % catch for custom case + 'tmpobj = findobj(gcf, ''userdata'', ''setfield'');' ... + 'if tmpval == ' int2str(length(listtype)) ',' ... % disable if non-custom type + ' set(tmpobj, ''enable'', ''off'');' ... + 'else,' ... + ' set(tmpobj, ''enable'', ''off'');' ... + 'end; clear tmpobj tmpobj2 tmpdata tmpval;' ]; + + geometry = { [1 1 1] [1 1] [1] [1 1 1] [1 1] [1 1 1] [1 0.3 0.7] [1] [1] }; + listui = { ... + { 'style' 'text' 'string' 'Filename' } ... + { 'style' 'edit' 'string' '' 'tag' 'filename' 'horizontalalignment' 'left' } ... + { 'style' 'pushbutton' 'string' 'Browse' 'callback' ... + [ '[tmpfile tmppath] = uiputfile(''*'', ''Exporting electrode location file -- pop_writelocs()'');' ... + 'set(findobj(gcbf, ''tag'', ''filename''), ''string'', char([tmppath tmpfile ]));' ... + 'clear tmpfile tmppath;' ] } ... + { 'style' 'text' 'string' strvcat('Select output file type', ' ', ' ') } ... + { 'style' 'listbox' 'tag' 'formatlist' 'string' strvcat(listtype) ... + 'value' length(listtype) 'callback' filetypecom } ... + { 'style' 'text' 'string' 'Select fields to export below' } ... + { } { 'style' 'pushbutton' 'string' '-> ADD' 'callback' addfieldcom 'userdata' 'setfield' } { } ... + { 'style' 'listbox' 'tag' 'list1' 'string' strvcat(fieldnames(chans)) 'userdata' 'setfield' } ... + { 'style' 'listbox' 'tag' 'list2' 'string' '' 'userdata' 'setfield2' } ... + { } { 'style' 'pushbutton' 'string' 'REMOVE <-' 'callback' rmfieldcom 'userdata' 'setfield' } { } ... + { 'style' 'text' 'string' 'Insert column names' } ... + { 'style' 'checkbox' 'tag' 'insertcol' 'value' 1 'userdata' 'setfield' } { } ... + { 'style' 'text' 'string' 'Enter custom header below' } ... + { 'style' 'edit' 'userdata' 'setfield' 'tag' 'inserttext' 'horizontalalignment' 'left' 'max' 2 } ... + }; + + inputgui(geometry, listui, 'pophelp(''writelocs'');', ... + 'Exporting electrode location file -- pop_writelocs()', { fieldnames(chans) {} formatinfo formatskip }, 'plot', [1 3 1 1 3 1 1 1 3 ]); + fig = gcf; + + % set default format + tmpobj = findobj(fig, 'tag', 'formatlist'); + set(tmpobj, 'value', 6); + eval(get(tmpobj, 'callback')); + + res = inputgui(geometry, listui, 'pophelp(''writelocs'');', ... + 'Exporting electrode location file -- pop_writelocs()', { listcolformat {} formatinfo formatskip }, fig, [1 3 1 1 3 1 1 1 3 ]); + if gcf ~= fig, return; end + exportfields = get(fig, 'userdata'); + exportfields = exportfields{2}; + close(fig); + + % decode the inputs + filename = res{1}; + if isempty(filename), + errordlg2('Error: Empty file name', 'Error'); + return; + end + options = { 'filetype' listtype{res{2}} 'format' exportfields ... + 'header' fastif(res{5}, 'on', 'off') 'customheader' res{6} }; +else + options = varargin; +end + +% generate history +% ---------------- +if isempty(inputname(1)) % not a variable name -> probably the structure from pop_chanedit + writelocs(chans, filename, options{:}); + com = sprintf('pop_writelocs( EEG.chanlocs, ''%s'', %s);', filename, vararg2str(options)); +else + if strcmpi(inputname(1), 'chantmp') + % do not write file (yet) + com = sprintf('pop_writelocs( chans, ''%s'', %s);', filename, vararg2str(options)); + else + writelocs(chans, filename, options{:}); + com = sprintf('pop_writelocs( %s, ''%s'', %s);', inputname(1), filename, vararg2str(options)); + end +end diff --git a/studio_functions/Functions/EEGLAB/CSD/questdlg2.m b/studio_functions/Functions/EEGLAB/CSD/questdlg2.m new file mode 100755 index 00000000..e542f763 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/CSD/questdlg2.m @@ -0,0 +1,102 @@ +% questdlg2() - questdlg function clone with coloring and help for +% eeglab(). +% +% Usage: same as questdlg() +% +% Warning: +% Case of button text and result might be changed by the function +% +% Author: Arnaud Delorme, CNL / Salk Institute, La Jolla, 11 August 2002 +% +% See also: inputdlg2(), errordlg2(), supergui(), inputgui() + +% Copyright (C) Arnaud Delorme, CNL / Salk Institute, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [result] = questdlg2(Prompt,Title,varargin); + +result = ''; +if nargin < 2 + help questdlg2; + return; +end +if isempty(varargin) + varargin = { 'Yes' 'No' 'Cancel' 'Yes' }; +end +result = varargin{end}; +if Prompt(end) == 10, Prompt(end) = []; end +if Prompt(end) == 10, Prompt(end) = []; end +if Prompt(end) == 10, Prompt(end) = []; end +if Prompt(end) == 10, Prompt(end) = []; end + +fig = figure('visible', 'off'); +set(gcf, 'name', Title); + +listui = {}; +geometry = {}; +if ~isempty(find(Prompt == 10)) + indlines = find(Prompt == 10); + if indlines(1) ~= 1, indlines = [ 0 indlines ]; end + if indlines(end) ~= length(Prompt), indlines = [ indlines length(Prompt)+1 ]; end + for index = 1:length(indlines)-1 + geometry{index} = [1]; + listui{index} = { 'Style', 'text', 'string' Prompt(indlines(index)+1:indlines(index+1)-1) }; + end +else + for index = 1:size(Prompt,1) + geometry{index} = [1]; + listui{index} = { 'Style', 'text', 'string' Prompt(index,:) }; + end +end +listui{end+1} = {}; + +geometry = { geometry{:} 1 ones(1,length(varargin)-1) }; +for index = 1:length(varargin)-1 % ignoring default val + listui = {listui{:} { 'width',80,'align','center','Style', 'pushbutton', 'string', varargin{index}, 'callback', ['set(gcbf, ''userdata'', ''' varargin{index} ''');'] } }; + if strcmp(varargin{index}, varargin{end}) + listui{end}{end+1} = 'fontweight'; + listui{end}{end+1} = 'bold'; + end +end + +%cr = length(find(Prompt == char(10)))+1; +%if cr == 1 +% cr = size(Prompt,1); +%end +%cr = cr^(7/); +%if cr >= 8, cr = cr-1; end +%if cr >= 4, cr = cr-1; end +%[tmp tmp2 allobj] = supergui( 'fig', fig, 'geomhoriz', geometry, 'geomvert', [cr 1 1], 'uilist', listui, ... +[tmp tmp2 allobj] = supergui( 'fig', fig, 'geomhoriz', geometry, 'uilist', listui, ... + 'borders', [0.05 0.015 0.08 0.06], 'spacing', [0 0], 'horizontalalignment', 'left', 'adjustbuttonwidth', 'off' ); + +waitfor( fig, 'userdata'); +try, + result = get(fig, 'userdata'); + close(fig); + drawnow; +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/adjustcylinder2.m b/studio_functions/Functions/EEGLAB/Scalp/adjustcylinder2.m new file mode 100755 index 00000000..5c165523 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/adjustcylinder2.m @@ -0,0 +1,60 @@ +% adjustcylinder() - Adjust 3d object coordinates to match a pair of points +% +% Usage: +% >> [x y z] = adjustcylinder( x, y, z, pos1, pos2); +% +% Inputs: +% x,y,z - 3-D point coordinates +% pos1 - position of first point [x y z] +% pos2 - position of second point [x y z] +% +% Outputs: +% x,y,z - updated 3-D point coordinates +% +% Author: Arnaud Delorme, CNL / Salk Institute, 30 Mai 2003 + +% Copyright (C) 2003 Arnaud Delorme +% +% This program is free software; you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation; either version 2 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +function [x, y, z] = adjustcylinder2( h, pos1, pos2); + + % figure; plot3(x(2,:),y(2,:),z(2,:)); [ x(2,:)' y(2,:)' z(2,:)'] + + % stretch z coordinates to match for vector length + % ------------------------------------------------ + dist = sqrt(sum((pos1-pos2).^2)); + z = get(h, 'zdata'); + zrange = max(z(:)) - min(z(:)); + set(h, 'zdata', get(h, 'zdata') /zrange*dist); + + % rotate in 3-D to match vector angle [0 0 1] -> vector angle) + % only have to rotate in the x-z and y-z plane + % -------------------------------------------- + vectrot = [ pos2(1)-pos1(1) pos2(2)-pos1(2) pos2(3)-pos1(3)]; + [thvect phivect] = cart2sph( vectrot(1), vectrot(2), vectrot(3) ); + + rotatematlab(h, [0 0 1], thvect/pi*180, [0 0 0]); + rotatematlab(h, [thvect+pi/2 0]/pi*180, (pi/2-phivect)/pi*180, [0 0 0]); + + x = get(h, 'xdata') + pos1(1); + y = get(h, 'ydata') + pos1(2); + z = get(h, 'zdata') + pos1(3); + + set(h, 'xdata', x); + set(h, 'ydata', y); + set(h, 'zdata', z); + return; + diff --git a/studio_functions/Functions/EEGLAB/Scalp/cbar.m b/studio_functions/Functions/EEGLAB/Scalp/cbar.m new file mode 100755 index 00000000..1838b4ed --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/cbar.m @@ -0,0 +1,244 @@ +% cbar() - Display full or partial color bar +% +% Usage: +% >> cbar % create a vertical cbar on the right side of a figure +% >> cbar(type) % specify direction as 'vert' or 'horiz' +% >> cbar(type,colors) % specify which colormap colors to plot +% else +% >> cbar(axhandle) % specify the axes to draw cbar in +% +% >> h = cbar(type|axhandle,colors, minmax, grad) +% +% Inputs: +% type - ['vert'|'horiz'] direction of the cbar {default: 'vert') +% ELSE axhandle = handle of axes to draw the cbar +% colors - vector of colormap indices to display, or integer to truncate upper +% limit by. +% (int n -> display colors [1:end-n]) {default: 0} +% minmax - [min, max] range of values to label on colorbar +% grad - [integer] number of tick labels. {default: 5}. +% +% Example: +% >> colormap('default') % default colormap is 64-color 'jet' +% >> cbar('vert',33:64); % plot a vertical cbar colored green->red +% % useful for showing >0 (warm) and 0 (green) +% % values only in a green=0 plot +% +% Author: Colin Humphries, Arnaud Delorme, CNL / Salk Institute, Feb. 1998- +% +% See also: colorbar() + +% Copyright (C) Colin Humphries, CNL / Salk Institute, Feb. 1998 +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% 12-13-98 added minmax arg -Scott Makeig +% 01-25-02 reformated help & license, added links -ad + +function [handle]=cbar(arg,colors,minmax, grad) + +if nargin < 2 + colors = 0; +end +posscale = 'off'; +if nargin < 1 + arg = 'vert'; + ax = []; +else + if isempty(arg) + arg = 0; + end + if arg(1) == 0 + ax = []; + arg = 'vert'; + elseif strcmpi(arg, 'pos') + ax = []; + arg = 'vert'; + posscale = 'on'; + else + if ischar(arg) + ax = []; + else + ax = arg; + arg = []; + end + end +end + +if nargin>2 + if size(minmax,1) ~= 1 || size(minmax,2) ~= 2 + help cbar + fprintf('cbar() : minmax arg must be [min,max]\n'); + return + end +end +if nargin < 4 + grad = 5; +end + +%obj = findobj('tag','cbar','parent',gcf); +%if ~isempty(obj) & ~isempty(arg) +% arg = []; +% ax = obj; +%end +try + icadefs; +catch + warning('cbar.m unable to find icadefs.m'); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Choose colorbar position +%%%%%%%%%%%%%%%%%%%%%%%%%%% + +if (length(colors) == 1) && (colors == 0) + t = caxis; +else + t = [0 1]; +end +if ~isempty(arg) + if strcmp(arg,'vert') + cax = gca; + pos = get(cax,'Position'); + stripe = 0.04; + edge = 0.01; + space = .02; + +% set(cax,'Position',[pos(1) pos(2) pos(3)*(1-stripe-edge-space) pos(4)]) +% rect = [pos(1)+(1-stripe-edge)*pos(3) pos(2) stripe*pos(3) pos(4)]; + + set(cax,'Position',[pos(1) pos(2) pos(3) pos(4)]) + rect = [pos(1)+pos(3)+space pos(2) stripe*pos(3) pos(4)]; + ax = axes('Position', rect); + elseif strcmp(arg,'horiz') + cax = gca; + pos = get(cax,'Position'); + stripe = 0.075; + space = .1; + set(cax,'Position',... + [pos(1) pos(2)+(stripe+space)*pos(4) pos(3) (1-stripe-space)*pos(4)]) + rect = [pos(1) pos(2) pos(3) stripe*pos(4)]; + ax = axes('Position', rect); + end +else + pos = get(ax,'Position'); + if pos(3) > pos(4) + arg = 'horiz'; + else + arg = 'vert'; + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Draw colorbar using image() +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if exist('DEFAULT_COLORMAP', 'var') + map = colormap(eval( [ DEFAULT_COLORMAP '(' int2str(max(size(colormap,1), max(colors))) ')' ])); +else + map = colormap; +end +n = size(map,1); + +if length(colors) == 1 + if strcmp(arg,'vert') + if strcmpi(posscale, 'on') + image([0 1],[0 t(2)],[ceil(n/2):n-colors]'); + else + image([0 1],t,[1:n-colors]'); + end + set(ax,'xticklabelmode','manual') + set(ax,'xticklabel',[],'YAxisLocation','right') + + else + image(t,[0 1],[1:n-colors]); + set(ax,'yticklabelmode','manual') + set(ax,'yticklabel',[],'YAxisLocation','right') + end + set(ax,'Ydir','normal','YAxisLocation','right') + +else % length > 1 + + if max(colors) > n + error('Color vector exceeds size of colormap') + end + if strcmp(arg,'vert') + image([0 1],t,[colors]'); + set(ax,'xticklabelmode','manual') + set(ax,'xticklabel',[]) + else + image([0 1],t,[colors]); + set(ax,'yticklabelmode','manual') + set(ax,'yticklabel',[],'YAxisLocation','right') + end + set(ax,'Ydir','normal','YAxisLocation','right') +end + +%%%%%%%%%%%%%%%%%%%%%%%%% +% Adjust cbar ticklabels +%%%%%%%%%%%%%%%%%%%%%%%%% + +if nargin > 2 + if strcmp(arg,'vert') + Cax = get(ax,'Ylim'); + else + Cax = get(ax,'Xlim'); + end + CBTicks = [Cax(1):(Cax(2)-Cax(1))/(grad-1):Cax(2)]; % caxis tick positions + CBLabels = [minmax(1):(minmax(2)-minmax(1))/(grad-1):minmax(2)]; % tick labels + + dec = floor(log10(max(abs(minmax)))); % decade of largest abs value + CBLabels = ([minmax]* [ linspace(1,0, grad);linspace(0, 1, grad)]); + %[1.0 .75 .50 .25 0.0; 0.0 .25 .50 .75 1.0]); + if dec<1 + CBLabels = round(CBLabels*10^(1-dec))*10^(dec-1); + elseif dec == 1 + CBLabels = round(CBLabels*10^(2-dec))*10^(dec-2); + else + CBLabels = round(CBLabels); + end +% minmax +% CBTicks +% CBLabels + + if strcmp(arg,'vert') + set(ax,'Ytick',CBTicks); + set(ax,'Yticklabel',CBLabels); + else + set(ax,'Xtick',CBTicks); + set(ax,'Xticklabel',CBLabels); + end +end +handle = ax; + +%%%%%%%%%%%%%%%%%% +% Adjust cbar tag +%%%%%%%%%%%%%%%%%% + +set(ax,'tag','cbar'); + +if exist('DEFAULT_COLORMAP', 'var') + colormap(DEFAULT_COLORMAP); +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/convertlocs.m b/studio_functions/Functions/EEGLAB/Scalp/convertlocs.m new file mode 100755 index 00000000..18e9f40d --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/convertlocs.m @@ -0,0 +1,240 @@ +% convertlocs() - Convert electrode locations between coordinate systems +% using the EEG.chanlocs structure. +% +% Usage: >> newchans = convertlocs( chanlocs, 'command'); +% +% Input: +% chanlocs - An EEGLAB EEG dataset OR a EEG.chanlocs channel locations structure +% 'command' - ['cart2topo'|'sph2topo'|'sphbesa2topo'| 'sph2cart'|'topo2cart'|'sphbesa2cart'| +% 'cart2sph'|'sphbesa2sph'|'topo2sph'| 'cart2sphbesa'|'sph2sphbesa'|'topo2sphbesa'| +% 'cart2all'|'sph2all'|'sphbesa2all'|'topo2all'] +% These command modes convert between four coordinate frames: 3-D Cartesian +% (cart), Matlab spherical (sph), Besa spherical (sphbesa), and 2-D polar (topo) +% 'auto' -- Here, the function finds the most complex coordinate frame +% and constrains all the others to this one. It searches first for Cartesian +% coordinates, then for spherical and finally for polar. Default is 'auto'. +% +% Optional input +% 'verbose' - ['on'|'off'] default is 'off'. +% +% Outputs: +% newchans - new EEGLAB channel locations structure +% +% Ex: CHANSTRUCT = convertlocs( CHANSTRUCT, 'cart2topo'); +% % Convert Cartesian coordinates to 2-D polar (topographic). +% +% Author: Arnaud Delorme, CNL / Salk Institute, 22 Dec 2002 +% +% See also: readlocs() + +% Copyright (C) Arnaud Delorme, CNL / Salk Institute, 22 Dec 2002, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function chans = convertlocs(chans, command, varargin) + +if nargin < 1 + help convertlocs; + return; +end + +if ~isfield(chans, 'theta') && ~isfield(chans, 'X') && ~isfield(chans, 'radius') && ~isfield(chans, 'sph_radius') + return +end + +if nargin < 2 + command = 'auto'; +end +if nargin == 4 && strcmpi(varargin{2}, 'on') + verbose = 1; +else + verbose = 0; % off +end + +% test if value exists for default +% -------------------------------- +if strcmp(command, 'auto') + if isfield(chans, 'X') && any(~cellfun(@isempty, { chans.X })) + command = 'cart2all'; + if verbose + disp('Make all coordinate frames uniform using Cartesian coords'); + end + else + if isfield(chans, 'sph_theta') && ~isempty(chans(1).sph_theta) + command = 'sph2all'; + if verbose + disp('Make all coordinate frames uniform using spherical coords'); + end + else + if isfield(chans, 'sph_theta_besa') && ~isempty(chans(1).sph_theta_besa) + command = 'sphbesa2all'; + if verbose + disp('Make all coordinate frames uniform using BESA spherical coords'); + end + else + command = 'topo2all'; + if verbose + disp('Make all coordinate frames uniform using polar coords'); + end + end + end + end +end + +% convert +% ------- +switch command + case 'topo2sph' + theta = {chans.theta}; + radius = {chans.radius}; + indices = find(~cellfun('isempty', theta)); + [sph_phi, sph_theta] = topo2sph( [ [ theta{indices} ]' [ radius{indices}]' ] ); + if verbose + disp('Warning: electrodes forced to lie on a sphere for polar to 3-D conversion'); + end + for index = 1:length(indices) + chans(indices(index)).sph_theta = sph_theta(index); + chans(indices(index)).sph_phi = sph_phi (index); + end + if isfield(chans, 'sph_radius') + meanrad = mean([ chans(indices).sph_radius ]); + if isempty(meanrad), meanrad = 1; end + else + meanrad = 1; + end + sph_radius(1:length(indices)) = {meanrad}; +case 'topo2sphbesa' + chans = convertlocs(chans, 'topo2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2sphbesa', varargin{:}); % search for spherical coords +case 'topo2cart' + chans = convertlocs(chans, 'topo2sph', varargin{:}); % search for spherical coords + if verbose + disp('Warning: spherical coordinates automatically updated'); + end + chans = convertlocs(chans, 'sph2cart', varargin{:}); % search for spherical coords +case 'topo2all' + chans = convertlocs(chans, 'topo2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2sphbesa', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2cart', varargin{:}); % search for spherical coords +case 'sph2cart' + sph_theta = {chans.sph_theta}; + sph_phi = {chans.sph_phi}; + indices = find(~cellfun('isempty', sph_theta)); + if ~isfield(chans, 'sph_radius'), sph_radius(1:length(indices)) = {1}; + else sph_radius = {chans.sph_radius}; + end + inde = find(cellfun('isempty', sph_radius)); + if ~isempty(inde) + meanrad = mean( [ sph_radius{:} ]); + sph_radius(inde) = { meanrad }; + end + [x, y, z] = sph2cart([ sph_theta{indices} ]'/180*pi, [ sph_phi{indices} ]'/180*pi, [ sph_radius{indices} ]'); + for index = 1:length(indices) + chans(indices(index)).X = x(index); + chans(indices(index)).Y = y(index); + chans(indices(index)).Z = z(index); + end +case 'sph2topo' + if verbose + % disp('Warning: all radii constrained to one for spherical to topo transformation'); + end + sph_theta = {chans.sph_theta}; + sph_phi = {chans.sph_phi}; + indices = find(~cellfun('isempty', sph_theta)); + [chan_num,angle,radius] = sph2topo([ ones(length(indices),1) [ sph_phi{indices} ]' [ sph_theta{indices} ]' ], 1, 2); % using method 2 + for index = 1:length(indices) + chans(indices(index)).theta = angle(index); + chans(indices(index)).radius = radius(index); + if ~isfield(chans, 'sph_radius') || isempty(chans(indices(index)).sph_radius) + chans(indices(index)).sph_radius = 1; + end + end +case 'sph2sphbesa' + % using polar coordinates + sph_theta = {chans.sph_theta}; + sph_phi = {chans.sph_phi}; + indices = find(~cellfun('isempty', sph_theta)); + [chan_num,angle,radius] = sph2topo([ones(length(indices),1) [ sph_phi{indices} ]' [ sph_theta{indices} ]' ], 1, 2); + [sph_theta_besa, sph_phi_besa] = topo2sph([angle radius], 1, 1); + for index = 1:length(indices) + chans(indices(index)).sph_theta_besa = sph_theta_besa(index); + chans(indices(index)).sph_phi_besa = sph_phi_besa(index); + end +case 'sph2all' + chans = convertlocs(chans, 'sph2topo', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2sphbesa', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2cart', varargin{:}); % search for spherical coords +case 'sphbesa2sph' + % using polar coordinates + sph_theta_besa = {chans.sph_theta_besa}; + sph_phi_besa = {chans.sph_phi_besa}; + indices = find(~cellfun('isempty', sph_theta_besa)); + [chan_num,angle,radius] = sph2topo([ones(length(indices),1) [ sph_theta_besa{indices} ]' [ sph_phi_besa{indices} ]' ], 1, 1); + %for index = 1:length(chans) + % chans(indices(index)).theta = angle(index); + % chans(indices(index)).radius = radius(index); + % chans(indices(index)).labels = int2str(index); + %end; + %figure; topoplot([],chans, 'style', 'blank', 'electrodes', 'labelpoint'); + + [sph_phi, sph_theta] = topo2sph([angle radius], 2); + for index = 1:length(indices) + chans(indices(index)).sph_theta = sph_theta(index); + chans(indices(index)).sph_phi = sph_phi (index); + end +case 'sphbesa2topo' + chans = convertlocs(chans, 'sphbesa2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2topo', varargin{:}); % search for spherical coords +case 'sphbesa2cart' + chans = convertlocs(chans, 'sphbesa2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2cart', varargin{:}); % search for spherical coords +case 'sphbesa2all' + chans = convertlocs(chans, 'sphbesa2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2all', varargin{:}); % search for spherical coords +case 'cart2topo' + chans = convertlocs(chans, 'cart2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2topo', varargin{:}); % search for spherical coords +case 'cart2sphbesa' + chans = convertlocs(chans, 'cart2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2sphbesa', varargin{:}); % search for spherical coords +case 'cart2sph' + if verbose + disp('WARNING: If XYZ center has not been optimized, optimize it using Edit > Channel Locations'); + end + X = {chans.X}; + Y = {chans.Y}; + Z = {chans.Z}; + indices = find(~cellfun('isempty', X)); + [th, phi, radius] = cart2sph( [ X{indices} ], [ Y{indices} ], [ Z{indices} ]); + for index = 1:length(indices) + chans(indices(index)).sph_theta = th(index)/pi*180; + chans(indices(index)).sph_phi = phi(index)/pi*180; + chans(indices(index)).sph_radius = radius(index); + end +case 'cart2all' + chans = convertlocs(chans, 'cart2sph', varargin{:}); % search for spherical coords + chans = convertlocs(chans, 'sph2all', varargin{:}); % search for spherical coords +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/error_bc.m b/studio_functions/Functions/EEGLAB/Scalp/error_bc.m new file mode 100755 index 00000000..10553856 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/error_bc.m @@ -0,0 +1,2 @@ +function res = error_bc +res = false; \ No newline at end of file diff --git a/studio_functions/Functions/EEGLAB/Scalp/finputcheck.m b/studio_functions/Functions/EEGLAB/Scalp/finputcheck.m new file mode 100755 index 00000000..9aaaa8c3 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/finputcheck.m @@ -0,0 +1,262 @@ +% finputcheck() - check Matlab function {'key','value'} input argument pairs +% +% Usage: >> result = finputcheck( varargin, fieldlist ); +% >> [result varargin] = finputcheck( varargin, fieldlist, ... +% callingfunc, mode, verbose ); +% Input: +% varargin - Cell array 'varargin' argument from a function call using 'key', +% 'value' argument pairs. See Matlab function 'varargin'. +% May also be a structure such as struct(varargin{:}) +% fieldlist - A 4-column cell array, one row per 'key'. The first +% column contains the key string, the second its type(s), +% the third the accepted value range, and the fourth the +% default value. Allowed types are 'boolean', 'integer', +% 'real', 'string', 'cell' or 'struct'. For example, +% {'key1' 'string' { 'string1' 'string2' } 'defaultval_key1'} +% {'key2' {'real' 'integer'} { minint maxint } 'defaultval_key2'} +% callingfunc - Calling function name for error messages. {default: none}. +% mode - ['ignore'|'error'] ignore keywords that are either not specified +% in the fieldlist cell array or generate an error. +% {default: 'error'}. +% verbose - ['verbose', 'quiet'] print information. Default: 'verbose'. +% +% Outputs: +% result - If no error, structure with 'key' as fields and 'value' as +% content. If error this output contain the string error. +% varargin - residual varagin containing unrecognized input arguments. +% Requires mode 'ignore' above. +% +% Note: In case of error, a string is returned containing the error message +% instead of a structure. +% +% Example (insert the following at the beginning of your function): +% result = finputcheck(varargin, ... +% { 'title' 'string' [] ''; ... +% 'percent' 'real' [0 1] 1 ; ... +% 'elecamp' 'integer' [1:10] [] }); +% if ischar(result) +% error(result); +% end +% +% Note: +% The 'title' argument should be a string. {no default value} +% The 'percent' argument should be a real number between 0 and 1. {default: 1} +% The 'elecamp' argument should be an integer between 1 and 10 (inclusive). +% +% Now 'g.title' will contain the title arg (if any, else the default ''), etc. +% +% Author: Arnaud Delorme, CNL / Salk Institute, 10 July 2002 + +% Copyright (C) Arnaud Delorme, CNL / Salk Institute, 10 July 2002, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [g, varargnew] = finputcheck( vararg, fieldlist, callfunc, mode, verbose ) + + if nargin < 2 + help finputcheck; + return; + end + if nargin < 3 + callfunc = ''; + else + callfunc = [callfunc ' ' ]; + end + if nargin < 4 + mode = 'do not ignore'; + end + if nargin < 5 + verbose = 'verbose'; + end + NAME = 1; + TYPE = 2; + VALS = 3; + DEF = 4; + SIZE = 5; + + varargnew = {}; + % create structure + % ---------------- + if ~isempty(vararg) + if isstruct(vararg) + g = vararg; + else + for index=1:length(vararg) + if iscell(vararg{index}) + vararg{index} = {vararg{index}}; + end + end + try + g = struct(vararg{:}); + catch + vararg = removedup(vararg, verbose); + try + g = struct(vararg{:}); + catch + g = [ callfunc 'error: bad ''key'', ''val'' sequence' ]; return; + end + end + end + else + g = []; + end + + for index = 1:size(fieldlist,NAME) + % check if present + % ---------------- + if ~isfield(g, fieldlist{index, NAME}) + g = setfield( g, fieldlist{index, NAME}, fieldlist{index, DEF}); + end + tmpval = getfield( g, {1}, fieldlist{index, NAME}); + + % check type + % ---------- + if ~iscell( fieldlist{index, TYPE} ) + res = fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}, ... + fieldlist{index, VALS}, tmpval, callfunc ); + if ischar(res), g = res; return; end + else + testres = 0; + tmplist = fieldlist; + for it = 1:length( fieldlist{index, TYPE} ) + if ~iscell(fieldlist{index, VALS}) + res{it} = fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}{it}, ... + fieldlist{index, VALS}, tmpval, callfunc ); + else res{it} = fieldtest( fieldlist{index, NAME}, fieldlist{index, TYPE}{it}, ... + fieldlist{index, VALS}{it}, tmpval, callfunc ); + end + if ~ischar(res{it}), testres = 1; end + end + if testres == 0, + g = res{1}; + for tmpi = 2:length(res) + g = [ g 10 'or ' res{tmpi} ]; + end + return; + end + end + end + + % check if fields are defined + % --------------------------- + allfields = fieldnames(g); + for index=1:length(allfields) + if isempty(strmatch(allfields{index}, fieldlist(:, 1)', 'exact')) + if ~strcmpi(mode, 'ignore') + g = [ callfunc 'error: undefined argument ''' allfields{index} '''']; return; + end + varargnew{end+1} = allfields{index}; + varargnew{end+1} = getfield(g, {1}, allfields{index}); + end + end + + +function g = fieldtest( fieldname, fieldtype, fieldval, tmpval, callfunc ); + NAME = 1; + TYPE = 2; + VALS = 3; + DEF = 4; + SIZE = 5; + g = []; + + switch fieldtype + case { 'integer' 'real' 'boolean' 'float' }, + if ~isnumeric(tmpval) && ~islogical(tmpval) + g = [ callfunc 'error: argument ''' fieldname ''' must be numeric' ]; return; + end + if strcmpi(fieldtype, 'boolean') + if tmpval ~=0 && tmpval ~= 1 + g = [ callfunc 'error: argument ''' fieldname ''' must be 0 or 1' ]; return; + end; + else + if strcmpi(fieldtype, 'integer') + if ~isempty(fieldval) + if (any(isnan(tmpval(:))) && ~any(isnan(fieldval))) ... + && (~ismember(tmpval, fieldval)) + g = [ callfunc 'error: wrong value for argument ''' fieldname '''' ]; return; + end + end + else % real or float + if ~isempty(fieldval) && ~isempty(tmpval) + if any(tmpval < fieldval(1)) || any(tmpval > fieldval(2)) + g = [ callfunc 'error: value out of range for argument ''' fieldname '''' ]; return; + end + end + end + end; + + + case 'string' + if ~ischar(tmpval) && ~isempty(tmpval) + g = [ callfunc 'error: argument ''' fieldname ''' must be a string' ]; return; + end + if ~isempty(fieldval) + if isempty(strmatch(char(lower(tmpval)), lower(fieldval), 'exact')) + g = [ callfunc 'error: wrong value for argument ''' fieldname '''' ]; return; + end + end + + + case 'cell' + if ~iscell(tmpval) + g = [ callfunc 'error: argument ''' fieldname ''' must be a cell array' ]; return; + end + + + case 'struct' + if ~isstruct(tmpval) + g = [ callfunc 'error: argument ''' fieldname ''' must be a structure' ]; return; + end + + case 'function_handle' + if ~isa(tmpval, 'function_handle') + g = [ callfunc 'error: argument ''' fieldname ''' must be a function handle' ]; return; + end + + case ''; + otherwise, error([ 'finputcheck error: unrecognized type ''' fieldname '''' ]); + end + +% remove duplicates in the list of parameters +% ------------------------------------------- +function cella = removedup(cella, verbose) +% make sure if all the values passed to unique() are strings, if not, exist +%try + [tmp indices] = unique_bc(cella(1:2:end)); + if length(tmp) ~= length(cella)/2 + myfprintf(verbose,'Note: duplicate ''key'', ''val'' parameter(s), keeping the last one(s)\n'); + end + cella = cella(sort(union(indices*2-1, indices*2))); +%catch + % some elements of cella were not string +% error('some ''key'' values are not string.'); +%end; + +function myfprintf(verbose, varargin) + +if strcmpi(verbose, 'verbose') + fprintf(varargin{:}); +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/headplot.m b/studio_functions/Functions/EEGLAB/Scalp/headplot.m new file mode 100755 index 00000000..979481eb --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/headplot.m @@ -0,0 +1,894 @@ +% headplot() - plot a spherically-splined EEG field map on a semi-realistic +% 3-D head model. Can 3-D rotate the head image using the left +% mouse button. +% Example: +% >> headplot example % show an example spherical 'eloc_angles' file +% >> headplot cartesian % show an example cartesian 'eloc_angles' file +% +% Setup usage (do only once for each scalp montage): +% +% >> headplot('setup', elocs, splinefile, 'Param','Value',...); +% % +% % NOTE: previous call format below is still supported +% % >> headplot('setup', elocs, splinefile, comment, type); +% +% Required Setup-mode Inputs: +% +% elocs - file of electrode locations (compatible with readlocs()), +% or EEG.chanlocs channel location structure. If the channel +% file extension is not standard, use readlocs() to load the +% data file, e.g. +% >> headplot('setup', ... +% readlocs('myfile.xxx', 'filetype', 'besa'),... +% 'splinefile'); +% splinefile - name of spline file to save spline info into. It is saved as a +% *.mat file and should be given the extension .spl . +% +% Optional Setup-mode Inputs: +% +% 'meshfile' - ['string' or structure] Matlab files containing a mesh. The +% mesh may be of different formats. It may be a Dipfit mesh as +% defined in the file standard_vol.mat. It may contain +% a structure with the fields 'vertices' and 'faces' or it +% it may contain a structure with at least two fields: +% POS - 3-D positions of vertices: +% x=left-right; y=back-front; z=up-down +% TRI1 - faces on which the scalp map should be computed +% plus possible optional fields are: +% center (optional) - 3-D center of head mesh +% TRI2 (optional) - faces in skin color +% NORM (optional) - normal for each vertex (better shading) +% 'orilocs' - ['off'|'on'] use original electrode locations on the head +% {default: 'off'} (extrapolated to spherical). Note that these +% electrode locations must be coregisted with the head mesh. +% 'transform' - [real array] Talairach-model transformation matrix to co-register +% the electrode locations with the head mesh: +% [shiftX shiftY shiftZ pitch roll yaw scaleX scaleY scaleZ] +% The transform is applied in the order shift(rotate(scale(elocs))) +% by the dipfit2.* plugin function traditionaldipfit.m +% This array is returned by coregister(). +% 'plotmeshonly' - [string] plot only mesh and electrode positions. Options are +% 'head' to plot the standard head mesh; 'sphere' to plot the +% texture of the head on a sphere; 'off' not to plot anything. +% {default: 'off'} +% 'comment' - ['string'] optional string containing comments for spline file +% {default: []} +% +% Standard-mode Usage thereafter: +% +% >> headplot(values,'spline_file','Param','Value',...) +% +% Required Standard-mode Inputs: +% +% values - vector containing a data value at each electrode position +% 'spline_file' - spline filename, computed and saved in 'setup' mode (above) +% +% Optional Standard-mode Inputs: +% +% 'meshfile' - [string] mesh file name. See file content in the setup-mode +% description above. {default: the EEGLAB head template file}. +% 'electrodes' - ['on'|'off'] -> show electrode positions {default 'on'} +% 'title' - Plot title {default: none} +% 'labels' - 2 -> plot stored electrode labels; +% 1 -> plot channel numbers; 0 -> no labels {default 0} +% 'cbar' - 0 -> Plot colorbar {default: no colorbar} +% Note: standard jet colormap) red = +;blue = -;green=0 +% h -> Colorbar axis handle (to specify headplot location) +% 'view' - Camera viewpoint in deg. [azimuth elevation] +% 'back'|'b'=[ 0 30]; 'front'|'f'=[180 30] +% 'left'|'l'=[-90 30]; 'right'|'r'=[ 90 30]; +% 'frontleft'|'bl','backright'|'br', etc., +% 'top'=[0 90], Can rotate with mouse {default [143 18]} +% 'maplimits' - 'absmax' -> make limits +/- the absolute-max +% 'maxmin' -> scale to data range +% [min,max] -> user-definined values +% {default = 'absmax'} +% 'lights' - (3,N) matrix whose rows give [x y z] pos. of each of +% N lights {default: four lights at corners} +% 'electrode3d' - ['on'|'off'] plot electrodes in 3-D. Default is 'off'. +% 'lighting' - 'off' = show wire frame head {default 'on'} +% 'material' - [see material function] {default 'dull'} +% 'colormap' - 3-column colormap matrix {default: jet(64)} +% 'verbose' - 'off' -> no msgs, no rotate3d {default: 'on'} +% 'orilocs' - [channel structure or channel file name] Use original +% channel locations instead of the one extrapolated from +% spherical locations. Note that if you use 'orilocs' +% during setup, this is not necessary here since the +% original channel location have already been saved. +% This option might be useful to show more channels than +% the ones actually used for interpolating (e.g., fiducials). +% 'transform' - [real array] homogeneous transformation matrix to apply +% to the original locations ('orilocs') before plotting them. +% +% Note: if an error is generated, headplot() may close the current figure +% +% Authors: Arnaud Delorme, Colin Humphries, Scott Makeig, SCCN/INC/UCSD, +% La Jolla, 1998- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Copyright (C) Arnaud Delorme, Colin Humphries and Scott Makeig, +% CNL / Salk Institute, Feb. 1998 +% +% Spherical spline method: Perrin et al. (1989) Electroenceph clin Neurophys +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% 12-12-98 changed electrode label lines to MarkerColor -sm +% 12-12-98 added colorbar option -sm (still graphically marred by tan rect.) +% 12-13-98 implemented colorbar option using enhanced cbar -sm +% 12-13-98 implemented 'setup' comment option -sm +% 03-20-00 added cartesian electrode locations option -sm +% 07-14-00 fixed line in calgx() -sm from -ch +% 03-23-01 documented 'cartesian' locfile option -sm +% 01-25-02 reformated help & license, added links -ad +% 03-21-02 added readlocs and the use of eloc input structure -ad + +function [HeadAxes, ColorbarHandle] = headplot(values, arg1, varargin) + +if nargin < 1 + help headplot + return +end + +%%%%%%%%%%%%%%%%%%%%%%%%%% Set Defaults %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +icadefs % load definitions +set(gca,'Color',BACKCOLOR); +DEFAULT_MESH = ['mheadnew.mat']; % upper head model file (987K) +DEFAULT_TRANSFORM = [0 -5 0 -0.1000 0 -1.5700 1040 800 950]; % stretching in different dimensions +DEFAULT_TRANSFORM = [0 -10 0 -0.1000 0 -1.600 1100 1100 1100]; % keep spherical shape. +%DEFAULT_MESH = '/home/arno/matlab/juliehiresmesh.mat'; +%DEFAULT_MESH = ['/home/scott/matlab/old' '/newupper.mat']; % whole head model file (183K) + +DEFAULT_LIGHTS = [-125 125 80; ... + 125 125 80; ... + 125 -125 125; ... + -125 -125 125]; % default lights at four corners + +HeadCenter = [0 0 30]; +FaceColor = [.8 .55 .35]*1.1; % ~= ruddy Caucasian - pick your complexion! +MAX_ELECTRODES = 1024; +ElectDFac = 1.06; % plot electrode marker dots out from head surface +plotelecopt.NamesDFac = 1.05; % plot electrode names/numbers out from markers +plotelecopt.NamesColor = 'k'; % 'r'; +plotelecopt.NamesSize = 10; % FontSize for electrode names +plotelecopt.MarkerColor= [0 0 0]; +plotelecopt.electrodes3d = 'off'; + +sqaxis = 1; % if non-zero, make head proportions anatomical +title_font = 18; +if ischar(values) + values = lower(values); + if strcmp(values,'setup') + +% +%%%%%%%%%%%%%%%%%%% Perform splining file setup %%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + if nargin < 3 + help headplot; + return; + end + eloc_file = arg1; + spline_file = varargin{1}; + + g = finputcheck(varargin(2:end), { 'orilocs' 'string' { 'on','off' } 'off'; + 'plotmeshonly' 'string' { 'head','off','sphere' } 'off'; + 'meshfile' { 'string','struct' } [] DEFAULT_MESH; + 'chaninfo' 'struct' [] struct([]); + 'plotchans' 'integer' [] []; + 'ica' 'string' { 'on','off' } 'off'; + 'transform' 'real' [] DEFAULT_TRANSFORM; + 'comment' 'string' [] '' }, 'headplot', 'ignore'); + if ischar(g), + error(g); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%% + % Open electrode file + %%%%%%%%%%%%%%%%%%%%%%%%%%% + [eloc_file, labels, Th, Rd, indices] = readlocs(eloc_file); + indices = find(~cellfun('isempty', { eloc_file.X })); + + % channels to plot + % ---------------- + if isempty(g.plotchans), g.plotchans = [1:length(eloc_file)]; end + if ~isfield(g.chaninfo, 'nosedir'), g.chaninfo(1).nosedir = '+x'; end + indices = intersect_bc(g.plotchans, indices); + + % if ICA select subset of channels if necessary + % --------------------------------------------- + if ~isfield(g.chaninfo, 'icachansind'), g.chaninfo(1).icachansind = 1:length(eloc_file); end + if strcmpi(g.ica, 'on'), + rmchans2 = setdiff_bc( g.chaninfo.icachansind, indices ); % channels to remove (non-plotted) + newinds = 1:length(g.chaninfo.icachansind); + allrm = []; + % remove non-plotted channels from indices + for index = 1:length(rmchans2) + chanind = find(g.chaninfo.icachansind == rmchans2(index)); + allrm = [ allrm chanind ]; + end + + newinds(allrm) = []; + indices = newinds; + eloc_file = eloc_file(g.chaninfo.icachansind); + end + + fprintf('Headplot: using existing XYZ coordinates\n'); + ElectrodeNames = strvcat({ eloc_file.labels }); + ElectrodeNames = ElectrodeNames(indices,:); + + Xeori = [ eloc_file(indices).X ]'; + Yeori = [ eloc_file(indices).Y ]'; + Zeori = [ eloc_file(indices).Z ]'; + + [newPOS POS TRI1 TRI2 NORM index1 center] = getMeshData(g.meshfile); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % rotate channel coordinates if necessary + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if strcmpi(lower(g.chaninfo.nosedir), '+x') + rotate = 0; + else + if strcmpi(lower(g.chaninfo.nosedir), '+y') + rotate = 3*pi/2; + elseif strcmpi(lower(g.chaninfo.nosedir), '-x') + rotate = pi; + else rotate = pi/2; + end + allcoords = (Yeori + Xeori*sqrt(-1))*exp(sqrt(-1)*rotate); + Xeori = imag(allcoords); + Yeori = real(allcoords); + end + newcoords = [ Xeori Yeori Zeori ]; + + %newcoords = transformcoords( [ Xe Ye Ze ], [0 -pi/16 -1.57], 100, -[6 0 46]); + %newcoords = transformcoords( [ Xeori Yeori Zeori ], g.transform(4:6), g.transform(7:9), g.transform(1:3)); + % same performed below with homogeneous transformation matrix + + transmat = traditionaldipfit( g.transform ); % arno + newcoords = transmat*[ newcoords ones(size(newcoords,1),1)]'; + newcoords = newcoords(1:3,:)'; + + % original center was [6 0 16] but the center of the sphere is [0 0 30] + % which compensate (see variable Headcenter) + %newcoords = transformcoords( [ Xe Ye Ze ], -[0 0 -pi/6]); + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % normalize with respect to head center + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + newcoordsnorm = newcoords - ones(size(newcoords,1),1)*HeadCenter; + tmpnorm = sqrt(sum(newcoordsnorm.^2,2)); + Xe = newcoordsnorm(:,1)./tmpnorm; + Ye = newcoordsnorm(:,2)./tmpnorm; + Ze = newcoordsnorm(:,3)./tmpnorm; + %plotchans3d([ Xe Ye Ze], cellstr(ElectrodeNames)); return; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Calculate g(x) for electrodes + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if strcmpi(g.plotmeshonly, 'off') + fprintf('Setting up splining matrix.\n'); + enum = length(Xe); + onemat = ones(enum,1); + G = zeros(enum,enum); + for i = 1:enum + ei = onemat-sqrt((Xe(i)*onemat-Xe).^2 + (Ye(i)*onemat-Ye).^2 + ... + (Ze(i)*onemat-Ze).^2); % default was /2 and no sqrt + gx = zeros(1,enum); + for j = 1:enum + gx(j) = calcgx(ei(j)); + end + G(i,:) = gx; + end + end + fprintf('Calculating splining matrix...\n') + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Open mesh file - contains POS and index1 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Project head vertices onto unit sphere + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + spherePOS = newPOS-ones(size(newPOS,1),1)*HeadCenter; % recenter + nPOSnorm = sqrt(sum(spherePOS.^2,2)); + spherePOS(:,1) = spherePOS(:,1)./nPOSnorm; + spherePOS(:,2) = spherePOS(:,2)./nPOSnorm; + spherePOS(:,3) = spherePOS(:,3)./nPOSnorm; + x = spherePOS(:,1); + y = spherePOS(:,2); + z = spherePOS(:,3); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Calculate new electrode positions on head + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if strcmpi(g.orilocs, 'off') + fprintf('Computing electrode locations on head...\n'); + for i=1:length(Xe) + elect = [Xe(i) Ye(i) Ze(i)]; + dists = distance(elect,spherePOS'); + [S,I] = sort(dists); + npoints = I(1:3); % closest 3 points + diffe = newPOS(npoints,:)-spherePOS(npoints,:); + newElect(i,:) = elect+mean(diffe)*ElectDFac; + %if Ze(i) < 0 % Plot superior electrodes only. + % newElect(i,:) = [0 0 0]; % Mark lower electrodes as having + %end % an electrode position not to be plotted + end + else + fprintf('Using original electrode locations on head...\n'); + newElect = newcoords; + end + + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % plot mesh and electrodes only + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if ~strcmpi(g.plotmeshonly, 'off') + if strcmpi(g.plotmeshonly, 'sphere') + newElect(:,1) = Xe; + newElect(:,2) = Ye; + newElect(:,3) = Ze; + POS(index1,:) = spherePOS; HeadCenter = [ 0 0 0 ]; + end + plotmesh(TRI1, POS, NORM); + plotelecopt.labelflag = 0; + plotelec(newElect, ElectrodeNames, HeadCenter, plotelecopt); + rotate3d; + return; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Calculate g(x) for sphere mesh vertices + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + fprintf('Computing %d vertices. Should take a while (see wait bar)\n',... + length(x)) + fprintf(' but does not have to be done again for this montage...\n'); + icadefs; + + gx = fastcalcgx(x,y,z,Xe,Ye,Ze); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Save spline file + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + comment = g.comment; + headplot_version = 2; + transform = g.transform; + try, save(spline_file, '-V6', '-mat', 'Xe', 'Ye', 'Ze', 'G', 'gx', 'newElect', ... + 'ElectrodeNames', 'indices', 'comment', 'headplot_version', 'transform'); + catch, + try, save(spline_file, '-mat', 'Xe', 'Ye', 'Ze', 'G', 'gx', 'newElect', ... + 'ElectrodeNames', 'indices', 'comment', 'headplot_version', 'transform'); + catch, error('headplot: save spline file error, out of space or file permission problem'); + end + end + tmpinfo = dir(spline_file); + fprintf('Saving (%dk) file %s\n',round(tmpinfo.bytes/1000), spline_file); + return + + elseif strcmp(values,'example') || strcmp(values,'demo') +% +%%%%%%%%%%%%%%%%%% Show an example electrode angles file %%%%%%%%%%%%%%%%%%%%%%%% +% + fprintf(['\nExample of a headplot() electrode angles file (spherical coords.)\n',... + 'Fields: chan_num cor_deg horiz_deg channel_name\n\n',... + ' 1 -90 -72 Fp1.\n',... + ' 2 90 72 Fp2.\n',... + ' 3 -62 -57 F3..\n',... + ' 4 62 57 F4..\n',... + ' 5 -45 0 C3..\n',... + ' 6 45 0 C4..\n',... + ' 7 -118 2 A1..\n',... + ' 8 118 -2 A2..\n',... + ' 9 -62 57 P3..\n',... + ' 10 62 -57 P4..\n',... + ' 11 -90 72 O1..\n',... + ' 12 90 -72 O2..\n',... + ' 13 -90 -36 F7..\n',... + ' 14 90 36 F8..\n',... + ' 15 -90 0 T3..\n',... + ' 16 90 0 T4..\n',... + ' 17 -90 36 T5..\n',... + ' 18 90 -36 T6..\n',... + ' 19 45 90 Fz..\n',... + ' 20 0 0 Cz..\n',... + ' 21 45 -90 Pz..\n',... + '\nA 90 deg coronal rotation points to right ear, -90 to left.\n' ,... + 'A positive horizontal rotation is counterclockwise from above.\n',... + 'Use pol2sph() to convert from topoplot() format to spherical.\n',... + 'Channel names should have 4 chars (. = space).\n',... + 'See also >> headplot cartesian\n\n\n']); + return + elseif strcmp(values,'cartesian') +% +%%%%%%%%%%%%%%%%%% Show an example cartesian electrode file %%%%%%%%%%%%%%%%%%% +% + fprintf(['\nExample of a headplot() electrode location file (cartesian coords.)\n',... + 'Fields: chan_num x y z channel_name\n\n',... + ' 1 0.4528 0.8888 -0.0694 Fp1.\n',... + 'Channel names should have 4 chars (. = space).\n',... + 'See also >> headplot example\n\n\n']); + return + else + fprintf('headplot(): Unknown first argument (%s).\n',values) + help headplot + end +else +% +%%%%%%%%%%%%%%%%%%%%%%%%%% Make the plot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + if nargin < 2 + help headplot + return + end + spline_file = arg1; + + g = finputcheck( varargin, { ... + 'cbar' 'real' [0 Inf] []; % Colorbar value must be 0 or axis handle.' + 'lighting' 'string' { 'on','off' } 'on'; + 'verbose' 'string' { 'on','off' } 'on'; + 'maplimits' { 'string','real' } [] 'absmax'; + 'title' 'string' [] ''; + 'lights' 'real' [] DEFAULT_LIGHTS; + 'view' { 'string','real' } [] [143 18]; + 'colormap' 'real' [] jet(256); + 'transform' 'real' [] []; + 'meshfile' {'string','struct' } [] DEFAULT_MESH; + 'electrodes' 'string' { 'on','off' } 'on'; + 'electrodes3d' 'string' { 'on','off' } 'off'; + 'eleccolor' 'cell' { } {}; + 'material' 'string' [] 'dull'; + 'orilocs' { 'string','struct' } [] ''; + 'labels' 'integer' [0 1 2] 0 }, 'headplot'); + if ischar(g) error(g); end + plotelecopt.electrodes3d = g.electrodes3d; + if length(g.eleccolor) > 0 && length(g.eleccolor) ~= length(values) + error('The number of color must be the same as the number of channels to plot'); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Open head mesh and electrode spline files + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if ~exist(spline_file) + error(sprintf('headplot(): spline_file "%s" not found. Run headplot in "setup" mode\n',... + spline_file)); + end + load(spline_file, '-mat'); + if exist('indices') + try, + values = values(indices); + catch, error('problem of index or electrode number with splinefile'); end + end + enum = length(values); + if enum ~= length(Xe) + close; + error('headplot(): Number of values in spline file should equal number of electrodes') + end + + % change electrode if necessary + % ----------------------------- + if ~isempty(g.orilocs) + eloc_file = readlocs( g.orilocs ); + fprintf('Using original electrode locations on head...\n'); + indices = find(~cellfun('isempty', { eloc_file.X } )); + newElect(:,1) = [ eloc_file(indices).X ]'; % attention inversion before + newElect(:,2) = [ eloc_file(indices).Y ]'; + newElect(:,3) = [ eloc_file(indices).Z ]'; + + % optional transformation + % ----------------------- + if ~isempty(g.transform) + transmat = traditionaldipfit( g.transform ); % arno + newElect = transmat*[ newElect ones(size(newElect,1),1)]'; + newElect = newElect(1:3,:)'; + end + end + + % -------------- + % load mesh file + % -------------- + [newPOS, POS, TRI1, TRI2, NORM, index1, center] = getMeshData(g.meshfile); + + %%%%%%%%%%%%%%%%%%%%%%%%%% + % Perform interpolation + %%%%%%%%%%%%%%%%%%%%%%%%%% + + meanval = mean(values); values = values - meanval; % make mean zero + onemat = ones(enum,1); + lamd = 0.1; + C = pinv([(G + lamd);ones(1,enum)]) * [values(:);0]; % fixing division error + P = zeros(1,size(gx,1)); + for j = 1:size(gx,1) + P(j) = dot(C,gx(j,:)); + end + P = P + meanval; + + %%%%%%%%%%%%%%%%%%%%%%%%%% + % Plot surfaces + %%%%%%%%%%%%%%%%%%%%%%%%%% + cla % clear axis + HeadAxes = gca; + + W = zeros(1,size(POS,1)); + m = size(g.colormap,1); + if size(g.maplimits) == [1,2] + amin = g.maplimits(1); + amax = g.maplimits(2); + elseif strcmp(g.maplimits,'maxmin') || strcmp(g.maplimits,'minmax') + amin = min(min(abs(P)))*1.02; % 2% shrinkage keeps within color bounds + amax = max(max(abs(P)))*1.02; + elseif strcmp(g.maplimits,'absmax') + amin = min(min(abs(P)))*1.02; % 2% shrinkage keeps within color bounds + amax = max(max(abs(P)))*1.02; + amax = max(-amin, amax); + amin = -amax; + %amin = -max(max(abs(P)))*1.02; % 2% shrinkage keeps within color bounds + %amax = -amin; + end + + idx = min(m,round((m-1)*(P-amin)/(amax-amin))+1); % get colormap indices + %subplot(1,2,1); hist(P(:)); + %idx = round((m-1)*P/(amax-amin))+m/2; + %idx = max(1,min(m,idx)); % get colormap indices + %subplot(1,2,2); hist(idx(:)); + %return; + + W(index1) = idx; + colormap(g.colormap) + p1 = patch('Vertices',POS,'Faces',TRI1,'FaceVertexCdata',W(:),... + 'FaceColor','interp', 'cdatamapping', 'direct', 'tag', 'mesh'); %%%%%%%%% Plot scalp map %%%%%%%%% + if exist('NORM') == 1 && ~isempty(NORM) + set(p1, 'vertexnormals', NORM); + end + + if ~isempty(TRI2) + FCmap = [g.colormap; g.colormap(end,:); FaceColor; FaceColor; FaceColor]; + colormap(FCmap) + W = ones(1,size(POS,1))*(m+2); + p2 = patch('Vertices',POS,'Faces',TRI2,'FaceColor','interp',... + 'FaceVertexCdata',W(:)); %%%%%%%% Plot face and lower head %%%%%% + else + p2 = []; + end + + axis([-125 125 -125 125 -125 125]) + axis off % hide axis frame + + %%%%%%%%%%%%%%%%%%%%%%%%% + % Draw colorbar - Note: uses enhanced cbar() function by Colin Humphries + %%%%%%%%%%%%%%%%%%%%%%%%% + if ~isempty(g.cbar) + BACKCOLOR = get(gcf,'Color'); + if g.cbar == 0 + ColorbarHandle = cbar(0,3,[amin amax]); + pos = get(ColorbarHandle,'position'); % move left & shrink to match head size + set(ColorbarHandle,'position',[pos(1)-.05 pos(2)+0.13 pos(3)*0.7 pos(4)-0.26]); + else + ColorbarHandle = cbar(g.cbar,3,[amin amax]); + end + end + axes(HeadAxes); + + %%%%%%%%%%%%%%%%%%%%%%%%% + % Turn on lights + %%%%%%%%%%%%%%%%%%%%%%%%% + + if strcmp(g.lighting,'on') + set([p1 p2],'EdgeColor','none') + + for i = 1:size(g.lights,1) + hl(i) = light('Position',g.lights(i,:),'Color',[1 1 1],... + 'Style','infinite'); + end + if ~isempty(p2) + set(p2,'DiffuseStrength',.6,'SpecularStrength',0,... + 'AmbientStrength',.4,'SpecularExponent',5) + end + set(p1,'DiffuseStrength',.6,'SpecularStrength',0,... + 'AmbientStrength',.3,'SpecularExponent',5) + try + lighting phong % all this gives a matte reflectance + catch + lighting gouraud % Octave + end + material(g.material); + end + + %%%%%%%%%%%%%%%%%%%%%%%%% + % Set viewpoint + %%%%%%%%%%%%%%%%%%%%%%%%% + + if ischar(g.view) + switch lower(g.view) + case {'front','f'} + view(-180,30) + case {'back','b'} + view(0,30) + case {'left','l'} + view(-90,30) + case {'right','r'} + view(90,30) + case {'frontright','fr'} + view(135,30) + case {'backright','br'} + view(45,30) + case {'frontleft','fl'} + view(-135,30) + case {'backleft','bl'} + view(-45,30) + case 'top' + view(0,90) + case 'bottom' % undocumented option! + view(0,-90) + Lights = [-125 125 80; ... + 125 125 80; ... + 125 -125 125; ... + -125 -125 125; ... + 0 10 -80]; % add light from below! + otherwise + close; error(['headplot(): Invalid View value %s',g.view]) + end + else + if ~ischar(g.view) + [h,a] = size(g.view); + if h~= 1 || a~=2 + close; error('headplot(): View matrix size must be (1,2).') + end + end + view(g.view) % set camera viewpoint + end + + if strcmp(g.electrodes,'on') % plot the electrode locations + if exist('newElect') + plotelecopt.labelflag = g.labels; + plotelecopt.eleccolor = g.eleccolor; + plotelec(newElect, ElectrodeNames, HeadCenter, plotelecopt); + else + fprintf('Variable newElect not read from spline file.\n'); + end + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Turn on rotate3d, allowing rotation of the plot using the mouse + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if ismatlab + if strcmp(g.verbose,'on') + rotate3d on; % Allow 3-D rotation of the plot by dragging the + else % left mouse button while cursor is on the plot + rotate3d off + end + else + rotate3d + end + % Make axis square + if sqaxis + axis image % keep the head proportions human and as large as possible + end + % Add a plot title + if ~isempty(g.title); + % title(['\n' g.title],'fontsize',title_font); + title([g.title],'fontsize',title_font); % Note: \n not interpreted by matlab-5.2 + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% calcgx() - function used in 'setup' +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function [out] = calcgx(in) + +out = 0; +m = 4; % 4th degree Legendre polynomial +for n = 1:7 % compute 7 terms + L = legendre(n,in); + out = out + ((2*n+1)/(n^m*(n+1)^m))*L(1); +end +out = out/(4*pi); + + +%%%%%%%%%%%%%%%%%%% +function gx = fastcalcgx(x,y,z,Xe,Ye,Ze) + +onemat = ones(length(x),length(Xe)); +EI = onemat - sqrt((repmat(x,1,length(Xe)) - repmat(Xe',length(x),1)).^2 +... + (repmat(y,1,length(Xe)) - repmat(Ye',length(x),1)).^2 +... + (repmat(z,1,length(Xe)) - repmat(Ze',length(x),1)).^2); +% +gx = zeros(length(x),length(Xe)); +m = 4; +icadefs; +ismatlab=1;%%GH 2022 +if ismatlab + hwb = waitbar(0,'Computing spline file (only done once)...', 'color', BACKEEGLABCOLOR); + hwbend = 7; +end +for n = 1:7 + L = legendre(n,EI); + gx = gx + ((2*n+1)/(n^m*(n+1)^m))*squeeze(L(1,:,:)); + if ismatlab + waitbar(n/hwbend,hwb); + end +end +gx = gx/(4*pi); +if ismatlab + close(hwb); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% distance() - function used in 'setup' +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function [out] = distance(w,p) +% w is a matrix of row vectors +% p is a matrix of column vectors + +l1 = size(w,1); +l2 = size(p,2); +out = zeros(l1,l2); + +for i = 1:l1 + x = w(i,:)'*ones(1,l2); + out(i,:) = sum((x-p).^2).^.5; +end + +% %%%%%%%%%%%%%%% +% plot electrodes +% %%%%%%%%%%%%%%% +function plotelec(newElect, ElectrodeNames, HeadCenter, opt); + + newNames = newElect*opt.NamesDFac; % Calculate electrode label positions + for i = 1:size(newElect,1) + if newElect(i,:) ~= [0 0 0] % plot radial lines to electrode sites + if strcmpi(opt.electrodes3d, 'off') + line([newElect(i,1) HeadCenter(1)],[newElect(i,2) HeadCenter(2)],... + [newElect(i,3) HeadCenter(3)],'color',opt.MarkerColor,'linewidth',1); + end + if opt.labelflag == 1 % plot electrode numbers + t=text(newNames(i,1),newNames(i,2),newNames(i,3),int2str(i)); + set(t,'Color',opt.NamesColor,'FontSize',opt.NamesSize,'FontWeight','bold',... + 'HorizontalAlignment','center'); + + elseif opt.labelflag == 2 % plot electrode names + if exist('ElectrodeNames') + name = sprintf('%s',ElectrodeNames(i,:)); + t=text(newNames(i,1),newNames(i,2),newNames(i,3),name); + set(t,'Color',opt.NamesColor,'FontSize',opt.NamesSize,'FontWeight','bold',... + 'HorizontalAlignment','center'); + else + fprintf('Variable ElectrodeNames not read from spline file.\n'); + end + else % plot electrode markers + + if strcmpi(opt.electrodes3d, 'off') + if isempty(opt.eleccolor) + line(newElect(i,1),newElect(i,2),newElect(i,3),'marker',... + '.','markersize',20,'color',opt.MarkerColor,'linestyle','none'); + else + if isempty(opt.eleccolor{i}) + line(newElect(i,1),newElect(i,2),newElect(i,3),'marker',... + '.','markersize',12,'color',opt.MarkerColor,'linestyle','none'); + else + line(newElect(i,1),newElect(i,2),newElect(i,3),'marker',... + '.','markersize',35,'color',opt.MarkerColor,'linestyle','none'); + line(newElect(i,1),newElect(i,2),newElect(i,3),'marker',... + '.','markersize',28,'color',[1 1 1],'linestyle','none'); + line(newElect(i,1),newElect(i,2),newElect(i,3),'marker',... + '.','markersize',15,'color',opt.eleccolor{i},'linestyle','none'); + end + end + else + [xc yc zc] = cylinder( 2, 10); + [xs ys zs] = sphere(10); + xc = [ xc; -xs(7:11,:)*2 ]; + yc = [ yc; -ys(7:11,:)*2 ]; + zc = [ zc; zs(7:11,:)*0.2+1 ]; + + hold on; + cylinderSize = 3; + colorarray = repmat(reshape(opt.MarkerColor, 1,1,3), [size(zc,1) size(zc,2) 1]); + handles = surf(xc*cylinderSize, yc*cylinderSize, zc*cylinderSize, colorarray, 'edgecolor', 'none', ... + 'backfacelighting', 'lit', 'facecolor', 'interp', 'facelighting', ... + 'phong', 'ambientstrength', 0.3); + + cylnderHeight = 1; + if newElect(i,3) < 10, addZ = -30; else addZ = 0; end + if newElect(i,3) < -20, addZ = -60; else addZ = 0; end + xx = newElect(i,1) - ( newElect(i,1)-HeadCenter(1) ) * 0.01 * cylnderHeight; + xxo1 = newElect(i,1) + ( newElect(i,1)-HeadCenter(1) ) * 0.01 * cylnderHeight; + yy = newElect(i,2) - ( newElect(i,2)-HeadCenter(2) ) * 0.01 * cylnderHeight; + yyo1 = newElect(i,2) + ( newElect(i,2)-HeadCenter(2) ) * 0.01 * cylnderHeight; + zz = newElect(i,3) - ( newElect(i,3)-HeadCenter(3)-addZ ) * 0.01 * cylnderHeight; + zzo1 = newElect(i,3) + ( newElect(i,3)-HeadCenter(3)-addZ ) * 0.01 * cylnderHeight; + [xc yc zc] = adjustcylinder2( handles, [xx yy zz], [xxo1 yyo1 zzo1] ); + end + + end + end + end + +% get mesh information +% -------------------- +function [newPOS POS TRI1 TRI2 NORM index1 center] = getMeshData(meshfile); +%#function mheadnew.mat +meshpath = fileparts(which('mheadnew.mat')); +if isdeployed + addpath( meshpath ); +end + +if ~isstruct(meshfile) + if ~exist(meshfile, 'file') + if isdeployed + meshfile = fullfile( meshpath, meshfile); + if ~exist(meshfile, 'file') + error('headplot(): deployed mesh file "%s" not found\n', meshfile); + end + else + error('headplot(): mesh file "%s" not found\n', meshfile); + end + end + fprintf('Loaded mesh file %s\n',meshfile); + try + meshfile = load(meshfile,'-mat'); + catch, + meshfile = []; + meshfile.POS = load('mheadnewpos.txt', '-ascii'); + meshfile.TRI1 = load('mheadnewtri1.txt', '-ascii'); % upper head + %try, TRI2 = load('mheadnewtri2.txt', '-ascii'); catch, end; % lower head + %index1 = load('mheadnewindex1.txt', '-ascii'); + meshfile.center = load('mheadnewcenter.txt', '-ascii'); + end +end; + +if isfield(meshfile, 'vol') + if isfield(meshfile.vol, 'r') + [X Y Z] = sphere(50); + POS = { X*max(meshfile.vol.r) Y*max(meshfile.vol.r) Z*max(meshfile.vol.r) }; + TRI1 = []; + else + POS = meshfile.vol.bnd(1).pnt; + TRI1 = meshfile.vol.bnd(1).tri; + end +elseif isfield(meshfile, 'bnd') + POS = meshfile.bnd(1).pnt; + TRI1 = meshfile.bnd(1).tri; +elseif isfield(meshfile, 'TRI1') + POS = meshfile.POS; + TRI1 = meshfile.TRI1; + try TRI2 = meshfile.TRI2; end % NEW + try center = meshfile.center; end % NEW +elseif isfield(meshfile, 'vertices') + POS = meshfile.vertices; + TRI1 = meshfile.faces; +else + error('Unknown Matlab mesh file'); +end +if exist('index1') ~= 1, index1 = sort(unique(TRI1(:))); end +if exist('TRI2') ~= 1, TRI2 = []; end +if exist('NORM') ~= 1, NORM = []; end +if exist('TRI1') ~= 1, error('Variable ''TRI1'' not defined in mesh file'); end +if exist('POS') ~= 1, error('Variable ''POS'' not defined in mesh file'); end +if exist('center') ~= 1, center = [0 0 0]; disp('Using [0 0 0] for center of head mesh'); end +newPOS = POS(index1,:); + diff --git a/studio_functions/Functions/EEGLAB/Scalp/icadefs.m b/studio_functions/Functions/EEGLAB/Scalp/icadefs.m new file mode 100755 index 00000000..f546637a --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/icadefs.m @@ -0,0 +1,232 @@ +% icadefs() - function to read in a set of EEGLAB system-wide (i.e. lab-wide) +% or working directory-wide constants and preferences. Change the +% way these are defined in the master icadefs.m file (usually +% in dir eeglab/functions/sigprocfunc) or make a custom copy of +% the icadefs.m file in a project directory. Then, calling functions +% that call icadefs from an EEGLAB session in that working directory +% will read the local copy, which may set preferences different from +% the system-wide copy. +% +% Author: Arnaud Delorme, Scott Makeig, SCCN/INC/UCSD, La Jolla, 05-20-97 + +% Copyright (C) 05-20-97 Scott Makeig, SCCN/INC/UCSD, scott@sccn.ucsd.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% ---------------------------------------------------------------------- +% ------ EEGLAB DEFINITION - YOU MAY CHANGE THE TEXT BELOW ------------- +% ---------------------------------------------------------------------- + + + +EEGOPTION_PATH = ''; % if empty, the home folder of the current user is used + % Note that this may create problems under Windows + % when unicode characters are part of the user name + % In this case, enter the path name manually here. + +YDIR = 1; % positive potential up = 1; negative up = -1 + % for most ERP plots + +HZDIR = 'up'; % ascending freqs = 'up'; descending = 'down' + % (e.g., timef/newtimef frequency direction) + +% Checking MATLAB version +clear version +tmpvers = version; +indp = find(tmpvers == '.'); +if str2num(tmpvers(indp(1)+1)) >= 1, tmpvers = [ tmpvers(1:indp(1)) '0' tmpvers(indp(1)+1:end) ]; end +indp = find(tmpvers == '.'); +VERS = str2num(tmpvers(1:indp(2)-1)); + +% font size +tmpComputer = computer; +tmpScreenSize = get(0, 'ScreenSize'); + +% Graph Definitions +DEFAULT_COLORMAP = 'jet'; + +if VERS < 8.04 + PLOT_LINEWIDTH = 2; + PLOT_LINEWIDTH_S = 1; + + % AXES FONTSIZE + AXES_FONTSIZE = 10; % Axis labels and legend font size + AXES_FONTSIZE_S = AXES_FONTSIZE - 2; % Axis labels and legend font size Small + AXES_FONTSIZE_L = 16; % Axis labels and legend font size Large + + % GUI FONTSIZE + GUI_FONTSIZE = 10; % graphic interface font size + GUI_FONTSIZE_S = GUI_FONTSIZE - 2; % graphic interface font size Small + GUI_FONTSIZE_L = GUI_FONTSIZE + 2; % graphic interface font size Large + + % TEXT FONTSIZE + TEXT_FONTSIZE = 10; % Miscellaneous font sizes + TEXT_FONTSIZE_S = TEXT_FONTSIZE - 2; % Miscellaneous font sizes Small + TEXT_FONTSIZE_L = TEXT_FONTSIZE + 2; % Miscellaneous font sizes Large + +elseif VERS >= 8.04 + + if strcmpi(tmpComputer(1:3), 'MAC') + + PLOT_LINEWIDTH = 1; + PLOT_LINEWIDTH_S = 0.5; + + %scale up fontsizes on higher resolution mac screens + retinaDisplay = false; + if tmpScreenSize(3) >= 1920 % bump fontsize only for the highest retina res settings + retinaDisplay = true; %comment this out if you don't want fontsizes increased at high display resolutions + %disp('Mac OSX retina display detected. If this is not desired comment out line 83 of icadefs.m'); + end + + % AXES FONTSIZE + if retinaDisplay + AXES_FONTSIZE = 12; % Axis labels and legend font size + else + AXES_FONTSIZE = 9; % Axis labels and legend font size + end + AXES_FONTSIZE_S = AXES_FONTSIZE - 2; % Axis labels and legend font size Small + AXES_FONTSIZE_L = 12.5; % Axis labels and legend font size Large + + % GUI FONTSIZE + if retinaDisplay + GUI_FONTSIZE = 14; % graphic interface font size + else + GUI_FONTSIZE = 12; % graphic interface font size + end + GUI_FONTSIZE_S = GUI_FONTSIZE - 2; % graphic interface font size Small + GUI_FONTSIZE_L = GUI_FONTSIZE + 2; % graphic interface font size Large + + % TEXT FONTSIZE + if retinaDisplay + TEXT_FONTSIZE = 14; % Miscellaneous font sizes + else + TEXT_FONTSIZE = 12; % Miscellaneous font sizes + end + TEXT_FONTSIZE_S = TEXT_FONTSIZE - 2; % Miscellaneous font sizes Small + TEXT_FONTSIZE_L = TEXT_FONTSIZE + 4; % Miscellaneous font sizes Large + else + PLOT_LINEWIDTH = 1; + PLOT_LINEWIDTH_S = 0.5; + + % AXES FONTSIZE + AXES_FONTSIZE = 9; % Axis labels and legend font size + AXES_FONTSIZE_S = AXES_FONTSIZE - 2; % Axis labels and legend font size Small + AXES_FONTSIZE_L = 12.5; % Axis labels and legend font size Large + + % GUI FONTSIZE + GUI_FONTSIZE = 10; % graphic interface font size + GUI_FONTSIZE_S = GUI_FONTSIZE - 2; % graphic interface font size Small + GUI_FONTSIZE_L = GUI_FONTSIZE + 2; % graphic interface font size Large + + % TEXT FONTSIZE + TEXT_FONTSIZE = 10; % Miscellaneous font sizes + TEXT_FONTSIZE_S = TEXT_FONTSIZE - 2; % Miscellaneous font sizes Small + TEXT_FONTSIZE_L = TEXT_FONTSIZE + 4; % Miscellaneous font sizes Large + end +end + +clear retinaDisplay tmpScreenSize tmpComputer tmpvers indp; + +% the eeg_options.m file also contains additional options + +% ---------------------------------------------------------------------- +% ------------------------ END OF DEFINITIONS -------------------------- +% ---------------------------------------------------------------------- + +% INSERT location of ica executable (UNIX ONLY) for binica.m below +eeglab_p = fileparts(which('eeglab')); +if ~isdeployed + ICABINARY = fullfile(eeglab_p, 'functions', 'supportfiles', 'ica_linux'); + tmpComputer = computer; + if strcmpi(tmpComputer(1:3), 'MAC') + ICABINARY = fullfile(eeglab_p, 'functions', 'supportfiles', 'ica_osx'); + elseif strcmpi(tmpComputer(1:2), 'PC') + ICABINARY = fullfile(eeglab_p, 'functions', 'supportfiles', 'binica.exe'); + end + clear tmpComputer +else + ICABINARY = fullfile(eeglab_p, 'functions', 'supportfiles', 'ica_linux'); +end + +try + set(0,'defaultaxesfontsize',AXES_FONTSIZE); + set(0,'defaulttextfontsize',TEXT_FONTSIZE); + set(0,'DefaultUicontrolFontSize',GUI_FONTSIZE); +catch + % most likely Octave here +end + +TUTORIAL_URL = 'http://sccn.ucsd.edu/wiki/EEGLAB'; % online version +DEFAULT_SRATE = 256.0175; % default local sampling rate (rarely used) +DEFAULT_TIMLIM = [-1000 2000]; % default local epoch limits (ms) + +% Set EEGLAB figure and GUI colors +% -------------------------------- +lowscreendepth = 0; +if ~exist('OCTAVE_VERSION') + if get(0, 'screendepth') <=8 % if mono or 8-bit color + lowscreendepth = 1; + end +end +if lowscreendepth + %fprintf('icadefs(): Setting display parameters for mono or 8-bit color\n'); + BACKCOLOR = [1 1 1]; % Background figure color + BACKEEGLABCOLOR = [1 1 1]; % EEGLAB main window background + GUIBUTTONCOLOR = [1 1 1]; % Buttons colors in figures + GUIPOPBUTTONCOLOR = [1 1 1]; % Buttons colors in GUI windows + GUIBACKCOLOR = [1 1 1]; % GUI background color + GUITEXTCOLOR = [0 0 0]; % GUI foreground color for text + PLUGINMENUCOLOR = [.5 0 .5]; % plugin menu color + +else % if full color screen + BACKCOLOR = [.93 .96 1]; % EEGLAB Background figure color + BACKEEGLABCOLOR = [.66 .76 1]; % EEGLAB main window background + GUIBUTTONCOLOR = BACKEEGLABCOLOR;% Buttons colors in figures + GUIPOPBUTTONCOLOR = BACKCOLOR; % Buttons colors in GUI windows + GUIBACKCOLOR = BACKEEGLABCOLOR;% EEGLAB GUI background color <--------- + GUITEXTCOLOR = [0 0 0.4]; % GUI foreground color for text + PLUGINMENUCOLOR = [.5 0 .5]; % plugin menu color +end + + +% THE FOLLOWING PARAMETERS WILL BE DEPRECATED IN LATER VERSIONS +% ------------------------------------------------------------- + +SHRINKWARNING = 1; % Warn user about the shrink factor in topoplot() (1/0) + +MAXENVPLOTCHANS = 264; % maximum number of channels to plot in envproj.m +MAXPLOTDATACHANS = 264; % maximum number of channels to plot in dataplot.m +MAXPLOTDATAEPOCHS = 264; % maximum number of epochs to plot in dataplot.m +MAXEEGPLOTCHANS = 264; % maximum number of channels to plot in eegplot.m +MAXTOPOPLOTCHANS = 264; % maximum number of channels to plot in topoplot.m + +DEFAULT_ELOC = 'chan.locs'; % default electrode location file for topoplot.m +DEFAULT_EPOCH = 10; % default epoch width to plot in eegplot(s) (in sec) + +SC = ['binica.sc']; % Master .sc script file for binica.m + % MATLAB will use first such file found + % in its path of script directories. + % Copy to pwd to alter ICA defaults diff --git a/studio_functions/Functions/EEGLAB/Scalp/intersect_bc.m b/studio_functions/Functions/EEGLAB/Scalp/intersect_bc.m new file mode 100755 index 00000000..b9b4cdbf --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/intersect_bc.m @@ -0,0 +1,56 @@ +% intersect_bc - intersect backward compatible with Matlab versions prior to 2013a + +% Copyright (C) 2013 Arnaud Delorme +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [C,IA,IB] = intersect_bc(A,B,varargin) + +errorFlag = error_bc; + +v = version; +indp = find(v == '.'); +v = str2num(v(1:indp(2)-1)); +if v > 7.19, v = floor(v) + rem(v,1)/10; end + +if nargin > 2 + ind = strmatch('legacy', varargin); + if ~isempty(ind) + varargin(ind) = []; + end +end + +if v >= 7.14 + [C,IA,IB] = intersect(A,B,varargin{:},'legacy'); + if errorFlag + [C2,IA2,IB2] = intersect(A,B,varargin{:}); + if (~isequal(C, C2) || ~isequal(IA, IA2) || ~isequal(IB, IB2)) + warning('backward compatibility issue with call to intersect function'); + end + end +else + [C,IA,IB] = intersect(A,B,varargin{:}); +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/loadtxt.m b/studio_functions/Functions/EEGLAB/Scalp/loadtxt.m new file mode 100755 index 00000000..9d0f5f92 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/loadtxt.m @@ -0,0 +1,177 @@ +% loadtxt() - load ascii text file into numeric or cell arrays +% +% Usage: +% >> array = loadtxt( filename, 'key', 'val' ...); +% +% Inputs: +% filename - name of the input file +% +% Optional inputs +% 'skipline' - number of lines to skip {default:0}. If this number is +% negative the program will only skip non-empty lines +% (can be useful for files transmitted from one platform +% to an other, as CR may be inserted at every lines). +% 'convert' - 'on' standard text conversion, see note 1 +% 'off' no conversion, considers text only +% 'force' force conversion, NaN are returned +% for non-numeric inputs {default:'on'} +% 'delim' - ascii character for delimiters. {default:[9 32] +% i.e space and tab}. It is also possible to enter +% strings, Ex: [9 ' ' ',']. +% 'blankcell' - ['on'|'off'] extract blank cells {default:'on'} +% 'verbose' - ['on'|'off'] {default:'on'} +% 'convertmethod' - ['str2double'|'str2num'] default is 'str2double' +% 'nlines' - [integer] number of lines to read {default: all file} +% +% Outputs: +% array - cell array. If the option 'force' is given, the function +% returns a numeric array. +% +% Notes: 1) Since it uses cell arrays, the function can handle text input. +% The function reads each token and then try to convert it to a +% number. If the conversion is unsuccessful, the string itself +% is included in the array. +% 2) The function adds empty entries for rows that contains +% fewer columns than others. +% +% Author: Arnaud Delorme, CNL / Salk Institute, 29 March 2002 + +% Copyright (C) Arnaud Delorme, CNL / Salk Institute, 29 March 2002 +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function array = loadtxt( filename, varargin ); + +if nargin < 1 + help loadtxt; + return; +end; +if ~isempty(varargin) + try, g = struct(varargin{:}); + catch, disp('Wrong syntax in function arguments'); return; end +else + g = []; +end + +g = finputcheck( varargin, { 'convert' 'string' { 'on';'off';'force' } 'on'; + 'skipline' 'integer' [0 Inf] 0; + 'verbose' 'string' { 'on';'off' } 'on'; + 'uniformdelim' 'string' { 'on';'off' } 'off'; + 'blankcell' 'string' { 'on';'off' } 'on'; + 'convertmethod' 'string' { 'str2double';'str2num' } 'str2double'; + 'delim' { 'integer';'string' } [] [9 32]; + 'nlines' 'integer' [] Inf }); +if ischar(g), error(g); end +if strcmpi(g.blankcell, 'off'), g.uniformdelim = 'on'; end +g.convert = lower(g.convert); +g.verbose = lower(g.verbose); +g.delim = char(g.delim); + +% open the file +% ------------- +if exist(filename) ~=2, error( ['file ' filename ' not found'] ); end; +fid=fopen(filename,'r','ieee-le'); +if fid<0, error( ['file ' filename ' found but error while opening file'] ); end; + +index = 0; +while index < abs(g.skipline) + tmpline = fgetl(fid); + if g.skipline > 0 || ~isempty(tmpline) + index = index + 1; + end; +end; % skip lines --------- + +inputline = fgetl(fid); +linenb = 1; +if strcmp(g.verbose, 'on'), fprintf('Reading file (lines): '); end +while isempty(inputline) || inputline(1)~=-1 + colnb = 1; + if ~isempty(inputline) + tabFirstpos = 1; + + % convert all delimiter to the first one + if strcmpi(g.uniformdelim, 'on') + for index = 2:length(g.delim) + inputline(find(inputline == g.delim(index))) = g.delim(1); + end + end + + while ~isempty(deblank(inputline)) + if strcmpi(g.blankcell,'off'), inputline = strtrim(inputline); end + if tabFirstpos && length(inputline) > 1 && all(inputline(1) ~= g.delim), tabFirstpos = 0; end + [tmp inputline tabFirstpos] = mystrtok(inputline, g.delim, tabFirstpos); + switch g.convert + case 'off', array{linenb, colnb} = tmp; + case 'on', + if strcmpi(g.convertmethod, 'str2double') + tmp2 = str2double(tmp); + if isnan( tmp2 ) , array{linenb, colnb} = tmp; + else array{linenb, colnb} = tmp2; + end + else + tmp2 = str2num(tmp); + if isempty( tmp2 ) , array{linenb, colnb} = tmp; + else array{linenb, colnb} = tmp2; + end + end + case 'force', array{linenb, colnb} = str2double(tmp); + end + colnb = colnb+1; + end + linenb = linenb +1; + end + inputline = fgetl(fid); + if linenb > g.nlines + inputline = -1; + end + if ~mod(linenb,10) && strcmp(g.verbose, 'on'), fprintf('%d ', linenb); end +end; +if strcmp(g.verbose, 'on'), fprintf('%d\n', linenb-1); end +if strcmp(g.convert, 'force'), array = [ array{:} ]; end +fclose(fid); + +% problem strtok do not consider tabulation +% ----------------------------------------- +function [str, strout, tabFirstpos] = mystrtok(strin, delim, tabFirstpos); + % remove extra spaces at the beginning + while any(strin(1) == delim) && strin(1) ~= 9 && strin(1) ~= ',' + strin = strin(2:end); + end + % for tab and coma, consider empty cells + if length(strin) > 1 && any(strin(1) == delim) + if tabFirstpos || any(strin(2) == delim) + str = ''; + strout = strin(2:end); + if strin(2) ~= 9 && strin(2) ~= ',' + tabFirstpos = 0; + strout = strtrim(strout); + end + else + [str, strout] = strtok(strin, delim); + end + else + [str, strout] = strtok(strin, delim); + end diff --git a/studio_functions/Functions/EEGLAB/Scalp/pop_chanedit.m b/studio_functions/Functions/EEGLAB/Scalp/pop_chanedit.m new file mode 100755 index 00000000..10be1470 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/pop_chanedit.m @@ -0,0 +1,1040 @@ +% pop_chanedit() - Edit the channel locations structure of an EEGLAB dataset, +% EEG.chanlocs. For structure location and file formats, +% see >> help readlocs +% +% EEG.chanlocs. For structure location and file formats, +% see >> help readlocs +% +% Usage: >> EEG = pop_chanedit( EEG, 'key1', value1, 'key2', value2, ... ); +% >> [ chanlocs options ] = pop_chanedit( chanlocs, 'key1', value1); +% >> [ chanlocs chaninfo options ] = pop_chanedit( chanlocs, chaninfo, ... +% 'key1', value1, 'key2', value2, ... ); +% +% Graphic interface: +% "Channel information ('field name')" - [edit boxes] display channel field +% contents for the current channel. Command line equivalent +% to modify these fields: 'transform' +% "Opt. 3D center" - [button] optimally re-center 3-D channel coordinates. Uses +% chancenter(). Command line equivalent: 'convert', { 'chancenter' +% [xc yc zc] }, [xc yc zc] being the center of the sphere. Use [] +% to find the center of the best fitting sphere. +% "Rotate axis" - [button] force one electrode to one position and rotate the other +% electrodes accordingly. Command line equivalent: 'forcelocs'. +% "Transform axis" - [button] perform any operation on channel fields. Command +% line equivalent: 'transform'. +% "Xyz->polar & sph." - [button] convert 3-D cartesian coordinates to polar and +% 3-D spherical coordinates. This is useful when you edit the +% coordinates manually. Command line equivalent: 'convert', 'cart2all'. +% "Sph.->polar & xyz" - [button] convert 3-D spherical coordinates to polar and +% 3-D cartesian coordinates. Command line equivalent: 'convert', 'sph2all'. +% "Polar->sph & xyz" - [button] convert 2-D polar coordinates to 3-D spherical and +% 3-D cartesian coordinates. Command line equivalent: 'convert', 'topo2all'. +% Note that if spherical radii are absent, they are forced to 1. +% "Set head radius" - [button] change head size radius. This is useful +% to make channels location compatible with a specified spherical model. +% Command line equivalent: 'headrad'. +% "Set channel types" - [button] set channel type names for a range of data channels. +% "Delete chan" - [button] delete channel. Command line equivalent: 'delete'. +% "Insert chan" - [button] insert channel before current channel. +% Command line equivalent: 'insert'. +% "<<" - [button] scroll channel backward by 10. +% "<" - [button] scroll channel backward by 1. +% ">" - [button] scroll channel forward by 1. +% ">>" - [button] scroll channel forward by 10. +% "Append chan" - [button] append channel after the current channel. +% Command line equivalent: 'append'. +% "Plot 2D" - [button] plot channel locations in 2-D using topoplot() +% "Plot radius [value (0.2-1.0), []=auto)" - [edit box] default plotting radius +% in 2-D polar views. This does NOT affect channel locations; it +% is only used for visualization. This parameter is attached to the +% chanlocs structure and is then used in all 2-D scalp topoplots. +% Default -> to data limits. Command line equivalent: 'plotrad'. +% "Nose along +X" - [list] Indicate the direction of the nose. This information +% is used in functions like topoplot(), headplot() and dipplot(). +% Command line equivalent: 'nosedir'. +% "Plot 3D" - [button] plot channel positions in 3-D using plotchans3d() +% "Read locations" - [button] read location file using readlocs() +% Command line equivalent: 'load'. +% "Read help" - [button] display readlocs() function help. +% "Save .ced" - [button] save channel locations in native EEGLAB ".ced" format. +% Command line equivalent: 'save'. +% "Save others" - [button] save channel locations in other formats using +% pop_writelocs() (see readlocs() for available channel formats). +% "Cancel" - [button] cancel all editing. +% "Help" - [button] display this help message. +% "OK" - [button] save edits and propagate to parent. +% +% Inputs: +% EEG - EEG dataset +% chanlocs - EEG.chanlocs structure +% +% Optional inputs: +% 'convert' - {conversion_type [args]} Conversion type may be: 'cart2topo' +% 'sph2topo', 'topo2sph', 'sph2cart', 'cart2sph', or 'chancenter'. +% See help messages for these functions. Args are only relevant +% for 'chancenter'. More info is given in the graphic interface +% description above. +% 'transform' - String command for manipulating arrays. 'chan' is full channel +% info. Fields that can be manipulated are 'labels', 'theta' +% 'radius' (polar angle and radius), 'X', 'Y', 'Z' (cartesian +% 3-D) or 'sph_theta', 'sph_phi', 'sph_radius' for spherical +% horizontal angle, azimuth and radius. +% Ex: 'chans(3) = chans(14)', 'X = -X' or a multi-step transform +% with steps separated by ';': Ex. 'TMP = X; X = Y; Y = TMP' +% 'changechan' - {number value1 value2 value3 ...} Change the values of all fields +% for the given channel number, mimimally {num label theta radius}. +% Ex: 'changechan' {12 'PXz' -90 0.30} +% 'changefield' - {number field value} Change field value for channel number number. +% Ex: {34 'theta' 320.4}. +% 'insert' - {number label theta radius X Y Z sph_theta sph_phi sph_radius } +% Insert new channel and specified values before the current channel +% number. If the number of values is less than 10, remaining +% fields will be 0. (Previously, this parameter was termed 'add'). +% 'append' - {num label theta radius X Y Z sph_theta sph_phi sph_radius } +% same as 'insert' (above) but insert the the new channel after +% the current channel number. +% 'delete' - [int_vector] Vector of channel numbers to delete. +% 'forcelocs' - [cell] call forcelocs() to force a particular channel to be at a +% particular location on the head sphere; rotate other channels +% accordingly. +% 'skirt' - Topographical polar skirt factor (see >> help topoplot) +% 'shrink' - Topographical polar shrink factor (see >> help topoplot) +% 'load' - [filename|{filename, 'key', 'val'}] Load channel location file +% optional arguments (such as file format) to the function +% readlocs() can be specified if the input is a cell array. +% 'save' - 'filename' Save text file with channel info. +% 'eval' - [string] evaluate string ('chantmp' is the name of the channel +% location structure). +% 'headrad' - [float] change head radius. +% 'lookup' - [string] look-up channel numbers for standard locations in the +% channel location file given as input. +% 'rplurchanloc' - [1,0] [1] Replace EEG.urchanlocs.If EEG.urchanlocs is empty this +% option will be ignored and will be set to [1] +% +% Outputs: +% EEG - new EEGLAB dataset with updated channel location structures +% EEG.chanlocs, EEG.urchanlocs, EEG.chaninfo +% chanlocs - updated channel location structure +% chaninfo - updated chaninfo structure +% options - structure containing plotting options (equivalent to EEG.chaninfo) +% +% Ex: EEG = pop_chanedit(EEG,'load', { 'dummy.elp' 'elp' }, 'delete', [3 4], ... +% 'convert', { 'xyz->polar' [] -1 1 }, 'save', 'mychans.loc' ) +% % Load polhemus file, delete two channels, convert to polar (see +% % cart2topo() for arguments) and save into 'mychans.loc'. +% +% Author: Arnaud Delorme, CNL / Salk Institute, 20 April 2002 +% +% See also: readlocs() + +% Copyright (C) Arnaud Delorme, CNL / Salk Institute, 15 March 2002, arno@salk.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% hidden parameter +% 'gui' - [figure value], allow to process the same dialog box several times + +function [chansout, chaninfo, urchans, com] = pop_chanedit(chans, orichaninfo, varargin); + +% process multiple datasets +% ------------------------- +if length(chans) > 1 && isfield(chans, 'setname') && nargin > 2 + [ chansout, com ] = eeg_eval( 'pop_chanedit', chans, 'params', { orichaninfo, varargin{:} } ); + return; +end + +urchans = []; +com =''; +if nargin < 1 + help pop_chanedit; + return; +end +chansout = chans; +chaninfo = []; +fig = []; + +if nargin < 2 + orichaninfo = []; +end + +if isempty(chans) || all(~ishandle(chans)) + % in case an EEG structure was given as input + % ------------------------------------------- + if isfield(chans, 'chanlocs') + + % process multiple datasets + if length(chans) > 1 + sameAsFirst = arrayfun(@(x)isequaln(chans(1).chanlocs, x.chanlocs), chans(2:end)); + if ~all(sameAsFirst) + error( [ 'All datasets need to have the exact same channel structure.' 10 'If you want to look up channel location for all datasets,' 10 'do so for the first one and write a loop' ] ); + end + + % pop up GUI for first dataset + EEG = chans(1); + [chansout, chaninfo, urchans, com] = pop_chanedit(EEG, orichaninfo, varargin{:}); + chans(1) = chansout; + + % pop up GUI for first dataset + for iDat = 2:length(chans) + EEG = chans(iDat); + eval(com); + chans(iDat) = EEG; + end + chansout = chans; + return; + end + + dataset_input = 1; + EEG = chans; + chans = EEG(1).chanlocs; + nchansori = EEG.nbchan; + if isfield(EEG, 'chaninfo') + chaninfo = EEG(1).chaninfo; + else chaninfo = []; + end + if isfield(EEG, 'urchanlocs') + urchans = EEG(1).urchanlocs; + end + else + nchansori = 0; + dataset_input = 0; + chaninfo = orichaninfo; + end + + % dealing with additional parameters + % ---------------------------------- + if nargin > 1 && ~ischar(orichaninfo), % nothing + if nargin > 2 + if ~ischar(varargin{1}) + urchans = varargin{1}; + varargin = varargin(2:end); + end + end + elseif nargin > 1 && ~isempty(orichaninfo) && ischar(orichaninfo) + varargin = { orichaninfo varargin{:} }; + if isequal(orichaninfo, chaninfo) + chaninfo = []; + end + orichaninfo = []; + end + + % insert "no data channels" in channel structure + % ---------------------------------------------- + nbchan = length(chans); + [tmp chaninfo chans] = eeg_checkchanlocs(chans, chaninfo); + + if isfield(chaninfo, 'shrink') && ~isempty(chaninfo.shrink) + icadefs; + if SHRINKWARNING + warndlg2( [ 'You are currently shrinking channel locations for display.' 10 ... + 'A new option (more anatomically correct) is to plot channels' 10 ... + 'outside head limits so the shrink option has been disabled.' 10 ... + '(Edit the icadefs file to disable this message)' ], 'Shrink factor warning'); + end + end + + oldchaninfo = chaninfo; +end + +% Checking for flag to replace 'urchanloc' field +indx_tmp = find(strcmp(varargin,'rplurchanloc')); +flag_replurchan = 0; +if ~isempty(indx_tmp) + flag_replurchan = varargin{indx_tmp+1}; +end + +if nargin < 3 && isstruct(chans) + + totaluserdat = {}; + % lookup channel locations if necessary + % ------------------------------------- + if ~all(cellfun('isempty', {chans.labels})) && all(cellfun('isempty', {chans.theta})) + [chans chaninfo urchans com] = pop_chanedit(chans, chaninfo, 'lookupgui', []); + for index = 1:length(chans) + chans(index).ref = ''; + chans(index).datachan = 1; + end + if ~isempty(com) + totaluserdat = com; + %[chans chaninfo urchans com] = pop_chanedit(chans, chaninfo, com{:}); + end + end + + commentfields = { 'Channel label ("label")', ... + 'Polar angle ("theta")', 'Polar radius ("radius")', ... + 'Cartesian X ("X")', ... + 'Cartesian Y ("Y")', ... + 'Cartesian Z ("Z")', ... + 'Spherical horiz. angle ("sph_theta")', ... + 'Spherical azimuth angle ("sph_phi")', ... + 'Spherical radius ("sph_radius")' ... + 'Channel type' 'Reference' ... + 'Index in backup ''urchanlocs'' structure' ... + 'Channel in data array (set=yes)' }; + + % add field values + % ---------------- + geometry = { 1 }; + tmpstr = sprintf('Channel information ("field_name"):'); + uilist = { { 'Style', 'text', 'string', tmpstr, 'fontweight', 'bold' } }; + + uiconvert = { ... + { 'Style', 'pushbutton', 'string', 'Opt. head center', 'callback', 'pop_chanedit(gcbf, [], ''chancenter'', []);' } ... + { 'Style', 'pushbutton', 'string', 'Rotate axis' , 'callback', 'pop_chanedit(gcbf, [], ''forcelocs'', []);' } ... + { 'Style', 'pushbutton', 'string', 'Transform axes' , 'callback', 'pop_chanedit(gcbf, [], ''transform'', []);' } ... + { }, ... + { 'Style', 'pushbutton', 'string', 'xyz -> polar & sph.', 'callback', 'pop_chanedit(gcbf, [], ''convert'', {''cart2all''});' }, ... + { 'Style', 'pushbutton', 'string', 'sph. -> polar & xyz', 'callback', 'pop_chanedit(gcbf, [], ''convert'', {''sph2all'' });' }, ... + { 'Style', 'pushbutton', 'string', 'polar -> sph. & xyz', 'callback', 'pop_chanedit(gcbf, [], ''convert'', {''topo2all''});' }, ... + { }, ... + { 'Style', 'pushbutton', 'string', 'Set head radius', 'callback', 'pop_chanedit(gcbf, [], ''headrad'', []);' } ... + { 'Style', 'pushbutton', 'string', 'Set channel types', 'callback', 'pop_chanedit(gcbf, [], ''settype'', []);' } ... + { 'Style', 'pushbutton', 'string', 'Set reference', 'callback', 'pop_chanedit(gcbf, [], ''setref'' , []);' } ... + { } { } }; + + % create text and edit for each field + % ----------------------------------- + allfields = { 'labels' 'theta' 'radius' 'X' 'Y' 'Z' 'sph_theta' 'sph_phi' 'sph_radius' 'type' 'ref' 'urchan' 'datachan' }; + for index = 1:length(allfields)-1 + cbfield = [ 'valnumtmp = str2num(get(findobj(gcbf, ''tag'', ''chaneditnumval''), ''string''));' ... + 'pop_chanedit(gcbf, [], ''changefield'', { valnumtmp ''' allfields{index} ''' get(gcbo, ''string'') });' ... + 'clear valnumtmp;' ]; + geometry = { geometry{:} [1.5 1 0.2 1] }; + uilist = { uilist{:}, ... + { 'Style', 'text', 'string', commentfields{index} }, ... + { 'Style', 'edit', 'tag', [ 'chanedit' allfields{index} ], 'string', ... + num2str(getfield(chans,{1}, allfields{index})), 'horizontalalignment', 'center', 'callback', cbfield } ... + { } uiconvert{index} }; + end + + % special checkbox for chandata field + % ----------------------------------- + geometry = { geometry{:} [2 0.35 0.5 1] }; + cbfield = [ 'valnumtmp = str2num(get(findobj(gcbf, ''tag'', ''chaneditnumval''), ''string''));' ... + 'pop_chanedit(gcbf, [], ''changefield'', { valnumtmp ''' allfields{end} ''' get(gcbo, ''value'') });' ... + 'clear valnumtmp;' ]; + uilist = { uilist{:}, ... + { 'Style', 'text', 'string', commentfields{end} }, ... + { 'Style', 'checkbox', 'tag', [ 'chanedit' allfields{end}], 'string', '' 'value', 1 'callback', cbfield } { } uiconvert{end} }; + + % add buttons + % ----------- + geometry = { geometry{:} [1] [1.15 0.5 0.6 1.9 0.4 0.4 1.15] [1.15 0.7 0.7 1 0.7 0.7 1.15] }; + cb_del = [ 'valnum = str2num(char(get(findobj(gcbf,''tag'', ''chaneditnumval''), ''string'')));' ... + 'pop_chanedit(gcbf, [], ''deletegui'', valnum);' ]; + cb_insert = [ 'valnum = str2num(char(get(findobj(gcbf,''tag'', ''chaneditnumval''), ''string'')));' ... + 'pop_chanedit(gcbf, [], ''insert'', valnum);' ]; + cb_append = [ 'valnum = str2num(char(get(findobj(gcbf,''tag'', ''chaneditnumval''), ''string'')));' ... + 'pop_chanedit(gcbf, [], ''append'', valnum);' ]; + + uilist = { uilist{:}, ... + { }, ... + { 'Style', 'pushbutton', 'string', 'Delete chan', 'callback', cb_del }, ... + { },{ }, ... + { 'Style', 'text' , 'string', ['Channel number (of ' int2str(length(chans)) ')'], ... + 'fontweight', 'bold', 'tag', 'chaneditscantitle' }, { },{ },{ }, ... + { 'Style', 'pushbutton', 'string', 'Insert chan', 'callback', cb_insert } ... + { 'Style', 'pushbutton', 'string', '<<', 'callback', [ 'pop_chanedit(gcbf, [], ''movecursor'', -10);' ] } ... + { 'Style', 'pushbutton', 'string', '<', 'callback', [ 'pop_chanedit(gcbf, [], ''movecursor'', -1);' ] } ... + { 'Style', 'edit' , 'string', '1', 'tag', 'chaneditnumval', 'callback', [ 'pop_chanedit(gcbf, []);' ] } ... + { 'Style', 'pushbutton', 'string', '>', 'callback', [ 'pop_chanedit(gcbf, [], ''movecursor'', 1);' ] } ... + { 'Style', 'pushbutton', 'string', '>>', 'callback', [ 'pop_chanedit(gcbf, [], ''movecursor'', 10);' ] } ... + { 'Style', 'pushbutton', 'string', 'Append chan', 'callback', cb_append }, ... + }; + + % add sorting options + % ------------------- + cb_rplurchan = [ 'valnumtmp = get(findobj(gcbf, ''tag'', ''rplurchan''), ''value'');' ... + 'pop_chanedit(gcbf, [], ''rplurchanloc'', valnumtmp);' ... + 'clear valnumtmp;' ]; + noseparam = strmatch(upper(chaninfo.nosedir), { '+X' '-X' '+Y' '-Y' }); + if isempty(noseparam), error('Wrong value for nose direction'); end + geometry = { geometry{:} [1] [0.9 1.3 0.6 1.1 0.9] [1] [1 1 1 1 1] [1]}; + uilist = { uilist{:},... + { } ... + { 'Style', 'pushbutton', 'string', 'Plot 2-D', 'callback', 'pop_chanedit(gcbf, [], ''plot2d'', []);' },... + { 'Style', 'text', 'string', 'Plot radius (0.2-1, []=auto)'} ... + { 'Style', 'edit', 'string', char(chaninfo.plotrad), 'tag', 'plotrad' 'callback' 'pop_chanedit(gcbf, [], ''plotrad'', []);' } ... + { 'Style', 'popupmenu', 'string', 'Nose along +X|Nose along -X|Nose along +Y|Nose along -Y', ... + 'tag' 'nosedir' 'value',noseparam, 'callback' 'pop_chanedit(gcbf,[],''nosedir'',[]);' 'listboxtop' noseparam } ... + { 'Style', 'pushbutton', 'string', 'Plot 3-D (xyz)', 'callback', 'pop_chanedit(gcbf, [], ''plot3d'', []);' } ... + {}, ... + { 'Style', 'pushbutton', 'string', 'Read locations', 'callback', 'pop_chanedit(gcbf,[],''load'',[]);' }, ... + { 'Style', 'pushbutton', 'string', 'Read locs help', 'callback', 'pophelp(''readlocs.m'');' }, ... + { 'Style', 'pushbutton', 'string', 'Look up locs', 'callback', 'pop_chanedit(gcbf,[], ''lookupgui'', []);' }, ... + { 'Style', 'pushbutton', 'string', 'Save (as .ced)', 'callback', 'pop_chanedit(gcbf,[], ''save'',[]);' } ... + { 'Style', 'pushbutton', 'string', 'Save (other types)', 'callback', 'pop_chanedit(gcbf,[], ''saveothers'',[]);' } ... + { 'Style', 'checkbox' , 'string', 'Overwrite Original Channels', 'callback', cb_rplurchan, 'tag' , 'rplurchan', 'value', flag_replurchan }... + }; + + % evaluation of command below is required to center text (if + % declared a text instead of edit, the uicontrol is not centered) + comeval = [ 'set(findobj( ''tag'', ''chanediturchan''), ''style'', ''text'', ''backgroundcolor'', [.66 .76 1] );' ... + 'set(findobj( ''tag'', ''chaneditref''), ''style'', ''text'', ''backgroundcolor'', [.66 .76 1] );' ... + 'set(findobj( ''tag'', ''ok''), ''callback'', ''valnumtmp = get(findobj(gcbf, ''''tag'''', ''''rplurchan''''), ''''value''''); pop_chanedit(gcbf, [],''''rplurchanloc'''',valnumtmp, ''''return'''', []);'')' ]; + + userdata.chans = chans; + userdata.nchansori = nchansori; + userdata.chaninfo = chaninfo; + userdata.urchans = urchans ; + userdata.commands = totaluserdat; + + [results userdata returnmode] = inputgui( 'geometry', geometry, 'uilist', uilist, 'helpcom', ... + 'pophelp(''pop_chanedit'');', 'title', 'Edit channel info -- pop_chanedit()', ... + 'userdata', userdata, 'eval' , comeval ); + + if length(results) == 0, + com = ''; + if dataset_input, chansout = EEG; end; + return; + end + + % transfer events back from global workspace + chans = userdata.chans; + chaninfo = userdata.chaninfo; + urchans = userdata.urchans; + if ~isempty(userdata.commands) + com = sprintf('%s=pop_chanedit(%s, %s);', inputname(1), inputname(1), vararg2str(userdata.commands)); + end + % Updating flag + flag_replurchan = results{15}; +else + + % call from command line or from a figure + % --------------------------------------- + currentpos = 0; + if ishandle(chans) + fig = chans; + userdata = get(fig, 'userdata'); + chans = userdata.chans; + nchansori = userdata.nchansori; + chaninfo = userdata.chaninfo; + urchans = userdata.urchans; + currentpos = str2num(get(findobj(fig, 'tag', 'chaneditnumval'), 'string')); + end + + args = varargin; + % no interactive inputs + % scan all the fields of g + % ------------------------ + for curfield = 1:2:length(args) + switch lower(args{curfield}) + case 'rplurchanloc' + if flag_replurchan, urchans = eeg_checkchanlocs(chans, chaninfo); end + args{curfield} = 'rplurchanloc'; + args{ curfield+1 } = flag_replurchan; + case 'return' + [tmpchans] = eeg_checkchanlocs(chans); + if nchansori ~= 0 && nchansori ~= length(tmpchans) + if ~popask(strvcat(['The number of data channels (' int2str(length(tmpchans)) ') not including fiducials does not'], ... + ['correspond to the initial number of channels (' int2str(nchansori) '), so for consistency purposes'], ... + 'new channel information will be ignored if this function was called from EEGLAB', ... + 'If you have added a reference channel manually, check the "Data channel" checkbox is off')) + else + set(findobj(fig, 'tag', 'ok'), 'userdata', 'stop'); + end + else + set(findobj(fig, 'tag', 'ok'), 'userdata', 'stop'); + end + args = {}; + case 'plot3d', % GUI only + tmpind = find(~cellfun('isempty', { chans.X })); + if ~isempty(tmpind), + plotchans3d([ [ chans(tmpind).X ]' [ chans(tmpind).Y ]' [ chans(tmpind).Z ]'], { chans(tmpind).labels }); + else disp('cannot plot: no XYZ coordinates'); + end + args = {}; + case 'plot2d', % GUI only + plotrad = str2num(get(findobj(fig, 'tag', 'plotrad'), 'string')); + figure; topoplot([],chans, 'style', 'blank', 'drawaxis', 'on', 'electrodes', ... + 'labelpoint', 'plotrad', plotrad, 'chaninfo', chaninfo); + args = {}; + case 'movecursor', % GUI only + currentpos = max(1,min(currentpos+args{curfield+1},length(chans))); + args = {}; + case 'plotrad', + if isempty( args{curfield+1} ) + args{curfield+1} = str2num(get(findobj(fig, 'tag', 'plotrad'), 'string')); + end + chaninfo.plotrad = args{curfield+1}; + case 'forcelocs', + if ~isempty(fig) % GUI BASED + [ comtmp tmpforce ] = forcelocs(chans); + if ~isempty(tmpforce), + args{curfield+1} = tmpforce{1}; + end + end + if ~isempty(args{curfield+1}) + chans = forcelocs(chans,args{curfield+1}); + disp('Convert XYZ coordinates to spherical and polar'); + end + case 'chancenter', + if ~isempty(fig) + [chans newcenter tmpcom] = pop_chancenter(chans); + args{curfield } = 'eval'; + args{curfield+1} = tmpcom; + end + case 'convert', + if iscell(args{curfield+1}) + method=args{curfield+1}{1}; + extraargs = args{curfield+1}(2:end); + else + method=args{curfield+1}; + extraargs = {''}; + end + if ~isempty(fig) && ~strcmp(method, 'chancenter') + tmpButtonName=questdlg2( strvcat('This will modify fields in the channel structure', ... + 'Are you sure you want to apply this function ?'), 'Confirmation', 'Cancel', 'Yes','Yes'); + if ~strcmpi(tmpButtonName, 'Yes'), return; end + end + switch method + case 'chancenter', + if isempty(extraargs) + [X Y Z]=chancenter( [chans.X ]', [ chans.Y ]', [ chans.Z ]',[]); + else + [X Y Z]=chancenter( [chans.X ]', [ chans.Y ]', [ chans.Z ]', extraargs{:}); + end + if isempty(X), return; end + for index = 1:length(chans) + chans(index).X = X(index); + chans(index).Y = Y(index); + chans(index).Z = Z(index); + end + disp('Note: automatically convert XYZ coordinates to spherical and polar'); + chans = convertlocs(chans, 'cart2all'); + otherwise + chans = convertlocs(chans, method, 'verbose', 'on'); + end + case 'settype' + if ~isempty(fig) + args{curfield+1} = inputdlg2({'Channel indices' 'Type (e.g. EEG)' }, ... + 'Set channel type', 1, { '' '' }, 'pop_chanedit'); + end + try, tmpchans = args{curfield+1}{1}; tmptype = args{curfield+1}{2};catch, return; end + if isempty(tmpchans) && isempty(tmptype), return; end + if ischar(tmpchans) + tmpchans = eval( [ '[' tmpchans ']' ], 'settype: error in channel indices'); + end + if ~ischar(tmptype), tmptype = num2str(tmptype); end + for index = 1:length(tmpchans) + if tmpchans(index) > 0 && tmpchans(index) <= length(chans) + chans( tmpchans(index) ).type = tmptype; + end + end + case 'setref' + if ~isempty(fig) + disp('Note that setting the reference only changes the reference labels'); + disp('Use the re-referencing menu to change the reference'); + args{curfield+1} = inputdlg2({'Channel indices' 'Reference (e.g. Cz)' }, ... + 'Set channel reference', 1, { '' '' }, 'pop_chanedit'); + end + try, tmpchans = args{curfield+1}{1}; tmpref = args{curfield+1}{2};catch, return; end + if isempty(tmpchans) && isempty(tmpref), return; end + if ischar(tmpchans) + tmpchans = eval( [ '[' tmpchans ']' ], 'settype: error in channel indices'); + end + if ~ischar(tmpref), tmpref = num2str(tmpref); end + for index = 1:length(tmpchans) + if tmpchans(index) > 0 && tmpchans(index) <= length(chans) + chans( tmpchans(index) ).ref = tmpref; + end + end + case 'transform' + if ~isempty(fig) + args{curfield+1} = inputdlg2({'Enter transform: (Ex: TMP=X; X=-Y; Y=TMP or Y(3) = X(2), etc.' }, ... + 'Transform', 1, { '' }, 'pop_chanedit'); + end + try, tmpoper = args{curfield+1}; catch, return; end + if isempty(deblank(tmpoper)), return; end + if iscell(tmpoper), tmpoper = tmpoper{1}; end + tmpoper = [ tmpoper ';' ]; + [eloc, labels, theta, radius, indices] = readlocs(chans); + if isempty(findstr(tmpoper, 'chans')) + try, + X = [ chans(indices).X ]; + Y = [ chans(indices).Y ]; + Z = [ chans(indices).Z ]; + sph_theta = [ chans(indices).sph_theta ]; + sph_phi = [ chans(indices).sph_phi ]; + sph_radius = [ chans(indices).sph_radius ]; + eval(tmpoper); + + for ind = 1:length(indices) + chans(indices(ind)).X = X(min(length(X),ind)); + chans(indices(ind)).Y = Y(min(length(Y),ind)); + chans(indices(ind)).Z = Z(min(length(Z),ind)); + chans(indices(ind)).theta = theta(min(length(theta),ind)); + chans(indices(ind)).radius = radius(min(length(radius),ind)); + chans(indices(ind)).sph_theta = sph_theta(min(length(sph_theta),ind)); + chans(indices(ind)).sph_phi = sph_phi(min(length(sph_phi),ind)); + chans(indices(ind)).sph_radius = sph_radius(min(length(sph_radius),ind)); + end + + if ~isempty(findstr(tmpoper, 'X')), chans = convertlocs(chans, 'cart2all'); end + if ~isempty(findstr(tmpoper, 'Y')), chans = convertlocs(chans, 'cart2all'); end + if ~isempty(findstr(tmpoper, 'Z')), chans = convertlocs(chans, 'cart2all'); end + if ~isempty(findstr(tmpoper, 'sph_theta')), chans = convertlocs(chans, 'sph2all'); + elseif ~isempty(findstr(tmpoper, 'theta')), chans = convertlocs(chans, 'topo2all'); end + if ~isempty(findstr(tmpoper, 'sph_phi')), chans = convertlocs(chans, 'sph2all'); end + if ~isempty(findstr(tmpoper, 'sph_radius')), chans = convertlocs(chans, 'sph2all'); + elseif ~isempty(findstr(tmpoper, 'radius')), chans = convertlocs(chans, 'topo2all'); end + catch, disp('Unknown error when applying transform'); end + else + eval(tmpoper); + end + + case 'headrad' + if ~isempty(fig) % GUI + tmpres = inputdlg2({'Enter new head radius (same unit as DIPFIT head model):' }, ... + 'Head radius', 1, { '' }, 'pop_chanedit'); + if ~isempty(tmpres), + args{ curfield+1 } = str2num(tmpres{1}); + else return; + end + end + if ~isempty( args{ curfield+1 } ) + allrad = [ chans.sph_radius ]; + if length(unique(allrad)) == 1 % already spherical + chans = pop_chanedit(chans, 'transform', [ 'sph_radius = ' num2str( args{ curfield+1 } ) ';' ]); + else % non-spherical, finding best match + factor = args{ curfield+1 } / mean(allrad); + chans = pop_chanedit(chans, 'transform', [ 'sph_radius = sph_radius*' num2str( factor ) ';' ]); + disp('Warning: electrodes do not lie on a sphere. Sphere model fitting for'); + disp(' dipole localization will work but generate many warnings'); + end + chans = convertlocs(chans, 'sph2all'); + end + + case 'shrink' + chans(1).shrink = args{ curfield+1 }; + + case 'plotrad' + chans(1).plotrad = args{ curfield+1 }; + + case 'deletegui' + chans(args{ curfield+1 })=[]; + currentpos = min(length(chans), currentpos); + args{ curfield } = 'delete'; + + case 'delete' + chans(args{ curfield+1 })=[]; + + case 'changefield' + tmpargs = args{ curfield+1 }; + if length( tmpargs ) < 3 + error('pop_chanedit: not enough arguments to change field value'); + end + if ~isempty(strmatch( tmpargs{2}, { 'X' 'Y' 'Z' 'theta' 'radius' 'sph_theta' 'sph_phi' 'sph_radius'})) + if ~isnumeric(tmpargs{3}), tmpargs{3} = str2num(tmpargs{3}); end + end + for paramChan = 2:2:length(tmpargs) + eval([ 'chans(' int2str(tmpargs{1}) ').' tmpargs{paramChan} '=' reformat(tmpargs{paramChan+1} ) ';' ]); + end + case { 'insert' 'add' 'append' } + tmpargs = args{ curfield+1 }; + allfields = fieldnames(chans); + if isnumeric(tmpargs) + tmpargs2 = cell(1, length(allfields)+1); + tmpargs2{1} = tmpargs; + tmpargs = tmpargs2; + if strcmpi(allfields{end}, 'datachan'), tmpargs{end} = 0; end + end + if length( tmpargs ) < length(allfields)+1 + error('pop_chanedit: not enough arguments to change all field values'); + end + num = tmpargs{1}; + if strcmpi(lower(args{curfield}), 'append'), num=num+1; currentpos = currentpos+1; end + chans(end+1) = chans(end); + chans(num+1:end) = chans(num:end-1); + for index = 1:length( allfields ) + chans = setfield(chans, {num}, allfields{index}, tmpargs{index+1}); + end + if isfield(chans, 'datachan') + if isempty(chans(num).datachan) + chans(num).datachan = 0; + end + end + case 'changechan' + tmpargs = args{ curfield+1 }; + num = tmpargs{1}; + allfields = fieldnames(chans); + if length( tmpargs ) < length(allfields)+1 + error('pop_chanedit: not enough arguments to change all field values'); + end + for index = 1:length( allfields ) + eval([ 'chans(' int2str(num) ').' allfields{index} '=' reformat(tmpargs{index+1}) ';' ]); + end + + case 'load' + if ~isempty(fig) % GUI + [tmpf tmpp] = uigetfile('*.*', 'Load a channel location file'); + drawnow; + if ~isequal(tmpf, 0), + tmpformats = readlocs('getinfos'); + tmpformattype = { 'autodetect' tmpformats(1:end-1).type }; + tmpformatstr = { 'autodetect' tmpformats(1:end-1).typestring }; + tmpformatdesc = { 'Autodetect file format from file extension' tmpformats(1:end-1).description }; + %cb_listbox = 'tmpdesc=get(gcbf, ''userdata''); set(findobj(gcbf, ''tag'', ''strdesc''), ''string'', strmultiline([ ''File format: '' tmpdesc{get(gcbo, ''value'')} ], 30, 10)); clear tmpdesc;'' } }, ''pophelp(''''readlocs'''')'',' ... + % 'Read electrode file'', tmpformatdesc, ''normal'', 4); + %txtgui = [ strmultiline([ 'File format: Autodetect file format from file extension'], 20, 10) 10 10 ]; + %tmpfmt = inputgui( 'geometry', {[1 1]}, ... + % 'uilist' , { { 'style', 'text', 'string', txtgui 'tag' 'strdesc' }, ... + % { 'style', 'listbox', 'string', strvcat(tmpformatstr) 'callback' '' } }, ... + % 'geomvert', [10], ... + % 'helpcom' , 'pophelp(''readlocs'');'); + tmpfmt = inputgui( 'geometry', {[1 1 1] [1]}, ... + 'uilist' , { { 'style', 'text', 'string', 'File format:' 'tag' 'strdesc' } {} {}, ... + { 'style', 'listbox', 'string', strvcat(tmpformatstr) 'callback' '' } }, ... + 'geomvert', [1 8], ... + 'helpcom' , 'pophelp(''readlocs'');'); + if isempty(tmpfmt), + args{ curfield+1 } = []; + else args{ curfield+1 } = { fullfile(tmpp, tmpf) 'filetype' tmpformattype{tmpfmt{1}} }; + end + else args{ curfield+1 } = []; + end + end + + tmpargs = args{ curfield+1 }; + if ~isempty(tmpargs), + if ischar(tmpargs) + [chans] = readlocs(tmpargs); + [tmp tmp2 chans] = eeg_checkchanlocs(chans); + chaninfo = []; + chaninfo.filename = tmpargs; + else + [chans] = readlocs(tmpargs{:}); + [tmp tmp2 chans] = eeg_checkchanlocs(chans); + chaninfo = []; + chaninfo.filename = tmpargs{1}; + end + + % backup file content etc... + % -------------------------- + tmptext = loadtxt( chaninfo.filename, 'delim', [], 'verbose', 'off', 'convert', 'off'); + chaninfo.filecontent = strvcat(tmptext{:}); + + % set urchan structure + % -------------------- + urchans = chans; + for index = 1:length(chans) + chans(index).urchan = index; + end + end + if ~isfield(chans, 'datachan') + chans(1).datachan = []; + end + for index = 1:length(chans) + if isempty(chans(index).datachan) + chans(index).datachan = 1; + end + end + + case 'eval' + tmpargs = args{ curfield+1 }; + eval(tmpargs); + + case 'saveothers' + com = pop_writelocs(chans); + args{ curfield } = 'eval'; + args{ curfield+1 } = com; + + case 'save' + if ~isempty(fig) + [tmpf tmpp] = uiputfile('*.ced', 'Save channel locs in EEGLAB .ced format'); + drawnow; + args{ curfield+1 } = fullfile(tmpp, tmpf); + end + tmpargs = args{ curfield+1 }; + [tmp, tmp, filext] = fileparts(tmpargs); + if isempty(tmpargs), return; end + fid = fopen(tmpargs, 'w'); + if fid ==-1, error('Cannot open file'); end + + allfields = fieldnames(chans); + fields = { 'labels' 'theta' 'radius' 'X' 'Y' 'Z' 'sph_theta' 'sph_phi' 'sph_radius' 'type' }; + tmpdiff = setdiff(fields, allfields); + if ~isempty(tmpdiff), error(sprintf('Field "%s" missing in channel location structure', tmpdiff{1})); end + if strcmpi(filext,'.ced') + origfield = fields; % Setting the order as expected in readlocs.m + else + origfield = intersect(allfields,fields,'stable'); % Getting the original order from file + end + fprintf(fid, 'Number\t'); + for field = 1:length(fields) + fprintf(fid, '%s\t', origfield{field}); + end + fprintf(fid, '\n'); + for index=1:length(chans) + fprintf(fid, '%d\t', index); + for field = 1:length(fields) + tmpval = getfield(chans, {index}, origfield{field}); + if ischar(tmpval) + fprintf(fid, '%s\t', tmpval); + else + fprintf(fid, '%3.3g\t', tmpval); + end + end + fprintf(fid, '\n'); + end + if isempty(tmpargs), chantmp = readlocs(tmpargs); end + + case 'nosedir' + nosevals = { '+X' '-X' '+Y' '-Y' }; + if ~isempty(fig) + tmpval = get(findobj(gcbf, 'tag', 'nosedir'), 'value'); + args{ curfield+1 } = nosevals{tmpval}; + warndlg2( [ 'Changing the nose direction will force EEGLAB to physically rotate ' 10 ... + 'electrodes, so next time you call this interface, nose direction will' 10 ... + 'be +X. If your electrodes are currently aligned with a specific' 10 ... + 'head model, you will have to rotate them in the model coregistration' 10 ... + 'interface to realign them with the model.'], 'My Warn Dialog'); + end + chaninfo.nosedir = args{ curfield+1 }; + if isempty(strmatch(chaninfo.nosedir, nosevals)) + error('Wrong value for nose direction'); + end + + case { 'lookup' 'lookupgui' } + if strcmpi(lower(args{curfield}), 'lookupgui') + standardchans = { 'Fp1' 'Fpz' 'Fp2' 'Nz' 'AF9' 'AF7' 'AF3' 'AFz' 'AF4' 'AF8' 'AF10' 'F9' 'F7' 'F5' ... + 'F3' 'F1' 'Fz' 'F2' 'F4' 'F6' 'F8' 'F10' 'FT9' 'FT7' 'FC5' 'FC3' 'FC1' 'FCz' 'FC2' ... + 'FC4' 'FC6' 'FT8' 'FT10' 'T9' 'T7' 'C5' 'C3' 'C1' 'Cz' 'C2' 'C4' 'C6' 'T8' 'T10' ... + 'TP9' 'TP7' 'CP5' 'CP3' 'CP1' 'CPz' 'CP2' 'CP4' 'CP6' 'TP8' 'TP10' 'P9' 'P7' 'P5' ... + 'P3' 'P1' 'Pz' 'P2' 'P4' 'P6' 'P8' 'P10' 'PO9' 'PO7' 'PO3' 'POz' 'PO4' 'PO8' 'PO10' ... + 'O1' 'Oz' 'O2' 'O9' 'O10' 'CB1' 'CB2' 'Iz' }; + for indexchan = 1:length(chans) + if isempty(chans(indexchan).labels), chans(indexchan).labels = ''; end + end + [tmp1 ind1 ind2] = intersect_bc( lower(standardchans), {chans.labels}); + if ~isempty(tmp1) || isfield(chans, 'theta') + + % finding template location files + % ------------------------------- + setmodel = [ 'tmpdat = get(gcbf, ''userdata'');' ... + 'tmpval = get(gcbo, ''value'');' ... + 'set(findobj(gcbf, ''tag'', ''elec''), ''string'', tmpdat{tmpval});' ... + 'clear tmpval tmpdat;' ]; + try + EEG = eeg_emptyset; % for dipfitdefs + dipfitdefs; + userdatatmp = { template_models(1).chanfile template_models(2).chanfile 'Standard-10-5-Cap385_witheog.elp' }; % last file in the path (see eeglab.m) + clear EEG; + catch, userdatatmp = { 'Standard-10-5-Cap385.sfp' 'Standard-10-5-Cap385.sfp' 'Standard-10-5-Cap385_witheog.elp' }; % files are in the path (see eeglab.m) + end + + % other commands for help/load + % ---------------------------- + comhelp = [ 'warndlg2(strvcat(''The template file depends on the model'',' ... + '''you intend to use for dipole fitting. The default file is fine for'',' ... + '''spherical model.'');' ]; + commandload = [ '[filename, filepath] = uigetfile(''*'', ''Select a text file'');' ... + 'if filename ~=0,' ... + ' set(findobj(''parent'', gcbf, ''tag'', ''elec''), ''string'', [ filepath filename ]);' ... + 'end;' ... + 'clear filename filepath tagtest;' ]; + if ~isfield(chans, 'theta'), message =1; + elseif all(cellfun('isempty', {chans.theta })), message =1; + else message =2; + end + if message == 1 + textcomment = strvcat('Only channel labels are present currently, but some of these labels have known', ... + 'positions. Do you want to look up coordinates for these channels using the electrode', ... + 'file below? If you have a channel location file for this dataset, press cancel, then', ... + 'use button "Read location" in the following gui. If you do not know, just press OK.'); + else + textcomment = strvcat('Some channel labels may have known locations.', ... + 'Do you want to look up coordinates for these channels using the electrode', ... + 'file below? If you do not know, press OK.'); + end + uilist = { { 'style' 'text' 'string' textcomment } ... + { 'style' 'popupmenu' 'string' [ 'use BESA file for 4-shell dipfit spherical model' ... + '|use MNI coordinate file for BEM dipfit model|Use spherical file with eye channels' ] ... + 'callback' setmodel 'value' 2 } ... + { } ... + { 'style' 'edit' 'string' userdatatmp{2} 'tag' 'elec' } ... + { 'style' 'pushbutton' 'string' '...' 'callback' commandload } ... + { } }; +% { 'Style', 'checkbox', 'value', 0, 'string','Overwrite Original Channels' } }; + + res = inputgui( { 1 [1 0.3] [1 0.3] 1 }, uilist, 'pophelp(''pop_chanedit'')', 'Look up channel locations?', userdatatmp, 'normal', [4 1 1 1] ); + if ~isempty(res) + chaninfo.filename = res{2}; + args{ curfield } = 'lookup'; + args{ curfield+1 } = res{2}; + com = args; + else + return; + end + end + else + chaninfo.filename = args{ curfield+1 }; + end + if strcmpi(chaninfo.filename, 'standard-10-5-cap385.elp') + dipfitdefs; + chaninfo.filename = template_models(1).chanfile; + elseif strcmpi(chaninfo.filename, 'standard_1005.elc') + dipfitdefs; + chaninfo.filename = template_models(2).chanfile; + elseif strcmpi(chaninfo.filename, 'standard_1005.ced') + dipfitdefs; + chaninfo.filename = template_models(2).chanfile; + end + tmplocs = readlocs( chaninfo.filename, 'defaultelp', 'BESA' ); + for indexchan = 1:length(chans) + if isempty(chans(indexchan).labels), chans(indexchan).labels = ''; end + end + [tmp ind1 ind2] = intersect_bc(lower({ tmplocs.labels }), lower({ chans.labels })); + if ~isempty(tmp) + chans = struct('labels', { chans.labels }, 'datachan', { chans.datachan }, 'type', { chans.type }); + [ind2 ind3] = sort(ind2); + ind1 = ind1(ind3); + + for index = 1:length(ind2) + chans(ind2(index)).theta = tmplocs(ind1(index)).theta; + chans(ind2(index)).radius = tmplocs(ind1(index)).radius; + chans(ind2(index)).X = tmplocs(ind1(index)).X; + chans(ind2(index)).Y = tmplocs(ind1(index)).Y; + chans(ind2(index)).Z = tmplocs(ind1(index)).Z; + chans(ind2(index)).sph_theta = tmplocs(ind1(index)).sph_theta; + chans(ind2(index)).sph_phi = tmplocs(ind1(index)).sph_phi; + chans(ind2(index)).sph_radius = tmplocs(ind1(index)).sph_radius; + end + if isfield(tmplocs, 'type') + for index = 1:length(ind2) + chans(ind2(index)).type = tmplocs(ind1(index)).type; + end + end + + tmpdiff = setdiff_bc([1:length(chans)], ind2); + if ~isempty(tmpdiff) + fprintf('Channel lookup: no location for '); + for index = 1:(length(tmpdiff)-1) + fprintf('%s,', chans(tmpdiff(index)).labels); + end + fprintf('%s\nSend us standard location for your channels at eeglab@sccn.ucsd.edu\n', ... + chans(tmpdiff(end)).labels); + end + if ~isfield(chans, 'type'), chans(1).type = []; end + end + if ~isempty(findstr(args{ curfield+1 }, 'standard_10')) && ... + ~isempty(findstr(args{ curfield+1 }, '.elc')) + chaninfo.nosedir = '+Y'; + else + chaninfo.nosedir = '+X'; + end + if flag_replurchan, urchans = eeg_checkchanlocs(chans, chaninfo); end + for index = 1:length(chans) + chans(index).urchan = index; + chans(index).ref = ''; + end + end + end + +end + +% call from a figure +% ------------------ +if ~isempty(fig) + userdata.chans = chans; + userdata.chaninfo = chaninfo; + userdata.commands = { userdata.commands{:} args{:} }; + userdata.urchans = urchans; + set(fig, 'userdata', userdata); + + set(findobj(fig, 'tag', 'chaneditnumval'), 'string', num2str(currentpos)); + set(findobj(fig, 'tag', 'chaneditscantitle'), 'string', ['Channel number (of ' int2str(length(chans)) ')']); + + % update GUI with current channel info + allfields = fieldnames(chans); + if ~isempty(chans) + for index = 1:length(allfields) + obj = findobj(fig, 'tag', [ 'chanedit' allfields{index}]); + if strcmpi(allfields{index}, 'datachan') + set(obj, 'value', getfield(chans(currentpos), allfields{index})); + else + tmpval = getfield(chans(currentpos), allfields{index}); + if ischar(tmpval) && strcmpi(tmpval, '[]'), tmpval = ''; end + set(obj, 'string', num2str(tmpval)); + end + end + else + for index = 1:length(allfields) + obj = findobj(fig, 'tag', [ 'chanedit' allfields{index}]); + if strcmpi(allfields{index}, 'datachan') + set(obj, 'value', 0); + else + set(obj, 'string', ''); + end + end + end +else + [chans chaninfo] = eeg_checkchanlocs(chans, chaninfo); + if dataset_input, + if nchansori == length(chans) + for index = 1:length(EEG) + EEG(index).chanlocs = chans; + EEG(index).chaninfo = chaninfo; + end + % Updating urchanlocs + if flag_replurchan && ~isempty(urchans), EEG.urchanlocs = urchans; end + EEG = eeg_checkset(EEG); % for channel orientation + else + disp('Channel structure size not consistent with the data so changes will be ignored'); + disp('Use the function pop_select(EEG, ''nochannel'', [x]); if you wish the remove data channels'); + end + try chansout = EEG; catch, end + else chansout = chans; + end +end + +return; + +% format the output field +% ----------------------- +function strval = reformat( val ) +if isnumeric(val) && isempty(val), val = '[]'; end +if ischar(val), strval = [ '''' val '''' ]; +else strval = num2str(val); +end + +% extract text using tokens (not used) +% ------------------------------------ +function txt = inserttxt( txt, tokins, tokfind); +locfind = findstr(txt, tokfind); +for index = length(locfind):-1:1 + txt = [txt(1:locfind(index)-1) tokins txt(locfind(index):end)]; +end + +% ask for confirmation +% -------------------- +function num = popask( text ) +ButtonName=questdlg2( text, ... + 'Confirmation', 'Cancel', 'Yes','Yes'); +switch lower(ButtonName), + case 'cancel', num = 0; + case 'yes', num = 1; +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/readlocs.m b/studio_functions/Functions/EEGLAB/Scalp/readlocs.m new file mode 100755 index 00000000..be8bb5b7 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/readlocs.m @@ -0,0 +1,710 @@ +% readlocs() - read electrode location coordinates and other information from a file. +% Several standard file formats are supported. Users may also specify +% a custom column format. Defined format examples are given below +% (see File Formats). +% Usage: +% >> eloc = readlocs( filename ); +% >> EEG.chanlocs = readlocs( filename, 'key', 'val', ... ); +% >> [eloc, labels, theta, radius, indices] = ... +% readlocs( filename, 'key', 'val', ... ); +% Inputs: +% filename - Name of the file containing the electrode locations +% {default: 2-D polar coordinates} (see >> help topoplot ) +% +% Optional inputs: +% 'filetype' - ['loc'|'sph'|'sfp'|'xyz'|'asc'|'polhemus'|'besa'|'chanedit'|'custom'] +% Type of the file to read. By default the file type is determined +% using the file extension (see below under File Formats), +% 'loc' an EEGLAB 2-D polar coordinates channel locations file +% Coordinates are theta and radius (see definitions below). +% 'sph' Matlab spherical coordinates (Note: spherical +% coordinates used by Matlab functions are different +% from spherical coordinates used by BESA - see below). +% 'sfp' EGI Cartesian coordinates (NOT Matlab Cartesian - see below). +% 'xyz' Matlab/EEGLAB Cartesian coordinates (NOT EGI Cartesian). +% z is toward nose; y is toward left ear; z is toward vertex +% 'asc' Neuroscan polar coordinates. +% 'polhemus' or 'polhemusx' - Polhemus electrode location file recorded +% with 'X' on sensor pointing to subject (see below and readelp()). +% 'polhemusy' - Polhemus electrode location file recorded with +% 'Y' on sensor pointing to subject (see below and readelp()). +% 'besa' BESA-'.elp' spherical coordinates. (Not MATLAB spherical - +% see below). +% 'chanedit' - EEGLAB channel location file created by pop_chanedit(). +% 'custom' - Ascii file with columns in user-defined 'format' (see below). +% 'importmode' - ['eeglab'|'native'] for location files containing 3-D cartesian electrode +% coordinates, import either in EEGLAB format (nose pointing toward +X). +% This may not always be possible since EEGLAB might not be able to +% determine the nose direction for scanned electrode files. 'native' import +% original carthesian coordinates (user can then specify the position of +% the nose when calling the topoplot() function; in EEGLAB the position +% of the nose is stored in the EEG.chaninfo structure). {default 'eeglab'} +% 'format' - [cell array] Format of a 'custom' channel location file (see above). +% {default: if no file type is defined. The cell array contains +% labels defining the meaning of each column of the input file. +% 'channum' [positive integer] channel number. +% 'labels' [string] channel name (no spaces). +% 'theta' [real degrees] 2-D angle in polar coordinates. +% positive => rotating from nose (0) toward left ear +% 'radius' [real] radius for 2-D polar coords; 0.5 is the head +% disk radius and limit for topoplot() plotting). +% 'X' [real] Matlab-Cartesian X coordinate (to nose). +% 'Y' [real] Matlab-Cartesian Y coordinate (to left ear). +% 'Z' [real] Matlab-Cartesian Z coordinate (to vertex). +% '-X','-Y','-Z' Matlab-Cartesian coordinates pointing opposite +% to the above. +% 'sph_theta' [real degrees] Matlab spherical horizontal angle. +% positive => rotating from nose (0) toward left ear. +% 'sph_phi' [real degrees] Matlab spherical elevation angle. +% positive => rotating from horizontal (0) upwards. +% 'sph_radius' [real] distance from head center (unused). +% 'sph_phi_besa' [real degrees] BESA phi angle from vertical. +% positive => rotating from vertex (0) towards right ear. +% 'sph_theta_besa' [real degrees] BESA theta horiz/azimuthal angle. +% positive => rotating from right ear (0) toward nose. +% 'ignore' ignore column}. +% The input file may also contain other channel information fields. +% 'type' channel type: 'EEG', 'MEG', 'EMG', 'ECG', others ... +% 'calib' [real near 1.0] channel calibration value. +% 'gain' [real > 1] channel gain. +% 'custom1' custom field #1. +% 'custom2', 'custom3', 'custom4', etc. more custom fields +% 'skiplines' - [integer] Number of header lines to skip (in 'custom' file types only). +% Note: Characters on a line following '%' will be treated as comments. +% 'readchans' - [integer array] indices of electrodes to read. {default: all} +% 'center' - [(1,3) real array or 'auto'] center of xyz coordinates for conversion +% to spherical or polar, Specify the center of the sphere here, or 'auto'. +% This uses the center of the sphere that best fits all the electrode +% locations read. {default: [0 0 0]}. [Deprecated] +% Outputs: +% eloc - structure containing the channel names and locations (if present). +% It has three fields: 'eloc.labels', 'eloc.theta' and 'eloc.radius' +% identical in meaning to the EEGLAB struct 'EEG.chanlocs'. +% labels - cell array of strings giving the names of the electrodes. NOTE: Unlike the +% three outputs below, includes labels of channels *without* location info. +% theta - vector (in degrees) of polar angles of the electrode locations. +% radius - vector of polar-coordinate radii (arc_lengths) of the electrode locations +% indices - indices, k, of channels with non-empty 'locs(k).theta' coordinate +% +% File formats: +% If 'filetype' is unspecified, the file extension determines its type. +% +% '.loc' or '.locs' or '.eloc': +% polar coordinates. Notes: angles in degrees: +% right ear is 90; left ear -90; head disk radius is 0.5. +% Fields: N angle radius label +% Sample: 1 -18 .511 Fp1 +% 2 18 .511 Fp2 +% 3 -90 .256 C3 +% 4 90 .256 C4 +% ... +% Note: In previous releases, channel labels had to contain exactly +% four characters (spaces replaced by '.'). This format still works, +% though dots are no longer required. +% '.sph': +% Matlab spherical coordinates. Notes: theta is the azimuthal/horizontal angle +% in deg.: 0 is toward nose, 90 rotated to left ear. Following this, performs +% the elevation (phi). Angles in degrees. +% Fields: N theta phi label +% Sample: 1 18 -2 Fp1 +% 2 -18 -2 Fp2 +% 3 90 44 C3 +% 4 -90 44 C4 +% ... +% '.elc': +% Cartesian 3-D electrode coordinates scanned using the EETrak software. +% See readeetraklocs(). +% '.elp': +% Polhemus-.'elp' Cartesian coordinates. By default, an .elp extension is read +% as PolhemusX-elp in which 'X' on the Polhemus sensor is pointed toward the +% subject. Polhemus files are not in columnar format (see readelp()). +% '.elp': +% BESA-'.elp' spherical coordinates: Need to specify 'filetype','besa'. +% The elevation angle (phi) is measured from the vertical axis. Positive +% rotation is toward right ear. Next, perform azimuthal/horizontal rotation +% (theta): 0 is toward right ear; 90 is toward nose, -90 toward occiput. +% Angles are in degrees. If labels are absent or weights are given in +% a last column, readlocs() adjusts for this. Default labels are E1, E2, ... +% Fields: Type label phi theta +% Sample: EEG Fp1 -92 -72 +% EEG Fp2 92 72 +% EEG C3 -46 0 +% EEG C4 46 0 +% ... +% '.xyz': +% Matlab/EEGLAB Cartesian coordinates. Here. x is towards the nose, +% y is towards the left ear, and z towards the vertex. Note that the first +% column (x) is -Y in a Matlab 3-D plot, the second column (y) is X in a +% matlab 3-D plot, and the third column (z) is Z. +% Fields: channum x y z label +% Sample: 1 .950 .308 -.035 Fp1 +% 2 .950 -.308 -.035 Fp2 +% 3 0 .719 .695 C3 +% 4 0 -.719 .695 C4 +% ... +% '.asc', '.dat': +% Neuroscan-.'asc' or '.dat' Cartesian polar coordinates text file. +% '.mat': +% Brainstrom channel location file. +% '.sfp': +% BESA/EGI-xyz Cartesian coordinates. Notes: For EGI, x is toward right ear, +% y is toward the nose, z is toward the vertex. EEGLAB converts EGI +% Cartesian coordinates to Matlab/EEGLAB xyz coordinates. +% Fields: label x y z +% Sample: Fp1 -.308 .950 -.035 +% Fp2 .308 .950 -.035 +% C3 -.719 0 .695 +% C4 .719 0 .695 +% ... +% '.ced': +% ASCII file saved by pop_chanedit(). Contains multiple MATLAB/EEGLAB formats. +% Cartesian coordinates are as in the 'xyz' format (above). +% Fields: channum label theta radius x y z sph_theta sph_phi ... +% Sample: 1 Fp1 -18 .511 .950 .308 -.035 18 -2 ... +% 2 Fp2 18 .511 .950 -.308 -.035 -18 -2 ... +% 3 C3 -90 .256 0 .719 .695 90 44 ... +% 4 C4 90 .256 0 -.719 .695 -90 44 ... +% ... +% The last columns of the file may contain any other defined fields (gain, +% calib, type, custom). +% +% Fieldtrip structure: +% If a Fieltrip structure is given as input, an EEGLAB +% chanlocs structure is returned +% Brainstrom Matlab file: +% If a Brainstrom Matlab file is given as input, an EEGLAB +% chanlocs structure is returned +% +% Author: Arnaud Delorme, Salk Institute, 8 Dec 2002 +% +% See also: readelp(), writelocs(), topo2sph(), sph2topo(), sph2cart() + +% Copyright (C) Arnaud Delorme, CNL / Salk Institute, 28 Feb 2002 +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + + +function [eloc, labels, theta, radius, indices] = readlocs( filename, varargin ); + +if nargin < 1 + help readlocs; + return; +end + +% NOTE: To add a new channel format: +% ---------------------------------- +% 1) Add a new element to the structure 'chanformat' (see 'ADD NEW FORMATS HERE' below): +% 2) Enter a format 'type' for the new file format, +% 3) Enter a (short) 'typestring' description of the format +% 4) Enter a longer format 'description' (possibly multiline, see ex. (1) below) +% 5) Enter format file column labels in the 'importformat' field (see ex. (2) below) +% 6) Enter the number of header lines to skip (if any) in the 'skipline' field +% 7) Document the new channel format in the help message above. +% 8) After testing, please send the new version of readloca.m to us +% at eeglab@sccn.ucsd.edu with a sample locs file. +% The 'chanformat' structure is also used (automatically) by the writelocs() +% and pop_readlocs() functions. You do not need to edit these functions. + +chanformat(1).type = 'polhemus'; +chanformat(1).typestring = 'Polhemus native .elp file'; +chanformat(1).description = [ 'Polhemus native coordinate file containing scanned electrode positions. ' ... + 'User must select the direction ' ... + 'for the nose after importing the data file.' ]; +chanformat(1).importformat = 'readelp() function'; +% --------------------------------------------------------------------------------------------------- +chanformat(2).type = 'besa'; +chanformat(2).typestring = 'BESA spherical .elp file'; +chanformat(2).description = [ 'BESA spherical coordinate file. Note that BESA spherical coordinates ' ... + 'are different from Matlab spherical coordinates' ]; +chanformat(2).skipline = 0; % some BESA files do not have headers +chanformat(2).importformat = { 'type' 'labels' 'sph_theta_besa' 'sph_phi_besa' 'sph_radius' }; +% --------------------------------------------------------------------------------------------------- +chanformat(3).type = 'xyz'; +chanformat(3).typestring = 'Matlab .xyz file'; +chanformat(3).description = [ 'Standard 3-D cartesian coordinate files with electrode numbers in ' ... + 'the first column and X, Y, and Z coordinates in columns 2, 3, and 4' ... + ' and channel labels in column 5' ]; +chanformat(3).importformat = { 'channum' '-Y' 'X' 'Z' 'labels'}; +% --------------------------------------------------------------------------------------------------- +chanformat(4).type = 'sfp'; +chanformat(4).typestring = 'BESA or EGI 3-D cartesian .sfp file'; +chanformat(4).description = [ 'Standard BESA 3-D cartesian coordinate files with electrode labels in ' ... + 'the first column and X, Y, and Z coordinates in columns 2, 3, and 4.' ... + 'Coordinates are re-oriented to fit the EEGLAB standard of having the ' ... + 'nose along the +X axis.' ]; +chanformat(4).importformat = { 'labels' '-Y' 'X' 'Z' }; +chanformat(4).skipline = 0; +% --------------------------------------------------------------------------------------------------- +chanformat(5).type = 'loc'; +chanformat(5).typestring = 'EEGLAB polar .loc file'; +chanformat(5).description = [ 'EEGLAB polar .loc file' ]; +chanformat(5).importformat = { 'channum' 'theta' 'radius' 'labels' }; +% --------------------------------------------------------------------------------------------------- +chanformat(6).type = 'sph'; +chanformat(6).typestring = 'Matlab .sph spherical file'; +chanformat(6).description = [ 'Standard 3-D spherical coordinate files in Matlab format' ]; +chanformat(6).importformat = { 'channum' 'sph_theta' 'sph_phi' 'labels' }; +% --------------------------------------------------------------------------------------------------- +chanformat(7).type = 'asc'; +chanformat(7).typestring = 'Neuroscan polar .asc file'; +chanformat(7).description = [ 'Neuroscan polar .asc file, automatically recentered to fit EEGLAB standard' ... + 'of having ''Cz'' at (0,0).' ]; +chanformat(7).importformat = 'readneurolocs'; +% --------------------------------------------------------------------------------------------------- +chanformat(8).type = 'dat'; +chanformat(8).typestring = 'Neuroscan 3-D .dat file'; +chanformat(8).description = [ 'Neuroscan 3-D cartesian .dat file. Coordinates are re-oriented to fit ' ... + 'the EEGLAB standard of having the nose along the +X axis.' ]; +chanformat(8).importformat = 'readneurolocs'; +% --------------------------------------------------------------------------------------------------- +chanformat(9).type = 'elc'; +chanformat(9).typestring = 'ASA .elc 3-D file'; +chanformat(9).description = [ 'ASA .elc 3-D coordinate file containing scanned electrode positions. ' ... + 'User must select the direction ' ... + 'for the nose after importing the data file.' ]; +chanformat(9).importformat = 'readeetraklocs'; +% --------------------------------------------------------------------------------------------------- +chanformat(10).type = 'chanedit'; +chanformat(10).typestring = 'EEGLAB complete 3-D file'; +chanformat(10).description = [ 'EEGLAB file containing polar, cartesian 3-D, and spherical 3-D ' ... + 'electrode locations.' ]; +chanformat(10).importformat = { 'channum' 'labels' 'theta' 'radius' 'X' 'Y' 'Z' 'sph_theta' 'sph_phi' ... + 'sph_radius' 'type' }; +chanformat(10).skipline = 1; +% --------------------------------------------------------------------------------------------------- +chanformat(11).type = 'tsv'; +chanformat(11).typestring = 'BIDS .tsv file'; +chanformat(11).description = [ 'Standard 3-D cartesian coordinate files with electrode labels in ' ... + 'the first column and X, Y, and Z coordinates in columns 2, 3, and 4' ]; +chanformat(11).importformat = { 'labels' 'X' 'Y' 'Z' }; +chanformat(11).skipline = 1; +% --------------------------------------------------------------------------------------------------- +chanformat(12).type = 'mat'; +chanformat(12).typestring = 'Brainstorm Matlab file format'; +chanformat(12).description = 'Custom Matlab file.'; +chanformat(12).importformat = ''; +% --------------------------------------------------------------------------------------------------- +chanformat(13).type = 'custom'; +chanformat(13).typestring = 'Custom file format'; +chanformat(13).description = 'Custom ASCII file format where user can define content for each file columns.'; +chanformat(13).importformat = ''; +% --------------------------------------------------------------------------------------------------- +% ----- ADD MORE FORMATS HERE ----------------------------------------------------------------------- +% --------------------------------------------------------------------------------------------------- + +listcolformat = { 'labels' 'channum' 'theta' 'radius' 'sph_theta' 'sph_phi' ... + 'sph_radius' 'sph_theta_besa' 'sph_phi_besa' 'gain' 'calib' 'type' ... + 'X' 'Y' 'Z' '-X' '-Y' '-Z' 'custom1' 'custom2' 'custom3' 'custom4' 'ignore' 'not def' }; + +% ---------------------------------- +% special mode for getting the info +% ---------------------------------- +if ischar(filename) && strcmp(filename, 'getinfos') + eloc = chanformat; + labels = listcolformat; + return; +end + +g = finputcheck( varargin, ... + { 'filetype' 'string' {} ''; + 'importmode' 'string' { 'eeglab','native' } 'eeglab'; + 'defaultelp' 'string' { 'besa','polhemus' } 'polhemus'; + 'skiplines' 'integer' [0 Inf] []; + 'elecind' 'integer' [1 Inf] []; + 'format' 'cell' [] {} }, 'readlocs'); +if ischar(g), error(g); end +if ~isempty(g.format), g.filetype = 'custom'; end + +if ischar(filename) + + % format auto detection + % -------------------- + if strcmpi(g.filetype, 'autodetect'), g.filetype = ''; end + g.filetype = strtok(g.filetype); + [~,~,fileextension] = fileparts(filename); + fileextension = fileextension(2:end); + g.filetype = lower(g.filetype); + if isempty(g.filetype) + switch lower(fileextension) + case {'loc' 'locs' 'eloc'}, g.filetype = 'loc'; % 5/27/2014 Ramon: 'eloc' option introduced. + case 'xyz', g.filetype = 'xyz'; + fprintf( [ 'WARNING: Matlab Cartesian coord. file extension (".xyz") detected.\n' ... + 'If importing EGI Cartesian coords, force type "sfp" instead.\n'] ); + case 'sph', g.filetype = 'sph'; + case 'ced', g.filetype = 'chanedit'; + case 'elp', g.filetype = g.defaultelp; + case 'asc', g.filetype = 'asc'; + case 'dat', g.filetype = 'dat'; + case 'elc', g.filetype = 'elc'; + case 'eps', g.filetype = 'besa'; + case 'sfp', g.filetype = 'sfp'; + case 'tsv', g.filetype = 'tsv'; + case 'mat', g.filetype = 'mat'; + otherwise, g.filetype = ''; + end + fprintf('readlocs(): ''%s'' format assumed from file extension\n', g.filetype); + else + if strcmpi(g.filetype, 'locs'), g.filetype = 'loc'; end + if strcmpi(g.filetype, 'eloc'), g.filetype = 'loc'; end + end + + % assign format from filetype + % --------------------------- + if ~isempty(g.filetype) && ~strcmpi(g.filetype, 'custom') ... + & ~strcmpi(g.filetype, 'asc') & ~strcmpi(g.filetype, 'elc') & ~strcmpi(g.filetype, 'dat') + indexformat = strmatch(lower(g.filetype), { chanformat.type }, 'exact'); + g.format = chanformat(indexformat).importformat; + if isempty(g.skiplines) + g.skiplines = chanformat(indexformat).skipline; + end + if isempty(g.filetype) + error( ['readlocs() error: The filetype cannot be detected from the \n' ... + ' file extension, and custom format not specified']); + end + end + + % import file + % ----------- + if strcmp(g.filetype, 'mat') + elocBrainstrom = load('-mat', filename ); + for iChan = 1:length(elocBrainstrom.Channel) + eloc(iChan).labels = elocBrainstrom.Channel(iChan).Name; + eloc(iChan).X = elocBrainstrom.Channel(iChan).Loc(1); + eloc(iChan).Y = elocBrainstrom.Channel(iChan).Loc(2); + eloc(iChan).Z = elocBrainstrom.Channel(iChan).Loc(3); + eloc(iChan).type = elocBrainstrom.Channel(iChan).Type; + end + if isfield(elocBrainstrom, 'SCS') + chans = { 'NAS' 'LPA' 'RPA' }; + for iChan = 1:length(chans) + if isfield(elocBrainstrom.SCS, chans{iChan}) + eloc(end+1).labels = chans{iChan}; + eloc(end).X = elocBrainstrom.SCS.(chans{iChan})(1); + eloc(end).Y = elocBrainstrom.SCS.(chans{iChan})(2); + eloc(end).Z = elocBrainstrom.SCS.(chans{iChan})(3); + eloc(end).type = elocBrainstrom.Channel(iChan).Type; + end + end + end + elseif strcmp(g.filetype, 'asc') || strcmp(g.filetype, 'dat') + eloc = readneurolocs( filename ); + eloc = rmfield(eloc, 'sph_theta'); % for the conversion below + eloc = rmfield(eloc, 'sph_theta_besa'); % for the conversion below + if isfield(eloc, 'type') + for index = 1:length(eloc) + eloc(index).labels = strtrim(eloc(index).labels); + type = eloc(index).type; + if type == 69, eloc(index).type = 'EEG'; + elseif type == 88, eloc(index).type = 'REF'; + elseif type >= 76 && type <= 82, eloc(index).type = 'FID'; + else eloc(index).type = num2str(eloc(index).type); + end + end + end + elseif strcmp(g.filetype, 'elc') + eloc = readeetraklocs( filename ); + %eloc = read_asa_elc( filename ); % from fieldtrip + %eloc = struct('labels', eloc.label, 'X', mattocell(eloc.pnt(:,1)'), 'Y', ... + % mattocell(eloc.pnt(:,2)'), 'Z', mattocell(eloc.pnt(:,3)')); + eloc = convertlocs(eloc, 'cart2all'); + eloc = rmfield(eloc, 'sph_theta'); % for the conversion below + eloc = rmfield(eloc, 'sph_theta_besa'); % for the conversion below + elseif strcmp(lower(g.filetype(1:end-1)), 'polhemus') || ... + strcmp(g.filetype, 'polhemus') + try, + [eloc labels X Y Z]= readelp( filename ); + if strcmp(g.filetype, 'polhemusy') + tmp = X; X = Y; Y = tmp; + end + for index = 1:length( eloc ) + eloc(index).X = X(index); + eloc(index).Y = Y(index); + eloc(index).Z = Z(index); + end + catch, + disp('readlocs(): Could not read Polhemus coords. Trying to read BESA .elp file.'); + [eloc, labels, theta, radius, indices] = readlocs( filename, 'defaultelp', 'besa', varargin{:} ); + end + else + % importing file + % -------------- + if isempty(g.skiplines), g.skiplines = 0; end + if strcmpi(g.filetype, 'chanedit') + array = loadtxt( filename, 'delim', 9, 'skipline', g.skiplines, 'blankcell', 'off'); + else + array = load_file_or_array( filename, g.skiplines); + end + if size(array,2) < length(g.format) + fprintf(['readlocs() warning: Fewer columns in the input than expected.\n' ... + ' See >> help readlocs\n']); + elseif size(array,2) > length(g.format) + fprintf(['readlocs() warning: More columns in the input than expected.\n' ... + ' See >> help readlocs\n']); + end + + % removing lines BESA + % ------------------- + if isempty(array{1,2}) + disp('BESA header detected, skipping three lines...'); + array = load_file_or_array( filename, g.skiplines-1); + if isempty(array{1,2}) + array = load_file_or_array( filename, g.skiplines-1); + end + end + + % xyz format, is the first col absent + % ----------------------------------- + if strcmp(g.filetype, 'xyz') + if size(array, 2) == 4 + array(:, 2:5) = array(:, 1:4); + end + end + + % removing comments and empty lines + % --------------------------------- + indexbeg = 1; + while isempty(array{indexbeg,1}) || ... + (ischar(array{indexbeg,1}) && array{indexbeg,1}(1) == '%' ) + indexbeg = indexbeg+1; + end + array = array(indexbeg:end,:); + + % converting file + % --------------- + for indexcol = 1:min(size(array,2), length(g.format)) + [str, mult] = checkformat(g.format{indexcol}); + for indexrow = 1:size( array, 1) + if mult ~= 1 + eval ( [ 'eloc(indexrow).' str '= -array{indexrow, indexcol};' ]); + else + eval ( [ 'eloc(indexrow).' str '= array{indexrow, indexcol};' ]); + end + end + end + end + + % handling BESA coordinates + % ------------------------- + if isfield(eloc, 'sph_theta_besa') + if isfield(eloc, 'type') + if isnumeric(eloc(1).type) + disp('BESA format detected ( Theta | Phi )'); + for index = 1:length(eloc) + eloc(index).sph_phi_besa = eloc(index).labels; + eloc(index).sph_theta_besa = eloc(index).type; + eloc(index).labels = ''; + eloc(index).type = ''; + end + eloc = rmfield(eloc, 'labels'); + end + end + if isfield(eloc, 'labels') + if isnumeric(eloc(1).labels) + disp('BESA format detected ( Elec | Theta | Phi )'); + for index = 1:length(eloc) + eloc(index).sph_phi_besa = eloc(index).sph_theta_besa; + eloc(index).sph_theta_besa = eloc(index).labels; + eloc(index).labels = eloc(index).type; + eloc(index).type = ''; + eloc(index).radius = 1; + end; + end + end + + try + eloc = convertlocs(eloc, 'sphbesa2all'); + eloc = convertlocs(eloc, 'topo2all'); % problem with some EGI files (not BESA files) + catch, disp('Warning: coordinate conversion failed'); end + fprintf('Readlocs: BESA spherical coords. converted, now deleting BESA fields\n'); + fprintf(' to avoid confusion (these fields can be exported, though)\n'); + eloc = rmfield(eloc, 'sph_phi_besa'); + eloc = rmfield(eloc, 'sph_theta_besa'); + + % converting XYZ coordinates to polar + % ----------------------------------- + elseif isfield(eloc, 'sph_theta') && any(~cellfun(@isempty, { eloc.sph_theta })) + try + eloc = convertlocs(eloc, 'sph2all'); + catch, disp('Warning: coordinate conversion failed'); end + elseif isfield(eloc, 'X') + try + eloc = convertlocs(eloc, 'cart2all'); + catch, disp('Warning: coordinate conversion failed'); end + else + try + eloc = convertlocs(eloc, 'topo2all'); + catch, disp('Warning: coordinate conversion failed'); end + end + + % inserting labels if no labels + % ----------------------------- + if ~isfield(eloc, 'labels') + fprintf('readlocs(): Inserting electrode labels automatically.\n'); + for index = 1:length(eloc) + eloc(index).labels = [ 'E' int2str(index) ]; + end + else + % remove trailing '.' + for index = 1:length(eloc) + if ischar(eloc(index).labels) + tmpdots = find( eloc(index).labels == '.' ); + eloc(index).labels(tmpdots) = []; + end + end + end + + % resorting electrodes if number not-sorted + % ----------------------------------------- + if isfield(eloc, 'channum') + if ~isnumeric(eloc(1).channum) + error('Channel numbers must be numeric'); + end + allchannum = [ eloc.channum ]; + if any( sort(allchannum) ~= allchannum ) + fprintf('readlocs(): Re-sorting channel numbers based on ''channum'' column indices\n'); + [tmp newindices] = sort(allchannum); + eloc = eloc(newindices); + end + eloc = rmfield(eloc, 'channum'); + end +else + if isstruct(filename) + % detect Fieldtrip structure and convert it + % ----------------------------------------- + if isfield(filename, 'pnt') + neweloc = []; + for index = 1:length(filename.label) + neweloc(index).labels = filename.label{index}; + neweloc(index).X = filename.pnt(index,1); + neweloc(index).Y = filename.pnt(index,2); + neweloc(index).Z = filename.pnt(index,3); + end + eloc = neweloc; + eloc = convertlocs(eloc, 'cart2all'); + else + eloc = filename; + end + else + disp('readlocs(): input variable must be a string or a structure'); + end; +end +if ~isempty(g.elecind) + eloc = eloc(g.elecind); +end +if nargout > 2 + if isfield(eloc, 'theta') + tmptheta = { eloc.theta }; % check which channels have (polar) coordinates set + else tmptheta = cell(1,length(eloc)); + end + if isfield(eloc, 'theta') + tmpx = { eloc.X }; % check which channels have (polar) coordinates set + else tmpx = cell(1,length(eloc)); + end + + indices = find(~cellfun('isempty', tmptheta)); + indices = intersect_bc(find(~cellfun('isempty', tmpx)), indices); + indices = sort(indices); + + indbad = setdiff_bc(1:length(eloc), indices); + tmptheta(indbad) = { NaN }; + theta = [ tmptheta{:} ]; +end +if nargout > 3 + if isfield(eloc, 'theta') + tmprad = { eloc.radius }; % check which channels have (polar) coordinates set + else tmprad = cell(1,length(eloc)); + end + tmprad(indbad) = { NaN }; + radius = [ tmprad{:} ]; +end + +%tmpnum = find(~cellfun('isclass', { eloc.labels }, 'char')); +%disp('Converting channel labels to string'); +for index = 1:length(eloc) + if ~ischar(eloc(index).labels) + eloc(index).labels = int2str(eloc(index).labels); + end +end +labels = { eloc.labels }; +if isfield(eloc, 'ignore') + eloc = rmfield(eloc, 'ignore'); +end + +% process fiducials if any +% ------------------------ +fidnames = { 'nz' 'lpa' 'rpa' 'nasion' 'left' 'right' 'nazion' 'fidnz' 'fidt9' 'fidt10' 'cms' 'drl' 'nas' 'lht' 'rht' 'lhj' 'rhj' }; +for index = 1:length(fidnames) + ind = strmatch(fidnames{index}, lower(labels), 'exact'); + if ~isempty(ind), eloc(ind).type = 'FID'; end +end + +return; + +% interpret the variable name +% --------------------------- +function array = load_file_or_array( varname, skiplines ); + if isempty(skiplines), + skiplines = 0; + end + if exist( varname ) == 2 + array = loadtxt(varname,'verbose','off','skipline',skiplines,'blankcell','off'); + else % variable in the global workspace + % -------------------------- + try, array = evalin('base', varname); + catch, error('readlocs(): cannot find the named file or variable, check syntax'); + end + end; +return; + +% check field format +% ------------------ +function [str, mult] = checkformat(str) + mult = 1; + if strcmpi(str, 'labels'), str = lower(str); return; end + if strcmpi(str, 'channum'), str = lower(str); return; end + if strcmpi(str, 'theta'), str = lower(str); return; end + if strcmpi(str, 'radius'), str = lower(str); return; end + if strcmpi(str, 'ignore'), str = lower(str); return; end + if strcmpi(str, 'sph_theta'), str = lower(str); return; end + if strcmpi(str, 'sph_phi'), str = lower(str); return; end + if strcmpi(str, 'sph_radius'), str = lower(str); return; end + if strcmpi(str, 'sph_theta_besa'), str = lower(str); return; end + if strcmpi(str, 'sph_phi_besa'), str = lower(str); return; end + if strcmpi(str, 'gain'), str = lower(str); return; end + if strcmpi(str, 'calib'), str = lower(str); return; end + if strcmpi(str, 'type') , str = lower(str); return; end + if strcmpi(str, 'X'), str = upper(str); return; end + if strcmpi(str, 'Y'), str = upper(str); return; end + if strcmpi(str, 'Z'), str = upper(str); return; end + if strcmpi(str, '-X'), str = upper(str(2:end)); mult = -1; return; end + if strcmpi(str, '-Y'), str = upper(str(2:end)); mult = -1; return; end + if strcmpi(str, '-Z'), str = upper(str(2:end)); mult = -1; return; end + if strcmpi(str, 'custom1'), return; end + if strcmpi(str, 'custom2'), return; end + if strcmpi(str, 'custom3'), return; end + if strcmpi(str, 'custom4'), return; end + error(['readlocs(): undefined field ''' str '''']); + \ No newline at end of file diff --git a/studio_functions/Functions/EEGLAB/Scalp/setdiff_bc.m b/studio_functions/Functions/EEGLAB/Scalp/setdiff_bc.m new file mode 100755 index 00000000..ded42e8d --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/setdiff_bc.m @@ -0,0 +1,56 @@ +% setdiff_bc - setdiff backward compatible with Matlab versions prior to 2013a + +% Copyright (C) 2013 Arnaud Delorme +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [C,IA] = setdiff_bc(A,B,varargin) + +errorFlag = error_bc; + +v = version; +indp = find(v == '.'); +v = str2num(v(1:indp(2)-1)); +if v > 7.19, v = floor(v) + rem(v,1)/10; end + +if nargin > 2 + ind = strmatch('legacy', varargin); + if ~isempty(ind) + varargin(ind) = []; + end +end + +if v >= 7.14 + [C,IA] = setdiff(A,B,varargin{:},'legacy'); + if errorFlag + [C2,IA2] = setdiff(A,B,varargin{:}); + if (~isequal(C, C2) || ~isequal(IA, IA2)) + warning('backward compatibility issue with call to setdiff function'); + end + end +else + [C,IA] = setdiff(A,B,varargin{:}); +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/sph2topo.m b/studio_functions/Functions/EEGLAB/Scalp/sph2topo.m new file mode 100755 index 00000000..b32e46cf --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/sph2topo.m @@ -0,0 +1,105 @@ +% sph2topo() - Convert from a 3-column headplot file in spherical coordinates +% to 3-column topoplot() locs file in polar (not cylindrical) coords. +% Used for topoplot() and other 2-D topographic plotting programs. +% Assumes a spherical coordinate system in which horizontal angles +% have a range [-180,180] deg, with zero pointing to the right ear. +% In the output polar coordinate system, zero points to the nose. +% See >> help readlocs +% Usage: +% >> [chan_num,angle,radius] = sph2topo(input,shrink_factor,method); +% +% Inputs: +% input = [channo,az,horiz] = chan_number, azumith (deg), horiz. angle (deg) +% When az>0, horiz=0 -> right ear, 90 -> nose +% When az<0, horiz=0 -> left ear, -90 -> nose +% shrink_factor = arc_length shrinking factor>=1 (deprecated). +% 1 -> plot edge is 90 deg azimuth {default}; +% 1.5 -> plot edge is +/-135 deg azimuth See +% >> help topoplot(). +% method = [1|2], optional. 1 is for Besa compatibility, 2 is for +% compatibility with Matlab function cart2sph(). Default is 2 +% +% Outputs: +% channo = channel number (as in input) +% angle = horizontal angle (0 -> nose; 90 -> right ear; -90 -> left ear) +% radius = arc_lengrh from vertex (Note: 90 deg az -> 0.5/shrink_factor); +% By topoplot() convention, radius=0.5 is the nasion-ear_canal plane. +% Use topoplot() 'plotrad' to plot chans with abs(az) > 90 deg. +% +% Author: Scott Makeig & Arnaud Delorme, SCCN/INC/UCSD, La Jolla, 6/12/98 +% +% See also: cart2topo(), topo2sph() + +% Copyright (C) 6/12/98 Scott Makeig, SCCN/INC/UCSD, scott@sccn.ucsd.edu +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% corrected left/right orientation mismatch, Blair Hicks 6/20/98 +% changed name sph2pol() -> sph2topo() for compatibility -sm +% 01-25-02 reformated help & license -ad +% 01-25-02 changed computation so that it works with sph2topo -ad + +function [channo,angle,radius] = sph2topo(input,factor, method) + +chans = size(input,1); +angle = zeros(chans,1); +radius = zeros(chans,1); + +if nargin < 1 + help sph2topo + return +end + +if nargin< 2 + factor = 0; +end +if factor==0 + factor = 1; +end +if factor < 1 + help sph2topo + return +end + +if size(input,2) ~= 3 + help sph2topo + return +end + +channo = input(:,1); +az = input(:,2); +horiz = input(:,3); + +if exist('method')== 1 && method == 1 + radius = abs(az/180)/factor; + i = find(az>=0); + angle(i) = 90-horiz(i); + i = find(az<0); + angle(i) = -90-horiz(i); +else + angle = -horiz; + radius = 0.5 - az/180; +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/topoplot.m b/studio_functions/Functions/EEGLAB/Scalp/topoplot.m new file mode 100755 index 00000000..e6ef4da2 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/topoplot.m @@ -0,0 +1,1728 @@ +% topoplot() - plot a topographic map of a scalp data field in a 2-D circular view +% (looking down at the top of the head) using interpolation on a fine +% cartesian grid. Can also show specified channel location(s), or return +% an interpolated value at an arbitrary scalp location (see 'noplot'). +% By default, channel locations below head center (arc_length 0.5) are +% shown in a 'skirt' outside the cartoon head (see 'plotrad' and 'headrad' +% options below). Nose is at top of plot; left is left; right is right. +% Using option 'plotgrid', the plot may be one or more rectangular grids. +% Usage: +% >> topoplot(datavector, EEG.chanlocs); % plot a map using an EEG chanlocs structure +% >> topoplot(datavector, 'my_chan.locs'); % read a channel locations file and plot a map +% >> topoplot('example'); % give an example of an electrode location file +% >> [h grid_or_val plotrad_or_grid, xmesh, ymesh]= ... +% topoplot(datavector, chan_locs, 'Input1','Value1', ...); +% Required Inputs: +% datavector - single vector of channel values. Else, if a vector of selected subset +% (int) channel numbers -> mark their location(s) using 'style' 'blank'. +% chan_locs - name of an EEG electrode position file (>> topoplot example). +% Else, an EEG.chanlocs structure (>> help readlocs or >> topoplot example) +% Optional inputs: +% 'maplimits' - 'absmax' -> scale map colors to +/- the absolute-max (makes green 0); +% 'maxmin' -> scale colors to the data range (makes green mid-range); +% [lo.hi] -> use user-definined lo/hi limits +% {default: 'absmax'} +% 'style' - 'map' -> plot colored map only +% 'contour' -> plot contour lines only +% 'both' -> plot both colored map and contour lines +% 'fill' -> plot constant color between contour lines +% 'blank' -> plot electrode locations only {default: 'both'} +% 'electrodes' - 'on','off','labels','numbers','ptslabels','ptsnumbers'. To set the 'pts' +% marker,,see 'Plot detail options' below. {default: 'on' -> mark electrode +% locations with points ('.') unless more than 64 channels, then 'off'}. +% 'plotchans' - [vector] channel numbers (indices) to use in making the head plot. +% {default: [] -> plot all chans} +% 'plotgrid' - [channels] Plot channel data in one or more rectangular grids, as +% specified by [channels], a position matrix of channel numbers defining +% the topographic locations of the channels in the +% grid. Zero values are ignored (given the figure background color); +% negative integers, the color of the polarity-reversed channel values. +% Ex: >> figure; ... +% >> topoplot(values,'chanlocs','plotgrid',[11 12 0; 13 14 15]); +% % Plot a (2,3) grid of data values from channels 11-15 with one empty +% grid cell (top right) {default: no grid plot} +% 'nosedir' - ['+X'|'-X'|'+Y'|'-Y'] direction of nose {default: '+X'} +% 'chaninfo' - [struct] optional structure containing fields 'nosedir', 'plotrad'. +% See these (separate) field definitions above, below. +% {default: nosedir +X, plotrad 0.5, all channels} +% 'plotrad' - [0.15<=float<=1.0] plotting radius = max channel arc_length to plot. +% See >> topoplot example. If plotrad > 0.5, chans with arc_length > 0.5 +% (i.e. below ears-eyes) are plotted in a circular 'skirt' outside the +% cartoon head. See 'intrad' below. {default: max(max(chanlocs.radius),0.5); +% If the chanlocs structure includes a field chanlocs.plotrad, its value +% is used by default}. +% 'headrad' - [0.15<=float<=1.0] drawing radius (arc_length) for the cartoon head. +% NOTE: Only headrad = 0.5 is anatomically correct! 0 -> don't draw head; +% 'rim' -> show cartoon head at outer edge of the plot {default: 0.5} +% 'intrad' - [0.15<=float<=1.0] radius of the scalp map interpolation area (square or +% disk, see 'intsquare' below). Interpolate electrodes in this area and use +% this limit to define boundaries of the scalp map interpolated data matrix +% {default: max channel location radius} +% 'intsquare' - ['on'|'off'] 'on' -> Interpolate values at electrodes located in the whole +% square containing the (radius intrad) interpolation disk; 'off' -> Interpolate +% values from electrodes shown in the interpolation disk only {default: 'on'}. +% 'conv' - ['on'|'off'] Show map interpolation only out to the convext hull of +% the electrode locations to minimize extrapolation. Use this option ['on'] when +% plotting pvalues {default: 'off'}. When plotting pvalues in totoplot, set +% 'conv' option to 'on' to minimize interpolation effects +% 'noplot' - ['on'|'off'|[rad theta]] do not plot (but return interpolated data). +% Else, if [rad theta] are coordinates of a (possibly missing) channel, +% returns interpolated value for channel location. For more info, +% see >> topoplot 'example' {default: 'off'} +% 'verbose' - ['on'|'off'] comment on operations on command line {default: 'on'}. +% 'chantype' - deprecated +% +% Plot detail options: +% 'drawaxis' - ['on'|'off'] draw axis on the top left corner. +% 'emarker' - Matlab marker char | {markerchar color size linewidth} char, else cell array +% specifying the electrode 'pts' marker. Ex: {'s','r',32,1} -> 32-point solid +% red square. {default: {'.','k',[],1} where marker size ([]) depends on the number +% of channels plotted}. +% 'emarker2' - {markchans}|{markchans marker color size linewidth} cell array specifying +% an alternate marker for specified 'plotchans'. Ex: {[3 17],'s','g'} +% {default: none, or if {markchans} only are specified, then {markchans,'o','r',10,1}} +% 'hcolor' - color of the cartoon head. Use 'hcolor','none' to plot no head. {default: 'k' = black} +% 'shading' - 'flat','interp' {default: 'flat'} +% 'numcontour' - number of contour lines {default: 6}. You may also enter a vector to set contours +% at specified values. +% 'contourvals' - values for contour {default: same as input values} +% 'pmask' - values for masking topoplot. Array of zeros and 1 of the same size as the input +% value array {default: []} +% 'color' - color of the contours {default: dark grey} +% 'whitebk ' - ('on'|'off') make the background color white (e.g., to print empty plotgrid channels) +% {default: 'off'} +% 'gridscale' - [int > 32] size (nrows) of interpolated scalp map data matrix {default: 67} +% 'colormap' - (n,3) any size colormap {default: existing colormap} +% 'circgrid' - [int > 100] number of elements (angles) in head and border circles {201} +% 'emarkercolor' - cell array of colors for 'blank' option. +% 'plotdisk' - ['on'|'off'] plot disk instead of dots for electrodefor 'blank' option. Size of disk +% is controlled by input values at each electrode. If an imaginary value is provided, +% plot partial circle with red for the real value and blue for the imaginary one. +% +% Dipole plotting options: +% 'dipole' - [xi yi xe ye ze] plot dipole on the top of the scalp map +% from coordinate (xi,yi) to coordinates (xe,ye,ze) (dipole head +% model has radius 1). If several rows, plot one dipole per row. +% Coordinates returned by dipplot() may be used. Can accept +% an EEG.dipfit.model structure (See >> help dipplot). +% Ex: ,'dipole',EEG.dipfit.model(17) % Plot dipole(s) for comp. 17. +% 'dipnorm' - ['on'|'off'] normalize dipole length {default: 'on'}. +% 'diporient' - [-1|1] invert dipole orientation {default: 1}. +% 'diplen' - [real] scale dipole length {default: 1}. +% 'dipscale' - [real] scale dipole size {default: 1}. +% 'dipsphere' - [real] size of the dipole sphere. {default: 85 mm}. +% 'dipcolor' - [color] dipole color as Matlab code code or [r g b] vector +% {default: 'k' = black}. +% Outputs: +% handle - handle of the colored surface.If +% contour only is plotted, then is the handle of +% the countourgroup. (If no surface or contour is plotted, +% return "gca", the handle of the current plot) +% grid_or_val - [matrix] the interpolated data image (with off-head points = NaN). +% Else, single interpolated value at the specified 'noplot' arg channel +% location ([rad theta]), if any. +% plotrad_or_grid - IF grid image returned above, then the 'plotrad' radius of the grid. +% Else, the grid image +% xmesh, ymesh - x and y values of the returned grid (above) +% +% Chan_locs format: +% See >> topoplot 'example' +% +% Examples: +% +% To plot channel locations only: +% >> figure; topoplot([],EEG.chanlocs,'style','blank','electrodes','labelpoint','chaninfo',EEG.chaninfo); +% +% Notes: - To change the plot map masking ring to a new figure background color, +% >> set(findobj(gca,'type','patch'),'facecolor',get(gcf,'color')) +% - Topoplots may be rotated. From the commandline >> view([deg 90]) {default: [0 90]) +% - When plotting pvalues make sure to use the option 'conv' to minimize extrapolation effects +% +% Authors: Andy Spydell, Colin Humphries, Arnaud Delorme & Scott Makeig +% CNL / Salk Institute, 8/1996-/10/2001; SCCN/INC/UCSD, Nov. 2001 - +% +% See also: timtopo(), envtopo() + +% Deprecated options: +% 'shrink' - ['on'|'off'|'force'|factor] Deprecated. 'on' -> If max channel arc_length +% > 0.5, shrink electrode coordinates towards vertex to plot all channels +% by making max arc_length 0.5. 'force' -> Normalize arc_length +% so the channel max is 0.5. factor -> Apply a specified shrink +% factor (range (0,1) = shrink fraction). {default: 'off'} +% 'electcolor' {'k'} ... electrode marking details and their {defaults}. +% 'emarker' {'.'}|'emarkersize' {14}|'emarkersizemark' {40}|'efontsize' {var} - +% electrode marking details and their {defaults}. +% 'ecolor' - color of the electrode markers {default: 'k' = black} +% 'interplimits' - ['electrodes'|'head'] 'electrodes'-> interpolate the electrode grid; +% 'head'-> interpolate the whole disk {default: 'head'}. + +% Unimplemented future options: + +% Copyright (C) Colin Humphries & Scott Makeig, CNL / Salk Institute, Aug, 1996 +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +% Topoplot Version 2.1 +% Early development history: +% Begun by Andy Spydell and Scott Makeig, NHRC, 7-23-96 +% 8-96 Revised by Colin Humphries, CNL / Salk Institute, La Jolla CA +% -changed surf command to imagesc (faster) +% -can now handle arbitrary scaling of electrode distances +% -can now handle non integer angles in chan_locs +% 4-4-97 Revised again by Colin Humphries, reformatted by SM +% -added parameters +% -changed chan_locs format +% 2-26-98 Revised by Colin +% -changed image back to surface command +% -added fill and blank styles +% -removed extra background colormap entry (now use any colormap) +% -added parameters for electrode colors and labels +% -now each topoplot axes use the caxis command again. +% -removed OUTPUT parameter +% 3-11-98 changed default emarkersize, improve help msg -sm +% 5-24-01 made default emarkersize vary with number of channels -sm +% 01-25-02 reformated help & license, added link -ad +% 03-15-02 added readlocs and the use of eloc input structure -ad +% 03-25-02 added 'labelpoint' options and allow Values=[] -ad &sm +% 03-25-02 added details to "Unknown parameter" warning -sm & ad + +function [handle,Zi,grid,Xi,Yi] = topoplot(Values,loc_file,varargin) + +% +%%%%%%%%%%%%%%%%%%%%%%%% Set defaults %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +icadefs % read defaults MAXTOPOPLOTCHANS and DEFAULT_ELOC and BACKCOLOR +if ~exist('BACKCOLOR') % if icadefs.m does not define BACKCOLOR + BACKCOLOR = [.93 .96 1]; % EEGLAB standard +end +whitebk = 'off'; % by default, make gridplot background color = EEGLAB screen background color + +persistent warningInterp; + +plotgrid = 'off'; +plotchans = []; +noplot = 'off'; +handle = []; +Zi = []; +chanval = NaN; +rmax = 0.5; % actual head radius - Don't change this! +INTERPLIMITS = 'head'; % head, electrodes +INTSQUARE = 'on'; % default, interpolate electrodes located though the whole square containing + % the plotting disk +default_intrad = 1; % indicator for (no) specified intrad +MAPLIMITS = 'absmax'; % absmax, maxmin, [values] +GRID_SCALE = 67; % plot map on a 67X67 grid +CIRCGRID = 201; % number of angles to use in drawing circles +AXHEADFAC = 1.3; % head to axes scaling factor +CONTOURNUM = 6; % number of contour levels to plot +STYLE = 'both'; % default 'style': both,straight,fill,contour,blank +HEADCOLOR = [0 0 0]; % default head color (black) +CCOLOR = [0.2 0.2 0.2]; % default contour color +ELECTRODES = []; % default 'electrodes': on|off|label - set below +MAXDEFAULTSHOWLOCS = 64;% if more channels than this, don't show electrode locations by default +EMARKER = '.'; % mark electrode locations with small disks +ECOLOR = [0 0 0]; % default electrode color = black +EMARKERSIZE = []; % default depends on number of electrodes, set in code +EMARKERLINEWIDTH = 1; % default edge linewidth for emarkers +EMARKERSIZE1CHAN = 20; % default selected channel location marker size +EMARKERCOLOR1CHAN = 'red'; % selected channel location marker color +EMARKER2CHANS = []; % mark subset of electrode locations with small disks +EMARKER2 = 'o'; % mark subset of electrode locations with small disks +EMARKER2COLOR = 'r'; % mark subset of electrode locations with small disks +EMARKERSIZE2 = 10; % default selected channel location marker size +EMARKER2LINEWIDTH = 1; +EFSIZE = get(0,'DefaultAxesFontSize'); % use current default fontsize for electrode labels +HLINEWIDTH = 2; % default linewidth for head, nose, ears +BLANKINGRINGWIDTH = .035;% width of the blanking ring +HEADRINGWIDTH = .007;% width of the cartoon head ring +SHADING = 'flat'; % default 'shading': flat|interp +shrinkfactor = []; % shrink mode (dprecated) +intrad = []; % default interpolation square is to outermost electrode (<=1.0) +plotrad = []; % plotting radius ([] = auto, based on outermost channel location) +headrad = []; % default plotting radius for cartoon head is 0.5 +squeezefac = 1.0; +MINPLOTRAD = 0.15; % can't make a topoplot with smaller plotrad (contours fail) +VERBOSE = 'off'; +MASKSURF = 'off'; +CONVHULL = 'off'; % dont mask outside the electrodes convex hull +DRAWAXIS = 'off'; +PLOTDISK = 'off'; +ContourVals = Values; +PMASKFLAG = 0; +COLORARRAY = { [1 0 0] [0.5 0 0] [0 0 0] }; +%COLORARRAY2 = { [1 0 0] [0.5 0 0] [0 0 0] }; +gb = [0 0]; +COLORARRAY2 = { [gb 0] [gb 1/4] [gb 2/4] [gb 3/4] [gb 1] }; + +%%%%%% Dipole defaults %%%%%%%%%%%% +DIPOLE = []; +DIPNORM = 'on'; +DIPNORMMAX = 'off'; +DIPSPHERE = 85; +DIPLEN = 1; +DIPSCALE = 1; +DIPORIENT = 1; +DIPCOLOR = [0 0 0]; +NOSEDIR = '+X'; +CHANINFO = []; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% +%%%%%%%%%%%%%%%%%%%%%%% Handle arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if nargin< 1 + help topoplot; + return +end + +% calling topoplot from Fieldtrip +% ------------------------------- +fieldtrip = 0; +if nargin < 2, loc_file = []; end +if isstruct(Values) || ~isstruct(loc_file), fieldtrip == 1; end +if ischar(loc_file), if exist(loc_file) ~= 2, fieldtrip == 1; end; end +if fieldtrip + error('Wrong calling format, are you trying to use the topoplot Fieldtrip function?'); +end + +nargs = nargin; +if nargs == 1 + if ischar(Values) + if any(strcmp(lower(Values),{'example','demo'})) + fprintf(['This is an example of an electrode location file,\n',... + 'an ascii file consisting of the following four columns:\n',... + ' channel_number degrees arc_length channel_name\n\n',... + 'Example:\n',... + ' 1 -18 .352 Fp1 \n',... + ' 2 18 .352 Fp2 \n',... + ' 5 -90 .181 C3 \n',... + ' 6 90 .181 C4 \n',... + ' 7 -90 .500 A1 \n',... + ' 8 90 .500 A2 \n',... + ' 9 -142 .231 P3 \n',... + '10 142 .231 P4 \n',... + '11 0 .181 Fz \n',... + '12 0 0 Cz \n',... + '13 180 .181 Pz \n\n',... + ... + 'In topoplot() coordinates, 0 deg. points to the nose, positive\n',... + 'angles point to the right hemisphere, and negative to the left.\n',... + 'The model head sphere has a circumference of 2; the vertex\n',... + '(Cz) has arc_length 0. Locations with arc_length > 0.5 are below\n',... + 'head center and are plotted outside the head cartoon.\n',... + 'Option plotrad controls how much of this lower-head "skirt" is shown.\n',... + 'Option headrad controls if and where the cartoon head will be drawn.\n',... + 'Option intrad controls how many channels will be included in the interpolation.\n',... + ]) + return + end + end +end +if nargs < 2 + loc_file = DEFAULT_ELOC; + if ~exist(loc_file) + fprintf('default locations file "%s" not found - specify chan_locs in topoplot() call.\n',loc_file) + error(' ') + end +end +if isempty(loc_file) + loc_file = 0; +end +if isnumeric(loc_file) && loc_file == 0 + loc_file = DEFAULT_ELOC; +end + +if nargs > 2 + if ~(round(nargs/2) == nargs/2) + error('Odd number of input arguments??') + end + for i = 1:2:length(varargin) + Param = varargin{i}; + Value = varargin{i+1}; + if ~ischar(Param) + error('Flag arguments must be strings') + end + Param = lower(Param); + switch Param + case 'conv' + CONVHULL = lower(Value); + if ~strcmp(CONVHULL,'on') && ~strcmp(CONVHULL,'off') + error('Value of ''conv'' must be ''on'' or ''off''.'); + end + case 'colormap' + if size(Value,2)~=3 + error('Colormap must be a n x 3 matrix') + end + colormap(Value) + case 'gridscale' + GRID_SCALE = Value; + case 'plotdisk' + PLOTDISK = lower(Value); + if ~strcmp(PLOTDISK,'on') && ~strcmp(PLOTDISK,'off') + error('Value of ''plotdisk'' must be ''on'' or ''off''.'); + end + case 'intsquare' + INTSQUARE = lower(Value); + if ~strcmp(INTSQUARE,'on') && ~strcmp(INTSQUARE,'off') + error('Value of ''intsquare'' must be ''on'' or ''off''.'); + end + case 'emarkercolors' + COLORARRAY = Value; + case {'interplimits','headlimits'} + if ~ischar(Value) + error('''interplimits'' value must be a string') + end + Value = lower(Value); + if ~strcmp(Value,'electrodes') && ~strcmp(Value,'head') + error('Incorrect value for interplimits') + end + INTERPLIMITS = Value; + case 'verbose' + VERBOSE = Value; + case 'nosedir' + NOSEDIR = Value; + if isempty(strmatch(lower(NOSEDIR), { '+x', '-x', '+y', '-y' })) + error('Invalid nose direction'); + end + case 'chaninfo' + CHANINFO = Value; + if isfield(CHANINFO, 'nosedir'), NOSEDIR = CHANINFO.nosedir; end + if isfield(CHANINFO, 'shrink' ), shrinkfactor = CHANINFO.shrink; end + if isfield(CHANINFO, 'plotrad') && isempty(plotrad), plotrad = CHANINFO.plotrad; end + case 'chantype' + case 'drawaxis' + DRAWAXIS = Value; + case 'maplimits' + MAPLIMITS = Value; + case 'masksurf' + MASKSURF = Value; + case 'circgrid' + CIRCGRID = Value; + if ischar(CIRCGRID) || CIRCGRID<100 + error('''circgrid'' value must be an int > 100'); + end + case 'style' + STYLE = lower(Value); + case 'numcontour' + CONTOURNUM = Value; + case 'electrodes' + ELECTRODES = lower(Value); + if strcmpi(ELECTRODES,'pointlabels') || strcmpi(ELECTRODES,'ptslabels') ... + | strcmpi(ELECTRODES,'labelspts') | strcmpi(ELECTRODES,'ptlabels') ... + | strcmpi(ELECTRODES,'labelpts') + ELECTRODES = 'labelpoint'; % backwards compatibility + elseif strcmpi(ELECTRODES,'pointnumbers') || strcmpi(ELECTRODES,'ptsnumbers') ... + | strcmpi(ELECTRODES,'numberspts') | strcmpi(ELECTRODES,'ptnumbers') ... + | strcmpi(ELECTRODES,'numberpts') | strcmpi(ELECTRODES,'ptsnums') ... + | strcmpi(ELECTRODES,'numspts') + ELECTRODES = 'numpoint'; % backwards compatibility + elseif strcmpi(ELECTRODES,'nums') + ELECTRODES = 'numbers'; % backwards compatibility + elseif strcmpi(ELECTRODES,'pts') + ELECTRODES = 'on'; % backwards compatibility + elseif ~strcmp(ELECTRODES,'off') ... + & ~strcmpi(ELECTRODES,'on') ... + & ~strcmp(ELECTRODES,'labels') ... + & ~strcmpi(ELECTRODES,'numbers') ... + & ~strcmpi(ELECTRODES,'labelpoint') ... + & ~strcmpi(ELECTRODES,'numpoint') + error('Unknown value for keyword ''electrodes'''); + end + case 'dipole' + DIPOLE = Value; + case 'dipsphere' + DIPSPHERE = Value; + case {'dipnorm', 'dipnormmax'} + if strcmp(Param,'dipnorm') + DIPNORM = Value; + if strcmpi(Value,'on') + DIPNORMMAX = 'off'; + end + else + DIPNORMMAX = Value; + if strcmpi(Value,'on') + DIPNORM = 'off'; + end + end + + case 'diplen' + DIPLEN = Value; + case 'dipscale' + DIPSCALE = Value; + case 'contourvals' + ContourVals = Value; + case 'pmask' + ContourVals = Value; + PMASKFLAG = 1; + case 'diporient' + DIPORIENT = Value; + case 'dipcolor' + DIPCOLOR = Value; + case 'emarker' + if ischar(Value) + EMARKER = Value; + elseif ~iscell(Value) || length(Value) > 4 + error('''emarker'' argument must be a cell array {marker color size linewidth}') + else + EMARKER = Value{1}; + end + if length(Value) > 1 + ECOLOR = Value{2}; + end + if length(Value) > 2 + EMARKERSIZE = Value{3}; + end + if length(Value) > 3 + EMARKERLINEWIDTH = Value{4}; + end + case 'emarker2' + if ~iscell(Value) || length(Value) > 5 + error('''emarker2'' argument must be a cell array {chans marker color size linewidth}') + end + EMARKER2CHANS = abs(Value{1}); % ignore channels < 0 + if length(Value) > 1 + EMARKER2 = Value{2}; + end + if length(Value) > 2 + EMARKER2COLOR = Value{3}; + end + if length(Value) > 3 + EMARKERSIZE2 = Value{4}; + end + if length(Value) > 4 + EMARKER2LINEWIDTH = Value{5}; + end + case 'shrink' + shrinkfactor = Value; + case 'intrad' + intrad = Value; + if ischar(intrad) || (intrad < MINPLOTRAD || intrad > 1) + error('intrad argument should be a number between 0.15 and 1.0'); + end + case 'plotrad' + plotrad = Value; + if ~isempty(plotrad) && (ischar(plotrad) || (plotrad < MINPLOTRAD || plotrad > 1)) + error('plotrad argument should be a number between 0.15 and 1.0'); + end + case 'headrad' + headrad = Value; + if ischar(headrad) && ( strcmpi(headrad,'off') || strcmpi(headrad,'none') ) + headrad = 0; % undocumented 'no head' alternatives + end + if isempty(headrad) % [] -> none also + headrad = 0; + end + if ~ischar(headrad) + if ~(headrad==0) && (headrad < MINPLOTRAD || headrad>1) + error('bad value for headrad'); + end + elseif ~strcmpi(headrad,'rim') + error('bad value for headrad'); + end + case {'headcolor','hcolor'} + HEADCOLOR = Value; + case {'contourcolor','ccolor'} + CCOLOR = Value; + case {'electcolor','ecolor'} + ECOLOR = Value; + case {'emarkersize','emsize'} + EMARKERSIZE = Value; + case {'emarkersize1chan','emarkersizemark'} + EMARKERSIZE1CHAN= Value; + case {'efontsize','efsize'} + EFSIZE = Value; + case 'shading' + SHADING = lower(Value); + if ~any(strcmp(SHADING,{'flat','interp'})) + error('Invalid shading parameter') + end + if strcmpi(SHADING,'interp') && isempty(warningInterp) + warning('Using interpolated shading in scalp topographies prevent to export them as vectorized figures'); + warningInterp = 1; + end + case 'noplot' + noplot = Value; + if ~ischar(noplot) + if length(noplot) ~= 2 + error('''noplot'' location should be [radius, angle]') + else + chanrad = noplot(1); + chantheta = noplot(2); + noplot = 'on'; + end + end + case 'gridscale' + GRID_SCALE = Value; + if ischar(GRID_SCALE) || GRID_SCALE ~= round(GRID_SCALE) || GRID_SCALE < 32 + error('''gridscale'' value must be integer > 32.'); + end + case {'plotgrid','gridplot'} + plotgrid = 'on'; + gridchans = Value; + case 'plotchans' + plotchans = Value(:); + if find(plotchans<=0) + error('''plotchans'' values must be > 0'); + end + % if max(abs(plotchans))>max(Values) | max(abs(plotchans))>length(Values) -sm ??? + case {'whitebk','whiteback','forprint'} + whitebk = Value; + case {'iclabel'} % list of options to ignore + otherwise + error(['Unknown input parameter ''' Param ''' ???']) + end + end +end + +if strcmpi(whitebk, 'on') + BACKCOLOR = [ 1 1 1 ]; +end + +if isempty(find(strcmp(varargin,'colormap'))) + if exist('DEFAULT_COLORMAP','var') + cmap = colormap(DEFAULT_COLORMAP); + else + cmap = parula; + end +else + cmap = colormap; +end +if strcmp(noplot,'on'), close(gcf); end +cmaplen = size(cmap,1); + +if strcmp(STYLE,'blank') % else if Values holds numbers of channels to mark + if length(Values) < length(loc_file) + ContourVals = zeros(1,length(loc_file)); + ContourVals(Values) = 1; + Values = ContourVals; + end +end + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%% test args for plotting an electrode grid %%%%%%%%%%%%%%%%%%%%%% +% +if strcmp(plotgrid,'on') + STYLE = 'grid'; + gchans = sort(find(abs(gridchans(:))>0)); + + % if setdiff(gchans,unique(gchans)) + % fprintf('topoplot() warning: ''plotgrid'' channel matrix has duplicate channels\n'); + % end + + if ~isempty(plotchans) + if intersect(gchans,abs(plotchans)) + fprintf('topoplot() warning: ''plotgrid'' and ''plotchans'' have channels in common\n'); + end + end +end + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%% misc arg tests %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if isempty(ELECTRODES) % if electrode labeling not specified + if length(Values) > MAXDEFAULTSHOWLOCS % if more channels than default max + ELECTRODES = 'off'; % don't show electrodes + else % else if fewer chans, + ELECTRODES = 'on'; % do + end +end + +if isempty(Values) + STYLE = 'blank'; +end +[r,c] = size(Values); +if r>1 && c>1, + error('input data must be a single vector'); +end +Values = Values(:); % make Values a column vector +ContourVals = ContourVals(:); % values for contour + +if ~isempty(intrad) && ~isempty(plotrad) && intrad < plotrad + error('intrad must be >= plotrad'); +end + +if ~strcmpi(STYLE,'grid') % if not plot grid only + +% +%%%%%%%%%%%%%%%%%%%% Read the channel location information %%%%%%%%%%%%%%%%%%%%%%%% +% + if ischar(loc_file) + [tmpeloc labels Th Rd indices] = readlocs( loc_file); + elseif isstruct(loc_file) % a locs struct + [tmpeloc labels Th Rd indices] = readlocs( loc_file ); + % Note: Th and Rd correspond to indices channels-with-coordinates only + else + error('loc_file must be a EEG.locs struct or locs filename'); + end + Th = pi/180*Th; % convert degrees to radians + allchansind = 1:length(Th); + + + if ~isempty(plotchans) + if max(plotchans) > length(Th) + error('''plotchans'' values must be <= max channel index'); + end + end + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% channels to plot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if ~isempty(plotchans) + plotchans = intersect_bc(plotchans, indices); +end +if ~isempty(Values) && ~strcmpi( STYLE, 'blank') && isempty(plotchans) + plotchans = indices; +end +if isempty(plotchans) && strcmpi( STYLE, 'blank') + plotchans = indices; +end + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%% filter channels used for components %%%%%%%%%%%%%%%%%%%%% +% +if isfield(CHANINFO, 'icachansind') && ~isempty(Values) && length(Values) ~= length(tmpeloc) + + % test if ICA component + % --------------------- + if length(CHANINFO.icachansind) == length(Values) + + % if only a subset of channels are to be plotted + % and ICA components also use a subject of channel + % we must find the new indices for these channels + + plotchans = intersect_bc(CHANINFO.icachansind, plotchans); + tmpvals = zeros(1, length(tmpeloc)); + tmpvals(CHANINFO.icachansind) = Values; + Values = tmpvals; + tmpvals = zeros(1, length(tmpeloc)); + tmpvals(CHANINFO.icachansind) = ContourVals; + ContourVals = tmpvals; + + end +end + +% +%%%%%%%%%%%%%%%%%%% last channel is reference? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if length(tmpeloc) == length(Values) + 1 % remove last channel if necessary + % (common reference channel) + if plotchans(end) == length(tmpeloc) + plotchans(end) = []; + end + +end + +% +%%%%%%%%%%%%%%%%%%% remove infinite and NaN values %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if length(Values) > 1 + inds = union_bc(find(isnan(Values)), find(isinf(Values))); % NaN and Inf values + plotchans = setdiff_bc(plotchans, inds); +end +if strcmp(plotgrid,'on') + plotchans = setxor(plotchans,gchans); % remove grid chans from head plotchans +end + +[x,y] = pol2cart(Th,Rd); % transform electrode locations from polar to cartesian coordinates +plotchans = abs(plotchans); % reverse indicated channel polarities +allchansind = allchansind(plotchans); +Th = Th(plotchans); +Rd = Rd(plotchans); +x = x(plotchans); +y = y(plotchans); +labels = labels(plotchans); % remove labels for electrodes without locations +labels = strvcat(labels); % make a label string matrix +if ~isempty(Values) && length(Values) > 1 + Values = Values(plotchans); + ContourVals = ContourVals(plotchans); +end + +% +%%%%%%%%%%%%%%%%%% Read plotting radius from chanlocs %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if isempty(plotrad) && isfield(tmpeloc, 'plotrad'), + plotrad = tmpeloc(1).plotrad; + if ischar(plotrad) % plotrad shouldn't be a string + plotrad = str2num(plotrad) % just checking + end + if plotrad < MINPLOTRAD || plotrad > 1.0 + fprintf('Bad value (%g) for plotrad.\n',plotrad); + error(' '); + end + if strcmpi(VERBOSE,'on') && ~isempty(plotrad) + fprintf('Plotting radius plotrad (%g) set from EEG.chanlocs.\n',plotrad); + end +end +if isempty(plotrad) + plotrad = min(1.0,max(Rd)*1.02); % default: just outside the outermost electrode location + plotrad = max(plotrad,0.5); % default: plot out to the 0.5 head boundary +end % don't plot channels with Rd > 1 (below head) + +if isempty(intrad) + default_intrad = 1; % indicator for (no) specified intrad + intrad = min(1.0,max(Rd)*1.02); % default: just outside the outermost electrode location +else + default_intrad = 0; % indicator for (no) specified intrad + if plotrad > intrad + plotrad = intrad; + end +end % don't interpolate channels with Rd > 1 (below head) +if ischar(plotrad) || plotrad < MINPLOTRAD || plotrad > 1.0 + error('plotrad must be between 0.15 and 1.0'); +end + +% +%%%%%%%%%%%%%%%%%%%%%%% Set radius of head cartoon %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if isempty(headrad) % never set -> defaults + if plotrad >= rmax + headrad = rmax; % (anatomically correct) + else % if plotrad < rmax + headrad = 0; % don't plot head + if strcmpi(VERBOSE, 'on') + fprintf('topoplot(): not plotting cartoon head since plotrad (%5.4g) < 0.5\n',... + plotrad); + end + end +elseif strcmpi(headrad,'rim') % force plotting at rim of map + headrad = plotrad; +end + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Shrink mode %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if ~isempty(shrinkfactor) || isfield(tmpeloc, 'shrink'), + if isempty(shrinkfactor) && isfield(tmpeloc, 'shrink'), + shrinkfactor = tmpeloc(1).shrink; + if strcmpi(VERBOSE,'on') + if ischar(shrinkfactor) + fprintf('Automatically shrinking coordinates to lie above the head perimter.\n'); + else + fprintf('Automatically shrinking coordinates by %3.2f\n', shrinkfactor); + end + end + end + + if ischar(shrinkfactor) + if strcmpi(shrinkfactor, 'on') || strcmpi(shrinkfactor, 'force') || strcmpi(shrinkfactor, 'auto') + if abs(headrad-rmax) > 1e-2 + fprintf(' NOTE -> the head cartoon will NOT accurately indicate the actual electrode locations\n'); + end + if strcmpi(VERBOSE,'on') + fprintf(' Shrink flag -> plotting cartoon head at plotrad\n'); + end + headrad = plotrad; % plot head around outer electrodes, no matter if 0.5 or not + end + else % apply shrinkfactor + plotrad = rmax/(1-shrinkfactor); + headrad = plotrad; % make deprecated 'shrink' mode plot + if strcmpi(VERBOSE,'on') + fprintf(' %g%% shrink applied.'); + if abs(headrad-rmax) > 1e-2 + fprintf(' Warning: With this "shrink" setting, the cartoon head will NOT be anatomically correct.\n'); + else + fprintf('\n'); + end + end + end +end; % if shrink + +% +%%%%%%%%%%%%%%%%% Issue warning if headrad ~= rmax %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + +if headrad ~= 0.5 && strcmpi(VERBOSE, 'on') + fprintf(' NB: Plotting map using ''plotrad'' %-4.3g,',plotrad); + fprintf( ' ''headrad'' %-4.3g\n',headrad); + fprintf('Warning: The plotting radius of the cartoon head is NOT anatomically correct (0.5).\n') +end +% +%%%%%%%%%%%%%%%%%%%%% Find plotting channels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + +pltchans = find(Rd <= plotrad); % plot channels inside plotting circle + +if strcmpi(INTSQUARE,'on') % interpolate channels in the radius intrad square + intchans = find(x <= intrad & y <= intrad); % interpolate and plot channels inside interpolation square +else + intchans = find(Rd <= intrad); % interpolate channels in the radius intrad circle only +end + +% +%%%%%%%%%%%%%%%%%%%%% Eliminate channels not plotted %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + +allx = x; +ally = y; +intchans; % interpolate using only the 'intchans' channels +pltchans; % plot using only indicated 'plotchans' channels + +if length(pltchans) < length(Rd) && strcmpi(VERBOSE, 'on') + fprintf('Interpolating %d and plotting %d of the %d scalp electrodes.\n', ... + length(intchans),length(pltchans),length(Rd)); +end; + + +% fprintf('topoplot(): plotting %d channels\n',length(pltchans)); +if ~isempty(EMARKER2CHANS) + if strcmpi(STYLE,'blank') + error('emarker2 not defined for style ''blank'' - use marking channel numbers in place of data'); + else % mark1chans and mark2chans are subsets of pltchans for markers 1 and 2 + [tmp1, mark1chans, tmp2] = setxor(pltchans,EMARKER2CHANS); + [tmp3, tmp4, mark2chans] = intersect_bc(EMARKER2CHANS,pltchans); + end +end + +if ~isempty(Values) + if length(Values) == length(Th) % if as many map Values as channel locs + intValues = Values(intchans); + intContourVals = ContourVals(intchans); + Values = Values(pltchans); + ContourVals = ContourVals(pltchans); + end; +end; % now channel parameters and values all refer to plotting channels only + +allchansind = allchansind(pltchans); +intTh = Th(intchans); % eliminate channels outside the interpolation area +intRd = Rd(intchans); +intx = x(intchans); +inty = y(intchans); +Th = Th(pltchans); % eliminate channels outside the plotting area +Rd = Rd(pltchans); +x = x(pltchans); +y = y(pltchans); + +labels= labels(pltchans,:); +% +%%%%%%%%%%%%%%% Squeeze channel locations to <= rmax %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + +squeezefac = rmax/plotrad; +intRd = intRd*squeezefac; % squeeze electrode arc_lengths towards the vertex +Rd = Rd*squeezefac; % squeeze electrode arc_lengths towards the vertex + % to plot all inside the head cartoon +intx = intx*squeezefac; +inty = inty*squeezefac; +x = x*squeezefac; +y = y*squeezefac; +allx = allx*squeezefac; +ally = ally*squeezefac; +% Note: Now outermost channel will be plotted just inside rmax + +else % if strcmpi(STYLE,'grid') + intx = rmax; inty=rmax; +end % if ~strcmpi(STYLE,'grid') + +% +%%%%%%%%%%%%%%%% rotate channels based on chaninfo %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if strcmpi(lower(NOSEDIR), '+x') + rotate = 0; +else + if strcmpi(lower(NOSEDIR), '+y') + rotate = 3*pi/2; + elseif strcmpi(lower(NOSEDIR), '-x') + rotate = pi; + else rotate = pi/2; + end + allcoords = (inty + intx*sqrt(-1))*exp(sqrt(-1)*rotate); + intx = imag(allcoords); + inty = real(allcoords); + allcoords = (ally + allx*sqrt(-1))*exp(sqrt(-1)*rotate); + allx = imag(allcoords); + ally = real(allcoords); + allcoords = (y + x*sqrt(-1))*exp(sqrt(-1)*rotate); + x = imag(allcoords); + y = real(allcoords); +end + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Make the plot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if ~strcmpi(STYLE,'blank') % if draw interpolated scalp map + if ~strcmpi(STYLE,'grid') % not a rectangular channel grid + % + %%%%%%%%%%%%%%%% Find limits for interpolation %%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + if default_intrad % if no specified intrad + if strcmpi(INTERPLIMITS,'head') % intrad is 'head' + xmin = min(-rmax,min(intx)); xmax = max(rmax,max(intx)); + ymin = min(-rmax,min(inty)); ymax = max(rmax,max(inty)); + + else % INTERPLIMITS = rectangle containing electrodes -- DEPRECATED OPTION! + xmin = max(-rmax,min(intx)); xmax = min(rmax,max(intx)); + ymin = max(-rmax,min(inty)); ymax = min(rmax,max(inty)); + end + else % some other intrad specified + xmin = -intrad*squeezefac; xmax = intrad*squeezefac; % use the specified intrad value + ymin = -intrad*squeezefac; ymax = intrad*squeezefac; + end + % + %%%%%%%%%%%%%%%%%%%%%%% Interpolate scalp map data %%%%%%%%%%%%%%%%%%%%%%%% + % + xi = linspace(xmin,xmax,GRID_SCALE); % x-axis description (row vector) + yi = linspace(ymin,ymax,GRID_SCALE); % y-axis description (row vector) + + try + [Xi,Yi,Zi] = griddata(inty,intx,double(intValues),yi',xi,'v4'); % interpolate data + [Xi,Yi,ZiC] = griddata(inty,intx,double(intContourVals),yi',xi,'v4'); % interpolate data + catch, + [Xi,Yi] = meshgrid(yi',xi); + Zi = gdatav4(inty,intx,double(intValues), Xi, Yi); + ZiC = gdatav4(inty,intx,double(intContourVals), Xi, Yi); + end + % + %%%%%%%%%%%%%%%%%%%%%%% Mask out data outside the head %%%%%%%%%%%%%%%%%%%%% + % + mask = (sqrt(Xi.^2 + Yi.^2) <= rmax); % mask outside the plotting circle + ii = find(mask == 0); + Zi(ii) = NaN; % mask non-plotting voxels with NaNs + ZiC(ii) = NaN; % mask non-plotting voxels with NaNs + grid = plotrad; % unless 'noplot', then 3rd output arg is plotrad + % + %%%%%%%%%% Return interpolated value at designated scalp location %%%%%%%%%% + % + if exist('chanrad') % optional first argument to 'noplot' + chantheta = (chantheta/360)*2*pi; + chancoords = round(ceil(GRID_SCALE/2)+GRID_SCALE/2*2*chanrad*[cos(-chantheta),... + -sin(-chantheta)]); + if chancoords(1)<1 ... + || chancoords(1) > GRID_SCALE ... + || chancoords(2)<1 ... + || chancoords(2)>GRID_SCALE + error('designated ''noplot'' channel out of bounds') + else + chanval = Zi(chancoords(1),chancoords(2)); + grid = Zi; + Zi = chanval; % return interpolated value instead of Zi + end + end + % + %%%%%%%%%%%%%%%%%%%%%%%%%% Return interpolated image only %%%%%%%%%%%%%%%%% + % + if strcmpi(noplot, 'on') + if strcmpi(VERBOSE,'on') + fprintf('topoplot(): no plot requested.\n') + end + return; + end + % + %%%%%%%%%%%%%%%%%%%%%%% Calculate colormap limits %%%%%%%%%%%%%%%%%%%%%%%%%% + % + if ischar(MAPLIMITS) + if strcmp(MAPLIMITS,'absmax') + amax = max(max(abs(Zi))); + amin = -amax; + elseif strcmp(MAPLIMITS,'maxmin') || strcmp(MAPLIMITS,'minmax') + amin = min(min(Zi)); + amax = max(max(Zi)); + else + error('unknown ''maplimits'' value.'); + end + elseif length(MAPLIMITS) == 2 + amin = MAPLIMITS(1); + amax = MAPLIMITS(2); + else + error('unknown ''maplimits'' value'); + end + delta = xi(2)-xi(1); % length of grid entry + + end % if ~strcmpi(STYLE,'grid') + % + %%%%%%%%%%%%%%%%%%%%%%%%%% Scale the axes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + %cla % clear current axis + hold on + h = gca; % uses current axes + + % instead of default larger AXHEADFAC + if squeezefac<0.92 && plotrad-headrad > 0.05 % (size of head in axes) + AXHEADFAC = 1.05; % do not leave room for external ears if head cartoon + % shrunk enough by the 'skirt' option + end + + set(gca,'Xlim',[-rmax rmax]*AXHEADFAC,'Ylim',[-rmax rmax]*AXHEADFAC); + % specify size of head axes in gca + + unsh = (GRID_SCALE+1)/GRID_SCALE; % un-shrink the effects of 'interp' SHADING + + % + %%%%%%%%%%%%%%%%%%%%%%%% Plot grid only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + if strcmpi(STYLE,'grid') % plot grid only + + % + % The goal below is to make the grid cells square - not yet achieved in all cases? -sm + % + g1 = size(gridchans,1); + g2 = size(gridchans,2); + gmax = max([g1 g2]); + Xi = linspace(-rmax*g2/gmax,rmax*g2/gmax,g1+1); + Xi = Xi+rmax/g1; Xi = Xi(1:end-1); + Yi = linspace(-rmax*g1/gmax,rmax*g1/gmax,g2+1); + Yi = Yi+rmax/g2; Yi = Yi(1:end-1); Yi = Yi(end:-1:1); % by trial and error! + % + %%%%%%%%%%% collect the gridchans values %%%%%%%%%%%%%%%%%%%%%%%%%%% + % + gridvalues = zeros(size(gridchans)); + for j=1:size(gridchans,1) + for k=1:size(gridchans,2) + gc = gridchans(j,k); + if gc > 0 + gridvalues(j,k) = Values(gc); + elseif gc < 0 + gridvalues(j,k) = -Values(abs(gc)); + else + gridvalues(j,k) = nan; % not-a-number = no value + end + end + end + % + %%%%%%%%%%% reset color limits for grid plot %%%%%%%%%%%%%%%%%%%%%%%%% + % + if ischar(MAPLIMITS) + if strcmp(MAPLIMITS,'maxmin') || strcmp(MAPLIMITS,'minmax') + amin = min(min(gridvalues(~isnan(gridvalues)))); + amax = max(max(gridvalues(~isnan(gridvalues)))); + elseif strcmp(MAPLIMITS,'absmax') + % 11/21/2005 Toby edit + % This should now work as specified. Before it only crashed (using + % "plotgrid" and "maplimits>absmax" options). + amax = max(max(abs(gridvalues(~isnan(gridvalues))))); + amin = -amax; + %amin = -max(max(abs([amin amax]))); + %amax = max(max(abs([amin amax]))); + else + error('unknown ''maplimits'' value'); + end + elseif length(MAPLIMITS) == 2 + amin = MAPLIMITS(1); + amax = MAPLIMITS(2); + else + error('unknown ''maplimits'' value'); + end + % + %%%%%%%%%% explicitly compute grid colors, allowing BACKCOLOR %%%%%% + % + gridvalues = 1+floor(cmaplen*(gridvalues-amin)/(amax-amin)); + gridvalues(find(gridvalues == cmaplen+1)) = cmaplen; + gridcolors = zeros([size(gridvalues),3]); + for j=1:size(gridchans,1) + for k=1:size(gridchans,2) + if ~isnan(gridvalues(j,k)) + gridcolors(j,k,:) = cmap(gridvalues(j,k),:); + else + if strcmpi(whitebk,'off') + gridcolors(j,k,:) = BACKCOLOR; % gridchans == 0 -> background color + % This allows the plot to show 'space' between separate sub-grids or strips + else % 'on' + gridcolors(j,k,:) = [1 1 1]; BACKCOLOR; % gridchans == 0 -> white for printing + end + end + end + end + + % + %%%%%%%%%% draw the gridplot image %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + handle=imagesc(Xi,Yi,gridcolors); % plot grid with explicit colors + axis square + % + %%%%%%%%%%%%%%%%%%%%%%%% Plot map contours only %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + elseif strcmp(STYLE,'contour') % plot surface contours only + [cls chs] = contour(Xi,Yi,ZiC,CONTOURNUM,'k'); + handle = chs; % handle to a contourgroup object + % for h=chs, set(h,'color',CCOLOR); end + % + %%%%%%%%%%%%%%%%%%%%%%%% Else plot map and contours %%%%%%%%%%%%%%%%%%%%%%%%% + % + elseif strcmp(STYLE,'both') % plot interpolated surface and surface contours + if strcmp(SHADING,'interp') + tmph = surface(Xi*unsh,Yi*unsh,zeros(size(Zi))-0.1,Zi,... + 'EdgeColor','none','FaceColor',SHADING); + else % SHADING == 'flat' + tmph = surface(Xi-delta/2,Yi-delta/2,zeros(size(Zi))-0.1,Zi,... + 'EdgeColor','none','FaceColor',SHADING); + end + if strcmpi(MASKSURF, 'on') + set(tmph, 'visible', 'off'); + handle = tmph; + end + + warning off; + if ~PMASKFLAG + [cls chs] = contour(Xi,Yi,ZiC,CONTOURNUM,'k'); + else + ZiC(find(ZiC > 0.5 )) = NaN; + [cls chs] = contourf(Xi,Yi,ZiC,0,'k'); + subh = get(chs, 'children'); + for indsubh = 1:length(subh) + numfaces = size(get(subh(indsubh), 'XData'),1); + set(subh(indsubh), 'FaceVertexCData', ones(numfaces,3), 'Cdatamapping', 'direct', 'facealpha', 0.5, 'linewidth', 2); + end + end + handle = tmph; % surface handle + try, for h=chs, set(h,'color',CCOLOR); end, catch, end % the try clause is for Octave + warning on; + % + %%%%%%%%%%%%%%%%%%%%%%%% Else plot map only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % + elseif strcmp(STYLE,'straight') || strcmp(STYLE,'map') % 'straight' was former arg + + if strcmp(SHADING,'interp') % 'interp' mode is shifted somehow... but how? + tmph = surface(Xi*unsh,Yi*unsh,zeros(size(Zi)),Zi,'EdgeColor','none',... + 'FaceColor',SHADING); + else + tmph = surface(Xi-delta/2,Yi-delta/2,zeros(size(Zi)),Zi,'EdgeColor','none',... + 'FaceColor',SHADING); + end + if strcmpi(MASKSURF, 'on') + set(tmph, 'visible', 'off'); + handle = tmph; + end + handle = tmph; % surface handle + % + %%%%%%%%%%%%%%%%%% Else fill contours with uniform colors %%%%%%%%%%%%%%%%%% + % + elseif strcmp(STYLE,'fill') + [cls chs] = contourf(Xi,Yi,Zi,CONTOURNUM,'k'); + + handle = chs; % handle to a contourgroup object + + % for h=chs, set(h,'color',CCOLOR); end + % <- 'not line objects.' Why does 'both' work above??? + + else + error('Invalid style') + end + % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Set color axis %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % +% caxis([amin amax]); % set coloraxis + +% 7/30/2014 Ramon: +-5% for the color limits were added +cax_sgn = sign([amin amax]); % getting sign +caxis([amin+cax_sgn(1)*(0.05*abs(amin)) amax+cax_sgn(2)*(0.05*abs(amax))]); % Adding 5% to the color limits + +else % if STYLE 'blank' +% +%%%%%%%%%%%%%%%%%%%%%%% Draw blank head %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + if strcmpi(noplot, 'on') + if strcmpi(VERBOSE,'on') + fprintf('topoplot(): no plot requested.\n') + end + return; + end + %cla + hold on + + set(gca,'Xlim',[-rmax rmax]*AXHEADFAC,'Ylim',[-rmax rmax]*AXHEADFAC) + % pos = get(gca,'position'); + % fprintf('Current axes size %g,%g\n',pos(3),pos(4)); + + if strcmp(ELECTRODES,'labelpoint') || strcmp(ELECTRODES,'numpoint') + text(-0.6,-0.6, ... + [ int2str(length(Rd)) ' of ' int2str(length(tmpeloc)) ' electrode locations shown']); + text(-0.6,-0.7, [ 'Click on electrodes to toggle name/number']); + tl = title('Channel locations'); + set(tl, 'fontweight', 'bold'); + end +end % STYLE 'blank' + +if exist('handle') ~= 1 + handle = gca; +end + +if ~strcmpi(STYLE,'grid') % if not plot grid only + +% +%%%%%%%%%%%%%%%%%%% Plot filled ring to mask jagged grid boundary %%%%%%%%%%%%%%%%%%%%%%%%%%% +% +hwidth = HEADRINGWIDTH; % width of head ring +hin = squeezefac*headrad*(1- hwidth/2); % inner head ring radius + +if strcmp(SHADING,'interp') + rwidth = BLANKINGRINGWIDTH*1.3; % width of blanking outer ring +else + rwidth = BLANKINGRINGWIDTH; % width of blanking outer ring +end +rin = rmax*(1-rwidth/2); % inner ring radius +if hin>rin + rin = hin; % dont blank inside the head ring +end + +if strcmp(CONVHULL,'on') %%%%%%%%% mask outside the convex hull of the electrodes %%%%%%%%% + cnv = convhull(allx,ally); + cnvfac = round(CIRCGRID/length(cnv)); % spline interpolate the convex hull + if cnvfac < 1, cnvfac=1; end + CIRCGRID = cnvfac*length(cnv); + + startangle = atan2(allx(cnv(1)),ally(cnv(1))); + circ = linspace(0+startangle,2*pi+startangle,CIRCGRID); + rx = sin(circ); + ry = cos(circ); + + allx = allx(:)'; % make x (elec locations; + to nose) a row vector + ally = ally(:)'; % make y (elec locations, + to r? ear) a row vector + erad = sqrt(allx(cnv).^2+ally(cnv).^2); % convert to polar coordinates + eang = atan2(allx(cnv),ally(cnv)); + eang = unwrap(eang); + eradi =spline(linspace(0,1,3*length(cnv)), [erad erad erad], ... + linspace(0,1,3*length(cnv)*cnvfac)); + eangi =spline(linspace(0,1,3*length(cnv)), [eang+2*pi eang eang-2*pi], ... + linspace(0,1,3*length(cnv)*cnvfac)); + xx = eradi.*sin(eangi); % convert back to rect coordinates + yy = eradi.*cos(eangi); + yy = yy(CIRCGRID+1:2*CIRCGRID); + xx = xx(CIRCGRID+1:2*CIRCGRID); + eangi = eangi(CIRCGRID+1:2*CIRCGRID); + eradi = eradi(CIRCGRID+1:2*CIRCGRID); + xx = xx*1.02; yy = yy*1.02; % extend spline outside electrode marks + + splrad = sqrt(xx.^2+yy.^2); % arc radius of spline points (yy,xx) + oob = find(splrad >= rin); % enforce an upper bound on xx,yy + xx(oob) = rin*xx(oob)./splrad(oob); % max radius = rin + yy(oob) = rin*yy(oob)./splrad(oob); % max radius = rin + + splrad = sqrt(xx.^2+yy.^2); % arc radius of spline points (yy,xx) + oob = find(splrad < hin); % don't let splrad be inside the head cartoon + xx(oob) = hin*xx(oob)./splrad(oob); % min radius = hin + yy(oob) = hin*yy(oob)./splrad(oob); % min radius = hin + + ringy = [[ry(:)' ry(1) ]*(rin+rwidth) yy yy(1)]; + ringx = [[rx(:)' rx(1) ]*(rin+rwidth) xx xx(1)]; + + ringh2= patch(ringy,ringx,ones(size(ringy)),BACKCOLOR,'edgecolor','none'); hold on + + % plot(ry*rmax,rx*rmax,'b') % debugging line + +else %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% mask the jagged border around rmax %%%%%%%%%%%%%%%5%%%%%% + + circ = linspace(0,2*pi,CIRCGRID); + rx = sin(circ); + ry = cos(circ); + ringx = [[rx(:)' rx(1) ]*(rin+rwidth) [rx(:)' rx(1)]*rin]; + ringy = [[ry(:)' ry(1) ]*(rin+rwidth) [ry(:)' ry(1)]*rin]; + + if ~strcmpi(STYLE,'blank') + ringh= patch(ringx,ringy,0.01*ones(size(ringx)),BACKCOLOR,'edgecolor','none'); hold on + end + % plot(ry*rmax,rx*rmax,'b') % debugging line +end + + %f1= fill(rin*[rx rX],rin*[ry rY],BACKCOLOR,'edgecolor',BACKCOLOR); hold on + %f2= fill(rin*[rx rX*(1+rwidth)],rin*[ry rY*(1+rwidth)],BACKCOLOR,'edgecolor',BACKCOLOR); + +% Former line-style border smoothing - width did not scale with plot +% brdr=plot(1.015*cos(circ).*rmax,1.015*sin(circ).*rmax,... % old line-based method +% 'color',HEADCOLOR,'Linestyle','-','LineWidth',HLINEWIDTH); % plot skirt outline +% set(brdr,'color',BACKCOLOR,'linewidth',HLINEWIDTH + 4); % hide the disk edge jaggies + +% +%%%%%%%%%%%%%%%%%%%%%%%%% Plot cartoon head, ears, nose %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if headrad > 0 % if cartoon head to be plotted +% +%%%%%%%%%%%%%%%%%%% Plot head outline %%%%%%%%%%%%%%%%%%%%%%%%%%% +% +headx = [[rx(:)' rx(1) ]*(hin+hwidth) [rx(:)' rx(1)]*hin]; +heady = [[ry(:)' ry(1) ]*(hin+hwidth) [ry(:)' ry(1)]*hin]; + +if ~ischar(HEADCOLOR) || ~strcmpi(HEADCOLOR,'none') + %ringh= patch(headx,heady,ones(size(headx)),HEADCOLOR,'edgecolor',HEADCOLOR,'linewidth', HLINEWIDTH); hold on + headx = [rx(:)' rx(1)]*hin; + heady = [ry(:)' ry(1)]*hin; + ringh= plot(headx,heady); + set(ringh, 'color',HEADCOLOR,'linewidth', HLINEWIDTH); hold on +end + +% rx = sin(circ); rX = rx(end:-1:1); +% ry = cos(circ); rY = ry(end:-1:1); +% for k=2:2:CIRCGRID +% rx(k) = rx(k)*(1+hwidth); +% ry(k) = ry(k)*(1+hwidth); +% end +% f3= fill(hin*[rx rX],hin*[ry rY],HEADCOLOR,'edgecolor',HEADCOLOR); hold on +% f4= fill(hin*[rx rX*(1+hwidth)],hin*[ry rY*(1+hwidth)],HEADCOLOR,'edgecolor',HEADCOLOR); + +% Former line-style head +% plot(cos(circ).*squeezefac*headrad,sin(circ).*squeezefac*headrad,... +% 'color',HEADCOLOR,'Linestyle','-','LineWidth',HLINEWIDTH); % plot head outline + +% +%%%%%%%%%%%%%%%%%%% Plot ears and nose %%%%%%%%%%%%%%%%%%%%%%%%%%% +% + base = rmax-.0046; + basex = 0.18*rmax; % nose width + tip = 1.15*rmax; + tiphw = .04*rmax; % nose tip half width + tipr = .01*rmax; % nose tip rounding + q = .04; % ear lengthening + EarX = [.497-.005 .510 .518 .5299 .5419 .54 .547 .532 .510 .489-.005]; % rmax = 0.5 + EarY = [q+.0555 q+.0775 q+.0783 q+.0746 q+.0555 -.0055 -.0932 -.1313 -.1384 -.1199]; + sf = headrad/plotrad; % squeeze the model ears and nose + % by this factor + if ~ischar(HEADCOLOR) || ~strcmpi(HEADCOLOR,'none') + plot3([basex;tiphw;0;-tiphw;-basex]*sf,[base;tip-tipr;tip;tip-tipr;base]*sf,... + 2*ones(size([basex;tiphw;0;-tiphw;-basex])),... + 'Color',HEADCOLOR,'LineWidth',HLINEWIDTH); % plot nose + plot3(EarX*sf,EarY*sf,2*ones(size(EarX)),'color',HEADCOLOR,'LineWidth',HLINEWIDTH) % plot left ear + plot3(-EarX*sf,EarY*sf,2*ones(size(EarY)),'color',HEADCOLOR,'LineWidth',HLINEWIDTH) % plot right ear + end +end + +% +% %%%%%%%%%%%%%%%%%%% Show electrode information %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + plotax = gca; + axis square % make plotax square + axis off + + pos = get(gca,'position'); + xlm = get(gca,'xlim'); + ylm = get(gca,'ylim'); + % textax = axes('position',pos,'xlim',xlm,'ylim',ylm); % make new axes so clicking numbers <-> labels + % will work inside head cartoon patch + % axes(textax); + axis square % make textax square + + pos = get(gca,'position'); + set(plotax,'position',pos); + + xlm = get(gca,'xlim'); + set(plotax,'xlim',xlm); + + ylm = get(gca,'ylim'); + set(plotax,'ylim',ylm); % copy position and axis limits again + +axis equal; +lim = [-0.525 0.525]; +%lim = [-0.56 0.56]; +set(gca, 'xlim', lim); set(plotax, 'xlim', lim); +set(gca, 'ylim', lim); set(plotax, 'ylim', lim); +set(gca, 'xlim', lim); set(plotax, 'xlim', lim); +set(gca, 'ylim', lim); set(plotax, 'ylim', lim); + +%get(textax,'pos') % test if equal! +%get(plotax,'pos') +%get(textax,'xlim') +%get(plotax,'xlim') +%get(textax,'ylim') +%get(plotax,'ylim') + + if isempty(EMARKERSIZE) + EMARKERSIZE = 10; + if length(y)>=160 + EMARKERSIZE = 3; + elseif length(y)>=128 + EMARKERSIZE = 3; + elseif length(y)>=100 + EMARKERSIZE = 3; + elseif length(y)>=80 + EMARKERSIZE = 4; + elseif length(y)>=64 + EMARKERSIZE = 5; + elseif length(y)>=48 + EMARKERSIZE = 6; + elseif length(y)>=32 + EMARKERSIZE = 8; + end + end +% +%%%%%%%%%%%%%%%%%%%%%%%% Mark electrode locations only %%%%%%%%%%%%%%%%%%%%%%%%%% +% +ELECTRODE_HEIGHT = 2.1; % z value for plotting electrode information (above the surf) + +if strcmp(ELECTRODES,'on') % plot electrodes as spots + if isempty(EMARKER2CHANS) + hp2 = plot3(y,x,ones(size(x))*ELECTRODE_HEIGHT,... + EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH); + else % plot markers for normal chans and EMARKER2CHANS separately + hp2 = plot3(y(mark1chans),x(mark1chans),ones(size((mark1chans)))*ELECTRODE_HEIGHT,... + EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH); + hp2b = plot3(y(mark2chans),x(mark2chans),ones(size((mark2chans)))*ELECTRODE_HEIGHT,... + EMARKER2,'Color',EMARKER2COLOR,'markerfacecolor',EMARKER2COLOR,'linewidth',EMARKER2LINEWIDTH,'markersize',EMARKERSIZE2); + end +% +%%%%%%%%%%%%%%%%%%%%%%%% Print electrode labels only %%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +elseif strcmp(ELECTRODES,'labels') % print electrode names (labels) + for i = 1:size(labels,1) + text(double(y(i)),double(x(i)),... + ELECTRODE_HEIGHT,labels(i,:),'HorizontalAlignment','center',... + 'VerticalAlignment','middle','Color',ECOLOR,... + 'FontSize',EFSIZE) + end +% +%%%%%%%%%%%%%%%%%%%%%%%% Mark electrode locations plus labels %%%%%%%%%%%%%%%%%%% +% +elseif strcmp(ELECTRODES,'labelpoint') + if isempty(EMARKER2CHANS) + hp2 = plot3(y,x,ones(size(x))*ELECTRODE_HEIGHT,... + EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH); + else + hp2 = plot3(y(mark1chans),x(mark1chans),ones(size((mark1chans)))*ELECTRODE_HEIGHT,... + EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH); + hp2b = plot3(y(mark2chans),x(mark2chans),ones(size((mark2chans)))*ELECTRODE_HEIGHT,... + EMARKER2,'Color',EMARKER2COLOR,'markerfacecolor',EMARKER2COLOR,'linewidth',EMARKER2LINEWIDTH,'markersize',EMARKERSIZE2); + end + for i = 1:size(labels,1) + hh(i) = text(double(y(i)+0.01),double(x(i)),... + ELECTRODE_HEIGHT,labels(i,:),'HorizontalAlignment','left',... + 'VerticalAlignment','middle','Color', ECOLOR,'userdata', num2str(allchansind(i)), ... + 'FontSize',EFSIZE, 'buttondownfcn', ... + ['tmpstr = get(gco, ''userdata'');'... + 'set(gco, ''userdata'', get(gco, ''string''));' ... + 'set(gco, ''string'', tmpstr); clear tmpstr;'] ); + end +% +%%%%%%%%%%%%%%%%%%%%%%% Mark electrode locations plus numbers %%%%%%%%%%%%%%%%%%% +% +elseif strcmp(ELECTRODES,'numpoint') + if isempty(EMARKER2CHANS) + hp2 = plot3(y,x,ones(size(x))*ELECTRODE_HEIGHT,... + EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH); + else + hp2 = plot3(y(mark1chans),x(mark1chans),ones(size((mark1chans)))*ELECTRODE_HEIGHT,... + EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH); + hp2b = plot3(y(mark2chans),x(mark2chans),ones(size((mark2chans)))*ELECTRODE_HEIGHT,... + EMARKER2,'Color',EMARKER2COLOR,'markerfacecolor',EMARKER2COLOR,'linewidth',EMARKER2LINEWIDTH,'markersize',EMARKERSIZE2); + end + for i = 1:size(labels,1) + hh(i) = text(double(y(i)+0.01),double(x(i)),... + ELECTRODE_HEIGHT,num2str(allchansind(i)),'HorizontalAlignment','left',... + 'VerticalAlignment','middle','Color', ECOLOR,'userdata', labels(i,:) , ... + 'FontSize',EFSIZE, 'buttondownfcn', ... + ['tmpstr = get(gco, ''userdata'');'... + 'set(gco, ''userdata'', get(gco, ''string''));' ... + 'set(gco, ''string'', tmpstr); clear tmpstr;'] ); + end +% +%%%%%%%%%%%%%%%%%%%%%% Print electrode numbers only %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +elseif strcmp(ELECTRODES,'numbers') + for i = 1:size(labels,1) + text(double(y(i)),double(x(i)),... + ELECTRODE_HEIGHT,int2str(allchansind(i)),'HorizontalAlignment','center',... + 'VerticalAlignment','middle','Color',ECOLOR,... + 'FontSize',EFSIZE) + end +% +%%%%%%%%%%%%%%%%%%%%%% Mark emarker2 electrodes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +elseif strcmp(ELECTRODES,'off') && ~isempty(EMARKER2CHANS) + hp2b = plot3(y(mark2chans),x(mark2chans),ones(size((mark2chans)))*ELECTRODE_HEIGHT,... + EMARKER2,'Color',EMARKER2COLOR,'markerfacecolor',EMARKER2COLOR,'linewidth',EMARKER2LINEWIDTH,'markersize',EMARKERSIZE2); +end +% +%%%%%%%% Mark specified electrode locations with red filled disks %%%%%%%%%%%%%%%%%%%%%% +% +try, + if strcmpi(STYLE,'blank') % if mark-selected-channel-locations mode + for kk = 1:length(1:length(x)) + if abs(Values(kk)) + if strcmpi(PLOTDISK, 'off') + angleRatio = real(Values(kk))/(real(Values(kk))+imag(Values(kk)))*360; + radius = real(Values(kk))+imag(Values(kk)); + allradius = [0.02 0.03 0.037 0.044 0.05]; + radius = allradius(radius); + hp2 = disk(y(kk),x(kk),radius, [1 0 0], 0 , angleRatio, 16); + if angleRatio ~= 360 + hp2 = disk(y(kk),x(kk),radius, [0 0 1], angleRatio, 360, 16); + end + else + tmpcolor = COLORARRAY{max(1,min(Values(kk), length(COLORARRAY)))}; + hp2 = plot3(y(kk),x(kk),ELECTRODE_HEIGHT,EMARKER,'Color', tmpcolor, 'markersize', EMARKERSIZE1CHAN); + hp2 = disk(y(kk),x(kk),real(Values(kk))+imag(Values(kk)), tmpcolor, 0, 360, 10); + end + end + end + end +catch, end +% +%%%%%%%%%%%%%%%%%%%%%%%%%%% Plot dipole(s) on the scalp map %%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +if ~isempty(DIPOLE) + hold on; + tmp = DIPOLE; + if isstruct(DIPOLE) + if ~isfield(tmp,'posxyz') + error('dipole structure is not an EEG.dipfit.model') + end + DIPOLE = []; % Note: invert x and y from dipplot usage + DIPOLE(:,1) = -tmp.posxyz(:,2)/DIPSPHERE; % -y -> x + DIPOLE(:,2) = tmp.posxyz(:,1)/DIPSPHERE; % x -> y + DIPOLE(:,3) = -tmp.momxyz(:,2); + DIPOLE(:,4) = tmp.momxyz(:,1); + DIPOLE(:,5) = tmp.momxyz(:,3); + else + DIPOLE(:,1) = -tmp(:,2); % same for vector input + DIPOLE(:,2) = tmp(:,1); + DIPOLE(:,3) = -tmp(:,4); + DIPOLE(:,4) = tmp(:,3); + end + for index = 1:size(DIPOLE,1) + if ~any(DIPOLE(index,:)) + DIPOLE(index,:) = []; + end + end + DIPOLE(:,1:4) = DIPOLE(:,1:4)*rmax*(rmax/plotrad); % scale radius from 1 -> rmax (0.5) + DIPOLE(:,3:end) = (DIPOLE(:,3:end))*rmax/100000*(rmax/plotrad); + if strcmpi(DIPNORM, 'on') + for index = 1:size(DIPOLE,1) + DIPOLE(index,3:4) = DIPOLE(index,3:4)/norm(DIPOLE(index,3:end))*0.2; + end + elseif strcmpi(DIPNORMMAX, 'on') + for inorm = 1: size(DIPOLE,1) + normtmp(inorm) = norm(DIPOLE(inorm,3:5)); % Max norm of projection on XY + end + [maxnorm,maxnormindx] = max(normtmp); + for index = 1:size(DIPOLE,1) + DIPOLE(index,3:4) = DIPOLE(index,3:4)/norm(DIPOLE(index,3:4))*0.2*normtmp(index)/normtmp(maxnormindx); + end; + end + DIPOLE(:, 3:4) = DIPORIENT*DIPOLE(:, 3:4)*DIPLEN; + + PLOT_DIPOLE=1; + if sum(DIPOLE(1,3:4).^2) <= 0.00001 + if strcmpi(VERBOSE,'on') + fprintf('Note: dipole is length 0 - not plotted\n') + end + PLOT_DIPOLE = 0; + end + if 0 % sum(DIPOLE(1,1:2).^2) > plotrad + if strcmpi(VERBOSE,'on') + fprintf('Note: dipole is outside plotting area - not plotted\n') + end + PLOT_DIPOLE = 0; + end + if PLOT_DIPOLE + for index = 1:size(DIPOLE,1) + hh = plot( DIPOLE(index, 1), DIPOLE(index, 2), '.'); + set(hh, 'color', DIPCOLOR, 'markersize', DIPSCALE*30); + hh = line( [DIPOLE(index, 1) DIPOLE(index, 1)+DIPOLE(index, 3)]', ... + [DIPOLE(index, 2) DIPOLE(index, 2)+DIPOLE(index, 4)]',[10 10]); + set(hh, 'color', DIPCOLOR, 'linewidth', DIPSCALE*30/7); + end + end +end + +end % if ~ 'gridplot' + +% +%%%%%%%%%%%%% Plot axis orientation %%%%%%%%%%%%%%%%%%%% +% +if strcmpi(DRAWAXIS, 'on') + axes('position', [0 0.85 0.08 0.1]); + axis off; + coordend1 = sqrt(-1)*3; + coordend2 = -3; + coordend1 = coordend1*exp(sqrt(-1)*rotate); + coordend2 = coordend2*exp(sqrt(-1)*rotate); + + line([5 5+round(real(coordend1))]', [5 5+round(imag(coordend1))]', 'color', 'k'); + line([5 5+round(real(coordend2))]', [5 5+round(imag(coordend2))]', 'color', 'k'); + if round(real(coordend2))<0 + text( 5+round(real(coordend2))*1.2, 5+round(imag(coordend2))*1.2-2, '+Y'); + else text( 5+round(real(coordend2))*1.2, 5+round(imag(coordend2))*1.2, '+Y'); + end + if round(real(coordend1))<0 + text( 5+round(real(coordend1))*1.2, 5+round(imag(coordend1))*1.2+1.5, '+X'); + else text( 5+round(real(coordend1))*1.2, 5+round(imag(coordend1))*1.2, '+X'); + end + set(gca, 'xlim', [0 10], 'ylim', [0 10]); +end + +% +%%%%%%%%%%%%% Set EEGLAB background color to match head border %%%%%%%%%%%%%%%%%%%%%%%% +% +try, + set(gcf, 'color', BACKCOLOR); + catch, +end; + +hold off +axis off +return + +% +% X(2:size(X,1)-1,2:size(X,2)-1) = NaN; +% X(isnan(X(:))) = []; +% X(1:2:end) = []; +% X(1:2:end) = []; +% X(1:2:end) = []; + +function vq = gdatav4(x,y,v,xq,yq) +%GDATAV4 MATLAB 4 GRIDDATA interpolation + +% Reference: David T. Sandwell, Biharmonic spline +% interpolation of GEOS-3 and SEASAT altimeter +% data, Geophysical Research Letters, 2, 139-142, +% 1987. Describes interpolation using value or +% gradient of value in any dimension. + +xy = x(:) + 1i*y(:); + +% Determine distances between points +d = abs(xy - xy.'); + +% Determine weights for interpolation +g = (d.^2) .* (log(d)-1); % Green's function. +% Fixup value of Green's function along diagonal +g(1:size(d,1)+1:end) = 0; +weights = g \ v(:); + +[m,n] = size(xq); +vq = zeros(size(xq)); +xy = xy.'; + +% Evaluate at requested points (xq,yq). Loop to save memory. +for i=1:m + for j=1:n + d = abs(xq(i,j) + 1i*yq(i,j) - xy); + g = (d.^2) .* (log(d)-1); % Green's function. + % Value of Green's function at zero + g(d==0) = 0; + vq(i,j) = g * weights; + end +end + +% +%%%%%%%%%%%%% Draw circle %%%%%%%%%%%%%%%%%%%%%%%% +% +function h2 = disk(X, Y, radius, colorfill, oriangle, endangle, segments) + A = linspace(oriangle/180*pi, endangle/180*pi, segments-1); + if endangle-oriangle == 360 + A = linspace(oriangle/180*pi, endangle/180*pi, segments); + h2 = patch( [X + cos(A)*radius(1)], [Y + sin(A)*radius(end)], zeros(1,segments)+3, colorfill); + else A = linspace(oriangle/180*pi, endangle/180*pi, segments-1); + h2 = patch( [X X + cos(A)*radius(1)], [Y Y + sin(A)*radius(end)], zeros(1,segments)+3, colorfill); + end + set(h2, 'FaceColor', colorfill); + set(h2, 'EdgeColor', 'none'); diff --git a/studio_functions/Functions/EEGLAB/Scalp/traditionaldipfit.m b/studio_functions/Functions/EEGLAB/Scalp/traditionaldipfit.m new file mode 100755 index 00000000..120e7009 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/traditionaldipfit.m @@ -0,0 +1,90 @@ +function [H] = traditionaldipfit(f); + +% TRADITIONALDIPFIT creates the homogenous spatial transformation matrix +% for a 9 parameter traditionaldipfit "Talairach-model" transformation +% +% H = traditionaldipfit(f) +% +% The transformation vector f should contain the +% x-shift +% y-shift +% z-shift +% (in length-units of the coordinate system used. For the MNI brain +% the unit is mm) +% followed by the +% pitch (rotation around x-axis) +% roll (rotation around y-axis) +% yaw (rotation around z-axis) +% (in radians) +% followed by the +% x-rescaling factor +% y-rescaling factor +% z-rescaling factor +% (in ratio = newscale/oldscale) +% +% H first applies scaling, then rotations, and finally the shifts. +% +% See also fieldtrip*/WARP3D.m + +% Copyright (C) 2000-2004, Robert Oostenveld +% +% This program is free software; you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation; either version 2 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +% compute the homogenous transformation matrix for the translation +if length(f) == 6, f(7:9) = 1; end; + +T = eye(4,4); +if isa( f, 'sym') + T = sym(T); +end; +T(1,4) = f(1); +T(2,4) = f(2); +T(3,4) = f(3); + +% precompute the sin/cos values of the angles +cX = cos(f(4)); +cY = cos(f(5)); +cZ = cos(f(6)); +sX = sin(f(4)); +sY = sin(f(5)); +sZ = sin(f(6)); + +% compute the homogenous transformation matrix for the rotation +R = eye(4,4); +if isa( f, 'sym') + R = sym(R); +end; +R(1,1) = cZ*cY + sZ*sX*sY; +R(1,2) = sZ*cY + cZ*sX*sY; +R(1,3) = cX*sY; +R(2,1) = -sZ*cX; +R(2,2) = cZ*cX; +R(2,3) = sX; +R(3,1) = sZ*sX*cY - cZ*sY; +R(3,2) = -cZ*sX*cY - sZ*sY; +R(3,3) = cX*cY; + +% compute the homogenous transformation matrix for the scaling +S = eye(4,4); +if isa( f, 'sym') + S = sym(S); +end; +S(1,1) = f(7); +S(2,2) = f(8); +S(3,3) = f(9); + +% compute the homogenous coordinate transformation matrix for use by WARP3D +H = T*R*S; + diff --git a/studio_functions/Functions/EEGLAB/Scalp/union_bc.m b/studio_functions/Functions/EEGLAB/Scalp/union_bc.m new file mode 100755 index 00000000..a307b3ba --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/union_bc.m @@ -0,0 +1,56 @@ +% union_bc - union backward compatible with Matlab versions prior to 2013a + +% Copyright (C) 2013 Arnaud Delorme +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [C,IA,IB] = union_bc(A,B,varargin) + +errorFlag = error_bc; + +v = version; +indp = find(v == '.'); +v = str2num(v(1:indp(2)-1)); +if v > 7.19, v = floor(v) + rem(v,1)/10; end + +if nargin > 2 + ind = strmatch('legacy', varargin); + if ~isempty(ind) + varargin(ind) = []; + end +end + +if v >= 7.14 + [C,IA,IB] = union(A,B,varargin{:},'legacy'); + if errorFlag + [C2,IA2,IB2] = union(A,B,varargin{:}); + if (~isequal(C, C2) || ~isequal(IA, IA2) || ~isequal(IB, IB2)) + warning('backward compatibility issue with call to union function'); + end + end +else + [C,IA,IB] = union(A,B,varargin{:}); +end diff --git a/studio_functions/Functions/EEGLAB/Scalp/unique_bc.m b/studio_functions/Functions/EEGLAB/Scalp/unique_bc.m new file mode 100755 index 00000000..e6d1195d --- /dev/null +++ b/studio_functions/Functions/EEGLAB/Scalp/unique_bc.m @@ -0,0 +1,56 @@ +% unique_bc - unique backward compatible with Matlab versions prior to 2013a + +% Copyright (C) 2013 Arnaud Delorme +% +% This file is part of EEGLAB, see http://www.eeglab.org +% for the documentation and details. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are met: +% +% 1. Redistributions of source code must retain the above copyright notice, +% this list of conditions and the following disclaimer. +% +% 2. Redistributions in binary form must reproduce the above copyright notice, +% this list of conditions and the following disclaimer in the documentation +% and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +% THE POSSIBILITY OF SUCH DAMAGE. + +function [C,IA,IB] = unique_bc(A,varargin) + +errorFlag = error_bc; + +v = version; +indp = find(v == '.'); +v = str2num(v(1:indp(2)-1)); +if v > 7.19, v = floor(v) + rem(v,1)/10; end + +if nargin > 2 + ind = strmatch('legacy', varargin); + if ~isempty(ind) + varargin(ind) = []; + end +end + +if v >= 7.14 + [C,IA,IB] = unique(A,varargin{:},'legacy'); + if errorFlag + [C2,IA2] = unique(A,varargin{:}); + if ~isequal(C, C2) || ~isequal(IA, IA2) || ~isequal(IB, IB2) + warning('backward compatibility issue with call to unique function'); + end + end +else + [C,IA,IB] = unique(A,varargin{:}); +end diff --git a/studio_functions/Functions/EEGLAB/supportfiles/EEGLAB_compile_splash.jpg b/studio_functions/Functions/EEGLAB/supportfiles/EEGLAB_compile_splash.jpg new file mode 100755 index 00000000..afac30ff Binary files /dev/null and b/studio_functions/Functions/EEGLAB/supportfiles/EEGLAB_compile_splash.jpg differ diff --git a/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-20-Cap81.ced b/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-20-Cap81.ced new file mode 100755 index 00000000..81ec13c3 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-20-Cap81.ced @@ -0,0 +1,82 @@ +Number labels theta radius X Y Z sph_theta sph_phi sph_radius +1 Fp1 -18 0.511 0.95 0.309 -0.0349 18 -2 1 +2 Fpz 0 0.511 0.999 -0 -0.0349 -0 -2 1 +3 Fp2 18 0.511 0.95 -0.309 -0.0349 -18 -2 1 +4 Nz 0 0.622 0.927 -0 -0.375 -0 -22 1 +5 AF9 -43 0.639 0.663 0.618 -0.423 43 -25 1 +6 AF7 -38 0.511 0.788 0.615 -0.0349 38 -2 1 +7 AF3 -23 0.411 0.885 0.376 0.276 23 16 1 +8 AFz 0 0.383 0.934 -0 0.358 -0 21 1 +9 AF4 23 0.411 0.885 -0.376 0.276 -23 16 1 +10 AF8 38 0.511 0.788 -0.615 -0.0349 -38 -2 1 +11 AF10 43 0.639 0.663 -0.618 -0.423 -43 -25 1 +12 F9 -55 0.639 0.52 0.742 -0.423 55 -25 1 +13 F7 -54 0.511 0.587 0.809 -0.0349 54 -2 1 +14 F5 -49 0.417 0.634 0.729 0.259 49 15 1 +15 F3 -39 0.333 0.673 0.545 0.5 39 30 1 +16 F1 -22 0.278 0.71 0.287 0.643 22 40 1 +17 Fz 0 0.256 0.719 -0 0.695 -0 44 1 +18 F2 22 0.278 0.71 -0.287 0.643 -22 40 1 +19 F4 39 0.333 0.673 -0.545 0.5 -39 30 1 +20 F6 49 0.417 0.634 -0.729 0.259 -49 15 1 +21 F8 54 0.511 0.587 -0.809 -0.0349 -54 -2 1 +22 F10 55 0.639 0.52 -0.742 -0.423 -55 -25 1 +23 FT9 -72 0.639 0.28 0.862 -0.423 72 -25 1 +24 FT7 -72 0.511 0.309 0.95 -0.0349 72 -2 1 +25 FC5 -69 0.394 0.339 0.883 0.326 69 19 1 +26 FC3 -62 0.278 0.36 0.676 0.643 62 40 1 +27 FC1 -45 0.178 0.375 0.375 0.848 45 58 1 +28 FCz 0 0.128 0.391 -0 0.921 -0 67 1 +29 FC2 45 0.178 0.375 -0.375 0.848 -45 58 1 +30 FC4 62 0.278 0.36 -0.676 0.643 -62 40 1 +31 FC6 69 0.394 0.339 -0.883 0.326 -69 19 1 +32 FT8 72 0.511 0.309 -0.95 -0.0349 -72 -2 1 +33 FT10 72 0.639 0.28 -0.862 -0.423 -72 -25 1 +34 T9 -90 0.639 5.55e-17 0.906 -0.423 90 -25 1 +35 T7 -90 0.511 6.12e-17 0.999 -0.0349 90 -2 1 +36 C5 -90 0.383 5.72e-17 0.934 0.358 90 21 1 +37 C3 -90 0.256 4.4e-17 0.719 0.695 90 44 1 +38 C1 -90 0.128 2.39e-17 0.391 0.921 90 67 1 +39 Cz 90 0 3.75e-33 -6.12e-17 1 -90 90 1 +40 C2 90 0.128 2.39e-17 -0.391 0.921 -90 67 1 +41 C4 90 0.256 4.4e-17 -0.719 0.695 -90 44 1 +42 C6 90 0.383 5.72e-17 -0.934 0.358 -90 21 1 +43 T8 90 0.511 6.12e-17 -0.999 -0.0349 -90 -2 1 +44 T10 90 0.639 5.55e-17 -0.906 -0.423 -90 -25 1 +45 TP9 -108 0.639 -0.28 0.862 -0.423 108 -25 1 +46 TP7 -108 0.511 -0.309 0.95 -0.0349 108 -2 1 +47 CP5 -111 0.394 -0.339 0.883 0.326 111 19 1 +48 CP3 -118 0.278 -0.36 0.676 0.643 118 40 1 +49 CP1 -135 0.178 -0.375 0.375 0.848 135 58 1 +50 CPz 180 0.128 -0.391 -4.79e-17 0.921 -180 67 1 +51 CP2 135 0.178 -0.375 -0.375 0.848 -135 58 1 +52 CP4 118 0.278 -0.36 -0.676 0.643 -118 40 1 +53 CP6 111 0.394 -0.339 -0.883 0.326 -111 19 1 +54 TP8 108 0.511 -0.309 -0.95 -0.0349 -108 -2 1 +55 TP10 108 0.639 -0.28 -0.862 -0.423 -108 -25 1 +56 P9 -126 0.639 -0.533 0.733 -0.423 126 -25 1 +57 P7 -126 0.511 -0.587 0.809 -0.0349 126 -2 1 +58 P5 -131 0.417 -0.634 0.729 0.259 131 15 1 +59 P3 -141 0.333 -0.673 0.545 0.5 141 30 1 +60 P1 -158 0.278 -0.71 0.287 0.643 158 40 1 +61 Pz 180 0.256 -0.719 -8.81e-17 0.695 -180 44 1 +62 P2 158 0.278 -0.71 -0.287 0.643 -158 40 1 +63 P4 141 0.333 -0.673 -0.545 0.5 -141 30 1 +64 P6 131 0.417 -0.634 -0.729 0.259 -131 15 1 +65 P8 126 0.511 -0.587 -0.809 -0.0349 -126 -2 1 +66 P10 126 0.639 -0.533 -0.733 -0.423 -126 -25 1 +67 PO9 -144 0.639 -0.733 0.533 -0.423 144 -25 1 +68 PO7 -144 0.511 -0.809 0.587 -0.0349 144 -2 1 +69 PO3 -157 0.411 -0.885 0.376 0.276 157 16 1 +70 POz 180 0.383 -0.934 -1.14e-16 0.358 -180 21 1 +71 PO4 157 0.411 -0.885 -0.376 0.276 -157 16 1 +72 PO8 144 0.511 -0.809 -0.587 -0.0349 -144 -2 1 +73 PO10 144 0.639 -0.733 -0.533 -0.423 -144 -25 1 +74 O1 -162 0.511 -0.95 0.309 -0.0349 162 -2 1 +75 Oz 180 0.511 -0.999 -1.22e-16 -0.0349 -180 -2 1 +76 O2 162 0.511 -0.95 -0.309 -0.0349 -162 -2 1 +77 O9 -162 0.639 -0.862 0.28 -0.423 162 -25 1 +78 O10 162 0.639 -0.862 -0.28 -0.423 -162 -25 1 +79 CB1 -135 0.722 -0.542 0.542 -0.643 135 -40 1 +80 CB2 135 0.722 -0.542 -0.542 -0.643 -135 -40 1 +81 Iz 180 0.639 -0.906 -1.11e-16 -0.423 -180 -25 1 diff --git a/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-5-Cap385.sfp b/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-5-Cap385.sfp new file mode 100755 index 00000000..e8e36973 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-5-Cap385.sfp @@ -0,0 +1,348 @@ +LPA -0.0865 0.0000 -0.0500 +RPA 0.0865 0.0000 -0.0500 +Nz 0.0000 0.0913 -0.0407 +Fp1 -0.0307 0.0949 -0.0047 +Fpz 0.0000 0.0999 -0.0021 +Fp2 0.0307 0.0949 -0.0047 +AF9 -0.0512 0.0723 -0.0462 +AF7 -0.0584 0.0807 -0.0070 +AF5 -0.0505 0.0856 0.0105 +AF3 -0.0370 0.0895 0.0245 +AF1 -0.0196 0.0920 0.0336 +AFz -0.0000 0.0929 0.0368 +AF2 0.0195 0.0921 0.0336 +AF4 0.0370 0.0895 0.0245 +AF6 0.0505 0.0856 0.0105 +AF8 0.0584 0.0808 -0.0070 +AF10 0.0512 0.0724 -0.0462 +F9 -0.0702 0.0523 -0.0482 +F7 -0.0804 0.0586 -0.0088 +F5 -0.0741 0.0635 0.0213 +F3 -0.0567 0.0677 0.0469 +F1 -0.0306 0.0704 0.0639 +Fz 0.0000 0.0714 0.0699 +F2 0.0306 0.0704 0.0640 +F4 0.0566 0.0677 0.0469 +F6 0.0741 0.0635 0.0214 +F8 0.0804 0.0587 -0.0088 +F10 0.0702 0.0523 -0.0482 +FT9 -0.0824 0.0274 -0.0495 +FT7 -0.0945 0.0308 -0.0100 +FC5 -0.0896 0.0338 0.0284 +FC3 -0.0697 0.0364 0.0617 +FC1 -0.0380 0.0381 0.0841 +FCz 0.0000 0.0387 0.0921 +FC2 0.0380 0.0381 0.0841 +FC4 0.0697 0.0364 0.0617 +FC6 0.0896 0.0338 0.0284 +FT8 0.0945 0.0308 -0.0100 +FT10 0.0824 0.0274 -0.0495 +T9 -0.0865 0.0000 -0.0500 +T7 -0.0994 0.0000 -0.0104 +C5 -0.0950 0.0000 0.0309 +C3 -0.0742 0.0000 0.0668 +C1 -0.0406 -0.0000 0.0913 +Cz 0.0000 0.0000 0.1000 +C2 0.0407 0.0000 0.0913 +C4 0.0743 0.0000 0.0669 +C6 0.0950 0.0000 0.0309 +T8 0.0994 0.0000 -0.0104 +T10 0.0865 0.0000 -0.0500 +TP9 -0.0824 -0.0274 -0.0495 +TP7 -0.0945 -0.0308 -0.0100 +CP5 -0.0896 -0.0338 0.0284 +CP3 -0.0697 -0.0364 0.0617 +CP1 -0.0380 -0.0381 0.0841 +CPz 0.0000 -0.0387 0.0921 +CP2 0.0380 -0.0381 0.0841 +CP4 0.0697 -0.0364 0.0617 +CP6 0.0896 -0.0338 0.0284 +TP8 0.0945 -0.0309 -0.0100 +TP10 0.0824 -0.0274 -0.0495 +P9 -0.0702 -0.0523 -0.0482 +P7 -0.0804 -0.0586 -0.0088 +P5 -0.0741 -0.0635 0.0213 +P3 -0.0567 -0.0677 0.0469 +P1 -0.0306 -0.0704 0.0639 +Pz 0.0000 -0.0714 0.0699 +P2 0.0306 -0.0704 0.0640 +P4 0.0566 -0.0677 0.0469 +P6 0.0741 -0.0635 0.0214 +P8 0.0804 -0.0587 -0.0088 +P10 0.0702 -0.0523 -0.0482 +PO9 -0.0512 -0.0723 -0.0462 +PO7 -0.0584 -0.0807 -0.0070 +PO5 -0.0505 -0.0856 0.0105 +PO3 -0.0370 -0.0895 0.0245 +PO1 -0.0196 -0.0920 0.0336 +POz 0.0000 -0.0929 0.0368 +PO2 0.0195 -0.0921 0.0336 +PO4 0.0370 -0.0895 0.0245 +PO6 0.0505 -0.0856 0.0105 +PO8 0.0584 -0.0808 -0.0070 +PO10 0.0512 -0.0724 -0.0462 +O1 -0.0307 -0.0949 -0.0047 +Oz 0.0000 -0.0999 -0.0021 +O2 0.0307 -0.0949 -0.0047 +I1 -0.0270 -0.0858 -0.0436 +O9 -0.0270 -0.0858 -0.0436 +Iz -0.0000 -0.0913 -0.0407 +I2 0.0270 -0.0858 -0.0436 +O10 0.0270 -0.0858 -0.0436 +AFp9h -0.0433 0.0863 -0.0259 +AFp7h -0.0412 0.0910 -0.0007 +AFp5h -0.0315 0.0945 0.0079 +AFp3h -0.0198 0.0969 0.0141 +AFp1h -0.0067 0.0982 0.0173 +AFp2h 0.0068 0.0982 0.0173 +AFp4h 0.0198 0.0969 0.0141 +AFp6h 0.0315 0.0945 0.0079 +AFp8h 0.0413 0.0910 -0.0007 +AFp10h 0.0433 0.0862 -0.0259 +AFF9h -0.0673 0.0683 -0.0282 +AFF7h -0.0679 0.0732 0.0045 +AFF5h -0.0562 0.0780 0.0271 +AFF3h -0.0371 0.0816 0.0442 +AFF1h -0.0130 0.0836 0.0533 +AFF2h 0.0129 0.0836 0.0533 +AFF4h 0.0371 0.0816 0.0441 +AFF6h 0.0563 0.0780 0.0271 +AFF8h 0.0678 0.0732 0.0045 +AFF10h 0.0673 0.0682 -0.0282 +FFT9h -0.0847 0.0437 -0.0299 +FFT7h -0.0876 0.0474 0.0082 +FFC5h -0.0751 0.0513 0.0414 +FFC3h -0.0506 0.0543 0.0669 +FFC1h -0.0178 0.0560 0.0809 +FFC2h 0.0178 0.0560 0.0809 +FFC4h 0.0505 0.0543 0.0669 +FFC6h 0.0751 0.0513 0.0413 +FFT8h 0.0876 0.0474 0.0082 +FFT10h 0.0848 0.0437 -0.0299 +FTT9h -0.0939 0.0151 -0.0308 +FTT7h -0.0980 0.0164 0.0102 +FCC5h -0.0852 0.0179 0.0490 +FCC3h -0.0578 0.0190 0.0793 +FCC1h -0.0204 0.0197 0.0958 +FCC2h 0.0205 0.0197 0.0959 +FCC4h 0.0578 0.0190 0.0793 +FCC6h 0.0853 0.0179 0.0490 +FTT8h 0.0981 0.0164 0.0102 +FTT10h 0.0939 0.0151 -0.0308 +TTP9h -0.0939 -0.0151 -0.0308 +TTP7h -0.0980 -0.0164 0.0102 +CCP5h -0.0852 -0.0179 0.0490 +CCP3h -0.0578 -0.0190 0.0793 +CCP1h -0.0204 -0.0197 0.0958 +CCP2h 0.0205 -0.0197 0.0959 +CCP4h 0.0578 -0.0190 0.0793 +CCP6h 0.0853 -0.0179 0.0490 +TTP8h 0.0981 -0.0164 0.0102 +TTP10h 0.0939 -0.0151 -0.0308 +TPP9h -0.0847 -0.0437 -0.0299 +TPP7h -0.0876 -0.0474 0.0082 +CPP5h -0.0751 -0.0513 0.0414 +CPP3h -0.0506 -0.0543 0.0669 +CPP1h -0.0178 -0.0560 0.0809 +CPP2h 0.0178 -0.0560 0.0809 +CPP4h 0.0505 -0.0543 0.0669 +CPP6h 0.0751 -0.0513 0.0413 +TPP8h 0.0876 -0.0474 0.0082 +TPP10h 0.0848 -0.0437 -0.0299 +PPO9h -0.0673 -0.0683 -0.0282 +PPO7h -0.0679 -0.0732 0.0045 +PPO5h -0.0562 -0.0780 0.0271 +PPO3h -0.0371 -0.0816 0.0442 +PPO1h -0.0130 -0.0836 0.0533 +PPO2h 0.0129 -0.0836 0.0533 +PPO4h 0.0371 -0.0816 0.0441 +PPO6h 0.0563 -0.0780 0.0271 +PPO8h 0.0678 -0.0732 0.0045 +PPO10h 0.0673 -0.0682 -0.0282 +POO9h -0.0433 -0.0863 -0.0259 +POO7h -0.0412 -0.0910 -0.0007 +POO5h -0.0315 -0.0945 0.0079 +POO3h -0.0198 -0.0969 0.0141 +POO1h -0.0067 -0.0982 0.0173 +POO2h 0.0068 -0.0982 0.0173 +POO4h 0.0198 -0.0969 0.0141 +POO6h 0.0315 -0.0945 0.0079 +POO8h 0.0413 -0.0910 -0.0007 +POO10h 0.0433 -0.0862 -0.0259 +OI1h -0.0150 -0.0961 -0.0232 +OI2h 0.0150 -0.0960 -0.0232 +Fp1h -0.0155 0.0986 -0.0034 +Fp2h 0.0156 0.0986 -0.0034 +AF9h -0.0560 0.0782 -0.0271 +AF7h -0.0552 0.0833 0.0021 +AF5h -0.0443 0.0877 0.0180 +AF3h -0.0287 0.0910 0.0298 +AF1h -0.0099 0.0927 0.0360 +AF2h 0.0099 0.0927 0.0359 +AF4h 0.0286 0.0910 0.0298 +AF6h 0.0443 0.0877 0.0180 +AF8h 0.0551 0.0833 0.0020 +AF10h 0.0560 0.0782 -0.0271 +F9h -0.0770 0.0567 -0.0292 +F7h -0.0788 0.0611 0.0066 +F5h -0.0667 0.0657 0.0350 +F3h -0.0445 0.0693 0.0567 +F1h -0.0156 0.0712 0.0684 +F2h 0.0156 0.0712 0.0684 +F4h 0.0445 0.0693 0.0567 +F6h 0.0667 0.0657 0.0350 +F8h 0.0788 0.0611 0.0066 +F10h 0.0770 0.0567 -0.0291 +FT9h -0.0904 0.0297 -0.0304 +FT7h -0.0941 0.0323 0.0094 +FC5h -0.0814 0.0352 0.0461 +FC3h -0.0550 0.0374 0.0745 +FC1h -0.0195 0.0386 0.0902 +FC2h 0.0194 0.0386 0.0902 +FC4h 0.0550 0.0374 0.0745 +FC6h 0.0814 0.0352 0.0461 +FT8h 0.0941 0.0324 0.0095 +FT10h 0.0904 0.0297 -0.0304 +T9h -0.0950 0.0000 -0.0309 +T7h -0.0994 0.0000 0.0105 +C5h -0.0865 -0.0000 0.0500 +C3h -0.0587 0.0000 0.0808 +C1h -0.0208 0.0000 0.0978 +C2h 0.0208 0.0000 0.0978 +C4h 0.0587 0.0000 0.0809 +C6h 0.0865 0.0000 0.0500 +T8h 0.0994 0.0000 0.0105 +T10h 0.0950 0.0000 -0.0309 +TP9h -0.0904 -0.0297 -0.0304 +TP7h -0.0941 -0.0323 0.0094 +CP5h -0.0814 -0.0352 0.0461 +CP3h -0.0550 -0.0374 0.0745 +CP1h -0.0195 -0.0386 0.0902 +CP2h 0.0194 -0.0386 0.0902 +CP4h 0.0550 -0.0374 0.0745 +CP6h 0.0814 -0.0352 0.0461 +TP8h 0.0941 -0.0324 0.0094 +TP10h 0.0904 -0.0297 -0.0304 +P9h -0.0770 -0.0567 -0.0292 +P7h -0.0788 -0.0611 0.0066 +P5h -0.0667 -0.0657 0.0350 +P3h -0.0445 -0.0693 0.0567 +P1h -0.0156 -0.0712 0.0684 +P2h 0.0156 -0.0712 0.0684 +P4h 0.0445 -0.0693 0.0567 +P6h 0.0667 -0.0657 0.0350 +P8h 0.0788 -0.0611 0.0066 +P10h 0.0770 -0.0567 -0.0291 +PO9h -0.0560 -0.0782 -0.0271 +PO7h -0.0552 -0.0833 0.0021 +PO5h -0.0443 -0.0877 0.0180 +PO3h -0.0287 -0.0910 0.0298 +PO1h -0.0099 -0.0927 0.0360 +PO2h 0.0099 -0.0927 0.0359 +PO4h 0.0286 -0.0910 0.0298 +PO6h 0.0443 -0.0877 0.0180 +PO8h 0.0551 -0.0833 0.0020 +PO10h 0.0560 -0.0782 -0.0271 +O1h -0.0155 -0.0986 -0.0034 +O2h 0.0156 -0.0986 -0.0034 +I1h -0.0137 -0.0896 -0.0421 +I2h 0.0137 -0.0896 -0.0421 +AFp9 -0.0396 0.0800 -0.0449 +AFp7 -0.0451 0.0890 -0.0059 +AFp5 -0.0367 0.0929 0.0039 +AFp3 -0.0259 0.0958 0.0114 +AFp1 -0.0134 0.0977 0.0161 +AFpz 0.0000 0.0983 0.0177 +AFp2 0.0134 0.0977 0.0161 +AFp4 0.0258 0.0958 0.0113 +AFp6 0.0367 0.0929 0.0039 +AFp8 0.0451 0.0890 -0.0059 +AFp10 0.0396 0.0800 -0.0449 +AFF9 -0.0614 0.0631 -0.0473 +AFF7 -0.0703 0.0706 -0.0080 +AFF5 -0.0631 0.0757 0.0163 +AFF3 -0.0474 0.0800 0.0364 +AFF1 -0.0254 0.0828 0.0498 +AFFz -0.0000 0.0838 0.0544 +AFF2 0.0254 0.0828 0.0498 +AFF4 0.0475 0.0800 0.0365 +AFF6 0.0631 0.0757 0.0163 +AFF8 0.0703 0.0706 -0.0080 +AFF10 0.0614 0.0631 -0.0473 +FFT9 -0.0773 0.0403 -0.0490 +FFT7 -0.0885 0.0453 -0.0095 +FFC5 -0.0831 0.0494 0.0254 +FFC3 -0.0641 0.0530 0.0554 +FFC1 -0.0349 0.0553 0.0755 +FFCz 0.0000 0.0562 0.0826 +FFC2 0.0349 0.0553 0.0756 +FFC4 0.0641 0.0530 0.0554 +FFC6 0.0830 0.0494 0.0254 +FFT8 0.0886 0.0453 -0.0095 +FFT10 0.0772 0.0403 -0.0490 +FTT9 -0.0855 0.0139 -0.0499 +FTT7 -0.0982 0.0156 -0.0103 +FCC5 -0.0937 0.0172 0.0303 +FCC3 -0.0731 0.0185 0.0655 +FCC1 -0.0400 0.0194 0.0895 +FCCz 0.0000 0.0197 0.0979 +FCC2 0.0400 0.0194 0.0896 +FCC4 0.0731 0.0185 0.0656 +FCC6 0.0937 0.0172 0.0303 +FTT8 0.0981 0.0156 -0.0103 +FTT10 0.0855 0.0139 -0.0498 +TTP9 -0.0855 -0.0139 -0.0499 +TTP7 -0.0982 -0.0156 -0.0103 +CCP5 -0.0937 -0.0172 0.0303 +CCP3 -0.0731 -0.0185 0.0655 +CCP1 -0.0400 -0.0194 0.0895 +CCPz 0.0000 -0.0197 0.0979 +CCP2 0.0400 -0.0194 0.0896 +CCP4 0.0731 -0.0185 0.0656 +CCP6 0.0937 -0.0172 0.0303 +TTP8 0.0981 -0.0156 -0.0103 +TTP10 0.0855 -0.0139 -0.0498 +TPP9 -0.0773 -0.0403 -0.0490 +TPP7 -0.0885 -0.0453 -0.0095 +CPP5 -0.0831 -0.0494 0.0254 +CPP3 -0.0641 -0.0530 0.0554 +CPP1 -0.0349 -0.0553 0.0755 +CPPz 0.0000 -0.0562 0.0826 +CPP2 0.0349 -0.0553 0.0756 +CPP4 0.0641 -0.0530 0.0554 +CPP6 0.0830 -0.0494 0.0254 +TPP8 0.0886 -0.0453 -0.0095 +TPP10 0.0772 -0.0403 -0.0490 +PPO9 -0.0614 -0.0631 -0.0473 +PPO7 -0.0703 -0.0706 -0.0080 +PPO5 -0.0631 -0.0757 0.0163 +PPO3 -0.0474 -0.0800 0.0364 +PPO1 -0.0255 -0.0828 0.0498 +PPOz 0.0000 -0.0838 0.0544 +PPO2 0.0254 -0.0828 0.0498 +PPO4 0.0475 -0.0800 0.0365 +PPO6 0.0631 -0.0757 0.0163 +PPO8 0.0703 -0.0706 -0.0080 +PPO10 0.0614 -0.0631 -0.0473 +POO9 -0.0396 -0.0800 -0.0449 +POO7 -0.0451 -0.0890 -0.0059 +POO5 -0.0367 -0.0929 0.0039 +POO3 -0.0259 -0.0958 0.0114 +POO1 -0.0134 -0.0977 0.0161 +POOz 0.0000 -0.0983 0.0177 +POO2 0.0134 -0.0977 0.0161 +POO4 0.0258 -0.0958 0.0113 +POO6 0.0367 -0.0929 0.0039 +POO8 0.0451 -0.0890 -0.0059 +POO10 0.0396 -0.0800 -0.0449 +OI1 -0.0295 -0.0923 -0.0246 +OIz -0.0000 -0.0975 -0.0218 +OI2 0.0295 -0.0922 -0.0246 +T3 -0.0994 0.0000 -0.0104 +T5 -0.0804 -0.0586 -0.0088 +T4 0.0994 0.0000 -0.0104 +T6 0.0804 -0.0587 -0.0088 +M1 -0.0707 -0.0130 -0.0707 +M2 0.0707 -0.0130 -0.0707 +A1 -0.0707 0.0000 -0.0707 +A2 0.0707 0.0000 -0.0707 diff --git a/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-5-Cap385_witheog.elp b/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-5-Cap385_witheog.elp new file mode 100755 index 00000000..28c0171b --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/Standard-10-5-Cap385_witheog.elp @@ -0,0 +1,357 @@ +346 + FID LPA -120.03 0 85 + FID RPA 120.03 0 85 + FID Nz 114.03 90 85 + EEG Fp1 -92.698 -72.074 85 + EEG Fpz 91.204 90 85 + EEG Fp2 92.698 72.074 85 + EEG AF9 -117.54 -54.695 85 + EEG AF7 -94.02 -54.108 85 + EEG AF5 -83.969 -59.461 85 + EEG AF3 -75.803 -67.539 85 + EEG AF1 -70.343 -77.973 85 + EEG AFz 68.39 90 85 + EEG AF2 70.358 78.046 85 + EEG AF4 75.803 67.539 85 + EEG AF6 83.969 59.461 85 + EEG AF8 94.016 54.142 85 + EEG AF10 117.52 54.733 85 + EEG F9 -118.84 -36.687 85 + EEG F7 -95.055 -36.087 85 + EEG F5 -77.687 -40.595 85 + EEG F3 -62.027 -50.053 85 + EEG F1 -50.225 -66.507 85 + EEG Fz 45.608 90 85 + EEG F2 50.181 66.507 85 + EEG F4 62.01 50.103 85 + EEG F6 77.631 40.595 85 + EEG F8 95.052 36.133 85 + EEG F10 118.84 36.687 85 + EEG FT9 -119.68 -18.393 85 + EEG FT7 -95.745 -18.052 85 + EEG FC5 -73.482 -20.668 85 + EEG FC3 -51.88 -27.575 85 + EEG FC1 -32.613 -45.075 85 + EEG FCz 22.792 90 85 + EEG FC2 32.613 45.075 85 + EEG FC4 51.88 27.575 85 + EEG FC6 73.482 20.668 85 + EEG FT8 95.745 18.052 85 + EEG FT10 119.68 18.393 85 + EEG T9 -120.03 0 85 + EEG T7 -95.973 0 85 + EEG C5 -71.982 0 85 + EEG C3 -48.004 0 85 + EEG C1 -23.974 0 85 + EEG Cz 0 90 85 + EEG C2 24.027 0 85 + EEG C4 48 0 85 + EEG C6 71.982 0 85 + EEG T8 95.973 0 85 + EEG T10 120.03 0 85 + EEG TP9 -119.68 18.393 85 + EEG TP7 -95.745 18.052 85 + EEG CP5 -73.482 20.668 85 + EEG CP3 -51.88 27.575 85 + EEG CP1 -32.613 45.075 85 + EEG CPz 22.792 -90 85 + EEG CP2 32.613 -45.075 85 + EEG CP4 51.88 -27.575 85 + EEG CP6 73.482 -20.668 85 + EEG TP8 95.743 -18.107 85 + EEG TP10 119.68 -18.393 85 + EEG P9 -118.84 36.687 85 + EEG P7 -95.055 36.087 85 + EEG P5 -77.687 40.595 85 + EEG P3 -62.027 50.053 85 + EEG P1 -50.225 66.507 85 + EEG Pz 45.608 -90 85 + EEG P2 50.181 -66.507 85 + EEG P4 62.01 -50.103 85 + EEG P6 77.631 -40.595 85 + EEG P8 95.052 -36.133 85 + EEG P10 118.84 -36.687 85 + EEG PO9 -117.54 54.695 85 + EEG PO7 -94.02 54.108 85 + EEG PO5 -83.969 59.461 85 + EEG PO3 -75.803 67.539 85 + EEG PO1 -70.343 77.973 85 + EEG POz 68.39 -90 85 + EEG PO2 70.358 -78.046 85 + EEG PO4 75.803 -67.539 85 + EEG PO6 83.969 -59.461 85 + EEG PO8 94.016 -54.142 85 + EEG PO10 117.52 -54.733 85 + EEG O1 -92.698 72.074 85 + EEG Oz 91.204 -90 85 + EEG O2 92.698 -72.074 85 + EEG I1 -115.86 72.532 85 + EEG Iz 114.03 -90 85 + EEG I2 115.86 -72.532 85 + EEG AFp9h -105.02 -63.355 85 + EEG AFp7h -90.401 -65.641 85 + EEG AFp5h -85.465 -71.565 85 + EEG AFp3h -81.886 -78.451 85 + EEG AFp1h -80.031 -86.097 85 + EEG AFp2h 80.032 86.039 85 + EEG AFp4h 81.886 78.451 85 + EEG AFp6h 85.465 71.565 85 + EEG AFp8h 90.401 65.589 85 + EEG AFp10h 105.03 63.329 85 + EEG AFF9h -106.39 -45.423 85 + EEG AFF7h -87.419 -47.151 85 + EEG AFF5h -74.258 -54.227 85 + EEG AFF3h -63.752 -65.551 85 + EEG AFF1h -57.79 -81.161 85 + EEG AFF2h 57.785 81.228 85 + EEG AFF4h 63.804 65.551 85 + EEG AFF6h 74.267 54.178 85 + EEG AFF8h 87.418 47.193 85 + EEG AFF10h 106.4 45.381 85 + EEG FFT9h -107.42 -27.291 85 + EEG FFT7h -85.294 -28.418 85 + EEG FFC5h -65.525 -34.337 85 + EEG FFC3h -47.97 -47.02 85 + EEG FFC1h -35.992 -72.367 85 + EEG FFC2h 35.992 72.367 85 + EEG FFC4h 47.944 47.077 85 + EEG FFC6h 65.577 34.337 85 + EEG FFT8h 85.294 28.418 85 + EEG FFT10h 107.4 27.263 85 + EEG FTT9h -107.94 -9.1355 85 + EEG FTT7h -84.139 -9.5002 85 + EEG FCC5h -60.628 -11.865 85 + EEG FCC3h -37.497 -18.197 85 + EEG FCC1h -16.49 -44 85 + EEG FCC2h 16.513 43.86 85 + EEG FCC4h 37.497 18.197 85 + EEG FCC6h 60.655 11.851 85 + EEG FTT8h 84.145 9.4907 85 + EEG FTT10h 107.94 9.1355 85 + EEG TTP9h -107.94 9.1355 85 + EEG TTP7h -84.139 9.5002 85 + EEG CCP5h -60.628 11.865 85 + EEG CCP3h -37.497 18.197 85 + EEG CCP1h -16.49 44 85 + EEG CCP2h 16.513 -43.86 85 + EEG CCP4h 37.497 -18.197 85 + EEG CCP6h 60.655 -11.851 85 + EEG TTP8h 84.145 -9.4907 85 + EEG TTP10h 107.94 -9.1355 85 + EEG TPP9h -107.42 27.291 85 + EEG TPP7h -85.294 28.418 85 + EEG CPP5h -65.525 34.337 85 + EEG CPP3h -47.97 47.02 85 + EEG CPP1h -35.992 72.367 85 + EEG CPP2h 35.992 -72.367 85 + EEG CPP4h 47.944 -47.077 85 + EEG CPP6h 65.577 -34.337 85 + EEG TPP8h 85.294 -28.418 85 + EEG TPP10h 107.4 -27.263 85 + EEG PPO9h -106.39 45.423 85 + EEG PPO7h -87.419 47.151 85 + EEG PPO5h -74.258 54.227 85 + EEG PPO3h -63.752 65.551 85 + EEG PPO1h -57.79 81.161 85 + EEG PPO2h 57.785 -81.228 85 + EEG PPO4h 63.804 -65.551 85 + EEG PPO6h 74.267 -54.178 85 + EEG PPO8h 87.418 -47.193 85 + EEG PPO10h 106.4 -45.381 85 + EEG POO9h -105.02 63.355 85 + EEG POO7h -90.401 65.641 85 + EEG POO5h -85.465 71.565 85 + EEG POO3h -81.886 78.451 85 + EEG POO1h -80.031 86.097 85 + EEG POO2h 80.032 -86.039 85 + EEG POO4h 81.886 -78.451 85 + EEG POO6h 85.465 -71.565 85 + EEG POO8h 90.401 -65.589 85 + EEG POO10h 105.03 -63.329 85 + EEG OI1h -103.42 81.128 85 + EEG OI2h 103.43 -81.119 85 + EEG Fp1h -91.951 -81.066 85 + EEG Fp2h 91.951 81.009 85 + EEG AF9h -105.74 -54.393 85 + EEG AF7h -88.796 -56.469 85 + EEG AF5h -79.619 -63.2 85 + EEG AF3h -72.656 -72.496 85 + EEG AF1h -68.886 -83.904 85 + EEG AF2h 68.939 83.904 85 + EEG AF4h 72.651 72.553 85 + EEG AF6h 79.619 63.2 85 + EEG AF8h 88.853 56.517 85 + EEG AF10h 105.74 54.393 85 + EEG F9h -106.98 -36.367 85 + EEG F7h -86.213 -37.789 85 + EEG F5h -69.502 -44.567 85 + EEG F3h -55.454 -57.294 85 + EEG F1h -46.82 -77.642 85 + EEG F2h 46.82 77.642 85 + EEG F4h 55.454 57.294 85 + EEG F6h 69.502 44.567 85 + EEG F8h 86.213 37.789 85 + EEG F10h 106.93 36.367 85 + EEG FT9h -107.72 -18.187 85 + EEG FT7h -84.603 -18.945 85 + EEG FC5h -62.534 -23.385 85 + EEG FC3h -41.758 -34.216 85 + EEG FC1h -25.615 -63.198 85 + EEG FC2h 25.592 63.316 85 + EEG FC4h 41.758 34.216 85 + EEG FC6h 62.534 23.385 85 + EEG FT8h 84.547 18.999 85 + EEG FT10h 107.72 18.187 85 + EEG T9h -108.02 0 85 + EEG T7h -83.97 0 85 + EEG C5h -59.971 0 85 + EEG C3h -35.998 0 85 + EEG C1h -12.007 0 85 + EEG C2h 12.007 0 85 + EEG C4h 35.964 0 85 + EEG C6h 59.971 0 85 + EEG T8h 83.97 0 85 + EEG T10h 108.02 0 85 + EEG TP9h -107.72 18.187 85 + EEG TP7h -84.603 18.945 85 + EEG CP5h -62.534 23.385 85 + EEG CP3h -41.758 34.216 85 + EEG CP1h -25.615 63.198 85 + EEG CP2h 25.592 -63.316 85 + EEG CP4h 41.758 -34.216 85 + EEG CP6h 62.534 -23.385 85 + EEG TP8h 84.604 -18.999 85 + EEG TP10h 107.72 -18.187 85 + EEG P9h -106.98 36.367 85 + EEG P7h -86.213 37.789 85 + EEG P5h -69.502 44.567 85 + EEG P3h -55.454 57.294 85 + EEG P1h -46.82 77.642 85 + EEG P2h 46.82 -77.642 85 + EEG P4h 55.454 -57.294 85 + EEG P6h 69.502 -44.567 85 + EEG P8h 86.213 -37.789 85 + EEG P10h 106.93 -36.367 85 + EEG PO9h -105.74 54.393 85 + EEG PO7h -88.796 56.469 85 + EEG PO5h -79.619 63.2 85 + EEG PO3h -72.656 72.496 85 + EEG PO1h -68.886 83.904 85 + EEG PO2h 68.939 -83.904 85 + EEG PO4h 72.651 -72.553 85 + EEG PO6h 79.619 -63.2 85 + EEG PO8h 88.853 -56.517 85 + EEG PO10h 105.74 -54.393 85 + EEG O1h -91.951 81.066 85 + EEG O2h 91.951 -81.009 85 + EEG I1h -114.91 81.307 85 + EEG I2h 114.91 -81.307 85 + EEG AFp9 -116.7 -63.665 85 + EEG AFp7 -93.384 -63.127 85 + EEG AFp5 -87.764 -68.444 85 + EEG AFp3 -83.447 -74.871 85 + EEG AFp1 -80.728 -82.19 85 + EEG AFpz 79.793 90 85 + EEG AFp2 80.728 82.19 85 + EEG AFp4 83.502 74.927 85 + EEG AFp6 87.764 68.444 85 + EEG AFp8 93.384 63.127 85 + EEG AFp10 116.7 63.665 85 + EEG AFF9 -118.25 -45.782 85 + EEG AFF7 -94.591 -45.122 85 + EEG AFF5 -80.608 -50.187 85 + EEG AFF3 -68.622 -59.353 85 + EEG AFF1 -60.101 -72.946 85 + EEG AFFz 57.01 90 85 + EEG AFF2 60.101 72.946 85 + EEG AFF4 68.579 59.3 85 + EEG AFF6 80.608 50.187 85 + EEG AFF8 94.591 45.122 85 + EEG AFF10 118.25 45.782 85 + EEG FFT9 -119.34 -27.535 85 + EEG FFT7 -95.458 -27.106 85 + EEG FFC5 -75.279 -30.73 85 + EEG FFC3 -56.333 -39.585 85 + EEG FFC1 -40.896 -57.744 85 + EEG FFCz 34.231 90 85 + EEG FFC2 40.859 57.744 85 + EEG FFC4 56.333 39.585 85 + EEG FFC6 75.266 30.76 85 + EEG FFT8 95.453 27.08 85 + EEG FFT10 119.36 27.565 85 + EEG FTT9 -119.94 -9.234 85 + EEG FTT7 -95.914 -9.0265 85 + EEG FCC5 -72.356 -10.402 85 + EEG FCC3 -49.021 -14.202 85 + EEG FCC1 -26.414 -25.873 85 + EEG FCCz 11.377 90 85 + EEG FCC2 26.389 25.873 85 + EEG FCC4 48.978 14.202 85 + EEG FCC6 72.356 10.402 85 + EEG FTT8 95.92 9.0356 85 + EEG FTT10 119.89 9.234 85 + EEG TTP9 -119.94 9.234 85 + EEG TTP7 -95.914 9.0265 85 + EEG CCP5 -72.356 10.402 85 + EEG CCP3 -49.021 14.202 85 + EEG CCP1 -26.414 25.873 85 + EEG CCPz 11.377 -90 85 + EEG CCP2 26.389 -25.873 85 + EEG CCP4 48.978 -14.202 85 + EEG CCP6 72.356 -10.402 85 + EEG TTP8 95.92 -9.0356 85 + EEG TTP10 119.89 -9.234 85 + EEG TPP9 -119.34 27.535 85 + EEG TPP7 -95.458 27.106 85 + EEG CPP5 -75.279 30.73 85 + EEG CPP3 -56.333 39.585 85 + EEG CPP1 -40.896 57.744 85 + EEG CPPz 34.231 -90 85 + EEG CPP2 40.859 -57.744 85 + EEG CPP4 56.333 -39.585 85 + EEG CPP6 75.266 -30.76 85 + EEG TPP8 95.453 -27.08 85 + EEG TPP10 119.36 -27.565 85 + EEG PPO9 -118.25 45.782 85 + EEG PPO7 -94.591 45.122 85 + EEG PPO5 -80.608 50.187 85 + EEG PPO3 -68.622 59.353 85 + EEG PPO1 -60.109 72.883 85 + EEG PPOz 57.01 -90 85 + EEG PPO2 60.101 -72.946 85 + EEG PPO4 68.579 -59.3 85 + EEG PPO6 80.608 -50.187 85 + EEG PPO8 94.591 -45.122 85 + EEG PPO10 118.25 -45.782 85 + EEG POO9 -116.7 63.665 85 + EEG POO7 -93.384 63.127 85 + EEG POO5 -87.764 68.444 85 + EEG POO3 -83.447 74.871 85 + EEG POO1 -80.728 82.19 85 + EEG POOz 79.793 -90 85 + EEG POO2 80.728 -82.19 85 + EEG POO4 83.502 -74.927 85 + EEG POO6 87.764 -68.444 85 + EEG POO8 93.384 -63.127 85 + EEG POO10 116.7 -63.665 85 + EEG OI1 -104.24 72.276 85 + EEG OIz 102.6 -90 85 + EEG OI2 104.26 -72.258 85 + EEG T3 -95.973 0 85 + EEG T5 -95.055 36.087 85 + EEG T4 95.973 0 85 + EEG T6 95.052 -36.133 85 + EEG M1 -134.52 10.419 85 + EEG M2 134.52 -10.419 85 + EEG A1 -135 0 85 + EEG A2 135 0 85 + EOG VEOG 125 63 85 + EOG HEOG -118 -48 85 + EOG EOG1 125 63 85 + EOG EOG2 -118 -48 85 + EOG LO1 -118 -48 85 + EOG LO2 118 48 85 + EOG IO1 -125 -63 85 + EOG IO2 125 63 85 + EOG SO1 -105 -65 85 + EOG SO2 105 65 85 diff --git a/studio_functions/Functions/EEGLAB/supportfiles/chan_file b/studio_functions/Functions/EEGLAB/supportfiles/chan_file new file mode 100755 index 00000000..aca04333 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/chan_file @@ -0,0 +1,21 @@ + 1 -18 .352 Fp1. + 2 18 .352 Fp2. + 3 -39 .231 F3.. + 4 39 .231 F4.. + 5 -90 .181 C3.. + 6 90 .181 C4.. + 7 -90 .500 A1.. + 8 90 .500 A2.. + 9 -142 .231 P3.. +10 142 .231 P4.. +11 -162 .352 O1.. +12 162 .352 O2.. +13 -54 .352 F7.. +14 54 .352 F8.. +15 -90 .352 T3.. +16 90 .352 T4.. +17 -126 .352 T5.. +18 126 .352 T6.. +19 0 .181 Fz.. +20 0 0 Cz.. +21 180 .181 Pz.. diff --git a/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh.mat b/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh.mat new file mode 100755 index 00000000..590cb1ac Binary files /dev/null and b/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh.mat differ diff --git a/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh.xyz b/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh.xyz new file mode 100755 index 00000000..c988bad6 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh.xyz @@ -0,0 +1,3 @@ +1 -91.2500 0.0846 -40.0000 NZ +2 14.9323 -85.0000 -40.0000 LPA +3 15.0677 85.0000 -40.0000 RPA diff --git a/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh_license.txt b/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh_license.txt new file mode 100755 index 00000000..392f2e77 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/colin27headmesh_license.txt @@ -0,0 +1,3 @@ +Copyright (C) 1993–2009 Louis Collins, McConnell Brain Imaging Centre, Montreal Neurological Institute, McGill University. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies. The authors and McGill University make no representations about the suitability of this software for any purpose. It is provided “as is” without express or implied warranty. The authors are not responsible for any data loss, equipment damage, property loss, or injury to subjects or patients resulting from the use or misuse of this software package. + + diff --git a/studio_functions/Functions/EEGLAB/supportfiles/eeglab1020.ced b/studio_functions/Functions/EEGLAB/supportfiles/eeglab1020.ced new file mode 100755 index 00000000..83234522 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/eeglab1020.ced @@ -0,0 +1,80 @@ +Number labels theta radius X Y Z sph_theta sph_phi sph_radius +1 Fp1 -18 0.511 0.95 0.309 -0.0349 18 -2 1 +2 Fp2 18 0.511 0.95 -0.309 -0.0349 -18 -2 1 +3 AF3 -23 0.411 0.885 0.376 0.276 23 16 1 +4 AF4 23 0.411 0.885 -0.376 0.276 -23 16 1 +5 AF7 -38 0.511 0.788 0.615 -0.0349 38 -2 1 +6 AF8 38 0.511 0.788 -0.615 -0.0349 -38 -2 1 +7 AF9 -43 0.639 0.663 0.618 -0.423 43 -25 1 +8 AF10 43 0.639 0.663 -0.618 -0.423 -43 -25 1 +9 F1 -22 0.278 0.71 0.287 0.643 22 40 1 +10 F2 22 0.278 0.71 -0.287 0.643 -22 40 1 +11 F3 -39 0.333 0.673 0.545 0.5 39 30 1 +12 F4 39 0.333 0.673 -0.545 0.5 -39 30 1 +13 F5 -49 0.417 0.634 0.729 0.259 49 15 1 +14 F6 49 0.417 0.634 -0.729 0.259 -49 15 1 +15 F7 -54 0.511 0.587 0.809 -0.0349 54 -2 1 +16 F8 54 0.511 0.587 -0.809 -0.0349 -54 -2 1 +17 F9 -55 0.639 0.52 0.742 -0.423 55 -25 1 +18 F10 55 0.639 0.52 -0.742 -0.423 -55 -25 1 +19 FC1 -45 0.178 0.375 0.375 0.848 45 58 1 +20 FC2 45 0.178 0.375 -0.375 0.848 -45 58 1 +21 FC3 -62 0.278 0.36 0.676 0.643 62 40 1 +22 FC4 62 0.278 0.36 -0.676 0.643 -62 40 1 +23 FC5 -69 0.394 0.339 0.883 0.326 69 19 1 +24 FC6 69 0.394 0.339 -0.883 0.326 -69 19 1 +25 FT7 -72 0.511 0.309 0.95 -0.0349 72 -2 1 +26 FT8 72 0.511 0.309 -0.95 -0.0349 -72 -2 1 +27 FT9 -72 0.639 0.28 0.862 -0.423 72 -25 1 +28 FT10 72 0.639 0.28 -0.862 -0.423 -72 -25 1 +29 C1 -90 0.128 2.39e-17 0.391 0.921 90 67 1 +30 C2 90 0.128 2.39e-17 -0.391 0.921 -90 67 1 +31 C3 -90 0.256 4.4e-17 0.719 0.695 90 44 1 +32 C4 90 0.256 4.4e-17 -0.719 0.695 -90 44 1 +33 C5 -90 0.383 5.72e-17 0.934 0.358 90 21 1 +34 C6 90 0.383 5.72e-17 -0.934 0.358 -90 21 1 +35 T7 -90 0.511 6.12e-17 0.999 -0.0349 90 -2 1 +36 T8 90 0.511 6.12e-17 -0.999 -0.0349 -90 -2 1 +37 T9 -90 0.639 5.55e-17 0.906 -0.423 90 -25 1 +38 T10 90 0.639 5.55e-17 -0.906 -0.423 -90 -25 1 +39 CP1 -135 0.178 -0.375 0.375 0.848 135 58 1 +40 CP2 135 0.178 -0.375 -0.375 0.848 -135 58 1 +41 CP3 -118 0.278 -0.36 0.676 0.643 118 40 1 +42 CP4 118 0.278 -0.36 -0.676 0.643 -118 40 1 +43 CP5 -111 0.394 -0.339 0.883 0.326 111 19 1 +44 CP6 111 0.394 -0.339 -0.883 0.326 -111 19 1 +45 TP7 -108 0.511 -0.309 0.95 -0.0349 108 -2 1 +46 TP8 108 0.511 -0.309 -0.95 -0.0349 -108 -2 1 +47 TP9 -108 0.639 -0.28 0.862 -0.423 108 -25 1 +48 TP10 108 0.639 -0.28 -0.862 -0.423 -108 -25 1 +49 P1 -158 0.278 -0.71 0.287 0.643 158 40 1 +50 P2 158 0.278 -0.71 -0.287 0.643 -158 40 1 +51 P3 -141 0.333 -0.673 0.545 0.5 141 30 1 +52 P4 141 0.333 -0.673 -0.545 0.5 -141 30 1 +53 P5 -131 0.417 -0.634 0.729 0.259 131 15 1 +54 P6 131 0.417 -0.634 -0.729 0.259 -131 15 1 +55 P7 -126 0.511 -0.587 0.809 -0.0349 126 -2 1 +56 P8 126 0.511 -0.587 -0.809 -0.0349 -126 -2 1 +57 P9 -126 0.639 -0.533 0.733 -0.423 126 -25 1 +58 P10 126 0.639 -0.533 -0.733 -0.423 -126 -25 1 +59 PO3 -157 0.411 -0.885 0.376 0.276 157 16 1 +60 PO4 157 0.411 -0.885 -0.376 0.276 -157 16 1 +61 PO7 -144 0.511 -0.809 0.587 -0.0349 144 -2 1 +62 PO8 144 0.511 -0.809 -0.587 -0.0349 -144 -2 1 +63 PO9 -144 0.639 -0.733 0.533 -0.423 144 -25 1 +64 PO10 144 0.639 -0.733 -0.533 -0.423 -144 -25 1 +65 O1 -162 0.511 -0.95 0.309 -0.0349 162 -2 1 +66 O2 162 0.511 -0.95 -0.309 -0.0349 -162 -2 1 +67 O9 -162 0.639 -0.862 0.28 -0.423 162 -25 1 +68 O10 162 0.639 -0.862 -0.28 -0.423 -162 -25 1 +69 CB1 -135 0.722 -0.542 0.542 -0.643 135 -40 1 +70 CB2 135 0.722 -0.542 -0.542 -0.643 -135 -40 1 +71 AFz 0 0.383 0.934 -0 0.358 -0 21 1 +72 POz 180 0.383 -0.934 -1.14e-16 0.358 -180 21 1 +73 Fpz 0 0.511 0.999 -0 -0.0349 -0 -2 1 +74 Oz 180 0.511 -0.999 -1.22e-16 -0.0349 -180 -2 1 +75 Fz 0 0.256 0.719 -0 0.695 -0 44 1 +76 Pz 180 0.256 -0.719 -8.81e-17 0.695 -180 44 1 +77 FCz 0 0.128 0.391 -0 0.921 -0 67 1 +78 CPz 180 0.128 -0.391 -4.79e-17 0.921 -180 67 1 +79 Cz 90 0 3.75e-33 -6.12e-17 1 -90 90 1 diff --git a/studio_functions/Functions/EEGLAB/supportfiles/eeglab_run_this_one_on_osx_or_linux b/studio_functions/Functions/EEGLAB/supportfiles/eeglab_run_this_one_on_osx_or_linux new file mode 100755 index 00000000..e2f9efb4 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/eeglab_run_this_one_on_osx_or_linux @@ -0,0 +1,4 @@ +#! /bin/bash +cd `dirname $0` +echo `pwd` +./eeglab.app/Contents/MacOS/applauncher diff --git a/studio_functions/Functions/EEGLAB/supportfiles/eeglab_run_this_one_on_windows.bat b/studio_functions/Functions/EEGLAB/supportfiles/eeglab_run_this_one_on_windows.bat new file mode 100755 index 00000000..3d62b545 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/eeglab_run_this_one_on_windows.bat @@ -0,0 +1 @@ +eeglab diff --git a/studio_functions/Functions/EEGLAB/supportfiles/head_modelColin27_5003_Standard-10-5-Cap339.mat b/studio_functions/Functions/EEGLAB/supportfiles/head_modelColin27_5003_Standard-10-5-Cap339.mat new file mode 100755 index 00000000..9c12c972 Binary files /dev/null and b/studio_functions/Functions/EEGLAB/supportfiles/head_modelColin27_5003_Standard-10-5-Cap339.mat differ diff --git a/studio_functions/Functions/EEGLAB/supportfiles/ica_linux b/studio_functions/Functions/EEGLAB/supportfiles/ica_linux new file mode 100755 index 00000000..bcd7fc36 Binary files /dev/null and b/studio_functions/Functions/EEGLAB/supportfiles/ica_linux differ diff --git a/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.elp b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.elp new file mode 100755 index 00000000..8d49003e --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.elp @@ -0,0 +1,372 @@ +3 2 +//Probe file +//Minor revision number +1 +//ProbeName +%N Name +//Probe type, number of sensors +0 72 +//Position of fiducials X+, Y+, Y- on the subject +%F 0.0955 0.0000 0.0000 +%F 0.0031 0.0681 0.0000 +%F -0.0031 -0.0681 0.0000 +//Sensor type +%S 400 +//Sensor name and data for sensor # 71 +%N LEYE +0.0572 0.0538 -0.0040 +//Sensor type +%S 400 +//Sensor name and data for sensor # 72 +%N REYE +0.0662 -0.0399 -0.0277 +//Sensor type +%S 400 +//Sensor name and data for sensor # 2 +%N FP1 +0.1068 0.0213 0.0441 +//Sensor type +%S 400 +//Sensor name and data for sensor # 3 +%N FPZ +0.1123 -0.0048 0.0441 +//Sensor type +%S 400 +//Sensor name and data for sensor # 4 +%N FP2 +0.1027 -0.0325 0.0457 +//Sensor type +%S 400 +//Sensor name and data for sensor # 5 +%N AF7 +0.0907 0.0445 0.0448 +//Sensor type +%S 400 +//Sensor name and data for sensor # 6 +%N AF3 +0.0937 0.0354 0.0688 +//Sensor type +%S 400 +//Sensor name and data for sensor # 7 +%N AFZ +0.0989 -0.0050 0.0794 +//Sensor type +%S 400 +//Sensor name and data for sensor # 8 +%N AF4 +0.0880 -0.0437 0.0673 +//Sensor type +%S 400 +//Sensor name and data for sensor # 9 +%N AF8 +0.0827 -0.0533 0.0408 +//Sensor type +%S 400 +//Sensor name and data for sensor # 10 +%N F9 +0.0533 0.0661 0.0232 +//Sensor type +%S 400 +//Sensor name and data for sensor # 11 +%N F7 +0.0675 0.0648 0.0442 +//Sensor type +%S 400 +//Sensor name and data for sensor # 12 +%N F5 +0.0729 0.0575 0.0678 +//Sensor type +%S 400 +//Sensor name and data for sensor # 13 +%N F3 +0.0752 0.0429 0.0897 +//Sensor type +%S 400 +//Sensor name and data for sensor # 14 +%N F1 +0.0806 0.0214 0.1010 +//Sensor type +%S 400 +//Sensor name and data for sensor # 15 +%N FZ +0.0818 -0.0038 0.1027 +//Sensor type +%S 400 +//Sensor name and data for sensor # 16 +%N F2 +0.0787 -0.0294 0.0977 +//Sensor type +%S 400 +//Sensor name and data for sensor # 17 +%N F4 +0.0709 -0.0492 0.0890 +//Sensor type +%S 400 +//Sensor name and data for sensor # 18 +%N F6 +0.0684 -0.0615 0.0658 +//Sensor type +%S 400 +//Sensor name and data for sensor # 19 +%N F8 +0.0602 -0.0684 0.0421 +//Sensor type +%S 400 +//Sensor name and data for sensor # 20 +%N F10 +0.0466 -0.0696 0.0220 +//Sensor type +%S 400 +//Sensor name and data for sensor # 21 +%N FT9 +0.0308 0.0728 0.0169 +//Sensor type +%S 400 +//Sensor name and data for sensor # 22 +%N FT7 +0.0404 0.0740 0.0474 +//Sensor type +%S 400 +//Sensor name and data for sensor # 23 +%N FC5 +0.0492 0.0673 0.0784 +//Sensor type +%S 400 +//Sensor name and data for sensor # 24 +%N FC3 +0.0519 0.0512 0.1034 +//Sensor type +%S 400 +//Sensor name and data for sensor # 25 +%N FC1 +0.0513 0.0249 0.1210 +//Sensor type +%S 400 +//Sensor name and data for sensor # 26 +%N FCZ +0.0555 -0.0060 0.1223 +//Sensor type +%S 400 +//Sensor name and data for sensor # 27 +%N FC2 +0.0519 -0.0339 0.1158 +//Sensor type +%S 400 +//Sensor name and data for sensor # 28 +%N FC4 +0.0463 -0.0571 0.1018 +//Sensor type +%S 400 +//Sensor name and data for sensor # 29 +%N FC6 +0.0397 -0.0723 0.0743 +//Sensor type +%S 400 +//Sensor name and data for sensor # 30 +%N FT8 +0.0333 -0.0786 0.0465 +//Sensor type +%S 400 +//Sensor name and data for sensor # 31 +%N FT10 +0.0249 -0.0761 0.0177 +//Sensor type +%S 400 +//Sensor name and data for sensor # 32 +%N T7 +0.0121 0.0810 0.0521 +//Sensor type +%S 400 +//Sensor name and data for sensor # 33 +%N C5 +0.0208 0.0757 0.0857 +//Sensor type +%S 400 +//Sensor name and data for sensor # 34 +%N C3 +0.0241 0.0582 0.1154 +//Sensor type +%S 400 +//Sensor name and data for sensor # 35 +%N C1 +0.0263 0.0311 0.1329 +//Sensor type +%S 400 +//Sensor name and data for sensor # 36 +%N CZ +0.0281 -0.0031 0.1397 +//Sensor type +%S 400 +//Sensor name and data for sensor # 37 +%N C2 +0.0244 -0.0363 0.1308 +//Sensor type +%S 400 +//Sensor name and data for sensor # 38 +%N C4 +0.0185 -0.0619 0.1133 +//Sensor type +%S 400 +//Sensor name and data for sensor # 39 +%N C6 +0.0131 -0.0770 0.0833 +//Sensor type +%S 400 +//Sensor name and data for sensor # 40 +%N T8 +0.0068 -0.0817 0.0501 +//Sensor type +%S 400 +//Sensor name and data for sensor # 41 +%N TP9 +-0.0199 0.0829 0.0312 +//Sensor type +%S 400 +//Sensor name and data for sensor # 42 +%N TP7 +-0.0127 0.0822 0.0625 +//Sensor type +%S 400 +//Sensor name and data for sensor # 43 +%N CP5 +-0.0102 0.0780 0.0938 +//Sensor type +%S 400 +//Sensor name and data for sensor # 44 +%N CP3 +-0.0042 0.0600 0.1217 +//Sensor type +%S 400 +//Sensor name and data for sensor # 45 +%N CP1 +-0.0033 0.0333 0.1407 +//Sensor type +%S 400 +//Sensor name and data for sensor # 46 +%N CPZ +-0.0045 0.0004 0.1455 +//Sensor type +%S 400 +//Sensor name and data for sensor # 47 +%N CP2 +-0.0052 -0.0366 0.1393 +//Sensor type +%S 400 +//Sensor name and data for sensor # 48 +%N CP4 +-0.0129 -0.0590 0.1219 +//Sensor type +%S 400 +//Sensor name and data for sensor # 49 +%N CP6 +-0.0181 -0.0743 0.0932 +//Sensor type +%S 400 +//Sensor name and data for sensor # 50 +%N TP8 +-0.0214 -0.0778 0.0631 +//Sensor type +%S 400 +//Sensor name and data for sensor # 51 +%N TP10 +-0.0304 -0.0793 0.0319 +//Sensor type +%S 400 +//Sensor name and data for sensor # 52 +%N P7 +-0.0389 0.0753 0.0700 +//Sensor type +%S 400 +//Sensor name and data for sensor # 53 +%N P5 +-0.0390 0.0692 0.0969 +//Sensor type +%S 400 +//Sensor name and data for sensor # 54 +%N P3 +-0.0362 0.0538 0.1200 +//Sensor type +%S 400 +//Sensor name and data for sensor # 55 +%N P1 +-0.0379 0.0292 0.1337 +//Sensor type +%S 400 +//Sensor name and data for sensor # 56 +%N PZ +-0.0366 0.0015 0.1387 +//Sensor type +%S 400 +//Sensor name and data for sensor # 57 +%N P2 +-0.0392 -0.0259 0.1340 +//Sensor type +%S 400 +//Sensor name and data for sensor # 58 +%N P4 +-0.0391 -0.0507 0.1203 +//Sensor type +%S 400 +//Sensor name and data for sensor # 59 +%N P6 +-0.0433 -0.0637 0.0947 +//Sensor type +%S 400 +//Sensor name and data for sensor # 60 +%N P8 +-0.0452 -0.0701 0.0696 +//Sensor type +%S 400 +//Sensor name and data for sensor # 61 +%N PO9 +-0.0696 0.0575 0.0513 +//Sensor type +%S 400 +//Sensor name and data for sensor # 62 +%N PO7 +-0.0627 0.0581 0.0816 +//Sensor type +%S 400 +//Sensor name and data for sensor # 63 +%N PO3 +-0.0604 0.0464 0.1057 +//Sensor type +%S 400 +//Sensor name and data for sensor # 64 +%N POZ +-0.0633 0.0022 0.1185 +//Sensor type +%S 400 +//Sensor name and data for sensor # 65 +%N PO4 +-0.0650 -0.0375 0.1059 +//Sensor type +%S 400 +//Sensor name and data for sensor # 66 +%N PO8 +-0.0684 -0.0462 0.0802 +//Sensor type +%S 400 +//Sensor name and data for sensor # 67 +%N PO10 +-0.0745 -0.0510 0.0526 +//Sensor type +%S 400 +//Sensor name and data for sensor # 68 +%N O1 +-0.0788 0.0314 0.0882 +//Sensor type +%S 400 +//Sensor name and data for sensor # 69 +%N OZ +-0.0841 0.0028 0.0903 +//Sensor type +%S 400 +//Sensor name and data for sensor # 70 +%N O2 +-0.0826 -0.0202 0.0901 +//Sensor type +%S 1C00 +//Sensor name and data for sensor # 1 +%N REF +-0.0395 -0.0622 0.0075 diff --git a/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.mat b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.mat new file mode 100755 index 00000000..d17bd09a Binary files /dev/null and b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.mat differ diff --git a/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.transform b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.transform new file mode 100755 index 00000000..758fe41c --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.transform @@ -0,0 +1,4 @@ +0 -3 -53.000 -0.200 0 -1.6 1000.0000 1000.0000 1000.0000 + +Original file is /data/common1/stern/eeg/jo74/jo74.elp +Nazion, LPA, RPA, REYE, slightly modified manually to appear on mesh diff --git a/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.xyz b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.xyz new file mode 100755 index 00000000..8397513f --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/mheadnew.xyz @@ -0,0 +1,75 @@ +1 -90.556 -2.7886 -34.035 Nz +2 1.9119 -68.161 -52.779 LPA +3 4.0881 68.161 -53.221 RPA +4 -52.291 -55.447 -45.873 LEYE +5 -68.498 37.95 -66.77 REYE +6 -92.256 -24.409 11.306 FP1 +7 -98.391 1.5188 12.55 FPZ +8 -89.461 29.487 12.372 FP2 +9 -75.68 -47.129 8.6605 AF7 +10 -74.112 -38.121 32.831 AF3 +11 -78.256 2.11 44.486 AFZ +12 -71.089 41.112 30.687 AF4 +13 -71.437 50.862 3.7189 AF8 +14 -42.715 -67.628 -20.061 F9 +15 -52.491 -66.743 3.3475 F7 +16 -53.301 -59.604 27.592 F5 +17 -51.621 -45.078 49.597 F3 +18 -55.282 -23.744 61.869 F1 +19 -56.841 1.4099 63.919 FZ +20 -55.53 27.089 58.552 F2 +21 -50.184 47.109 48.591 F4 +22 -52.696 59.477 25.428 F6 +23 -49.568 66.613 0.61239 F8 +24 -40.273 68.21 -21.781 F10 +25 -21.732 -73.668 -30.743 FT9 +26 -25.043 -75.148 1.0487 FT7 +27 -27.697 -68.708 33.217 FC5 +28 -25.836 -52.694 58.348 FC3 +29 -22.504 -26.387 75.631 FC1 +30 -27.245 4.3769 77.918 FCZ +31 -25.808 32.37 70.995 FC2 +32 -23.767 55.724 56.296 FC4 +33 -23.2 71.11 28.122 FC6 +34 -22.634 77.594 -0.35807 FT8 +35 -20.055 75.34 -30.267 FT10 +36 3.8149 -81.319 -0.0055424 T7 +37 1.8156 -76.275 34.683 C5 +38 3.9824 -58.879 64.548 C3 +39 4.5284 -31.855 82.293 C1 +40 3.1373 2.2782 89.514 CZ +41 4.0437 35.572 80.249 C2 +42 5.6143 61.333 62.074 C4 +43 4.5122 76.585 31.688 C6 +44 3.9537 81.467 -2.0743 T8 +45 31.066 -82.284 -26.855 TP9 +46 30.211 -81.794 5.2553 TP7 +47 33.86 -77.669 36.452 CP5 +48 33.01 -59.852 65.092 CP3 +49 35.139 -33.189 84.047 CP1 +50 36.326 -0.26843 88.704 CPZ +51 34.721 36.736 82.703 CP2 +52 38.167 59.352 64.251 CP4 +53 37.121 74.797 35.179 CP6 +54 34.274 78.392 5.0438 TP8 +55 36.85 80.154 -27.313 TP10 +56 57.17 -74.132 7.4429 P7 +57 62.438 -68.032 33.822 P5 +58 63.843 -52.72 57.107 P3 +59 67.526 -28.081 70.339 P1 +60 66.454 -0.43066 75.658 PZ +61 67.283 27.034 70.695 P2 +62 63.753 51.82 57.431 P4 +63 62.41 64.937 31.583 P6 +64 59.101 71.39 6.6433 P8 +65 83.021 -55.443 -16.878 PO9 +66 82.298 -56.244 14.185 PO7 +67 84.498 -44.617 38.329 PO3 +68 88.617 -0.35073 50.555 POZ +69 86.643 39.382 38.099 PO4 +70 84.619 48.178 12.286 PO8 +71 84.974 53.154 -15.947 PO10 +72 98.618 -29.086 17.611 O1 +73 103.41 -0.34313 18.783 OZ +74 101.24 22.603 19.018 O2 +75 41.406 63.327 -53.133 REF diff --git a/studio_functions/Functions/EEGLAB/supportfiles/test_compiled_version.m b/studio_functions/Functions/EEGLAB/supportfiles/test_compiled_version.m new file mode 100755 index 00000000..ff56ae43 --- /dev/null +++ b/studio_functions/Functions/EEGLAB/supportfiles/test_compiled_version.m @@ -0,0 +1,100 @@ +function test_compiled_version(varargin) +global CURRENTSTUDY CURRENTSET ALLEEG EEG STUDY + +res = questdlg2('Are you seeing the command line outputs?', 'Compiled version', 'No', 'Yes', 'Yes'); +if strcmpi(res, 'No') + res = questdlg2( [ 'Users need to be able to see command line' 10 ... + 'output even for the compiled version. This' 10 ... + 'require fixing and recompiling. Continue anyway?' ], 'Compiled version', 'No', 'Yes', 'Yes'); + if strcmpi(res, 'No') + return + end +end + +try + % EEGLAB history file generated on the 08-Jul-2020 + % ------------------------------------------------ + EEG = pop_loadset( 'filename', 'eeglab_data.set', 'filepath', 'sample_data'); + EEG = eeg_checkset( EEG ); + EEG = pop_loadset('filename','eeglab_data.set','filepath','sample_data'); + EEG = eeg_checkset( EEG ); + EEG.etc.eeglabvers = 'development head'; % this tracks which version of EEGLAB is being used, you may ignore it + EEG = pop_loadset('filename','eeglab_data.set','filepath','sample_data'); + EEG = eeg_checkset( EEG ); + EEG=pop_chanedit(EEG, 'lookup',fullfile('plugins','dipfit','standard_BESA','standard-10-5-cap385.elp'),'load',{fullfile('sample_data','eeglab_chan32.locs') 'filetype' 'autodetect'}); + EEG = eeg_checkset( EEG ); + EEG.etc.eeglabvers = '2020.0'; % this tracks which version of EEGLAB is being used, you may ignore it + EEG = pop_loadset('filename','eeglab_data.set','filepath','sample_data'); + EEG = eeg_checkset( EEG ); + EEG=pop_chanedit(EEG, 'lookup',fullfile('plugins','dipfit','standard_BEM','elec', 'standard_1005.elc')); + EEG = eeg_checkset( EEG ); + EEG = pop_clean_rawdata(EEG, 'FlatlineCriterion',5,'ChannelCriterion',0.8,'LineNoiseCriterion',4,'Highpass','off','BurstCriterion',20,'WindowCriterion',0.25,'BurstRejection','on','Distance','Euclidian','WindowCriterionTolerances',[-Inf 7] ); + EEG = eeg_checkset( EEG ); + EEG = eeg_checkset( EEG ); + %EEG = pop_runica(EEG, 'icatype', 'runica', 'extended',1,'interrupt','on', 'pca', 10); + EEG = pop_runica(EEG, 'icatype', 'picard', 'pca', 10); + EEG = eeg_checkset( EEG ); + EEG = pop_iclabel(EEG, 'default'); + EEG = eeg_checkset( EEG ); + EEG = pop_dipfit_settings( EEG, 'hdmfile',fullfile('plugins','dipfit','standard_BEM','standard_vol.mat'),'coordformat','MNI','mrifile',fullfile('plugins','dipfit','standard_BEM','standard_mri.mat'),'chanfile',fullfile('plugins','dipfit','standard_BEM','elec', 'standard_1005.elc'),'coord_transform',[0 0 0 0 0 -1.5708 1 1 1] ,'chansel',[1:31] ); + EEG = eeg_checkset( EEG ); + EEG = pop_multifit(EEG, 1,'threshold',100,'plotopt',{'normlen','on'}); + EEG = eeg_checkset( EEG ); + EEG = pop_headplot(EEG, 0, [1:3] , 'Components of dataset: Continuous EEG Data', [2 2], 'setup',{'eeglab_data.spl','meshfile','mheadnew.mat','transform',[-1.136 7.7523 11.4527 -0.027117 0.015531 -1.5455 0.91234 0.93161 0.80698] }); + close; + EEG = pop_loadset( 'filename', 'eeglab_data_epochs_ica.set', 'filepath', 'sample_data'); + EEG = pop_dipfit_settings( EEG, 'hdmfile',fullfile('plugins','dipfit','standard_BEM','standard_vol.mat'),'coordformat','MNI','mrifile',fullfile('plugins','dipfit','standard_BEM','standard_mri.mat'),'chanfile',fullfile('plugins','dipfit','standard_BEM','elec', 'standard_1005.elc'),'coord_transform',[0.83215 -15.6287 2.4114 0.081214 0.00093739 -1.5732 1.1742 1.0601 1.1485],'chansel',[1:31] ); + EEG = pop_leadfield(EEG, 'sourcemodel','LORETA-Talairach-BAs.mat','sourcemodel2mni',[],'downsample',1); + pop_dipfit_loreta(EEG, 6); + close + + % STUDY + % ----- + STUDY = []; CURRENTSTUDY = 0; ALLEEG = []; EEG=[]; CURRENTSET=[]; + pop_editoptions( 'option_storedisk', 1); + + commands = {}; + EEG = pop_loadset('filename','eeglab_data_epochs_ica.set','filepath','sample_data'); + for iS = 1:10 + fileName1 = sprintf('eeglab_data_epochs_ica_c1_%d.set', iS); + EEG2 = EEG; EEG2.data = EEG2.data+rand(EEG.nbchan, EEG.pnts, EEG.trials)*20-10; + pop_saveset(EEG2, 'filename',fileName1); + + fileName2 = sprintf('eeglab_data_epochs_ica_c2_%d.set', iS); + EEG2 = EEG; EEG2.data = EEG2.data+rand(EEG.nbchan, EEG.pnts, EEG.trials)*20-10; + EEG2.data(:, 129:end,:) = EEG2.data(:, 129:end,:)+rand(EEG.nbchan, 256, EEG.trials)*20-5; + pop_saveset(EEG2, 'filename',fileName2); + + commands = { commands{:} ... + { 'index' iS*2-1 'load' fileName1 'subject' sprintf('S%d', iS) 'condition' '1' } ... + { 'index' iS*2 'load' fileName2 'subject' sprintf('S%d', iS) 'condition' '2' } }; + end + + [STUDY, ALLEEG] = std_editset(STUDY, ALLEEG, 'commands', commands); + CURRENTSTUDY = 1; EEG = ALLEEG; CURRENTSET = [1:length(EEG)]; + STUDY = std_makedesign(STUDY, ALLEEG); + + [STUDY, ALLEEG] = std_precomp(STUDY, ALLEEG, {},'savetrials','on','interp','on','recompute','on','erp','on'); + STUDY = std_erpplot(STUDY,ALLEEG,'channels',{'Fz'}, 'design', 1); + close; + + STUDY = pop_statparams(STUDY, 'mode','fieldtrip', 'condstats', 'on'); + STUDY = std_erpplot(STUDY,ALLEEG,'channels',{'Fz'}, 'design', 1); + close; + + % cleaning up + delete('eeglab_data_epochs_ica_*.*'); + delete('*.daterp'); + delete('eeglab_data.spl'); + +catch lasterr + % show error on command line + disp(lasterr.getReport()) + warndlg2( [ 'Script failed with error below (see also command line). Fix and try again.' 10 10 ... + lasterr.message ], 'Compiled version'); + return +end + +warndlg2( [ 'Script run successfully.' ], 'Compiled version'); + +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERPLAB_ERP_Viewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERPLAB_ERP_Viewer.m new file mode 100755 index 00000000..13bf1d1d --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERPLAB_ERP_Viewer.m @@ -0,0 +1,432 @@ + +% New ERP viewer GUI Layout - Simple ERP viewer 0.014 +% +% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + +% ERPLAB Studio Toolbox +% + +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +% Reqs: +% - data loaded in valid ERPset +% - GUI Layout Toolbox +% - EEGLAB and ERPLAB + + +% +% Demo to explore an ERP Viewer using the new GUI Layout Toolbox +% Now with more in nested functions + +function ERPLAB_ERP_Viewer(ALLERP,selectedERP_index,binArray,chanArray,Parameterfile) + +global viewer_ERPDAT; +global gui_erp_waviewer; +ERPtooltype = erpgettoolversion('tooltype'); +% global observe_ERPDAT; +% if ~strcmpi(ERPtooltype,'EStudio') +viewer_ERPDAT = v_ERPDAT; +% end +% addlistener(observe_ERPDAT,'erpschange',@allErpChanged); +if ~strcmpi(ERPtooltype,'EStudio') && ~strcmpi(ERPtooltype,'ERPLAB') + global observe_ERPDAT; + observe_ERPDAT = o_ERPDAT; + observe_ERPDAT.Two_GUI = 0; + observe_ERPDAT.ALLERP = []; + observe_ERPDAT.CURRENTERP = []; + observe_ERPDAT.ERP = []; + observe_ERPDAT.Count_ERP = 0; + observe_ERPDAT.Count_currentERP = 0; + observe_ERPDAT.Process_messg = 0; +end +try + close(EStudio_gui_erp_totl.Window); +catch +end + +if nargin<1 + beep; + disp('ERP_wave_viewer() error: ALLERP should be imported.'); + return; +end + +if isempty(ALLERP) + beep; + disp('ERP_wave_viewer() error: The imported ALLERP is empty.'); + return; +end + +%%checking datatype +counterp = 0; +datatypeFlag = []; +for Numoferpset = 1:length(ALLERP) + if ~strcmpi(ALLERP(Numoferpset).datatype, 'ERP') && ~strcmpi(ALLERP(Numoferpset).datatype, 'CSD') + counterp = counterp+1; + datatypeFlag(counterp) = Numoferpset; + end +end +if ~isempty(datatypeFlag) + msgboxText = ['ERP Wave Viewer donot support to plot the wave for the data that donot belong to "ERP" or "CSD".\n'... + 'Please remove the following ERPset with index(es):',32,num2str(datatypeFlag),'.']; + if strcmpi(ERPtooltype,'ERPLAB') + title_msg = 'ERPLAB: ERPLAB_ERP_Viewer() datatype error:'; + elseif strcmpi(ERPtooltype,'EStudio') + title_msg = 'EStudio: ERPLAB_ERP_Viewer() datatype error:'; + else + title_msg = ' ERPLAB_ERP_Viewer() datatype error:'; + end + errorfound(sprintf(msgboxText), title_msg); + return; +end + + + +if nargin<2 + selectedERP_index = length(ALLERP); + try + binArray = [1:ALLERP(selectedERP_index(end)).nbin]; + chanArray =[1:ALLERP(selectedERP_index(end)).nchan]; + catch + binArray = [1:ALLERP(end).nbin]; + chanArray =[1:ALLERP(end).nchan]; + end + Parameterfile = []; +end +if isempty(selectedERP_index) || min(selectedERP_index)<=0 || max(selectedERP_index)>length(ALLERP) + selectedERP_index = length(ALLERP); +end + +if nargin<3 + try + binArray = [1:ALLERP(selectedERP_index(end)).nbin]; + chanArray =[1:ALLERP(selectedERP_index(end)).nchan]; + catch + binArray = [1:ALLERP(end).nbin]; + chanArray =[1:ALLERP(end).nchan]; + end + Parameterfile = []; +end + +if nargin<4 + try + chanArray =[1:ALLERP(selectedERP_index(end)).nchan]; + catch + chanArray =[1:ALLERP(end).nchan]; + end + Parameterfile = []; +end +if nargin<5 + Parameterfile = []; +end +if nargin>6 + help ERP_wave_viewer; + return; +end + + +% if ~strcmpi(ERPtooltype,'EStudio') +% addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +% addlistener(viewer_ERPDAT,'v_currentERP_change',@v_currentERP_change); +% addlistener(viewer_ERPDAT,'v_messg_change',@V_messg_change); +% addlistener(viewer_ERPDAT,'count_legend_change',@count_legend_change); +% addlistener(viewer_ERPDAT,'page_xyaxis_change',@page_xyaxis_change); +% % end + + +viewer_ERPDAT.Count_currentERP = 0; +% viewer_ERPDAT.Process_messg = 0;%0 is the default means there is no message for processing procedure; +%1 means the processign procedure is running +%2 means the processign procedure is done +%3 means there are some errors for processing procedure +viewer_ERPDAT.count_legend=0;%% this is to capture the changes of legend name +viewer_ERPDAT.page_xyaxis=0;%%get the changes of x/y axis based on the changed pages or selected ERPsets +viewer_ERPDAT.count_loadproper = 0; +viewer_ERPDAT.Process_messg = 0; +viewer_ERPDAT.count_twopanels = 0;%% Automaticlly saving the changes on the other panel if the current panel is changed +viewer_ERPDAT.Reset_Waviewer_panel = 0; + +viewer_ERPDAT.ALLERP = ALLERP; +viewer_ERPDAT.ERP_bin = binArray; +viewer_ERPDAT.ERP_chan = chanArray; +% +% Count_ERP = 1; +% Count_currentERP =0; +% Sanity checks +try + test = uix.HBoxFlex(); +catch + beep; + disp('The GUI Layout Toolbox might not be installed. Quitting') + return +end + +%%Setting the flags for all panels that are used to get the changes from +%%each panel +estudioworkingmemory('MyViewer_ERPsetpanel',0); +estudioworkingmemory('MyViewer_chanbin',0); +estudioworkingmemory('MyViewer_xyaxis',0); +estudioworkingmemory('MyViewer_plotorg',0); +estudioworkingmemory('MyViewer_labels',0); +estudioworkingmemory('MyViewer_linelegend',0); +estudioworkingmemory('MyViewer_other',0); + +ERPwaviewer.ALLERP =ALLERP; +ERPwaviewer.ERP = ALLERP(selectedERP_index(end)); +ERPwaviewer.CURRENTERP =selectedERP_index(end); +ERPwaviewer.SelectERPIdx =selectedERP_index; +ERPwaviewer.bin = binArray; +ERPwaviewer.chan = chanArray; +ERPwaviewer.erp_binchan_op = 1;%% 1. Auto; 2.Custom +ERPwaviewer.binchan_op = 1;%% 1. Auto; 2.Custom + +ERPwaviewer.plot_org.Grid = 1; %1.Channels; 2.Bins; 3. ERPsets; 4. None +ERPwaviewer.plot_org.Overlay = 2; %1.Channels; 2.Bins; 3. ERPsets; 4. None +ERPwaviewer.plot_org.Pages = 3; %1.Channels; 2.Bins; 3. ERPsets; 4. None +ERPwaviewer.plot_org.gridlayout.op = 1; %1.Auto; 2. Custom +ERPwaviewer.plot_org.gridlayout.data = []; +ERPwaviewer.Lines = []; +ERPwaviewer.Legend = []; +ERPwaviewer.xaxis = []; +ERPwaviewer.yaxis = []; +ERPwaviewer.polarity = []; +ERPwaviewer.SEM = []; +ERPwaviewer.PageIndex = 1; +ERPwaviewer.baselinecorr = 'none'; +ERPwaviewer.chanbinsetlabel = []; +ERPwaviewer.figbackgdcolor = []; +ERPwaviewer.figname = 'My Viewer'; +assignin('base','ALLERPwaviewer',ERPwaviewer); + +estudioworkingmemory('zoomSpace',0);%%sett for zoom in and zoom out +try + close(gui_erp_waviewer.Window);%%close previous GUI if exists +catch +end + +gui_erp_waviewer = struct(); + +gui_erp_waviewer = createInterface(); + +f_redrawERP_viewer_test(); +if ~isempty( Parameterfile)%% update the panels based on the saved file + + if isempty(Parameterfile.ALLERP) + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Do you want to use the default "ALLERP"? \n Because there is no "ALLERP" in the "Parameterfile"']; + title = 'My Viewer>ERPLAB_ERP_Viewer'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + + if strcmpi(button,'Yes') + ERPwaviewerdef = evalin('base','ALLERPwaviewer'); + Parameterfile.ALLERP= ERPwaviewerdef.ALLERP; + Parameterfile.ERP = ERPwaviewerdef.ERP; + else + if strcmpi(button,'No') + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > ERPLAB_ERP_Viewer: \n Cannot use the file because no ALLERP can be used.\n\n'); + else + beep + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > ERPLAB_ERP_Viewer: \n User selected cancel.\n\n'); + end + return; + end + end + assignin('base','ALLERPwaviewer',Parameterfile); + viewer_ERPDAT.count_loadproper = viewer_ERPDAT.count_loadproper+1; + f_redrawERP_viewer_test(); +end + + function gui_erp_waviewer = createInterface(); + ERPtooltype = erpgettoolversion('tooltype'); + + if strcmpi(ERPtooltype,'EStudio') + try + [version reldate] = geterplabstudioversion; + erplabstudiover = version; + catch + erplabstudiover = '??'; + end + + currvers = ['ERPLAB Studio ' erplabstudiover,'- My Viewer']; + else + try + [version reldate] = geterplabversion; + erplabstudiover = version; + catch + erplabstudiover = '??'; + end + + currvers = ['ERPLAB ' erplabstudiover,'- My Viewer']; + end + estudioworkingmemory('viewername','My Viewer'); + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + catch + ColorBviewer_def = [0.7765,0.7294,0.8627]; + end + % gui_erp_waviewer = struct(); + % First, let's start the window + gui_erp_waviewer.Window = figure( 'Name', currvers, ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off', 'tag', 'rollover'); + + + new_pos = [1 1 1000 1000]; + set(gui_erp_waviewer.Window, 'Position', new_pos); + + % + View menu + gui_erp_waviewer.exit = uimenu( gui_erp_waviewer.Window, 'Label','Exit', 'Callback', @onExit); + gui_erp_waviewer.help = uimenu( gui_erp_waviewer.Window, 'Label', 'Help', 'Callback', @onhelp); + + %%-----------Setting------------------------------------------------ + %% Create tabs + context_tabs = uix.VBox('Parent', gui_erp_waviewer.Window); + gui_erp_waviewer.tabERP = uix.HBoxFlex( 'Parent', context_tabs, 'Spacing', 10,'BackgroundColor',ColorBviewer_def); + %% Arrange the main interface for ERP panel (Tab3) + gui_erp_waviewer.ViewBox = uix.VBox('Parent', gui_erp_waviewer.tabERP,'BackgroundColor',ColorBviewer_def); + + + gui_erp_waviewer.ViewPanel = uix.BoxPanel('Parent', gui_erp_waviewer.ViewBox,'TitleColor',ColorBviewer_def,'ForegroundColor','k');% + gui_erp_waviewer.ViewContainer = uicontainer('Parent', gui_erp_waviewer.ViewPanel); + + gui_erp_waviewer.panelscroll = uix.ScrollingPanel('Parent', gui_erp_waviewer.tabERP); + set(gui_erp_waviewer.panelscroll,'BackgroundColor',ColorBviewer_def); + % + Adjust the main layout + set( gui_erp_waviewer.tabERP, 'Widths', [-4, 270]); % Viewpanel and settings panel + + + gui_erp_waviewer.panel_fonts = f_get_default_fontsize(); %% get the default fontsize based on the different plat form, e.g., Mac + + gui_erp_waviewer.settingLayout = uiextras.VBox('Parent', gui_erp_waviewer.panelscroll,'BackgroundColor',ColorBviewer_def); + + % + Create the settings window panels for ERP panel + gui_erp_waviewer.panel{1} = f_ERPsets_waviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(1) = 280; + + gui_erp_waviewer.panel{2} = f_ERP_Binchan_waviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(2) = 280; + + gui_erp_waviewer.panel{3} = f_ERP_timeampscal_waveviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(3) = 490; + + gui_erp_waviewer.panel{4} = f_ERP_plotorg_waveviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(4) = 405; + + gui_erp_waviewer.panel{5} = f_ERP_labelset_waveviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(5) = 200; + + gui_erp_waviewer.panel{6} = f_ERP_lineset_waveviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(6) = 555; + + gui_erp_waviewer.panel{7} = f_ERP_otherset_waveviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(7) = 225; + + gui_erp_waviewer.panel{8} = f_ERP_property_waveviewer_GUI(gui_erp_waviewer.settingLayout,gui_erp_waviewer.panel_fonts); + gui_erp_waviewer.panelSizes(8) = 90; + + set(gui_erp_waviewer.settingLayout, 'Heights', gui_erp_waviewer.panelSizes); + gui_erp_waviewer.panelscroll.Heights = sum(gui_erp_waviewer.panelSizes); + + %% Hook up the minimize callback and IsMinimized + set( gui_erp_waviewer.panel{1}, 'MinimizeFcn', {@nMinimize, 1} ); + set( gui_erp_waviewer.panel{2}, 'MinimizeFcn', {@nMinimize, 2}); + set( gui_erp_waviewer.panel{3}, 'MinimizeFcn', {@nMinimize, 3}); + set( gui_erp_waviewer.panel{4}, 'MinimizeFcn', {@nMinimize, 4}); + set( gui_erp_waviewer.panel{5}, 'MinimizeFcn', {@nMinimize, 5}); + set( gui_erp_waviewer.panel{6}, 'MinimizeFcn', {@nMinimize, 6}); + set( gui_erp_waviewer.panel{7}, 'MinimizeFcn', {@nMinimize, 7}); + set( gui_erp_waviewer.panel{8}, 'MinimizeFcn', {@nMinimize, 8}); + whichpanel = [4:8]; + for Numofpanel = 1:length(whichpanel) + minned = gui_erp_waviewer.panel{whichpanel(Numofpanel)}.IsMinimized; + szs = get( gui_erp_waviewer.settingLayout, 'Sizes' ); + if minned + set( gui_erp_waviewer.panel{whichpanel(Numofpanel)}, 'IsMinimized', false); + szs(whichpanel(Numofpanel)) = gui_erp_waviewer.panelSizes(whichpanel(Numofpanel)); + else + set( gui_erp_waviewer.panel{whichpanel(Numofpanel)}, 'IsMinimized', true); + szs(whichpanel(Numofpanel)) = 25; + end + set( gui_erp_waviewer.settingLayout, 'Sizes', szs ); + gui_erp_waviewer.panelscroll.Heights = sum(szs); + end + %% + Create the view + p = gui_erp_waviewer.ViewContainer; + gui_erp_waviewer.ViewAxes = uiextras.HBox( 'Parent', p,'BackgroundColor',ColorBviewer_def); + + end % createInterface + + + function nMinimize( eventSource, eventData, whichpanel) %#ok + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + catch + ColorBviewer_def = [0.7020 0.77 0.85]; + end + minned = gui_erp_waviewer.panel{whichpanel}.IsMinimized; + szs = get( gui_erp_waviewer.settingLayout, 'Sizes' ); + if minned + set( gui_erp_waviewer.panel{whichpanel}, 'IsMinimized', false); + szs(whichpanel) = gui_erp_waviewer.panelSizes(whichpanel); + else + set( gui_erp_waviewer.panel{whichpanel}, 'IsMinimized', true); + szs(whichpanel) = 25; + end + set( gui_erp_waviewer.settingLayout, 'Sizes', szs ,'BackgroundColor',ColorBviewer_def); + gui_erp_waviewer.panelscroll.Heights = sum(szs); + set(gui_erp_waviewer.panelscroll,'BackgroundColor',ColorBviewer_def); + end % nMinimize + + +%%--------------------Function is to close the toolbox--------------------- + function onExit(~,~) + BackERPLABcolor1 = [1 0.9 0.3]; % yellow + question1 = ['Are you sure to quit "ERP wave viewer"?']; + title1 = 'My Viewer>Exit'; + oldcolor1 = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor1) + button1 = questdlg(sprintf(question1), title1,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor1); + if strcmpi(button1,'Yes') + try + close(gui_erp_waviewer.Window); + clear ALLERPwaviewer; + catch + return; + end + else + return; + end + end + +%%-------------Help for my Viewer------------------------------------------ + function onhelp(~,~) + + + end + +%%%%%%%%%%%%%%%%%%%%%%% +end % end of the function \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERP_layoutstringGUI.fig b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERP_layoutstringGUI.fig new file mode 100644 index 00000000..bd47ae8f Binary files /dev/null and b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERP_layoutstringGUI.fig differ diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERP_layoutstringGUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERP_layoutstringGUI.m new file mode 100644 index 00000000..226b107b --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/ERP_layoutstringGUI.m @@ -0,0 +1,251 @@ +function varargout = ERP_layoutstringGUI(varargin) +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @ERP_layoutstringGUI_OpeningFcn, ... + 'gui_OutputFcn', @ERP_layoutstringGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%----------------------------------------------------------------------------------- +function ERP_layoutstringGUI_OpeningFcn(hObject, eventdata, handles, varargin) +handles.output = []; + +try + plotArray = varargin{1}; +catch + for ii = 1:100 + plotArray{ii,1} = ['chan-',num2str(ii)]; + end +end +for jj = 1:length(plotArray) + plotArrayFormt(jj,1) = {char(plotArray{jj})}; +end +plotArrayFormt(length(plotArrayFormt)+1) = {'None'}; + +try + plotArrayFormtOlder = varargin{2}; +catch + plotArrayFormtOlder = plotArrayFormt; +end + +handles.plotArrayFormtOlder = plotArrayFormtOlder; + +handles.plotArrayFormt = plotArrayFormt; + +plotBoxdef = f_getrow_columnautowaveplot(plotArray); +try + plotBox = varargin{3}; +catch + plotBox = plotBoxdef; +end +Numrows = plotBox(1); +Numcolumns = plotBox(2); +% GridinforDatadef = cell(Numrows,Numcolumns); +count = 0; +for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + count = count +1; + if count> numel(plotArray) + GridinforDatadef{Numofrows,Numofcolumns} = char('None'); + else + GridinforDatadef{Numofrows,Numofcolumns} = char(plotArray{count}); + end + end +end + +try + GridinforData = varargin{4}; +catch + GridinforData = GridinforDatadef; +end +if isempty(GridinforData) + GridinforData = GridinforDatadef; +end + +if size(GridinforData,1)~= Numrows || size(GridinforData,2)~= Numcolumns + GridinforData = GridinforDatadef; +end +FonsizeDefault = f_get_default_fontsize(); +% tablePosition = handles.uitable1_layout.Position; +for Numofcolumns = 1:Numcolumns + if size(plotArrayFormt,1) > size(plotArrayFormt,2) + columFormat{Numofcolumns} = plotArrayFormt'; + else + columFormat{Numofcolumns} = plotArrayFormt; + end + ColumnEditable(Numofcolumns) =1; + ColumnName{1,Numofcolumns} = char(['C',num2str(Numofcolumns)]); + % ColumnWidth{Numofcolumns} =tablePosition(3)/(Numcolumns+0.2); +end + +for Numofrows = 1:Numrows + RowName{1,Numofrows} = char(['R',num2str(Numofrows)]); +end +set(handles.uitable1_layout,'Data',GridinforData); +handles.uitable1_layout.ColumnEditable = logical(ColumnEditable); +% handles.uitable1_layout.ColumnWidth = ColumnWidth; +handles.uitable1_layout.ColumnName = ColumnName; +handles.uitable1_layout.RowName = RowName; +handles.uitable1_layout.ColumnFormat = columFormat; +handles.uitable1_layout.FontSize = FonsizeDefault; +% +% Color GUI +% +% handles = painterplab(handles); +[version reldate,ColorBdef,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +set(handles.gui_chassis, 'Color', ColorBviewer_def); +% +% Set font size +% +% handles = setfonterplab(handles); + +% Update handles structure + + + +guidata(hObject, handles); + +set(handles.gui_chassis, 'Name', 'Plot Organinzation > Grid Layout', 'WindowStyle','modal'); + +% UIWAIT makes ERP_layoutstringGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + +%----------------------------------------------------------------------------------- +function varargout = ERP_layoutstringGUI_OutputFcn(hObject, eventdata, handles) +try + varargout{1} = handles.output; +catch + varargout{1} = []; +end +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +%---------------------------------------------------------------------------------- +% function listbox_list_Callback(hObject, eventdata, handles) +% +% %---------------------------------------------------------------------------------- +% function listbox_list_CreateFcn(hObject, eventdata, handles) +% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) +% set(hObject,'BackgroundColor','white'); +% end + +%---------------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); +%---------------------------------------------------------------------------------- +function pushbutton_ok_Callback(hObject, eventdata, handles) + +Data = get(handles.uitable1_layout, 'Data'); +plotArrayFormt = handles.plotArrayFormt; +handles.output = {Data,plotArrayFormt}; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%---------------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + % The GUI is still in UIWAIT, us UIRESUME + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes on button press in pushbutton_edit. +function pushbutton_edit_Callback(hObject, eventdata, handles) +plotArrayFormt = handles.plotArrayFormt; +plotArrayFormtOld=handles.plotArrayFormtOlder; +for ii = 1:length(plotArrayFormtOld)-1 + plotArrayFormtOldin{ii,1} = plotArrayFormtOld{ii}; +end +[Numrows,Numcolumns]= size(plotArrayFormt); + +if Numrows ==1 && Numcolumns>=2 + for Numofcolumns = 1:Numcolumns-1 + plotArrayFormtin{Numofcolumns,1} = char(plotArrayFormt{Numofcolumns}); + end +elseif Numrows >=2 && Numcolumns==1 + for Numofrows = 1:Numrows-1 + plotArrayFormtin{Numofrows,1} = char(plotArrayFormt{Numofrows}); + end +else + return; +end +try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + PLOTORG(1) = ERPwaviewerin.plot_org.Grid; + PLOTORG(2) = ERPwaviewerin.plot_org.Overlay ; + PLOTORG(3) = ERPwaviewerin.plot_org.Pages; +catch + PLOTORG = [1 2 3]; +end +changedoutput = editlayoutstringGUI(plotArrayFormtOldin,plotArrayFormtin,PLOTORG); + +if isempty(changedoutput) + return; +end +try + for Numofrows = 1:size(changedoutput) + changeStr{Numofrows} = char(changedoutput{Numofrows,2}); + end +catch + for Numofrows = 1:size(changedoutput) + changeStr{Numofrows} = char(changedoutput{Numofrows,1}); + end +end + +if ~isempty(changeStr) + columFormat = handles.uitable1_layout.ColumnFormat; + columFormatOld = columFormat{1}; + GridinforDataOld = handles.uitable1_layout.Data; + [Numrows,Numcolumns] = size(GridinforDataOld); + for Numofrow = 1:Numrows + for Numofcolumn = 1:Numcolumns + SingleStr = char(GridinforDataOld{Numofrow,Numofcolumn}); + [C,IA] = ismember_bc2(SingleStr,columFormatOld); + if C ==1 + if IA < length(columFormatOld) + try + GridinforDataOld{Numofrow,Numofcolumn} = char(changeStr{IA}); + catch + GridinforDataOld{Numofrow,Numofcolumn} = char(''); + end + elseif IA == length(columFormatOld) + GridinforDataOld{Numofrow,Numofcolumn} = char('None'); + end + else + GridinforDataOld{Numofrow,Numofcolumn} = char('None'); + end + end + end + handles.uitable1_layout.Data = GridinforDataOld; + changeStr{length(changeStr)+1} = char('None'); + for Numofcolumns = 1:Numcolumns + handles.uitable1_layout.ColumnFormat{Numofcolumns} = changeStr; + end + handles.plotArrayFormt = changeStr; +end +guidata(hObject, handles); +% uiresume(handles.gui_chassis); + + diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/default_amp_ticks.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/default_amp_ticks.m new file mode 100755 index 00000000..46edb5e4 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/default_amp_ticks.m @@ -0,0 +1,84 @@ +% PURPOSE: subroutine for ploterpGUI.m +% Creates default Y ticks for ERPLAB's plotting GUI +% +% FORMAT +% +% [def miny maxy] = default_amp_ticks(ERP, yrange) +% +% INPUTS +% +% ERP - ERPset +% yrange - min and max ERP amplitudes +% +% OUTPUT +% +% def - tick values to show in Y axis +% miny - minimum ERP amplitude (to be used for auto-Y) +% maxy - maximum ERP amplitude (to be used for auto-Y) +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2012 +% +% Rewritten by JLC. Nov 10th, 2013 +% +function [def, miny, maxy] = default_amp_ticks(ERP, binArray, yrange) +def = {'-1 1'}; +if nargin<3 + yrange = []; +end +if nargin<2 + binArray = 1:ERP.nbin; +end +nbin = length(binArray); +ymin = zeros(1,nbin); +ymax = ymin; +minpnts = 40; % minimum amuount of values for selecting ticks. +for k=1:nbin + ymin(k) = min(min(ERP.bindata(:,:,binArray(k))')); + ymax(k) = max(max(ERP.bindata(:,:,binArray(k))')); +end +miny = min(ymin); +maxy = max(ymax); +if isempty(miny) || isempty(maxy) + miny = 0; + maxy = 0; + return +end +if isempty(yrange) + yrange(1) = miny*1.2; + yrange(2) = maxy*1.1; +end +if sum(sign(yrange))==0 % when yscale goes from - to + + yrmax = max(abs(yrange)); + yarray = -round(yrmax):0.1:round(yrmax); + if length(yarray)<40 + yarray = linspace(-yrmax, yrmax, minpnts); + end +else % when yscale goes from - to - or + to + + yarray = round(yrange(1)):0.1:round(yrange(2)); + if length(yarray)<40 + yarray = linspace(yrange(1), yrange(2), minpnts); + end +end +a1 = yarray(yarray>0); +b1 = closest(a1, [ min(a1)+(max(a1)-min(a1))*0.25 min(a1)+(max(a1)-min(a1))*0.5 min(a1)+(max(a1)-min(a1))*0.75 max(a1)]); +a2 = yarray(yarray<0); +if ~isempty(a2) && ~isempty(b1) + b2 = -1*fliplr(b1); +elseif ~isempty(a2) && isempty(b1) + b2 = closest(a2, [ min(a2) min(a2)+(max(a2)-min(a2))*0.25 min(a2)+(max(a2)-min(a2))*0.5 min(a2)+(max(a2)-min(a2))*0.75]); + b1 = -1*fliplr(b2); +else + b2 = []; +end + +%ams: round to more sensible numbers +sensible_ones = [-100:0.5:100]; +b1 = closest(sensible_ones,b1); +b2 = closest(sensible_ones,b2); + +def = {vect2colon([b2 0 b1],'Delimiter','off')}; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/default_amp_ticks_viewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/default_amp_ticks_viewer.m new file mode 100755 index 00000000..f01c70e9 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/default_amp_ticks_viewer.m @@ -0,0 +1,128 @@ +% PURPOSE: Creates default Y ticks for EStudio plotting GUI +% +% FORMAT +% +% def = default_amp_ticks(yrange) +% +% INPUTS +% +% ERP - ERPset +% yrange - min and max ERP amplitudes +% +% OUTPUT +% +% def - tick values to show in Y axis +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + + + +function def = default_amp_ticks_viewer(yrange) + +def = []; + +if nargin<1 + beep; + disp('Please input the y scale with two elements'); + return; +end + +if numel(yrange) ==1 || isempty(yrange) + beep; + disp('Please input the y scale with two elements'); + return; +end + +if yrange(1)>= yrange(2) + beep; + disp('Please the left edge of y scale should be smaller than the righ edge.'); + return; + +end + +minpnts = 40; % minimum amuount of values for selecting ticks. +if sum(sign(yrange))==0 % when yscale goes from - to + + yrmax = max(abs(yrange)); + yarray = -round(yrmax):0.1:round(yrmax); + if length(yarray)<40 + yarray = linspace(-yrmax, yrmax, minpnts); + end +else % when yscale goes from - to - or + to + + yarray = round(yrange(1)):0.1:round(yrange(2)); + if length(yarray)<40 + yarray = linspace(yrange(1), yrange(2), minpnts); + end +end + +a1 = yarray(yarray>0); +b1 = closest(a1, [ min(a1)+(max(a1)-min(a1))*0.25 min(a1)+(max(a1)-min(a1))*0.5 min(a1)+(max(a1)-min(a1))*0.75 max(a1)]); +a2 = yarray(yarray<0); +if ~isempty(a2) && ~isempty(b1) + b2 = -1*fliplr(b1); +elseif ~isempty(a2) && isempty(b1) + b2 = closest(a2, [ min(a2) min(a2)+(max(a2)-min(a2))*0.25 min(a2)+(max(a2)-min(a2))*0.5 min(a2)+(max(a2)-min(a2))*0.75]); + b1 = -1*fliplr(b2); +else + b2 = []; +end + +%ams: round to more sensible numbers +if 0.05<= yrange(2) - yrange(1) <=0.1 + sensible_ones = [-10000:0.01:10000]; +elseif 0< yrange(2) - yrange(1) <0.05 + sensible_ones = [-100:0.0001:100]; +elseif yrange(2) - yrange(1)>=1 +sensible_ones = [-10000:0.5:10000]; +else + sensible_ones = [-10000:0.05:10000]; +end +b1 = closest(sensible_ones,b1); +b2 = closest(sensible_ones,b2); + +if ~isempty(b2) + Ajust_left =[]; + count = 0; + for ii = 1:numel(b2) + if b2(ii)< yrange(1) + count = count+1; + Ajust_left(count) = ii; + end + end + b2(Ajust_left) = []; +end + +if ~isempty(b1) + Ajust_right =[]; + count = 0; + for ii = 1:numel(b1) + if b1(ii)> yrange(2) + count = count+1; + Ajust_right(count) = ii; + end + end + b1(Ajust_right) = []; +end +b1 = unique(b1); +b2 = unique(b2); +if ~isempty(b1)&& ~isempty(b2) + def = vect2colon([b2 0 b1],'Delimiter','off'); +elseif isempty(b1)&& ~isempty(b2) + if yrange(2) >0 && b2(end)<0 + def = vect2colon([b2 0 yrange(2)],'Delimiter','off'); + else + def = vect2colon([b2 yrange(2)],'Delimiter','off'); + end +elseif ~isempty(b1)&& isempty(b2) + if yrange(1)<0 && b1(1)>0 + def = vect2colon([yrange(1) 0 b1],'Delimiter','off'); + else + def = vect2colon([yrange(1) b1],'Delimiter','off'); + end +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/editlayoutstringGUI.fig b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/editlayoutstringGUI.fig new file mode 100755 index 00000000..6c819a93 Binary files /dev/null and b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/editlayoutstringGUI.fig differ diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/editlayoutstringGUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/editlayoutstringGUI.m new file mode 100755 index 00000000..a10e0ea5 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/editlayoutstringGUI.m @@ -0,0 +1,161 @@ +function varargout = editlayoutstringGUI(varargin) +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @editlayoutstringGUI_OpeningFcn, ... + 'gui_OutputFcn', @editlayoutstringGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%----------------------------------------------------------------------------------- +function editlayoutstringGUI_OpeningFcn(hObject, eventdata, handles, varargin) +handles.output = []; + +try + listname = varargin{1}; +catch + for ii = 1:100 + listname{ii,1} = num2str(ii); + end +end + +try + listnameOlder = varargin{2}; +catch + listnameOlder = listname; +end + + +try + PLOTORG = varargin{3}; +catch + PLOTORG = [1 2 3]; +end + +try + titlename = varargin{4}; +catch + titlename = 'Edit labels for Plot Organization'; +end + +[Numrows,Numcolumns] = size(listname); + + +for Numofrows = 1:Numrows + for Numofcolumns = 1:2 + try + if Numofcolumns==1 + GridinforData{Numofrows,Numofcolumns} = char(listname{Numofrows,1}); + else + GridinforData{Numofrows,Numofcolumns} = char(listnameOlder{Numofrows}); + end + catch + GridinforData{Numofrows,Numofcolumns} = 'None'; + end + end +end + + + +ColumnEditable =[0,1]; +ColumnWidth = {300 300}; +ColumnName{1,1} = char(['Default Name']); +ColumnName{1,2} = char(['Custom Name']); +columFormat = {'char','char'}; + +for Numofrow = 1:Numrows + if PLOTORG(1)==1 + RowsName{Numofrow} = char(['Ch',num2str(Numofrow)]); + elseif PLOTORG(1)==2 + RowsName{Numofrow} = char(['Bin',num2str(Numofrow)]); + elseif PLOTORG(1)==3 + RowsName{Numofrow} = char(['Erp',num2str(Numofrow)]); + else + RowsName{Numofrow} = char(['Ch',num2str(Numofrow)]); + end +end + +% +% Color GUI +% +% handles = painterplab(handles); +[version reldate,ColorBdef,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +set(handles.gui_chassis, 'Color', ColorBviewer_def); +% +% Set font size +% +% handles = setfonterplab(handles); + +% Update handles structure + + + +guidata(hObject, handles); +set(handles.uitable1_layout,'Data',GridinforData); +handles.uitable1_layout.ColumnEditable = logical(ColumnEditable); +handles.uitable1_layout.ColumnWidth = ColumnWidth; +handles.uitable1_layout.ColumnName = ColumnName; +handles.uitable1_layout.RowName = RowsName; +handles.uitable1_layout.ColumnFormat = columFormat; +set(handles.gui_chassis, 'Name', titlename, 'WindowStyle','modal'); + +% UIWAIT makes editlayoutstringGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + +%----------------------------------------------------------------------------------- +function varargout = editlayoutstringGUI_OutputFcn(hObject, eventdata, handles) +try + varargout{1} = handles.output; +catch + varargout{1} = []; +end +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +%---------------------------------------------------------------------------------- +% function listbox_list_Callback(hObject, eventdata, handles) +% +% %---------------------------------------------------------------------------------- +% function listbox_list_CreateFcn(hObject, eventdata, handles) +% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) +% set(hObject,'BackgroundColor','white'); +% end + +%---------------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); +%---------------------------------------------------------------------------------- +function pushbutton_ok_Callback(hObject, eventdata, handles) + +Data = get(handles.uitable1_layout, 'Data'); +handles.output = Data; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%---------------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + % The GUI is still in UIWAIT, us UIRESUME + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/erpAutoYLim.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/erpAutoYLim.m new file mode 100755 index 00000000..87d03979 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/erpAutoYLim.m @@ -0,0 +1,152 @@ +% PURPOSE: subroutine for ploterpGUI.m +% identifies minimum and maximum values of ERP amplitudes for Y scaling. +% +% FORMAT +% +% [yylim, serror] = erpAutoYLim(ERP, binArray, chanArray, xxlim) +% +% INPUTS +% +% ERP - ERPset +% binArray - indices of bins from where to get the amplitude values +% chanArray - indices of channels from where to get the amplitude values +% xxlim - current scale for time ([min max] in ms) +% +% +% OUTPUT +% +% yylim - range for Y scale +% serror - error flag. 0 means no errors. +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2013 + +function [yylim, serror] = erpAutoYLim(ERP, binArray, chanArray, xxlim,blcorrdata) +%ams updated blcorrdata +serror = 0; +if nargin<1 + error('erpAutoYLim needs 1 input argument at least.') +end + +datatype = checkdatatype(ERP); + +if nargin<5 + blcorrdata = 'no'; +end + + +if nargin<4 + if strcmpi(datatype, 'ERP') + xxlim = [ERP.xmin ERP.xmax]*1000; + else + xxlim = [ERP.xmin ERP.xmax]; + end +end +if nargin<3 + chanArray = 1:ERP.nchan; +end +if nargin<2 + binArray = 1:ERP.nbin; +end +if isempty(binArray) + binArray = 1:ERP.nbin; +end +if isempty(chanArray) + chanArray = 1:ERP.nchan; +end +if isempty(xxlim) + if strcmpi(datatype, 'ERP') + if strcmp(datatype,'CSD') + datatype = 'ERP'; % if CSD data, treat as ERP data here + end + xxlim = [ERP.xmin ERP.xmax]*1000; + else + xxlim = [ERP.xmin ERP.xmax]; + end +end +try + nbin = length(binArray); + nchan = length(chanArray); + fs = ERP.srate; + + if strcmpi(datatype,'CSD') + datatype = 'ERP'; % if CSD data, treat as ERP data here + end + + if strcmpi(datatype, 'ERP') + + + if xxlim(1)round(ERP.xmax*1000) + aux_xxlim(2) = round(ERP.xmax*1000); + else + aux_xxlim(2) = xxlim(2); + end + else % fft + if xxlim(1)<5 + aux_xxlim(1) = 5; % to avoid including the spectrum under 5 Hz in calculating Y auto (too big!) + else + aux_xxlim(1) = xxlim(1); + end + if xxlim(2)>round(fs/2); + aux_xxlim(2) = round(fs/2); + else + aux_xxlim(2) = xxlim(2); + end + end + + %disp('start') + %aux_xxlim + %[ERP.xmin ERP.xmax] + %fs + [p1, p2, checkw] = window2sample(ERP, aux_xxlim(1:2) , fs, 'relaxed'); + %disp('end') + + + if strcmpi(blcorrdata,'no') + datresh = reshape(ERP.bindata(chanArray,p1:p2,binArray), 1, (p2-p1+1)*nbin*nchan); + yymax = max(datresh); + yymin = min(datresh); + else + datresh = reshape(blcorrdata(chanArray,p1:p2,binArray), 1, (p2-p1+1)*nbin*nchan); + yymax = max(datresh); + yymin = min(datresh); + end + + if abs(yymax)<1 && abs(yymin)<1 + yylim(1:2) = [yymin*1.2 yymax*1.1]; % JLC. Mar 11, 2015 + else + yylim(1:2) = round([yymin*1.2 yymax*1.1]); % JLC. Sept 26, 2012 + end + + % + % in case of flatlined ERPs + % + if yylim(1)<1E-6 && yylim(2)<1E-6 + if strcmpi(datatype, 'ERP') + yylim(1:2) = [-1 1]; + fprintf('WARNING: It seems like erpAutoYLim() found flatlined ERPs. So auto Y-limit was set to [-1 1].\n'); + else + yylim(1:2) = [0 1]; + fprintf('WARNING: It seems like erpAutoYLim() found flatlined Spectrum. So auto Y-limit was set to [0 1].\n'); + end + end +catch + if strcmpi(datatype, 'ERP') + yylim(1:2) = [-10 10]; + else + yylim(1:2) = [0 1]; + end + serror =1; + fprintf('WARNING: ERPLAB could not find the auto Y limits for %s.\nPlease check your input parameters and waverforms.\n', ERP.erpname); + fprintf('Default Y limit values were loaded.\n'); + return +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_Binchan_waviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_Binchan_waviewer_GUI.m new file mode 100755 index 00000000..0f679dbb --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_Binchan_waviewer_GUI.m @@ -0,0 +1,1034 @@ +% ERPset selector panel +% +% Author: Guanghui ZHANG & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 & 2023 + +% ERPLAB Toolbox +% + +% +% Initial setup +% +function varargout = f_ERP_Binchan_waviewer_GUI(varargin) +% +global viewer_ERPDAT +global observe_ERPDAT; + +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +addlistener(viewer_ERPDAT,'v_currentERP_change',@v_currentERP_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); +addlistener(observe_ERPDAT,'ERP_chan_change',@ERP_chan_changed); +addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed); +addlistener(observe_ERPDAT,'Two_GUI_change',@Two_GUI_change); + + + +ERPwaveview_binchan = struct(); +%---------Setting the parameter which will be used in the other panels----------- + +try + [version reldate,ColorBviewer_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +catch + ColorBviewer_def = [0.7765 0.7294 0.8627]; +end +ERPdatasets = []; % Local data structure +% global Chanbin_waveviewer_box; +if nargin == 0 + fig = figure(); % Parent figure + Chanbin_waveviewer_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Channels and Bins', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); % Create boxpanel +elseif nargin == 1 + Chanbin_waveviewer_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Channels and Bins', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); +elseif nargin == 3 || nargin == 2 + Chanbin_waveviewer_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Channels and Bins', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +elseif nargin == 4 + Chanbin_waveviewer_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Channels and Bins', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); + +end + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end + +drawui_erpsetbinchan_viewer(FonsizeDefault); + +varargout{1} = Chanbin_waveviewer_box; +% Draw the ui + function drawui_erpsetbinchan_viewer(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + catch + ColorBviewer_def = [0.7765 0.7294 0.8627]; + end + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + SelectedIndex = ERPwaviewer.SelectERPIdx; + ALLERP = ERPwaviewer.ALLERP; + if max(SelectedIndex(:))> length(ALLERP) + SelectedIndex =length(ALLERP); + end + catch + beep; + disp('f_ERP_Binchan_waviewer_GUI error: Restart ERPwave Viewer'); + return; + end + ERPwaveview_binchan.vBox = uiextras.VBox('Parent', Chanbin_waveviewer_box, 'Spacing', 5,'BackgroundColor',ColorBviewer_def); % VBox for everything + ERPtooltype = erpgettoolversion('tooltype'); + if ~strcmpi(ERPtooltype,'EStudio') %&& ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaviewer.erp_binchan_op = 0; + end + try + Enable_auto = ERPwaviewer.binchan_op; + catch + Enable_auto = 1; + end + if Enable_auto ==1 + Enable_label = 'off'; + elseif Enable_auto ==0 + Enable_label = 'on'; + end + %%---------------------Options for selecting channel and bins----------------------------------------------------- + ERPwaveview_binchan.opts_title = uiextras.HBox('Parent', ERPwaveview_binchan.vBox, 'Spacing', 5,'BackgroundColor',ColorBviewer_def); + ERPwaveview_binchan.auto = uicontrol('Style', 'radiobutton','Parent', ERPwaveview_binchan.opts_title,... + 'String','Same as EStudio','callback',@Chanbin_auto,'Value',Enable_auto,'Enable','on','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); + + + ERPwaveview_binchan.custom = uicontrol('Style', 'radiobutton','Parent', ERPwaveview_binchan.opts_title,... + 'String','Custom','callback',@Chanbin_custom,'Value',~Enable_auto,'Enable','on','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); + % + %%---------------------Display channel and bin labels----------------------------------------------------- + ERPwaveview_binchan.DataSelGrid = uiextras.HBox('Parent', ERPwaveview_binchan.vBox,'BackgroundColor',ColorBviewer_def); + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERP,SelectedIndex); + + Chanlist_name = cell(length(chanStr)+1,1); + Chanlist_name(1) = {'All'}; + for Numofchan11 = 1:length(chanStr) + Chanlist_name(Numofchan11+1) = {char(strcat(num2str(Numofchan11),'.',32,char(chanStr(Numofchan11))))}; + end + % Channel information + Chanlist = chanStr; + Chan_sel = ERPwaviewer.chan; + if ~isempty(Chan_sel) + if max(Chan_sel)> numel(Chanlist) + Chan_sel= 1:length(Chanlist); + end + else + Chan_sel= 1:length(Chanlist); + end + ERPwaveview_binchan.ElecRange = uicontrol('Parent', ERPwaveview_binchan.DataSelGrid,'Style','listbox','min',1,'max',length(Chanlist_name),... + 'String', Chanlist_name,'Callback',@ViewerElecRange,'FontSize',FonsizeDefault,'Enable',Enable_label); % 2B + if numel(Chan_sel) == numel(Chanlist) + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value = Chan_sel+1; + end + %%Bin information + brange = cell(length(binStr)+1,1); + BinNum = length(binStr); + Bin_sel = ERPwaviewer.bin; + if ~isempty(Bin_sel) + if max(Bin_sel)> BinNum + Bin_sel= 1:BinNum; + end + else + Bin_sel= 1:BinNum; + end + brange(1) = {'All'}; + for Numofbin11 = 1:length(binStr) + brange(Numofbin11+1) = {char(strcat(num2str(Numofbin11),'.',32,char(binStr(Numofbin11))))}; + end + ERPwaveview_binchan.BinRange = uicontrol('Parent', ERPwaveview_binchan.DataSelGrid,'Style','listbox','Min',1,'Max',BinNum+1,... + 'String', brange,'callback',@ViewerBinRange,'FontSize',FonsizeDefault,'Enable',Enable_label); % 2C + if BinNum== numel(Bin_sel) + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value = Bin_sel+1; + end + set(ERPwaveview_binchan.DataSelGrid, 'Sizes',[ -1.2 -2]); + + if strcmpi(ERPtooltype,'EStudio') + ERPwaveview_binchan.auto.String = 'Same as EStudio'; + % elseif strcmpi(ERPtooltype,'ERPLAB') + % ERPwaveview_binchan.auto.String = 'Same as ERPLAB'; + % set(ERPwaveview_binchan.opts_title ,'Sizes',[130 90]); + else + ERPwaveview_binchan.auto.String = ''; + ERPwaveview_binchan.auto.Enable = 'off'; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.custom.String = ''; + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Enable = 'off'; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + + + %%Help and apply + ERPwaveview_binchan.help_apply_title = uiextras.HBox('Parent', ERPwaveview_binchan.vBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',ERPwaveview_binchan.help_apply_title ); + uicontrol('Style','pushbutton','Parent', ERPwaveview_binchan.help_apply_title ,'String','Cancel',... + 'callback',@setbinchan_help,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'FontWeight','bold','HorizontalAlignment','left' + uiextras.Empty('Parent',ERPwaveview_binchan.help_apply_title ); + ERPwaveview_binchan.apply = uicontrol('Style','pushbutton','Parent',ERPwaveview_binchan.help_apply_title ,'String','Apply',... + 'callback',@setbinchan_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent',ERPwaveview_binchan.help_apply_title ); + set(ERPwaveview_binchan.help_apply_title ,'Sizes',[40 70 20 70 20]); + set(ERPwaveview_binchan.vBox, 'Sizes', [20 190 25]); + end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%---------------------------------------------- Subfunctions --------------------------------------------%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%-----------------------Channel changes------------------------------------ + function ViewerElecRange(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=2 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + ChanArray = Source.Value; + [x_flag,y_flag] = find(ChanArray==1); + if ~isempty(y_flag) + Source.Value = 1; + else + if length(Source.String)-1 == numel(ChanArray) + Source.Value = 1; + end + end + estudioworkingmemory('MyViewer_chanbin',1); + ERPwaveview_binchan.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_binchan.apply.ForegroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%----------------------------Bin change----------------------------------- + function ViewerBinRange(BinSource,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=2 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + BinArray = BinSource.Value; + [x_flag,y_flag] = find(BinArray==1); + if ~isempty(y_flag) + BinSource.Value = 1; + else + if length(BinSource.String)-1 == numel(BinArray) + BinSource.Value = 1; + end + end + + estudioworkingmemory('MyViewer_chanbin',1); + ERPwaveview_binchan.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_binchan.apply.ForegroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%---------------Setting for auto option----------------------------------- + function Chanbin_auto(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=2 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_chanbin',1); + ERPwaveview_binchan.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_binchan.apply.ForegroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + ERPtooltype = erpgettoolversion('tooltype'); + if strcmpi(ERPtooltype,'EStudio') + ERPwaveview_binchan.auto.Value = 1; + ERPwaveview_binchan.custom.Value =0; + ERPwaveview_binchan.ElecRange.Enable = 'off'; + ERPwaveview_binchan.BinRange.Enable = 'off'; + Selected_erpset= estudioworkingmemory('selectederpstudio'); + Geterpbinchan = estudioworkingmemory('geterpbinchan'); + CurrentERPIndex = Geterpbinchan.Select_index; + try + ERPwaviewerIN = evalin('base','ALLERPwaviewer'); + ALLERPIN = ERPwaviewerIN.ALLERP; + if max(Selected_erpset(:))> length(ALLERPIN) + Selected_erpset =1; + CurrentERPIndex =1; + end + catch + beep; + disp('f_ERP_Binchan_waviewer_GUI error: Restart ERPwave Viewer'); + return; + end + + BinArray = Geterpbinchan.bins{Geterpbinchan.Select_index}; + chanArray = Geterpbinchan.elecs_shown{Geterpbinchan.Select_index}; + chan_bin = Geterpbinchan.bins_chans(CurrentERPIndex); + if chan_bin ==1 + ERPwaviewerIN.plot_org.Grid =2; + ERPwaviewerIN.plot_org.Overlay=1; + ERPwaviewerIN.plot_org.Pages=3; + elseif chan_bin==0 + ERPwaviewerIN.plot_org.Grid =1; + ERPwaviewerIN.plot_org.Overlay=2; + ERPwaviewerIN.plot_org.Pages=3; + end + + % Channel information + chanStr = [1:(numel(ERPwaveview_binchan.ElecRange.String)-1)]; + Chanlist = chanStr; + Chan_sel = chanArray; + if ~isempty(Chan_sel) + if max(Chan_sel)> numel(Chanlist) + Chan_sel= 1:length(Chanlist); + end + else + Chan_sel= 1:length(Chanlist); + end + try + if length(Chan_sel) == numel(chanStr) + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =Chan_sel+1; + end + catch + ERPwaveview_binchan.ElecRange.Value =1; + end + + %%Bin information + binStr = ERPwaveview_binchan.BinRange.String; + BinNum = length(binStr)-1; + Bin_sel = BinArray; + if ~isempty(Bin_sel) + if max(Bin_sel)> BinNum + Bin_sel= 1:BinNum; + end + else + Bin_sel= 1:BinNum; + end + + if BinNum== numel(Bin_sel) + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value = Bin_sel+1; + end + + elseif strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_binchan.auto.Value = 1; + ERPwaveview_binchan.custom.Value =0; + ERPwaveview_binchan.ElecRange.Enable = 'off'; + ERPwaveview_binchan.BinRange.Enable = 'off'; + Selected_erpset = evalin('base','CURRENTERP'); + ALLERP = evalin('base','ALLERP'); + if ~isempty(Selected_erpset) && ~isempty(ALLERP) && (Selected_erpset<= length(ALLERP)) && min(Selected_erpset)>0 + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERP,SelectedIndex); + Chanlist_name = cell(length(chanStr)+1,1); + Chanlist_name(1) = {'All'}; + for Numofchan11 = 1:length(chanStr) + Chanlist_name(Numofchan11+1) = {char(strcat(num2str(Numofchan11),'.',32,char(chanStr(Numofchan11))))}; + end + ERPwaveview_binchan.ElecRange.String = Chanlist_name; + ERPwaveview_binchan.ElecRange.Value =1; + + brange = cell(length(binStr)+1,1); + brange(1) = {'All'}; + for Numofbin11 = 1:length(binStr) + brange(Numofbin11+1) = {char(strcat(num2str(Numofbin11),'.',32,char(binStr(Numofbin11))))}; + end + ERPwaveview_binchan.BinRange.String = brange; + ERPwaveview_binchan.BinRange.Value = 1; + end + else + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + end +%%---------------Setting for custom option--------------------------------- + function Chanbin_custom(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=2 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_chanbin',1); + ERPwaveview_binchan.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_binchan.apply.ForegroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + + ERPtooltype = erpgettoolversion('tooltype'); + if ~strcmpi(ERPtooltype,'EStudio') && ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + ERPwaveview_binchan.auto.Enable = 'off'; + else + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + end + + +%%-------------------------------Help-------------------------------------- + function setbinchan_help(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=2 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + changeFlag = estudioworkingmemory('MyViewer_chanbin'); + if changeFlag~=1 + return; + end + + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nChannels and Bins > Cancel-f_ERP_Binchan_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + if ERPwaviewer_apply.binchan_op==1 + ERPwaveview_binchan.auto.Value = 1; + ERPwaveview_binchan.custom.Value =0; + ERPwaveview_binchan.ElecRange.Enable = 'off'; + ERPwaveview_binchan.BinRange.Enable = 'off'; + else + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + + binArray = ERPwaviewer_apply.bin; + chanArray = ERPwaviewer_apply.chan; + if numel(binArray) == length(ERPwaveview_binchan.BinRange.String)-1 + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value =binArray+1; + end + if numel(chanArray)==length(ERPwaveview_binchan.ElecRange.String)-1 + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =chanArray+1; + end + + ERPtooltype = erpgettoolversion('tooltype'); + if ~strcmpi(ERPtooltype,'EStudio') %&& ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + + estudioworkingmemory('MyViewer_chanbin',0); + ERPwaveview_binchan.apply.BackgroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.5 0.5 0.9]; + ERPwaveview_binchan.apply.ForegroundColor = [0 0 0]; + end + +%%------------------------------Apply-------------------------------------- + function setbinchan_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=2 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + MessageViewer= char(strcat('Channels and Bins > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nChannels and Bins > Apply-f_ERP_Binchan_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + + ERPwaviewer_apply.binchan_op = ERPwaveview_binchan.auto.Value; + ChanArrayValue = ERPwaveview_binchan.ElecRange.Value; + if numel(ChanArrayValue)== 1&& ChanArrayValue ==1 + ChanArray = [1:length(ERPwaveview_binchan.ElecRange.String)-1]; + else + ChanArray = ChanArrayValue-1; + end + ERPwaviewer_apply.chan = ChanArray; + BinArrayValue = ERPwaveview_binchan.BinRange.Value; + if BinArrayValue ==1 + BinArray = [1:length(ERPwaveview_binchan.BinRange.String)-1]; + else + BinArray = BinArrayValue-1; + end + ERPwaviewer_apply.bin = BinArray; + + %%recover the label for bin and channel panel, and reset + %%backgroundcolor of "Apply" + estudioworkingmemory('MyViewer_chanbin',0); + ERPwaveview_binchan.apply.BackgroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.5 0.5 0.9]; + ERPwaveview_binchan.apply.ForegroundColor = [0 0 0]; + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + %%change the other panels based on the changed bins and channels + viewer_ERPDAT.Count_currentERP = viewer_ERPDAT.Count_currentERP+1; + %%plot waves + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; + end + +%%---------change channels and bins based on the selected ERPsets---------- + function v_currentERP_change(~,~) + try + ERPwaviewer_S = evalin('base','ALLERPwaviewer'); + catch + return; + end + ALLERP_S = ERPwaviewer_S.ALLERP; + Selected_ERPsetlabel = ERPwaviewer_S.SelectERPIdx; + + if max(Selected_ERPsetlabel(:))> length(ALLERP_S) + Selected_ERPsetlabel =length(ALLERP_S); + end + try + ERPwaviewer_S.ERP = ALLERP_S(Selected_ERPsetlabel(1)); + ERPwaviewer_S.CURRENTERP =Selected_ERPsetlabel(1); + catch + ERPwaviewer_S.ERP = ALLERP_S(Selected_ERPsetlabel(1)); + ERPwaviewer_S.CURRENTERP =Selected_ERPsetlabel(1); + end + + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERP_S,Selected_ERPsetlabel); + % Channel information + Chanlist_name = cell(length(chanStr)+1,1); + Chanlist_name(1) = {'All'}; + for Numofchan11 = 1:length(chanStr) + Chanlist_name(Numofchan11+1) = {char(strcat(num2str(Numofchan11),'.',32,char(chanStr(Numofchan11))))}; + end + % Channel information + Chanlist = chanStr; + Chan_selindex = ERPwaveview_binchan.ElecRange.Value; + if numel(Chan_selindex) ==1 && Chan_selindex==1 + Chan_sel = [1:numel(ERPwaveview_binchan.ElecRange.String)-1]; + else + Chan_sel =Chan_selindex-1; + end + if ~isempty(Chan_sel) + if max(Chan_sel)> numel(Chanlist) + Chan_sel= 1:length(Chanlist); + end + else + Chan_sel= 1:length(Chanlist); + end + ERPwaveview_binchan.ElecRange.String = Chanlist_name; + try + if length(Chan_sel) == numel(chanStr) + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =Chan_sel+1; + end + catch + ERPwaveview_binchan.ElecRange.Value =1; + end + ERPwaveview_binchan.ElecRange.Min = 1; + ERPwaveview_binchan.ElecRange.Max = length(ERPwaveview_binchan.ElecRange.String)+1; + + %%Bin information + brange = cell(length(binStr)+1,1); + BinNum = length(binStr); + Bin_selIndex = ERPwaveview_binchan.BinRange.Value; + if numel(Bin_selIndex) ==1 && Bin_selIndex==1 + Bin_sel = [1:numel(ERPwaveview_binchan.BinRange.String)-1]; + else + Bin_sel = Bin_selIndex-1; + end + if ~isempty(Bin_sel) + if max(Bin_sel)> BinNum + Bin_sel= 1:BinNum; + end + else + Bin_sel= 1:BinNum; + end + brange(1) = {'All'}; + for Numofbin11 = 1:length(binStr) + brange(Numofbin11+1) = {char(strcat(num2str(Numofbin11),'.',32,char(binStr(Numofbin11))))}; + end + ERPwaveview_binchan.BinRange.String = brange; + if BinNum== numel(Bin_sel) + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value = Bin_sel+1; + end + + ChanArrayValue = ERPwaveview_binchan.ElecRange.Value; + if numel(ChanArrayValue)== 1&& ChanArrayValue ==1 + ChanArray = [1:length(ERPwaveview_binchan.ElecRange.String)-1]; + else + ChanArray = ChanArrayValue-1; + end + ERPwaviewer_S.chan = ChanArray; + + BinArrayValue =ERPwaveview_binchan.BinRange.Value ; + if BinArrayValue ==1 + BinArray = [1:length(ERPwaveview_binchan.BinRange.String)-1]; + else + BinArray = BinArrayValue-1; + end + ERPwaviewer_S.bin = BinArray; + assignin('base','ALLERPwaviewer',ERPwaviewer_S); + end + + + +%%------------update this panel based on the imported parameters----------- + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + + try + ERPwaviewer_S = evalin('base','ALLERPwaviewer'); + catch + return; + end + ALLERP_S = ERPwaviewer_S.ALLERP; + Selected_ERPsetlabel = ERPwaviewer_S.SelectERPIdx; + + if max(Selected_ERPsetlabel(:))> length(ALLERP_S) + Selected_ERPsetlabel =length(ALLERP_S); + end + try + ERPwaviewer_S.ERP = ALLERP_S(Selected_ERPsetlabel(1)); + ERPwaviewer_S.CURRENTERP =Selected_ERPsetlabel(1); + catch + ERPwaviewer_S.ERP = ALLERP_S(Selected_ERPsetlabel(1)); + ERPwaviewer_S.CURRENTERP =Selected_ERPsetlabel(1); + end + + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERP_S,Selected_ERPsetlabel); + % Channel information + Chanlist_name = cell(length(chanStr)+1,1); + Chanlist_name(1) = {'All'}; + for Numofchan11 = 1:length(chanStr) + Chanlist_name(Numofchan11+1) = {char(strcat(num2str(Numofchan11),'.',32,char(chanStr(Numofchan11))))}; + end + % Channel information + Chanlist = chanStr; + Chan_sel =ERPwaviewer_S.chan; + if ~isempty(Chan_sel) + if max(Chan_sel)> numel(Chanlist) + Chan_sel= 1:length(Chanlist); + end + else + Chan_sel= 1:length(Chanlist); + end + ERPwaveview_binchan.ElecRange.String = Chanlist_name; + try + if length(Chan_sel) == numel(chanStr) + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =Chan_sel+1; + end + catch + ERPwaveview_binchan.ElecRange.Value =1; + end + ERPwaveview_binchan.ElecRange.Min = 1; + ERPwaveview_binchan.ElecRange.Max = length(ERPwaveview_binchan.ElecRange.String)+1; + + %%Bin information + brange = cell(length(binStr)+1,1); + BinNum = length(binStr); + Bin_sel = ERPwaviewer_S.bin; + if ~isempty(Bin_sel) + if max(Bin_sel)> BinNum + Bin_sel= 1:BinNum; + end + else + Bin_sel= 1:BinNum; + end + brange(1) = {'All'}; + for Numofbin11 = 1:length(binStr) + brange(Numofbin11+1) = {char(strcat(num2str(Numofbin11),'.',32,char(binStr(Numofbin11))))}; + end + ERPwaveview_binchan.BinRange.String = brange; + if BinNum== numel(Bin_sel) + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value = Bin_sel+1; + end + + ERPtooltype = erpgettoolversion('tooltype'); + if ~strcmpi(ERPtooltype,'EStudio') && ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaviewer_S.erp_binchan_op = 0; + end + + %%Auto or Custom + binchanOp = ERPwaviewer_S.binchan_op; + if binchanOp ==1 + ERPwaveview_binchan.auto.Value = 1; + ERPwaveview_binchan.custom.Value =0; + ERPwaveview_binchan.ElecRange.Enable = 'off'; + ERPwaveview_binchan.BinRange.Enable = 'off'; + else + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + %%settings dependent on runing EStudio or ERPLAB or other way (e.g.,script). + if strcmpi(ERPtooltype,'EStudio') + ERPwaveview_binchan.auto.String = 'Same as EStudio'; + elseif strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_binchan.auto.String = 'Same as ERPLAB'; + else + ERPwaveview_binchan.auto.String = ''; + ERPwaveview_binchan.auto.Enable = 'off'; + ERPwaveview_binchan.custom.Value =1; + ERPwaveview_binchan.custom.String = ''; + ERPwaveview_binchan.auto.Value = 0; + ERPwaveview_binchan.custom.Enable = 'off'; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + end + + end + +%%modify the channels based on the changes of main EStudio + function ERP_chan_changed(~,~) + ALLERPStudio = observe_ERPDAT.ALLERP; + if isempty(ALLERPStudio) || (length(ALLERPStudio)==1&& strcmpi(ALLERPStudio(1).erpname,'No ERPset loaded')) || strcmpi(ALLERPStudio(length(ALLERPStudio)).erpname,'No ERPset loaded') + return; + end + try + ChanBinAutoValue = ERPwaveview_binchan.auto.Value; + catch + return; + end + + ChanArrayStudio = observe_ERPDAT.ERP_chan; + chanNumdef = length(ERPwaveview_binchan.ElecRange.String)-1; + + if ~isempty(ChanArrayStudio) && ChanBinAutoValue==1 + if min(ChanArrayStudio(:))<=0 || max(ChanArrayStudio(:))>chanNumdef + return; + end + + MessageViewer= char(strcat('Channels and Bins > Channel')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + % viewer_ERPDAT.Process_messg =1; + + try + ALLERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nChannels and Bins -f_ERP_Binchan_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + try + if numel(ChanArrayStudio)==chanNumdef + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =ChanArrayStudio+1; + end + catch + ERPwaveview_binchan.ElecRange.Value =1; + end + ALLERPwaviewer_apply.chan = ChanArrayStudio; + assignin('base','ALLERPwaviewer',ALLERPwaviewer_apply); + %%change the other panels based on the changed bins and channels + viewer_ERPDAT.Count_currentERP = viewer_ERPDAT.Count_currentERP+1; + %%plot waves + f_redrawERP_viewer_test(); + end + end + +%%modify the bins based on the changes of main EStudio + function ERP_bin_changed(~,~) + ALLERPStudio = observe_ERPDAT.ALLERP; + if isempty(ALLERPStudio) || (length(ALLERPStudio)==1&& strcmpi(ALLERPStudio(1).erpname,'No ERPset loaded')) || strcmpi(ALLERPStudio(length(ALLERPStudio)).erpname,'No ERPset loaded') + return; + end + + try + ChanBinAutoValue = ERPwaveview_binchan.auto.Value; + catch + return; + end + BinArrayStudio = observe_ERPDAT.ERP_bin; + binNumdef = length(ERPwaveview_binchan.BinRange.String)-1; + if ~isempty(BinArrayStudio) && ChanBinAutoValue==1 + if min(BinArrayStudio(:))<=0 || max(BinArrayStudio(:))> binNumdef + return; + end + MessageViewer= char(strcat('Channels and Bins > Bin')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + % viewer_ERPDAT.Process_messg =1; + + try + ALLERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nChannels and Bins -f_ERP_Binchan_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + try + if numel(BinArrayStudio)==binNumdef + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value =BinArrayStudio+1; + end + catch + ERPwaveview_binchan.BinRange.Value =1; + end + ALLERPwaviewer_apply.bin = BinArrayStudio; + assignin('base','ALLERPwaviewer',ALLERPwaviewer_apply); + %%change the other panels based on the changed bins and channels + viewer_ERPDAT.Count_currentERP = viewer_ERPDAT.Count_currentERP+1; + %%plot waves + f_redrawERP_viewer_test(); + end + end + + +%%change channels and bins based on the main EStudio + function Two_GUI_change(~,~) + if observe_ERPDAT.Two_GUI~=2 + return; + end + + ERPtooltype = erpgettoolversion('tooltype'); + if isempty(observe_ERPDAT.ALLERP) + try + % % cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + + + ALLERPStudio = observe_ERPDAT.ALLERP; + if strcmpi(ERPtooltype,'EStudio') + if (length(ALLERPStudio)==1&& strcmpi(ALLERPStudio(1).erpname,'No ERPset loaded')) || strcmpi(ALLERPStudio(length(ALLERPStudio)).erpname,'No ERPset loaded') + try + % cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + end + + try + ALLERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nChannels and Bins -f_ERP_Binchan_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + + try + ChanBinAutoValue = ERPwaveview_binchan.auto.Value; + catch + return; + end + MessageViewer= char(strcat('Channels and Bins')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + + if strcmpi(ERPtooltype,'EStudio') && ChanBinAutoValue==1 + ALLERPwaviewer_apply.bin=observe_ERPDAT.ERP_bin; + ALLERPwaviewer_apply.chan=observe_ERPDAT.ERP_chan; + end + + BinArrayStudio = ALLERPwaviewer_apply.bin; + binNumdef = length(ERPwaveview_binchan.BinRange.String)-1; + if ~isempty(BinArrayStudio) && ChanBinAutoValue==1 + if min(BinArrayStudio(:))<=0 || max(BinArrayStudio(:))> binNumdef + return; + end + try + if numel(BinArrayStudio)==binNumdef + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value =BinArrayStudio+1; + end + catch + ERPwaveview_binchan.BinRange.Value =1; + end + ALLERPwaviewer_apply.bin = BinArrayStudio; + end + + ChanArrayStudio = ALLERPwaviewer_apply.chan; + chanNumdef = length(ERPwaveview_binchan.ElecRange.String)-1; + if ~isempty(ChanArrayStudio) && ChanBinAutoValue==1 + if min(ChanArrayStudio(:))<=0 || max(ChanArrayStudio(:))>chanNumdef + return; + end + try + if numel(ChanArrayStudio)==chanNumdef + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =ChanArrayStudio+1; + end + ERPwaveview_binchan.ElecRange.Max = length( ERPwaveview_binchan.ElecRange.String)+2; + catch + ERPwaveview_binchan.ElecRange.Value =1; + end + ALLERPwaviewer_apply.chan = ChanArrayStudio; + end + ERPwaveview_binchan.ElecRange.Max = length(ERPwaveview_binchan.ElecRange.String)+2; + assignin('base','ALLERPwaviewer',ALLERPwaviewer_apply); + %%change the other panels based on the changed bins and channels + viewer_ERPDAT.Count_currentERP = viewer_ERPDAT.Count_currentERP+1; + %%plot waves + f_redrawERP_viewer_test(); + observe_ERPDAT.Two_GUI = 0; + end + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_chanbin'); + if changeFlag~=1 + return; + end + setbinchan_apply(); + end + +%%Reset this panel with the default parameters + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==2 + ERPtooltype = erpgettoolversion('tooltype'); + try + ERPwaviewerIN = evalin('base','ALLERPwaviewer'); + ALLERPIN = ERPwaviewerIN.ALLERP; + catch + beep; + disp('f_ERP_Binchan_waviewer_GUI error: Restart ERPwave Viewer'); + return; + end + + if strcmpi(ERPtooltype,'EStudio') + ERPwaveview_binchan.auto.Value = 1; + ERPwaveview_binchan.custom.Value =0; + ERPwaveview_binchan.ElecRange.Enable = 'off'; + ERPwaveview_binchan.BinRange.Enable = 'off'; + Selected_erpset= estudioworkingmemory('selectederpstudio'); + Geterpbinchan = estudioworkingmemory('geterpbinchan'); + CurrentERPIndex = Geterpbinchan.Select_index; + + if max(Selected_erpset(:))> length(ALLERPIN) + Selected_erpset =1; + CurrentERPIndex =1; + end + BinArray = Geterpbinchan.bins{Geterpbinchan.Select_index}; + chanArray = Geterpbinchan.elecs_shown{Geterpbinchan.Select_index}; + chan_bin = Geterpbinchan.bins_chans(CurrentERPIndex); + if chan_bin ==1 + ERPwaviewerIN.plot_org.Grid =2; + ERPwaviewerIN.plot_org.Overlay=1; + ERPwaviewerIN.plot_org.Pages=3; + elseif chan_bin==0 + ERPwaviewerIN.plot_org.Grid =1; + ERPwaviewerIN.plot_org.Overlay=2; + ERPwaviewerIN.plot_org.Pages=3; + end + + % Channel information + chanStr = [1:(numel(ERPwaveview_binchan.ElecRange.String)-1)]; + Chanlist = chanStr; + Chan_sel = chanArray; + if ~isempty(Chan_sel) + if max(Chan_sel)> numel(Chanlist) + Chan_sel= 1:length(Chanlist); + end + else + Chan_sel= 1:length(Chanlist); + end + try + if length(Chan_sel) == numel(chanStr) + ERPwaveview_binchan.ElecRange.Value =1; + else + ERPwaveview_binchan.ElecRange.Value =Chan_sel+1; + end + catch + ERPwaveview_binchan.ElecRange.Value =1; + end + + %%Bin information + binStr = ERPwaveview_binchan.BinRange.String; + BinNum = length(binStr)-1; + Bin_sel = BinArray; + if ~isempty(Bin_sel) + if max(Bin_sel)> BinNum + Bin_sel= 1:BinNum; + end + else + Bin_sel= 1:BinNum; + end + + if BinNum== numel(Bin_sel) + ERPwaveview_binchan.BinRange.Value =1; + else + ERPwaveview_binchan.BinRange.Value = Bin_sel+1; + end + + ERPwaviewerIN.bin = Bin_sel; + ERPwaviewerIN.chan = Chan_sel; + ERPwaviewerIN.binchan_op = 1; + elseif strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_binchan.auto.Value = 1; + ERPwaveview_binchan.custom.Value =0; + ERPwaveview_binchan.auto.Enable = 'off'; + ERPwaveview_binchan.custom.Enable = 'off'; + ERPwaveview_binchan.ElecRange.Enable = 'on'; + ERPwaveview_binchan.BinRange.Enable = 'on'; + Selected_erpset = evalin('base','CURRENTERP'); + ALLERP = evalin('base','ALLERP'); + if ~isempty(Selected_erpset) && ~isempty(ALLERP) && (Selected_erpset<= length(ALLERP)) && min(Selected_erpset)>0 + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERP,Selected_erpset); + Chanlist_name = cell(length(chanStr)+1,1); + Chanlist_name(1) = {'All'}; + for Numofchan11 = 1:length(chanStr) + Chanlist_name(Numofchan11+1) = {char(strcat(num2str(Numofchan11),'.',32,char(chanStr(Numofchan11))))}; + end + ERPwaveview_binchan.ElecRange.String = Chanlist_name; + ERPwaveview_binchan.ElecRange.Value =1; + + brange = cell(length(binStr)+1,1); + brange(1) = {'All'}; + for Numofbin11 = 1:length(binStr) + brange(Numofbin11+1) = {char(strcat(num2str(Numofbin11),'.',32,char(binStr(Numofbin11))))}; + end + ERPwaveview_binchan.BinRange.String = brange; + ERPwaveview_binchan.BinRange.Value = 1; + end + ERPwaviewerIN.bin = [1:length(ERPwaveview_binchan.BinRange.String)-1]; + ERPwaviewerIN.chan = [1:length(ERPwaveview_binchan.ElecRange.String)-1]; + ERPwaviewerIN.binchan_op = 1; + end + assignin('base','ALLERPwaviewer',ERPwaviewerIN); + ERPwaveview_binchan.apply.BackgroundColor = [1 1 1]; + Chanbin_waveviewer_box.TitleColor= [0.5 0.5 0.9]; + ERPwaveview_binchan.apply.ForegroundColor = [0 0 0]; + viewer_ERPDAT.Reset_Waviewer_panel=3; + end + end%%reset end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_labelset_waveviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_labelset_waveviewer_GUI.m new file mode 100755 index 00000000..51f0c94b --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_labelset_waveviewer_GUI.m @@ -0,0 +1,639 @@ +%%This function is to plot the panel for "Viewer properties". + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_labelset_waveviewer_GUI(varargin) + +global viewer_ERPDAT; +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +% addlistener(viewer_ERPDAT,'Process_messg_change',@Process_messg_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); + +gui_labelset_waveviewer = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erplabelset_viewer_property; +[version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + box_erplabelset_viewer_property = uiextras.BoxPanel('Parent', fig, 'Title', 'Chan/Bin/ERPset Labels', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize',12); % Create boxpanel +elseif nargin == 1 + box_erplabelset_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Chan/Bin/ERPset Labels', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize',12); +else + box_erplabelset_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Chan/Bin/ERPset Labels', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +end +%-----------------------------Draw the panel------------------------------------- + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end + +drawui_plot_property(FonsizeDefault); +varargout{1} = box_erplabelset_viewer_property; + + function drawui_plot_property(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_labelset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + %%--------------------channel and bin setting---------------------- + gui_labelset_waveviewer.DataSelBox = uiextras.VBox('Parent', box_erplabelset_viewer_property,'BackgroundColor',ColorBviewer_def); + + %%-----------------Setting for label location title------- + gui_labelset_waveviewer.location_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_labelset_waveviewer.location_title,'String','Label Location:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',1,'FontWeight','bold'); %,'HorizontalAlignment','left' + + %%-----------------Setting for Auto------- + locationAuto = 1; + locationno = 0; + locationcustom = 0;%% the default value + if locationAuto ==1 + locationno =0; + locationcustom =0; + elseif locationno ==1 + locationAuto = 0; + locationcustom =0; + elseif locationcustom ==1 + locationAuto = 0; + locationno =0; + end + gui_labelset_waveviewer.parameters_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_labelset_waveviewer.labelauto = uicontrol('Style','radiobutton','Parent', gui_labelset_waveviewer.parameters_title,'String','Auto',... + 'callback',@labelauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',locationAuto); % + gui_labelset_waveviewer.nolabel = uicontrol('Style','radiobutton','Parent', gui_labelset_waveviewer.parameters_title,'String','No labels',... + 'callback',@nolabel,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',locationno); % + gui_labelset_waveviewer.customlabel = uicontrol('Style','radiobutton','Parent', gui_labelset_waveviewer.parameters_title,'String','Custom',... + 'callback',@customlabel,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',locationcustom); % + if gui_labelset_waveviewer.labelauto.Value + gui_labelset_waveviewer.nolabel.Value = ~gui_labelset_waveviewer.labelauto.Value; + gui_labelset_waveviewer.customlabel.Value = ~gui_labelset_waveviewer.labelauto.Value; + customdefEnable = 'off'; + elseif gui_labelset_waveviewer.nolabel.Value + gui_labelset_waveviewer.labelauto.Value.Value = ~gui_labelset_waveviewer.nolabel.Value; + gui_labelset_waveviewer.customlabel.Value = ~gui_labelset_waveviewer.nolabel.Value; + customdefEnable = 'off'; + elseif gui_labelset_waveviewer.customlabel.Value + gui_labelset_waveviewer.labelauto.Value.Value = ~gui_labelset_waveviewer.nolabel.Value; + gui_labelset_waveviewer.nolabel.Value = ~gui_labelset_waveviewer.nolabel.Value; + customdefEnable = 'on'; + end + ERPwaviewer.chanbinsetlabel.location.auto = gui_labelset_waveviewer.labelauto.Value; + ERPwaviewer.chanbinsetlabel.location.no = gui_labelset_waveviewer.nolabel.Value; + ERPwaviewer.chanbinsetlabel.location.custom =gui_labelset_waveviewer.customlabel.Value; + + xperDef = '50'; + yperDef = '100'; + CenDef = 1; + gui_labelset_waveviewer.labelloc_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_labelset_waveviewer.xperctitle = uicontrol('Style','text','Parent', gui_labelset_waveviewer.labelloc_title,'String','X%',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',~gui_labelset_waveviewer.labelauto.Value); % + gui_labelset_waveviewer.xperc_edit = uicontrol('Style','edit','Parent', gui_labelset_waveviewer.labelloc_title,'String',xperDef,... + 'callback',@label_xperc, 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',customdefEnable); % + gui_labelset_waveviewer.yperctitle = uicontrol('Style','text','Parent', gui_labelset_waveviewer.labelloc_title,'String','Y%',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + gui_labelset_waveviewer.yperc_edit = uicontrol('Style','edit','Parent', gui_labelset_waveviewer.labelloc_title,'String',yperDef,... + 'callback',@label_yperc, 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',customdefEnable); % + gui_labelset_waveviewer.center = uicontrol('Style','checkbox','Parent', gui_labelset_waveviewer.labelloc_title,'String','Centered',... + 'callback',@label_center,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Enable',customdefEnable,'Value',CenDef); % + set(gui_labelset_waveviewer.labelloc_title,'Sizes',[30 45 30 45 80]); + ERPwaviewer.chanbinsetlabel.location.xperc = str2num(char(gui_labelset_waveviewer.xperc_edit.String)); + ERPwaviewer.chanbinsetlabel.location.yperc = str2num(char(gui_labelset_waveviewer.yperc_edit.String)); + ERPwaviewer.chanbinsetlabel.location.center = gui_labelset_waveviewer.center.Value; + + % + %%--------------------font and font size--------------------------- + gui_labelset_waveviewer.font_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + fontDef = 2; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + labelfontsizeinum = str2num(char(fontsize)); + LabelfontsizeValue = 4; + uicontrol('Style','text','Parent', gui_labelset_waveviewer.font_title,'String','Label Font & Fontsize & Color:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'FontWeight','bold'); %,'HorizontalAlignment','left' + gui_labelset_waveviewer.font_custom_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_labelset_waveviewer.font_custom_title ,'String','Font',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + gui_labelset_waveviewer.font_custom_type = uicontrol('Style','popupmenu','Parent', gui_labelset_waveviewer.font_custom_title ,'String',fonttype,... + 'callback',@label_font,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',fontDef,'Enable',customdefEnable); % + + uicontrol('Style','text','Parent', gui_labelset_waveviewer.font_custom_title ,'String','Size',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + + gui_labelset_waveviewer.font_custom_size = uicontrol('Style','popupmenu','Parent', gui_labelset_waveviewer.font_custom_title ,'String',fontsize,... + 'callback',@label_fontsize,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',LabelfontsizeValue,'Enable',customdefEnable); % + set(gui_labelset_waveviewer.font_custom_title,'Sizes',[30 110 30 70]); + ERPwaviewer.chanbinsetlabel.font = gui_labelset_waveviewer.font_custom_type.Value; + ERPwaviewer.chanbinsetlabel.fontsize = labelfontsizeinum(gui_labelset_waveviewer.font_custom_size.Value); + + %%--------------Label text color----------- + Labelfontcolor =1; + gui_labelset_waveviewer.labelcolor_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_labelset_waveviewer.labelcolor_title,'String','Color',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + textColor = {'Black','Red','Blue','Green','Orange','Cyan','Magenla'}; + gui_labelset_waveviewer.labelcolor = uicontrol('Style','popupmenu','Parent',gui_labelset_waveviewer.labelcolor_title,'String',textColor,... + 'callback',@label_color,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',customdefEnable,'Value',Labelfontcolor); % + uiextras.Empty('Parent',gui_labelset_waveviewer.labelcolor_title); + uiextras.Empty('Parent',gui_labelset_waveviewer.labelcolor_title); + set(gui_labelset_waveviewer.labelcolor_title,'Sizes',[40 100 30 70]); + ERPwaviewer.chanbinsetlabel.textcolor = gui_labelset_waveviewer.labelcolor.Value; + + %%-----------------------help and apply---------------------------- + gui_labelset_waveviewer.help_apply_title = uiextras.HBox('Parent', gui_labelset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',gui_labelset_waveviewer.help_apply_title ); + uicontrol('Style','pushbutton','Parent', gui_labelset_waveviewer.help_apply_title ,'String','Cancel',... + 'callback',@label_help,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'FontWeight','bold','HorizontalAlignment','left' + uiextras.Empty('Parent',gui_labelset_waveviewer.help_apply_title ); + gui_labelset_waveviewer.Apply= uicontrol('Style','pushbutton','Parent',gui_labelset_waveviewer.help_apply_title ,'String','Apply',... + 'callback',@label_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent',gui_labelset_waveviewer.help_apply_title ); + set(gui_labelset_waveviewer.help_apply_title ,'Sizes',[40 70 20 70 20]); + set(gui_labelset_waveviewer.DataSelBox ,'Sizes',[20 25 25 20 25 25 25]); + assignin('base','ALLERPwaviewer',ERPwaviewer); + end + +%%***********************************************************************%% +%%--------------------------Sub function---------------------------------%% +%%***********************************************************************%% +%%-------------------------Setting for load-------------------------------- + function labelauto(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_labelset_waveviewer.labelauto.Value = 1; + gui_labelset_waveviewer.nolabel.Value = 0; + gui_labelset_waveviewer.customlabel.Value = 0; + Enable = 'off'; + gui_labelset_waveviewer.xperc_edit.Enable =Enable ; + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Value = 2; + gui_labelset_waveviewer.font_custom_size.Value = 4; + gui_labelset_waveviewer.xperc_edit.String ='50' ; + gui_labelset_waveviewer.yperc_edit.String = '100'; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.label_customtable.Enable = Enable; + gui_labelset_waveviewer.labelcolor.Value = 1; + %%----------------Update the label----------------- + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_labelset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + binArray = ERPwaviewer.bin; + chanArray = ERPwaviewer.chan; + ERPsetArray = ERPwaviewer.SelectERPIdx; + ALLERPIN = ERPwaviewer.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + for ii = 1:100 + LabelName{ii,1} = ''; + LabelNamenum(ii,1) =ii; + end + if ERPwaviewer.plot_org.Grid ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + for Numofplot = 1:numel(plotArray) + LabelName{Numofplot,1} = chanStr{plotArray(Numofplot)}; + end + elseif ERPwaviewer.plot_org.Grid == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + for Numofplot = 1:numel(plotArray) + LabelName{Numofplot,1} = chanStr{plotArray(Numofplot)}; + end + elseif ERPwaviewer.plot_org.Grid == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numoferpset = 1:numel(plotArray) + LabelName{Numoferpset,1} = {char(ALLERPIN(plotArray(Numoferpset)).erpname)}; + end + else + plotArray = chanArray; + for Numofplot = 1:numel(plotArray) + LabelName{Numofplot,1} = chanStr{plotArray(Numofplot)}; + end + end + + labels_str = table(LabelNamenum,LabelName); + labels_str = table2cell(labels_str); + gui_labelset_waveviewer.label_customtable.Data = labels_str; + end + +%%-------------------------Setting for Save-------------------------------- + function nolabel(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_labelset_waveviewer.labelauto.Value = 0; + gui_labelset_waveviewer.nolabel.Value = 1; + gui_labelset_waveviewer.customlabel.Value = 0; + Enable = 'off'; + gui_labelset_waveviewer.xperc_edit.Enable =Enable ; + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.label_customtable.Enable = Enable; + end + +%%-------------------------Setting for Save as----------------------------- + function customlabel(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_labelset_waveviewer.labelauto.Value = 0; + gui_labelset_waveviewer.nolabel.Value =0; + gui_labelset_waveviewer.customlabel.Value = 1; + Enable = 'on'; + gui_labelset_waveviewer.xperc_edit.Enable =Enable ; + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.label_customtable.Enable = Enable; + end + +%%-------------------X percentage------------------------------------------ + function label_xperc(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + if isempty(str2num(Source.String)) + gui_labelset_waveviewer.xperc_edit.String ='50' ; + end + end + +%%-------------------Y percentage------------------------------------------ + function label_yperc(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + if isempty(str2num(Source.String)) + gui_labelset_waveviewer.yperc_edit.String = '100'; + end + end + +%%-------------------------center for label text--------------------------- + function label_center(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%--------------------------Font of label text----------------------------- + function label_font(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%------------------------Fontsize of label text--------------------------- + function label_fontsize(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%-----------------------color of label text------------------------------- + function label_color(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_labels',1); + gui_labelset_waveviewer.Apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_labelset_waveviewer.Apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%--------------------------Help------------------------------------------- + function label_help(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + changeFlag = estudioworkingmemory('MyViewer_labels'); + if changeFlag~=1 + return; + end + + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Chan/Bin/ERPset Labels > Apply-f_ERP_labelset_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + + if ERPwaviewer_apply.chanbinsetlabel.location.auto==1 + Enable = 'off'; + gui_labelset_waveviewer.labelauto.Value = 1; + gui_labelset_waveviewer.nolabel.Value = 0; + gui_labelset_waveviewer.customlabel.Value = 0; + elseif ERPwaviewer_apply.chanbinsetlabel.location.no==1 + Enable = 'off'; + gui_labelset_waveviewer.labelauto.Value = 0; + gui_labelset_waveviewer.nolabel.Value = 1; + gui_labelset_waveviewer.customlabel.Value = 0; + elseif ERPwaviewer_apply.chanbinsetlabel.location.custom==1 + Enable = 'on'; + gui_labelset_waveviewer.labelauto.Value = 0; + gui_labelset_waveviewer.nolabel.Value = 0; + gui_labelset_waveviewer.customlabel.Value = 1; + end + gui_labelset_waveviewer.xperc_edit.Enable = Enable; + gui_labelset_waveviewer.xperc_edit.String = num2str( ERPwaviewer_apply.chanbinsetlabel.location.xperc); + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.yperc_edit.String = num2str( ERPwaviewer_apply.chanbinsetlabel.location.yperc); + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Value = ERPwaviewer_apply.chanbinsetlabel.font; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + FontSize = ERPwaviewer_apply.chanbinsetlabel.fontsize; + fontsizeStr = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + labelfontsizeinum = str2num(char(fontsizeStr)); + [X_label,Y_label] = find(labelfontsizeinum==FontSize); + if isempty(X_label) || X_label> numel(labelfontsizeinum) + X_label = 4; + end + gui_labelset_waveviewer.font_custom_size.Value = X_label; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.labelcolor.Value = ERPwaviewer_apply.chanbinsetlabel.textcolor; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.center.Value = ERPwaviewer_apply.chanbinsetlabel.location.center; + + estudioworkingmemory('MyViewer_labels',0); + gui_labelset_waveviewer.Apply.BackgroundColor = [1 1 1]; + gui_labelset_waveviewer.Apply.ForegroundColor = [0 0 0]; + box_erplabelset_viewer_property.TitleColor= [0.5 0.5 0.9]; + end + +%%------------------------------Apply-------------------------------------- + function label_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=5 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_labels',0); + gui_labelset_waveviewer.Apply.BackgroundColor = [1 1 1]; + gui_labelset_waveviewer.Apply.ForegroundColor = [0 0 0]; + box_erplabelset_viewer_property.TitleColor= [0.5 0.5 0.9]; + + MessageViewer= char(strcat('Chan/Bin/ERPset Labels > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Chan/Bin/ERPset Labels > Apply-f_ERP_labelset_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + ERPwaviewer_apply.chanbinsetlabel.location.auto = gui_labelset_waveviewer.labelauto.Value; + ERPwaviewer_apply.chanbinsetlabel.location.no = gui_labelset_waveviewer.nolabel.Value; + ERPwaviewer_apply.chanbinsetlabel.location.custom =gui_labelset_waveviewer.customlabel.Value; + ERPwaviewer_apply.chanbinsetlabel.location.xperc = str2num(char(gui_labelset_waveviewer.xperc_edit.String)); + ERPwaviewer_apply.chanbinsetlabel.location.yperc = str2num(char(gui_labelset_waveviewer.yperc_edit.String)); + if ( ERPwaviewer_apply.chanbinsetlabel.location.no==1 || ERPwaviewer_apply.chanbinsetlabel.location.custom ==1) && (isempty(ERPwaviewer_apply.chanbinsetlabel.location.xperc) || isempty(ERPwaviewer_apply.chanbinsetlabel.location.yperc)) + ERPwaviewer_apply.chanbinsetlabel.location.auto = 1; + ERPwaviewer_apply.chanbinsetlabel.location.no = 0; + ERPwaviewer_apply.chanbinsetlabel.location.custom =0; + end + ERPwaviewer_apply.chanbinsetlabel.location.center = gui_labelset_waveviewer.center.Value; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + labelfontsizeinum = str2num(char(fontsize)); + ERPwaviewer_apply.chanbinsetlabel.font = gui_labelset_waveviewer.font_custom_type.Value; + try + ERPwaviewer_apply.chanbinsetlabel.fontsize = labelfontsizeinum(gui_labelset_waveviewer.font_custom_size.Value); + catch + ERPwaviewer_apply.chanbinsetlabel.fontsize = 10; + end + ERPwaviewer_apply.chanbinsetlabel.textcolor = gui_labelset_waveviewer.labelcolor.Value; + + ALLERPwaviewer=ERPwaviewer_apply; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; + end + + +%%-------------change this panel based on the loaded parameters------------ + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_labelset_waveviewer_GUI() > Apply error: Please run the ERP wave viewer again.'); + return; + end + AutoValue = ERPwaviewer_apply.chanbinsetlabel.location.auto; + NoValue = ERPwaviewer_apply.chanbinsetlabel.location.no; + CustomValue = ERPwaviewer_apply.chanbinsetlabel.location.custom; + if AutoValue ==1 && NoValue==0 && CustomValue==0 + gui_labelset_waveviewer.labelauto.Value = 1; + gui_labelset_waveviewer.nolabel.Value = 0; + gui_labelset_waveviewer.customlabel.Value = 0; + Enable = 'off'; + gui_labelset_waveviewer.xperc_edit.Enable =Enable ; + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Value = 2; + gui_labelset_waveviewer.font_custom_size.Value = 4; + gui_labelset_waveviewer.xperc_edit.String ='50' ; + gui_labelset_waveviewer.yperc_edit.String = '100'; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.label_customtable.Enable = Enable; + elseif AutoValue ==0 && NoValue==1 && CustomValue==0 + gui_labelset_waveviewer.labelauto.Value = 0; + gui_labelset_waveviewer.nolabel.Value = 1; + gui_labelset_waveviewer.customlabel.Value = 0; + Enable = 'off'; + gui_labelset_waveviewer.xperc_edit.Enable =Enable ; + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.label_customtable.Enable = Enable; + elseif AutoValue ==0 && NoValue==0 && CustomValue==1 + gui_labelset_waveviewer.labelauto.Value = 0; + gui_labelset_waveviewer.nolabel.Value =0; + gui_labelset_waveviewer.customlabel.Value = 1; + Enable = 'on'; + gui_labelset_waveviewer.xperc_edit.Enable =Enable ; + gui_labelset_waveviewer.yperc_edit.Enable = Enable; + gui_labelset_waveviewer.center.Enable = Enable; + gui_labelset_waveviewer.font_custom_type.Enable = Enable; + gui_labelset_waveviewer.font_custom_size.Enable = Enable; + gui_labelset_waveviewer.labelcolor.Enable = Enable; + gui_labelset_waveviewer.label_customtable.Enable = Enable; + end + Xperc = ERPwaviewer_apply.chanbinsetlabel.location.xperc; + Yperc = ERPwaviewer_apply.chanbinsetlabel.location.yperc; + Center = ERPwaviewer_apply.chanbinsetlabel.location.center; + gui_labelset_waveviewer.xperc_edit.String = num2str(Xperc); + gui_labelset_waveviewer.yperc_edit.String = num2str(Yperc); + if Center ==1 + gui_labelset_waveviewer.center.Value = 1; + else + gui_labelset_waveviewer.center.Value = 0; + end + Labelfont = ERPwaviewer_apply.chanbinsetlabel.font; + gui_labelset_waveviewer.font_custom_type.Value = Labelfont; + Labelfontsize = ERPwaviewer_apply.chanbinsetlabel.fontsize; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + fontsize = str2num(char(fontsize)); + [xsize,y] = find(fontsize ==Labelfontsize); + gui_labelset_waveviewer.font_custom_size.Value = xsize; + textColor = ERPwaviewer_apply.chanbinsetlabel.textcolor; + gui_labelset_waveviewer.labelcolor.Value = textColor; + end + + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_labels'); + if changeFlag~=1 + return; + end + label_apply(); + end + +%%------------------------------------------------------------------------- +%%-----------------Reset this panel with the default parameters------------ +%%------------------------------------------------------------------------- + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==5 + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_labelset_waveviewer_GUI error: Restart ERPwave Viewer'); + return; + end + gui_labelset_waveviewer.labelauto.Value=1; % + gui_labelset_waveviewer.nolabel.Value=0; % + gui_labelset_waveviewer.customlabel.Value=0; % + ERPwaviewerin.chanbinsetlabel.location.auto =1; + ERPwaviewerin.chanbinsetlabel.location.no =0; + ERPwaviewerin.chanbinsetlabel.location.custom=0; + %%label position + gui_labelset_waveviewer.xperc_edit.String = '50'; + gui_labelset_waveviewer.xperc_edit.Enable ='off'; % + gui_labelset_waveviewer.yperc_edit.String ='100'; + gui_labelset_waveviewer.yperc_edit.Enable='off'; % + gui_labelset_waveviewer.center.Value =1; + gui_labelset_waveviewer.center.Enable='off'; % + ERPwaviewerin.chanbinsetlabel.location.xperc =50; + ERPwaviewerin.chanbinsetlabel.location.yperc = 100; + ERPwaviewerin.chanbinsetlabel.location.center =1; + %%label font, fontsize and color + ERPwaviewerin.chanbinsetlabel.font =2; + ERPwaviewerin.chanbinsetlabel.fontsize =10; + ERPwaviewerin.chanbinsetlabel.textcolor=1; + fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + gui_labelset_waveviewer.font_custom_type.Value=2; + gui_labelset_waveviewer.font_custom_type.String = fonttype; + gui_labelset_waveviewer.font_custom_type.Enable='off'; % + gui_labelset_waveviewer.font_custom_size.Value=4; + gui_labelset_waveviewer.font_custom_size.Enable='off'; % + gui_labelset_waveviewer.labelcolor.Value=1; + gui_labelset_waveviewer.labelcolor.Enable='off'; % + assignin('base','ALLERPwaviewer',ERPwaviewerin); + gui_labelset_waveviewer.Apply.BackgroundColor = [1 1 1]; + gui_labelset_waveviewer.Apply.ForegroundColor = [0 0 0]; + box_erplabelset_viewer_property.TitleColor= [0.5 0.5 0.9]; + viewer_ERPDAT.Reset_Waviewer_panel=6; + end + end + + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_lineset_waveviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_lineset_waveviewer_GUI.m new file mode 100755 index 00000000..93f52b13 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_lineset_waveviewer_GUI.m @@ -0,0 +1,1049 @@ +%%This function is to plot the panel for "Viewer properties". + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_lineset_waveviewer_GUI(varargin) + +global viewer_ERPDAT; +addlistener(viewer_ERPDAT,'legend_change',@legend_change); +addlistener(viewer_ERPDAT,'page_xyaxis_change',@page_xyaxis_change); +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +addlistener(viewer_ERPDAT,'v_currentERP_change',@v_currentERP_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); + + +gui_erplinset_waveviewer = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erplineset_viewer_property; + +[version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + box_erplineset_viewer_property = uiextras.BoxPanel('Parent', fig, 'Title', 'Lines & Legends', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); % Create boxpanel +elseif nargin == 1 + box_erplineset_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Lines & Legends', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w');%[0.7765,0.7294,0.8627] +else + box_erplineset_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Lines & Legends', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +end +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_lineset_property(FonsizeDefault); +varargout{1} = box_erplineset_viewer_property; + + function drawui_lineset_property(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + %%--------------------channel and bin setting---------------------- + gui_erplinset_waveviewer.DataSelBox = uiextras.VBox('Parent', box_erplineset_viewer_property,'BackgroundColor',ColorBviewer_def); + %%-----------------Setting for Auto------- + linAutoValue = 1; + if linAutoValue ==1 + DataEnable = 'off'; + else + DataEnable = 'on'; + end + gui_erplinset_waveviewer.parameters_title = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erplinset_waveviewer.parameters_title,'String','Lines:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left','FontWeight','bold'); % + + gui_erplinset_waveviewer.linesauto = uicontrol('Style','radiobutton','Parent', gui_erplinset_waveviewer.parameters_title,'String','Auto',... + 'callback',@lines_auto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',linAutoValue); % + gui_erplinset_waveviewer.linescustom = uicontrol('Style','radiobutton','Parent', gui_erplinset_waveviewer.parameters_title,'String','Custom',... + 'callback',@lines_custom,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',~linAutoValue); % + + set(gui_erplinset_waveviewer.parameters_title,'Sizes',[60 70 70]); + + %%-----------Setting for line table----------------------------- + gui_erplinset_waveviewer.line_customtable_title = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + try + plot_org = ERPwaviewer.plot_org; + if plot_org.Grid ==1 + GridNum = numel(ERPwaviewer.chan); + elseif plot_org.Grid ==2 + GridNum = numel(ERPwaviewer.bin); + elseif plot_org.Grid ==3 + GridNum = numel(ERPwaviewer.SelectERPIdx); + else + GridNum = numel(ERPwaviewer.chan); + end + catch + GridNum = []; + end + [lineNameStr,linecolors,linetypes,linewidths,linecolors_str,linetypes_str,linewidths_str,linecolorsrgb] = f_get_lineset_ERPviewer(); + if linAutoValue + lineset_str =table(lineNameStr,linecolors,linetypes,linewidths); + lineset_str = table2cell(lineset_str); + else + lineset_str =table(lineNameStr,linecolorsrgb,linetypes,linewidths); + lineset_str = table2cell(lineset_str); + end + gui_erplinset_waveviewer.line_customtable = uitable(gui_erplinset_waveviewer.line_customtable_title); + gui_erplinset_waveviewer.line_customtable.ColumnFormat = {'char', 'char',... + {'solid','dash','dot','dashdot','plus','circle','asterisk'},... + {'0.25','0.5','1','1.5','2','2.5','3','3.5','4','4.5','5','5.5','6','6.5','7','7.5','8','8.5','9','9.5','10','10.5'}}; + gui_erplinset_waveviewer.line_customtable.Data = lineset_str; + gui_erplinset_waveviewer.line_customtable.ColumnEditable = [false, true,true,true]; + gui_erplinset_waveviewer.line_customtable.FontSize = FonsizeDefault; + gui_erplinset_waveviewer.line_customtable.ColumnName = {'#','Color','Style', 'Width'}; + gui_erplinset_waveviewer.line_customtable.Enable = DataEnable; + gui_erplinset_waveviewer.line_customtable.BackgroundColor = [1 1 1;1 1 1]; + gui_erplinset_waveviewer.line_customtable.RowName = []; + gui_erplinset_waveviewer.line_customtable.ColumnWidth = {25 80 65 50}; + gui_erplinset_waveviewer.line_customtable.CellEditCallback = @line_customtable; + %%setting for uitable: https://undocumentedmatlab.com/artiALLERPwaviewercles/multi-line-uitable-column-headers + if gui_erplinset_waveviewer.linesauto.Value ==1 + gui_erplinset_waveviewer.line_customtable.Enable = 'off'; + else + gui_erplinset_waveviewer.line_customtable.Enable = 'on'; + end + ERPwaviewer.Lines.auto =gui_erplinset_waveviewer.linesauto.Value; + ERPwaviewer.Lines.data =gui_erplinset_waveviewer.line_customtable.Data; + + %%------------------setting for legend--------------------------------------- + legendAuto = 1; + gui_erplinset_waveviewer.legend_title = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erplinset_waveviewer.legend_title,'String','Legend:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left','FontWeight','bold'); % + gui_erplinset_waveviewer.legendauto = uicontrol('Style','radiobutton','Parent', gui_erplinset_waveviewer.legend_title,'String','Auto',... + 'callback',@legend_auto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',legendAuto); % + gui_erplinset_waveviewer.legendcustom = uicontrol('Style','radiobutton','Parent', gui_erplinset_waveviewer.legend_title,'String','Custom',... + 'callback',@legend_custom,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',~legendAuto); % + set( gui_erplinset_waveviewer.legend_title,'Sizes',[60 70 70]); + + + %%-----------Setting for legend table ----------------------------- + gui_erplinset_waveviewer.legend_customtable_title = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + for ii = 1:100 + LegendName{ii,1} = ''; + LegendNamenum(ii,1) =ii; + end + ALLERPIN = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + if max(ERPsetArray(:))> length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + try + plot_org = ERPwaviewer.plot_org; + ERPIN = ERPwaviewer.ERP; + if plot_org.Overlay ==1 + ChanArray = ERPwaviewer.chan; + for Numofchan = 1:numel(ChanArray) + LegendName{Numofchan,1} = char(chanStr(ChanArray(Numofchan))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==2 + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==3 + ALLERP = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + for Numoferpset = 1:numel(ERPsetArray) + LegendName{Numoferpset,1} = char(ALLERP(Numoferpset).erpname); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + else + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + catch + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + gui_erplinset_waveviewer.legend_customtable = uitable(gui_erplinset_waveviewer.legend_customtable_title); + gui_erplinset_waveviewer.legend_customtable.ColumnEditable = [false,true]; + + gui_erplinset_waveviewer.legend_customtable.Data = legendset_str; + gui_erplinset_waveviewer.legend_customtable.FontSize = FonsizeDefault; + gui_erplinset_waveviewer.legend_customtable.ColumnName = {'#','Name'}; + gui_erplinset_waveviewer.legend_customtable.CellEditCallback = @legend_customtable; + gui_erplinset_waveviewer.legend_customtable.BackgroundColor = [1 1 1;1 1 1]; + gui_erplinset_waveviewer.legend_customtable.RowName = []; + gui_erplinset_waveviewer.legend_customtable.ColumnWidth = {20 200}; + % gui_erplinset_waveviewer.legend_customtable.CellEditCallback = {@legend_customtable,ERPwaviewer_num}; + %%setting for uitable: https://undocumentedmatlab.com/artiALLERPwaviewercles/multi-line-uitable-column-headers + if gui_erplinset_waveviewer.legendauto.Value ==1 + gui_erplinset_waveviewer.legend_customtable.Enable = 'off'; + fontEnable = 'off'; + else + gui_erplinset_waveviewer.legend_customtable.Enable = 'on'; + fontEnable = 'on'; + end + ERPwaviewer.Legend.auto = gui_erplinset_waveviewer.legendauto.Value; + ERPwaviewer.Legend.data = gui_erplinset_waveviewer.legend_customtable.Data; + + + % + %%--------------------legend font and font size--------------------------- + gui_erplinset_waveviewer.labelfont_title = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + fontDef = 2; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + labelfontsizeinum = str2num(char(fontsize)); + LabelfontsizeValue = 4; + uicontrol('Style','text','Parent', gui_erplinset_waveviewer.labelfont_title ,'String','Font',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + gui_erplinset_waveviewer.font_custom_type = uicontrol('Style','popupmenu','Parent', gui_erplinset_waveviewer.labelfont_title ,'String',fonttype,... + 'callback',@legendfont,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',fontDef,'Enable',fontEnable); % + uicontrol('Style','text','Parent', gui_erplinset_waveviewer.labelfont_title ,'String','Size',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + gui_erplinset_waveviewer.font_custom_size = uicontrol('Style','popupmenu','Parent', gui_erplinset_waveviewer.labelfont_title ,'String',fontsize,... + 'callback',@legendfontsize,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',LabelfontsizeValue,'Enable',fontEnable); % + set(gui_erplinset_waveviewer.labelfont_title,'Sizes',[30 110 30 70]); + ERPwaviewer.Legend.font = gui_erplinset_waveviewer.font_custom_type.Value; + ERPwaviewer.Legend.fontsize = labelfontsizeinum(gui_erplinset_waveviewer.font_custom_size.Value); + + + %%----------------------------Legend textcolor--------------------- + legendtextcolorAuto =1; + gui_erplinset_waveviewer.legend_textitle = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erplinset_waveviewer.legend_textitle,'String','Text color',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + gui_erplinset_waveviewer.legendtextauto = uicontrol('Style','radiobutton','Parent', gui_erplinset_waveviewer.legend_textitle,'String','Auto',... + 'callback',@legendtextauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',legendtextcolorAuto,'Enable',fontEnable); % + gui_erplinset_waveviewer.legendtextcustom = uicontrol('Style','radiobutton','Parent',gui_erplinset_waveviewer.legend_textitle,'String','Same as lines',... + 'callback',@legendtextcustom,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',~legendtextcolorAuto,'Enable',fontEnable,'HorizontalAlignment','left'); % + set(gui_erplinset_waveviewer.legend_textitle,'Sizes',[70 60 150]); + ERPwaviewer.Legend.textcolor = gui_erplinset_waveviewer.legendtextauto.Value; + + %%------------------------Legend columns--------------------------- + legendcolumns =1; + gui_erplinset_waveviewer.legend_columnstitle = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erplinset_waveviewer.legend_columnstitle,'String','Columns',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + for Numoflegend = 1:100 + columnStr{Numoflegend} = num2str(Numoflegend); + end + gui_erplinset_waveviewer.legendcolumns = uicontrol('Style','popupmenu','Parent', gui_erplinset_waveviewer.legend_columnstitle,'String',columnStr,... + 'callback',@legendcolumns,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',legendcolumns,'Enable',fontEnable); % + uiextras.Empty('Parent', gui_erplinset_waveviewer.legend_columnstitle ); + set(gui_erplinset_waveviewer.legend_columnstitle,'Sizes',[60 100 70]); + ERPwaviewer.Legend.columns = gui_erplinset_waveviewer.legendcolumns.Value; + + + %%-------------------------help and apply-------------------------- + gui_erplinset_waveviewer.help_apply_title = uiextras.HBox('Parent', gui_erplinset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',gui_erplinset_waveviewer.help_apply_title ); + uicontrol('Style','pushbutton','Parent', gui_erplinset_waveviewer.help_apply_title ,'String','Cancel',... + 'callback',@linelegend_help,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'FontWeight','bold','HorizontalAlignment','left' + uiextras.Empty('Parent',gui_erplinset_waveviewer.help_apply_title ); + gui_erplinset_waveviewer.apply = uicontrol('Style','pushbutton','Parent',gui_erplinset_waveviewer.help_apply_title ,'String','Apply',... + 'callback',@LineLegend_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent',gui_erplinset_waveviewer.help_apply_title ); + set(gui_erplinset_waveviewer.help_apply_title ,'Sizes',[40 70 20 70 20]); + + set(gui_erplinset_waveviewer.DataSelBox ,'Sizes',[20 200 20 180 25 25 25 25]); + ALLERPwaviewer=ERPwaviewer; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + end + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +%%-------------------------Setting for load-------------------------------- + function lines_auto(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erplinset_waveviewer.linesauto.Value =1; + gui_erplinset_waveviewer.linescustom.Value = 0; + gui_erplinset_waveviewer.line_customtable.Enable = 'off'; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + try + plot_org = ERPwaviewer.plot_org; + if plot_org.Grid ==1 + GridNum = numel(ERPwaviewer.chan); + elseif plot_org.Grid ==2 + GridNum = numel(ERPwaviewer.bin); + elseif plot_org.Grid ==3 + GridNum = numel(ERPwaviewer.SelectERPIdx); + + else + GridNum = numel(ERPwaviewer.chan); + end + catch + GridNum = []; + end + [lineNameStr,linecolors,linetypes,linewidths,linecolors_str,linetypes_str,linewidths_str,linecolorsrgb] = f_get_lineset_ERPviewer(); + lineset_str =table(lineNameStr,linecolors,linetypes,linewidths); + lineset_str = table2cell(lineset_str); + gui_erplinset_waveviewer.line_customtable.ColumnFormat = {'char', 'char',... + {'solid','dash','dot','dashdot','plus','circle','asterisk'},... + {'0.25','0.5','1','1.5','2','2.5','3','3.5','4','4.5','5','5.5','6','6.5','7','7.5','8','8.5','9','9.5','10','10.5'}}; + gui_erplinset_waveviewer.line_customtable.Data = lineset_str; + end + +%%-------------------------Setting for Save-------------------------------- + function lines_custom(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erplinset_waveviewer.linesauto.Value =0; + gui_erplinset_waveviewer.linescustom.Value = 1; + gui_erplinset_waveviewer.line_customtable.Enable = 'on'; + [lineNameStr,linecolors,linetypes,linewidths,linecolors_str,linetypes_str,linewidths_str,linecolorsrgb] = f_get_lineset_ERPviewer(); + lineset_str =table(lineNameStr,linecolorsrgb,linetypes,linewidths); + lineset_str = table2cell(lineset_str); + gui_erplinset_waveviewer.line_customtable.ColumnFormat = {'char', 'char',... + {'solid','dash','dot','dashdot','plus','circle','asterisk'},... + {'0.25','0.5','1','1.5','2','2.5','3','3.5','4','4.5','5','5.5','6','6.5','7','7.5','8','8.5','9','9.5','10','10.5'}}; + for ii = 1:length(linecolorsrgb) + gui_erplinset_waveviewer.line_customtable.Data{ii,2} = linecolorsrgb{ii}; + end + end + +%%-------------------------Setting for Save as-------------------------------- + function line_customtable(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%--------------------legend auto----------------------------------- + function legend_auto(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erplinset_waveviewer.legendauto.Value = 1; + gui_erplinset_waveviewer.legendcustom.Value = 0; + gui_erplinset_waveviewer.legend_customtable.Enable = 'off'; + + gui_erplinset_waveviewer.font_custom_type.Enable = 'off'; % + gui_erplinset_waveviewer.font_custom_size.Enable = 'off'; + gui_erplinset_waveviewer.legendtextauto.Enable = 'off'; + gui_erplinset_waveviewer.legendtextcustom.Enable = 'off'; + gui_erplinset_waveviewer.legendtextauto.Value = 1; + gui_erplinset_waveviewer.legendtextcustom.Value = 0; + gui_erplinset_waveviewer.legendcolumns.Value =1; + gui_erplinset_waveviewer.legendcolumns.Enable = 'off'; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for ii = 1:100 + LegendName{ii,1} = ''; + LegendNamenum(ii,1) =ii; + end + try + plot_org = ERPwaviewer.plot_org; + ERPIN = ERPwaviewer.ERP; + if plot_org.Overlay ==1 + LegendName = []; + ChanArray = ERPwaviewer.chan; + + for Numofchan = 1:numel(ChanArray) + LegendName{Numofchan,1} = ERPIN.chanlocs(ChanArray(Numofchan)).labels; + end + for ii = length(LegendName)+1:100 + LegendName{ii,1} = ''; + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==2 + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(ERPIN.bindescr{binArray(Numofbin)}); + end + for ii = length(LegendName)+1:100 + LegendName{ii,1} = ''; + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==3 + ALLERP = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + for Numoferpset = 1:numel(ERPsetArray) + LegendName{Numoferpset,1} = char(ALLERP(ERPsetArray(Numoferpset)).erpname); + end + for ii = length(LegendName)+1:100 + LegendName{ii,1} = ''; + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + else + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(ERPIN.bindescr{binArray(Numofbin)}); + end + for ii = length(LegendName)+1:100 + LegendName{ii,1} = ''; + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + catch + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + gui_erplinset_waveviewer.legend_customtable.ColumnEditable = [false,true]; + gui_erplinset_waveviewer.legend_customtable.Data = legendset_str; + gui_erplinset_waveviewer.font_custom_size.Value = 4; + gui_erplinset_waveviewer.font_custom_type.Value =1; + end + +%%-------------------legend custom----------------------------------------- + function legend_custom(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erplinset_waveviewer.legendauto.Value = 0; + gui_erplinset_waveviewer.legendcustom.Value = 1; + gui_erplinset_waveviewer.legend_customtable.Enable = 'on'; + gui_erplinset_waveviewer.font_custom_type.Enable = 'on'; % + gui_erplinset_waveviewer.font_custom_size.Enable = 'on'; + gui_erplinset_waveviewer.legendtextauto.Enable = 'on'; + gui_erplinset_waveviewer.legendtextcustom.Enable = 'on'; + gui_erplinset_waveviewer.legendcolumns.Enable = 'on'; + end + +%%---------------------------legend table---------------------------------- + function legend_customtable(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%----------------------font of legend text-------------------------------- + function legendfont(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%----------------------fontsize of legend text---------------------------- + function legendfontsize(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%----------------------------textcolor auto------------------------------- + function legendtextauto(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erplinset_waveviewer.legendtextauto.Value =1; % + gui_erplinset_waveviewer.legendtextcustom.Value =0; + end + + +%%----------------------------textcolor auto------------------------------- + function legendtextcustom(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erplinset_waveviewer.legendtextauto.Value =0; % + gui_erplinset_waveviewer.legendtextcustom.Value =1; + end + +%%----------------------Columns of legend names---------------------------- + function legendcolumns(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_linelegend',1); + gui_erplinset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; %%mark the changes + gui_erplinset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplineset_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + end + + +%%-------------------------------Help-------------------------------------- + function linelegend_help(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + changeFlag = estudioworkingmemory('MyViewer_linelegend'); + if changeFlag~=1 + return; + end + + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nLines & Legends > Cancel-f_ERP_lineset_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + + gui_erplinset_waveviewer.linesauto.Value= ERPwaviewer_apply.Lines.auto; + gui_erplinset_waveviewer.linescustom.Value= ~ERPwaviewer_apply.Lines.auto; + gui_erplinset_waveviewer.line_customtable.Data=ERPwaviewer_apply.Lines.data; + if gui_erplinset_waveviewer.linesauto.Value==1 + gui_erplinset_waveviewer.line_customtable.Enable = 'off'; + else + gui_erplinset_waveviewer.line_customtable.Enable = 'on'; + end + + gui_erplinset_waveviewer.legendauto.Value= ERPwaviewer_apply.Legend.auto; + gui_erplinset_waveviewer.legendcustom.Value= ~ERPwaviewer_apply.Legend.auto; + gui_erplinset_waveviewer.legend_customtable.Data=ERPwaviewer_apply.Legend.data; + + + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + labelfontsizeinum = str2num(char(fontsize)); + gui_erplinset_waveviewer.font_custom_type.Value= ERPwaviewer_apply.Legend.font; + fontsizeValue = ERPwaviewer_apply.Legend.fontsize ; + [x_label,y_label] = find(labelfontsizeinum==fontsizeValue); + if isempty(x_label) + x_label = 4; + end + gui_erplinset_waveviewer.font_custom_size.Value= x_label; + gui_erplinset_waveviewer.legendtextauto.Value= ERPwaviewer_apply.Legend.textcolor; + gui_erplinset_waveviewer.legendtextcustom.Value= ~ERPwaviewer_apply.Legend.textcolor; + gui_erplinset_waveviewer.legendcolumns.Value=ERPwaviewer_apply.Legend.columns; + if gui_erplinset_waveviewer.legendauto.Value==1 + LegendEnable = 'off'; + else + LegendEnable = 'on'; + end + gui_erplinset_waveviewer.font_custom_type.Enable = LegendEnable; + gui_erplinset_waveviewer.font_custom_size.Enable = LegendEnable; + gui_erplinset_waveviewer.legendtextauto.Enable = LegendEnable; + gui_erplinset_waveviewer.legendtextcustom.Enable = LegendEnable; + gui_erplinset_waveviewer.legendcolumns.Enable = LegendEnable; + gui_erplinset_waveviewer.legend_customtable.Enable = LegendEnable; + + estudioworkingmemory('MyViewer_linelegend',0); + gui_erplinset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_erplinset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erplineset_viewer_property.TitleColor= [0.5 0.5 0.9]; + end + + +%%-----------------Apply the changed parameters---------------------------- + function LineLegend_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges();%%check if the changes were applied for the other panels + if ~isempty(messgStr) && viewerpanelIndex~=6 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_linelegend',0); + gui_erplinset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_erplinset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erplineset_viewer_property.TitleColor= [0.5 0.5 0.9]; + + MessageViewer= char(strcat('Lines & Legends > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer_apply = ALLERPwaviewer; + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Lines & Legends > Apply-f_ERP_lineset_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + ERPwaviewer_apply.Lines.auto = gui_erplinset_waveviewer.linesauto.Value; + ERPwaviewer_apply.Lines.data = gui_erplinset_waveviewer.line_customtable.Data; + ERPwaviewer_apply.Legend.auto = gui_erplinset_waveviewer.legendauto.Value; + ERPwaviewer_apply.Legend.data = gui_erplinset_waveviewer.legend_customtable.Data; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + labelfontsizeinum = str2num(char(fontsize)); + ERPwaviewer_apply.Legend.font = gui_erplinset_waveviewer.font_custom_type.Value; + ERPwaviewer_apply.Legend.fontsize = labelfontsizeinum(gui_erplinset_waveviewer.font_custom_size.Value); + ERPwaviewer_apply.Legend.textcolor = gui_erplinset_waveviewer.legendtextauto.Value; + ERPwaviewer_apply.Legend.columns = gui_erplinset_waveviewer.legendcolumns.Value; + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; + end + + +%%--------------change the legend name------------------------------------- + function legend_change(~,~) + if viewer_ERPDAT.count_legend==0 + return; + end + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for ii = 1:100 + LegendName{ii,1} = ''; + LegendNamenum(ii,1) =ii; + end + ALLERPIN = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + if max(ERPsetArray(:))> length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + try + plot_org = ERPwaviewer.plot_org; + ERPIN = ERPwaviewer.ERP; + if plot_org.Overlay ==1 + ChanArray = ERPwaviewer.chan; + for Numofchan = 1:numel(ChanArray) + LegendName{Numofchan,1} = char(chanStr(ChanArray(Numofchan))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==2 + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==3 + ALLERP = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + for Numoferpset = 1:numel(ERPsetArray) + LegendName{Numoferpset,1} = char(ALLERP(ERPsetArray(Numoferpset)).erpname); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + else + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + catch + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + if gui_erplinset_waveviewer.legendauto.Value ==1 + gui_erplinset_waveviewer.legend_customtable.Data = legendset_str; + ERPwaviewer.Legend.auto = gui_erplinset_waveviewer.legendauto.Value; + ERPwaviewer.Legend.data = gui_erplinset_waveviewer.legend_customtable.Data; + ALLERPwaviewer=ERPwaviewer; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + end + end + +%%--------changed the legend names based on the current page--------------- + function page_xyaxis_change(~,~) + if viewer_ERPDAT.page_xyaxis==0 + return; + end + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for ii = 1:100 + LegendName{ii,1} = ''; + LegendNamenum(ii,1) =ii; + end + ALLERPIN = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + if max(ERPsetArray(:))> length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + try + plot_org = ERPwaviewer.plot_org; + ERPIN = ERPwaviewer.ERP; + if plot_org.Overlay ==1 + ChanArray = ERPwaviewer.chan; + for Numofchan = 1:numel(ChanArray) + LegendName{Numofchan,1} = char(chanStr(ChanArray(Numofchan))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==2 + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==3 + ALLERP = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + for Numoferpset = 1:numel(ERPsetArray) + LegendName{Numoferpset,1} = char(ALLERP(ERPsetArray(Numoferpset)).erpname); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + else + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + catch + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + if gui_erplinset_waveviewer.legendauto.Value ==1 && plot_org.Pages ==3 + gui_erplinset_waveviewer.legend_customtable.Data = legendset_str; + ERPwaviewer.Legend.auto = gui_erplinset_waveviewer.legendauto.Value; + ERPwaviewer.Legend.data = gui_erplinset_waveviewer.legend_customtable.Data; + assignin('base','ALLERPwaviewer',ERPwaviewer); + end + end + + +%%-----change legend if ERPsets is changed from the first two panels------- + function v_currentERP_change(~,~) + if viewer_ERPDAT.Count_currentERP == 0 + return; + end + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for ii = 1:100 + LegendName{ii,1} = ''; + LegendNamenum(ii,1) =ii; + end + ALLERPIN = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + if max(ERPsetArray(:))> length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + try + plot_org = ERPwaviewer.plot_org; + ERPIN = ERPwaviewer.ERP; + if plot_org.Overlay ==1 + ChanArray = ERPwaviewer.chan; + for Numofchan = 1:numel(ChanArray) + LegendName{Numofchan,1} = char(chanStr(ChanArray(Numofchan))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==2 + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + elseif plot_org.Overlay ==3 + ALLERP = ERPwaviewer.ALLERP; + ERPsetArray = ERPwaviewer.SelectERPIdx; + for Numoferpset = 1:numel(ERPsetArray) + LegendName{Numoferpset,1} = char(ALLERP(ERPsetArray(Numoferpset)).erpname); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + else + binArray = ERPwaviewer.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + catch + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + if gui_erplinset_waveviewer.legendauto.Value ==1 + gui_erplinset_waveviewer.legend_customtable.Data = legendset_str; + ERPwaviewer.Legend.auto = gui_erplinset_waveviewer.legendauto.Value; + ERPwaviewer.Legend.data = gui_erplinset_waveviewer.legend_customtable.Data; + assignin('base','ALLERPwaviewer',ERPwaviewer); + end + end + + + +%%-------------change this panel based on the loaded parameters------------ + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + %%Line settings + LineValue = ERPwaviewer.Lines.auto; + if numel(LineValue)~=1 || (LineValue~=1 && LineValue~=0) + LineValue = 1; + ERPwaviewer.Lines.auto = 1; + end + if LineValue==1 + gui_erplinset_waveviewer.linesauto.Value =1; + gui_erplinset_waveviewer.linescustom.Value = 0; + gui_erplinset_waveviewer.line_customtable.Enable = 'off'; + else + gui_erplinset_waveviewer.linesauto.Value =0; + gui_erplinset_waveviewer.linescustom.Value = 1; + gui_erplinset_waveviewer.line_customtable.Enable = 'on'; + end + + LineData = ERPwaviewer.Lines.data; + gui_erplinset_waveviewer.line_customtable.Data = LineData; + % + %%Legend setting + LegendAuto = ERPwaviewer.Legend.auto; + if LegendAuto==1 + gui_erplinset_waveviewer.legendauto.Value = 1; + gui_erplinset_waveviewer.legendcustom.Value = 0; + gui_erplinset_waveviewer.legend_customtable.Enable = 'off'; + gui_erplinset_waveviewer.font_custom_type.Enable = 'off'; % + gui_erplinset_waveviewer.font_custom_size.Enable = 'off'; + gui_erplinset_waveviewer.legendtextauto.Enable = 'off'; + gui_erplinset_waveviewer.legendtextcustom.Enable = 'off'; + gui_erplinset_waveviewer.legendtextauto.Value = 1; + gui_erplinset_waveviewer.legendtextcustom.Value = 0; + gui_erplinset_waveviewer.legendcolumns.Value =1; + gui_erplinset_waveviewer.legendcolumns.Enable = 'off'; + else + gui_erplinset_waveviewer.legendauto.Value = 0; + gui_erplinset_waveviewer.legendcustom.Value = 1; + gui_erplinset_waveviewer.legend_customtable.Enable = 'on'; + gui_erplinset_waveviewer.font_custom_type.Enable = 'on'; % + gui_erplinset_waveviewer.font_custom_size.Enable = 'on'; + gui_erplinset_waveviewer.legendtextauto.Enable = 'on'; + gui_erplinset_waveviewer.legendtextcustom.Enable = 'on'; + gui_erplinset_waveviewer.legendcolumns.Enable = 'on'; + end + LegendData = ERPwaviewer.Legend.data; + gui_erplinset_waveviewer.legend_customtable.Data = LegendData; + legendfont =ERPwaviewer.Legend.font; + gui_erplinset_waveviewer.font_custom_type.Value = legendfont; + legendfontsize = ERPwaviewer.Legend.fontsize; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + gui_erplinset_waveviewer.font_custom_size.String = fontsize; + fontsize = str2num(char(fontsize)); + [xsize,y] = find(fontsize ==legendfontsize); + gui_erplinset_waveviewer.font_custom_size.Value = xsize; + + Legendtextcolor = ERPwaviewer.Legend.textcolor; + if Legendtextcolor==1 + gui_erplinset_waveviewer.legendtextauto.Value =1; % + gui_erplinset_waveviewer.legendtextcustom.Value =0; + else + gui_erplinset_waveviewer.legendtextauto.Value =0; % + gui_erplinset_waveviewer.legendtextcustom.Value =1; + end + legendColumns = ERPwaviewer.Legend.columns; + gui_erplinset_waveviewer.legendcolumns.Value = legendColumns; + for Numoflegend = 1:100 + columnStr{Numoflegend} = num2str(Numoflegend); + end + gui_erplinset_waveviewer.legendcolumns.String = columnStr; + end + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_linelegend'); + if changeFlag~=1 + return; + end + LineLegend_apply(); + end + +%%------------------------------------------------------------------------- +%%-----------------Reset this panel with the default parameters------------ +%%------------------------------------------------------------------------- + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==6 + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI error: Restart ERPwave Viewer'); + return; + end + %%Lines + gui_erplinset_waveviewer.linesauto.Value =1; + gui_erplinset_waveviewer.linescustom.Value = 0; + gui_erplinset_waveviewer.line_customtable.Enable = 'off'; + [lineNameStr,linecolors,linetypes,linewidths,linecolors_str,linetypes_str,linewidths_str,linecolorsrgb] = f_get_lineset_ERPviewer(); + lineset_str =table(lineNameStr,linecolors,linetypes,linewidths); + lineset_str = table2cell(lineset_str); + gui_erplinset_waveviewer.line_customtable.ColumnFormat = {'char', 'char',... + {'solid','dash','dot','dashdot','plus','circle','asterisk'},... + {'0.25','0.5','1','1.5','2','2.5','3','3.5','4','4.5','5','5.5','6','6.5','7','7.5','8','8.5','9','9.5','10','10.5'}}; + gui_erplinset_waveviewer.line_customtable.Data = lineset_str; + ERPwaviewerin.Lines.auto =1; + ERPwaviewerin.Lines.data = gui_erplinset_waveviewer.line_customtable.Data; + %%Legends + gui_erplinset_waveviewer.legendauto.Value = 1; + gui_erplinset_waveviewer.legendcustom.Value = 0; + gui_erplinset_waveviewer.legend_customtable.Enable = 'off'; + gui_erplinset_waveviewer.font_custom_type.Enable = 'off'; % + gui_erplinset_waveviewer.font_custom_size.Enable = 'off'; + gui_erplinset_waveviewer.legendtextauto.Enable = 'off'; + gui_erplinset_waveviewer.legendtextcustom.Enable = 'off'; + gui_erplinset_waveviewer.legendtextauto.Value = 1; + gui_erplinset_waveviewer.legendtextcustom.Value = 0; + gui_erplinset_waveviewer.legendcolumns.Value =1; + gui_erplinset_waveviewer.legendcolumns.Enable = 'off'; + + for ii = 1:100 + LegendName{ii,1} = ''; + LegendNamenum(ii,1) =ii; + end + ALLERPIN = ERPwaviewerin.ALLERP; + ERPsetArray = ERPwaviewerin.SelectERPIdx; + if max(ERPsetArray(:))> length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + try + plot_org = ERPwaviewerin.plot_org; + ERPIN = ERPwaviewerin.ERP; + if plot_org.Overlay ==2 + binArray = ERPwaviewerin.bin; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + catch + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + end + gui_erplinset_waveviewer.legend_customtable.ColumnEditable = [false,true]; + gui_erplinset_waveviewer.legend_customtable.Data = legendset_str; + gui_erplinset_waveviewer.font_custom_size.Value = 4; + gui_erplinset_waveviewer.font_custom_type.Value =2; + ERPwaviewerin.Legend.auto=1; + ERPwaviewerin.Legend.data =gui_erplinset_waveviewer.legend_customtable.Data; + ERPwaviewerin.Legend.font=1; + ERPwaviewerin.Legend.fontsize=10; + ERPwaviewerin.Legend.textcolor=1; + ERPwaviewerin.Legend.columns=1; + assignin('base','ALLERPwaviewer',ERPwaviewerin); + gui_erplinset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_erplinset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erplineset_viewer_property.TitleColor= [0.5 0.5 0.9]; + viewer_ERPDAT.Reset_Waviewer_panel=7; + end + end +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_otherset_waveviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_otherset_waveviewer_GUI.m new file mode 100755 index 00000000..23fcd3a2 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_otherset_waveviewer_GUI.m @@ -0,0 +1,803 @@ +%%This function is to plot the panel for "Viewer properties". + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_otherset_waveviewer_GUI(varargin) + +global viewer_ERPDAT; +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +% addlistener(viewer_ERPDAT,'Process_messg_change',@Process_messg_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); + + +gui_otherset_waveviewer = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erplabelset_viewer_otherset; +[version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + box_erplabelset_viewer_otherset = uiextras.BoxPanel('Parent', fig, 'Title', 'Other', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize',12); % Create boxpanel +elseif nargin == 1 + box_erplabelset_viewer_otherset = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Other', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize',12); +else + box_erplabelset_viewer_otherset = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Other', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +end +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_otherset_waviewer(FonsizeDefault); +varargout{1} = box_erplabelset_viewer_otherset; + + function drawui_otherset_waviewer(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_lineset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + gui_otherset_waveviewer.DataSelBox = uiextras.VBox('Parent', box_erplabelset_viewer_otherset,'BackgroundColor',ColorBviewer_def); + %%----------Polarity Setting--------------------------------------- + Polaritylabel = 1; + gui_otherset_waveviewer.polarity_title = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_otherset_waveviewer.polarity_title,'String','Polarity',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); %,'FontWeight','bold' + gui_otherset_waveviewer.polarity_up = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.polarity_title,'String','Positive up',... + 'callback',@polarup,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',Polaritylabel); %,'FontWeight','bold' + gui_otherset_waveviewer.polarity_down = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.polarity_title,'String','Negative up',... + 'callback',@polardown, 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',~Polaritylabel); %,'FontWeight','bold' + set(gui_otherset_waveviewer.polarity_title,'Sizes',[50 90 90]); + ERPwaviewer.polarity=gui_otherset_waveviewer.polarity_up.Value; + + %%----------------SEM of wave-------------------------------------- + SEMlabel = 0; + SEMCustomValue = 0; + gui_otherset_waveviewer.SEM_title = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_otherset_waveviewer.show_SEM = uicontrol('Style','checkbox','Parent', gui_otherset_waveviewer.SEM_title ,'String','Show standard error',... + 'callback',@showSEM,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',SEMlabel); % + SMEString = {'0','1','2','3','4','5','6','7','8','9','10'}; + gui_otherset_waveviewer.SEM_custom = uicontrol('Style','popupmenu','Parent', gui_otherset_waveviewer.SEM_title ,'String',SMEString,... + 'callback',@SEMerror,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',SEMCustomValue+1); % + set(gui_otherset_waveviewer.SEM_title,'Sizes',[160 80]); + ERPwaviewer.SEM.active =gui_otherset_waveviewer.show_SEM.Value; + ERPwaviewer.SEM.error = gui_otherset_waveviewer.SEM_custom.Value-1; + SEMtransValue = 0; + gui_otherset_waveviewer.SEMtrans_title = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_otherset_waveviewer.SEMtrans_title ,'String','transoarency',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','right'); % + SMEtransString = {'0','0.1','0.2','0.3','0.4','0.5','0.6','0.7','0.8','0.9','1'}; + gui_otherset_waveviewer.SEMtrans_custom = uicontrol('Style','popupmenu','Parent', gui_otherset_waveviewer.SEMtrans_title ,'String',SMEtransString,... + 'callback',@SEMtrans,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',SEMtransValue*10 +1); % + set(gui_otherset_waveviewer.SEMtrans_title,'Sizes',[160 80]); + if SEMlabel + gui_otherset_waveviewer.SEM_custom.Enable = 'on'; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'on'; + else + gui_otherset_waveviewer.SEM_custom.Enable = 'off'; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'off'; + end + ERPwaviewer.SEM.trans = (gui_otherset_waveviewer.SEMtrans_custom.Value-1)/10; + + %%----------------baseline correction------------------------------ + blc_def = 'none'; + try + blc_def = ERPwaviewer.baselinecorr; + catch + blc_def = 'none'; + end + if numel(blc_def) ==2 + noneValue =0; + preValue =0; + postValue = 0; + wholeValue =0; + customValue = 1; + customString = num2str(blc_def); + customEnable = 'on'; + else + if strcmpi(blc_def,'none') + noneValue =1; + preValue =0; + postValue = 0; + wholeValue =0; + customValue = 0; + customString = ''; + customEnable = 'off'; + elseif strcmpi(blc_def,'pre') + noneValue =0; + preValue =1; + postValue = 0; + wholeValue =0; + customValue = 0; + customString = ''; + customEnable = 'off'; + elseif strcmpi(blc_def,'post') + noneValue =0; + preValue =0; + postValue = 1; + wholeValue =0; + customValue = 0; + customString = ''; + customEnable = 'off'; + elseif strcmpi(blc_def,'whole') + noneValue =0; + preValue =0; + postValue = 0; + wholeValue =1; + customValue = 0; + customString = ''; + customEnable = 'off'; + end + end + gui_otherset_waveviewer.bsl_title = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_otherset_waveviewer.bsl_title ,'String','Baseline Correction:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'FontWeight','bold'); %,'HorizontalAlignment','left' + gui_otherset_waveviewer.bsl_title_1 = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_otherset_waveviewer.bsl_none = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.bsl_title_1 ,'String','None',... + 'callback',@bsl_none,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',noneValue); + gui_otherset_waveviewer.bsl_pre = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.bsl_title_1 ,'String','Pre',... + 'callback',@bsl_pre,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',preValue); %,'HorizontalAlignment','left','FontWeight','bold' + gui_otherset_waveviewer.bsl_post = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.bsl_title_1 ,'String','Post',... + 'callback',@bsl_post, 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',postValue); %,'HorizontalAlignment','left','FontWeight','bold' + gui_otherset_waveviewer.bsl_whole = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.bsl_title_1 ,'String','Whole',... + 'callback',@bsl_whole, 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',wholeValue); %,'HorizontalAlignment','left','FontWeight','bold' + gui_otherset_waveviewer.bsl_title_3 = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_otherset_waveviewer.bsl_custom = uicontrol('Style','radiobutton','Parent', gui_otherset_waveviewer.bsl_title_3 ,'String','Custom',... + 'callback',@bsl_custom,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',customValue); %,'HorizontalAlignment','left','FontWeight','bold' + gui_otherset_waveviewer.bsl_customedit = uicontrol('Style','edit','Parent', gui_otherset_waveviewer.bsl_title_3 ,'String',customString,... + 'callback',@bsl_customedit, 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',customEnable); %,'HorizontalAlignment','left','FontWeight','bold' + set( gui_otherset_waveviewer.bsl_title_3,'Sizes',[80 155]); + + if gui_otherset_waveviewer.bsl_none.Value ==1 + ERPwaviewer.baselinecorr = 'none'; + elseif gui_otherset_waveviewer.bsl_pre.Value ==1 + ERPwaviewer.baselinecorr = 'pre'; + elseif gui_otherset_waveviewer.bsl_post.Value ==1 + ERPwaviewer.baselinecorr = 'post'; + elseif gui_otherset_waveviewer.bsl_whole.Value ==1 + ERPwaviewer.baselinecorr = 'whole'; + elseif gui_otherset_waveviewer.bsl_custom.Value ==1 + ERPwaviewer.baselinecorr = str2num(char(gui_otherset_waveviewer.bsl_customedit)); + else + ERPwaviewer.baselinecorr = 'none'; + end + + %%Figure background color: the default is white + bgColor = [1 1 1]; + gui_otherset_waveviewer.figurebakcolor_title = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_otherset_waveviewer.figurebakcolor_title,'String','Figure Background Color:',... + 'FontSize',FonsizeDefault-1,'BackgroundColor',ColorBviewer_def,'FontWeight','bold'); %,'HorizontalAlignment','left' + gui_otherset_waveviewer.figurebakcolor = uicontrol('Style','edit','Parent', gui_otherset_waveviewer.figurebakcolor_title,'String',num2str(bgColor),... + 'callback',@figbackcolor,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + set(gui_otherset_waveviewer.figurebakcolor_title,'Sizes',[150 85]); + ERPwaviewer.figbackgdcolor = str2num(gui_otherset_waveviewer.figurebakcolor.String); + + + %%Apply and save the changed parameters + gui_otherset_waveviewer.help_run_title = uiextras.HBox('Parent', gui_otherset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent', gui_otherset_waveviewer.help_run_title ); + uicontrol('Style','pushbutton','Parent', gui_otherset_waveviewer.help_run_title,'String','Cancel',... + 'callback',@other_help,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'FontWeight','bold'%,'HorizontalAlignment','left' + uiextras.Empty('Parent', gui_otherset_waveviewer.help_run_title ); + gui_otherset_waveviewer.apply = uicontrol('Style','pushbutton','Parent', gui_otherset_waveviewer.help_run_title ,'String','Apply',... + 'callback',@other_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent', gui_otherset_waveviewer.help_run_title); + set(gui_otherset_waveviewer.help_run_title,'Sizes',[40 70 20 70 20]); + + set(gui_otherset_waveviewer.DataSelBox,'Sizes',[25 25 25 20 20 25 25 25]); + ALLERPwaviewer=ERPwaviewer; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + end + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + + +%%-------------------------Setting for Polarity up------------------------- + function polarup(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.polarity_up.Value = 1; + gui_otherset_waveviewer.polarity_down.Value = 0; + end + +%%-------------------------Setting for Polarity down----------------------- + function polardown(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + gui_otherset_waveviewer.polarity_up.Value = 0; + gui_otherset_waveviewer.polarity_down.Value = 1; + end + +%%-------------------Show SEM---------------------------------------------- + function showSEM(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + Value = Str.Value; + if Value ==1 + gui_otherset_waveviewer.SEM_custom.Enable = 'on'; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'on'; + else + gui_otherset_waveviewer.SEM_custom.Enable = 'off'; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'off'; + gui_otherset_waveviewer.SEM_custom.Value = 1; + gui_otherset_waveviewer.SEMtrans_custom.Value = 1; + end + end + + +%%----------------SEM error setting---------------------------------------- + function SEMerror(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + end +%%---------------------------SEM trans.------------------------------------ + function SEMtrans(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%--------------------Baseline correction:none----------------------------- + function bsl_none(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + gui_otherset_waveviewer.bsl_none.Value =1; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + end + + +%%--------------------Baseline correction:pre----------------------------- + function bsl_pre(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =1; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + end + + +%%--------------------Baseline correction:post----------------------------- + function bsl_post(~,~) + + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =1; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + end + +%%--------------------Baseline correction:whole---------------------------- + function bsl_whole(~,~) + + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =1; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + end + +%%--------------------Baseline correction:custom--------------------------- + function bsl_custom(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 1; + gui_otherset_waveviewer.bsl_customedit.Enable = 'on'; + end +%%-------------------Custom define baseline period------------------------- + function bsl_customedit(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + MessageViewer= char(strcat('Other > Baseline Correction > Custom')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Other > Baseline Correction > Custom() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + bacselinePeriod = str2num(char(Str.String)); + if isempty(bacselinePeriod) || numel(bacselinePeriod)==1 + viewer_ERPDAT.Process_messg =3; + Str.String = ''; + fprintf(2,'\n Other > Baseline Correction > Custom() error: \n Inputs must be two numbers.\n\n'); + return; + end + + TimeRange = ERPwaviewer.ERP.times; + if bacselinePeriod(1) Baseline Correction > Custom() error: \n',32,msgboxText,'.\n\n']); + return; + end + if bacselinePeriod(2)>TimeRange(end) + msgboxText = strcat('Right edge of baseline period should be smaller than',32,num2str(TimeRange(end)),'ms'); + viewer_ERPDAT.Process_messg =3; + Str.String = ''; + fprintf(2,['\n Other > Baseline Correction > Custom() error: \n',32,msgboxText,'.\n\n']); + return; + end + if bacselinePeriod(1)>=bacselinePeriod(end) + msgboxText = strcat('Right edge of baseline period should be larger than left edge'); + viewer_ERPDAT.Process_messg =3; + Str.String = ''; + fprintf(2,['\n Other > Baseline Correction > Custom() error: \n',32,msgboxText,'.\n\n']); + return; + end + end + + +%%-------------------figure background color------------------------------- + function figbackcolor(Str,~) + + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_other',1); + gui_otherset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_otherset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erplabelset_viewer_otherset.TitleColor= [0.4940 0.1840 0.5560]; + + bgColor = str2num(Str.String); + if isempty(bgColor) + msgboxText = strcat('Inputs are invalid and it should be,e.g., [1 1 1]'); + title = 'EStudio>ERP Wave Viewer>Other: Figure Background Color'; + errorfound(msgboxText, title); + Str.String = num2str([1 1 1]); + return; + end + + if max(bgColor)>1 || min(bgColor) <0 || numel(bgColor)~=3 + msgboxText = strcat('Inputs are invalid and it should be,e.g., [1 1 1]'); + title = 'EStudio>ERP Wave Viewer>Other: Figure Background Color'; + errorfound(msgboxText, title); + Str.String = num2str([1 1 1]); + return; + end + end + +%%----------------------------Help----------------------------------------- + function other_help(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + changeFlag = estudioworkingmemory('MyViewer_other'); + if changeFlag~=1 + return; + end + + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\nOther > Cancel-f_ERP_otherset_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + + gui_otherset_waveviewer.polarity_up.Value=ERPwaviewer_apply.polarity;%% the polarity of wave + gui_otherset_waveviewer.polarity_down.Value = ~ERPwaviewer_apply.polarity; + %%SME + SMEActiveFlag = ERPwaviewer_apply.SEM.active; + gui_otherset_waveviewer.show_SEM.Value=SMEActiveFlag; + gui_otherset_waveviewer.SEM_custom.Value=ERPwaviewer_apply.SEM.error +1; + %%trans + gui_otherset_waveviewer.SEMtrans_custom.Value = 10* ERPwaviewer_apply.SEM.trans +1; + if SMEActiveFlag==1 + Enable = 'on'; + else + Enable = 'off'; + end + gui_otherset_waveviewer.SEM_custom.Enable = Enable; + gui_otherset_waveviewer.SEMtrans_custom.Enable = Enable; + gui_otherset_waveviewer.figurebakcolor.String=num2str(ERPwaviewer_apply.figbackgdcolor); + %%baseline correction method + BslMethod = ERPwaviewer_apply.baselinecorr; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + gui_otherset_waveviewer.bsl_customedit.String = ''; + if ischar(BslMethod) + if strcmpi(BslMethod,'none') + gui_otherset_waveviewer.bsl_custom.Value =0; + gui_otherset_waveviewer.bsl_none.Value=1; + gui_otherset_waveviewer.bsl_pre.Value=0; + gui_otherset_waveviewer.bsl_post.Value=0; + gui_otherset_waveviewer.bsl_whole.Value=0; + elseif strcmpi(BslMethod,'pre') + gui_otherset_waveviewer.bsl_custom.Value =0; + gui_otherset_waveviewer.bsl_none.Value=0; + gui_otherset_waveviewer.bsl_pre.Value=1; + gui_otherset_waveviewer.bsl_post.Value=0; + gui_otherset_waveviewer.bsl_whole.Value=0; + elseif strcmpi(BslMethod,'post') + gui_otherset_waveviewer.bsl_custom.Value =0; + gui_otherset_waveviewer.bsl_none.Value=0; + gui_otherset_waveviewer.bsl_pre.Value=0; + gui_otherset_waveviewer.bsl_post.Value=1; + gui_otherset_waveviewer.bsl_whole.Value=0; + elseif strcmpi(BslMethod,'whole') + gui_otherset_waveviewer.bsl_custom.Value =0; + gui_otherset_waveviewer.bsl_none.Value=0; + gui_otherset_waveviewer.bsl_pre.Value=0; + gui_otherset_waveviewer.bsl_post.Value=0; + gui_otherset_waveviewer.bsl_whole.Value=1; + + end + elseif isnumeric(BslMethod) + gui_otherset_waveviewer.bsl_custom.Value =1; + gui_otherset_waveviewer.bsl_none.Value=0; + gui_otherset_waveviewer.bsl_pre.Value=0; + gui_otherset_waveviewer.bsl_post.Value=0; + gui_otherset_waveviewer.bsl_whole.Value=0; + gui_otherset_waveviewer.bsl_customedit.String = num2str(BslMethod); + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + end + estudioworkingmemory('MyViewer_other',0); + gui_otherset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_otherset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erplabelset_viewer_otherset.TitleColor= [0.5 0.5 0.9]; + + end + + +%%-------------------------Apply the changed parameters-------------------- + function other_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=7 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_other',0); + gui_otherset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_otherset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erplabelset_viewer_otherset.TitleColor= [0.5 0.5 0.9]; + MessageViewer= char(strcat('Other > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer_apply = ALLERPwaviewer; + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Other > Apply-f_ERP_otherset_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + ERPwaviewer_apply.polarity = gui_otherset_waveviewer.polarity_up.Value;%% the polarity of wave + %%SME + ERPwaviewer_apply.SEM.active = gui_otherset_waveviewer.show_SEM.Value; + ERPwaviewer_apply.SEM.error = gui_otherset_waveviewer.SEM_custom.Value-1; + %%trans + ERPwaviewer_apply.SEM.trans = (gui_otherset_waveviewer.SEMtrans_custom.Value-1)/10; + %%MGFP + % ERPwaviewer_apply.MGFP = gui_otherset_waveviewer.MGFP_on.Value; + ERPwaviewer_apply.figbackgdcolor = str2num(gui_otherset_waveviewer.figurebakcolor.String); + %%baseline correction method + if gui_otherset_waveviewer.bsl_none.Value ==1 + ERPwaviewer_apply.baselinecorr = 'none'; + elseif gui_otherset_waveviewer.bsl_pre.Value ==1 + ERPwaviewer_apply.baselinecorr = 'pre'; + elseif gui_otherset_waveviewer.bsl_post.Value ==1 + ERPwaviewer_apply.baselinecorr = 'post'; + elseif gui_otherset_waveviewer.bsl_whole.Value ==1 + ERPwaviewer_apply.baselinecorr = 'whole'; + elseif gui_otherset_waveviewer.bsl_custom.Value ==1 + ERPwaviewer_apply.baselinecorr = str2num(char(gui_otherset_waveviewer.bsl_customedit.String)); + %checking the defined time-window for baselne correction + if isempty(ERPwaviewer_apply.baselinecorr)|| numel(ERPwaviewer_apply.baselinecorr)==1 + msgboxText = strcat(' Inputs must be two numbers! If you donot change it, "none" will be used for baseline correction!'); + title = 'EStudio>ERP Wave Viewer: Baseline period for "Baseline Correction" on "Other"'; + errorfound(msgboxText, title); + ERPwaviewer_apply.baselinecorr = 'none'; + return; + end + %%may check the left and right edges for the defined + %%time=window + else + ERPwaviewer_apply.baselinecorr = 'none'; + end + ALLERPwaviewer=ERPwaviewer_apply; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; + end + +%%---------change this panel based on the loaded paras.-------------------- + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_otherset_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + PolirityValue = ERPwaviewer_apply.polarity; + if PolirityValue ==1 + gui_otherset_waveviewer.polarity_up.Value = 1; + gui_otherset_waveviewer.polarity_down.Value = 0; + else + gui_otherset_waveviewer.polarity_up.Value = 0; + gui_otherset_waveviewer.polarity_down.Value = 1; + end + + % + %%SEM settings + SEMValue = ERPwaviewer_apply.SEM.active; + if SEMValue==1 + gui_otherset_waveviewer.SEM_custom.Enable = 'on'; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'on'; + ERRORValue = ERPwaviewer_apply.SEM.error; + if isempty(ERRORValue) || ERRORValue<0 || ERRORValue>10 + ERRORValue = 0; + ERPwaviewer_apply.SEM.error = 0; + end + gui_otherset_waveviewer.SEM_custom.Value =ERRORValue+1; + SEMTrans = ERPwaviewer_apply.SEM.trans; + if isempty(SEMTrans) || SEMTrans<0 || SEMTrans>1 + SEMTrans = 0; + ERPwaviewer_apply.SEM.trans = 0; + end + gui_otherset_waveviewer.SEMtrans_custom.Value = SEMTrans*10 +1; + else + gui_otherset_waveviewer.SEM_custom.Enable = 'off'; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'off'; + gui_otherset_waveviewer.SEM_custom.Value =1; + gui_otherset_waveviewer.SEMtrans_custom.Value =1; + end + + % + %%Baseline settings + BalineCorrection = ERPwaviewer_apply.baselinecorr; + if numel(BalineCorrection) ==2 + if ~isnumeric(BalineCorrection) + gui_otherset_waveviewer.bsl_none.Value =1; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + ERPwaviewer_apply.baselinecorr = 'none'; + else + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 1; + gui_otherset_waveviewer.bsl_customedit.Enable = 'on'; + gui_otherset_waveviewer.bsl_customedit.String = num2str(BalineCorrection); + end + else + + if strcmpi(BalineCorrection,'pre') + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =1; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + elseif strcmpi(BalineCorrection,'post') + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =1; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + elseif strcmpi(BalineCorrection,'all') + gui_otherset_waveviewer.bsl_none.Value =0; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =1; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + else + gui_otherset_waveviewer.bsl_none.Value =1; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value = 0; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + end + end + + % + %%Background color + try + BackgroundColor = ERPwaviewer_apply.figbackgdcolor; + catch + BackgroundColor = [1 1 1]; + end + if isempty(BackgroundColor) || numel(BackgroundColor)~=3 || max(BackgroundColor)>1 ||min (BackgroundColor)<0 + BackgroundColor = [1 1 1]; + end + gui_otherset_waveviewer.figurebakcolor.String = num2str(BackgroundColor); + + ERPwaviewer_apply.figbackgdcolor = BackgroundColor; + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + end + + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_other'); + if changeFlag~=1 + return; + end + other_apply(); + end + + +%%------------------------------------------------------------------------- +%%-----------------Reset this panel with the default parameters------------ +%%------------------------------------------------------------------------- + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==7 + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_otherset_waveviewer_GUI error: Restart ERPwave Viewer'); + return; + end + + gui_otherset_waveviewer.polarity_up.Value =1; + gui_otherset_waveviewer.polarity_down.Value =0; + ERPwaviewerin.polarity = gui_otherset_waveviewer.polarity_up.Value;%% the polarity of wave + + %%SME + gui_otherset_waveviewer.show_SEM.Value =0; + ERPwaviewerin.SEM.active = gui_otherset_waveviewer.show_SEM.Value; + gui_otherset_waveviewer.SEM_custom.Value =1; + gui_otherset_waveviewer.SEM_custom.Enable = 'off'; + ERPwaviewerin.SEM.error = gui_otherset_waveviewer.SEM_custom.Value-1; + %%trans + ERPwaviewerin.SEM.trans = (gui_otherset_waveviewer.SEMtrans_custom.Value-1)/10; + gui_otherset_waveviewer.SEMtrans_custom.Value =1; + gui_otherset_waveviewer.SEMtrans_custom.Enable = 'off'; + gui_otherset_waveviewer.bsl_none.Value =1; + ERPwaviewerin.baselinecorr = 'none'; + gui_otherset_waveviewer.bsl_pre.Value =0; + gui_otherset_waveviewer.bsl_post.Value =0; + gui_otherset_waveviewer.bsl_whole.Value =0; + gui_otherset_waveviewer.bsl_custom.Value =0; + gui_otherset_waveviewer.bsl_customedit.String = ''; + gui_otherset_waveviewer.bsl_customedit.Enable = 'off'; + gui_otherset_waveviewer.figurebakcolor.String ='1,1,1'; + ERPwaviewerin.figbackgdcolor =[1 1 1]; + assignin('base','ALLERPwaviewer',ERPwaviewerin); + gui_otherset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_otherset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erplabelset_viewer_otherset.TitleColor= [0.5 0.5 0.9]; + % viewer_ERPDAT.Reset_Waviewer_panel=3; + end + end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_plotorg_waveviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_plotorg_waveviewer_GUI.m new file mode 100755 index 00000000..e98e88e8 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_plotorg_waveviewer_GUI.m @@ -0,0 +1,2642 @@ +%%This function is to plot the panel for "plot organization". + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_plotorg_waveviewer_GUI(varargin) + +global viewer_ERPDAT + +addlistener(viewer_ERPDAT,'v_currentERP_change',@v_currentERP_change); +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); + +gui_plotorg_waveviewer = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erpwave_viewer_plotorg; +[version reldate,ColorBdef,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + box_erpwave_viewer_plotorg = uiextras.BoxPanel('Parent', fig, 'Title', 'Plot Organization', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); % Create boxpanel +elseif nargin == 1 + box_erpwave_viewer_plotorg = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Organization', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); +else + box_erpwave_viewer_plotorg = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Organization', 'Padding', 5,... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +end + +estudioworkingmemory('OverlayIndex',0); + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end + +drawui_plot_org(FonsizeDefault); +varargout{1} = box_erpwave_viewer_plotorg; + + function drawui_plot_org(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewerin = ALLERPwaviewer; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + gui_plotorg_waveviewer.DataSelBox = uiextras.VBox('Parent', box_erpwave_viewer_plotorg,'BackgroundColor',ColorBviewer_def); + %%--------------------grind overlay and pages---------------------- + gui_plotorg_waveviewer.DataSelGrid = uiextras.Grid('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + % First column: + uiextras.Empty('Parent',gui_plotorg_waveviewer.DataSelGrid); + gui_plotorg_waveviewer.plotorg_c1 = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','',... + 'callback',@plotorg_c1,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',1); % 1B + gui_plotorg_waveviewer.plotorg_c2 = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','',... + 'callback',@plotorg_c2,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',0); % 1B + gui_plotorg_waveviewer.plotorg_c3 = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','',... + 'callback',@plotorg_c3,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',0); % 1B + gui_plotorg_waveviewer.plotorg_c4 = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','',... + 'callback',@plotorg_c4,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',0); % 1B + gui_plotorg_waveviewer.plotorg_c5 = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','',... + 'callback',@plotorg_c5,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',0); % 1B + gui_plotorg_waveviewer.plotorg_c6 = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','',... + 'callback',@plotorg_c6,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',0); % 1B + % Second column: + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Grid',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'FontWeight','bold'); % 2A + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Channels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 2B + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Channels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 2C + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Bins',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 2D + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Bins',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 2E + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 2F + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 2G + + % Third column: + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Overlay',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'FontWeight','bold'); % 3A + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Bins',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3B + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3C + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Channels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3D + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3E + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Chans',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3F + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Bins',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3G + + % Fourth column: + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Pages',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'FontWeight','bold'); % 3A + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3B + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Bins',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3C + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3D + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Channels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3E + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Bins',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3F + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.DataSelGrid,'String','Channels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % 3G + + set(gui_plotorg_waveviewer.DataSelGrid, 'ColumnSizes',[30 70 70 70],'RowSizes',[20 20 20 20 20 20 20]); + ERPwaviewerin.plot_org.Grid = 1; + ERPwaviewerin.plot_org.Overlay = 2; + ERPwaviewerin.plot_org.Pages =3; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + %%----------------------Setting for grid layout-------------------- + gui_plotorg_waveviewer.layout_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gridlayoutValue = 1; + % First column: + gui_plotorg_waveviewer.layout= uicontrol('Style','text','Parent', gui_plotorg_waveviewer.layout_title,'String','Grid Layout:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + set(gui_plotorg_waveviewer.layout,'HorizontalAlignment','left'); + gui_plotorg_waveviewer.layout_auto = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.layout_title,'String','Auto',... + 'callback',@layout_auto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',gridlayoutValue); % + gui_plotorg_waveviewer.layout_custom = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.layout_title,'String','Custom',... + 'callback',@layout_custom,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',~gridlayoutValue); % + set(gui_plotorg_waveviewer.layout_title, 'Sizes',[80 70 70]); + ERPwaviewerin.plot_org.gridlayout.op = gui_plotorg_waveviewer.layout_auto.Value; + + %%NUmber of rows and columns + binArray = ERPwaviewerin.bin; + chanArray = ERPwaviewerin.chan; + ERPsetArray = ERPwaviewerin.SelectERPIdx; + ALLERPIN = ERPwaviewerin.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + GridValue = 1; + if GridValue ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(chanArray)+1) = {'None'}; + elseif GridValue == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + plotArrayStr = binStr(binArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(binArray)+1) = {'None'}; + elseif GridValue == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + plotArrayStr = cell(numel(ERPsetArray),1); + for Numoferpset = 1:numel(ERPsetArray) + plotArrayStr(Numoferpset,1) = {char(ALLERPIN(ERPsetArray(Numoferpset)).erpname)}; + end + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(ERPsetArray)+1) = {'None'}; + else + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(chanArray)+1) = {'None'}; + end + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + try + Numrows = plotBox(1); + Numcolumns = plotBox(2); + catch + Numrows = 1; + Numcolumns = 1; + end + if gridlayoutValue==1 + rowcolumnEnable = 'off'; + else + rowcolumnEnable = 'on'; + end + gui_plotorg_waveviewer.row_column_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + for ii = 1:256 + rowcolumnString{ii} = num2str(ii); + end + uiextras.Empty('Parent', gui_plotorg_waveviewer.row_column_title); + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.row_column_title,'String','Row(s)',... + 'FontSize',FonsizeDefault-2,'BackgroundColor',ColorBviewer_def); % 1B + gui_plotorg_waveviewer.rownum = uicontrol('Style','popupmenu','Parent', gui_plotorg_waveviewer.row_column_title,'String',rowcolumnString,... + 'callback',@plotorg_rownum,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',Numrows,'Enable',rowcolumnEnable); % 1B + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.row_column_title,'String','Column(s)',... + 'FontSize',FonsizeDefault-2,'BackgroundColor',ColorBviewer_def); % 1B + gui_plotorg_waveviewer.columnnum = uicontrol('Style','popupmenu','Parent', gui_plotorg_waveviewer.row_column_title,'String',rowcolumnString,... + 'callback',@plotorg_columnnum,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',Numcolumns,'Enable',rowcolumnEnable); % 1B + set(gui_plotorg_waveviewer.row_column_title, 'Sizes',[20 35 65 55 65]); + ERPwaviewerin.plot_org.gridlayout.rows = gui_plotorg_waveviewer.rownum.Value; + ERPwaviewerin.plot_org.gridlayout.columns =gui_plotorg_waveviewer.columnnum.Value; + + %%-------------------------Grid information------------------------ + count = 0; + for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + count = count +1; + if count> numel(plotArray) + GridinforData{Numofrows,Numofcolumns} = char('None'); + else + GridinforData{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + end + end + end + ERPwaviewerin.plot_org.gridlayout.data =GridinforData; + columFormat = plotArrayFormt'; + ERPwaviewerin.plot_org.gridlayout.columFormat = columFormat; + ERPwaviewerin.plot_org.gridlayout.columFormatOrig = columFormat; + + + %%---------------------Gap between rows---------------------------- + gui_plotorg_waveviewer.gridspace_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_plotorg_waveviewer.gridspace_title ,'String','Grid Spacing',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','center','FontWeight','bold'); % + rowgapgtpValue = 1; + RowGTPStr = '10'; + RowgapgtpEnable = 'off'; + if rowgapgtpValue==1 && ~gui_plotorg_waveviewer.layout_auto.Value + RowgapgtpEnable = 'on'; + end + gui_plotorg_waveviewer.rowgap_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_plotorg_waveviewer.rowgap = uicontrol('Style','text','Parent', gui_plotorg_waveviewer.rowgap_title,'String','Row:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + set(gui_plotorg_waveviewer.rowgap,'HorizontalAlignment','left'); + gui_plotorg_waveviewer.rowgap_auto = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.rowgap_title,'String','Gap (%)',... + 'callback',@rowgapgtpauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',rowgapgtpValue,'Enable',rowcolumnEnable); % + gui_plotorg_waveviewer.rowgapGTPcustom = uicontrol('Style','edit','Parent', gui_plotorg_waveviewer.rowgap_title,'String',RowGTPStr,... + 'callback',@rowgapgtpcustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',RowgapgtpEnable); % + if gui_plotorg_waveviewer.layout_auto.Value ==1 + gui_plotorg_waveviewer.rowgapGTPcustom.String = '10'; + end + set(gui_plotorg_waveviewer.rowgap_title, 'Sizes',[60 90 85]); + ERPwaviewerin.plot_org.gridlayout.rowgap.GTPOP = gui_plotorg_waveviewer.rowgap_auto.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.GTPValue = str2num(gui_plotorg_waveviewer.rowgapGTPcustom.String); + + RowgapOVERLAPEnable = 'off'; + if rowgapgtpValue==0 && ~gui_plotorg_waveviewer.layout_auto.Value + RowgapOVERLAPEnable = 'on'; + end + RowoverlayStr = '40'; + gui_plotorg_waveviewer.rowgapcustom_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',gui_plotorg_waveviewer.rowgapcustom_title); + gui_plotorg_waveviewer.rowoverlap = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.rowgapcustom_title,'String','Overlap (%)',... + 'callback',@rowoverlap, 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Enable',rowcolumnEnable,'Value',~rowgapgtpValue); % + gui_plotorg_waveviewer.rowgapoverlayedit = uicontrol('Style','edit','Parent', gui_plotorg_waveviewer.rowgapcustom_title,'String',RowoverlayStr,... + 'callback',@rowoverlapcustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',RowgapOVERLAPEnable); % + set(gui_plotorg_waveviewer.rowgapcustom_title, 'Sizes',[60 90 85]); + ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayOP = gui_plotorg_waveviewer.rowoverlap.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayValue = str2num(gui_plotorg_waveviewer.rowgapoverlayedit.String); + + %%---------------------Gap between columns------------------------ + columngapgtpValue = 1; + columnGTPStr = ''; + columngapgtpEnable = 'off'; + gui_plotorg_waveviewer.columngap_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_plotorg_waveviewer.columngap = uicontrol('Style','text','Parent', gui_plotorg_waveviewer.columngap_title,'String','Column:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + set(gui_plotorg_waveviewer.columngap,'HorizontalAlignment','left'); + gui_plotorg_waveviewer.columngapgtpop = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.columngap_title,'String','Gap (%)',... + 'callback',@columngapgtpop,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',columngapgtpValue,'Enable',rowcolumnEnable); % + gui_plotorg_waveviewer.columngapgtpcustom = uicontrol('Style','edit','Parent', gui_plotorg_waveviewer.columngap_title,'String',columnGTPStr,... + 'callback',@columngapGTPcustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',columngapgtpEnable); % + if gui_plotorg_waveviewer.layout_auto.Value ==1 + gui_plotorg_waveviewer.columngapgtpcustom.String = '10'; + end + set(gui_plotorg_waveviewer.columngap_title, 'Sizes',[60 90 85]); + ERPwaviewerin.plot_org.gridlayout.columngap.GTPOP = gui_plotorg_waveviewer.columngapgtpop.Value; + ERPwaviewerin.plot_org.gridlayout.columngap.GTPValue = str2num(gui_plotorg_waveviewer.columngapgtpcustom.String); + + columngapOVERLAPEnable = 'off'; + if columngapgtpValue==0 && ~gui_plotorg_waveviewer.layout_auto.Value + columngapOVERLAPEnable = 'on'; + end + columnoverlayStr = ''; + gui_plotorg_waveviewer.columngapcustom_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',gui_plotorg_waveviewer.columngapcustom_title); + gui_plotorg_waveviewer.columnoverlay = uicontrol('Style','radiobutton','Parent', gui_plotorg_waveviewer.columngapcustom_title,'String','Overlap (%)',... + 'callback',@columnoverlap, 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Enable',rowcolumnEnable,'Value',~columngapgtpValue); % + gui_plotorg_waveviewer.columngapoverlapedit = uicontrol('Style','edit','Parent', gui_plotorg_waveviewer.columngapcustom_title,'String',columnoverlayStr,... + 'callback',@columnoverlaycustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',columngapOVERLAPEnable); % + set(gui_plotorg_waveviewer.columngapcustom_title, 'Sizes',[60 90 85]); + ERPwaviewerin.plot_org.gridlayout.columngap.OverlayOP = gui_plotorg_waveviewer.columnoverlay.Value; + ERPwaviewerin.plot_org.gridlayout.columngap.OverlayValue = str2num(gui_plotorg_waveviewer.columngapoverlapedit.String); + + %%---------------help and apply the changed parameters------------- + gui_plotorg_waveviewer.save_load_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_plotorg_waveviewer.layout_custom_edit = uicontrol('Style','pushbutton','Parent', gui_plotorg_waveviewer.save_load_title ,'String','Edit',... + 'callback',@plotorg_edit,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',rowcolumnEnable); %,'HorizontalAlignment','left' + % uiextras.Empty('Parent', gui_plotorg_waveviewer.save_load_title ); + gui_plotorg_waveviewer.layout_custom_load = uicontrol('Style','pushbutton','Parent', gui_plotorg_waveviewer.save_load_title,'String','Load',... + 'callback',@layout_custom_load,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + % uiextras.Empty('Parent', gui_plotorg_waveviewer.save_load_title ); + gui_plotorg_waveviewer.layout_custom_save = uicontrol('Style','pushbutton','Parent', gui_plotorg_waveviewer.save_load_title,'String','Save',... + 'callback',@layout_custom_save,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + % uiextras.Empty('Parent', gui_plotorg_waveviewer.save_load_title ); + % set(gui_plotorg_waveviewer.save_load_title,'Sizes',[40 70 20 70 30]); + + gui_plotorg_waveviewer.help_run_title = uiextras.HBox('Parent', gui_plotorg_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent', gui_plotorg_waveviewer.help_run_title ); + gui_plotorg_waveviewer.cancel = uicontrol('Style','pushbutton','Parent', gui_plotorg_waveviewer.help_run_title,'String','Cancel',... + 'callback',@plotorg_cancel,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uiextras.Empty('Parent', gui_plotorg_waveviewer.help_run_title); + gui_plotorg_waveviewer.apply = uicontrol('Style','pushbutton','Parent', gui_plotorg_waveviewer.help_run_title,'String','Apply',... + 'callback',@plotorg_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent', gui_plotorg_waveviewer.help_run_title); + set(gui_plotorg_waveviewer.help_run_title,'Sizes',[40 70 20 70 30]); + set(gui_plotorg_waveviewer.DataSelBox,'Sizes',[150 25 25 20 25 25 25 25 25 25]); + gui_plotorg_waveviewer.columFormatStr = ''; + assignin('base','ALLERPwaviewer',ERPwaviewerin); + end + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +%%-------------------------Setting for Grid-------------------------------- + function plotorg_c1(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Warning: Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + LayoutFlag = gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets. Please select the first or third options (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + return; + else +% if y_Flag==3 +% gui_plotorg_waveviewer.plotorg_c1.Value = 0; +% end +% return; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + + chanArray = ERPwaviewerin.chan; + plotArray = chanArray; + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value==1 + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + end + end + estudioworkingmemory('OverlayIndex',1); + + end + +%%-------------------------Setting for Overlay-------------------------------- + function plotorg_c2(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + LayoutFlag = gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets. Please select the first or third options (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + return; + else + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + return; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 1; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [0,1,0,0,0,0]; + + chanArray = ERPwaviewerin.chan; + plotArray = chanArray; + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value==1 + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + end + end + estudioworkingmemory('OverlayIndex',1); + end + +%%-------------------------Setting for Pages-------------------------------- + function plotorg_c3(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Warning: Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + LayoutFlag = gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~=3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets. Please select the first or third options (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 1; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + return; + else +% if y_Flag==1 +% gui_plotorg_waveviewer.plotorg_c3.Value = 0; +% end +% return; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 1; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,1,0,0,0]; + + plotArray = ERPwaviewerin.bin; + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value==1 + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + end + end + estudioworkingmemory('OverlayIndex',1); + end + + +%%-------------------------Setting for Pages-------------------------------- + function plotorg_c4(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Warning: Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + LayoutFlag = gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets. Please select the first or third options (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + return; + else + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + return; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 1; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,1,0,0]; + + plotArray = ERPwaviewerin.bin; + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value==1 + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + end + end + estudioworkingmemory('OverlayIndex',1); + end + + +%%-------------------------Setting for Pages-------------------------------- + function plotorg_c5(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Warning: Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + LayoutFlag = gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets. Please select the first or third options (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 1; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + return; + else + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + return; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 1; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,1,0]; + + plotArray = indexerp; + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value==1 + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + end + end + estudioworkingmemory('OverlayIndex',1); + end + + +%%-------------------------Setting for Pages-------------------------------- + function plotorg_c6(source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Warning: Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + LayoutFlag = gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets. Please select the first or third options (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 1; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + return; + else + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + return; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.plotorg_c1.Value = 0; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 1; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,0,1]; + + plotArray = indexerp; + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value==1 + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + end + end + estudioworkingmemory('OverlayIndex',1); + end + + +%%----------------Setting for gridlayout auto----------------------------- + function layout_auto(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.layout_auto.Value =1; + gui_plotorg_waveviewer.layout_custom.Value = 0; + gui_plotorg_waveviewer.layout_custom_edit.Enable = 'off'; + gui_plotorg_waveviewer.rownum.Enable = 'off'; + gui_plotorg_waveviewer.columnnum.Enable = 'off'; + + gui_plotorg_waveviewer.rowgap_auto.Value = 1; + gui_plotorg_waveviewer.rowgap_auto.Enable = 'off'; + gui_plotorg_waveviewer.rowgapGTPcustom.String = '10'; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'off'; + gui_plotorg_waveviewer.rowoverlap.Value = 0; + gui_plotorg_waveviewer.rowoverlap.Enable = 'off'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + gui_plotorg_waveviewer.columngapgtpop.Value = 1; + gui_plotorg_waveviewer.columngapgtpop.Enable = 'off'; + gui_plotorg_waveviewer.columngapgtpcustom.String = '10'; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'off'; + gui_plotorg_waveviewer.columnoverlay.Value = 0; + gui_plotorg_waveviewer.columnoverlay.Enable = 'off'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + binArray = ERPwaviewerin.bin; + chanArray = ERPwaviewerin.chan; + ERPsetArray = ERPwaviewerin.SelectERPIdx; + ALLERPIN = ERPwaviewerin.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + if gui_plotorg_waveviewer.plotorg_c3.Value ==1 || gui_plotorg_waveviewer.plotorg_c4.Value ==1 + GridValue=2; + elseif gui_plotorg_waveviewer.plotorg_c5.Value==1 || gui_plotorg_waveviewer.plotorg_c6.Value ==1 + GridValue=3; + else + GridValue=1; + end + + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + if GridValue ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + elseif GridValue == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + plotArrayStr = binStr(binArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + elseif GridValue == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numoferpset = 1:numel(ERPsetArray) + plotArrayStr(Numoferpset,1) = {char(ALLERPIN(ERPsetArray(Numoferpset)).erpname)}; + end + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + else + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + end + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + Numrows = plotBox(1); + Numcolumns=plotBox(2); + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + return; + end + GridinforData = ''; + count = 0; + for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + count = count +1; + if count> numel(plotArray) + GridinforData{Numofrows,Numofcolumns} = char('None'); + else + GridinforData{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + end + end + end + + ERPwaviewerin.plot_org.gridlayout.data =GridinforData; + ERPwaviewerin.plot_org.gridlayout.columFormat = plotArrayFormt'; + ERPwaviewerin.plot_org.gridlayout.columFormatOrig = plotArrayFormt'; + gui_plotorg_waveviewer.columFormatStr = ''; + % assignin('base','ALLERPwaviewer',ERPwaviewerin); + end + + +%%--------------Setting for layout custom---------------------------------- + function layout_custom(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.layout_auto.Value =0; + gui_plotorg_waveviewer.layout_custom.Value = 1; + gui_plotorg_waveviewer.rownum.Enable = 'on'; + gui_plotorg_waveviewer.columnnum.Enable = 'on'; + gui_plotorg_waveviewer.layout_custom_edit.Enable = 'on'; + + gui_plotorg_waveviewer.rowgap_auto.Enable = 'on'; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'on'; + gui_plotorg_waveviewer.rowoverlap.Enable = 'on'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'on'; + rowGTPop = gui_plotorg_waveviewer.rowgap_auto.Value; + rowoverlayop = gui_plotorg_waveviewer.rowoverlap.Value; + if rowGTPop && ~rowoverlayop + gui_plotorg_waveviewer.rowoverlap.Value =0; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + end + if rowGTPop && rowoverlayop + gui_plotorg_waveviewer.rowoverlap.Value =0; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + rowoverlayop =0; + end + if rowoverlayop && ~rowGTPop + gui_plotorg_waveviewer.rowgap_auto.Enable = 'off'; + gui_plotorg_waveviewer.rowgap_auto.Value = 0; + end + + gui_plotorg_waveviewer.columngapgtpop.Enable = 'on'; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'on'; + gui_plotorg_waveviewer.columnoverlay.Enable = 'on'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'on'; + columnGTPop = gui_plotorg_waveviewer.columngapgtpop.Value; + columnoverlayop = gui_plotorg_waveviewer.columnoverlay.Value; + if columnGTPop && ~columnoverlayop + gui_plotorg_waveviewer.columnoverlay.Value =0; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + end + if columnGTPop && columnoverlayop + gui_plotorg_waveviewer.columnoverlay.Value =0; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + columnoverlayop = 0; + end + + if columnoverlayop && ~columnGTPop + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'off'; + gui_plotorg_waveviewer.columngapgtpop.Value = 0; + end + end + +%%------------------number of rows----------------------------------------- + function plotorg_rownum(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%------------------------------Number of columns-------------------------- + function plotorg_columnnum(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + end + + + +%%-------------------row GTP option---------------------------------------- + function rowgapgtpauto(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.rowgap_auto.Value = 1; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'on'; + gui_plotorg_waveviewer.rowoverlap.Value =0; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + end + +%%----------------------row GTP custom------------------------------------- + function rowgapgtpcustom(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + rowgap = str2num(Source.String); + if isempty(rowgap) || numel(rowgap)~=1 || rowgap<=0 + Source.String = '10'; + return; + end + end + + +%%----------------row gap overlay option----------------------------------- + function rowoverlap(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.rowgap_auto.Value = 0; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'off'; + gui_plotorg_waveviewer.rowoverlap.Value =1; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'on'; + end + +%%-------------------row gap overlay custom-------------------------------- + function rowoverlapcustom(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + rowoverlay = str2num(Source.String); + if isempty(rowoverlay) || numel(rowoverlay)~=1 || rowoverlay<=0 || rowoverlay>=100 + Source.String = '40'; + return; + end + end + + +%%----------------column GTP option---------------------------------------- + function columngapgtpop(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + gui_plotorg_waveviewer.columngapgtpop.Value =1; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'on'; + gui_plotorg_waveviewer.columnoverlay.Value=0; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + end +%%-----------------column GTP custom--------------------------------------- + function columngapGTPcustom(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + columngap = str2num(Source.String); + if isempty(columngap) || numel(columngap)~=1 || columngap<=0 + Source.String = '10'; + return; + end + end + + +%%----------------column overlay option------------------------------------ + function columnoverlap(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + colnOverlay = str2num(char( gui_plotorg_waveviewer.columngapoverlapedit.String)); + gui_plotorg_waveviewer.columngapgtpop.Value =0; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'off'; + gui_plotorg_waveviewer.columnoverlay.Value=1; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'on'; + % Source.String = '40'; + if isempty(colnOverlay) + gui_plotorg_waveviewer.columngapoverlapedit.String = '40'; + end + end + + +%%-----------------column overlay custom----------------------------------- + function columnoverlaycustom(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + columnoverlay = str2num(Source.String); + if isempty(columnoverlay) || numel(columnoverlay)~=1 || columnoverlay<=0 || columnoverlay>=100 + Source.String = '40'; + return; + end + end + +%%-----------------Edit the layout----------------------------------------- + function plotorg_edit(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_plotorg',1); + gui_plotorg_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_plotorg_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpwave_viewer_plotorg.TitleColor= [0.4940 0.1840 0.5560]; + + MessageViewer= char(strcat('Plot Organization > Edit')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n f_ERP_plotorg_waveviewer_GUI()> plotorg_edit() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + ERPwaviewerin.plot_org.gridlayout.rows = gui_plotorg_waveviewer.rownum.Value; + ERPwaviewerin.plot_org.gridlayout.columns = gui_plotorg_waveviewer.columnnum.Value; + assignin('base','ALLERPwaviewer',ERPwaviewerin); + + + columFormat = ERPwaviewerin.plot_org.gridlayout.columFormat; + if isempty(gui_plotorg_waveviewer.columFormatStr) + for ii = 1:length(columFormat)-1 + columFormatin{ii,1} = columFormat{ii}; + end + else + columFormatStr = gui_plotorg_waveviewer.columFormatStr; + for ii = 1:length(columFormat)-1 + if ii < length(columFormatStr) + try + columFormatin{ii,1} = columFormatStr{ii}; + catch + columFormatin{ii,1} = columFormat{ii}; + end + else + columFormatin{ii,1} = columFormat{ii}; + end + end + end + + plotArrayFormtOlder = ERPwaviewerin.plot_org.gridlayout.columFormatOrig; + plotBox(1) = ERPwaviewerin.plot_org.gridlayout.rows; + plotBox(2) = ERPwaviewerin.plot_org.gridlayout.columns; + try + GridinforData = ERPwaviewerin.plot_org.gridlayout.data; + catch + GridinforData = []; + end + def = ERP_layoutstringGUI(columFormatin,plotArrayFormtOlder,plotBox,GridinforData); + if isempty(def) + disp('User selected cancel'); + return; + end + TableDataDf = def{1}; + columFormat = def{2}; + [NumRows,NumColumns] = size(TableDataDf); + GridposArray = zeros(NumRows,NumColumns); + for Numofrows = 1:NumRows + for Numofcolumns = 1:NumColumns + SingleStr = char(TableDataDf{Numofrows,Numofcolumns}); + [C,IA] = ismember_bc2(SingleStr,columFormat); + if C ==1 + if IA < length(columFormat) + GridposArray(Numofrows,Numofcolumns) = IA; + elseif IA == length(columFormat) %%%If the element is 'None' + GridposArray(Numofrows,Numofcolumns) = 0; + end + else + GridposArray(Numofrows,Numofcolumns) = 0; + end + end + end + GridposArrayMarker = cell(NumRows,NumColumns); + for Numofrows = 1:NumRows + for Numofcolumns = 1:NumColumns + CellNum = GridposArray(Numofrows,Numofcolumns); + [xRow,yColumn] = find(GridposArray==CellNum); + if CellNum > 0 && ~isempty(xRow) && numel(yColumn)>1 + GridposArrayMarker{Numofrows,Numofcolumns} = [xRow,yColumn]; + end + end + end + try %% try to display the reminder for the repeated items if they exist + msgboxTextAll = ''; + for Numofrows = 1:NumRows + for Numofcolumns = 1:NumColumns + CellNum = GridposArray(Numofrows,Numofcolumns); + SingleCellMarker = GridposArrayMarker{Numofrows,Numofcolumns}; + if ~isempty(SingleCellMarker) + xRow = SingleCellMarker(:,1); + yColumn = SingleCellMarker(:,2); + msgboxText = [num2str(numel(yColumn)),32,'"',columFormat{CellNum},'"',32, 'are defined and they are at',32,]; + Location = char(strcat('(R',num2str(xRow(1)),',','C',num2str(yColumn(1)),')')); + for Numofreapt = 2:numel(yColumn) + if Numofreapt==numel(yColumn) + Location = char(strcat(Location,', and',32,'(R',num2str(xRow(Numofreapt)),',','C',num2str(yColumn(Numofreapt)),').')); + else + Location = char(strcat(Location,',',32,'(R',num2str(xRow(Numofreapt)),',','C',num2str(yColumn(Numofreapt)),')')); + end + end + for Numofmarker = 2:numel(xRow) + GridposArrayMarker{xRow(Numofmarker),yColumn(Numofmarker)} = ''; + end + if isempty(msgboxTextAll) + msgboxTextAll = strcat('%s\n',msgboxText,32,Location); + else + msgboxTextAll = strcat(msgboxTextAll,'\n',msgboxText,32,Location); + end + end + end + end + catch + + end + + button = 'Apply'; + if ~isempty(msgboxTextAll) + question = ['Do you want to use these repeated items?']; + BackERPLABcolor = [1 0.9 0.3]; % yellow + title = 'EStudio Reminder: My Viewer > Plot organization > Edit'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf([msgboxTextAll],question), title,'No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + end + + if isempty(button) || strcmpi(button,'No') + return; + end + + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_plotorglayout_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + ERPwaviewerin.plot_org.gridlayout.columFormat = columFormat; + gui_plotorg_waveviewer.columFormatStr = columFormat; + ERPwaviewerin.plot_org.gridlayout.data =TableDataDf; + assignin('base','ALLERPwaviewer',ERPwaviewerin); + f_redrawERP_viewer_test(); + estudioworkingmemory('MyViewer_plotorg',0); + gui_plotorg_waveviewer.apply.BackgroundColor = [1,1,1]; + box_erpwave_viewer_plotorg.TitleColor= [0.5 0.5 0.9]; + gui_plotorg_waveviewer.apply.ForegroundColor = [0 0 0]; + end + + +%%-------load the saved parameters for plotting organization--------------- + function layout_custom_load(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + [filename, filepath] = uigetfile('*.mat', ... + 'Load parametrs for "Plot Organization"', ... + 'MultiSelect', 'off'); + if isequal(filename,0) + disp('User selected Cancel'); + return; + end + try + Plot_orgpar = importdata([filepath,filename]); + catch + beep; + disp('Cannot load the file.'); + return; + end + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() > layout_custom_load() error: Please run the ERP wave viewer again.'); + return; + end + try + GridValue = Plot_orgpar.Grid; + OverlayValue = Plot_orgpar.Overlay; + PageValue=Plot_orgpar.Pages; + catch + GridValue = 1;OverlayValue = 2;PageValue=3; + end + + %%------------------default labels--------------------------------- + binArray = ERPwaviewerin.bin; + chanArray = ERPwaviewerin.chan; + ERPsetArray = ERPwaviewerin.SelectERPIdx; + ALLERPIN = ERPwaviewerin.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + for Numofselectederp = 1:numel(ERPsetArray) + SrateNum_mp(Numofselectederp,1) = ALLERPIN(ERPsetArray(Numofselectederp)).srate; + end + if numel(unique(SrateNum_mp))>1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if PageValue~= 3 + MessageViewer= char(strcat('Warning: Sampling rate varies across ERPsets. We used the first option. (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + GridValue = 1;OverlayValue = 2;PageValue=3; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + if GridValue==1 && OverlayValue == 2&& PageValue ==3 + gui_plotorg_waveviewer.plotorg_c1.Value =1; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + elseif GridValue==1 && OverlayValue == 3&& PageValue ==2 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =1; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,1,0,0,0,0]; + elseif GridValue==2 && OverlayValue == 1 && PageValue ==3 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =1; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,1,0,0,0]; + elseif GridValue==2 && OverlayValue == 3 && PageValue ==1 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =1; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,1,0,0]; + elseif GridValue==3 && OverlayValue == 1 && PageValue ==2 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =1; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,1,0]; + elseif GridValue==3 && OverlayValue == 2 && PageValue ==1 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =1; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,0,1]; + end + + try + gui_plotorg_waveviewer.layout_auto.Value=Plot_orgpar.gridlayout.op; + gui_plotorg_waveviewer.layout_custom.Value = ~Plot_orgpar.gridlayout.op; + ERPwaviewerin.plot_org.Grid= GridValue; + ERPwaviewerin.plot_org.Overlay =OverlayValue; + ERPwaviewerin.plot_org.Pages=PageValue; + catch + beep; + disp('The imported parameters were invalid.') + return; + end + + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + if GridValue ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormtdef = plotArrayStr; + plotArrayFormtdef(numel(plotArray)+1) = {'None'}; + elseif GridValue == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + plotArrayStr = binStr(binArray); + plotArrayFormtdef = plotArrayStr; + plotArrayFormtdef(numel(plotArray)+1) = {'None'}; + elseif GridValue == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numoferpset = 1:numel(ERPsetArray) + plotArrayStr(Numoferpset,1) = {char(ALLERPIN(ERPsetArray(Numoferpset)).erpname)}; + end + plotArrayFormtdef = plotArrayStr; + plotArrayFormtdef(numel(plotArray)+1) = {'None'}; + else + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormtdef = plotArrayStr; + plotArrayFormtdef(numel(plotArray)+1) = {'None'}; + end + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + + gui_plotorg_waveviewer.rownum.Value=Plot_orgpar.gridlayout.rows; + gui_plotorg_waveviewer.columnnum.Value=Plot_orgpar.gridlayout.columns; + try + RowNum = Plot_orgpar.gridlayout.rows; + catch + RowNum = plotBox(1); + Plot_orgpar.gridlayout.rows = plotBox(1); + end + try + ColumNum = Plot_orgpar.gridlayout.columns; + catch + ColumNum = plotBox(2); + Plot_orgpar.gridlayout.columns= plotBox(2); + end + plotArrayFormtimp = Plot_orgpar.gridlayout.columFormatOrig; + + plotArrayFormtimpChag = Plot_orgpar.gridlayout.columFormat; + button=''; + if numel(plotArrayFormtimp) ~= numel(plotArrayFormtdef) + button='OK'; + plotArrayFormtimp = plotArrayFormtdef; + plotArrayFormtimpChag =plotArrayFormtdef; + else + code =0; + for Numoflabel = 1:numel(plotArrayFormtimpChag)-1 + if ~strcmpi(plotArrayFormtimp{Numoflabel},plotArrayFormtdef{Numoflabel}) + code = code+1; + end + if code~=0 + plotArrayFormtimp = plotArrayFormtdef; + plotArrayFormtimpChag =plotArrayFormtdef; + button='OK'; + end + end + end + GridinforData = Plot_orgpar.gridlayout.data; + if ~isempty(button) + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Warning: Bin/Channel/ERPset labels in saved parameter file donot match with the default ones.\n\n See Command Window for details']; + title = 'Plot Organization > Load > layout_custom_load()'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'OK','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + + fileCheck{1,1} = 'Default labels'; + fileCheck{1,2} = 'Imported labels'; + plotArrayFormtimp1 = Plot_orgpar.gridlayout.columFormatOrig; + for Numoflist = 1:max([numel(plotArrayFormtimp1), numel(plotArrayFormtdef)])-1 + if Numoflist < numel(plotArrayFormtdef) + fileCheck{Numoflist+1,1} = plotArrayFormtdef{Numoflist}; + else + fileCheck{Numoflist+1,1} = 'none'; + end + + if Numoflist < numel(plotArrayFormtimp1) + fileCheck{1+Numoflist,2} = plotArrayFormtimp1{Numoflist}; + else + fileCheck{1+Numoflist,2} ='none'; + end + end + + fprintf( [repmat('_',1,40) '\n']); + + for Numoflist = 1:size(fileCheck,1) + hdr{1} = fileCheck{Numoflist,1}; + hdr{2} = fileCheck{Numoflist,2}; + fprintf( '\n%5s %24s %20s\n\n', hdr{:}); + end + fprintf( ['\n',repmat('_',1,40) '\n']); + + GridinforData = ''; + count = 0; + for Numofrows = 1:RowNum + for Numofcolumns = 1:ColumNum + count = count +1; + if count> numel(plotArrayFormtimp)-1 + GridinforData{Numofrows,Numofcolumns} = char('None'); + else + GridinforData{Numofrows,Numofcolumns} = char(plotArrayFormtimp(count)); + end + end + end + end + + if gui_plotorg_waveviewer.layout_auto.Value==1 + LayOutauto = 'off'; + else + LayOutauto = 'on'; + end + try + ERPwaviewerin.plot_org.gridlayout.data= GridinforData; + gui_plotorg_waveviewer.layoutinfor_table.Enable =LayOutauto; + gui_plotorg_waveviewer.rownum.Enable=LayOutauto; + gui_plotorg_waveviewer.columnnum.Enable=LayOutauto; + ERPwaviewerin.plot_org.gridlayout.rows = Plot_orgpar.gridlayout.rows; + ERPwaviewerin.plot_org.gridlayout.columns =Plot_orgpar.gridlayout.columns; + ERPwaviewerin.plot_org.gridlayout.columFormat = plotArrayFormtimpChag; + ERPwaviewerin.plot_org.gridlayout.columFormatOrig = plotArrayFormtimp; + catch + beep; + disp('The imported parameters didnot match with those of "Plot Organization".') + return; + end + + %%row gap + try + rowgapAutoValue = Plot_orgpar.gridlayout.rowgap.GTPOP; + gui_plotorg_waveviewer.rowgap_auto.Value = rowgapAutoValue; + gui_plotorg_waveviewer.rowgapGTPcustom.String = num2str( Plot_orgpar.gridlayout.rowgap.GTPValue); + gui_plotorg_waveviewer.rowoverlap.Value = ~rowgapAutoValue; + gui_plotorg_waveviewer.rowgapoverlayedit.String = num2str(Plot_orgpar.gridlayout.rowgap.OverlayValue); + + gui_plotorg_waveviewer.rowgap_auto.Enable = LayOutauto; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = LayOutauto; + gui_plotorg_waveviewer.rowoverlap.Enable = LayOutauto; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = LayOutauto; + if gui_plotorg_waveviewer.layout_auto.Value ==0 + if rowgapAutoValue ==1 + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'on'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + else + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'off'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'on'; + end + end + catch + beep; + disp('The imported parameters for rows at "Grid Spacing" didnot match with those of "Plot Organization".') + return; + end + %%column gap + try + columngapAutoValue= Plot_orgpar.gridlayout.columngap.GTPOP ; + gui_plotorg_waveviewer.columngapgtpop.Value= columngapAutoValue; + gui_plotorg_waveviewer.columngapgtpcustom.String = num2str(Plot_orgpar.gridlayout.columngap.GTPValue); + gui_plotorg_waveviewer.columnoverlay.Value = ~columngapAutoValue; + gui_plotorg_waveviewer.columngapoverlapedit.String = num2str(Plot_orgpar.gridlayout.columngap.OverlayValue); + gui_plotorg_waveviewer.columngapgtpop.Enable = LayOutauto; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = LayOutauto; + gui_plotorg_waveviewer.columnoverlay.Enable = LayOutauto; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = LayOutauto; + if gui_plotorg_waveviewer.layout_auto.Value ==0 + if columngapAutoValue ==1 + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'on'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + else + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'off'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'on'; + end + end + catch + beep; + disp('The imported parameters for columns at "Grid Spacing" didnot match with those of "Plot Organization".') + return; + end + assignin('base','ALLERPwaviewer',ERPwaviewerin); + + viewer_ERPDAT.page_xyaxis = viewer_ERPDAT.page_xyaxis+1; + %%change the legend names based on the imported parameters + viewer_ERPDAT.count_legend = viewer_ERPDAT.count_legend+1; + f_redrawERP_viewer_test(); + end + + +%%-----------------Save parameters as .mat format-------------------------- + function layout_custom_save(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex==4 + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + if gui_plotorg_waveviewer.plotorg_c1.Value ==1 + GridValue=1; OverlayValue = 2; PageValue =3; + elseif gui_plotorg_waveviewer.plotorg_c2.Value ==1 + GridValue=1; OverlayValue = 3; PageValue =2; + elseif gui_plotorg_waveviewer.plotorg_c3.Value ==1 + GridValue=2; OverlayValue = 1; PageValue =3; + elseif gui_plotorg_waveviewer.plotorg_c4.Value ==1 + GridValue=2; OverlayValue = 3; PageValue =1; + elseif gui_plotorg_waveviewer.plotorg_c5.Value ==1 + GridValue=3; OverlayValue = 1; PageValue =2; + elseif gui_plotorg_waveviewer.plotorg_c6.Value ==1 + GridValue=3; OverlayValue = 2; PageValue =1; + end + + Plot_orgpar.Grid =GridValue; + Plot_orgpar.Overlay = OverlayValue; + Plot_orgpar.Pages = PageValue; + Plot_orgpar.gridlayout.op =gui_plotorg_waveviewer.layout_auto.Value; + Plot_orgpar.gridlayout.data =ERPwaviewerin.plot_org.gridlayout.data; + Plot_orgpar.gridlayout.rows = gui_plotorg_waveviewer.rownum.Value; + Plot_orgpar.gridlayout.columns = gui_plotorg_waveviewer.columnnum.Value; + Plot_orgpar.gridlayout.columFormat = ERPwaviewerin.plot_org.gridlayout.columFormat; + Plot_orgpar.gridlayout.columFormatOrig = ERPwaviewerin.plot_org.gridlayout.columFormatOrig; + Plot_orgpar.gridlayout.rowgap.GTPOP = ERPwaviewerin.plot_org.gridlayout.rowgap.GTPOP; + Plot_orgpar.gridlayout.rowgap.GTPValue = ERPwaviewerin.plot_org.gridlayout.rowgap.GTPValue; + Plot_orgpar.gridlayout.rowgap.OverlayOP = ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayOP; + Plot_orgpar.gridlayout.rowgap.OverlayValue = ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayValue; + + Plot_orgpar.gridlayout.columngap.GTPOP = ERPwaviewerin.plot_org.gridlayout.columngap.GTPOP; + Plot_orgpar.gridlayout.columngap.GTPValue = ERPwaviewerin.plot_org.gridlayout.columngap.GTPValue; + Plot_orgpar.gridlayout.columngap.OverlayOP = ERPwaviewerin.plot_org.gridlayout.columngap.OverlayOP; + Plot_orgpar.gridlayout.columngap.OverlayValue = ERPwaviewerin.plot_org.gridlayout.columngap.OverlayValue; + + pathstr = pwd; + namedef ='LayoutInfor'; + [erpfilename, erppathname, indxs] = uiputfile({'*.mat'}, ... + ['Save "','Information of Plot Organization', '" as'],... + fullfile(pathstr,namedef)); + if isequal(erpfilename,0) + disp('User selected Cancel') + return + end + [pathx, filename, ext] = fileparts(erpfilename); + [pathstr, erpfilename, ext] = fileparts(erpfilename) ; + if indxs==1 + ext = '.mat'; + elseif indxs==2 + ext = '.mat'; + else + ext = '.mat'; + end + erpFilename = char(strcat(erpfilename,ext)); + try + save([erppathname,erpFilename],'Plot_orgpar','-v7.3'); + catch + beep; + disp('Cannot save the parameters for "Plot Organization", please try again'); + return; + end + end + + +%%--------------Canel changed parameters----------------------------------- + function plotorg_cancel(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + changeFlag = estudioworkingmemory('MyViewer_plotorg'); + if changeFlag~=1 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Plot Organization > Cancel error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + try + GridValue=ERPwaviewer_apply.plot_org.Grid ; + OverlayValue=ERPwaviewer_apply.plot_org.Overlay; + PageValue=ERPwaviewer_apply.plot_org.Pages; + catch + GridValue=1; OverlayValue = 2; PageValue =3; + end + + try + ALLERP = ERPwaviewer_apply.ALLERP; + indexerp = ERPwaviewer_apply.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp) = ALLERP(indexerp(Numofselectederp)).srate; + end + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if PageValue~=3 + GridValue=1; OverlayValue = 2; PageValue =3; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + if GridValue==1 && OverlayValue == 2&& PageValue ==3 + gui_plotorg_waveviewer.plotorg_c1.Value =1; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + elseif GridValue==1 && OverlayValue == 3&& PageValue ==2 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =1; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,1,0,0,0,0]; + elseif GridValue==2 && OverlayValue == 1 && PageValue ==3 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =1; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,1,0,0,0]; + elseif GridValue==2 && OverlayValue == 3 && PageValue ==1 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =1; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,1,0,0]; + elseif GridValue==3 && OverlayValue == 1 && PageValue ==2 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =1; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,1,0]; + elseif GridValue==3 && OverlayValue == 2 && PageValue ==1 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =1; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,0,1]; + end + + gui_plotorg_waveviewer.layout_auto.Value = ERPwaviewer_apply.plot_org.gridlayout.op; + gui_plotorg_waveviewer.layout_custom.Value = ~ERPwaviewer_apply.plot_org.gridlayout.op; + gui_plotorg_waveviewer.layout_auto.Enable = 'on'; + gui_plotorg_waveviewer.layout_custom.Enable = 'on'; + if gui_plotorg_waveviewer.layout_auto.Value==1 + EnableFlag = 'off'; + gui_plotorg_waveviewer.layout_custom_edit.Enable = 'off'; + else + EnableFlag = 'on'; + gui_plotorg_waveviewer.layout_custom_edit.Enable = 'on'; + end + gui_plotorg_waveviewer.rownum.Value= ERPwaviewer_apply.plot_org.gridlayout.rows; + gui_plotorg_waveviewer.columnnum.Value=ERPwaviewer_apply.plot_org.gridlayout.columns; + rowGapValue = ERPwaviewer_apply.plot_org.gridlayout.rowgap.GTPOP; + gui_plotorg_waveviewer.rowgap_auto.Value=rowGapValue; + gui_plotorg_waveviewer.rowoverlap.Value=~rowGapValue; + gui_plotorg_waveviewer.rowgapGTPcustom.String = num2str(ERPwaviewer_apply.plot_org.gridlayout.rowgap.GTPValue); + gui_plotorg_waveviewer.rowgapoverlayedit.String=num2str(ERPwaviewer_apply.plot_org.gridlayout.rowgap.OverlayValue); + columnGapValue =ERPwaviewer_apply.plot_org.gridlayout.columngap.GTPOP; + gui_plotorg_waveviewer.columngapgtpop.Value= columnGapValue; + gui_plotorg_waveviewer.columnoverlay.Value = ~columnGapValue; + gui_plotorg_waveviewer.columngapgtpcustom.String = num2str(ERPwaviewer_apply.plot_org.gridlayout.columngap.GTPValue); + gui_plotorg_waveviewer.columngapoverlapedit.String=num2str(ERPwaviewer_apply.plot_org.gridlayout.columngap.OverlayValue); + + gui_plotorg_waveviewer.rownum.Enable = EnableFlag; + gui_plotorg_waveviewer.columnnum.Enable = EnableFlag; + gui_plotorg_waveviewer.rowgap_auto.Enable = EnableFlag; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = EnableFlag; + gui_plotorg_waveviewer.rowoverlap.Enable = EnableFlag; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = EnableFlag; + gui_plotorg_waveviewer.columngapgtpop.Enable = EnableFlag; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = EnableFlag; + gui_plotorg_waveviewer.columnoverlay.Enable = EnableFlag; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = EnableFlag; + if strcmpi(EnableFlag,'on') + gui_plotorg_waveviewer.rowgap_auto.Enable = 'on'; + gui_plotorg_waveviewer.rowoverlap.Enable = 'on'; + if rowGapValue==1 + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'on'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + else + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'off'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'on'; + end + gui_plotorg_waveviewer.columngapgtpop.Enable = 'on'; + gui_plotorg_waveviewer.columnoverlay.Enable = 'on'; + if columnGapValue==1 + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'on'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + else + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'off'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'on'; + end + end + gui_plotorg_waveviewer.columFormatStr = ''; + estudioworkingmemory('MyViewer_plotorg',0); + gui_plotorg_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_plotorg_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erpwave_viewer_plotorg.TitleColor= [0.5 0.5 0.9]; + end + + + +%%----------------------Apply the changed parameters----------------------- + function plotorg_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=4 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_plotorg',0); + gui_plotorg_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_plotorg_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erpwave_viewer_plotorg.TitleColor= [0.5 0.5 0.9]; + + MessageViewer= char(strcat('Plot Organization > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + %%checking the numbers of rows and columns + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Plot Organization > Apply-f_ERP_plotorg_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + binArray = ERPwaviewerin.bin; + chanArray = ERPwaviewerin.chan; + ERPsetArray = ERPwaviewerin.SelectERPIdx; + ALLERPIN = ERPwaviewerin.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + + if gui_plotorg_waveviewer.plotorg_c1.Value ==1 + GridValue=1; OverlayValue = 2; PageValue =3; + elseif gui_plotorg_waveviewer.plotorg_c2.Value ==1 + GridValue=1; OverlayValue = 3; PageValue =2; + elseif gui_plotorg_waveviewer.plotorg_c3.Value ==1 + GridValue=2; OverlayValue = 1; PageValue =3; + elseif gui_plotorg_waveviewer.plotorg_c4.Value ==1 + GridValue=2; OverlayValue = 3; PageValue =1; + elseif gui_plotorg_waveviewer.plotorg_c5.Value ==1 + GridValue=3; OverlayValue = 1; PageValue =2; + elseif gui_plotorg_waveviewer.plotorg_c6.Value ==1 + GridValue=3; OverlayValue = 2; PageValue =1; + end + + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + if GridValue ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + elseif GridValue == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + plotArrayStr = binStr(binArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + elseif GridValue == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numoferpset = 1:numel(ERPsetArray) + plotArrayStr(Numoferpset,1) = {char(ALLERPIN(ERPsetArray(Numoferpset)).erpname)}; + end + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + else + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(chanArray)+1) = {'None'}; + end + + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + try + NumrowsDef = plotBox(1); + NumcolumnsDef = plotBox(2); + catch + NumrowsDef = 1; + NumcolumnsDef = 1; + end + % NumcolumnsChanged = gui_plotorg_waveviewer.rownum.Value; + % NumrowsChanged = gui_plotorg_waveviewer.columnnum.Value; + % allNum = NumcolumnsChanged*NumrowsChanged; + % button = 'none'; + % if NumcolumnsChanged*NumrowsChanged< NumrowsDef* NumcolumnsDef + % question = ['Are you sure to set row and column numbers to be',32,num2str(NumrowsChanged),32,'and',32,num2str(NumcolumnsChanged),'?\n\n',... + % 'If so, only the first',32,num2str(allNum),32,'items will be plotted.\n',... + % 'If not, the default numbers of rows and columns will be used.\n']; + % BackERPLABcolor = [1 0.9 0.3]; % yellow + % title = 'My Viewer > Plot Organization > Column(s)'; + % oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + % set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + % button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + % set(0,'DefaultUicontrolBackgroundColor',oldcolor) + % end + % if isempty(button) || strcmpi(button,'Cancel') + % return; + % end + % if strcmpi(button,'No') + % count = 0; + % for Numofrows = 1:NumrowsDef + % for Numofcolumns = 1:NumcolumnsDef + % count = count +1; + % if count> numel(plotArray) + % GridinforData{Numofrows,Numofcolumns} = char('None'); + % else + % GridinforData{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + % end + % end + % end + % ERPwaviewerin.plot_org.gridlayout.data =GridinforData; + % gui_plotorg_waveviewer.rownum.Value=NumrowsDef; + % gui_plotorg_waveviewer.columnnum.Value=NumcolumnsDef; + % end + count = 0; + for Numofrows = 1:NumrowsDef + for Numofcolumns = 1:NumcolumnsDef + count = count +1; + if count> numel(plotArray) + GridinforDatadef{Numofrows,Numofcolumns} = char('None'); + else + GridinforDatadef{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + end + end + end + + + if gui_plotorg_waveviewer.layout_auto.Value==1 + ERPwaviewerin.plot_org.gridlayout.rows = gui_plotorg_waveviewer.rownum.Value; + ERPwaviewerin.plot_org.gridlayout.columns =gui_plotorg_waveviewer.columnnum.Value; + ERPwaviewerin.plot_org.gridlayout.columFormat = plotArrayFormt'; + ERPwaviewerin.plot_org.gridlayout.columFormatOrig = plotArrayFormt'; + ERPwaviewerin.plot_org.gridlayout.data =GridinforDatadef; + else + if ~isempty(gui_plotorg_waveviewer.columFormatStr) + plotArrayFormtOld= gui_plotorg_waveviewer.columFormatStr; + else + plotArrayFormtOld = ERPwaviewerin.plot_org.gridlayout.columFormat; + end + for ii = 1:length(plotArrayFormt)-1 + if ii< length(plotArrayFormtOld) + try + plotArrayFormtNew{ii} = char(plotArrayFormtOld{ii}); + catch + plotArrayFormtNew{ii} = char(plotArrayFormt{ii}); + end + else + plotArrayFormtNew{ii} = char(plotArrayFormt{ii}); + end + end + plotArrayFormtNew{length(plotArrayFormt)} = {'None'}; + ERPwaviewerin.plot_org.gridlayout.columFormat = plotArrayFormtNew'; + ERPwaviewerin.plot_org.gridlayout.columFormatOrig = plotArrayFormt'; + end + + ERPwaviewerin.plot_org.Grid = GridValue; + ERPwaviewerin.plot_org.Overlay = OverlayValue; + ERPwaviewerin.plot_org.Pages = PageValue; + ERPwaviewerin.plot_org.gridlayout.op =gui_plotorg_waveviewer.layout_auto.Value; + ERPwaviewerin.plot_org.gridlayout.rows = gui_plotorg_waveviewer.rownum.Value; + ERPwaviewerin.plot_org.gridlayout.columns = gui_plotorg_waveviewer.columnnum.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.GTPOP = gui_plotorg_waveviewer.rowgap_auto.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.GTPValue = str2num(gui_plotorg_waveviewer.rowgapGTPcustom.String); + ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayOP = gui_plotorg_waveviewer.rowoverlap.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayValue = str2num(gui_plotorg_waveviewer.rowgapoverlayedit.String); + ERPwaviewerin.plot_org.gridlayout.columngap.GTPOP = gui_plotorg_waveviewer.columngapgtpop.Value; + ERPwaviewerin.plot_org.gridlayout.columngap.GTPValue = str2num(gui_plotorg_waveviewer.columngapgtpcustom.String); + ERPwaviewerin.plot_org.gridlayout.columngap.OverlayOP = gui_plotorg_waveviewer.columnoverlay.Value; + ERPwaviewerin.plot_org.gridlayout.columngap.OverlayValue = str2num(gui_plotorg_waveviewer.columngapoverlapedit.String); + + assignin('base','ALLERPwaviewer',ERPwaviewerin); + overlayIndex = estudioworkingmemory('OverlayIndex'); + if ~isempty(overlayIndex) && overlayIndex==1 + viewer_ERPDAT.count_legend = viewer_ERPDAT.count_legend+1; + end + f_redrawERP_viewer_test();%%plot ERP waves + viewer_ERPDAT.Process_messg =2; + end + +%%----------------change ORG based on the selected ERPsets----------------- + function v_currentERP_change(~,~) + if viewer_ERPDAT.Count_currentERP == 0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + %%Force Grid, Overlay, and Pages to be 1,2,3, respectively if "Same as ERPLAB" + PlotOrg_ERPLAB= estudioworkingmemory('PlotOrg_ERPLAB');%% "Same as ERPLAB"? See "ERPsets" panel of ERP Wave Viewer + if PlotOrg_ERPLAB==1 + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + end + estudioworkingmemory('PlotOrg_ERPLAB',0); + + indexerp = ERPwaviewer_apply.SelectERPIdx; + ALLERP = ERPwaviewer_apply.ALLERP; + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + end + LayoutFlag=gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if numel(unique(SrateNum_mp))>1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Sampling rate varies across ERPsets.\n We used the first option (i.e., Channels, Bins, ERPsets).')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + binArray = ERPwaviewer_apply.bin; + chanArray = ERPwaviewer_apply.chan; + ERPsetArray = ERPwaviewer_apply.SelectERPIdx; + ALLERPIN = ERPwaviewer_apply.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + ERPwaviewer_apply.SelectERPIdx = ERPsetArray; + end + + if gui_plotorg_waveviewer.plotorg_c1.Value ==1 + GridValue=1; OverlayValue = 2; PageValue =3; + elseif gui_plotorg_waveviewer.plotorg_c2.Value ==1 + GridValue=1; OverlayValue = 3; PageValue =2; + elseif gui_plotorg_waveviewer.plotorg_c3.Value ==1 + GridValue=2; OverlayValue = 1; PageValue =3; + elseif gui_plotorg_waveviewer.plotorg_c4.Value ==1 + GridValue=2; OverlayValue = 3; PageValue =1; + elseif gui_plotorg_waveviewer.plotorg_c5.Value ==1 + GridValue=3; OverlayValue = 1; PageValue =2; + elseif gui_plotorg_waveviewer.plotorg_c6.Value ==1 + GridValue=3; OverlayValue = 2; PageValue =1; + end + ERPwaviewer_apply.plot_org.Grid =GridValue; + ERPwaviewer_apply.plot_org.Overlay = OverlayValue; + ERPwaviewer_apply.plot_org.Pages = PageValue; + + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + if numel(binArray)> length(binStr) + binArray = [1:length(binStr)]; + ERPwaviewer_apply.bin = binArray; + end + if numel(chanArray)> length(chanStr) + chanArray = [1:length(chanStr)]; + ERPwaviewer_apply.chan = chanArray; + end + + if GridValue ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + elseif GridValue == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + plotArrayStr = binStr(binArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + elseif GridValue == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numoferpset = 1:numel(ERPsetArray) + plotArrayStr(Numoferpset,1) = {char(ALLERPIN(ERPsetArray(Numoferpset)).erpname)}; + end + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + else + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(chanArray)+1) = {'None'}; + end + plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns + if gui_plotorg_waveviewer.layout_auto.Value + try + gui_plotorg_waveviewer.rownum.Value = plotBox(1); + gui_plotorg_waveviewer.columnnum.Value = plotBox(2); + catch + gui_plotorg_waveviewer.rownum.Value=1; + gui_plotorg_waveviewer.columnnum.Value=1; + end + end + Numrows = gui_plotorg_waveviewer.rownum.Value; + Numcolumns=gui_plotorg_waveviewer.columnnum.Value; + count = 0; + for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + count = count +1; + if count> numel(plotArray) + GridinforData{Numofrows,Numofcolumns} = char('None'); + else + GridinforData{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + end + end + end + if gui_plotorg_waveviewer.layout_auto.Value + ERPwaviewer_apply.plot_org.Grid = GridValue; + ERPwaviewer_apply.plot_org.gridlayout.data =GridinforData; + ERPwaviewer_apply.plot_org.gridlayout.rows = gui_plotorg_waveviewer.rownum.Value; + ERPwaviewer_apply.plot_org.gridlayout.columns =gui_plotorg_waveviewer.columnnum.Value; + ERPwaviewer_apply.plot_org.gridlayout.columFormat = plotArrayFormt'; + ERPwaviewer_apply.plot_org.gridlayout.columFormatOrig = plotArrayFormt'; + else + ERPwaviewer_apply.plot_org.gridlayout.columFormatOrig = plotArrayFormt; + plotArrayFormtOld = ERPwaviewer_apply.plot_org.gridlayout.columFormat; + for ii = 1:length(plotArrayFormt)-1 + if ii< length(plotArrayFormtOld) + try + plotArrayFormtNew{ii} = char(plotArrayFormtOld{ii}); + catch + plotArrayFormtNew{ii} = char(plotArrayFormt{ii}); + end + else + plotArrayFormtNew{ii} = char(plotArrayFormt{ii}); + end + end + plotArrayFormtNew{length(plotArrayFormt)} = {'None'}; + ERPwaviewer_apply.plot_org.gridlayout.columFormat = plotArrayFormtNew'; + end + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + + end + + +%%-------------modify this panel based on updated parameters--------------- + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + try + GridValue=ERPwaviewer_apply.plot_org.Grid ; + OverlayValue=ERPwaviewer_apply.plot_org.Overlay; + PageValue=ERPwaviewer_apply.plot_org.Pages; + catch + GridValue=1; OverlayValue = 2; PageValue =3; + end + + try + ALLERP = ERPwaviewer_apply.ALLERP; + indexerp = ERPwaviewer_apply.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).srate; + end + if length(unique(SrateNum_mp))~=1 + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if PageValue ~=3 + MessageViewer= char(strcat('Warning: Sampling rate varies across ERPsets. We used the first option. (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + GridValue=1; OverlayValue = 2; PageValue =3; + ERPwaviewer_apply.plot_org.Grid = 1; + ERPwaviewer_apply.plot_org.Overlay = 2; + ERPwaviewer_apply.plot_org.Pages = 3; + + chanArray = ERPwaviewer_apply.chan; + ERPsetArray = ERPwaviewer_apply.SelectERPIdx; + ALLERPIN = ERPwaviewer_apply.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + ERPwaviewer_apply.SelectERPIdx = ERPsetArray; + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + plotArray = chanArray; + plotArrayStr = chanStr(chanArray); + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + plotBox = f_getrow_columnautowaveplot(plotArray); + try + Numrows = plotBox(1); + Numcolumns = plotBox(2); + catch + Numrows = 1; + Numcolumns = 1; + end + count = 0; + for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + count = count +1; + if count> numel(plotArray) + GridinforData{Numofrows,Numofcolumns} = char('None'); + else + GridinforData{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + end + end + end + ERPwaviewer_apply.plot_org.gridlayout.data =GridinforData; + ERPwaviewer_apply.plot_org.gridlayout.rows = Numrows; + ERPwaviewer_apply.plot_org.gridlayout.columns =Numcolumns; + ERPwaviewer_apply.plot_org.gridlayout.columFormat = plotArrayFormt'; + ERPwaviewer_apply.plot_org.gridlayout.columFormatOrig = plotArrayFormt'; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + + + if GridValue==1 && OverlayValue == 2&& PageValue ==3 + gui_plotorg_waveviewer.plotorg_c1.Value =1; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + elseif GridValue==1 && OverlayValue == 3&& PageValue ==2 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =1; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,1,0,0,0,0]; + elseif GridValue==2 && OverlayValue == 1 && PageValue ==3 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =1; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,1,0,0,0]; + elseif GridValue==2 && OverlayValue == 3 && PageValue ==1 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =1; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,1,0,0]; + elseif GridValue==3 && OverlayValue == 1 && PageValue ==2 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =1; + gui_plotorg_waveviewer.plotorg_c6.Value =0; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,1,0]; + elseif GridValue==3 && OverlayValue == 2 && PageValue ==1 + gui_plotorg_waveviewer.plotorg_c1.Value =0; + gui_plotorg_waveviewer.plotorg_c2.Value =0; + gui_plotorg_waveviewer.plotorg_c3.Value =0; + gui_plotorg_waveviewer.plotorg_c4.Value =0; + gui_plotorg_waveviewer.plotorg_c5.Value =0; + gui_plotorg_waveviewer.plotorg_c6.Value =1; + gui_plotorg_waveviewer.LayoutFlag = [0,0,0,0,0,1]; + end + + AutoValue = ERPwaviewer_apply.plot_org.gridlayout.op; + if AutoValue ==1 + Enable = 'off'; + gui_plotorg_waveviewer.layout_auto.Value =1; + gui_plotorg_waveviewer.layout_custom.Value = 0; + else + Enable = 'on'; + gui_plotorg_waveviewer.layout_auto.Value =0; + gui_plotorg_waveviewer.layout_custom.Value = 1; + end + gui_plotorg_waveviewer.layout_auto.Enable ='on'; + gui_plotorg_waveviewer.layout_custom.Enable ='on'; + gui_plotorg_waveviewer.layout_custom_edit.Enable = Enable; + gui_plotorg_waveviewer.rownum.Enable = Enable; + gui_plotorg_waveviewer.columnnum.Enable = Enable; + gui_plotorg_waveviewer.rowgap_auto.Enable = Enable; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = Enable; + gui_plotorg_waveviewer.rowoverlap.Enable = Enable; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = Enable; + gui_plotorg_waveviewer.columngapgtpop.Enable = Enable; + gui_plotorg_waveviewer.columngapgtpcustom.Enable = Enable; + gui_plotorg_waveviewer.columnoverlay.Enable = Enable; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = Enable; + + RowNum = ERPwaviewer_apply.plot_org.gridlayout.rows; + columNum = ERPwaviewer_apply.plot_org.gridlayout.columns; + gui_plotorg_waveviewer.rownum.Value = RowNum; + gui_plotorg_waveviewer.columnnum.Value = columNum; + + %%Row gap and overlay + rowgapValue = ERPwaviewer_apply.plot_org.gridlayout.rowgap.GTPOP; + rowgapCustom = ERPwaviewer_apply.plot_org.gridlayout.rowgap.GTPValue; + rowoverlayValue = ERPwaviewer_apply.plot_org.gridlayout.rowgap.OverlayOP; + rowoverlayCustom = ERPwaviewer_apply.plot_org.gridlayout.rowgap.OverlayValue; + gui_plotorg_waveviewer.rowgap_auto.Value = rowgapValue; + gui_plotorg_waveviewer.rowgapGTPcustom.String = num2str(rowgapCustom); + gui_plotorg_waveviewer.rowoverlap.Value = rowoverlayValue; + gui_plotorg_waveviewer.rowgapoverlayedit.String = num2str(rowoverlayCustom); + if AutoValue==0 %% if Grid layout is Custom + gui_plotorg_waveviewer.rowgap_auto.Enable = 'on'; + gui_plotorg_waveviewer.rowoverlap.Enable = 'on'; + if rowgapValue ==1 + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'on'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'off'; + end + if rowoverlayValue ==1 + gui_plotorg_waveviewer.rowgapGTPcustom.Enable = 'off'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable = 'on'; + end + end + %%column gap and oveerlay + columnGapValue = ERPwaviewer_apply.plot_org.gridlayout.columngap.GTPOP; + columnGapcustom = ERPwaviewer_apply.plot_org.gridlayout.columngap.GTPValue; + columnoverlayValue = ERPwaviewer_apply.plot_org.gridlayout.columngap.OverlayOP; + columnoverlaycustom = ERPwaviewer_apply.plot_org.gridlayout.columngap.OverlayValue; + gui_plotorg_waveviewer.columngapgtpop.Value = columnGapValue; + gui_plotorg_waveviewer.columngapgtpcustom.String = num2str(columnGapcustom); + gui_plotorg_waveviewer.columnoverlay.Value = columnoverlayValue; + gui_plotorg_waveviewer.columngapoverlapedit.String = num2str(columnoverlaycustom); + if AutoValue==0 + gui_plotorg_waveviewer.columngapgtpop.Enable = 'on'; + gui_plotorg_waveviewer.columnoverlay.Enable = 'on'; + if columnGapValue==1 + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'on'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'off'; + end + if columnoverlayValue==1 + gui_plotorg_waveviewer.columngapgtpcustom.Enable = 'off'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable = 'on'; + end + end + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + end + + + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_plotorg'); + if changeFlag~=1 + return; + end + + %%checking the numbers of rows and columns + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Plot Organization > Apply-f_ERP_plotorg_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + ERPsetArray = ERPwaviewerin.SelectERPIdx; + ALLERPIN = ERPwaviewerin.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + for ii = 1:numel(ERPsetArray) + Srates(ii) = ALLERPIN(ERPsetArray(ii)).srate; + end + LayoutFlag=gui_plotorg_waveviewer.LayoutFlag; + [~,y_Flag] = find(LayoutFlag==1); + if numel(unique(Srates))~=1%%If the sampling rate varies across ERPsets, ERPsets must be "Pages". + gui_plotorg_waveviewer.plotorg_c2.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'off'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'off'; + if y_Flag~=1 && y_Flag~= 3 + MessageViewer= char(strcat('Warning: Sampling rate varies across ERPsets. We used the first option. (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + end + else + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + end + plotorg_apply(); + end + + +%%------------------------------------------------------------------------- +%%-----------------Reset this panel with the default parameters------------ +%%------------------------------------------------------------------------- + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==4 + try + ERPwaviewerin = evalin('base','ALLERPwaviewer'); + ALLERP = ERPwaviewerin.ALLERP; + indexerp = ERPwaviewerin.SelectERPIdx; + catch + beep; + disp('f_ERP_plotorg_waveviewer_GUI error: Restart ERPwave Viewer'); + return; + end + gui_plotorg_waveviewer.plotorg_c1.Value = 1; + gui_plotorg_waveviewer.plotorg_c2.Value = 0; + gui_plotorg_waveviewer.plotorg_c3.Value = 0; + gui_plotorg_waveviewer.plotorg_c4.Value = 0; + gui_plotorg_waveviewer.plotorg_c5.Value = 0; + gui_plotorg_waveviewer.plotorg_c6.Value = 0; + gui_plotorg_waveviewer.LayoutFlag = [1,0,0,0,0,0]; + + ERPwaviewerin.plot_org.Grid = 1; + ERPwaviewerin.plot_org.Overlay = 2; + ERPwaviewerin.plot_org.Pages = 3; + estudioworkingmemory('OverlayIndex',1); + %%check sampling rate and data type + for Numofselectederp = 1:numel(indexerp) + SrateNum_mp(Numofselectederp,1) = ALLERP(indexerp(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(indexerp(Numofselectederp)).datatype; + end + if length(unique(Datype))~=1 || (numel(indexerp)==1 && strcmpi(char(Datype),'ERP')~=1) + MessageViewer= char(strcat('Warning: Type of data varies across ERPsets. We only plot waves for ERPset (see Command Window)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + fprintf(2,['\n Warning: ',MessageViewer,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + gui_plotorg_waveviewer.plotorg_c2.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c4.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c5.Enable = 'on'; + gui_plotorg_waveviewer.plotorg_c6.Enable = 'on'; + ERPwaviewerin.plot_org.gridlayout.op = 1; + gui_plotorg_waveviewer.layout_auto.Value =1; + gui_plotorg_waveviewer.layout_custom.Value =0; + %%row and column numbers + plotArray = ERPwaviewerin.chan; + if isempty(plotArray) + plotArray = [1:ERPwaviewerin.ERP.nchan]; + end + plotBox = f_getrow_columnautowaveplot(plotArray); + try + NumrowsDef = plotBox(1); + NumcolumnsDef = plotBox(2); + catch + NumrowsDef = 1; + NumcolumnsDef = 1; + end + gui_plotorg_waveviewer.rownum.Value=NumrowsDef; + gui_plotorg_waveviewer.columnnum.Value=NumcolumnsDef; + gui_plotorg_waveviewer.rownum.Enable='off'; + gui_plotorg_waveviewer.columnnum.Enable='off'; + ERPwaviewerin.plot_org.gridlayout.rows = NumrowsDef; + ERPwaviewerin.plot_org.gridlayout.columns=NumcolumnsDef; + ERPsetArray = ERPwaviewerin.SelectERPIdx; + ALLERPIN = ERPwaviewerin.ALLERP; + if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + plotArrayStr = chanStr(plotArray); + count = 0; + for Numofrows = 1:NumrowsDef + for Numofcolumns = 1:NumcolumnsDef + count = count +1; + if count> numel(plotArray) + GridinforData{Numofrows,Numofcolumns} = char('None'); + else + GridinforData{Numofrows,Numofcolumns} = char(plotArrayStr(count)); + end + end + end + ERPwaviewerin.plot_org.gridlayout.data =GridinforData; + plotArrayFormt = plotArrayStr; + plotArrayFormt(numel(plotArray)+1) = {'None'}; + ERPwaviewerin.plot_org.gridlayout.columFormat = plotArrayFormt'; + ERPwaviewerin.plot_org.gridlayout.columFormatOrig= plotArrayFormt'; + %%Grid spacing + gui_plotorg_waveviewer.rowgap_auto.Value =1; + gui_plotorg_waveviewer.rowgapGTPcustom.String = '10'; + gui_plotorg_waveviewer.rowoverlap.Value = 0; + gui_plotorg_waveviewer.rowgapoverlayedit.String = '40'; + gui_plotorg_waveviewer.columngapgtpop.Value =1; + gui_plotorg_waveviewer.columngapgtpcustom.String = '10'; + gui_plotorg_waveviewer.columnoverlay.Value=0; + gui_plotorg_waveviewer.columngapoverlapedit.String = '40'; + gui_plotorg_waveviewer.rowgap_auto.Enable ='off'; + gui_plotorg_waveviewer.rowgapGTPcustom.Enable ='off'; + gui_plotorg_waveviewer.rowoverlap.Enable ='off'; + gui_plotorg_waveviewer.rowgapoverlayedit.Enable ='off'; + gui_plotorg_waveviewer.columngapgtpop.Enable ='off'; + gui_plotorg_waveviewer.columngapgtpcustom.Enable ='off'; + gui_plotorg_waveviewer.columnoverlay.Enable ='off'; + gui_plotorg_waveviewer.columngapoverlapedit.Enable ='off'; + gui_plotorg_waveviewer.layout_custom_edit.Enable ='off'; + ERPwaviewerin.plot_org.gridlayout.rowgap.GTPOP = gui_plotorg_waveviewer.rowgap_auto.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.GTPValue = str2num(gui_plotorg_waveviewer.rowgapGTPcustom.String); + ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayOP = gui_plotorg_waveviewer.rowoverlap.Value; + ERPwaviewerin.plot_org.gridlayout.rowgap.OverlayValue = str2num(gui_plotorg_waveviewer.rowgapoverlayedit.String); + ERPwaviewerin.plot_org.gridlayout.columngap.GTPOP = gui_plotorg_waveviewer.columngapgtpop.Value; + ERPwaviewerin.plot_org.gridlayout.columngap.GTPValue = str2num(gui_plotorg_waveviewer.columngapgtpcustom.String); + ERPwaviewerin.plot_org.gridlayout.columngap.OverlayOP = gui_plotorg_waveviewer.columnoverlay.Value; + ERPwaviewerin.plot_org.gridlayout.columngap.OverlayValue = str2num(gui_plotorg_waveviewer.columngapoverlapedit.String); + + gui_plotorg_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_plotorg_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erpwave_viewer_plotorg.TitleColor= [0.5 0.5 0.9]; + + assignin('base','ALLERPwaviewer',ERPwaviewerin); + viewer_ERPDAT.Reset_Waviewer_panel=5; + end + end%%end of reset + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_property_waveviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_property_waveviewer_GUI.m new file mode 100755 index 00000000..6c676b19 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_property_waveviewer_GUI.m @@ -0,0 +1,300 @@ +%%This function is to plot the panel for "Viewer properties". + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_property_waveviewer_GUI(varargin) +global gui_erp_waviewer; +global viewer_ERPDAT; +% addlistener(viewer_ERPDAT,'v_currentERP_change',@Count_currentERPChanged); +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); + + +gui_property_waveviewer = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erpwave_viewer_property; +[version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + box_erpwave_viewer_property = uiextras.BoxPanel('Parent', fig, 'Title', 'Viewer Properties', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); % Create boxpanel +elseif nargin == 1 + box_erpwave_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Viewer Properties', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); +else + box_erpwave_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Viewer Properties', 'Padding', 5,... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_plot_property(FonsizeDefault); +varargout{1} = box_erpwave_viewer_property; + + function drawui_plot_property(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + %%--------------------channel and bin setting---------------------- + gui_property_waveviewer.DataSelBox = uiextras.VBox('Parent', box_erpwave_viewer_property,'BackgroundColor',ColorBviewer_def); + + %%-----------------Setting for + %%parameters--------------------------------------- + gui_property_waveviewer.parameters_title = uiextras.HBox('Parent', gui_property_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + + uicontrol('Style','text','Parent', gui_property_waveviewer.parameters_title,'String','Parameters:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); %1A + gui_property_waveviewer.parameters_load = uicontrol('Style','pushbutton','Parent', gui_property_waveviewer.parameters_title,'String','Load',... + 'callback',@parameters_load,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + gui_property_waveviewer.parameters_save = uicontrol('Style','pushbutton','Parent', gui_property_waveviewer.parameters_title,'String','Save',... + 'callback',@parameters_save,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + gui_property_waveviewer.parameters_saveas = uicontrol('Style','pushbutton','Parent', gui_property_waveviewer.parameters_title,'String','Save as',... + 'callback',@parameters_saveas,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + set(gui_property_waveviewer.parameters_title, 'Sizes',[70 55 55 55]); + + %%-----------Setting for viewer title----------------------------- + gui_property_waveviewer.viewer_TN_title = uiextras.HBox('Parent', gui_property_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_property_waveviewer.viewer_TN_title,'String','Title:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); %1A + ViewerName = estudioworkingmemory('viewername'); + if isempty(ViewerName) + ViewerName = char('My Viewer'); + end + gui_property_waveviewer.parameters_load = uicontrol('Style','edit','Parent',gui_property_waveviewer.viewer_TN_title,'String',ViewerName,... + 'callback',@viewer_TN,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + set(gui_property_waveviewer.viewer_TN_title, 'Sizes',[70 165]); + set(gui_property_waveviewer.DataSelBox ,'Sizes',[30 25]) + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + + +%%-------------------------Setting for load-------------------------------- + function parameters_load(~,~) + [filename, filepath,indxs] = uigetfile({'*.mat'}, ... + 'Load parametrs for "My viewer"', ... + 'MultiSelect', 'off'); + if isequal(filename,0) + disp('User selected Cancel'); + return; + end + + [pathstr, erpfilename, ext] = fileparts(filename) ; + if indxs==1 + ext = '.mat'; + elseif indxs==2 + ext = '.mat'; + else + ext = '.mat'; + end + erpFilename = char(strcat(erpfilename,ext)); + MessageViewer= char(strcat('Viewer Properties > Load')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + + try + ERPwaviewer = importdata([filepath,erpFilename]); + + if isempty(ERPwaviewer.ALLERP) + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Do you want to use the default "ALLERP"? \n Because there is no "ALLERP" in the file']; + title = 'My Viewer>Viewer Properties'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + if strcmpi(button,'Yes') + ERPwaviewerdef = evalin('base','ALLERPwaviewer'); + ERPwaviewer.ALLERP= ERPwaviewerdef.ALLERP; + ERPwaviewer.ERP = ERPwaviewerdef.ERP; + else + if strcmpi(button,'No') + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Load: \n Cannot use the file because no ALLERP can be used.\n\n'); + else + beep + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Load: \n User selected cancel.\n\n'); + end + return; + end + end + + assignin('base','ALLERPwaviewer',ERPwaviewer); + catch + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Load: \n Cannot load the saved parameters of My viewer.\n\n'); + return; + end + viewer_ERPDAT.count_loadproper = viewer_ERPDAT.count_loadproper+1; + % estudioworkingmemory('zoomSpace',1.5); + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; + end + +%%-------------------------Setting for Save-------------------------------- + function parameters_save(~,~) + MessageViewer= char(strcat('Viewer Properties > Save')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Save: \n There is no "ALLERPwaviewer" on Workspace, Please run My Viewer again.\n\n'); + return; + end + pathstr = pwd; + namedef ='Viewer'; + erpFilename = char(strcat(namedef,'.mat')); + + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Do you want to include "ALLERP"?']; + title = 'My Viewer>Viewer Properties'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + + if strcmpi(button,'No') || strcmpi(button,'Yes') + if strcmpi(button,'No') + ERPwaviewer.ALLERP = []; + ERPwaviewer.ERP = []; + end + try + save([pathstr,filesep,erpFilename],'ERPwaviewer','-v7.3'); + viewer_ERPDAT.Process_messg =2; + catch + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Save as: \n Cannot save the parameters of My viewer.\n\n'); + return; + end + else + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Save as: \n User selected cancel.\n\n'); + return; + end + + end +%%-------------------------Setting for Save as-------------------------------- + function parameters_saveas(~,~) + MessageViewer= char(strcat('Viewer Properties > Save as')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + + pathstr = pwd; + namedef ='Viewer'; + [erpfilename, erppathname, indxs] = uiputfile({'*.mat'}, ... + ['Save "','Information of My Viewer', '" as'],... + fullfile(pathstr,namedef)); + + if isequal(erpfilename,0) + beep; + viewer_ERPDAT.Process_messg =3; + disp('User selected Cancel') + return + end + + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Save as: \n There is no "ALLERPwaviewer" on Workspace, Please run My Viewer again.\n\n'); + return; + end + + % [pathx, filename, ext] = fileparts(erpfilename); + [pathstr, erpfilename, ext] = fileparts(erpfilename) ; + if indxs==1 + ext = '.mat'; + elseif indxs==2 + ext = '.mat'; + else + ext = '.mat'; + end + erpFilename = char(strcat(erpfilename,ext)); + + + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Do you want to include "ALLERP"?']; + title = 'My Viewer>Viewer Properties'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + + if strcmpi(button,'No') || strcmpi(button,'Yes') + if strcmpi(button,'No') + ERPwaviewer.ALLERP = []; + ERPwaviewer.ERP = []; + end + try + save([erppathname,erpFilename],'ERPwaviewer','-v7.3'); + viewer_ERPDAT.Process_messg =2; + catch + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Save as: \n Cannot save the parameters of My viewer.\n\n'); + return; + end + else + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My viewer > Viewer Propoerties > Save as: \n User selected cancel.\n\n'); + return; + end + + end + +%%----------------Setting for location path----------------------------- + function viewer_TN(source_locationname,~) + MessageViewer= char(strcat('Viewer Properties > Title')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + ViewerName = source_locationname.String; + if isempty(ViewerName) + ViewerName = 'My Viewer'; + end + try + [version1 reldate] = geterplabstudioversion; + erplabstudiover = version1; + catch + erplabstudiover = '??'; + end + currvers = ['ERPLAB Studio ' erplabstudiover,'-',32,ViewerName]; + estudioworkingmemory('viewername',ViewerName); + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n\n My Viewer > Viewer Propoerties > Title: \n There is no "ALLERPwaviewer" on Workspace, Please run My Viewer again.\n\n'); + return; + end + ERPwaviewer.figname = ViewerName; + assignin('base','ALLERPwaviewer',ERPwaviewer); + gui_erp_waviewer.Window.Name = currvers; + viewer_ERPDAT.Process_messg =2; + end +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_timeampscal_waveviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_timeampscal_waveviewer_GUI.m new file mode 100755 index 00000000..0174656e --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERP_timeampscal_waveviewer_GUI.m @@ -0,0 +1,3060 @@ +%%This function is to plot the panel for "Viewer properties". + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_timeampscal_waveviewer_GUI(varargin) +global viewer_ERPDAT + +addlistener(viewer_ERPDAT,'v_currentERP_change',@v_currentERP_change); +addlistener(viewer_ERPDAT,'page_xyaxis_change',@page_xyaxis_change); +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); + +gui_erpxyaxeset_waveviewer = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erpxtaxes_viewer_property; +[version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + box_erpxtaxes_viewer_property = uiextras.BoxPanel('Parent', fig, 'Title', 'Time and Amplitude Scales', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize',12); % Create boxpanel +elseif nargin == 1 + box_erpxtaxes_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Time and Amplitude Scales', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize',12); +else + box_erpxtaxes_viewer_property = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Time and Amplitude Scales', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +end +%-----------------------------Draw the panel------------------------------------- + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end + + +drawui_plot_xyaxis_viewer(FonsizeDefault); +varargout{1} = box_erpxtaxes_viewer_property; + + function drawui_plot_xyaxis_viewer(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + try + timeArray(1) = ERPwaviewer.ERP.times(1); + timeArray(2) = ERPwaviewer.ERP.times(end); + catch + timeArray = []; + end + try + timerangeAuto = ERPwaviewer.xaxis.trangeauto; + catch + timerangeAuto =1; + end + gui_erpxyaxeset_waveviewer.DataSelBox = uiextras.VBox('Parent', box_erpxtaxes_viewer_property,'BackgroundColor',ColorBviewer_def); + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%Setting for X axis%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + try + ERPIN = ERPwaviewer.ERP; + timeArray(1) = ERPwaviewer.ERP.times(1); + timeArray(2) = ERPwaviewer.ERP.times(end); + [timeticks stepX]= default_time_ticks_studio(ERPIN, [timeArray(1),timeArray(2)]); + if ~isempty(stepX) && numel(stepX) ==1 + stepX = floor(stepX/2); + end + catch + timeticks = []; + timeArray =[]; + end + %%-----------------Setting for time range------- + gui_erpxyaxeset_waveviewer.xaxis_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xaxis_title,'String','X Axis:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','center','FontWeight','bold'); % + + %%-------Display with second or millisecond------------------------ + gui_erpxyaxeset_waveviewer.display_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.display_title,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Display in','HorizontalAlignment','left'); % + xdispysecondValue = 1; + gui_erpxyaxeset_waveviewer.xmillisecond = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.display_title,... + 'callback',@xmilsecond,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Millisecond','Value',xdispysecondValue); % + gui_erpxyaxeset_waveviewer.xsecond = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.display_title,... + 'callback',@xsecond,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Second','Value',~xdispysecondValue); % + set(gui_erpxyaxeset_waveviewer.display_title,'Sizes',[75 90 75]); + ERPwaviewer.xaxis.tdis = 1; + erpworkingmemory('MyViewer_xaxis_second',0); + erpworkingmemory('MyViewer_xaxis_msecond',1); + %%------time range------ + gui_erpxyaxeset_waveviewer.xtimerange_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_erpxyaxeset_waveviewer.timerange_label = uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimerange_title,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Time Range','Max',10,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.timerange_edit = uicontrol('Style','edit','Parent', gui_erpxyaxeset_waveviewer.xtimerange_title,'String',num2str(timeArray),... + 'callback',@timerangecustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + + gui_erpxyaxeset_waveviewer.xtimerangeauto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.xtimerange_title,'String','Auto',... + 'callback',@xtimerangeauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',timerangeAuto); % + if gui_erpxyaxeset_waveviewer.xtimerangeauto.Value ==1 + enableName = 'off'; + else + enableName = 'on'; + end + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = enableName; + set(gui_erpxyaxeset_waveviewer.xtimerange_title,'Sizes',[80 100 60]); + ERPwaviewer.xaxis.timerange = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + ERPwaviewer.xaxis.trangeauto = gui_erpxyaxeset_waveviewer.xtimerangeauto.Value; + + %%----------------------time ticks--------------------------------- + stepX = []; + timeticksAuto = 1; + xtick_precision =0; + + gui_erpxyaxeset_waveviewer.xtimetick_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_erpxyaxeset_waveviewer.timeticks_label = uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimetick_title ,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Time Ticks','HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.timeticks_edit = uicontrol('Style','edit','Parent', gui_erpxyaxeset_waveviewer.xtimetick_title ,'String',timeticks,... + 'callback',@timetickscustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + gui_erpxyaxeset_waveviewer.xtimetickauto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.xtimetick_title ,'String','Auto',... + 'callback',@xtimetickauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',timeticksAuto); % + if gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + enableName_tick = 'off'; + else + enableName_tick = 'on'; + end + % gui_erpxyaxeset_waveviewer.timeticks_label.Enable = enableName_tick; + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = enableName_tick; + set(gui_erpxyaxeset_waveviewer.xtimetick_title,'Sizes',[80 100 60]); + ERPwaviewer.xaxis.timeticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + ERPwaviewer.xaxis.ticksauto = gui_erpxyaxeset_waveviewer.xtimetickauto.Value; + + + %%--------x tick precision with decimals--------------------------- + gui_erpxyaxeset_waveviewer.xtickprecision_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.xtickprecision_title); + uicontrol('Style','text','Parent',gui_erpxyaxeset_waveviewer.xtickprecision_title ,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Precision','HorizontalAlignment','left'); % + xprecisoonName = {'0','1','2','3','4','5','6'}; + gui_erpxyaxeset_waveviewer.xticks_precision = uicontrol('Style','popupmenu','Parent',gui_erpxyaxeset_waveviewer.xtickprecision_title,'String',xprecisoonName,... + 'callback',@xticksprecison,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',xtick_precision+1); % + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtickprecision_title,'String','# decimals',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + set(gui_erpxyaxeset_waveviewer.xtickprecision_title,'Sizes',[30 65 60 80]); + ERPwaviewer.xaxis.tickdecimals = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + + + + %%-----time minor ticks-------------------------------------------- + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticksStr) && numel(xticksStr)>1 + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + timeminorLabel = 0; + if timeminorLabel==1 + xminorEnable_auto = 'on'; + else + xminorEnable_auto = 'off'; + end + timeminorstep = 1; + if timeminorstep ==1 + xminorEnable_custom = 'off'; + else + xminorEnable_custom = 'on'; + end + gui_erpxyaxeset_waveviewer.xtimeminnortick_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_erpxyaxeset_waveviewer.xtimeminorauto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.xtimeminnortick_title ,... + 'callback',@timeminortickslabel,'String','Minor ticks','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left','Value',timeminorLabel); % + gui_erpxyaxeset_waveviewer.timeminorticks_custom = uicontrol('Style','edit','Parent', gui_erpxyaxeset_waveviewer.xtimeminnortick_title ,... + 'callback',@timeminorticks_custom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'String',num2str(stepX),'Enable',xminorEnable_custom); % + gui_erpxyaxeset_waveviewer.timeminorticks_auto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.xtimeminnortick_title,... + 'callback',@timeminortickscustom_auto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Auto','Value',timeminorstep, 'Enable',xminorEnable_auto); % + set(gui_erpxyaxeset_waveviewer.xtimeminnortick_title,'Sizes',[90 90 50]); + ERPwaviewer.xaxis.tminor.disp = gui_erpxyaxeset_waveviewer.xtimeminorauto.Value; + ERPwaviewer.xaxis.tminor.step = str2num(char(gui_erpxyaxeset_waveviewer.timeminorticks_custom.String)); + ERPwaviewer.xaxis.tminor.auto = gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value; + + %%-----time ticks label-------------------------------------------- + timetickLabel = 1; + gui_erpxyaxeset_waveviewer.xtimelabel_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimelabel_title ,'String','Labels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.xtimelabel_on = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.xtimelabel_title,... + 'callback',@xtimelabelon,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','On','Value',timetickLabel); % + gui_erpxyaxeset_waveviewer.xtimelabel_off = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.xtimelabel_title,... + 'callback',@xtimelabeloff,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Off','Value',~timetickLabel); % + uiextras.Empty('Parent',gui_erpxyaxeset_waveviewer.xtimelabel_title); + set(gui_erpxyaxeset_waveviewer.xtimelabel_title,'Sizes',[50 50 50 80]); + if gui_erpxyaxeset_waveviewer.xtimelabel_on.Value ==1 + fontenable = 'on'; + else + fontenable = 'off'; + end + ERPwaviewer.xaxis.label = gui_erpxyaxeset_waveviewer.xtimelabel_on.Value; + + + %%-----font, font size, and text color for time ticks-------------- + ttickLabelfont = 2; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + xfontsizeinum = str2num(char(fontsize)); + ttickLabelfontsizeV = 4; + ttickLabelfontcolor = 1; + gui_erpxyaxeset_waveviewer.xtimefont_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimefont_title,'String','Font',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + gui_erpxyaxeset_waveviewer.xtimefont_custom = uicontrol('Style','popupmenu','Parent', gui_erpxyaxeset_waveviewer.xtimefont_title ,'String',fonttype,... + 'callback',@xtimefont,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',fontenable,'Value',ttickLabelfont); % + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimefont_title ,'String','Size',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.font_custom_size = uicontrol('Style','popupmenu','Parent', gui_erpxyaxeset_waveviewer.xtimefont_title ,'String',fontsize,... + 'callback',@xtimefontsize,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',fontenable,'Value',ttickLabelfontsizeV); % + set(gui_erpxyaxeset_waveviewer.xtimefont_title,'Sizes',[30 100 30 80]); + ERPwaviewer.xaxis.font = gui_erpxyaxeset_waveviewer.xtimefont_custom.Value; + ERPwaviewer.xaxis.fontsize = xfontsizeinum(gui_erpxyaxeset_waveviewer.font_custom_size.Value); + + %%%---------------------color for x label text-------------- + gui_erpxyaxeset_waveviewer.xtimelabelcolor_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimelabelcolor_title,'String','Color',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + textColor = {'Black','Red','Blue','Green','Orange','Cyan','Magenla'}; + gui_erpxyaxeset_waveviewer.xtimetextcolor = uicontrol('Style','popupmenu','Parent', gui_erpxyaxeset_waveviewer.xtimelabelcolor_title ,'String',textColor,... + 'callback',@xtimecolor,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',fontenable,'Value',ttickLabelfontcolor); % + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.xtimelabelcolor_title); + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.xtimelabelcolor_title); + set(gui_erpxyaxeset_waveviewer.xtimelabelcolor_title,'Sizes',[40 100 30 70]); + ERPwaviewer.xaxis.fontcolor = gui_erpxyaxeset_waveviewer.xtimetextcolor.Value; + + %%%----Setting for the xunits display-------------------------- + timeunits = 1; + gui_erpxyaxeset_waveviewer.xtimeunits_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.xtimeunits_title ,'String','Units',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.xtimeunits_on = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.xtimeunits_title,... + 'callback',@xtimeunitson,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','On','Value',timeunits); % + gui_erpxyaxeset_waveviewer.xtimeunits_off = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.xtimeunits_title,... + 'callback',@xtimeunitsoff,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Off','Value',~timeunits); % + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.xtimeunits_title); + set(gui_erpxyaxeset_waveviewer.xtimeunits_title,'Sizes',[50 50 50 80]); + ERPwaviewer.xaxis.units = gui_erpxyaxeset_waveviewer.xtimeunits_on.Value; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%Setting for Y axis%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%-----------Y scale--------- + ALLERPIN = ERPwaviewer.ALLERP; + ERPArrayin = ERPwaviewer.SelectERPIdx; + BinArrayIN = []; + ChanArrayIn = []; + plotOrg = [1 2 3]; + try + plotOrg(1) = ERPwaviewer.plot_org.Grid; + plotOrg(2) = ERPwaviewer.plot_org.Overlay; + plotOrg(3) = ERPwaviewer.plot_org.Pages; + catch + plotOrg = [1 2 3]; + end + try + ChanArrayIn = ERPwaviewer.chan; + catch + ChanArrayIn = []; + end + try + BinArrayIN = ERPwaviewer.bin; + catch + BinArrayIN = []; + end + CURRENTERPIN = ERPwaviewer.CURRENTERP; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + [x,yscales_v] = find(ERPArrayin ==CURRENTERPIN); + yRangeLabel = ''; + if isempty(yscales_v) + yRangeLabel = ''; + else + yRangeLabel = num2str(yylim_out(yscales_v,:)); + end + yRangeauto = 1; + gui_erpxyaxeset_waveviewer.yaxis_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.yaxis_title,'String','Y Axis:',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',1,'HorizontalAlignment','center','FontWeight','bold'); % + gui_erpxyaxeset_waveviewer.yrange_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_erpxyaxeset_waveviewer.yrange_label = uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.yrange_title,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Y Scale','Max',10,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.yrange_edit = uicontrol('Style','edit','Parent', gui_erpxyaxeset_waveviewer.yrange_title,'String',yRangeLabel,... + 'callback',@yrangecustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + gui_erpxyaxeset_waveviewer.yrangeauto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.yrange_title,'String','Auto',... + 'callback',@yrangeauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',yRangeauto); % + if gui_erpxyaxeset_waveviewer.yrangeauto.Value ==1 + yenableName = 'off'; + else + yenableName = 'on'; + end + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = yenableName; + set(gui_erpxyaxeset_waveviewer.yrange_title ,'Sizes',[60 120 60]); + ERPwaviewer.yaxis.scales = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + ERPwaviewer.yaxis.scalesauto = gui_erpxyaxeset_waveviewer.yrangeauto.Value; + + %%--------Y ticks-------------------------------------------------- + ytick_precision = 1; + yticksLabel = ''; + if ~isempty(str2num(yRangeLabel)) + yticksLabel = default_amp_ticks_viewer(str2num(yRangeLabel)); + end + yTickauto = 1; + if isempty(str2num(yticksLabel)) + yticksLabel = ''; + else + if ~isempty(str2num(yticksLabel)) && numel((str2num(yticksLabel)))==1 + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + else + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + for Numofnum = 1:numel(yticksnumbel)-1 + yticksLabel = [yticksLabel,32,sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(Numofnum+1))]; + end + end + end + gui_erpxyaxeset_waveviewer.ytick_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_erpxyaxeset_waveviewer.yticks_label = uicontrol('Style','text','Parent',gui_erpxyaxeset_waveviewer.ytick_title ,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Y Ticks','HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.yticks_edit = uicontrol('Style','edit','Parent',gui_erpxyaxeset_waveviewer.ytick_title,'String',yticksLabel,... + 'callback',@ytickscustom,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % + gui_erpxyaxeset_waveviewer.ytickauto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.ytick_title ,'String','Auto',... + 'callback',@ytickauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'Value',yTickauto); % + if gui_erpxyaxeset_waveviewer.ytickauto.Value ==1 + yenableName_tick = 'off'; + else + yenableName_tick = 'on'; + end + gui_erpxyaxeset_waveviewer.yticks_edit.Enable = yenableName_tick; + set(gui_erpxyaxeset_waveviewer.ytick_title,'Sizes',[60 120 60]); + ERPwaviewer.yaxis.ticks = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + ERPwaviewer.yaxis.tickauto = gui_erpxyaxeset_waveviewer.ytickauto.Value; + + %%--------Y tick precision with decimals--------------------------- + gui_erpxyaxeset_waveviewer.ytickprecision_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.ytickprecision_title); + uicontrol('Style','text','Parent',gui_erpxyaxeset_waveviewer.ytickprecision_title ,... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Precision','HorizontalAlignment','left'); % + yprecisoonName = {'0','1','2','3','4','5','6'}; + gui_erpxyaxeset_waveviewer.yticks_precision = uicontrol('Style','popupmenu','Parent',gui_erpxyaxeset_waveviewer.ytickprecision_title,'String',yprecisoonName,... + 'callback',@yticksprecison,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',ytick_precision+1); % + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.ytickprecision_title,'String','# decimals',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + set(gui_erpxyaxeset_waveviewer.ytickprecision_title,'Sizes',[30 65 60 80]); + ERPwaviewer.yaxis.tickdecimals = gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + + %%-----y minor ticks----------------------------------------------- + yminorLabel = 0; + + if yminorLabel ==1 + yminorautoLabel = 'on'; + else + yminorautoLabel ='off'; + end + yminorautoValue = 1; + if yminorautoValue ==1 + yminoreditEnable = 'off'; + else + yminoreditEnable = 'on'; + end + yticksStr = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + stepY = []; + yscaleRange = (str2num(yRangeLabel)); + if ~isempty(yticksStr) && numel(yticksStr)>1 + if numel(yticksStr)>=2 + for Numofxticks = 1:numel(yticksStr)-1 + stepY(1,Numofxticks) = yticksStr(Numofxticks)+(yticksStr(Numofxticks+1)-yticksStr(Numofxticks))/2; + end + %%adjust the left edge + steyleft = (yticksStr(2)-yticksStr(1))/2; + for ii = 1:1000 + if (yticksStr(1)- steyleft*ii)>=yscaleRange(1) + stepY = [(yticksStr(1)- steyleft*ii),stepY]; + else + break; + end + end + %%adjust the right edge + steyright = (yticksStr(end)-yticksStr(end-1))/2; + for ii = 1:1000 + if (yticksStr(end)+ steyright*ii)<=yscaleRange(end) + stepY = [stepY,(yticksStr(end)+ steyright*ii)]; + else + break; + end + end + end + end + gui_erpxyaxeset_waveviewer.yminnortick_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + gui_erpxyaxeset_waveviewer.yminortick = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.yminnortick_title ,'String','Minor Ticks',... + 'callback',@yminordisp,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left','Value',yminorLabel); % + gui_erpxyaxeset_waveviewer.yminorstepedit = uicontrol('Style','edit','Parent',gui_erpxyaxeset_waveviewer.yminnortick_title ,... + 'callback',@yminorstepedit,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'String',char(num2str(stepY)),'Enable',yminoreditEnable); % + gui_erpxyaxeset_waveviewer.yminorstep_auto = uicontrol('Style','checkbox','Parent', gui_erpxyaxeset_waveviewer.yminnortick_title,... + 'callback',@yminorstepauto,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Auto','Value',yminorautoValue,'Enable',yminorautoLabel); % + ERPwaviewer.yaxis.yminor.disp = gui_erpxyaxeset_waveviewer.yminortick.Value; + ERPwaviewer.yaxis.yminor.step = str2num(char(gui_erpxyaxeset_waveviewer.yminorstepedit.String)); + ERPwaviewer.yaxis.yminor.auto = gui_erpxyaxeset_waveviewer.yminorstep_auto.Value; + set(gui_erpxyaxeset_waveviewer.yminnortick_title,'Sizes',[90 90 50]); + + %%-----y ticks label----------------------------------------------- + ytickLabel = 1; + gui_erpxyaxeset_waveviewer.ylabel_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.ylabel_title,'String','Labels',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.ylabel_on = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.ylabel_title,... + 'callback',@ylabelon,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','On','Value',ytickLabel); % + gui_erpxyaxeset_waveviewer.ylabel_off = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.ylabel_title,... + 'callback',@ylabeloff,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Off','Value',~ytickLabel); % + if gui_erpxyaxeset_waveviewer.ylabel_on.Value ==1 + yfontenable = 'on'; + else + yfontenable = 'off'; + end + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.ylabel_title); + set(gui_erpxyaxeset_waveviewer.ylabel_title,'Sizes',[50 50 50 80]); + ERPwaviewer.yaxis.label = gui_erpxyaxeset_waveviewer.ylabel_on.Value; + + %%-----y ticklabel:font, font size, and text color for time ticks + ytickLabelfont = 2; + ytickLabelfontsize = 4; + ytickLabelfontcolor = 1; + gui_erpxyaxeset_waveviewer.yfont_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.yfont_title,'String','Font',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + gui_erpxyaxeset_waveviewer.yfont_custom = uicontrol('Style','popupmenu','Parent', gui_erpxyaxeset_waveviewer.yfont_title,'String',fonttype,... + 'callback',@yaxisfont, 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',yfontenable,'Value',ytickLabelfont); % + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.yfont_title ,'String','Size',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); % + yfontsize={'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + gui_erpxyaxeset_waveviewer.yfont_custom_size = uicontrol('Style','popupmenu','Parent', gui_erpxyaxeset_waveviewer.yfont_title ,'String',yfontsize,... + 'callback',@yaxisfontsize,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',yfontenable,'Value',ytickLabelfontsize); % + set(gui_erpxyaxeset_waveviewer.yfont_title,'Sizes',[30 100 30 80]); + ERPwaviewer.yaxis.font = gui_erpxyaxeset_waveviewer.yfont_custom.Value; + ERPwaviewer.yaxis.fontsize = xfontsizeinum(gui_erpxyaxeset_waveviewer.yfont_custom_size.Value); + + %%% color for y ticklabel text + gui_erpxyaxeset_waveviewer.ylabelcolor_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.ylabelcolor_title,'String','Color',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + ytextColor = {'Black','Red','Blue','Green','Orange','Cyan','Magenla'}; + gui_erpxyaxeset_waveviewer.ytextcolor = uicontrol('Style','popupmenu','Parent', gui_erpxyaxeset_waveviewer.ylabelcolor_title ,'String',ytextColor,... + 'callback',@yaxisfontcolor,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',yfontenable,'Value',ytickLabelfontcolor); % + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.ylabelcolor_title); + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.ylabelcolor_title); + set(gui_erpxyaxeset_waveviewer.ylabelcolor_title,'Sizes',[40 100 30 70]); + ERPwaviewer.yaxis.fontcolor = gui_erpxyaxeset_waveviewer.ytextcolor.Value; + + %%%-----------Setting for the units display of y axis--------------- + yunits = 1; + gui_erpxyaxeset_waveviewer.yunits_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uicontrol('Style','text','Parent', gui_erpxyaxeset_waveviewer.yunits_title ,'String','Units',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'HorizontalAlignment','left'); % + gui_erpxyaxeset_waveviewer.yunits_on = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.yunits_title,... + 'callback',@yunitson,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','On','Value',yunits); % + gui_erpxyaxeset_waveviewer.yunits_off = uicontrol('Style','radiobutton','Parent', gui_erpxyaxeset_waveviewer.yunits_title,... + 'callback',@yunitsoff,'FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def,'String','Off','Value',~yunits); % + uiextras.Empty('Parent', gui_erpxyaxeset_waveviewer.yunits_title); + set(gui_erpxyaxeset_waveviewer.yunits_title,'Sizes',[50 50 50 80]); + ERPwaviewer.yaxis.units = gui_erpxyaxeset_waveviewer.yunits_on.Value; + + %%Apply and save the changed parameters + gui_erpxyaxeset_waveviewer.help_run_title = uiextras.HBox('Parent', gui_erpxyaxeset_waveviewer.DataSelBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',gui_erpxyaxeset_waveviewer.help_run_title); + uicontrol('Style','pushbutton','Parent', gui_erpxyaxeset_waveviewer.help_run_title ,'String','Cancel',... + 'callback',@xyaxis_help,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'FontWeight','bold','HorizontalAlignment','left' + uiextras.Empty('Parent',gui_erpxyaxeset_waveviewer.help_run_title ); + gui_erpxyaxeset_waveviewer.apply = uicontrol('Style','pushbutton','Parent',gui_erpxyaxeset_waveviewer.help_run_title ,'String','Apply',... + 'callback',@xyaxis_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent',gui_erpxyaxeset_waveviewer.help_run_title ); + set(gui_erpxyaxeset_waveviewer.help_run_title,'Sizes',[40 70 20 70 30]); + + %%save the parameters + ALLERPwaviewer=ERPwaviewer; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + end + +%%*********************************************************************************************************************************%% +%%----------------------------------------------Sub function-----------------------------------------------------------------------%% +%%*********************************************************************************************************************************%% + +%%------------------------------------------------------------------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%X axis%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%------------------------------------------------------------------------- + +%%----------------------dispaly xtick labels with milliseocnd-------------- + function xmilsecond(Source,~) + %%check if the changed parameters was saved for the other panels + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + xSecondflag = erpworkingmemory('MyViewer_xaxis_second'); + xmSecondflag = erpworkingmemory('MyViewer_xaxis_msecond'); + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value; + + if xSecondflag==0 && xmSecondflag==1 + gui_erpxyaxeset_waveviewer.xmillisecond.Value =1; %display with millisecond + gui_erpxyaxeset_waveviewer.xsecond.Value =0; + return; + else + xprecisoonName = {'0','1','2','3','4','5','6'}; + if xtick_precision< 0 || xtick_precision>6 + xtick_precision =0; + end + gui_erpxyaxeset_waveviewer.xticks_precision.String = xprecisoonName; + gui_erpxyaxeset_waveviewer.xticks_precision.Value =xtick_precision+1; + + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.xmillisecond.Value =1; %display with millisecond + gui_erpxyaxeset_waveviewer.xsecond.Value =0;%display with second + ERPwaviewerIN = evalin('base','ALLERPwaviewer'); + if xSecondflag==1 && xmSecondflag==0 + %%transform the data with millisecond into second. + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray*1000); + else + try + if ERPwaviewerIN.plot_org.Pages==3 + ERPArray = ERPwaviewerIN.SelectERPIdx; + ERPselectedIndex = ERPwaviewerIN.PageIndex; + if ERPselectedIndex> length(ERPArray) + ERPselectedIndex= length(ERPArray); + end + ALLERPin = ERPwaviewerIN.ALLERP; + try + TimesCurrent = ALLERPin(ERPArray(ERPselectedIndex)).times; + catch + TimesCurrent = ALLERPin(end).times; + end + timeArray(1) = TimesCurrent(1); + timeArray(2) = TimesCurrent(end); + else + timeArray(1) = ERPwaviewer.ERP.times(1); + timeArray(2) = ERPwaviewer.ERP.times(end); + end + catch + timeArray = []; + end + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray); + end + %%change xtick labels based on the modified x range + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + if xtick_precision<0 + xtick_precision =0; + end + timeArray = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String);% in millisecond + timeticks = str2num(gui_erpxyaxeset_waveviewer.timeticks_edit.String); + if ~isempty(timeticks) + timeticks = timeticks*1000; + timeticks= f_decimal(char(num2str(timeticks)),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks; + else + if ~isempty(timeArray) && numel(timeArray)==2 %%&& gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + [timeticks stepX]= default_time_ticks_studio(ERPwaviewerIN.ERP, timeArray); + if xtick_precision<0 + xtick_precision=0; + gui_erpxyaxeset_waveviewer.xticks_precision.Value=1; + end + timeticks= f_decimal(char(timeticks),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks; + end + end + %%change minor xtick labels based on the modified x range + xticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String));%in millisecond + stepX = str2num(gui_erpxyaxeset_waveviewer.timeminorticks_custom.String); + if ~isempty(stepX) + stepX = stepX.*1000; + % stepX= f_decimal(char(num2str(stepX)),xtick_precision); + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String =num2str(stepX); + else + stepX = []; + if ~isempty(xticks) && numel(xticks)>1 + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticksStr) && numel(xticksStr)>1 && numel(timeArray) ==2 && (timeArray(1)< timeArray(2)) + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + end + if gui_erpxyaxeset_waveviewer.xtimeminorauto.Value==1 && gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = num2str(stepX); + end + end + + erpworkingmemory('MyViewer_xaxis_second',0); + erpworkingmemory('MyViewer_xaxis_msecond',1); + end + end + +%%----------------------display wave with second--------------------------- + function xsecond(Source,~) + %%check if the changed parameters was saved for the other panels + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + xSecondflag = erpworkingmemory('MyViewer_xaxis_second'); + xmSecondflag = erpworkingmemory('MyViewer_xaxis_msecond'); + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + if xSecondflag==1 && xmSecondflag==0 + gui_erpxyaxeset_waveviewer.xmillisecond.Value =0; %display with millisecond + gui_erpxyaxeset_waveviewer.xsecond.Value =1; + return; + else + xprecisoonName = {'1','2','3','4','5','6'}; + gui_erpxyaxeset_waveviewer.xticks_precision.String = xprecisoonName; + if xtick_precision<=0 + xtick_precision=1; + end + gui_erpxyaxeset_waveviewer.xticks_precision.Value=xtick_precision; + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.xmillisecond.Value =0; %display with millisecond + gui_erpxyaxeset_waveviewer.xsecond.Value =1;%display with second + ERPwaviewerIN = evalin('base','ALLERPwaviewer'); + if xSecondflag==0 && xmSecondflag==1 + %%transform the data with millisecond into second. + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray/1000); + else + try + + if ERPwaviewerIN.plot_org.Pages==3 + ERPArray = ERPwaviewerIN.SelectERPIdx; + ERPselectedIndex = ERPwaviewerIN.PageIndex; + if ERPselectedIndex> length(ERPArray) + ERPselectedIndex= length(ERPArray); + end + ALLERPin = ERPwaviewerIN.ALLERP; + try + TimesCurrent = ALLERPin(ERPArray(ERPselectedIndex)).times; + catch + TimesCurrent = ALLERPin(end).times; + end + timeArray(1) = TimesCurrent(1)/1000; + timeArray(2) = TimesCurrent(end)/1000; + else + timeArray(1) = ERPwaviewer.ERP.times(1)/1000; + timeArray(2) = ERPwaviewer.ERP.times(end)/1000; + end + catch + timeArray = []; + end + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray); + end + %%change xtick labels based on the modified x range + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value; + timeArray = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String);%% in seocnd + timeticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + if ~isempty(timeticks) + timeticks = timeticks/1000;%% in second + timeticks= f_decimal(num2str(timeticks),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks;%in second + else + if ~isempty(timeArray) && numel(timeArray)==2 %&& gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + [timeticks stepX]= default_time_ticks_studio(ERPwaviewerIN.ERP, timeArray*1000);%% in millisecond + + timeticks = num2str(str2num(char(timeticks))/1000);%% in second + timeticks= f_decimal(timeticks,xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks;%in second + end + end + + %%change minor xtick labels based on the modified x range + xticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String));%%in second + stepX = str2num(gui_erpxyaxeset_waveviewer.timeminorticks_custom.String); + + if ~isempty(stepX) + stepX = stepX/1000; + % stepX= f_decimal(char(num2str(stepX)),xtick_precision); + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String =num2str(stepX); + else + stepX = []; + if ~isempty(xticks) && numel(xticks)>1 + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String));%% in second + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticksStr) && numel(xticksStr)>1 && numel(timeArray) ==2 && (timeArray(1)< timeArray(2)) + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + end + if gui_erpxyaxeset_waveviewer.xtimeminorauto.Value==1 && gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = num2str(stepX); + end + end + + erpworkingmemory('MyViewer_xaxis_second',1); + erpworkingmemory('MyViewer_xaxis_msecond',0); + end + end + + +%%-------------------------time range auto--------------------------------- + function xtimerangeauto(strx_auto,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = strx_auto.Value; + xdisSecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value; + if Value==1 + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'off'; + + try + if ALLERPwaviewer.plot_org.Pages==3 + ERPArray = ALLERPwaviewer.SelectERPIdx; + ERPselectedIndex = ALLERPwaviewer.PageIndex; + if ERPselectedIndex> length(ERPArray) + ERPselectedIndex= length(ERPArray); + end + ALLERPin = ALLERPwaviewer.ALLERP; + try + TimesCurrent = ALLERPin(ERPArray(ERPselectedIndex)).times; + catch + TimesCurrent = ALLERPin(end).times; + end + timeArray(1) = TimesCurrent(1); + timeArray(2) = TimesCurrent(end); + else + timeArray(1) = ERPwaviewer.ERP.times(1); + timeArray(2) = ERPwaviewer.ERP.times(end); + end + catch + timeArray = []; + end + if xdisSecondValue ==0%% in second + timeArray = timeArray/1000; + end + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray); + if numel(timeArray)==2 && gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + if xdisSecondValue ==0%% in second + [timeticks stepX]= default_time_ticks_studio(ERPwaviewer.ERP, timeArray*1000);%% in millisecond + timeticks = num2str(str2num(char(timeticks))/1000); + else + [timeticks stepX]= default_time_ticks_studio(ERPwaviewer.ERP, timeArray);%% in millisecond + end + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + timeticks= f_decimal(char(timeticks),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = char(timeticks); + end + else + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'on'; + end + end + +%%-------------------------Custom setting for time range------------------- + function timerangecustom(Strtimcustom,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + xdisSecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value; + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPIN = ERPwaviewer.ERP; + timeArray(1) = ERPwaviewer.ERP.times(1); + timeArray(2) = ERPwaviewer.ERP.times(end); + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + timcustom = str2num(Strtimcustom.String); + %%checking the inputs + if xdisSecondValue==0 + timeArray = timeArray/1000; + end + if numel(timcustom)==1 || isempty(timcustom) + messgStr = strcat('Time range in "Time and Amplitude Scales" - Inputs must be two numbers!'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + Strtimcustom.String = num2str(timeArray); + viewer_ERPDAT.Process_messg =4; + return; + end + if timcustom(1) >= timcustom(2) + messgStr = strcat('Time range in "Time and Amplitude Scales" - The left edge should be smaller than the right one'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + Strtimcustom.String = num2str(timeArray); + viewer_ERPDAT.Process_messg =4; + return; + end + if numel(timcustom)==2 && gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + if xdisSecondValue ==0%% in second + [timeticks stepX]= default_time_ticks_studio(ERPwaviewer.ERP, timcustom*1000);%% in millisecond + timeticks = num2str(str2num(char(timeticks))/1000); + else + [timeticks stepX]= default_time_ticks_studio(ERPwaviewer.ERP, timcustom);%% in millisecond + end + if gui_erpxyaxeset_waveviewer.xmillisecond.Value==1 + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + else + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value; + end + timeticks= f_decimal(char(timeticks),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = char(timeticks); + end + + end + +%%----------------------x ticks custom------------------------------------- + function timetickscustom(Str,~) + ERPwaviewerIN = evalin('base','ALLERPwaviewer'); + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + xdisSecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value; + timeArray = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String); + timeticksdef = ''; + if ~isempty(timeArray) + if xdisSecondValue ==0%% in second + [timeticks stepX]= default_time_ticks_studio(ERPwaviewerIN.ERP, timeArray*1000);%% in millisecond + timeticksdef = num2str(str2num(char(timeticks))/1000); + else + [timeticksdef stepX]= default_time_ticks_studio(ERPwaviewerIN.ERP, timeArray);%% in millisecond + end + if gui_erpxyaxeset_waveviewer.xmillisecond.Value==1 + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + else + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value; + end + timeticksdef= f_decimal(char(timeticksdef),xtick_precision); + end + + timtickcustom = str2num(char(Str.String)); + %%checking the inputs + if isempty(timtickcustom) + messgStr = strcat('Time ticks in "Time and Amplitude Scales" - We used the default values because input are not numeric values'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + viewer_ERPDAT.Process_messg =4; + Str.String = timeticksdef; + return; + end + + + end + +%%-------------------------Setting for xticks auto------------------------ + function xtimetickauto(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = Str.Value; + if Value ==1 + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.xtimetickauto.Value =1; + + try + ERPwaviewer = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + xdisSecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value; + timeArray = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String); + if ~isempty(timeArray) && gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1%% + if xdisSecondValue ==0%% in second + [timeticks stepX]= default_time_ticks_studio(ERPwaviewer.ERP, timeArray*1000);%% in millisecond + timeticks = num2str(str2num(char(timeticks))/1000); + else + [timeticks stepX]= default_time_ticks_studio(ERPwaviewer.ERP, timeArray);%% in millisecond + end + if xdisSecondValue==0 + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value; + else + xtick_precision = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + end + timeticks= f_decimal(char(timeticks),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks; + end + else + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'on'; + gui_erpxyaxeset_waveviewer.xtimetickauto.Value = 0; + end + end + +%%--------------------change decimals of x tick labels--------------------- + function xticksprecison(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + + if gui_erpxyaxeset_waveviewer.xmillisecond.Value==1 + xtick_precision = Source.Value-1; + if xtick_precision<0 + xtick_precision=0; + Source.Value=1; + end + else + xtick_precision = Source.Value; + if xtick_precision<=0 + xtick_precision=1; + Source.Value=1; + end + end + + timeticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + if ~isempty(timeticks) + timeticks= f_decimal(char(num2str(timeticks)),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks; + end + + end + +%%---------------------display xtick minor or not-------------------------- + function timeminortickslabel(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = Str.Value; + if Value ==1 + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'on'; + if gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value ==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'on'; + end + else + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'off'; + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + end + + Value = Str.Value; + xticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticks) && numel(xticks)>1 + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticksStr) && numel(xticksStr)>1 && numel(timeArray) ==2 && (timeArray(1)< timeArray(2)) + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + end + if Value==1 && gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = num2str(stepX); + end + + end + +%%--------------------------custom step for minor xtick-------------------- + function timeminorticks_custom(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Str_xtick_minor = str2num(Str.String); + if isempty(Str_xtick_minor) + messgStr = strcat('Minor ticks for "X Axs" in "Time and Amplitude Scales" - Input must be numeric '); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + + end + +%%--------------------------step for xtick automaticlly-------------------- + function timeminortickscustom_auto(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = Str.Value; + xticks = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticks) && numel(xticks)>1 + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + stepX = []; + if ~isempty(xticksStr) && numel(xticksStr)>1 && numel(timeArray) ==2 && (timeArray(1)< timeArray(2)) + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + end + if Value==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = num2str(stepX); + else + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'on'; + end + end + + +%%--------------------Setting for time tick label:on----------------------- + function xtimelabelon(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.xtimelabel_on.Value = 1; + gui_erpxyaxeset_waveviewer.xtimelabel_off.Value = 0; + gui_erpxyaxeset_waveviewer.xtimefont_custom.Enable = 'on'; + gui_erpxyaxeset_waveviewer.font_custom_size.Enable = 'on'; + gui_erpxyaxeset_waveviewer.xtimetextcolor.Enable = 'on'; + end + +%%--------------------Setting for time tick label:on----------------------- + function xtimelabeloff(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.xtimelabel_on.Value = 0; + gui_erpxyaxeset_waveviewer.xtimelabel_off.Value = 1; + gui_erpxyaxeset_waveviewer.xtimefont_custom.Enable = 'off'; + gui_erpxyaxeset_waveviewer.font_custom_size.Enable = 'off'; + gui_erpxyaxeset_waveviewer.xtimetextcolor.Enable = 'off'; + end + +%%----------------------font of x labelticks------------------------------- + function xtimefont(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%---------------------fontsize of x labelticks---------------------------- + function xtimefontsize(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end +%%---------------------color of x labelticks------------------------------- + function xtimecolor(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%------------------Setting for units:on----------------------------------- + function xtimeunitson(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.xtimeunits_on.Value = 1; + gui_erpxyaxeset_waveviewer.xtimeunits_off.Value = 0; + end + +%%------------------Setting for units:off---------------------------------- + function xtimeunitsoff(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.xtimeunits_on.Value = 0; + gui_erpxyaxeset_waveviewer.xtimeunits_off.Value = 1; + end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Y axis%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%-------------------------Y scale----------------------------------------- + function yrangecustom(yscalStr,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + yscalecustom = str2num(char(yscalStr.String)); + %%checking the inputs + if isempty(yscalecustom)|| numel(yscalecustom)==1 + messgStr = strcat('Y scale for "Y Axs" in "Time and Amplitude Scales" - Inputs must be two numbers '); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + + if yscalecustom(1) >= yscalecustom(2) + messgStr = strcat('Y scale for "Y Axs" in "Time and Amplitude Scales" - The left edge should be smaller than the right one '); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + if ~isempty(yscalecustom) && numel(yscalecustom)==2 && yscalecustom(1) < yscalecustom(2) && gui_erpxyaxeset_waveviewer.ytickauto.Value==1 + yticksLabel = default_amp_ticks_viewer(yscalecustom); + ytick_precision = gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + if isempty(str2num(yticksLabel)) + yticksLabel = ''; + else + if ~isempty(str2num(yticksLabel)) && numel((str2num(yticksLabel)))==1 + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + else + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + for Numofnum = 1:numel(yticksnumbel)-1 + yticksLabel = [yticksLabel,32,sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(Numofnum+1))]; + end + end + end + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticksLabel; + end + + end + +%%--------------------Y Scale Auto----------------------------------------- + function yrangeauto(yscaleauto,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = yscaleauto.Value; + if Value ==1 + try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + ALLERPIN = ERPwaviewer.ALLERP; + ERPArrayin = ERPwaviewer.SelectERPIdx; + BinArrayIN = []; + ChanArrayIn = []; + plotOrg = [1 2 3]; + try + plotOrg(1) = ERPwaviewer.plot_org.Grid; + plotOrg(2) = ERPwaviewer.plot_org.Overlay; + plotOrg(3) = ERPwaviewer.plot_org.Pages; + catch + plotOrg = [1 2 3]; + end + try + ChanArrayIn = ERPwaviewer.chan; + catch + ChanArrayIn = []; + end + try + BinArrayIN = ERPwaviewer.bin; + catch + BinArrayIN = []; + end + PageCurrent = ERPwaviewer.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + try + yRangeLabel = num2str(yylim_out(PageCurrent,:)); + catch + yRangeLabel = num2str(yylim_out(1,:)); + end + gui_erpxyaxeset_waveviewer.yrange_edit.String =yRangeLabel; + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'on'; + end + + yscalecustom = str2num(gui_erpxyaxeset_waveviewer.yrange_edit.String); + if ~isempty(yscalecustom) && numel(yscalecustom)==2 && yscalecustom(1) < yscalecustom(2) + yticksLabel = default_amp_ticks_viewer(yscalecustom); + ytick_precision = gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + if isempty(str2num(yticksLabel)) + yticksLabel = ''; + else + if ~isempty(str2num(yticksLabel)) && numel((str2num(yticksLabel)))==1 + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + else + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + for Numofnum = 1:numel(yticksnumbel)-1 + yticksLabel = [yticksLabel,32,sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(Numofnum+1))]; + end + end + end + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticksLabel; + end + + + end + +%%----------------------Y ticks-------------------------------------------- + function ytickscustom(Str,~) + ERPwaviewerIN = evalin('base','ALLERPwaviewer'); + yticksLabel = ERPwaviewerIN.yaxis.ticks; + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + ytickcustom = str2num(char(Str.String)); + %%checking the inputs + if isempty(ytickcustom) + messgStr = strcat('Y ticks on "Time and Amplitude Scales": Input must be a number!'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + Str.String = ''; + viewer_ERPDAT.Process_messg =4; + return; + end + yRange = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + %%checking if the time sticks exceed the time range + if ~isempty(yRange) && numel(yRange) ==2 + if min(ytickcustom(:))< yRange(1)%% compared with the left edge of time range + messgStr = strcat('Y ticks in "Time and Amplitude Scales": Minimum of Y ticks should be larger than the left edge of y scale!'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + Str.String = ''; + viewer_ERPDAT.Process_messg =4; + return; + end + if max(ytickcustom(:))>yRange(2)%% compared with the right edge of time range + messgStr = strcat('Y ticks in "Time and Amplitude Scales": Maximum of Y ticks should be smaller than the right edge of y scale!'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + Str.String = ''; + viewer_ERPDAT.Process_messg =4; + return; + end + yticksLabel = char(Str.String); + ytick_precision = gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + if ytick_precision<0 + ytick_precision=1; + end + if isempty(str2num(yticksLabel)) + yticksLabel = ''; + else + if ~isempty(str2num(yticksLabel)) && numel((str2num(yticksLabel)))==1 + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + else + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + for Numofnum = 1:numel(yticksnumbel)-1 + yticksLabel = [yticksLabel,32,sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(Numofnum+1))]; + end + end + end + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticksLabel; + end + end + +%%----------------------------Y ticks auto--------------------------------- + function ytickauto(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = Str.Value; + if Value ==1 + yRangeLabel = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + if ~isempty(yRangeLabel) && numel(yRangeLabel) ==2 && (yRangeLabel(1)1 && numel(yscaleRange) ==2 && (yscaleRange(1)=2 + for Numofxticks = 1:numel(yticksStr)-1 + stepY(1,Numofxticks) = yticksStr(Numofxticks)+(yticksStr(Numofxticks+1)-yticksStr(Numofxticks))/2; + end + %%adjust the left edge + steyleft = (yticksStr(2)-yticksStr(1))/2; + for ii = 1:1000 + if (yticksStr(1)- steyleft*ii)>=yticksStr(1) + stepY = [(yticksStr(1)- steyleft*ii),stepY]; + else + break; + end + end + %%adjust the right edge + steyright = (yticksStr(end)-yticksStr(end-1))/2; + for ii = 1:1000 + if (yticksStr(end)+ steyright*ii)<=yticksStr(end) + stepY = [stepY,(yticksStr(end)+ steyright*ii)]; + else + break; + end + end + end + end + gui_erpxyaxeset_waveviewer.yminorstepedit.String = num2str(stepY); + end + else + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.yminorstep_auto.Enable = 'off'; + end + end + +%%---------------------custom edit the step of minor yticks---------------- + function yminorstepedit(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + ytickmin_step = str2num(Str.String); + if isempty(ytickmin_step) + messgStr = strcat('Minor ticks for "Y Axs" in "Time and Amplitude Scales": Input must be one number or more numbers'); + erpworkingmemory('ERPViewer_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + viewer_ERPDAT.Process_messg =4; + return; + end + end + +%%-------------------Auto step of minor yticks----------------------------- + function yminorstepauto(Str,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + Value = Str.Value;%% + if Value ==1 + yticksStr = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + stepY = []; + yscaleRange = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + if ~isempty(yticksStr) && numel(yticksStr)>1 && numel(yscaleRange) ==2 && (yscaleRange(1)=2 + for Numofxticks = 1:numel(yticksStr)-1 + stepY(1,Numofxticks) = yticksStr(Numofxticks)+(yticksStr(Numofxticks+1)-yticksStr(Numofxticks))/2; + end + %%adjust the left edge + steyleft = (yticksStr(2)-yticksStr(1))/2; + for ii = 1:1000 + if (yticksStr(1)- steyleft*ii)>=yticksStr(1) + stepY = [(yticksStr(1)- steyleft*ii),stepY]; + else + break; + end + end + %%adjust the right edge + steyright = (yticksStr(end)-yticksStr(end-1))/2; + for ii = 1:1000 + if (yticksStr(end)+ steyright*ii)<=yticksStr(end) + stepY = [stepY,(yticksStr(end)+ steyright*ii)]; + else + break; + end + end + end + end + gui_erpxyaxeset_waveviewer.yminorstepedit.String = num2str(stepY); + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'on'; + end + end + +%%------------------------------Y label:on--------------------------------- + function ylabelon(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.ylabel_on.Value = 1; + gui_erpxyaxeset_waveviewer.ylabel_off.Value = 0; + gui_erpxyaxeset_waveviewer.yfont_custom.Enable = 'on'; + gui_erpxyaxeset_waveviewer.yfont_custom_size.Enable = 'on'; + gui_erpxyaxeset_waveviewer.ytextcolor.Enable = 'on'; + end + + +%%------------------------font of y labelticks----------------------------- + function yaxisfont(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%------------------------fontsize of y label ticks------------------------ + function yaxisfontsize(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + +%%------------------------color of y label ticks--------------------------- + function yaxisfontcolor(Source,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%------------------------------Y label:off-------------------------------- + function ylabeloff(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.ylabel_on.Value = 0; + gui_erpxyaxeset_waveviewer.ylabel_off.Value = 1; + gui_erpxyaxeset_waveviewer.yfont_custom.Enable = 'off'; + gui_erpxyaxeset_waveviewer.yfont_custom_size.Enable = 'off'; + gui_erpxyaxeset_waveviewer.ytextcolor.Enable = 'off'; + end + +%%---------------------------Y units:on------------------------------------ + function yunitson(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.yunits_on.Value = 1; + gui_erpxyaxeset_waveviewer.yunits_off.Value = 0; + end + +%%---------------------------Y units:off----------------------------------- + function yunitsoff(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_xyaxis',1); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [0.4940 0.1840 0.5560]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [1 1 1]; + box_erpxtaxes_viewer_property.TitleColor= [0.4940 0.1840 0.5560]; + + gui_erpxyaxeset_waveviewer.yunits_on.Value = 0; + gui_erpxyaxeset_waveviewer.yunits_off.Value = 1; + end + + +%%-----------------------help---------------------------------------------- + function xyaxis_help(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + changeFlag = estudioworkingmemory('MyViewer_xyaxis'); + if changeFlag~=1%% Donot reset this panel if there is no change + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Time and Amplitude Scales > Cancel-f_ERP_timeampscal_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + xdispsecondValue = ERPwaviewer_apply.xaxis.tdis; + if xdispsecondValue==1%% with millisecond + gui_erpxyaxeset_waveviewer.xmillisecond.Value =1; + gui_erpxyaxeset_waveviewer.xsecond.Value = 0; + xprecisoonName = {'0','1','2','3','4','5','6'}; + gui_erpxyaxeset_waveviewer.xticks_precision.String = xprecisoonName; + else%% with second + gui_erpxyaxeset_waveviewer.xmillisecond.Value =0; + gui_erpxyaxeset_waveviewer.xsecond.Value = 1; + xprecisoonName = {'1','2','3','4','5','6'}; + gui_erpxyaxeset_waveviewer.xticks_precision.String = xprecisoonName; + end + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%-------------------------time range------------------------------ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if xdispsecondValue==1 + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(ERPwaviewer_apply.xaxis.timerange); + else + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(ERPwaviewer_apply.xaxis.timerange/1000); + end + TRFlag = ERPwaviewer_apply.xaxis.trangeauto; + if TRFlag==1 + gui_erpxyaxeset_waveviewer.xtimerangeauto.Value = 1 ; + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.xtimerangeauto.Value = 0 ; + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'on'; + end + xticks_precision = ERPwaviewer_apply.xaxis.tickdecimals; + %%time ticks + if xdispsecondValue==1 + timeticks= ERPwaviewer_apply.xaxis.timeticks; + if ~isempty(timeticks) + timeticks= f_decimal(char(num2str(timeticks)),xticks_precision); + else + timeticks = ''; + end + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks; + gui_erpxyaxeset_waveviewer.xticks_precision.Value = xticks_precision+1; + else + timeticks= ERPwaviewer_apply.xaxis.timeticks/1000;%%Convert character array or string scalar to numeric array + if ~isempty(timeticks) + timeticks= f_decimal(char(num2str(timeticks)),xticks_precision); + else + timeticks = ''; + end + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeticks; + gui_erpxyaxeset_waveviewer.xticks_precision.Value = xticks_precision; + end + xtickAuto = ERPwaviewer_apply.xaxis.ticksauto; + gui_erpxyaxeset_waveviewer.xtimetickauto.Value=xtickAuto; + if xtickAuto==1 + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'on'; + end + %%minor for xticks + XMinorDis = ERPwaviewer_apply.xaxis.tminor.disp; + xMinorAuto = ERPwaviewer_apply.xaxis.tminor.auto; + gui_erpxyaxeset_waveviewer.xtimeminorauto.Value = XMinorDis; + if xMinorAuto==1 + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value =1; + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value =0; + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'on'; + end + if XMinorDis==1 + if xMinorAuto==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'on'; + end + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'on'; + else + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'off'; + end + xtickMinorstep = ERPwaviewer_apply.xaxis.tminor.step; + if xdispsecondValue==0 + xtickMinorstep= xtickMinorstep/1000;%%Convert character array or string scalar to numeric array + end + if ~isempty(xtickMinorstep) + xtickMinorstep= f_decimal(char(num2str(xtickMinorstep)),xticks_precision); + else + xtickMinorstep = ''; + end + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = xtickMinorstep; + %%x labels + xlabelFlag = ERPwaviewer_apply.xaxis.label; + gui_erpxyaxeset_waveviewer.xtimelabel_on.Value = xlabelFlag; + gui_erpxyaxeset_waveviewer.xtimelabel_off.Value = ~xlabelFlag; + gui_erpxyaxeset_waveviewer.xtimefont_custom.Value = ERPwaviewer_apply.xaxis.font; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + xfontsizeinum = str2num(char(fontsize)); + xlabelfontsize = ERPwaviewer_apply.xaxis.fontsize; + [x_label,~] = find(xfontsizeinum==xlabelfontsize); + if isempty(x_label) + x_label=5; + end + gui_erpxyaxeset_waveviewer.font_custom_size.Value = x_label; + gui_erpxyaxeset_waveviewer.xtimetextcolor.Value = ERPwaviewer_apply.xaxis.fontcolor; + if xlabelFlag==1 + xlabelFlagEnable = 'on'; + else + xlabelFlagEnable = 'off'; + end + gui_erpxyaxeset_waveviewer.xtimefont_custom.Enable = xlabelFlagEnable; + gui_erpxyaxeset_waveviewer.font_custom_size.Enable = xlabelFlagEnable; + gui_erpxyaxeset_waveviewer.xtimetextcolor.Enable = xlabelFlagEnable; + %%x units + xaxisunits= ERPwaviewer_apply.xaxis.units; + gui_erpxyaxeset_waveviewer.xtimeunits_on.Value =xaxisunits; + gui_erpxyaxeset_waveviewer.xtimeunits_off.Value = ~xaxisunits; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%------------------------setting for y axes----------------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + gui_erpxyaxeset_waveviewer.yrange_edit.String = num2str(ERPwaviewer_apply.yaxis.scales); + gui_erpxyaxeset_waveviewer.yrangeauto.Value = ERPwaviewer_apply.yaxis.scalesauto; + if gui_erpxyaxeset_waveviewer.yrangeauto.Value==1 + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'on'; + end + ytickdecimals = ERPwaviewer_apply.yaxis.tickdecimals; + gui_erpxyaxeset_waveviewer.yticks_precision.Value = ytickdecimals+1; + YTicks=ERPwaviewer_apply.yaxis.ticks; + if ~isempty(YTicks) + YTicks= f_decimal(char(num2str(YTicks)),ytickdecimals); + else + YTicks = ''; + end + gui_erpxyaxeset_waveviewer.yticks_edit.String = YTicks; + + gui_erpxyaxeset_waveviewer.ytickauto.Value=ERPwaviewer_apply.yaxis.tickauto ; + if gui_erpxyaxeset_waveviewer.ytickauto.Value==1 + gui_erpxyaxeset_waveviewer.yticks_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yticks_edit.Enable = 'on'; + end + %%minor yticks + yMinorDisp= ERPwaviewer_apply.yaxis.yminor.disp; + yMinorAuto = ERPwaviewer_apply.yaxis.yminor.auto; + if yMinorDisp==1 + gui_erpxyaxeset_waveviewer.yminortick.Value=1; + gui_erpxyaxeset_waveviewer.yminorstep_auto.Enable = 'on'; + if yMinorAuto==1 + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'on'; + end + else + gui_erpxyaxeset_waveviewer.yminortick.Value=0; + gui_erpxyaxeset_waveviewer.yminorstep_auto.Enable = 'off'; + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; + end + gui_erpxyaxeset_waveviewer.yminorstep_auto.Value = yMinorAuto; + gui_erpxyaxeset_waveviewer.yminorstepedit.String = num2str(ERPwaviewer_apply.yaxis.yminor.step); + + gui_erpxyaxeset_waveviewer.ylabel_on.Value = ERPwaviewer_apply.yaxis.label; + gui_erpxyaxeset_waveviewer.ylabel_off.Value = ~ERPwaviewer_apply.yaxis.label; + gui_erpxyaxeset_waveviewer.yfont_custom.Value =ERPwaviewer_apply.yaxis.font; + ylabelFontsize = ERPwaviewer_apply.yaxis.fontsize; + [yx_label,~] = find(xfontsizeinum==ylabelFontsize); + if isempty(yx_label) + yx_label=5; + end + gui_erpxyaxeset_waveviewer.yfont_custom_size.Value = yx_label; + gui_erpxyaxeset_waveviewer.ytextcolor.Value= ERPwaviewer_apply.yaxis.fontcolor; + if gui_erpxyaxeset_waveviewer.ylabel_on.Value==1 + ylabelFlagEnable = 'on'; + else + ylabelFlagEnable = 'off'; + end + gui_erpxyaxeset_waveviewer.yfont_custom.Enable = ylabelFlagEnable; + gui_erpxyaxeset_waveviewer.yfont_custom_size.Enable = ylabelFlagEnable; + gui_erpxyaxeset_waveviewer.ytextcolor.Enable = ylabelFlagEnable; + + gui_erpxyaxeset_waveviewer.yunits_on.Value = ERPwaviewer_apply.yaxis.units; + gui_erpxyaxeset_waveviewer.yunits_off.Value = ~ERPwaviewer_apply.yaxis.units; + estudioworkingmemory('MyViewer_xyaxis',0); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erpxtaxes_viewer_property.TitleColor= [0.5 0.5 0.9]; + end + +%%-----------------------------Apply--------------------------------------- + function xyaxis_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=3 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_xyaxis',0); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erpxtaxes_viewer_property.TitleColor= [0.5 0.5 0.9]; + + MessageViewer= char(strcat('Time and Amplitude Scales > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Time and Amplitude Scales > Apply-f_ERP_timeampscal_waveviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + %%time range + xdispsecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value; %display with millisecond + if xdispsecondValue==1 + timeRange = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String);%get the time range for plotting and check it + else + timeRange = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String)*1000; + end + + if numel(timeRange)==1 || isempty(timeRange) + timeRange(1) = ERPwaviewer_apply.ERP.times(1); + timeRange(2) = ERPwaviewer_apply.ERP.times(end); + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Time and Amplitude Scales > Apply-Time range() error.\n Inputs must be two numbers! Please change it, otherwise, the default values will be used.\n\n'); + % return; + end + if timeRange(1) >= timeRange(2) + timeRange(1) = ERPwaviewer_apply.ERP.times(1); + timeRange(2) = ERPwaviewer_apply.ERP.times(end); + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n Time and Amplitude Scales > Apply-Time range() error.\n The left edge should not be smaller than the right one!\n Please change current values, otherwise, the default ones will be used!\n\n'); + % return; + end + ERPwaviewer_apply.xaxis.timerange = timeRange; + ERPwaviewer_apply.xaxis.trangeauto = gui_erpxyaxeset_waveviewer.xtimerangeauto.Value; + ERPwaviewer_apply.xaxis.tdis = xdispsecondValue; + %%getting xticks + if xdispsecondValue==1 + xticksArray = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + else + xticksArray = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String))*1000;%%transform into millisecond + end + count_xtks = 0; + xticks_exm = []; + if ~isempty(xticksArray) && numel(timeRange) ==2 %%check if xticks exceed the defined time range + for Numofxticks = 1:numel(xticksArray) + if xticksArray(Numofxticks)< timeRange(1) || xticksArray(Numofxticks)> timeRange(2) + count_xtks =count_xtks+1; + xticks_exm(count_xtks) = Numofxticks; + end + end + xticksArray(xticks_exm) = []; + end + ERPwaviewer_apply.xaxis.timeticks = xticksArray; + ERPwaviewer_apply.xaxis.ticksauto = gui_erpxyaxeset_waveviewer.xtimetickauto.Value; + if gui_erpxyaxeset_waveviewer.xmillisecond.Value==1 + ERPwaviewer_apply.xaxis.tickdecimals = gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + else + ERPwaviewer_apply.xaxis.tickdecimals = gui_erpxyaxeset_waveviewer.xticks_precision.Value; + end + + %%minor for xticks + ERPwaviewer_apply.xaxis.tminor.disp = gui_erpxyaxeset_waveviewer.xtimeminorauto.Value; + xticckMinorstep = str2num(char(gui_erpxyaxeset_waveviewer.timeminorticks_custom.String)); + if xdispsecondValue==1 + ERPwaviewer_apply.xaxis.tminor.step = xticckMinorstep; + else + ERPwaviewer_apply.xaxis.tminor.step = xticckMinorstep*1000; + end + ERPwaviewer_apply.xaxis.tminor.auto = gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value; + %%xtick label on/off + ERPwaviewer_apply.xaxis.label = gui_erpxyaxeset_waveviewer.xtimelabel_on.Value; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + xfontsizeinum = str2num(char(fontsize)); + ERPwaviewer_apply.xaxis.font = gui_erpxyaxeset_waveviewer.xtimefont_custom.Value; + ERPwaviewer_apply.xaxis.fontsize = xfontsizeinum(gui_erpxyaxeset_waveviewer.font_custom_size.Value); + ERPwaviewer_apply.xaxis.fontcolor = gui_erpxyaxeset_waveviewer.xtimetextcolor.Value; + ERPwaviewer_apply.xaxis.units = gui_erpxyaxeset_waveviewer.xtimeunits_on.Value; + %%y scales + YScales = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + if isempty(YScales) + ALLERPIN = ERPwaviewer_apply.ALLERP; + ERPArrayin = ERPwaviewer_apply.SelectERPIdx; + BinArrayIN = []; + ChanArrayIn = []; + plotOrg = [1 2 3]; + try + plotOrg(1) = ERPwaviewer_apply.plot_org.Grid; + plotOrg(2) = ERPwaviewer_apply.plot_org.Overlay; + plotOrg(3) = ERPwaviewer_apply.plot_org.Pages; + catch + plotOrg = [1 2 3]; + end + try + ChanArrayIn = ERPwaviewer_apply.chan; + catch + ChanArrayIn = []; + end + try + BinArrayIN = ERPwaviewer_apply.bin; + catch + BinArrayIN = []; + end + PageCurrent = ERPwaviewer_apply.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + YScales = []; + try + YScales = yylim_out(PageCurrent,:); + catch + YScales = yylim_out(1,:); + end + end + ERPwaviewer_apply.yaxis.scales =YScales ; + ERPwaviewer_apply.yaxis.scalesauto = gui_erpxyaxeset_waveviewer.yrangeauto.Value; + %%yticks + YTicks = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + count_xtks = 0; + yticks_exm = []; + if ~isempty(YTicks) && numel(YScales) ==2 %%check if xticks exceed the defined time range + for Numofxticks = 1:numel(YTicks) + if YTicks(Numofxticks)< YScales(1) || YTicks(Numofxticks)> YScales(2) + count_xtks =count_xtks+1; + yticks_exm(count_xtks) = Numofxticks; + end + end + YTicks(yticks_exm) = []; + end + ERPwaviewer_apply.yaxis.tickdecimals = gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + ERPwaviewer_apply.yaxis.ticks = YTicks; + ERPwaviewer_apply.yaxis.tickauto = gui_erpxyaxeset_waveviewer.ytickauto.Value; + %%minor yticks + ERPwaviewer_apply.yaxis.yminor.disp = gui_erpxyaxeset_waveviewer.yminortick.Value; + ERPwaviewer_apply.yaxis.yminor.step = str2num(char(gui_erpxyaxeset_waveviewer.yminorstepedit.String)); + ERPwaviewer_apply.yaxis.yminor.auto = gui_erpxyaxeset_waveviewer.yminorstep_auto.Value; + %%y labels: on/off + ERPwaviewer_apply.yaxis.label = gui_erpxyaxeset_waveviewer.ylabel_on.Value; + %%yticks: font and font size + ERPwaviewer_apply.yaxis.font = gui_erpxyaxeset_waveviewer.yfont_custom.Value; + yfontsizeinum = str2num(char(fontsize)); + ERPwaviewer_apply.yaxis.fontsize = yfontsizeinum(gui_erpxyaxeset_waveviewer.yfont_custom_size.Value); + %%yticks color + ERPwaviewer_apply.yaxis.fontcolor = gui_erpxyaxeset_waveviewer.ytextcolor.Value; + %%y units + ERPwaviewer_apply.yaxis.units = gui_erpxyaxeset_waveviewer.yunits_on.Value; + %%save the parameters + ALLERPwaviewer=ERPwaviewer_apply; + assignin('base','ALLERPwaviewer',ALLERPwaviewer); + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2;%% complete + end + + +%%------------change this panel based on the changed ERPsets--------------- + function v_currentERP_change(~,~) + if viewer_ERPDAT.Count_currentERP == 0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + try + ERPIN = ERPwaviewer_apply.ERP; + timeArray(1) = ERPwaviewer_apply.ERP.times(1); + timeArray(2) = ERPwaviewer_apply.ERP.times(end); + [timeticks stepX]= default_time_ticks_studio(ERPIN, [timeArray(1),timeArray(2)]); + if ~isempty(stepX) && numel(stepX) ==1 + stepX = floor(stepX/2); + end + catch + timeticks = []; + timeArray = []; + end + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------------Setting for X axis------------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + xSecondflag = erpworkingmemory('MyViewer_xaxis_second'); + xmSecondflag = erpworkingmemory('MyViewer_xaxis_msecond'); + if isempty(xSecondflag) && isempty(xmSecondflag) + xdispysecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value;%%millisecond + end + if xSecondflag ==0 && xmSecondflag==1 + xdispysecondValue =1; + if gui_erpxyaxeset_waveviewer.xtimerangeauto.Value==1 + if xdispysecondValue==1 + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray); + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'0','1','2','3','4','5','6'}; + else + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray/1000); + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'1','2','3','4','5','6'}; + end + end + else + xdispysecondValue =0; + end + if xdispysecondValue==1 + xtick_precision =gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + if xtick_precision<0 + xtick_precision =0; + gui_erpxyaxeset_waveviewer.xticks_precision.Value=1; + end + else + xtick_precision =gui_erpxyaxeset_waveviewer.xticks_precision.Value; + if xtick_precision<=0 + xtick_precision =1; + gui_erpxyaxeset_waveviewer.xticks_precision.Value=1; + end + end + if gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + if xdispysecondValue==0 + timetickstrs = num2str(str2num(char(timeticks))/1000); + else + timetickstrs = timeticks; + end + timetickstrs= f_decimal(char(timetickstrs),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = char(timetickstrs); + end + ERPwaviewer_apply.xaxis.tickdecimals = xtick_precision; + + %%X minor ticks + stepX = []; + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + if xdispysecondValue~=1 + xticksStr = xticksStr*1000; + timeArray = timeArray*1000; + end + + if gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value ==1 + if ~isempty(xticksStr) && numel(xticksStr)>1 + stepX = []; + if ~isempty(xticksStr) && numel(xticksStr)>1 && numel(timeArray) ==2 && (timeArray(1)< timeArray(2)) + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + end + if xdispysecondValue==0 + stepX = stepX/1000; + end + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = num2str(stepX); + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------------Setting for Y axis------------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%y scale + ALLERPIN = ERPwaviewer_apply.ALLERP; + ERPArrayin = ERPwaviewer_apply.SelectERPIdx; + BinArrayIN = []; + ChanArrayIn = []; + plotOrg = [1 2 3]; + try + plotOrg(1) = ERPwaviewer_apply.plot_org.Grid; + plotOrg(2) = ERPwaviewer_apply.plot_org.Overlay; + plotOrg(3) = ERPwaviewer_apply.plot_org.Pages; + catch + plotOrg = [1 2 3]; + end + try + ChanArrayIn = ERPwaviewer_apply.chan; + catch + ChanArrayIn = []; + end + try + BinArrayIN = ERPwaviewer_apply.bin; + catch + BinArrayIN = []; + end + + PageCurrent = ERPwaviewer_apply.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + try + yRangeLabel = num2str(yylim_out(PageCurrent,:)); + catch + yRangeLabel = num2str(yylim_out(1,:)); + end + + if gui_erpxyaxeset_waveviewer.yrangeauto.Value ==1 + gui_erpxyaxeset_waveviewer.yrange_edit.String = yRangeLabel; + end + %%y ticks + yticksLabel = ''; + if ~isempty(str2num(yRangeLabel)) + yticksLabel = default_amp_ticks_viewer(str2num(yRangeLabel)); + end + ytick_precision= gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + yticksLabel= f_decimal(char(yticksLabel),ytick_precision); + if gui_erpxyaxeset_waveviewer.ytickauto.Value ==1 + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticksLabel; + end + + %%y minor ticks + if gui_erpxyaxeset_waveviewer.yminorstep_auto.Value==1 + yticksStr = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + stepY = []; + yscaleRange = (str2num(yRangeLabel)); + if ~isempty(yticksStr) && numel(yticksStr)>1 + if numel(yticksStr)>=2 + for Numofxticks = 1:numel(yticksStr)-1 + stepY(1,Numofxticks) = yticksStr(Numofxticks)+(yticksStr(Numofxticks+1)-yticksStr(Numofxticks))/2; + end + %%adjust the left edge + steyleft = (yticksStr(2)-yticksStr(1))/2; + for ii = 1:1000 + if (yticksStr(1)- steyleft*ii)>=yscaleRange(1) + stepY = [(yticksStr(1)- steyleft*ii),stepY]; + else + break; + end + end + %%adjust the right edge + steyright = (yticksStr(end)-yticksStr(end-1))/2; + for ii = 1:1000 + if (yticksStr(end)+ steyright*ii)<=yscaleRange(end) + stepY = [stepY,(yticksStr(end)+ steyright*ii)]; + else + break; + end + end + end + end + gui_erpxyaxeset_waveviewer.yminorstepedit.String=char(num2str(stepY)); + end + + if xdispysecondValue==1 + ERPwaviewer_apply.xaxis.timerange = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String); + else + ERPwaviewer_apply.xaxis.timerange = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String)*1000; + end + timeRange = ERPwaviewer_apply.xaxis.timerange ; + %%getting xticks + if xdispysecondValue==1 + xticksArray = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + else + xticksArray = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String))*1000; + end + count_xtks = 0; + xticks_exm = []; + if ~isempty(xticksArray) && numel(timeRange) ==2 %%check if xticks exceed the defined time range + for Numofxticks = 1:numel(xticksArray) + if xticksArray(Numofxticks)< timeRange(1) || xticksArray(Numofxticks)> timeRange(2) + count_xtks =count_xtks+1; + xticks_exm(count_xtks) = Numofxticks; + end + end + xticksArray(xticks_exm) = []; + end + + xticckMinorstep = str2num(char(gui_erpxyaxeset_waveviewer.timeminorticks_custom.String)); + if xdispysecondValue==1 + ERPwaviewer_apply.xaxis.tminor.step = xticckMinorstep; + else + ERPwaviewer_apply.xaxis.tminor.step = xticckMinorstep*1000; + end + ERPwaviewer_apply.xaxis.timeticks = xticksArray; + + %%y axis + YScales = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + if isempty(YScales) + PageCurrent = ERPwaviewer_apply.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + YScales = []; + try + YScales = yylim_out(PageCurrent,:); + catch + YScales = yylim_out(1,:); + end + end + ERPwaviewer_apply.yaxis.scales =YScales ; + YTicks = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + count_xtks = 0; + yticks_exm = []; + if ~isempty(YTicks) && numel(YScales) ==2 %%check if xticks exceed the defined time range + for Numofxticks = 1:numel(YTicks) + if YTicks(Numofxticks)< YScales(1) || YTicks(Numofxticks)> YScales(2) + count_xtks =count_xtks+1; + yticks_exm(count_xtks) = Numofxticks; + end + end + YTicks(yticks_exm) = []; + end + ERPwaviewer_apply.yaxis.ticks = YTicks; + ERPwaviewer_apply.yaxis.yminor.step = str2num(char(gui_erpxyaxeset_waveviewer.yminorstepedit.String)); + %%save the parameters + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%---------------change X/Y axis based on the current Page---------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function page_xyaxis_change(~,~) + if viewer_ERPDAT.page_xyaxis==0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI() error: Please run the ERP wave viewer again.'); + return; + end + + try + ERPIN = ERPwaviewer_apply.ERP; + timeArray(1) = ERPwaviewer_apply.ERP.times(1); + timeArray(2) = ERPwaviewer_apply.ERP.times(end); + [timeticks stepX]= default_time_ticks_studio(ERPIN, [timeArray(1),timeArray(2)]); + if ~isempty(stepX) && numel(stepX) ==1 + stepX = floor(stepX/2); + end + catch + timeticks = ''; + timeArray = []; + end + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------------Setting for X axis------------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + xSecondflag = erpworkingmemory('MyViewer_xaxis_second'); + xmSecondflag = erpworkingmemory('MyViewer_xaxis_msecond'); + if isempty(xSecondflag) && isempty(xmSecondflag) + xdispysecondValue = gui_erpxyaxeset_waveviewer.xmillisecond.Value;%%millisecond + end + if xSecondflag ==0 && xmSecondflag==1 + xdispysecondValue =1; + if gui_erpxyaxeset_waveviewer.xtimerangeauto.Value==1 + if xdispysecondValue==1 + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray); + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'0','1','2','3','4','5','6'}; + else + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray/1000); + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'1','2','3','4','5','6'}; + end + end + else + xdispysecondValue =0; + end + + if xdispysecondValue==1 + xtick_precision =gui_erpxyaxeset_waveviewer.xticks_precision.Value-1; + if xtick_precision<0 + xtick_precision =0; + gui_erpxyaxeset_waveviewer.xticks_precision.Value=1; + end + else + xtick_precision =gui_erpxyaxeset_waveviewer.xticks_precision.Value; + if xtick_precision<=0 + xtick_precision =1; + gui_erpxyaxeset_waveviewer.xticks_precision.Value=1; + end + end + ERPwaviewer_apply.xaxis.tickdecimals = xtick_precision; + + if gui_erpxyaxeset_waveviewer.xtimetickauto.Value ==1 + if xdispysecondValue==0 + timeticks = num2str(str2num(char(timeticks))/1000); + end + timeticks= f_decimal(char(timeticks),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = char(timeticks); + end + %%X minor ticks + stepX = []; + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + if xdispysecondValue~=1 + xticksStr = xticksStr*1000; + timeArray = timeArray*1000; + end + if gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value ==1 + if ~isempty(xticksStr) && numel(xticksStr)>1 + + if ~isempty(xticksStr) && numel(xticksStr)>1 && numel(timeArray) ==2 && (timeArray(1)< timeArray(2)) + if numel(xticksStr)>=2 + for Numofxticks = 1:numel(xticksStr)-1 + stepX(1,Numofxticks) = xticksStr(Numofxticks)+(xticksStr(Numofxticks+1)-xticksStr(Numofxticks))/2; + end + %%adjust the left edge + stexleft = (xticksStr(2)-xticksStr(1))/2; + for ii = 1:1000 + if (xticksStr(1)- stexleft*ii)>=timeArray(1) + stepX = [(xticksStr(1)- stexleft*ii),stepX]; + else + break; + end + end + %%adjust the right edge + stexright = (xticksStr(end)-xticksStr(end-1))/2; + for ii = 1:1000 + if (xticksStr(end)+ stexright*ii)<=timeArray(end) + stepX = [stepX,(xticksStr(end)+ stexright*ii)]; + else + break; + end + end + end + end + end + if xdispysecondValue==0 + stepX =stepX/1000; + end + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = num2str(stepX); + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------------Setting for Y axis------------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%y scale + ALLERPIN = ERPwaviewer_apply.ALLERP; + ERPArrayin = ERPwaviewer_apply.SelectERPIdx; + BinArrayIN = []; + ChanArrayIn = []; + plotOrg = [1 2 3]; + try + plotOrg(1) = ERPwaviewer_apply.plot_org.Grid; + plotOrg(2) = ERPwaviewer_apply.plot_org.Overlay; + plotOrg(3) = ERPwaviewer_apply.plot_org.Pages; + catch + plotOrg = [1 2 3]; + end + try + ChanArrayIn = ERPwaviewer_apply.chan; + catch + ChanArrayIn = []; + end + try + BinArrayIN = ERPwaviewer_apply.bin; + catch + BinArrayIN = []; + end + + PageCurrent = ERPwaviewer_apply.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + try + yRangeLabel = num2str(yylim_out(PageCurrent,:)); + catch + yRangeLabel = num2str(yylim_out(1,:)); + end + + if gui_erpxyaxeset_waveviewer.yrangeauto.Value ==1 + gui_erpxyaxeset_waveviewer.yrange_edit.String = yRangeLabel; + end + %%y ticks + yticksLabel = ''; + if ~isempty(str2num(yRangeLabel)) + yticksLabel = default_amp_ticks_viewer(str2num(yRangeLabel)); + end + + ytick_precision= gui_erpxyaxeset_waveviewer.yticks_precision.Value-1; + yticksLabel= f_decimal(char(yticksLabel),ytick_precision); + + if gui_erpxyaxeset_waveviewer.ytickauto.Value ==1 + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticksLabel; + end + + %%y minor ticks + if gui_erpxyaxeset_waveviewer.yminorstep_auto.Value==1 + yticksStr = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + stepY = []; + yscaleRange = (str2num(yRangeLabel)); + if ~isempty(yticksStr) && numel(yticksStr)>1 + if numel(yticksStr)>=2 + for Numofxticks = 1:numel(yticksStr)-1 + stepY(1,Numofxticks) = yticksStr(Numofxticks)+(yticksStr(Numofxticks+1)-yticksStr(Numofxticks))/2; + end + %%adjust the left edge + steyleft = (yticksStr(2)-yticksStr(1))/2; + for ii = 1:1000 + if (yticksStr(1)- steyleft*ii)>=yscaleRange(1) + stepY = [(yticksStr(1)- steyleft*ii),stepY]; + else + break; + end + end + %%adjust the right edge + steyright = (yticksStr(end)-yticksStr(end-1))/2; + for ii = 1:1000 + if (yticksStr(end)+ steyright*ii)<=yscaleRange(end) + stepY = [stepY,(yticksStr(end)+ steyright*ii)]; + else + break; + end + end + end + end + gui_erpxyaxeset_waveviewer.yminorstepedit.String=char(num2str(stepY)); + end + + if xdispysecondValue==1 + ERPwaviewer_apply.xaxis.timerange = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String); + else + ERPwaviewer_apply.xaxis.timerange = str2num(gui_erpxyaxeset_waveviewer.timerange_edit.String)*1000; + end + timeRange = ERPwaviewer_apply.xaxis.timerange; + + %%getting xticks + if xdispysecondValue==1 + xticksArray = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + else + xticksArray = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String))*1000; + end + count_xtks = 0; + xticks_exm = []; + if ~isempty(xticksArray) && numel(timeRange) ==2 %%check if xticks exceed the defined time range + for Numofxticks = 1:numel(xticksArray) + if xticksArray(Numofxticks)< timeRange(1) || xticksArray(Numofxticks)> timeRange(2) + count_xtks =count_xtks+1; + xticks_exm(count_xtks) = Numofxticks; + end + end + xticksArray(xticks_exm) = []; + end + + xticckMinorstep = str2num(char(gui_erpxyaxeset_waveviewer.timeminorticks_custom.String)); + if xdispysecondValue==1 + ERPwaviewer_apply.xaxis.tminor.step = xticckMinorstep; + else + ERPwaviewer_apply.xaxis.tminor.step = xticckMinorstep*1000; + end + ERPwaviewer_apply.xaxis.timeticks = xticksArray; + + %%y axis + YScales = str2num(char(gui_erpxyaxeset_waveviewer.yrange_edit.String)); + if isempty(YScales) + PageCurrent = ERPwaviewer_apply.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + YScales = []; + try + YScales = yylim_out(PageCurrent,:); + catch + YScales = yylim_out(1,:); + end + end + ERPwaviewer_apply.yaxis.scales =YScales ; + YTicks = str2num(char(gui_erpxyaxeset_waveviewer.yticks_edit.String)); + count_xtks = 0; + yticks_exm = []; + if ~isempty(YTicks) && numel(YScales) ==2 %%check if xticks exceed the defined time range + for Numofxticks = 1:numel(YTicks) + if YTicks(Numofxticks)< YScales(1) || YTicks(Numofxticks)> YScales(2) + count_xtks =count_xtks+1; + yticks_exm(count_xtks) = Numofxticks; + end + end + YTicks(yticks_exm) = []; + end + ERPwaviewer_apply.yaxis.ticks = YTicks; + ERPwaviewer_apply.yaxis.yminor.step = str2num(char(gui_erpxyaxeset_waveviewer.yminorstepedit.String)); + %%save the parameters + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + end + +%%-------------modify this panel based on the updated parameters----------- + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERP_timeampscal_waveviewer_GUI()> count_loadproper_change() error: Please run the ERP wave viewer again.'); + return; + end + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%------------------------------X axis---------------------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%display xtick with milliseocnd or second + xdispysecondValue = ERPwaviewer_apply.xaxis.tdis; + gui_erpxyaxeset_waveviewer.xmillisecond.Value = xdispysecondValue; + gui_erpxyaxeset_waveviewer.xsecond.Value = ~xdispysecondValue; + + %%x range + timeRange = ERPwaviewer_apply.xaxis.timerange; + timeRangeAuto = ERPwaviewer_apply.xaxis.trangeauto; + if timeRangeAuto~=0 && timeRangeAuto~=1 + timeRangeAuto =1; + end + if xdispysecondValue ==1 + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeRange); + else + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeRange/1000); + end + + gui_erpxyaxeset_waveviewer.xtimerangeauto.Value = timeRangeAuto; + if timeRangeAuto==1 + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'on'; + end + timeTick = ERPwaviewer_apply.xaxis.timeticks; + timetickAuto = ERPwaviewer_apply.xaxis.ticksauto; + + if xdispysecondValue ==0%% in second + timeTick = timeTick/1000; + end + xtick_precision = ERPwaviewer_apply.xaxis.tickdecimals; + if xdispysecondValue==1 + if xtick_precision<0 + xtick_precision=1; + end + gui_erpxyaxeset_waveviewer.xticks_precision.Value = xtick_precision+1; + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'0','1','2','3','4','5','6'}; + else + if xtick_precision<=0 + xtick_precision=1; + end + gui_erpxyaxeset_waveviewer.xticks_precision.Value = xtick_precision; + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'1','2','3','4','5','6'}; + end + + timeTick= f_decimal(char(num2str(timeTick)),xtick_precision); + gui_erpxyaxeset_waveviewer.timeticks_edit.String = timeTick; + gui_erpxyaxeset_waveviewer.xtimetickauto.Value = timetickAuto; + if timetickAuto==1 + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'on'; + end + + timetixkMinordip = ERPwaviewer_apply.xaxis.tminor.disp; + timetixkMinorstep = ERPwaviewer_apply.xaxis.tminor.step; + timetixkMinorauto = ERPwaviewer_apply.xaxis.tminor.auto; + gui_erpxyaxeset_waveviewer.xtimeminorauto.Value = timetixkMinordip; + if xdispysecondValue ==0%% in second + timetixkMinorstep = timetixkMinorstep/1000; + end + timetixkMinorstep= f_decimal(char(num2str(timetixkMinorstep)),xtick_precision); + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = char(timetixkMinorstep); + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value = timetixkMinorauto; + if timetixkMinordip ==0 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'on'; + if timetixkMinorauto==1 + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'on'; + end + end + %%xticklabels + xticklabelValue = ERPwaviewer_apply.xaxis.label; + gui_erpxyaxeset_waveviewer.xtimelabel_on.Value = xticklabelValue; + gui_erpxyaxeset_waveviewer.xtimelabel_off.Value = ~xticklabelValue; + xticklabelfont = ERPwaviewer_apply.xaxis.font; + gui_erpxyaxeset_waveviewer.xtimefont_custom.Value = xticklabelfont; + xticklabelfontsize = ERPwaviewer_apply.xaxis.fontsize; + fontsize = {'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + fontsize = str2num(char(fontsize)); + [xsize,y] = find(fontsize ==xticklabelfontsize); + gui_erpxyaxeset_waveviewer.font_custom_size.Value = xsize; + xticklabelcolor = ERPwaviewer_apply.xaxis.fontcolor; + gui_erpxyaxeset_waveviewer.xtimetextcolor.Value =xticklabelcolor; + xaxisunits = ERPwaviewer_apply.xaxis.units; + gui_erpxyaxeset_waveviewer.xtimeunits_on.Value =xaxisunits; + gui_erpxyaxeset_waveviewer.xtimeunits_off.Value = ~xaxisunits; + if xticklabelValue ==1 + XticklabelEnable = 'on'; + else + XticklabelEnable = 'off'; + end + gui_erpxyaxeset_waveviewer.xtimefont_custom.Enable = XticklabelEnable; + gui_erpxyaxeset_waveviewer.font_custom_size.Enable = XticklabelEnable; + gui_erpxyaxeset_waveviewer.xtimetextcolor.Enable = XticklabelEnable; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%------------------------------Y axis---------------------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + YScales = ERPwaviewer_apply.yaxis.scales; + YScalesAuto = ERPwaviewer_apply.yaxis.scalesauto; + gui_erpxyaxeset_waveviewer.yrange_edit.String = num2str(YScales); + gui_erpxyaxeset_waveviewer.yrangeauto.Value = YScalesAuto; + if YScalesAuto==1 + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'on'; + end + %%y ticks + try + gui_erpxyaxeset_waveviewer.yticks_precision.Value =ERPwaviewer_apply.yaxis.tickdecimals; + catch + gui_erpxyaxeset_waveviewer.yticks_precision.Value =1; + end + + yticks = ERPwaviewer_apply.yaxis.ticks; + yticksauto = ERPwaviewer_apply.yaxis.tickauto; + ytick_precision = ERPwaviewer_apply.yaxis.tickdecimals; + gui_erpxyaxeset_waveviewer.yticks_precision.Value = ytick_precision+1; + yticks= f_decimal(char(num2str(yticks)),ytick_precision); + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticks; + gui_erpxyaxeset_waveviewer.ytickauto.Value = yticksauto; + if yticksauto==1 + gui_erpxyaxeset_waveviewer.yticks_edit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yticks_edit.Enable = 'on'; + end + + ytickminordisp = ERPwaviewer_apply.yaxis.yminor.disp; + ytickminorstep = ERPwaviewer_apply.yaxis.yminor.step; + ytickminorauto = ERPwaviewer_apply.yaxis.yminor.auto; + gui_erpxyaxeset_waveviewer.yminortick.Value = ytickminordisp; + gui_erpxyaxeset_waveviewer.yminorstepedit.String = num2str(ytickminorstep); + gui_erpxyaxeset_waveviewer.yminorstep_auto.Value = ytickminorauto; + if ytickminordisp==0 + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.yminorstep_auto.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yminorstep_auto.Enable = 'on'; + if ytickminorauto==1 + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; + else + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'on'; + end + end + yticklabel = ERPwaviewer_apply.yaxis.label; + gui_erpxyaxeset_waveviewer.ylabel_on.Value = yticklabel; + gui_erpxyaxeset_waveviewer.ylabel_off.Value = ~yticklabel; + yticklabelfont = ERPwaviewer_apply.yaxis.font; + yticklabelfontsize = ERPwaviewer_apply.yaxis.fontsize; + yticklabelcolor = ERPwaviewer_apply.yaxis.fontcolor; + gui_erpxyaxeset_waveviewer.yfont_custom.Value = yticklabelfont; + [ysize,~] = find(fontsize ==yticklabelfontsize); + gui_erpxyaxeset_waveviewer.yfont_custom_size.Value = ysize; + gui_erpxyaxeset_waveviewer.ytextcolor.Value = yticklabelcolor; + if yticklabel==1 + yticksEnable = 'on'; + else + yticksEnable = 'off'; + end + gui_erpxyaxeset_waveviewer.yfont_custom.Enable = yticksEnable; + gui_erpxyaxeset_waveviewer.yfont_custom_size.Enable = yticksEnable; + gui_erpxyaxeset_waveviewer.ytextcolor.Enable = yticksEnable; + yunits = ERPwaviewer_apply.yaxis.units; + gui_erpxyaxeset_waveviewer.yunits_on.Value = yunits; + gui_erpxyaxeset_waveviewer.yunits_off.Value = ~yunits; + end + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_xyaxis'); + if changeFlag~=1 + return; + end + xyaxis_apply(); + end + +%%------------------------------------------------------------------------- +%%-----------------Reset this panel with the default parameters------------ +%%------------------------------------------------------------------------- + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==3 + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + + catch + beep; + disp('f_ERP_Binchan_waviewer_GUI error: Restart ERPwave Viewer'); + return; + end + + ALLERPIN = ERPwaviewer_apply.ALLERP; + try + ERPIN = ERPwaviewer_apply.ERP; + timeArray(1) = ERPwaviewer_apply.ERP.times(1); + timeArray(2) = ERPwaviewer_apply.ERP.times(end); + [timeticks stepX]= default_time_ticks_studio(ERPIN, [timeArray(1),timeArray(2)]); + if ~isempty(stepX) && numel(stepX) ==1 + stepX = floor(stepX/2); + end + catch + timeticks = ''; + timeArray = []; + end + gui_erpxyaxeset_waveviewer.xmillisecond.Value =1; + gui_erpxyaxeset_waveviewer.xsecond.Value =0; + ERPwaviewer_apply.xaxis.tdis =1; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------------Setting for X axis--------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%time range + gui_erpxyaxeset_waveviewer.timerange_edit.String = num2str(timeArray); + ERPwaviewer_apply.xaxis.timerange = timeArray; + gui_erpxyaxeset_waveviewer.timerange_edit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.xtimerangeauto.Value = 1; + ERPwaviewer_apply.xaxis.trangeauto =1; + %%x ticklable + gui_erpxyaxeset_waveviewer.timeticks_edit.String = char(timeticks);%% xtick label + ERPwaviewer_apply.xaxis.timeticks = str2num(char(timeticks)); + gui_erpxyaxeset_waveviewer.timeticks_edit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.xtimetickauto.Value=1; + ERPwaviewer_apply.xaxis.ticksauto = 1; + %%x precision for x ticklabel + gui_erpxyaxeset_waveviewer.xticks_precision.String = {'0','1','2','3','4','5','6'}; + gui_erpxyaxeset_waveviewer.xticks_precision.Value = 1; + ERPwaviewer_apply.xaxis.tickdecimals = 0; + %%x minor ticks + gui_erpxyaxeset_waveviewer.xtimeminorauto.Value =0; + ERPwaviewer_apply.xaxis.tminor.disp = 0; + stepX = []; + timeArray = str2num(char(gui_erpxyaxeset_waveviewer.timerange_edit.String)); + xticksStr = str2num(char(gui_erpxyaxeset_waveviewer.timeticks_edit.String)); + gui_erpxyaxeset_waveviewer.timeminorticks_custom.String = ''; + gui_erpxyaxeset_waveviewer.timeminorticks_custom.Enable = 'off'; + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Value=1; + gui_erpxyaxeset_waveviewer.timeminorticks_auto.Enable = 'off'; + ERPwaviewer_apply.xaxis.tminor.step =[]; + ERPwaviewer_apply.xaxis.tminor.auto = 1; + %%x label on/off + gui_erpxyaxeset_waveviewer.xtimelabel_on.Value=1; % + gui_erpxyaxeset_waveviewer.xtimelabel_off.Value=0; + ERPwaviewer_apply.xaxis.label =1; + + %%font and font size + ERPwaviewer_apply.xaxis.font =2; + gui_erpxyaxeset_waveviewer.xtimefont_custom.Value=2; + ERPwaviewer_apply.xaxis.fontsize =10; + gui_erpxyaxeset_waveviewer.font_custom_size.Value=4; + fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + gui_erpxyaxeset_waveviewer.yfont_custom.String=fonttype; % + yfontsize={'4','6','8','10','12','14','16','18','20','24','28','32','36',... + '40','50','60','70','80','90','100'}; + gui_erpxyaxeset_waveviewer.font_custom_size.String = yfontsize; + + %%color for x ticklabel + xtextColor = {'Black','Red','Blue','Green','Orange','Cyan','Magenla'}; + gui_erpxyaxeset_waveviewer.xtimetextcolor.String =xtextColor ; + ERPwaviewer_apply.xaxis.fontcolor =1; + %%x units + ERPwaviewer_apply.xaxis.units =1; + gui_erpxyaxeset_waveviewer.xtimeunits_on.Value=1; % + gui_erpxyaxeset_waveviewer.xtimeunits_off.Value=0; % + erpworkingmemory('MyViewer_xaxis_second',0); + erpworkingmemory('MyViewer_xaxis_msecond',1); + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------------Setting for Y axis--------------- + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%y scale + ALLERPIN = ERPwaviewer_apply.ALLERP; + ERPArrayin = ERPwaviewer_apply.SelectERPIdx; + BinArrayIN = []; + ChanArrayIn = []; + plotOrg = [1 2 3]; + try + ChanArrayIn = ERPwaviewer_apply.chan; + catch + ChanArrayIn = []; + end + try + BinArrayIN = ERPwaviewer_apply.bin; + catch + BinArrayIN = []; + end + + PageCurrent = ERPwaviewer_apply.PageIndex; + yylim_out = f_erpAutoYLim(ALLERPIN, ERPArrayin,plotOrg,BinArrayIN, ChanArrayIn); + try + yRangeLabel = num2str(yylim_out(PageCurrent,:)); + catch + yRangeLabel = num2str(yylim_out(1,:)); + end + %%Y range + gui_erpxyaxeset_waveviewer.yrange_edit.String = yRangeLabel; + gui_erpxyaxeset_waveviewer.yrange_edit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.yrangeauto.Value =1; + ERPwaviewer_apply.yaxis.scales = str2num(yRangeLabel); + ERPwaviewer_apply.yaxis.scalesauto = 1; + %%Y tick label + %%y ticks + ytick_precision=1; + yticksLabel = ''; + if ~isempty(str2num(yRangeLabel)) + yticksLabel = default_amp_ticks_viewer(str2num(yRangeLabel)); + yticksLabel= f_decimal(yticksLabel,ytick_precision); + end + gui_erpxyaxeset_waveviewer.yticks_edit.String = yticksLabel; + gui_erpxyaxeset_waveviewer.yticks_edit.Enable = 'off'; + gui_erpxyaxeset_waveviewer.ytickauto.Value =1; + ERPwaviewer_apply.yaxis.ticks = str2num(yticksLabel); + ERPwaviewer_apply.yaxis.tickauto = 1; + gui_erpxyaxeset_waveviewer.yticks_precision.Value=2; + ERPwaviewer_apply.yaxis.tickdecimals=1; + %%Y minor + ERPwaviewer_apply.yaxis.yminor.disp =0; + ERPwaviewer_apply.yaxis.yminor.auto =1; + ERPwaviewer_apply.yaxis.yminor.step = []; + gui_erpxyaxeset_waveviewer.yminortick.Value=0; % + gui_erpxyaxeset_waveviewer.yminorstepedit.String =''; + gui_erpxyaxeset_waveviewer.yminorstepedit.Enable = 'off'; % + gui_erpxyaxeset_waveviewer.yminorstep_auto.Value=1; + gui_erpxyaxeset_waveviewer.yminorstep_auto.Enable ='off'; % + %%Y ticklabel on/off + ERPwaviewer_apply.yaxis.label = 1; + gui_erpxyaxeset_waveviewer.ylabel_on.Value=1; % + gui_erpxyaxeset_waveviewer.ylabel_off.Value=0; + %%font and fontsize + ERPwaviewer_apply.yaxis.font=2; + ERPwaviewer_apply.yaxis.fontsize=10; + gui_erpxyaxeset_waveviewer.yfont_custom.Value=2; + gui_erpxyaxeset_waveviewer.yfont_custom_size.Value=4; + %%color for y ticklabels + ytextColor = {'Black','Red','Blue','Green','Orange','Cyan','Magenla'}; + gui_erpxyaxeset_waveviewer.ytextcolor.String = ytextColor; + gui_erpxyaxeset_waveviewer.ytextcolor.Value=1; + ERPwaviewer_apply.yaxis.fontcolor =1; + %%y units + gui_erpxyaxeset_waveviewer.yunits_on.Value=1; % + gui_erpxyaxeset_waveviewer.yunits_off.Value=0; % + ERPwaviewer_apply.yaxis.units=1; + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + gui_erpxyaxeset_waveviewer.apply.BackgroundColor = [1 1 1]; + gui_erpxyaxeset_waveviewer.apply.ForegroundColor = [0 0 0]; + box_erpxtaxes_viewer_property.TitleColor= [0.5 0.5 0.9]; + viewer_ERPDAT.Reset_Waviewer_panel=4; + end + end%% end of reset for the current panel + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERPsets_waviewer_GUI.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERPsets_waviewer_GUI.m new file mode 100755 index 00000000..9f5e5cc7 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ERPsets_waviewer_GUI.m @@ -0,0 +1,938 @@ +% ERP Viewer for EStudio Toolbox +% +% Author: Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + +% ERPLAB Toolbox +% + +% +% Initial setup +% +function varargout = f_ERPsets_waviewer_GUI(varargin) +% +global viewer_ERPDAT +global observe_ERPDAT; +global gui_erp_waviewer; +addlistener(viewer_ERPDAT,'count_loadproper_change',@count_loadproper_change); +addlistener(viewer_ERPDAT,'count_twopanels_change',@count_twopanels_change); +addlistener(viewer_ERPDAT,'Reset_Waviewer_panel_change',@Reset_Waviewer_panel_change); +addlistener(observe_ERPDAT,'Two_GUI_change',@Two_GUI_change); +ERPwaveview_erpsetops = struct(); +%---------Setting the parameter which will be used in the other panels----------- + +try + [version reldate,ColorBviewer_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; +catch + ColorBviewer_def = [0.7765 0.7294 0.8627]; +end +ERPdatasets = []; % Local data structure +% global ERPsets_waveviewer_box; +if nargin == 0 + fig = figure(); % Parent figure + ERPsets_waveviewer_box = uiextras.BoxPanel('Parent', fig, 'Title', 'ERPsets', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); % Create boxpanel +elseif nargin == 1 + ERPsets_waveviewer_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5,... + 'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w','FontSize', 12); +elseif nargin == 3 || nargin == 2 + ERPsets_waveviewer_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); +elseif nargin == 4 + ERPsets_waveviewer_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5, ... + 'FontSize', varargin{2},'BackgroundColor',ColorBviewer_def,'TitleColor',[0.5 0.5 0.9],'ForegroundColor','w'); + +end +% ERPsets_waveviewer_box.Position(4) = 400; +try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; +catch + return; +end + +ALLERP = ERPwaviewer.ALLERP; +ERPdatasets = getERPDatasets(ALLERP); % Get datasets from ALLERP +ERPdatasets = sortdata(ERPdatasets); +ERPdatasets = sortdata(ERPdatasets); + +%%Get local path +sel_path = cd; +estudioworkingmemory('ERP_save_folder',sel_path); + + +varargout{1} = ERPsets_waveviewer_box; +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end + +drawui_erpsetbinchan_viewer(ERPdatasets,ERPwaviewer,FonsizeDefault) + +% Draw the ui + function drawui_erpsetbinchan_viewer(ERPdatasets,ERPwaviewer,FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef; + catch + ColorBviewer_def = [0.7765 0.7294 0.8627]; + end + try + SelectedIndex = ERPwaviewer.SelectERPIdx; + ALLERP = ERPwaviewer.ALLERP; + if max(SelectedIndex(:))> length(ALLERP) + SelectedIndex =length(ALLERP); + end + catch + beep; + disp('f_ERPsets_waviewer_GUI error: Restart ERPwave Viewer'); + return; + end + + [r, ~] = size(ERPdatasets); % Get size of array of ERPdatasets. r is # of ERPdatasets + % Sort the ERPdatasets!!! + ERPdatasets = sortdata(ERPdatasets); + ERPwaveview_erpsetops.vBox = uiextras.VBox('Parent', ERPsets_waveviewer_box, 'Spacing', 5,'BackgroundColor',ColorBviewer_def); % VBox for everything + ERPtooltype = erpgettoolversion('tooltype'); + if ~strcmpi(ERPtooltype,'EStudio') && ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaviewer.erp_binchan_op = 0; + end + + try + Enable_auto = ERPwaviewer.erp_binchan_op; + catch + Enable_auto = 1; + end + + if Enable_auto ==1 + Enable_label = 'off'; + elseif Enable_auto ==0 + Enable_label = 'on'; + end + + + %%---------------------Options for selecting ERPsets----------------------------------------------------- + ERPwaveview_erpsetops.opts_title = uiextras.HBox('Parent', ERPwaveview_erpsetops.vBox, 'Spacing', 5,'BackgroundColor',ColorBviewer_def); + ERPwaveview_erpsetops.auto = uicontrol('Style', 'radiobutton','Parent', ERPwaveview_erpsetops.opts_title,... + 'String',' ','callback',@erpselect_auto,'Value',Enable_auto,'Enable','on','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); + + ERPwaveview_erpsetops.custom = uicontrol('Style', 'radiobutton','Parent', ERPwaveview_erpsetops.opts_title,... + 'String','Custom','callback',@erpselect_custom,'Value',~Enable_auto,'Enable','on','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); + + if strcmpi(ERPtooltype,'EStudio') + ERPwaveview_erpsetops.auto.String = 'Same as EStudio'; + elseif strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_erpsetops.auto.String = 'Same as ERPLAB'; + set(ERPwaveview_erpsetops.opts_title,'Sizes',[130 90]); + else + ERPwaveview_erpsetops.auto.String = ''; + ERPwaveview_erpsetops.auto.Enable = 'off'; + ERPwaveview_erpsetops.custom.String = ''; + ERPwaveview_erpsetops.custom.Enable = 'off'; + end + + + %%-----------------------Display tthe selected ERPsets--------------------------------------- + panelshbox = uiextras.HBox('Parent', ERPwaveview_erpsetops.vBox, 'Spacing', 5,'BackgroundColor',ColorBviewer_def); + dsnames = {}; + if size(ERPdatasets,1)==1 + if strcmp(ERPdatasets{1},'No ERPset loaded') + dsnames = {''}; + else + dsnames{1} = strcat(num2str(cell2mat(ERPdatasets(1,2))),'.',32,ERPdatasets{1,1}); + end + else + for Numofsub = 1:size(ERPdatasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(ERPdatasets(Numofsub,2))),'.',32,ERPdatasets{Numofsub,1})); + end + end + ds_length = length(ERPdatasets); + ERPwaveview_erpsetops.butttons_datasets = uicontrol('Parent', panelshbox, 'Style', 'listbox', 'min', 1,'max',... + ds_length,'String', dsnames,'Value', SelectedIndex,'Callback',@selectdata,'FontSize',FonsizeDefault,'Enable',Enable_label); + %%Help and apply + ERPwaveview_erpsetops.help_apply_title = uiextras.HBox('Parent', ERPwaveview_erpsetops.vBox,'BackgroundColor',ColorBviewer_def); + uiextras.Empty('Parent',ERPwaveview_erpsetops.help_apply_title ); + uicontrol('Style','pushbutton','Parent', ERPwaveview_erpsetops.help_apply_title ,'String','Cancel',... + 'callback',@erpset_help,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent',ERPwaveview_erpsetops.help_apply_title ); + ERPwaveview_erpsetops.erpset_apply = uicontrol('Style','pushbutton','Parent',ERPwaveview_erpsetops.help_apply_title ,'String','Apply',... + 'callback',@ERPset_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); %,'HorizontalAlignment','left' + uiextras.Empty('Parent',ERPwaveview_erpsetops.help_apply_title ); + set(ERPwaveview_erpsetops.help_apply_title ,'Sizes',[40 70 20 70 20]); + set(ERPwaveview_erpsetops.vBox, 'Sizes', [20 190 25]); + ERPwaveview_erpsetops.ERPLABFlag = 0; + end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%---------------------------------------------- Subfunctions --------------------------------------------%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%-----------------select the ERPset of interest-------------------------- + function selectdata(source,EventData) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=1 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + estudioworkingmemory('MyViewer_ERPsetpanel',1); + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_erpsetops.erpset_apply.ForegroundColor = [1 1 1]; + ERPsets_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + end + + +%%---------------Setting for auto option----------------------------------- + function erpselect_auto(source,~) + + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=1 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + ERPtooltype = erpgettoolversion('tooltype'); + estudioworkingmemory('MyViewer_ERPsetpanel',1); + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_erpsetops.erpset_apply.ForegroundColor = [1 1 1]; + ERPsets_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + + BackERPLABcolor1 = [1 0.9 0.3]; % yellow + question1 = ['Are you sure to use the same ERPsets as',32, ERPtooltype,'?\n If so, the current ERPsets will be overwritten.']; + title1 = 'ERP Wave Viewer>ERPsets'; + oldcolor1 = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor1) + button1 = questdlg(sprintf(question1), title1,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor1); + + MessageViewer= char(strcat('ERPsets>" Same as',32,ERPtooltype,32,'"')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + if strcmpi(ERPtooltype,'EStudio') || strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_erpsetops.auto.Value = 1; + ERPwaveview_erpsetops.custom.Value =0; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'off'; + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + ERPwaveview_erpsetops.auto.Enable = 'off'; + ERPwaveview_erpsetops.custom.Enable = 'off'; + end + + if strcmpi(button1,'Yes') + if strcmpi(ERPtooltype,'EStudio') || strcmpi(ERPtooltype,'ERPLAB') + if strcmpi(ERPtooltype,'ERPLAB') + try + Selected_erpset = evalin('base','CURRENTERP'); + CURRENTERPStudio = Selected_erpset; + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n ERPsets error: Cannot get CURRENTERP from Workspace.\n'); + return; + end + estudioworkingmemory('PlotOrg_ERPLAB',1); + end + try + ALLERPin = evalin('base','ALLERP'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n ERPsets error: Cannot get ALLERP from Workspace.\n'); + return; + end + if isempty(ALLERPin) + viewer_ERPDAT.Process_messg =3; + try + cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + + if strcmpi(ERPtooltype,'EStudio') + Selected_erpset= estudioworkingmemory('selectederpstudio'); + CURRENTERPStudio = observe_ERPDAT.CURRENTERP; + if length(ALLERPin)==1 && strcmpi(ALLERPin(1).erpname,'No ERPset loaded') + try + cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + end + + if isempty(Selected_erpset) || Selected_erpset> length(ALLERPin) + Selected_erpset = length(ALLERPin); + end + if isempty(CURRENTERPStudio) || CURRENTERPStudio> length(ALLERPin) + CURRENTERPStudio = length(ALLERPin); + end + + [x_index,y_index] = find(Selected_erpset==CURRENTERPStudio); + if isempty(y_index) + y_index = numel(Selected_erpset); + end + + ERPwaveview_erpsetops.ALLERP = ALLERPin; + ERPwaveview_erpsetops.ERP = ALLERPin(CURRENTERPStudio); + ERPwaveview_erpsetops.CURRENTERP = CURRENTERPStudio; + ERPwaveview_erpsetops.SelectERPIdx = Selected_erpset; + ERPwaveview_erpsetops.PageIndex = y_index; + ERPwaveview_erpsetops.ERPLABFlag = 1; + ERPdatasets = getERPDatasets(ALLERPin); % Get datasets from ALLERP + ERPdatasets = sortdata(ERPdatasets); + dsnames = {}; + if size(ERPdatasets,1)==1 + if strcmp(ERPdatasets{1},'No ERPset loaded') + dsnames = {''}; + else + dsnames{1} = strcat(num2str(cell2mat(ERPdatasets(1,2))),'.',32,ERPdatasets{1,1}); + end + else + for Numofsub = 1:size(ERPdatasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(ERPdatasets(Numofsub,2))),'.',32,ERPdatasets{Numofsub,1})); + end + end + + ds_length = size(ERPdatasets,1); + if ds_length<=2 + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length+1; + else + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length; + end + ERPwaveview_erpsetops.butttons_datasets.String = dsnames; + ERPwaveview_erpsetops.butttons_datasets.Value = Selected_erpset; + + + MessageViewer= char(strcat('ERPsets>" Same as',32,ERPtooltype,32,'"')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =2; + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + ERPwaveview_erpsetops.auto.Enable = 'off'; + end + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + estudioworkingmemory('MyViewer_ERPsetpanel',0); + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [1 1 1]; + return; + end + end + +%%---------------Setting for custom option--------------------------------- + function erpselect_custom(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=1 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + estudioworkingmemory('MyViewer_ERPsetpanel',1); + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [0.4940 0.1840 0.5560]; + ERPwaveview_erpsetops.erpset_apply.ForegroundColor = [1 1 1]; + ERPsets_waveviewer_box.TitleColor= [0.4940 0.1840 0.5560]; + + ERPtooltype = erpgettoolversion('tooltype'); + if ~strcmpi(ERPtooltype,'EStudio') && ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + ERPwaveview_erpsetops.auto.Enable = 'off'; + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + end + end + + +% called datasets = sortdata(datasets), sorts datasets in order based on +% parents + function varargout = sortdata(data) + cinds = []; + ndata = {}; % Sorted data + it = 1; % Iterator for row + for i = data' % Iterate thru all datasets + if cell2mat(i(3)) == 0 % Find base datasets (child of 0 means it's not reliant on another dataset) + [~, ic] = size(cinds); + cinds(1, ic+1) = cell2mat(i(2)); % Append dataset number to list of current indexes + ndata(it,:) = i'; % Put it in + it = it + 1; + end + end + + cond = true; + while cond + ninds = []; % Reset new indexes + for i = data' % Iterate thru all data + for j = cinds % Iterate thru all parents + if cell2mat(i(3)) == j % Check to see if every datapoint is a child of the current layer + [~, nic] = size(ninds); + ninds(1, nic+1) = cell2mat(i(2)); % Append dataset number to the next round of parents + [ndr, ~] = size(ndata); + for v = 1:ndr + if cell2mat(ndata(v, 2)) == j + ndata(v+2:end+1,:) = ndata(v+1:end,:); + ndata(v+1,:) = i'; + end + end + end + end + end + [~, nic] = size(ninds); + if nic == 0 % If we've gone thru all of them, there should be no new indexes + cond = false; + end + clear cinds + cinds = ninds; % Start again with ninds + end + varargout{1} = ndata; + end + + +%----------------------Get the information of the updated ERPsets---------- + function ERPdatasets = getERPDatasets(ALLERP) + ERPdatasets = {}; + if isempty(ALLERP) + beep; + disp('f_ERPsets_waveviewer_GUI>getERPDatasets error: ALLERP is empty.'); + return; + end + for Numoferpset = 1:length(ALLERP) + ERPdatasets{Numoferpset,1} = ALLERP(Numoferpset).erpname; + ERPdatasets{Numoferpset,2} = Numoferpset; + ERPdatasets{Numoferpset,3} = 0; + ERPdatasets{Numoferpset,4} = ALLERP(Numoferpset).filename; + ERPdatasets{Numoferpset,5} = ALLERP(Numoferpset).filepath; + end + end + + +%%-------------------------------Help-------------------------------------- + function erpset_help(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=1 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + changeFlag = estudioworkingmemory('MyViewer_ERPsetpanel'); + if changeFlag~=1 + return; + end + + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n ERPsets > Cancel-f_ERPsets_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + ERPwaveview_erpsetops.ERPLABFlag=0; + + ERP_OP = ERPwaviewer_apply.erp_binchan_op; + if ERP_OP ==1 + ERPwaveview_erpsetops.auto.Value = 1; + ERPwaveview_erpsetops.custom.Value =0; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'off'; + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + end + + ALLERPin = ERPwaviewer_apply.ALLERP; + ERPdatasets = getERPDatasets(ALLERPin); % Get datasets from ALLERP + ERPdatasets = sortdata(ERPdatasets); + dsnames = {}; + if size(ERPdatasets,1)==1 + if strcmp(ERPdatasets{1},'No ERPset loaded') + dsnames = {''}; + else + dsnames{1} = strcat(num2str(cell2mat(ERPdatasets(1,2))),'.',32,ERPdatasets{1,1}); + end + else + for Numofsub = 1:size(ERPdatasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(ERPdatasets(Numofsub,2))),'.',32,ERPdatasets{Numofsub,1})); + end + end + + ds_length = size(ERPdatasets,1); + if ds_length<=2 + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length+1; + else + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length; + end + ERPwaveview_erpsetops.butttons_datasets.String = dsnames; + Selected_erpset = ERPwaviewer_apply.SelectERPIdx; + if min(Selected_erpset(:))<=0 || max(Selected_erpset(:)) > length(ALLERPin) + Selected_erpset = length(ALLERPin); + ERPwaviewer_apply.SelectERPIdx = Selected_erpset; + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + f_redrawERP_viewer_test();%%Plot the waves + end + ERPwaveview_erpsetops.butttons_datasets.Value = Selected_erpset; + + estudioworkingmemory('MyViewer_ERPsetpanel',0); + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [1 1 1]; + ERPwaveview_erpsetops.erpset_apply.ForegroundColor = [0 0 0]; + ERPsets_waveviewer_box.TitleColor= [0.5 0.5 0.9]; + end + +%%------------------------------Apply-------------------------------------- + function ERPset_apply(~,~) + [messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); + if ~isempty(messgStr) && viewerpanelIndex~=1 + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; + end + + MessageViewer= char(strcat('ERPsets > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n ERPsets > Apply-f_ERPsets_waviewer_GUI() error: Cannot get parameters for whole panel.\n Please run My viewer again.\n\n'); + return; + end + if ERPwaveview_erpsetops.ERPLABFlag==1 + ERPwaviewer_apply.ALLERP = ERPwaveview_erpsetops.ALLERP; + ERPwaviewer_apply.ERP = ERPwaveview_erpsetops.ERP; + ERPwaviewer_apply.CURRENTERP= ERPwaveview_erpsetops.CURRENTERP; + ERPwaviewer_apply.SelectERPIdx= ERPwaveview_erpsetops.SelectERPIdx; + ERPwaviewer_apply.PageIndex= ERPwaveview_erpsetops.PageIndex; + ERPwaveview_erpsetops.ERPLABFlag=0; + end + ERPsetArray = ERPwaveview_erpsetops.butttons_datasets.Value; + CurrentERP = ERPsetArray(1); + ALLERPIN = ERPwaviewer_apply.ALLERP; + for Numofselectederp = 1:numel(ERPsetArray) + SrateNum_mp(Numofselectederp,1) = ALLERPIN(ERPsetArray(Numofselectederp)).srate; + end + % if numel(unique(SrateNum_mp))>1 + % MessageViewer= char(strcat('Sampling rate varies across the selected ERPsets, we therefore set "ERPsets" to be "Pages".')); + % erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + % viewer_ERPDAT.Process_messg =4; + % %% + % MessageViewer= char(strcat('ERPsets > Apply')); + % erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + % end + + ERPwaviewer_apply.CURRENTERP = CurrentERP; + ERPwaviewer_apply.ERP = ERPwaviewer_apply.ALLERP(CurrentERP); + ERPwaviewer_apply.SelectERPIdx = ERPsetArray; + ERPwaviewer_apply.erp_binchan_op = ERPwaveview_erpsetops.auto.Value; + + if ERPwaveview_erpsetops.auto.Value ==1 + Geterpbinchan = estudioworkingmemory('geterpbinchan'); + CurrentERPIndex = Geterpbinchan.Select_index; + chan_bin = Geterpbinchan.bins_chans(CurrentERPIndex); + if chan_bin ==1 + ERPwaviewer_apply.plot_org.Grid =2; + ERPwaviewer_apply.plot_org.Overlay=1; + ERPwaviewer_apply.plot_org.Pages=3; + elseif chan_bin==0 + ERPwaviewer_apply.plot_org.Grid =1; + ERPwaviewer_apply.plot_org.Overlay=2; + ERPwaviewer_apply.plot_org.Pages=3; + end + %%% we may need to get the grid layout automatically + end + + estudioworkingmemory('MyViewer_ERPsetpanel',0); + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [1 1 1]; + ERPwaveview_erpsetops.erpset_apply.ForegroundColor = [0 0 0]; + ERPsets_waveviewer_box.TitleColor= [0.5 0.5 0.9]; + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + viewer_ERPDAT.Count_currentERP = viewer_ERPDAT.Count_currentERP+1; + f_redrawERP_viewer_test();%%Plot the waves + MessageViewer= char(strcat('ERPsets > Apply')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =2; + end + + +%%------------Update this panel based on the imported parameters----------- + function count_loadproper_change(~,~) + if viewer_ERPDAT.count_loadproper ==0 + return; + end + try + ERPwaviewer_up = evalin('base','ALLERPwaviewer'); + SelectedIndex = ERPwaviewer_up.SelectERPIdx; + ALLERPup = ERPwaviewer_up.ALLERP; + if isempty(ALLERPup) + beep; + disp('f_ERPsets_waviewer_GUI()>count_loadproper_change() error: ALLERP is empty.'); + return; + end + if max(SelectedIndex(:))> length(ALLERPup) + SelectedIndex =length(ALLERPup); + ERPwaviewer_up.SelectERPIdx = SelectedIndex; + end + catch + beep; + disp('f_ERPsets_waviewer_GUI()>count_loadproper_change() error: Restart ERPwave Viewer'); + return; + end + + ERPtooltype = erpgettoolversion('tooltype'); + if isempty(ERPtooltype) + ERPtooltype = 'MyViewer'; + erpgettoolversion('tooltype','MyViewer'); + end + if ~strcmpi(ERPtooltype,'EStudio') && ~strcmpi(ERPtooltype,'ERPLAB') + ERPwaviewer_up.erp_binchan_op = 0; + end + try + Enable_auto = ERPwaviewer_up.erp_binchan_op; + catch + Enable_auto = 1; + ERPwaviewer_up.erp_binchan_op = 1; + end + if Enable_auto ==1 + Enable_label = 'off'; + elseif Enable_auto ==0 + Enable_label = 'on'; + end + ERPwaveview_erpsetops.auto.Value = Enable_auto; + ERPwaveview_erpsetops.custom.Value=~Enable_auto; + ERPdatasets = getERPDatasets(ALLERPup); % Get datasets from ALLERP + ERPdatasets = sortdata(ERPdatasets); + dsnames = {}; + if size(ERPdatasets,1)==1 + if strcmp(ERPdatasets{1},'No ERPset loaded') + dsnames = {''}; + else + dsnames{1} = strcat(num2str(cell2mat(ERPdatasets(1,2))),'.',32,ERPdatasets{1,1}); + end + else + for Numofsub = 1:size(ERPdatasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(ERPdatasets(Numofsub,2))),'.',32,ERPdatasets{Numofsub,1})); + end + end + + ERPwaveview_erpsetops.butttons_datasets.Enable = Enable_label; + ds_length = length(ERPdatasets); + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length; + ERPwaveview_erpsetops.butttons_datasets.String = dsnames; + ERPwaveview_erpsetops.butttons_datasets.Value = SelectedIndex; + if strcmpi(ERPtooltype,'EStudio') + ERPwaveview_erpsetops.auto.String = 'Same as EStudio'; + elseif strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_erpsetops.auto.String = 'Same as ERPLAB'; + else + ERPwaveview_erpsetops.auto.String = ''; + ERPwaveview_erpsetops.auto.Enable = 'off'; + ERPwaveview_erpsetops.custom.String = ''; + ERPwaveview_erpsetops.custom.Enable = 'off'; + end + assignin('base','ALLERPwaviewer',ERPwaviewer_up); + end + + + +%%change this panel based on the chaneges of main EStudio + function Two_GUI_change(~,~) + ERPtooltype = erpgettoolversion('tooltype'); + if observe_ERPDAT.Two_GUI~=1 + return; + end + + if isempty(observe_ERPDAT.ALLERP) + try + close(gui_erp_waviewer.Window);%%close previous GUI if exists + catch + end + return; + end + ALLERPNew = observe_ERPDAT.ALLERP; + %%checking datatype + counterp = 0; + datatypeFlag = []; + for Numoferpset = 1:length(ALLERPNew) + if ~strcmpi(ALLERPNew(Numoferpset).datatype, 'ERP') && ~strcmpi(ALLERPNew(Numoferpset).datatype, 'CSD') + counterp = counterp+1; + datatypeFlag(counterp) = Numoferpset; + end + end + if ~isempty(datatypeFlag) + msgboxText = ['ERP Wave Viewer donot support to plot the wave for the data that donot belong to "ERP" or "CSD".\n'... + 'Please remove the following ERPset with index(es):',32,num2str(datatypeFlag),'.']; + if strcmpi(ERPtooltype,'ERPLAB') + title_msg = 'ERPLAB: ERPLAB_ERP_Viewer() datatype error:'; + elseif strcmpi(ERPtooltype,'EStudio') + title_msg = 'EStudio: ERPLAB_ERP_Viewer() datatype error:'; + else + title_msg = ' ERPLAB_ERP_Viewer() datatype error:'; + end + errorfound(sprintf(msgboxText), title_msg); + return; + end + + try + ERPAutoValue = ERPwaveview_erpsetops.auto.Value; + catch + return; + end + + if isempty(observe_ERPDAT.ALLERP) + try + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + MessageViewer= char(strcat('Update "ERP wave Viewer"')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + + %%check ALLERP for EStudio + if strcmpi(ERPtooltype,'EStudio') + if (length(ALLERPStudio)==1&& strcmpi(ALLERPStudio(1).erpname,'No ERPset loaded')) || strcmpi(ALLERPStudio(length(ALLERPStudio)).erpname,'No ERPset loaded') + try + % cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + end + try + ERPwaviewer_up = evalin('base','ALLERPwaviewer'); + catch + beep; + disp('f_ERPsets_waviewer_GUI() error: Restart ERPwave Viewer'); + return; + end + if ERPAutoValue ==1 + if strcmpi(ERPtooltype,'ERPLAB') + ERPArrayStudio= observe_ERPDAT.CURRENTERP; + elseif strcmpi(ERPtooltype,'EStudio') + ERPArrayStudio= estudioworkingmemory('selectederpstudio'); + else + ERPArrayStudio= observe_ERPDAT.CURRENTERP; + end + CURRENTERPStudio = observe_ERPDAT.CURRENTERP; + estudioworkingmemory('PlotOrg_ERPLAB',1);%%This is used to Grid, Overlay, and Pages if "same as ERPLAB" + + end + + % else + if ERPAutoValue ~=1 + ERPArrayStudio = ERPwaviewer_up.SelectERPIdx; + CURRENTERPStudio=ERPwaviewer_up.CURRENTERP; + % ALLERPStudio = evalin('base','ALLERP'); + end + ALLERPStudio = observe_ERPDAT.ALLERP; + if max(ERPArrayStudio(:))> length(ALLERPStudio) || min(ERPArrayStudio(:))<=0 + ERPArrayStudio = length(ALLERPStudio); + CURRENTERPStudio = length(ALLERPStudio); + end + [x_index,y_index] = find(ERPArrayStudio==CURRENTERPStudio); + if isempty(y_index) + y_index = numel(ERPArrayStudio); + end + + ERPwaviewer_up.ALLERP = ALLERPStudio; + ERPwaviewer_up.ERP = ALLERPStudio(CURRENTERPStudio); + ERPwaviewer_up.CURRENTERP = CURRENTERPStudio; + ERPwaviewer_up.SelectERPIdx = ERPArrayStudio; + ERPwaviewer_up.PageIndex = y_index; + ERPdatasets = getERPDatasets(ALLERPStudio); % Get datasets from ALLERP + ERPdatasets = sortdata(ERPdatasets); + dsnames = {}; + if size(ERPdatasets,1)==1 + if strcmp(ERPdatasets{1},'No ERPset loaded') + dsnames = {''}; + else + dsnames{1} = strcat(num2str(cell2mat(ERPdatasets(1,2))),'.',32,ERPdatasets{1,1}); + end + else + for Numofsub = 1:size(ERPdatasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(ERPdatasets(Numofsub,2))),'.',32,ERPdatasets{Numofsub,1})); + end + end + + % ERPwaveview_erpsetops.butttons_datasets.Enable = Enable_label; + ds_length = length(ERPdatasets); + if ds_length<=2 + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length+1; + else + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length; + end + ERPwaveview_erpsetops.butttons_datasets.String = dsnames; + ERPwaveview_erpsetops.butttons_datasets.Value = ERPArrayStudio; + + if strcmpi(ERPtooltype,'ERPLAB') && ERPAutoValue ==1 + % ERPwaviewer_up.bin= [1:observe_ERPDAT.ERP.nbin]; + % ERPwaviewer_up.chan = [1:observe_ERPDAT.ERP.nchan]; + ERPwaviewer_up.PageIndex = 1; + end + + assignin('base','ALLERPwaviewer',ERPwaviewer_up); + viewer_ERPDAT.Count_currentERP = viewer_ERPDAT.Count_currentERP+1; + f_redrawERP_viewer_test();%%Plot the waves + + MessageViewer= char(strcat('Update "ERP wave Viewer"')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =2; + observe_ERPDAT.Two_GUI =2; + end + +%%------------------------------------------------------------------------- +%%Automatically saving the changed parameters for the current panel if the +%%user change parameters for the other panels. +%%------------------------------------------------------------------------- + function count_twopanels_change(~,~) + if viewer_ERPDAT.count_twopanels==0 + return; + end + changeFlag = estudioworkingmemory('MyViewer_ERPsetpanel'); + if changeFlag~=1 + return; + end + ERPset_apply(); + end + + +%%Reset this panel with the default parameters + function Reset_Waviewer_panel_change(~,~) + if viewer_ERPDAT.Reset_Waviewer_panel==1 + ERPtooltype = erpgettoolversion('tooltype'); + if strcmpi(ERPtooltype,'EStudio') || strcmpi(ERPtooltype,'ERPLAB') + ERPwaveview_erpsetops.auto.Value = 1; + ERPwaveview_erpsetops.custom.Value =0; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'off'; + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + ERPwaveview_erpsetops.auto.Enable = 'off'; + ERPwaveview_erpsetops.custom.Enable = 'off'; + end + if strcmpi(ERPtooltype,'EStudio') || strcmpi(ERPtooltype,'ERPLAB') + if strcmpi(ERPtooltype,'ERPLAB') + try + Selected_erpset = evalin('base','CURRENTERP'); + CURRENTERPStudio = Selected_erpset; + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n ERPsets error: Cannot get CURRENTERP from Workspace.\n'); + return; + end + estudioworkingmemory('PlotOrg_ERPLAB',1); + end + try + ALLERPin = evalin('base','ALLERP'); + catch + viewer_ERPDAT.Process_messg =3; + fprintf(2,'\n ERPsets error: Cannot get ALLERP from Workspace.\n'); + return; + end + if isempty(ALLERPin) + viewer_ERPDAT.Process_messg =3; + try + cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + + if strcmpi(ERPtooltype,'EStudio') + Selected_erpset= estudioworkingmemory('selectederpstudio'); + CURRENTERPStudio = observe_ERPDAT.CURRENTERP; + if length(ALLERPin)==1 && strcmpi(ALLERPin(1).erpname,'No ERPset loaded') + try + cprintf('red',['\n ERP Wave viewer will be closed because ALLERP is empty.\n\n']); + close(gui_erp_waviewer.Window); + catch + end + assignin('base','ALLERPwaviewer',[]); + return; + end + end + + if isempty(Selected_erpset) || Selected_erpset> length(ALLERPin) + Selected_erpset = length(ALLERPin); + end + if isempty(CURRENTERPStudio) || CURRENTERPStudio> length(ALLERPin) + CURRENTERPStudio = length(ALLERPin); + end + + [x_index,y_index] = find(Selected_erpset==CURRENTERPStudio); + if isempty(y_index) + y_index = numel(Selected_erpset); + end + + ERPwaveview_erpsetops.ALLERP = ALLERPin; + ERPwaveview_erpsetops.ERP = ALLERPin(CURRENTERPStudio); + ERPwaveview_erpsetops.CURRENTERP = CURRENTERPStudio; + ERPwaveview_erpsetops.SelectERPIdx = Selected_erpset; + ERPwaveview_erpsetops.PageIndex = y_index; + ERPwaveview_erpsetops.ERPLABFlag = 1; + + ERPdatasets = getERPDatasets(ALLERPin); % Get datasets from ALLERP + ERPdatasets = sortdata(ERPdatasets); + dsnames = {}; + if size(ERPdatasets,1)==1 + if strcmp(ERPdatasets{1},'No ERPset loaded') + dsnames = {''}; + else + dsnames{1} = strcat(num2str(cell2mat(ERPdatasets(1,2))),'.',32,ERPdatasets{1,1}); + end + else + for Numofsub = 1:size(ERPdatasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(ERPdatasets(Numofsub,2))),'.',32,ERPdatasets{Numofsub,1})); + end + end + + ds_length = size(ERPdatasets,1); + if ds_length<=2 + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length+1; + else + ERPwaveview_erpsetops.butttons_datasets.Max = ds_length; + end + ERPwaveview_erpsetops.butttons_datasets.String = dsnames; + ERPwaveview_erpsetops.butttons_datasets.Value = Selected_erpset; + else + ERPwaveview_erpsetops.auto.Value = 0; + ERPwaveview_erpsetops.custom.Value =1; + ERPwaveview_erpsetops.butttons_datasets.Enable = 'on'; + ERPwaveview_erpsetops.auto.Enable = 'off'; + end + try + ERPwaviewer_apply = evalin('base','ALLERPwaviewer'); + catch + ERPwaviewer_apply = []; + end + ERPwaviewer_apply.ALLERP = ERPwaveview_erpsetops.ALLERP; + ERPwaviewer_apply.ERP = ERPwaveview_erpsetops.ERP; + ERPwaviewer_apply.CURRENTERP= ERPwaveview_erpsetops.CURRENTERP; + ERPwaviewer_apply.SelectERPIdx= ERPwaveview_erpsetops.SelectERPIdx; + ERPwaviewer_apply.PageIndex= ERPwaveview_erpsetops.PageIndex; + ERPwaviewer_apply.erp_binchan_op = ERPwaveview_erpsetops.auto.Value; + ERPwaveview_erpsetops.erpset_apply.BackgroundColor = [1 1 1]; + ERPwaveview_erpsetops.erpset_apply.ForegroundColor = [0 0 0]; + ERPsets_waveviewer_box.TitleColor= [0.5 0.5 0.9]; + + assignin('base','ALLERPwaviewer',ERPwaviewer_apply); + viewer_ERPDAT.Reset_Waviewer_panel=2; + end + end + + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustbindtabasedtimedefd.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustbindtabasedtimedefd.m new file mode 100755 index 00000000..a2beffce --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustbindtabasedtimedefd.m @@ -0,0 +1,177 @@ + +%%ERPbindata contains the values for each point and it should be is column +%%vector. e.g., ERPbindata = [1 2 4 5 3 2 5 6 3 2 5 6 6 ....] + + +%%Time indexes for each time point e.g., timesrange = +%%[-199.21875,-195.3125,-191.40625,-187.5,-183.59375,-179.6875,-175.78125,-171.875,-167.96875,....] +%%if sampling rate is 256 + +%%time window which is to display the ERPwave, e.g., timew: [-100 700] + + +%%fs sampling rate of the data, e.g., fs =256 + + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function [Xtimerange, bindata] = f_adjustbindtabasedtimedefd(ERPbindata, timesrange,timew,fs) + +Xtimerange = []; +bindata = []; +if nargin<1 + help f_adjustbindtabasedtimedefd; + return; +end + +if nargin<2 + + return; +end + +if numel(unique(timesrange)) ==1 + return; +end + +if timesrange(1)>= timesrange(end) + return; +end + + + +if nargin<3 + timew(1)=timerange(1); + timew(2)=timerange(numel(timerange)); +end +if isempty(timew) || numel(unique(timew))~=2 + timew(1)=timerange(1); + timew(2)=timerange(numel(timerange)); +end + +if nargin<4 + fs = ceil(1000/(timesrange(2)-timesrange(1))); +end + +deffs = ceil(1000/(timesrange(2)-timesrange(1))); + +if deffs~=fs + disp('The defined sampling rate dosenot match with the inputed "timesrange"'); + return; +end + +if numel(timew) ==1 + beep; + disp('"timew" has two elements!!!'); + return; +end + +if timew(1)>= timew(2) + return; +end + +ERPbindata = reshape(ERPbindata,1,[]);%% reshape the data into a column vector +if numel(ERPbindata) ~=numel(timesrange) + beep; + disp('The number of time points for the inputed data doesnot match with "timesrange"'); + return; +end + +time_bin = 1000/fs; + +% [xxx, latsamp, latdiffms] = closest(ERP.times, timerange); +% time_range_times = ERP.times(latsamp(1):latsamp(2)); + + +if (timew(1)< timesrange(1)) && (timew(2)<= timesrange(end)) %% case 1 + [xxx, latsamp, latdiffms] = closest(timesrange, timew); + Xtimerange = timesrange(latsamp(1):latsamp(2)); + for ii = 1:1000000 + Xtimerange_first = Xtimerange(1)-time_bin; + if timew(1) <= Xtimerange_first + Xtimerange = [Xtimerange_first,Xtimerange]; + else + break; + end + end + +elseif (timew(1)< timesrange(1)) && (timew(2)> timesrange(end))%% case 2 + Xtimerange = timesrange; + for ii = 1:1000000% loop for the left edge + Xtimerange_first = Xtimerange(1)-time_bin; + if timew(1) <= Xtimerange_first + Xtimerange = [Xtimerange_first,Xtimerange]; + else + break; + end + end + for ii = 1:1000000%Loop for the right edge + Xtimerange_last = Xtimerange(end)+time_bin; + if timew(2) >= Xtimerange_last + Xtimerange = [Xtimerange,Xtimerange_last]; + else + break; + end + end + +elseif (timew(1)>= timesrange(1)) && (timew(2)> timesrange(end))%% case 3 + + [xxx, latsamp, latdiffms] = closest(timesrange, [timew(1) timesrange(end)]); + Xtimerange = timesrange(latsamp(1):latsamp(2)); + + for ii = 1:1000000%Loop for the right edge + Xtimerange_last = Xtimerange(end)+time_bin; + if timew(2) >= Xtimerange_last + Xtimerange = [Xtimerange,Xtimerange_last]; + else + break; + end + end + +elseif (timew(1)>= timesrange(1)) && (timew(2)<= timesrange(end))%%case 4: if the xtick range is within the defined time range + [xxx, latsamp, latdiffms] = closest(timesrange, timew); + Xtimerange = timesrange(latsamp(1):latsamp(2)); +end + +if abs(Xtimerange(1))>abs(timew(1))%%check the first element + Xtimerange(1) = []; +end + +if abs(Xtimerange(end))>abs(timew(2))%% check the last element + Xtimerange(end) = []; +end + +%%------------------------Adjust the data based on the xtick time range------------------------- +bindata = nan(1,numel(Xtimerange)); + +if (timew(1)< timesrange(1)) && (timew(2)<= timesrange(end)) %% case 1 + [xxx, latsamp_xtick, latdiffms] = closest(Xtimerange,[timesrange(1),Xtimerange(end)]); + + [xxx, latsamp_time, latdiffms] = closest(timesrange,[timesrange(1),Xtimerange(end)]); + bindata(1,latsamp_xtick(1):latsamp_xtick(2)) = ERPbindata(1,latsamp_time(1):latsamp_time(2)); + +elseif (timew(1)< timesrange(1)) && (timew(2)> timesrange(end))%% case 2 + [xxx, latsamp_xtick, latdiffms] = closest(Xtimerange,[timesrange(1),timesrange(end)]); + bindata(1,latsamp_xtick(1):latsamp_xtick(2)) = ERPbindata; + +elseif (timew(1)>= timesrange(1)) && (timew(2)> timesrange(end))%% case 3 + [xxx, latsamp_xtick, latdiffms] = closest(Xtimerange,[Xtimerange(1),timesrange(end)]); + [xxx, latsamp_time, latdiffms] = closest(timesrange,[Xtimerange(1),timesrange(end)]); + + if numel(latsamp_xtick(1):latsamp_xtick(2)) -numel(latsamp_time(1):latsamp_time(2)) ==1 + latsamp_xtick(2) = latsamp_xtick(2)-1; + end + bindata(1,latsamp_xtick(1):latsamp_xtick(2)) = ERPbindata(1,latsamp_time(1):latsamp_time(2)); +elseif (timew(1)>= timesrange(1)) && (timew(2)<= timesrange(end))%%case 4: if the xtick range is within the defined time range + [xxx, latsamp, latdiffms] = closest(timesrange, [Xtimerange(1),Xtimerange(end)]); + bindata= ERPbindata(1,latsamp(1):latsamp(2)); +end +end + + + diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustdata_xyrange_xyticks.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustdata_xyrange_xyticks.m new file mode 100755 index 00000000..46bc44f5 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustdata_xyrange_xyticks.m @@ -0,0 +1,41 @@ +%%This function is to compute the specific time-range for xth columns for +%%GAP setting + + + + +function [bindatadjust,Xtimerangeadjust,Xticksadjust] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,offset,NumColumns,PosIndexs,stepX,fs) + +bindatadjust = []; +Xtimerangeadjust = []; +Xticksadjust = []; + +if isempty(stepX) + stepX = ceil(Xtimerange(end)-Xtimerange(1)); +end + +timebin = 1000/fs; +Timet_step_p = ceil(stepX/(1000/fs)); + + + +%%if the number of columns is 1 +if NumColumns==1 + bindatadjust = bindatatrs+offset(PosIndexs(1)); + Xtimerangeadjust = Xtimerange; + Xticksadjust = qXticks; + return; +end +try + ColumnNums = PosIndexs(2); +catch + ColumnNums =1; +end +RowNums = PosIndexs(1); +%%if the number of columns is larger than 1. +bindatadjust = bindatatrs+offset(PosIndexs(1)); +Xtimerangeadjust = NaN(1,numel(Xtimerange)); +TimeAdjust = (ColumnNums-1)*(numel(Xtimerange)+Timet_step_p)*timebin; +Xtimerangeadjust = Xtimerange+TimeAdjust; +Xticksadjust = qXticks+TimeAdjust; +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustdata_xyrange_xyticks_overlay.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustdata_xyrange_xyticks_overlay.m new file mode 100755 index 00000000..aeef98d0 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_adjustdata_xyrange_xyticks_overlay.m @@ -0,0 +1,56 @@ +%%This function is to compute the specific time-range for xth columns for +%%Overlay setting + + + + +function [bindatadjust,Xtimerangeadjust,Xticksadjust,TimeAdjustOut,XtimerangeadjustALL] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,offset,NumColumns,PosIndexs,stepXP) + +bindatadjust = []; +Xtimerangeadjust = []; +Xticksadjust = []; +TimeAdjustOut = 0; +XtimerangeadjustALL = []; +if isempty(stepXP) + stepXP = ceil(numel(Xtimerange)*0.4); +end + +timebin = unique(diff(Xtimerange)); + + +try + ColumnNums = PosIndexs(2); +catch + ColumnNums =1; +end + +%%if the number of columns is 1 +if NumColumns==1 || ColumnNums==1 + bindatadjust = bindatatrs+offset(PosIndexs(1)); + Xtimerangeadjust = Xtimerange; + Xticksadjust = qXticks; + TimeAdjustOut = 0; + XtimerangeadjustALL =Xtimerange ; + return; +end + +Xtimerangeadjust = NaN(1,numel(Xtimerange)); +%%if the number of columns is larger than 1. +if ColumnNums>1 + timeRangeAll(1,:) = Xtimerange; + Xticksadjustall(1,:)=qXticks; + TimeAdjustALL(1) = 0; + for ii = 2:NumColumns + TimeAdjust = (numel(Xtimerange)-stepXP)*timebin;%%need to modify this based on the percentage of Overlay + Xtimerangeadjust1 = timeRangeAll(ii-1,:)+TimeAdjust; + timeRangeAll(ii,:) = Xtimerangeadjust1; + Xticksadjustall(ii,:)=Xticksadjustall(ii-1,:)+TimeAdjust; + TimeAdjustALL(ii) = Xticksadjustall(ii,1)-Xticksadjustall(1,1); + end + bindatadjust = bindatatrs+offset(PosIndexs(1)); + Xtimerangeadjust = timeRangeAll(ColumnNums,:); + Xticksadjust = Xticksadjustall(ColumnNums,:); + TimeAdjustOut = TimeAdjustALL(ColumnNums); + XtimerangeadjustALL = timeRangeAll; +end +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_check_erpviewerpanelchanges.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_check_erpviewerpanelchanges.m new file mode 100644 index 00000000..d0b826a3 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_check_erpviewerpanelchanges.m @@ -0,0 +1,53 @@ +function [messgStr,viewerpanelIndex ]= f_check_erpviewerpanelchanges() + +messgStr = ''; +viewerpanelIndex = 0; + + +MyViewer_ERPset = estudioworkingmemory('MyViewer_ERPsetpanel'); +if ~isempty(MyViewer_ERPset) && MyViewer_ERPset==1 + messgStr = char( 'Changes on "ERPsets" have not been applied'); + viewerpanelIndex =1; +end + + +MyViewer_chanbin = estudioworkingmemory('MyViewer_chanbin'); +if ~isempty(MyViewer_ERPset) && MyViewer_chanbin==1 + messgStr = char( 'Changes on "Channels and Bins" have not been applied'); + viewerpanelIndex =2; +end + + +MyViewer_xyaxis = estudioworkingmemory('MyViewer_xyaxis'); +if ~isempty(MyViewer_ERPset) && MyViewer_xyaxis==1 + messgStr = char( 'Changes on "Time and Amplitude Scales" have not been applied'); + viewerpanelIndex =3; +end + + +MyViewer_plotorg = estudioworkingmemory('MyViewer_plotorg'); +if ~isempty(MyViewer_ERPset) && MyViewer_plotorg==1 + messgStr = char( 'Changes on "Plot Organization" have not been applied'); + viewerpanelIndex =4; +end + +MyViewer_labels = estudioworkingmemory('MyViewer_labels'); +if ~isempty(MyViewer_ERPset) && MyViewer_labels==1 + messgStr = char( 'Changes on "Chan/Bin/ERPset Labels" have not been applied'); + viewerpanelIndex =5; +end + +MyViewer_linelegend = estudioworkingmemory('MyViewer_linelegend'); +if ~isempty(MyViewer_ERPset) && MyViewer_linelegend==1 + messgStr = char( 'Changes on "Lines & legends" have not been applied'); + viewerpanelIndex =6; +end + + +MyViewer_other = estudioworkingmemory('MyViewer_other'); +if ~isempty(MyViewer_ERPset) && MyViewer_other==1 + messgStr = char( 'Changes on "Other" have not been applied'); + viewerpanelIndex =7; +end + +return; diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_decimal.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_decimal.m new file mode 100644 index 00000000..de5f60b6 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_decimal.m @@ -0,0 +1,38 @@ + + +function [yticksLabel, msgboxText]= f_decimal(yticksLabel,ytick_precision) + +msgboxText = ''; + +if nargin<1 + help f_decimal; + return; +end + +if isnumeric(yticksLabel) + yticksLabel = num2str(yticksLabel); +end + +if nargin<2 + ytick_precision=0; +end + +yticksLabel = char(yticksLabel); + +if isempty(str2num(yticksLabel)) + yticksLabel = ''; +else + if ~isempty(str2num(yticksLabel)) && numel((str2num(yticksLabel)))==1 + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + else + yticksnumbel = str2num(yticksLabel); + yticksLabel = sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(1)); + for Numofnum = 1:numel(yticksnumbel)-1 + yticksLabel = [yticksLabel,32,sprintf(['%.',num2str(ytick_precision),'f'],yticksnumbel(Numofnum+1))]; + end + end +end + + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_erpAutoYLim.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_erpAutoYLim.m new file mode 100755 index 00000000..dffa58be --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_erpAutoYLim.m @@ -0,0 +1,238 @@ + +% PURPOSE: subroutine for ploterpGUI.m +% identifies minimum and maximum values of ERP amplitudes for Y scaling for the selected single ERP or multi-ERPsets. +% +% FORMAT +% +% [yylim, serror] = erpAutoYLim(ALLERP,ERPsetArray, binArray, chanArray, xxlim) +% + +% INPUTS +% +% ALLERP - ALLERPset +% ERPsetArray - indices of the seleted ERPsets +% binArray - indices of bins from where to get the amplitude values +% chanArray - indices of channels from where to get the amplitude values +% xxlim - current scale for time ([min max] in ms) +% orgpar - plot orginization including three elements: [Grid,Overlay,Pages]; Each element is equal to any of 1,2, and 3. +% "1" is "Channel", "2" is "Bin", and "3" is "ERPset". +% +% OUTPUT +% +% yylim - range for Y scale +% serror - error flag. 0 means no errors. +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + + +function [yylim_out, serror] = f_erpAutoYLim(ALLERP, ERPsetArray,orgpar,binArray, chanArray,CurrentERPIndex, xxlim,blcorrdata) + +yylim_out = []; + +serror = 0; +if nargin<2 + beep; + error('f_erpAutoYLim needs 2 input arguments at least.'); + return; +end +if isempty(ALLERP) + beep; + error('f_erpAutoYLim() error: ALLERP is empty.'); + return; +end + + +if isempty(ERPsetArray) + beep; + error('f_erpAutoYLim() error: Indices of the seleted ERPsets are empty.'); + return; +end + + + +if max(ERPsetArray) >length(ALLERP) + beep; + error('f_erpAutoYLim() error: One of indices of the seleted ERPsets is larger than the length of ALLERP.'); + return; +end + +if min(ERPsetArray) <=0 + beep; + error('f_erpAutoYLim() error: Indices of the seleted ERPsets should be positive values.'); + return; +end + +if nargin<8 + blcorrdata = 'no'; +end + + +if nargin<7 + xxlim = []; +end +if nargin< 6 || (CurrentERPIndex > length(ERPsetArray)) || (CurrentERPIndex <=0) + CurrentERPIndex = length(ERPsetArray); +end +if nargin<5 + chanArray = []; +end + +if nargin<4 + binArray = []; +end + +if nargin<3 + orgpar = [1 2 3];%%It means that Channel will be Grid, Bin will be Overlay, and ERPset will be pages +end +%%Generate the indices of tiem points + +for Numofselectederp = 1:numel(ERPsetArray) + SampNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).pnts; + StartTNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).times(1); + StopTNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).times(end); + SrateNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).srate; +end + + + +if numel(ERPsetArray) ==1 + TimeIndex = ALLERP(ERPsetArray).times; +else + if numel(unique(SrateNum_mp))>1 %%Check if the sampling rate is the same across the selected ERPsets, otherwise, the "ERPsets" will be fixed as "Pages". + % msgboxText = ['EStudio says: Sampling rate varies across the selected ERPsets, we therefore set "ERPsets" to be "Pages".']; + % title = 'EStudio: f_geterpdata().'; + % errorfound(msgboxText, title); + if orgpar(1)==1 && (orgpar(2) ==2 || orgpar(2) ==3) + orgpar = [1 2 3]; + elseif orgpar(1)==2 && (orgpar(2) ==1 || orgpar(2) ==3) + orgpar = [2 1 3]; + elseif orgpar(1)==3 && (orgpar(2) ==1 || orgpar(2) ==2) + orgpar = [setdiff([1 2 3],[orgpar(2) 3]), orgpar(2), 3]; + end + TimeIndex = []; + else%%if the sampling rate is the same across the selected ERPsets. + + if numel(unique(SampNum_mp))==1 && numel(unique(StartTNum_mp))==1 && numel(unique(StopTNum_mp))==1 && numel(unique(SrateNum_mp))==1 %%if the number of channels is the same + TimeIndex = []; + else + Min_start = min(StartTNum_mp(:));%%Minimum + Max_end = max(StopTNum_mp(:));%%Maximum + TimeIndex = [Min_start:1000/SrateNum_mp(1):Max_end]; + end + + end + +end + +[ERPpdata,legendpName,ERPperrordata] = f_geterpdata(ALLERP,ERPsetArray,orgpar,CurrentERPIndex); + +%%Get the ylim +try + if orgpar(3) ==3%%if ERPset is assigned to be "Pages" + for Numoferpset = 1:numel(ERPsetArray) + ERPIN = ALLERP(ERPsetArray(Numoferpset)); + if isempty(binArray) || max(binArray)> ERPIN.nbin || min(binArray)<= 0 + binArrayin = 1:ERPIN.nbin; + else + binArrayin = binArray; + end + + if isempty(chanArray) || max(chanArray)> ERPIN.nchan || min(chanArray)<= 0 + chanArrayin = 1:ERPIN.nchan; + else + chanArrayin = chanArray; + end + + if isempty(xxlim) || min(xxlim) < ERPIN.times(1) || max(xxlim) > ERPIN.times(end) + xxlimin = [ ERPIN.times(1), ERPIN.times(end)]; + else + xxlimin = xxlim; + end + [yylim, serror] = erpAutoYLim(ERPIN, binArrayin, chanArrayin, xxlimin,blcorrdata); + yylim_out(Numoferpset,:) = yylim; + end + + elseif orgpar(3) ==1%%if Channel is assigned to be "Pages" + yylim_outchan = []; + ERPIN = ALLERP(ERPsetArray(1));%% + for Numofchannel = 1:size(ERPpdata,1) + Databin = squeeze(ERPpdata(Numofchannel,:,:,:));%%samples by bins by ERPsets + Databin = permute(Databin,[3 1 2]);%%ERPsets by samples by bins + ERPIN.bindata = Databin; + ERPIN.nchan = size(Databin,1); + ERPIN.nbin = size(Databin,3); + if ~isempty(TimeIndex) + ERPIN.times = TimeIndex; + ERPIN.xmin = TimeIndex(1)/1000; + ERPIN.xmax = TimeIndex(end)/1000; + end + + if isempty(binArray) || max(binArray)> ERPIN.nbin || min(binArray)<= 0 + binArrayin = 1:ERPIN.nbin; + else + binArrayin = binArray; + end + chanArrayin = 1:ERPIN.nchan; + + [yylim, serror] = erpAutoYLim(ERPIN, binArrayin, chanArrayin); + yylim_outchan(Numofchannel,:) = yylim; + end + + if max(chanArray)> size(ERPpdata,1) || min(chanArray)<= 0 + yylim_out = yylim_outchan; + else + yylim_out = yylim_outchan(chanArray,:); + end + + elseif orgpar(3) ==2%%if bin is assigned to be "Pages" + ERPIN = ALLERP(ERPsetArray(1));%% + for Numofbin = 1:size(ERPpdata,3) + Databin = squeeze(ERPpdata(:,:,Numofbin,:));%%samples by bins by ERPsets + % Databin = permute(Databin,[3 1 2]);%%ERPsets by samples by bins + ERPIN.bindata = Databin; + ERPIN.nchan = size(Databin,1); + ERPIN.nbin = size(Databin,3); + if ~isempty(TimeIndex) + ERPIN.times = TimeIndex; + ERPIN.xmin = TimeIndex(1)/1000; + ERPIN.xmax = TimeIndex(end)/1000; + end + + if isempty(chanArray) || max(chanArray)> ERPIN.nchan || min(chanArray)<= 0 + chanArrayin = 1:ERPIN.nchan; + else + chanArrayin = chanArray; + end + binArrayin = 1:ERPIN.nbin; + + + [yylim, serror] = erpAutoYLim(ERPIN, binArrayin, chanArrayin); + yylim_outbin(Numofbin,:) = yylim; + end + + if max(binArray)> size(ERPpdata,3) || min(binArray)<= 0 + yylim_out = yylim_outbin; + else + yylim_out = yylim_outbin(binArray,:); + end + + else + beep; + error('f_erpAutoYLim() error: Please check if all of the parameters is correct.'); + return; + end + + +catch + + beep; + error('f_erpAutoYLim() error: Please check if all of the parameters is correct.'); + return; +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_erpwave_viewer_update_parameter.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_erpwave_viewer_update_parameter.m new file mode 100644 index 00000000..d55a5747 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_erpwave_viewer_update_parameter.m @@ -0,0 +1,770 @@ +%Ths is part of pop_plotERPwaviewer.m +% PURPOSE: It use to update the parameters based on the all saved +% paramerters or + +% + + + +function [ERPwaviewerIN, ErroMessg] = f_erpwave_viewer_update_parameter(Parameterfile,parse_param) + + +ErroMessg = ''; +ERPwaviewerIN = []; +if nargin < 1 || nargin>2 + ERPwaviewerIN = []; + help f_erpwave_viewer_update_parameter + return; +end + +if nargin < 2 + ALLERPdef = []; + PagesIndexdef = []; + ERPsetArraydef = []; + binArraydef = []; + chanArraydef = []; +else + ALLERPdef= parse_param.Results.ALLERP; + PagesIndexdef = parse_param.Results.CURRENTPLOT; + ERPsetArraydef = parse_param.Results.ERPsetArray; + binArraydef = parse_param.Results.binArray; + chanArraydef = parse_param.Results.chanArray; +end + + +try + ERPwaviewerIN =importdata(Parameterfile); +catch + ErroMessg = strcat('f_erpwave_viewer_update_parameter() error: Cannot import "Parameterfile".'); + beep; + disp(ErroMessg); + return; +end + +ALLERPIN = ERPwaviewerIN.ALLERP; + +if isempty(ALLERPIN)&& isempty(ALLERPdef) + ErroMessg = strcat('f_erpwave_viewer_update_parameter() error: ALLERP is empty in both "Parameterfile" and "parse_param".'); + beep; + disp(ErroMessg); + return; +end + +% +%%bin array and channel array +binArray = ERPwaviewerIN.bin; +chanArray = ERPwaviewerIN.chan; +ERPsetArray = ERPwaviewerIN.SelectERPIdx; + +if ~isempty(ALLERPdef) + ALLERPIN = ALLERPdef; + if isempty(ERPsetArraydef) || min(ERPsetArraydef)<=0 || max(ERPsetArraydef)>length(ALLERPdef) + if isempty(ERPsetArray) || min(ERPsetArray)<=0 || max(ERPsetArray)>length(ALLERPdef) + ERPsetArray = length(ALLERPdef); + end + else + ERPsetArray = ERPsetArraydef; + end + [chanStrdef,binStrdef,diff_mark] = f_geterpschanbin(ALLERPdef,ERPsetArray); + if ~isempty(chanArraydef) && min(chanArraydef)>0 && max(chanArraydef)<= length(chanStrdef) + chanArray = chanArraydef; + else + if isempty(chanArray) || min(chanArray)<=0 || max(chanArray) > length(chanStrdef) + chanArray = [1:length(chanStrdef)]; + end + end + + if ~isempty(binArraydef) && min(binArraydef)>0 && max(binArraydef)<= length(binStrdef) + binArray = binArraydef; + else + if isempty(binArray) || min(binArray)<=0 || max(binArray)> length(binStrdef) + binArray = [1:length(binStrdef)]; + end + end + +else + ALLERPIN = ERPwaviewerIN.ALLERP; + %%checking the indices of the selected ERPsets + if isempty(ERPsetArraydef) || min(ERPsetArraydef)<=0 || max(ERPsetArraydef)>length(ALLERPIN) + if isempty(ERPsetArray) || min(ERPsetArray)<=0 || max(ERPsetArray)>length(ALLERPIN) + ERPsetArray = length(ALLERPIN); + end + else + ERPsetArray = ERPsetArraydef; + end + [chanStrdef,binStrdef,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + if ~isempty(chanArraydef) && min(chanArraydef)>0 && max(chanArraydef)<= length(chanStrdef) + chanArray = chanArraydef; + else + if isempty(chanArray) || min(chanArray)<=0 || max(chanArray) > length(chanStrdef) + chanArray = [1:length(chanStrdef)]; + end + end + + if ~isempty(binArraydef) && min(binArraydef)>0 && max(binArraydef)<= length(binStrdef) + binArray = binArraydef; + else + if isempty(binArray) || min(binArray)<=0 || max(binArray)> length(binStrdef) + binArray = [1:length(binStrdef)]; + end + end +end + +ERPwaviewerIN.bin=binArray; +ERPwaviewerIN.chan = chanArray; +ERPwaviewerIN.SelectERPIdx = ERPsetArray; +ERPwaviewerIN.ALLERP=ALLERPIN; + + +ERPIN= ERPwaviewerIN.ERP; +CURRENTERPIN = ERPwaviewerIN.CURRENTERP; + +if isempty(CURRENTERPIN) || CURRENTERPIN > length(ALLERPIN) %%checking index of current erpset + CURRENTERPIN =length(ALLERPIN); +end + +ParameterNames = {'ALLERP','CURRENTPLOT','ERPsetArray','binArray','chanArray','PLOTORG','GridposArray',... + 'LabelsName','Blc','Box','LineColor','LineStyle','LineMarker','LineWidth','LegendName','LegendFont',... + 'LegendFontsize','Labeloc','Labelfont','Labelfontsize','YDir','SEM','Transparency','GridSpace','TimeRange', ... + 'Xticks','Xticklabel','Xlabelfont','Xlabelfontsize','Xlabelcolor','Xunits','MinorTicksX','YScales','Yticks',... + 'Yticklabel','Ylabelfont','Ylabelfontsize','Ylabelcolor','Yunits','MinorTicksY','LegtextColor','Legcolumns',... + 'FigureName','FigbgColor','Labelcolor','Ytickdecimal','Xtickdecimal','XtickdisFlag','ErrorMsg','History'}; + + +parse_Results = parse_param.Results; +parseuseDef = parse_param.UsingDefaults; +parse_paramout= parse_Results; + +diffStr = f_setdiffstr(ParameterNames,parseuseDef); +fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; + +linecolorsrgb = {'[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]'}'; + + +for ii = 1:length(diffStr) + [C,IA] = ismember_bc2(diffStr{ii},ParameterNames); + if C==1 && IA<=length(ParameterNames) + % valuedef = getfield(parse_paraDef,parseuseDef{ii}); + % parse_paramout = setfield(parse_paramout,parseuseDef{ii},valuedef); + switch IA + case 6 + PLOTORG = getfield(parse_paramout,'PLOTORG'); + if numel(unique(PLOTORG))~=3 + PLOTORG = [1 2 3]; + else + if PLOTORG(1)~=1 && PLOTORG(1)~=2 && PLOTORG(1)~=3 + PLOTORG = [1 2 3]; + elseif PLOTORG(2)~=1 && PLOTORG(2)~=2 && PLOTORG(2)~=3 + PLOTORG = [1 2 3]; + elseif PLOTORG(3)~=1 && PLOTORG(3)~=2 && PLOTORG(3)~=3 + PLOTORG = [1 2 3]; + end + end + ERPwaviewerIN.plot_org.Grid=PLOTORG(1); + ERPwaviewerIN.plot_org.Overlay=PLOTORG(2); + ERPwaviewerIN.plot_org.Pages=PLOTORG(3); + case 7 + GridposArray = getfield(parse_paramout,'GridposArray'); + %%need to further edit this parameters. + try + PLOTORG(1) = ERPwaviewerIN.plot_org.Grid ; + PLOTORG(2) = ERPwaviewerIN.plot_org.Overlay; + PLOTORG(3) = ERPwaviewerIN.plot_org.Pages; + catch + PLOTORG = [1 2 3]; %%"Channels" is Grid; "Bins" is Overlay; "ERPsets" is Pages. + end + ALLERPIN = ERPwaviewerIN.ALLERP; + binArray = ERPwaviewerIN.bin; + chanArray = ERPwaviewerIN.chan; + ERPsetArray = ERPwaviewerIN.SelectERPIdx; + [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + if isempty(binArray) + binArray = [1:length(binStr)]; + end + + if isempty(chanArray) + chanArray = [1:length(chanStr)]; + end + + if isempty(ERPsetArray) || max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); + end + if PLOTORG(1) ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + for Numofchan = 1:numel(chanArray) + try + plotArrayStrdef{Numofchan} = chanStr{plotArray(Numofchan)}; + catch + end + end + elseif PLOTORG(1) == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + for Numofchan = 1:numel(plotArray) + try + plotArrayStrdef{Numofchan} = binStr{plotArray(Numofchan)}; + catch + end + end + elseif PLOTORG(1) == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numofchan = 1:numel(plotArray) + try + plotArrayStrdef{Numofchan} = ALLERPIN(plotArray(Numofchan)).erpname; + catch + plotArrayStrdef{Numofchan} = 'none'; + end + end + + end + for Numofrow = 1:size(GridposArray,1) + for Numofcolumn = 1:size(GridposArray,2) + [x_df,y_df] = find([1:numel(plotArray)]==GridposArray(Numofrow,Numofcolumn)); + if ~isempty(y_df) + GridposArrayStr{Numofrow,Numofcolumn} = char(plotArrayStrdef{y_df}); + else + GridposArrayStr{Numofrow,Numofcolumn} = 'none'; + end + end + end + ERPwaviewerIN.plot_org.gridlayout.data = GridposArrayStr; + case 8 + LabelsNamedef = getfield(parse_paramout,'LabelsName'); + if ~isempty(LabelsNamedef) + % + columFormatOld = ERPwaviewerIN.plot_org.gridlayout.columFormat; + for ii = 1:length(columFormatOld)-1 + try + LabelsName{ii} = LabelsNamedef{ii} ; + catch + LabelsName{ii} = columFormatOld{ii}; + end + end + LabelsName{length(LabelsName)+1} = 'None'; + GridinforDataOld = ERPwaviewerIN.plot_org.gridlayout.data; + [Numrows,Numcolumns] = size(GridinforDataOld); + for Numofrow = 1:Numrows + for Numofcolumn = 1:Numcolumns + SingleStr = char(GridinforDataOld{Numofrow,Numofcolumn}); + [C,IA] = ismember_bc2(SingleStr,columFormatOld); + if C ==1 + if IA < length(columFormatOld) + try + GridinforDataOld{Numofrow,Numofcolumn} = char(LabelsName{IA}); + catch + GridinforDataOld{Numofrow,Numofcolumn} = char(''); + end + elseif IA == length(columFormatOld) + GridinforDataOld{Numofrow,Numofcolumn} = char('None'); + end + else + GridinforDataOld{Numofrow,Numofcolumn} = char('None'); + end + end + end + ERPwaviewerIN.plot_org.gridlayout.data = GridinforDataOld; + ERPwaviewerIN.plot_org.gridlayout.columFormat = LabelsName; + end + case 9%%baseline correction + Blc = getfield(parse_paramout,'Blc'); + if ~isempty(Blc) + if length(Blc) ==2 + if isnumeric(qBlc) && unique(Blc)==2 + ERPwaviewerIN.baselinecorr = sort(Blc); + end + else + if ischar(Blc) + if strcmpi(Blc,'no') || strcmpi(Blc,'none') || strcmpi(Blc,'pre')||strcmpi(Blc,'post')|| strcmpi(Blc,'all') + ERPwaviewerIN.baselinecorr = Blc; + end + end + end + end + + case 10 + Box = getfield(parse_paramout,'Box'); + if ~isempty(Box) && numel(Box)==2 + ERPwaviewerIN.plot_org.gridlayout.rows = Box(1); + ERPwaviewerIN.plot_org.gridlayout.columns = Box(2); + end + case 11 + LineColor = getfield(parse_paramout,'LineColor'); + %%need to further confirm this + if ~isempty(LineColor) + for ii = 1:length(linecolorsrgb) + try + lineColor_One = LineColor(ii,:); + catch + lineColor_One =str2num(linecolorsrgb{ii}); + end + if ~isempty(lineColor_One)&& numel(lineColor_One)==3 && min(lineColor_One)>=0 && max(lineColor_One)<=1 + try + ERPwaviewerIN.Lines.data{ii,2} = num2str(lineColor_One); + catch + ERPwaviewerIN.Lines.data{ii,2} = linecolorsrgb{ii}; + end + end + end + ERPwaviewerIN.Lines.auto =0; + end + case 12 + LineStyle = getfield(parse_paramout,'LineStyle'); + if ~isempty(LineStyle) + for jj = 1:length(LineStyle) + LineStyle_one = LineStyle{jj}; + if strcmpi(LineStyle_one,'-') + ERPwaviewerIN.Lines.data{jj,3} = 'solid'; + elseif strcmpi(LineStyle_one,'--') + ERPwaviewerIN.Lines.data{jj,3} = 'dash'; + elseif strcmpi(LineStyle_one,':') + ERPwaviewerIN.Lines.data{jj,3} = 'dot'; + elseif strcmpi(LineStyle_one,'-.') + ERPwaviewerIN.Lines.data{jj,3} = 'dashdot'; + else + ERPwaviewerIN.Lines.data{jj,3} = 'solid'; + end + end + end + case 13 + LineMarker = getfield(parse_paramout,'LineMarker'); + if ~isempty(LineMarker) + for ii = 1:length(LineMarker) + LineMarker_one = LineMarker{ii}; + if strcmpi(LineMarker_one,'+') + ERPwaviewerIN.Lines.data{jj,3} = 'plus'; + elseif strcmpi(LineMarker_one,'o') + ERPwaviewerIN.Lines.data{jj,3} = 'circle'; + elseif strcmpi(LineMarker_one,'*') + ERPwaviewerIN.Lines.data{jj,3} = 'asterisk'; + end + end + end + case 14 + LineWidth = getfield(parse_paramout,'LineWidth'); + if ~isempty(LineWidth) + for jj = 1:numel(LineWidth) + LineWidth_one = LineWidth(jj); + if LineWidth_one<=0 + LineWidth_one =1; + end + try + ERPwaviewerIN.Lines.data{jj,4} = LineWidth_one; + catch + ERPwaviewerIN.Lines.data{jj,4} = 1; + end + end + end + case 15 + LegendName1 = getfield(parse_paramout,'LegendName'); + if ~isempty(LegendName1) + for ii = 1:100 + try + LegendName{ii,1} = LegendName1{ii}; + catch + LegendName{ii,1} = ''; + end + LegendNamenum(ii,1) =ii; + end + legendset_str = table(LegendNamenum,LegendName); + legendset_str = table2cell(legendset_str); + ERPwaviewerIN.Legend.data = legendset_str; + end + case 16 + LegendFont = getfield(parse_paramout,'LegendFont'); + if ~isempty(LegendFont) + [C1,IA1] = ismember_bc2(LegendFont,fonttype); + if C1 ==1 + ERPwaviewerIN.Legend.font = IA1; + else + ERPwaviewerIN.Legend.font = 1; + end + end + case 17 + LegendFontsize = getfield(parse_paramout,'LegendFontsize'); + if ~isempty(LegendFontsize) && numel(LegendFontsize)==1 && LegendFontsize>0 + ERPwaviewerIN.Legend.fontsize = LegendFontsize; + end + + case 18 + Labeloc = getfield(parse_paramout,'Labeloc'); + if ~isempty(Labeloc) + try + ERPwaviewerIN.chanbinsetlabel.location.xperc = Labeloc(1); + catch + ERPwaviewerIN.chanbinsetlabel.location.xperc = 0; + end + try + ERPwaviewerIN.chanbinsetlabel.location.yperc = Labeloc(2); + catch + ERPwaviewerIN.chanbinsetlabel.location.yperc = 70; + end + try + ERPwaviewerIN.chanbinsetlabel.location.center = Labeloc(3); + catch + ERPwaviewerIN.chanbinsetlabel.location.center = 1; + end + if ERPwaviewerIN.chanbinsetlabel.location.center~=0 && ERPwaviewerIN.chanbinsetlabel.location.center~=1 + ERPwaviewerIN.chanbinsetlabel.location.center=1; + end + end + case 19 + Labelfont = getfield(parse_paramout,'Labelfont'); + if ~isempty(Labelfont) + [C2,IA2] = ismember_bc2(Labelfont,fonttype); + if C2 ==1 + ERPwaviewerIN.chanbinsetlabel.font = IA2; + else + ERPwaviewerIN.chanbinsetlabel.font = 1; + end + end + + case 20 + Labelfontsize = getfield(parse_paramout,'Labelfontsize'); + if ~isempty(Labelfontsize) && numel(Labelfontsize)==1 && Labelfontsize>0 + ERPwaviewerIN.chanbinsetlabel.fontsize = Labelfontsize; + end + case 21 + YDir = getfield(parse_paramout,'YDir'); + if ~isempty(YDir) && numel(YDir)==1 + ERPwaviewerIN.polarity = YDir; + end + case 22 + SEM = getfield(parse_paramout,'SEM'); + if ~isempty(SEM) && SEM>=0 + ERPwaviewerIN.SEM.error = SEM; + end + case 23 + Transparency = getfield(parse_paramout,'Transparency'); + if ~isempty(Transparency) && Transparency>=0 + ERPwaviewerIN.SEM.trans = Transparency; + end + case 24 + Gridspace = getfield(parse_paramout,'GridSpace'); + Layoutop = ERPwaviewerIN.plot_org.gridlayout.op; + if Layoutop==1 + ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPOP = 1; + ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPValue =10; + ERPwaviewerIN.plot_org.gridlayout.rowgap.OverlayOP = 0; + ERPwaviewerIN.plot_org.gridlayout.rowgap.OverlayValue =40; + ERPwaviewerIN.plot_org.gridlayout.columngap.GTPOP =1; + ERPwaviewerIN.plot_org.gridlayout.columngap.GTPValue =10; + ERPwaviewerIN.plot_org.gridlayout.columngap.OverlayOP =0; + ERPwaviewerIN.plot_org.gridlayout.columngap.OverlayValue =40; + else + try + rowgapop = Gridspace(1,1); + catch + rowgapop =1; + end + ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPOP = rowgapop; + if rowgapop%%gap + try + rowgapValue = Gridspace(1,2); + catch + rowgapValue=10; + end + if isempty(rowgapValue) || numel(rowgapValue)~=1 || rowgapValue<=0 + rowgapValue = 10; + end + ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPValue = rowgapValue; + + else%%overlay + Gridspace(1,1) = 2; + ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPOP = 2; + try + rowoverlayValue = Gridspace(1,2); + catch + rowoverlayValue = 40; + end + if isempty(rowoverlayValue) || numel(rowoverlayValue)~=1 || rowoverlayValue<=0 || rowoverlayValue>100 + rowoverlayValue = 40; + end + ERPwaviewerIN.plot_org.gridlayout.rowgap.OverlayValue= rowoverlayValue; + end + %%for columns + try + columngapop = Gridspace(2,1); + catch + Gridspace(2,1) = 1; + end + ERPwaviewerIN.plot_org.gridlayout.columngap.GTPOP=columngapop; + if columngapop%%gap + try + columngapValue = Gridspace(2,2); + catch + columngapValue = 10; + end + if isempty(columngapValue) || numel(columngapValue)~=1 || columngapValue<=0 + columngapValue = 10; + end + ERPwaviewerIN.plot_org.gridlayout.columngap.GTPValue= columngapValue; + else%% overlay + try + columnoverlayValue = Gridspace(2,2); + catch + columnoverlayValue = 20; + end + if isempty(columnoverlayValue) || numel(columnoverlayValue)~=1 || columnoverlayValue<=0 || columnoverlayValue>100 + columnoverlayValue = 20; + end + ERPwaviewerIN.plot_org.gridlayout.columngap.OverlayValue= columnoverlayValue; + end + end + case 25 + TimeRange = unique(getfield(parse_paramout,'TimeRange')); + if ~isempty(TimeRange) && numel(TimeRange)==2 + ERPwaviewerIN.xaxis.timerange=sort(TimeRange); + end + + case 26 + Xticks = getfield(parse_paramout,'Xticks'); + if ~isempty(Xticks) + ERPwaviewerIN.xaxis.timeticks = sort(Xticks); + end + case 27 + Xticklabel = getfield(parse_paramout,'Xticklabel'); + if ~isempty(Xticklabel) + if strcmpi(Xticklabel,'off') + ERPwaviewerIN.xaxis.label = 0; + else + ERPwaviewerIN.xaxis.label = 1; + end + end + case 28 + Xlabelfont = getfield(parse_paramout,'Xlabelfont'); + if ~isempty(Xlabelfont) + [C3,IA3] = ismember_bc2(Xlabelfont,fonttype); + if C3 ==1 + ERPwaviewerIN.xaxis.font = IA3; + else + ERPwaviewerIN.xaxis.font = 1; + end + end + case 29 + Xlabelfontsize = getfield(parse_paramout,'Xlabelfontsize'); + if ~isempty(Xlabelfontsize) && Xlabelfontsize>0 + ERPwaviewerIN.xaxis.fontsize = Xlabelfontsize; + end + case 30 + Xlabelcolor = getfield(parse_paramout,'Xlabelcolor'); + if numel(Xlabelcolor) ==3 + if Xlabelcolor(1)==0 && Xlabelcolor(2)==0 && Xlabelcolor(3)==0 + ERPwaviewerIN.xaxis.fontcolor =1; + elseif Xlabelcolor(1)==1 && Xlabelcolor(2)==0 && Xlabelcolor(3)==0 + ERPwaviewerIN.xaxis.fontcolor =2; + elseif Xlabelcolor(1)==0 && Xlabelcolor(2)==0 && Xlabelcolor(3)==1 + ERPwaviewerIN.xaxis.fontcolor =3; + elseif Xlabelcolor(1)==0 && Xlabelcolor(2)==1 && Xlabelcolor(3)==0 + ERPwaviewerIN.xaxis.fontcolor =4; + elseif roundn(Xlabelcolor(1),-2)==0.93 && roundn(Xlabelcolor(2),-2)==0.69 && roundn(Xlabelcolor(3),-2)==0.13 + ERPwaviewerIN.xaxis.fontcolor =5; + elseif Xlabelcolor(1)==0 && Xlabelcolor(2)==1 && Xlabelcolor(3)==1 + ERPwaviewerIN.xaxis.fontcolor =6; + elseif Xlabelcolor(1)==1 && Xlabelcolor(2)==0 && Xlabelcolor(3)==1 + ERPwaviewerIN.xaxis.fontcolor =7; + else + ERPwaviewerIN.xaxis.fontcolor =1; + end + end + case 31 + Xunits = getfield(parse_paramout,'Xunits'); + if ~isempty(Xunits) + if strcmpi(Xunits,'off') + ERPwaviewerIN.xaxis.units = 0; + else + ERPwaviewerIN.xaxis.units = 1; + end + end + case 32 + MinorTicksX = getfield(parse_paramout,'MinorTicksX'); + if ~isempty(MinorTicksX) + try + xminorValue = MinorTicksX(1); + catch + xminorValue =0; + end + ERPwaviewerIN.xaxis.tminor.disp =xminorValue; + if xminorValue==0 + ERPwaviewerIN.xaxis.tminor.step = 0; + ERPwaviewerIN.xaxis.tminor.auto = 0; + else + try + xminorstr = MinorTicksX(2:end); + catch + xminorstr = []; + end + if isempty(xminorstr) + ERPwaviewerIN.xaxis.tminor.step = 0; + ERPwaviewerIN.xaxis.tminor.auto = 0; + else + ERPwaviewerIN.xaxis.tminor.step = xminorstr; + end + end + end + case 33 + YScales = unique(getfield(parse_paramout,'YScales')); + if ~isempty(YScales) && numel(YScales)==2 + ERPwaviewerIN.yaxis.scales = sort(YScales); + end + case 34 + Yticks = getfield(parse_paramout,'Yticks'); + if ~isempty(Yticks) + ERPwaviewerIN.yaxis.ticks = sort(Yticks); + end + case 35 + Yticklabel =getfield(parse_paramout,'Yticklabel'); + if ~isempty(Yticklabel) + if strcmpi(Yticklabel,'off') + ERPwaviewerIN.yaxis.label = 0; + else + ERPwaviewerIN.yaxis.label = 1; + end + end + + case 36 + Ylabelfont = getfield(parse_paramout,'Ylabelfont'); + if ~isempty(Ylabelfont) + [C4,IA4] = ismember_bc2(Ylabelfont,fonttype); + if C4 ==1 + ERPwaviewerIN.yaxis.font = IA4; + else + ERPwaviewerIN.yaxis.font = 1; + end + end + case 37 + Ylabelfontsize = getfield(parse_paramout,'Ylabelfontsize'); + if ~isempty(Ylabelfontsize) && Ylabelfontsize>0 + ERPwaviewerIN.yaxis.fontsize = Ylabelfontsize; + end + case 38 + Ylabelcolor = getfield(parse_paramout,'Ylabelcolor'); + if numel(Ylabelcolor) ==3 + if Ylabelcolor(1)==0 && Ylabelcolor(2)==0 && Ylabelcolor(3)==0 + ERPwaviewerIN.yaxis.fontcolor =1; + elseif Ylabelcolor(1)==1 && Ylabelcolor(2)==0 && Ylabelcolor(3)==0 + ERPwaviewerIN.yaxis.fontcolor =2; + elseif Ylabelcolor(1)==0 && Ylabelcolor(2)==0 && Ylabelcolor(3)==1 + ERPwaviewerIN.yaxis.fontcolor =3; + elseif Ylabelcolor(1)==0 && Ylabelcolor(2)==1 && Ylabelcolor(3)==0 + ERPwaviewerIN.yaxis.fontcolor =4; + elseif roundn(Ylabelcolor(1),-2)==0.93 && roundn(Ylabelcolor(2),-2)==0.69 && roundn(Ylabelcolor(3),-2)==0.13 + ERPwaviewerIN.yaxis.fontcolor =5; + elseif Ylabelcolor(1)==0 && Ylabelcolor(2)==1 && Ylabelcolor(3)==1 + ERPwaviewerIN.yaxis.fontcolor =6; + elseif Ylabelcolor(1)==1 && Ylabelcolor(2)==0 && Ylabelcolor(3)==1 + ERPwaviewerIN.yaxis.fontcolor=7; + else + ERPwaviewerIN.yaxis.fontcolor =1; + end + end + case 39 + Yunits = getfield(parse_paramout,'Yunits'); + if ~isempty(Yunits) + if strcmpi(Yunits,'off') + ERPwaviewerIN.yaxis.units = 0; + else + ERPwaviewerIN.yaxis.units = 1; + end + end + case 40 + MinorTicksY = getfield(parse_paramout,'MinorTicksY'); + if ~isempty(MinorTicksY) + try + yminorValue = MinorTicksY(1); + catch + yminorValue =0; + end + ERPwaviewerIN.yaxis.yminor.disp =yminorValue; + if yminorValue==0 + ERPwaviewerIN.yaxis.yminor.step = 0; + ERPwaviewerIN.yaxis.yminor.auto = 0; + else + try + yminorstr = MinorTicksY(2:end); + catch + yminorstr = []; + end + if isempty(yminorstr) + ERPwaviewerIN.yaxis.yminor.step = 0; + ERPwaviewerIN.yaxis.yminor.auto = 0; + else + ERPwaviewerIN.yaxis.yminor.step = yminorstr; + end + end + end + case 41 + LegtextColor = getfield(parse_paramout,'LegtextColor'); + if ~isempty(LegtextColor) && (LegtextColor==0 || LegtextColor==1) + ERPwaviewerIN.Legend.textcolor = LegtextColor; + end + + case 42 + Legcolumns = getfield(parse_paramout,'Legcolumns'); + if ~isempty(Legcolumns) && numel(Legcolumns)==1 && Legcolumns>0 + ERPwaviewerIN.Legend.columns = Legcolumns; + end + case 43 + FigureName = getfield(parse_paramout,'FigureName'); + if ~isempty(FigureName) + ERPwaviewerIN.figname = FigureName; + end + case 44 + FigbgColor = getfield(parse_paramout,'FigbgColor'); + if ~isempty(FigbgColor) || min(FigbgColor)>=0 || max(FigbgColor)<=1 + ERPwaviewerIN.figbackgdcolor = FigbgColor; + end + + case 45 + Labelcolor = getfield(parse_paramout,'Labelcolor'); + if numel(Labelcolor) ==3 + if Labelcolor(1)==0 && Labelcolor(2)==0 && Labelcolor(3)==0 + ERPwaviewerIN.chanbinsetlabel.textcolor =1; + elseif Labelcolor(1)==1 && Labelcolor(2)==0 && Labelcolor(3)==0 + ERPwaviewerIN.chanbinsetlabel.textcolor =2; + elseif Labelcolor(1)==0 && Labelcolor(2)==0 && Labelcolor(3)==1 + ERPwaviewerIN.chanbinsetlabel.textcolor =3; + elseif Labelcolor(1)==0 && Labelcolor(2)==1 && Labelcolor(3)==0 + ERPwaviewerIN.chanbinsetlabel.textcolor =4; + elseif roundn(Labelcolor(1),-2)==0.93 && roundn(Labelcolor(2),-2)==0.69 && roundn(Labelcolor(3),-2)==0.13 + ERPwaviewerIN.chanbinsetlabel.textcolor =5; + elseif Labelcolor(1)==0 && Labelcolor(2)==1 && Labelcolor(3)==1 + ERPwaviewerIN.chanbinsetlabel.textcolor =6; + elseif Labelcolor(1)==1 && Labelcolor(2)==0 && Labelcolor(3)==1 + ERPwaviewerIN.chanbinsetlabel.textcolor=7; + else + ERPwaviewerIN.chanbinsetlabel.textcolor =1; + end + end + case 46 + Ytickdecimal = getfield(parse_paramout,'Ytickdecimal'); + if ~isempty(Ytickdecimal)&& numel(Ytickdecimal)==1 && Ytickdecimal>=0 + ERPwaviewerIN.yaxis.tickdecimals=Ytickdecimal; + end + case 47 + Xtickdecimal = getfield(parse_paramout,'Xtickdecimal'); + if ~isempty(Xtickdecimal)&&numel(Xtickdecimal)==1 && Xtickdecimal>=0 + ERPwaviewerIN.xaxis.tickdecimals=Xtickdecimal; + end + case 48 + XtickdisFlag = getfield(parse_paramout,'XtickdisFlag'); + if ~isempty(XtickdisFlag) && numel(XtickdisFlag) ==1 && (XtickdisFlag==0 || XtickdisFlag==1) + ERPwaviewerIN.xaxis.tdis = XtickdisFlag; + end + end + end +end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_existvector.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_existvector.m new file mode 100755 index 00000000..21c90c89 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_existvector.m @@ -0,0 +1,50 @@ + + + +function [Exist,ExistIndex] = f_existvector(TotalVector,SmallVector) + +Exist = 0;%%1.There exists some elements in SmallVector which donot belong to TotalVector. +ExistIndex = []; + +if nargin < 1 + help f_existvector + return; +end + + +if nargin < 2 + msgboxText = ['There should be two inputs']; + error('prog:input', ['f_existvector() says: ' msgboxText]); +end + +if ~isnumeric(TotalVector) + msgboxText = ['The first input must be number(s)']; + error('prog:input', ['f_existvector() says: ' msgboxText]); +end + + +if ~isnumeric(SmallVector) + msgboxText = ['The second input must be number(s)']; + error('prog:input', ['f_existvector() says: ' msgboxText]); +end + +if numel(TotalVector) < numel(SmallVector) + msgboxText = ['Numbers of the second input should be smaller than for the first one.']; + error('prog:input', ['f_existvector() says: ' msgboxText]); +end + + +%%----------organize the inputs into column vectors------------------------ +TotalVector = reshape(TotalVector,[],1); +SmallVector = reshape(SmallVector,[],1); +count = 0; +for kk = 1:numel(SmallVector) + [x_check,y_check] = find(SmallVector(kk,1) == TotalVector); + if isempty(y_check) + Exist = 1; + count = count+1; + ExistIndex(count) =kk; + end +end +return; + diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_get_lineset_ERPviewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_get_lineset_ERPviewer.m new file mode 100755 index 00000000..de7229b0 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_get_lineset_ERPviewer.m @@ -0,0 +1,80 @@ + + + +function [lineNameStr,linecolors,linetypes,linewidths,linecolors_str,linetypes_str,linewidths_str,linecolorsrgb] = f_get_lineset_ERPviewer() + +for ii = 1:105 + lineNameStr{ii,1} =strcat(num2str(ii)); +end + +linecolors = {'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]',... + 'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1 0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]'}'; + +linecolors_str = {'Black [0 0 0]','Red [1 0 0]','Blue [0 0 1]','Green [0 1 0]','Orange [1,0.65 0]','Cyan [0 1 1]','Magenla [1 0 1]',... + 'Gray [0.5 0.5 0.5]','LightCoral [0.94 0.50 0.50]','DeepSkyBlue [0 0.75 1]','LightGreen [0.57 0.93 0.57]','DarkOrange [1 0.55 0]','Pink [1 0.75 0.80]','Gold [1 0.84 0]'}'; + +linecolorsrgb = {'0 0 0','1 0 0','0 0 1','0 1 0','1 0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1 0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1 0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1 0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1 0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1,0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1 0.65 0','0 1 1','1 0 1',... + '0.5 0.5 0.5','0.94 0.50 0.50','0 0.75 1','0.57 0.93 0.57','1 0.55 0','1 0.75 0.80','1 0.84 0',... + '0 0 0','1 0 0','0 0 1','0 1 0','1,0.65 0','0 1 1','1 0 1'}'; + +linetypes = {'solid','solid','solid','solid','solid','solid','solid',... + 'dash','dash','dash','dash','dash','dash','dash',... + 'dot','dot','dot','dot','dot','dot','dot',... + 'dashdot','dashdot','dashdot','dashdot','dashdot','dashdot','dashdot',... + 'plus','plus','plus','plus','plus','plus','plus',... + 'solid','solid','solid','solid','solid','solid','solid',... + 'dash','dash','dash','dash','dash','dash','dash',... + 'dot','dot','dot','dot','dot','dot','dot',... + 'dashdot','dashdot','dashdot','dashdot','dashdot','dashdot','dashdot',... + 'plus','plus','plus','plus','plus','plus','plus',... + 'solid','solid','solid','solid','solid','solid','solid',... + 'dash','dash','dash','dash','dash','dash','dash',... + 'dot','dot','dot','dot','dot','dot','dot',... + 'dashdot','dashdot','dashdot','dashdot','dashdot','dashdot','dashdot',... + 'plus','plus','plus','plus','plus','plus','plus'}'; + +linetypes_str = {'solid','dash','dot','dashdot','plus','circle','asterisk'}'; + +linewidths = [1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1;... + 1;1;1;1;1;1;1]; + +linewidths_str = [1:10]'; +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_geterpdata.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_geterpdata.m new file mode 100755 index 00000000..3629e6d6 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_geterpdata.m @@ -0,0 +1,222 @@ +% PURPOSE : Get the legend and bindata and binerror data for single and mutiple ERPsets +% +% FORMAT : + +% f_geterpdata(ALLERP,ERPsetArray,orgpar); +% +% +% INPUTS : +% +% ALLERP - structure array of ERP structures (ERPsets) +% To read the ERPset from a list in a text file, +% replace ALLERP by the whole filename. + +%ERPsetArray -Index of the selected ERPsets e.g., [1 2 3], the index +% should be not larger than the length of ALLERP + +%orgpar -Indicates how to display the selected ERPsets which +% contains three elements: first one is Grid; the second +% one is Overlay; the last one is Page. For example, [1 2 3] +% represents that Channel will be Grid, Bin will be +% Overlay, and ERPset will be Page. + + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + +%%%Note: please ensure that the sampling rate is the same across the +%%%selected ERPsets at least. Otherwise, "ERPsets" will be fixed as "Pages" + +function [ERPdata,legendName,ERPerrordata,timeRange] = f_geterpdata(ALLERP,ERPsetArray,orgpar,ERPselectIndex) +ERPdata = []; +legendName = []; +ERPerrordata = []; +timeRange = []; +if nargin==0 + beep; + help f_geterpdata; + return; +end +if nargin<2 || isempty(ERPsetArray) + beep; + disp('Please input the index of the selected ERPsets'); + return; +end +if isempty(ALLERP) + beep; + disp('Inputed ALLERP is empty'); + return; +end +[x,y] = find(ERPsetArray>length(ALLERP)); +if ~isempty(y) + beep; + disp('Please the index of the selected ERPsets should not be larger than the length of ALLERP.'); + return; +end + +[x,y] = find(ERPsetArray<=0); +if ~isempty(y) + beep; + disp('Please the index of the selected ERPsets should be positive integer.'); + return; +end + +if nargin<3 + orgpar = [1 2 3];%% Grid is channel; Overlay is bin; page is ERPset +end + +if nargin<4|| (ERPselectIndex>length(ERPsetArray)) + ERPselectIndex =length(ERPsetArray); +end + +% +%%--------------------When only one ERPset is selected.-------------------- +if numel(ERPsetArray) ==1 + + ERPdata = ALLERP(ERPsetArray).bindata;%% ERP data for different bins + + ERPerrordata = ALLERP(ERPsetArray).binerror;%% ERP eroor data + if isempty(ERPerrordata) + ERPerrordata = nan(size(ERPdata,1),size(ERPdata,2),size(ERPdata,3)); + end + timeRange = ALLERP(ERPsetArray).times; + switch orgpar(2)%%Get the legend name according to overlay: overlay is 1 (channel), 2(bin), and 3(ERPset) + case 1 + legendName = cell(ALLERP(ERPsetArray).nchan,1); + chanlabels = ALLERP(ERPsetArray).chanlocs; + for Numofchan = 1:ALLERP(ERPsetArray).nchan + legendName(Numofchan,1) = {char(chanlabels(Numofchan).labels)}; + end + case 2 + legendName = cell(ALLERP(ERPsetArray).nbin,1); + bindescrp = ALLERP(ERPsetArray).bindescr; + for Numofbin = 1:ALLERP(ERPsetArray).nbin + legendName(Numofbin,1) = {char(bindescrp{Numofbin})}; + end + + case 3 + legendName = cell(1,1); + legendName(1,1) = {ALLERP(ERPsetArray).erpname}; + otherwise + legendName = cell(ALLERP(ERPsetArray).nbin,1); + bindescrp = ALLERP(ERPsetArray).bindescr; + for Numofbin = 1:ALLERP(ERPsetArray).nbin + legendName(Numofbin,1) = {char(bindescrp{Numofbin})}; + end + end + return; +end + +% +%%--------------------When mutiple ERPsets are selected.-------------------- + +%%Check the number of bins and channels and samples across ERPsets +chanNum_mp = [];%%Number of channels for multiple subjects +BinNum_mp = [];%%Number of bins for multiple subjects. +SampNum_mp = [];%%Number of samples +StartTNum_mp = [];%%Start time of epoch +StopTNum_mp = [];%%Stop time of epoch +SrateNum_mp = [];%%Sampling rate + +for Numofselectederp = 1:numel(ERPsetArray) + chanNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).nchan; + BinNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).nbin; + SampNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).pnts; + StartTNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).times(1); + StopTNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).times(end); + SrateNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).srate; +end + +if numel(unique(SrateNum_mp))>1 %%Check if the sampling rate is the same across the selected ERPsets, otherwise, the "ERPsets" will be fixed as "Pages". +% msgboxText = ['EStudio says: Sampling rate varies across the selected ERPsets, we therefore set "ERPsets" to be "Pages".']; +% title = 'EStudio: f_geterpdata().'; +% errorfound(msgboxText, title); + if orgpar(1)==1 && (orgpar(2) ==2 || orgpar(2) ==3) + orgpar = [1 2 3]; + elseif orgpar(1)==2 && (orgpar(2) ==1 || orgpar(2) ==3) + orgpar = [2 1 3]; + elseif orgpar(1)==3 && (orgpar(2) ==1 || orgpar(2) ==2) + orgpar = [setdiff([1 2 3],[orgpar(2) 3]), orgpar(2), 3]; + end +end + +%%-------check if the numbers of channels and bins and samples are the same across the selected ERPsets-------- +if numel(unique(chanNum_mp))==1 && numel(unique(SampNum_mp))==1 && numel(unique(BinNum_mp))==1 && numel(unique(StartTNum_mp))==1 && numel(unique(StopTNum_mp))==1 && numel(unique(SrateNum_mp))==1 %%if the number of channels is the same + ERPdata = nan(max(chanNum_mp),max(SampNum_mp),max(BinNum_mp),numel(ERPsetArray)); + ERPerrordata = nan(max(chanNum_mp),max(SampNum_mp),max(BinNum_mp),numel(ERPsetArray));%% ERP eroor data + %%Get the data acorss ERPsets + for Numofselectederp = 1:numel(ERPsetArray) + ERPdata(:,:,:,Numofselectederp) = ALLERP(ERPsetArray(Numofselectederp)).bindata; + errordata = ALLERP(ERPsetArray(Numofselectederp)).binerror; + if ~isempty(errordata) + ERPerrordata(:,:,:,Numofselectederp) =errordata; + end + end + timeRange = ALLERP(ERPsetArray(Numofselectederp)).times; + +else%%If any of bins, channels, samples varies across the selected ERPsets. + + %%There are two possible situations: one is that the sampling rate is the same + %%across the selected ERPsets and the other one is sampling rate varies + + % + %%First situation:the sampling rate is the same across the selected ERPsets + if numel(unique(SrateNum_mp))==1 + Min_start = min(StartTNum_mp(:)); + Max_end = max(StopTNum_mp(:));%%Maximum + + Times = [Min_start:1000/SrateNum_mp(1):Max_end]; + timeRange = Times; + ERPdata = nan(max(chanNum_mp),numel(Times),max(BinNum_mp),numel(ERPsetArray)); + ERPerrordata = nan(max(chanNum_mp),numel(Times),max(BinNum_mp),numel(ERPsetArray)); + + for Numofselectederp = 1:numel(ERPsetArray) + ERP_sg = ALLERP(ERPsetArray(Numofselectederp)); + EpochStart = ERP_sg.times(1); + EpochEnd = ERP_sg.times(end); + [xxx, latsamp, latdiffms] = closest(Times, [EpochStart,EpochEnd]); + ERPdata(1:ERP_sg.nchan,latsamp(1):latsamp(2),1:ERP_sg.nbin,Numofselectederp) = ERP_sg.bindata; + errordata = ERP_sg.binerror; + if ~isempty(errordata) + ERPerrordata(1:ERP_sg.nchan,latsamp(1):latsamp(2),1:ERP_sg.nbin,Numofselectederp) =errordata; + end + + end + + %%Second situation is that the sampling rate varies across the selected ERPsets. + else + ERPdata = nan(max(chanNum_mp),SampNum_mp(ERPselectIndex),max(BinNum_mp),numel(ERPsetArray)); + ERPerrordata = nan(max(chanNum_mp),SampNum_mp(ERPselectIndex),max(BinNum_mp),numel(ERPsetArray)); + + ERP_sg = ALLERP(ERPsetArray(ERPselectIndex));%%The information for individual subject + ERPdata(1:chanNum_mp(ERPselectIndex),:,1:BinNum_mp(ERPselectIndex),ERPselectIndex) = ERP_sg.bindata; + errordata = ERP_sg.binerror; + if ~isempty(errordata)%%Get the error data + ERPerrordata(1:chanNum_mp(ERPselectIndex),:,1:BinNum_mp(ERPselectIndex),ERPselectIndex) =errordata; + end + end +end + +%%Get the legend name according to overlay: overlay is 1 (channel), 2(bin), and 3(ERPset) +switch orgpar(2) + case 1 + [chanStr,binStr,~] = f_geterpschanbin(ALLERP,ERPsetArray); + legendName = chanStr; + case 2 + [chanStr,binStr,~] = f_geterpschanbin(ALLERP,ERPsetArray); + legendName = binStr; + case 3 + legendName = cell(numel(ERPsetArray),1); + for Numoferp = 1:numel(ERPsetArray) + legendName(Numoferp,1) = {ALLERP(ERPsetArray(Numoferp)).erpname}; + end + otherwise + [chanStr,binStr,~] = f_geterpschanbin(ALLERP,ERPsetArray); + legendName = chanStr; +end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_geterpschanbin.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_geterpschanbin.m new file mode 100755 index 00000000..e6919fe8 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_geterpschanbin.m @@ -0,0 +1,216 @@ +% PURPOSE : Get the name of channels and bins for single and mutiple ERPsets +% +% FORMAT : + +% f_geterpschanbin(ALLERP,SelectedERPIndex); +% +% +% INPUTS : +% +% ALLERP - structure array of ERP structures (ERPsets) +% To read the ERPset from a list in a text file, +% replace ALLERP by the whole filename. +%SelectedERPIndex -Index of the selected ERPsets e.g., [1 2 3], the index +% should be not larger than the length of ALLERP + + + + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + +function [chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERP,SelectedERPIndex) +diff_mark = [0 0]; +chanStr = []; +binStr = []; +if nargin==0 + beep; + help f_geterpschanbin; + return; +end + + +if nargin<2 || isempty(SelectedERPIndex) + beep; + disp('Please input the index of the selected ERPsets'); + return; +end + +if isempty(ALLERP) + beep; + disp('Inputed ALLERP is empty'); + return; + +end + +[x,y] = find(SelectedERPIndex>length(ALLERP)); +if ~isempty(y) + beep; + disp('Please the index of the selected ERPsets should not be larger than the length of ALLERP.'); + + return; +end + +[x,y] = find(SelectedERPIndex<=0); +if ~isempty(y) + beep; + disp('Please the index of the selected ERPsets should be positive integer.'); + return; +end + +% +%%--------------------When only one ERPset is selected.-------------------- +if numel(SelectedERPIndex) ==1 + ERP = ALLERP(SelectedERPIndex); + + %%--------Get the names of bins----------- + BinNum = ERP.nbin; + BinName = ERP.bindescr; + binStr = cell(BinNum,1); + for i = 1:BinNum + binStr(i) = {char(BinName{i})}; + end + + %%--------Get the names of chans----------- + ChanNum = ERP.nchan; + Chanlist = ERP.chanlocs; + chanStr = cell(ChanNum,1); + for Numofchan = 1:length(Chanlist) + chanStr(Numofchan) = {char(Chanlist(Numofchan).labels)}; + end + return; +end + + +% +%%------------------When multiple ERPsets are selected------------------- + +chanNum_mp = [];%%Number of channels for multiple subjects +BinNum_mp = [];%%Number of bins for multiple subjects. + + +for Numofselectederp = 1:numel(SelectedERPIndex) + chanNum_mp(Numofselectederp,1) = ALLERP(SelectedERPIndex(Numofselectederp)).nchan; + BinNum_mp(Numofselectederp,1) = ALLERP(SelectedERPIndex(Numofselectederp)).nbin; +end + + + +%%Getting the names of bins and chans +%%for the first selected ERPsets. +ERP = ALLERP(SelectedERPIndex(1)); + +%%-------check if the number of channels is the same across the selected ERPsets-------- +if numel(unique(chanNum_mp))==1%%if the number of channels is the same + ChanNum = ERP.nchan; + Chanlist = ERP.chanlocs; + chanStr = cell(ChanNum,1); + for Numofchan = 1:length(Chanlist) + chanStr(Numofchan) = {char(Chanlist(Numofchan).labels)}; + end + +elseif numel(unique(chanNum_mp))>1%%varies across the selected ERPsets + [x_chan,y_chan] = find(chanNum_mp==max(chanNum_mp(:)));%% find the position of max. value + + ERP = ALLERP(SelectedERPIndex(x_chan)); + + ChanNum = ERP.nchan; + Chanlist = ERP.chanlocs; + chanStr_max = cell(ChanNum,1); + for Numofchan = 1:length(Chanlist) + chanStr_max(Numofchan) = {Chanlist(Numofchan).labels}; + end + + SelectedERPIndex_chan_lf =SelectedERPIndex(setdiff(1:numel(SelectedERPIndex),x_chan)); + + for Numoferpleft = 1:numel(SelectedERPIndex_chan_lf) + ERP = ALLERP(SelectedERPIndex_chan_lf(Numoferpleft)); + ChanNum1 = ERP.nchan; + + for Numofchan = 1:ChanNum1 + if ~strcmpi(chanStr_max(Numofchan),ERP.chanlocs(Numofchan).labels) + chanStr_checkc = char(chanStr_max(Numofchan)); + if ~strcmpi(chanStr_checkc(1),'*') + chanStr_max(Numofchan) = {char(strcat('**',chanStr_max(Numofchan)))}; + end + end + end + for Numofchan = ChanNum1+1:length(chanStr_max) + chanStr_checkc = char(chanStr_max(Numofchan)); + if ~strcmpi(chanStr_checkc(1),'*') + chanStr_max(Numofchan) = {char(strcat('**',chanStr_max(Numofchan)))}; + end + end + clear ERP; + end + diff_mark(1) = 1; + + chanStr = cell(length(chanStr_max),1); + for Numofchan = 1:length(chanStr_max) + chanStr(Numofchan) = {char(chanStr_max(Numofchan))}; + end + +end + +% +%%-------check if the number of bins is the same across the selcted ERPsets-------- +ERP = ALLERP(SelectedERPIndex(1)); +if numel(unique(BinNum_mp))==1%%if the number of bins is the same + BinNum = ERP.nbin; + BinName = ERP.bindescr; + binStr = cell(BinNum,1); + for Numofbin = 1:BinNum + binStr(Numofbin) = {char(BinName{Numofbin})}; + end + +elseif numel(unique(BinNum_mp))>1%%varies across the selected ERPsets + [x_bin,y_bin] = find(BinNum_mp==max(BinNum_mp));%% find the position of max. value + + ERP = ALLERP(SelectedERPIndex(x_bin)); + + BinNum = ERP.nbin; + BinName = ERP.bindescr; + + + binStr_max = cell(BinNum,1); + for Numofbin = 1:BinNum + binStr_max(Numofbin) = {char(BinName{Numofbin})}; + end + + + SelectedERPIndex_bin_lf =SelectedERPIndex(setdiff(1:numel(SelectedERPIndex),x_bin)); + for Numoferpleft = 1:numel(SelectedERPIndex_bin_lf) + ERP = ALLERP(SelectedERPIndex_bin_lf(Numoferpleft)); + BinNum1 = ERP.nbin; + for Numofbin = 1:BinNum1 + if ~strcmpi(binStr_max(Numofbin),ERP.bindescr{Numofbin}) + binStr_checkc = char(binStr_max(Numofbin)); + if ~strcmpi(binStr_checkc(1),'*')%%Check if the bins which vary across selected ERPsets have been marked. + binStr_max(Numofbin) = {char(strcat('**',binStr_max(Numofbin)))}; + end + end + end + + for Numofbin = BinNum1+1:length(binStr_max) + binStr_checkc = char(binStr_max(Numofbin)); + if ~strcmpi(binStr_checkc(1),'*') + binStr_max(Numofbin) = {char(strcat('**',binStr_max(Numofbin)))}; + end + end + clear ERP; + end + diff_mark(2) = 1; + binStr = cell(length(binStr_max),1); + for Numofbin = 1:length(binStr_max) + binStr(Numofbin) = {char(binStr_max(Numofbin))}; + end +end + +end + diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_getrow_columnautowaveplot.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_getrow_columnautowaveplot.m new file mode 100755 index 00000000..f99adbe4 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_getrow_columnautowaveplot.m @@ -0,0 +1,49 @@ +% PURPOSE : Compute the default number of row and columns when plot ERP +% waves and this function is based on the ERLAB function in ploterpGUI() +% +% FORMAT : + +% f_getrow_columnautowaveplot(plotArray); +% +% +% INPUTS : +% +% plotArray -Index of Grid e.g., [1 2 3 4 5 6 7 8] + +% OUTPUTS: +% +% pbox -First element is the number of row and the second one is +% the number of columns, e.g., pbox = [3 3]; + + + + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + + +function pbox = f_getrow_columnautowaveplot(plotArray) +newnch = numel(plotArray); +% if get(handles.checkbox_MGFP, 'Value') +% newnch = newnch + 1; +% end +dsqr = round(sqrt(newnch)); +sqrdif = dsqr^2 - newnch; +if sqrdif<0 + pbox(1) = dsqr + 1; +else + pbox(1) = dsqr; +end +pbox(2) = dsqr; +if pbox(1)<=0 % JLC. 11/05/13 + pbox(1)=1; +end +if pbox(2)<=0 % JLC. 11/05/13 + pbox(2)=1; +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ploterpserpviewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ploterpserpviewer.m new file mode 100755 index 00000000..9aa20851 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_ploterpserpviewer.m @@ -0,0 +1,1470 @@ +% PURPOSE: subroutine for pop_plotERPwaveiwer.m +% plot ERP waveforms +% + +% FORMAT: +% + +% f_ploterpserpviewer(ALLERP,qCURRENTPLOT, qPLOTORG,qbinArray,qchanArray,qGridposArray,plotBox,qBlc,qLineColorspec,qLineStylespec,qLineMarkerspec,qLineWidthspec,... +% qLegendName,qLegendFont,qLegendFontsize,qCBELabels,qLabelfont,qLabelfontsize,qPolarityWave,qSEM,qTransparency,qGridspace,qtimeRange,qXticks,qXticklabel,... +% qXlabelfont,qXlabelfontsize,qXlabelcolor,qMinorTicksX,qXunits,qYScales,qYticks,qYticklabel,qYlabelfont,qYlabelfontsize,qYlabelcolor,qYunits,qMinorTicksY,... +% qplotArrayStr,qERPArray,qlegcolor,qlegcolumns,qFigureName,qFigbgColor,qLabelcolor) + +% Inputs: +% +%ALLERP -ALLERPset +%qCURRENTPLOT -index of current ERPset/bin/channel(e.g., 1) +%qPLOTORG -plot organization including three elements (the default is [1 2 3]) +% First element is for Grid (1 is channel; 2 is bin; 3 is ERPset) +% Second element is for Overlay (1 is channel; 2 is bin; 3 is ERPset) +% Third element is for Page (1 is channel; 2 is bin; 3 is ERPset) +%qbinArray -index(es) of bin(s) to plot ( 1 2 3 ...) +%qchanArray -index(es) of channel(s) to plot ( 5 10 11 ...) +%qGridposArray -location and correponding index of each subplot. E.g., +% plot three channels with 2 x 2, the default qGridposArray is +% [5,10;11,0].The each element of GridposArray is the +% index of selected Channel/bin/ERPset. +%plotBox -ditribution of plotting boxes in rows x columns. +%qBlc -string or numeric interval for baseline correction +% reference window: 'no','pre','post','all', or [-100 0] +%qLineColorspec -line color with RGB,e.g., [0 0 0;1 0 0] +%qLineStylespec -line style e.g., {'-','-'} +%qLineMarkerspec -line marker e.g., {'o','*','none'} +%qLineWidthspec -line width e.g., [1 1 1] +%qLegendName -legend name e.g., {'Rare','Frequent'} +%qLegendFont -font for legend name e.g., 'Courier' or 'Times' +%qLegendFontsize -fontsize for legend name (one value) e.g., 12 or 16 +%qCBELabels -location for channel/bin/erpset label including three +% elements e.g., [100 100 1]; first and second represent +% the percentage of time range or y scales; the last +% element determine whether display the label (1 or 0) +%qLabelfont -label font +%qLabelfontsize -label fontsize +%qPolarityWave -"Y" axis is inverted (-UP)?: 'yes', 'no'. 1 is positive up and 0 +% is negative up +%'SEM' - plot standard error of the mean (if available). 0 is +% off and other is on. +%qTransparency - +%qGridspace -Setting Grid space between rows or columns +%qtimeRange -time window is used to display the wave e.g., [-200 800] +%qXticks - ticks for x axes e.g., [-200 0 200 400 600 800] +%qXticklabel -display xticklabels? 1 is on and 0 is off. +%qXlabelfont -font for xtick and xticklabel e.g., 'Courier' +%qXlabelfontsize -fontsize for xticklabel e.g., 12 +%qXlabelcolor -color (RGB) for xticklabels e.g., [0 0 0] +%qMinorTicksX - +%qXunits -display units for x axes. "on" or "off" +%qYScales - y scales e.g., [-6 10] +%qYticks - y ticks e.g., [-6 -3 0 5 10] +%qYticklabel -display yticklabels? 1 is on and 0 is off. +%qYlabelfont -font for yticklabels e.g., 'Courier' +%qYlabelfontsize -fontsize for yticklabels +%qYlabelcolor -color (RGB) for yticks and yticklabels e.g., [0 0 0] +%qYunits -display units for x axes. "on" or "off" +%qMinorTicksY - +%qplotArrayStr -names for plotting bins/channels/erpsets e.g., {'FCz','FC1','FC2'} +%qERPArray -index(es) of the selected erpsets from ALLERP e.g., [1 2 3] +%qlegcolor - legand text color. 1: using black color; 0 same as the +% line colors +%qlegcolumns -Number of columns for legend names. e.g., 1 or 2,.... +%qFigbgColor -Background color of figure. The default is [1 1 1] +%qLabelcolor -Channel/Bin/ERPset label color in RGB, e.g., [0 0 0] +%qYtickdecimal -determine the number of decimals of y tick labels +% - e.g., -6.0 -3.0 0.0 3.0 6.0 if qYtickdecimal is 1 +%qXtickdecimal -determine the nunmber of decimals of x tick labels +% -e.g., -0.2 0.0 0.2 0.4 0.6 0.8 if qXtickdecimal is 1 +%qXdisFlag -the way is to display xticks: 1 is in millisecond, 0 is in second + + + +% *** This function is part of EStudio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 & 2023 + + +function f_ploterpserpviewer(ALLERP,qCURRENTPLOT, qPLOTORG,qbinArray,qchanArray,qGridposArray,plotBox,qBlc,qLineColorspec,qLineStylespec,qLineMarkerspec,qLineWidthspec,... + qLegendName,qLegendFont,qLegendFontsize,qCBELabels,qLabelfont,qLabelfontsize,qPolarityWave,qSEM,qTransparency,qGridspace,qtimeRange,qXticks,qXticklabel,... + qXlabelfont,qXlabelfontsize,qXlabelcolor,qMinorTicksX,qXunits,qYScales,qYticks,qYticklabel,qYlabelfont,qYlabelfontsize,qYlabelcolor,qYunits,qMinorTicksY,... + qplotArrayStr,qERPArray,qlegcolor,qlegcolumns,qFigureName,qFigbgColor,qLabelcolor,qYtickdecimal,qXtickdecimal,qXdisFlag) + +if nargin<1 + help f_ploterpserpviewer; + return +end + +if isempty(ALLERP) + msgboxText = 'No ALLERP was found!'; + title_msg = 'EStudio: f_ploterpserpviewer() error:'; + errorfound(msgboxText, title_msg); + return; +end + + +if nargin<40 || isempty(qERPArray) + qERPArray = [1:length(ALLERP)]; +end + +if max(qERPArray)>length(ALLERP) + qERPArray=length(ALLERP); +end + +[chanStrdef,binStrdef] = f_geterpschanbin(ALLERP,[1:length(ALLERP)]); + +if nargin<5 + qchanArray = 1:length(chanStrdef); +end +Existchan = f_existvector([1:length(chanStrdef)],qchanArray); +if Existchan==1 + qchanArray = [1:length(chanStrdef)]; + Existchan =1; +end + + +if nargin<4 + qbinArray = 1:length(binStrdef); +end +Existbin = f_existvector([1:length(binStrdef)],qbinArray); +if Existbin==1 + qbinArray = 1:length(binStrdef); + Existbin = 1; +end + +if nargin<3 + qPLOTORG = [1 2 3];%%Channel is "Grid"; Bin is "Overlay"; ERPst is page +end +%%check ALLERP and adjust "qPLOTORG" +for Numofselectederp = 1:numel(qERPArray) + SrateNum_mp(Numofselectederp,1) = ALLERP(qERPArray(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(qERPArray(Numofselectederp)).datatype; +end +if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==2 && qPLOTORG(2)==1) + +else + if length(unique(Datype))~=1 + msgboxText = 'Type of data across ERPsets is different!'; + title_msg = 'EStudio: f_ploterpserpviewer() error:'; + errorfound(msgboxText, title_msg); + return; + end + if length(unique(SrateNum_mp))~=1 + msgboxText = 'Sampling rate varies across ERPsets!'; + title_msg = 'EStudio: f_ploterpserpviewer() error:'; + errorfound(msgboxText, title_msg); + return; + end +end + +if nargin<2|| isempty(qCURRENTPLOT) + qCURRENTPLOT = 1; +end +if ~isnumeric(qCURRENTPLOT) + msgboxText = 'qCURRENTPLOT must be a numeric!'; + title_msg = 'EStudio: f_ploterpserpviewer() error:'; + errorfound(msgboxText, title_msg); + return; +end +if qCURRENTPLOT <=0 + msgboxText = 'qCURRENTPLOT must be a positive numeric!'; + title_msg = 'EStudio: f_ploterpserpviewer() error:'; + errorfound(msgboxText, title_msg); + return; +end + +if qPLOTORG(1) ==1 + plotArray = qchanArray; +elseif qPLOTORG(1) ==2 + plotArray = qbinArray; +elseif qPLOTORG(1) ==3 + plotArray = qERPArray; +else + plotArray = qchanArray; +end +plotBoxdef = f_getrow_columnautowaveplot(plotArray); +if isempty(qPLOTORG) || numel(qPLOTORG)~=3 || numel(unique(qPLOTORG)) ~=3 || min(qPLOTORG)<0 || max(qPLOTORG)>3 + qPLOTORG = [1 2 3]; +end + +if qPLOTORG(2) ==1 %% if the selected Channel is "Grid" + OverlayArraydef = qchanArray; + for Numofchan = 1:numel(qchanArray) + LegendNamedef{Numofchan,1} =char(chanStrdef(qchanArray(Numofchan))); + end +elseif qPLOTORG(2) == 2 %% if the selected Bin is "Grid" + OverlayArraydef = qbinArray; + for Numofbin = 1:numel(qbinArray) + LegendNamedef{Numofbin,1} = char(binStrdef(qbinArray(Numofbin))); + end +elseif qPLOTORG(2) == 3%% if the selected ERPset is "Grid" + OverlayArraydef = qERPArray; + for Numoferpset = 1:numel(qERPArray) + try + LegendNamedef{Numoferpset} = ALLERPIN(qERPArray(Numoferpset)).erpname; + catch + LegendNamedef{Numoferpset} = ''; + end + end +else + OverlayArraydef = qbinArray; + for Numofbin = 1:numel(qbinArray) + LegendNamedef{Numofbin,1} = char(binStr(qbinArray(Numofbin))); + end +end + +LineColordef = [0 0 0;1 0 0;0 0 1;0 1 0;1,0.65 0;0 1 1;1 0 1;0.5 0.5 0.5;0.94 0.50 0.50;0 0.75 1;0.57 0.93 0.57;1 0.55 0;1 0.75 0.80;1 0.84 0];%% get from:https://htmlcolorcodes.com/color-names/ +LineMarkerdef = {'none','none','none','none','+','o','*'}; +LineStyledef = {'-','--',':','-.','-','-','-',}; +[ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] = f_geterpdata(ALLERP,[1:length(ALLERP)],qPLOTORG); +%%%%%%%%%%%%%%%%%%%%-------------------------------------------------------- + +if qPLOTORG(1) ==1 %% if the selected Channel is "Grid" + plotArray = qchanArray; + for Numofchan = 1:numel(plotArray) + try + plotArrayStrdef{Numofchan} = chanStrdef{plotArray(Numofchan)}; + catch + plotArrayStrdef{Numofchan} = 'no'; + end + end +elseif qPLOTORG(1) == 2 %% if the selected Bin is "Grid" + plotArray = qbinArray; + for Numofbin = 1:numel(plotArray) + try + plotArrayStrdef{Numofbin} = binStrdef{plotArray(Numofbin)}; + catch + plotArrayStrdef{Numofbin} = 'no'; + end + end +elseif qPLOTORG(1) == 3%% if the selected ERPset is "Grid" + plotArray = qERPArray; + for Numoferp = 1:numel(plotArray) + try + plotArrayStrdef{Numoferp} = ALLERP(plotArray(Numoferp)).erpname; + catch + plotArrayStrdef{Numoferp} = 'no'; + end + end +else + plotArray = qchanArray; + for Numofchan = 1:numel(chanArray) + try + plotArrayStrdef{Numofchan} = chanStrdef{plotArray(Numofchan)}; + catch + plotArrayStrdef{Numofchan} = 'no'; + end + end +end + + +if nargin<48 || (qXdisFlag~=1 && qXdisFlag~=0) + qXdisFlag =1; +end + + +if nargin<47 || qXtickdecimal<0 + qXtickdecimal =0; +else + qXtickdecimal =ceil(qXtickdecimal); +end + + + +if nargin<46 || numel(qYtickdecimal)~=1 || qYtickdecimal<0 + qYtickdecimal =1; +end + + + +if nargin<45 %%label text color + qLabelcolor = [0 0 0 ]; +end +if isempty(qLabelcolor) || numel(qLabelcolor)~=3 || max(qLabelcolor)>1 || min(qLabelcolor)<0 + qLabelcolor = [0 0 0]; +end + +if nargin <44%% Figure background color + qFigbgColor = [1 1 1]; +end +if isempty(qFigbgColor) || numel(qFigbgColor)~=3 || max(qFigbgColor)>1 || min(qFigbgColor)<0 + qFigbgColor = [1 1 1]; +end + + +if nargin< 43 + qFigureName= ''; +end + + +if nargin <42 + qlegcolumns=1; +end + +if qlegcolumns<0 || isempty(qlegcolumns) + qlegcolumns =1; +end + +if nargin <41 + qlegcolor=1; +end + +if isempty(qlegcolor) || (qlegcolor~=1 && qlegcolor~=0) + qlegcolor=1; +end + +if nargin <39 || isempty(qplotArrayStr) + qplotArrayStr = plotArrayStrdef; +end + + +%% +if nargin <38 + qMinorTicksY = 0; +end + +%%display y units? +if nargin<37 + qYunits = 'on'; +end + +%%ylable color +if nargin <36 + qYlabelcolor = [0 0 0]; +end + +%%ylabel fontsize +if nargin<35 + qYlabelfontsize =12; +end + +%%ylable font +if nargin <34 + qYlabelfont = 'Geneva'; +end + +%%display ylabels? +if nargin<33 + qYticklabel = 'on'; +end + +%%yticks +datresh = squeeze(ERPdatadef(qchanArray,:,qbinArray,qERPArray)); +yymax = max(datresh(:)); +yymin = min(datresh(:)); +if abs(yymax)<1 && abs(yymin)<1 + scalesdef(1:2) = [yymin*1.2 yymax*1.1]; % JLC. Mar 11, 2015 +else + scalesdef(1:2) = [floor(yymin*1.2) ceil(yymax*1.1)]; % JLC. Sept 26, 2012 +end +yylim_out = f_erpAutoYLim(ALLERP, qERPArray,qPLOTORG,qbinArray, qchanArray,qCURRENTPLOT); +try + Yscalesdef = yylim_out(qCURRENTPLOT,:); +catch + Yscalesdef = scalesdef; +end +if nargin <32 + if isempty(qYScales) + qYticks = default_amp_ticks_viewer(Yscalesdef); + else + qYticks = default_amp_ticks_viewer(qYScales); + end +end + +%%y scale +if nargin <31 + qYScales = Yscalesdef; +end + +%%display x units? +if nargin <30 + qXunits = 'on'; +end +%%minor of xlabel +if nargin <29 + qMinorTicksX = 0; +end + +%%xlabel color +if nargin <28 + qXlabelcolor = [0 0 0]; +end + +%%xlabel fontsize +if nargin <27 + qXlabelfontsize = 12; +end + + +%%xlabel font +if nargin <26 + qXlabelfont= 'Geneva'; +end + +%%disply xtick labels ? +if nargin<25 + qXticklabel = 'on'; +end + +%%xticks +try + ERPIN = ALLERP(qCURRENTPLOT); +catch + ERPIN = ALLERP(end); +end + +try + [timeticksdef stepX]= default_time_ticks_studio(ERPIN, qtimeRange); + timeticksdef = str2num(char(timeticksdef)); +catch + timeticksdef = []; +end +if nargin<24 + qXticks = timeticksdef; +end + +%%------------------------time range of plot wave-------------------------- +if nargin<23 + qtimeRange(1) = timeRangedef(1); + qtimeRange(2) = timeRangedef(end); +end + +if isempty(qtimeRange) + qtimeRange(1) = timeRangedef(1); + qtimeRange(2) = timeRangedef(end); +end + +%%------------------------------------Grid space--------------------------- +if nargin<22 + qGridspace =[1 10; 1 10]; +end +if isempty(qGridspace) || numel(qGridspace)~=4 || (size(qGridspace,1)~=2 || size(qGridspace,2)~=2) + qGridspace =[1 10; 1 10]; +else + [rowgs,columgs] = size(qGridspace); + if rowgs~=2 || columgs~=2 + qGridspace =[1 10; 1 10]; + else + if qGridspace(1,1)~=1 && qGridspace(1,1)~=2 + qGridspace(1,1) =1; + end + if (qGridspace(1,1)==1 && qGridspace(1,2)<=0) + qGridspace(1,2) =10; + elseif (qGridspace(1,1)==2 && (qGridspace(1,2)<=0|| qGridspace(1,2)>100)) + qGridspace(1,2) =10; + end + if qGridspace(2,1)~=1 && qGridspace(2,1)~=2 + qGridspace(2,1) =1; + end + if (qGridspace(2,1)==1 && qGridspace(2,2)<=0) + qGridspace(2,2) =10; + elseif (qGridspace(2,1)==2 && (qGridspace(2,2)<=0|| qGridspace(2,2)>=100)) + qGridspace(2,2) =10; + + end + end +end + + +%%---------------------------------Transparency---------------------------- +if nargin <21 + qTransparency = 0; +end + +%%standard error of mean +if nargin <20 + qSME = 0; +end + + +%%polarity of wave; the default is positive up +if nargin <19 + qPolarityWave = 1; +end + +%%fontsize of channel/bin/erpset label +if nargin <18 + qLabelfontsize = 12; +end + +%%font of channel/bin/erpset label +if nargin <17 + qLabelfont= 'Geneva'; +end + +%%location of channel/bin/erpset label +if nargin<16 + qCBELabels =[50 100 1]; +end + +%%fontsize of legend name +if nargin <15 + qLegendFontsize = 12; +end + +%%font of legend name +if nargin <14 + qLegendFont = 'Geneva'; +end + +%%legend name +if nargin < 13 + qLegendName=LegendNamedef; +end + +%%line width +for Numofcolor = 1:numel(OverlayArraydef) + qLineWidthspecdef(1,Numofcolor) =1; +end +if nargin < 12 + qLineWidthspec = qLineWidthspecdef; +end + + +%%line marker +for Numofcolor = 1:numel(OverlayArraydef) + NumIndex = ceil(Numofcolor/7); + try + qLineMarkerspecdef{1,Numofcolor} = LineMarkerdef{NumIndex}; + catch + qLineMarkerspecdef{1,Numofcolor} = 'none'; + end +end +if nargin< 11 + qLineMarkerspec = qLineMarkerspecdef; +end + + +%%line style +for Numofcolor = 1:numel(OverlayArraydef) + NumIndex = ceil(Numofcolor/7); + try + qLineStylespecdef{1,Numofcolor} = LineStyledef{NumIndex}; + catch + qLineStylespecdef{1,Numofcolor} = '-'; + end +end +if nargin< 10 + qLineStylespec = qLineStylespecdef; +end + + +%%line color +for Numofcolor = 1:numel(OverlayArraydef) + Numindex = floor(Numofcolor/14); + if Numindex==0 + try + qLineColorspecdef(Numofcolor,:) = LineColordef(Numofcolor,:); + catch + qLineColorspecdef(Numofcolor,:) = [0 0 0]; + end + elseif Numindex~=0 + if floor(Numofcolor/14) ==ceil(Numofcolor/14) + qLineColorspecdef(Numofcolor,:) = LineColordef(14,:); + else + try + qLineColorspecdef(Numofcolor,:) = LineColordef(Numofcolor-14*Numindex,:); + catch + qLineColorspecdef(Numofcolor,:) = [0 0 0]; + end + end + else + try + qLineColorspecdef(Numofcolor,:) = LineColordef(14,:); + catch + qLineColorspecdef(Numofcolor,:) = [0 0 0]; + end + end +end +if nargin< 9 + qLineColorspec = qLineColorspecdef; +end + + + +if nargin<8 + qBlc = 'none'; +end + +if nargin<7 || isempty(plotBox) || numel(plotBox)~=2 + plotBox =plotBoxdef; +end + + +NumRows = ceil(plotBox(1)); +NumColumns = ceil(plotBox(2)); +if nargin<6 || isempty(qGridposArray) + count = 0; + for Numofrow = 1:NumRows %%organization of Grid + for Numofcolumn = 1:NumColumns + count = count +1; + if count> numel(plotArray) + GridposArraydef(Numofrow,Numofcolumn) =0; + else + GridposArraydef(Numofrow,Numofcolumn) = plotArray(count); + end + end + end + qGridposArray = GridposArraydef; +end +%%check elements in qGridposArray +plotArray = reshape(plotArray,1,[]); +for Numofrows = 1:size(qGridposArray,1) + for Numofcolumns = 1:size(qGridposArray,2) + SingleGridpos = qGridposArray(Numofrows,Numofcolumns); + if SingleGridpos~=0 + ExistGridops = f_existvector(plotArray,SingleGridpos); + if ExistGridops==1 + qGridposArray(Numofrows,Numofcolumns) =0; + else + [xpos,ypos]= find(plotArray==SingleGridpos); + qGridposArray(Numofrows,Numofcolumns) =ypos; + end + end + end +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%-------------------------------Plot wave-------------------------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +for Numoferpset = 1:length(ALLERP) + DataType{Numoferpset} = ALLERP(Numoferpset).datatype; +end +DataType = unique(DataType); + +ALLERPBls = ALLERP; +% +%%baseline correction +if length(DataType)==1 && strcmpi(char(DataType), 'ERP') + if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==2 && qPLOTORG(2)==1) + ERPArraybls = qERPArray(qCURRENTPLOT); + else + ERPArraybls = qERPArray; + end + for Numoferpset = ERPArraybls + ERP = ALLERP(Numoferpset); + if ~strcmpi(qBlc,'no') && ~strcmpi(qBlc,'none')%% when the baseline correction is "pre","post","whole" + + if strcmpi(qBlc,'pre') + indxtimelock = find(ERP.times==0) ; % zero-time locked + aa = 1; + elseif strcmpi(qBlc,'post') + indxtimelock = length(ERP.times); + aa = find(ERP.times==0); + elseif strcmpi(qBlc,'all') + indxtimelock = length(ERP.times); + aa = 1; + else + fs = ERP.srate; + kktime =1000; + toffsa = abs(round(ERP.xmin*fs))+1; % +1 October 2nd 2008 + blcnum = qBlc/kktime; % from msec to secs 03-28-2009 + % + % Check & fix baseline range + % + if blcnum(1)ERP.xmax + blcnum(2) = ERP.xmax; + end + aa = round(blcnum(1)*fs)+ toffsa; % in samples 12-16-2008 + indxtimelock = round(blcnum(2)*fs) + toffsa; % in samples + end + + for Numofchan = qchanArray + for Numofbin = qbinArray + if Numofchan<= ERP.nchan && Numofbin<= ERP.nbin + baselineV = mean(ERP.bindata(Numofchan,aa:indxtimelock,Numofbin)); + ERP.bindata(Numofchan,:,Numofbin) = ERP.bindata(Numofchan,:,Numofbin)-baselineV; + end + end + end + end + ALLERPBls(Numoferpset) = ERP; + end + +else + qBlc = 'no'; +end + + +% [ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] +[ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] = f_geterpdata(ALLERPBls,qERPArray,qPLOTORG,qCURRENTPLOT); +datatype = ''; +if qPLOTORG(1)==1 && qPLOTORG(2)==2 %% Array is plotnum by samples by datanum + if qCURRENTPLOT> numel(qERPArray) + qCURRENTPLOT= length(qERPArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + % if isempty(timeRangedef) + timeRangedef = ALLERPBls(qERPArray(qCURRENTPLOT)).times; + % end + try + fs= ALLERPBls(qERPArray(qCURRENTPLOT)).srate; + datatype = ALLERPBls(qERPArray(qCURRENTPLOT)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==2 && qPLOTORG(2)==1 + if qCURRENTPLOT> length(qERPArray) + qCURRENTPLOT= length(qERPArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindata = permute(bindata,[3 2 1 4]); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindataerror = permute(bindataerror,[3 2 1 4]); + if isempty(timeRangedef) + timeRangedef = ALLERPBls(qERPArray(qCURRENTPLOT)).times; + end + try + fs= ALLERPBls(qERPArray(qCURRENTPLOT)).srate; + datatype = ALLERPBls(qERPArray(qCURRENTPLOT)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==1 && qPLOTORG(2)==3 %%Grid is channel; Overlay is ERPsets; Page is bin + if qCURRENTPLOT> numel(qbinArray) + qCURRENTPLOT = numel(qbinArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindata = permute(bindata,[1 2 4 3]); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindataerror = permute(bindataerror,[1 2 4 3]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==3 && qPLOTORG(2)==1%%Grid is ERPsets; Overlay is channel + if qCURRENTPLOT> numel(qbinArray) + qCURRENTPLOT = numel(qbinArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindata = permute(bindata,[4 2 1 3]); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindataerror = permute(bindataerror,[4 2 1 3]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==2 && qPLOTORG(2)==3%%Grid is bin; Overlay is ERPset; Page is channel + if qCURRENTPLOT> numel(qchanArray) + qCURRENTPLOT = numel(qchanArray); + end + bindata = ERPdatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindata = permute(bindata,[3 2 4 1]); + bindataerror = ERPerrordatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindataerror = permute(bindataerror,[3 2 4 1]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==3 && qPLOTORG(2)==2%%Grid is ERPset; Overlay is bin; Page is channel + if qCURRENTPLOT> numel(qchanArray) + qCURRENTPLOT = numel(qchanArray); + end + bindata = ERPdatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindata = permute(bindata,[4 2 3 1]); + bindataerror = ERPerrordatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindataerror = permute(bindataerror,[4 2 3 1]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +else + if qCURRENTPLOT> length(qERPArray) + qCURRENTPLOT= length(qERPArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + if isempty(timeRangedef) + timeRangedef = ALLERPBls(qERPArray(qCURRENTPLOT)).times; + end + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +end + +if isempty(qtimeRange) + qtimeRange = [timeRangedef(1) timeRangedef(end)]; +end + + +Numrows = plotBox(1); +Numcolumns = plotBox(2); + + +pboxTotal = 1:Numrows*Numcolumns; +corners = linspace(Numrows*Numcolumns-Numcolumns+1,Numrows*Numcolumns,Numcolumns); +pboxplot = setxor(pboxTotal, corners); +if isempty(pboxplot) + pboxplot = 1; +end + +NumOverlay = size(bindata,3); + + +%%get y axis +y_scale_def = [1.1*min(bindata(:)),1.1*max(bindata(:))]; +yMaxdef = ceil(max(bindata(:)))-floor(min(bindata(:))); +try + isyaxislabel = qGridspace(1,1); + Ypert = qGridspace(1,2); +catch + isyaxislabel = 1; + Ypert = 10; +end + +if isempty( qYScales) + qYScales = [floor(min(bindata(:))),ceil(max(bindata(:)))]; +end + +if isyaxislabel==1 %% y axis GAP + if Ypert<0 + Ypert = 10; + end + if ~isempty(qYScales) + if numel(qYScales)==2 + yscaleall = qYScales(end)-qYScales(1); + else + yscaleall = 2*max(abs(qYScales)); + qYScales = [-max(abs(qYScales)),max(abs(qYScales))]; + end + if yscaleall < y_scale_def(2)-y_scale_def(2) + yscaleall = y_scale_def(2)-y_scale_def(2); + end + + for Numofrows = 1:Numrows + OffSetY(Numofrows) = yscaleall*(Numrows-Numofrows)*(Ypert/100+1); + end + else + for Numofrows = 1:Numrows + OffSetY(Numofrows) = yMaxdef*(Numrows-Numofrows)*(Ypert/100+1); + end + end +else%% y axis Overlay + if Ypert>=100 || Ypert<=0 + Ypert = 40; + end + if ~isempty(qYScales) + if numel(qYScales)==2 + yscaleall = qYScales(end)-qYScales(1); + else + yscaleall = 2*max(abs(qYScales)); + qYScales = [-max(abs(qYScales)),max(abs(qYScales))]; + end + + if yscaleall < y_scale_def(2)-y_scale_def(2) + yscaleall = y_scale_def(2)-y_scale_def(2); + end + + if Numrows ==1 + OffSetY = 0; + else + for Numofrows = 1:Numrows-1 + OffSetY(Numofrows) = yscaleall*(Numrows-Numofrows)*(1-(Ypert/100)); + end + OffSetY(Numrows)=0; + end + else + qYScales = [ceil(max(bindata(:))), floor(min(bindata(:)))]; + if Numrows ==1 + OffSetY = 0; + else + for Numofrows = 1:Numrows-1 + OffSetY(Numofrows) = yMaxdef*(Numrows-Numofrows)*(1-(Ypert/100)); + end + OffSetY(Numrows)=0; + end + end +end + + + +%%X axis gap +try + isxaxislabel = qGridspace(2,1); + Xpert = qGridspace(2,2); +catch + isxaxislabel = 1; + Xpert = 10; +end +if isxaxislabel ~=1 && isxaxislabel~=2 + isxaxislabel = 1; +end + + +if isxaxislabel==1 && Xpert<=0 + Xpert =10; +elseif isxaxislabel==2 && (Xpert<=0 || Xpert >=100) + Xpert =40; +end +try + StepX = (timeRangedef(end)-timeRangedef(1))*(Xpert/100); +catch + beep; + disp('ERP.times only has one element.'); + return; +end +StepXP = ceil(StepX/(1000/fs)); + + + +%%check yticks +try + count =0; + ytickDis =[]; + for Numofytick = 1:numel(qYticks) + if qYticks(Numofytick) < qYScales(1) || qYticks(Numofytick) > qYScales(end) + count = count+1; + ytickDis(count) = Numofytick; + end + end + qYticks(ytickDis) = []; +catch +end +if isempty(qYticks) + qYticks = str2num(char(default_amp_ticks_viewer(qYScales))); +end + + + +%%Get the figure name which is to be plotted +if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==1 && qPLOTORG(2)==2) %% Page is ERPset + ERP = ALLERPBls(qCURRENTPLOT); + if isempty(ERP.filename) || strcmp(ERP.filename,'') + ERP.filename = 'still_not_saved!'; + end + if isempty(ERP.erpname) + fname = 'none'; + else + [pathstr, fname, ext] = fileparts(ERP.erpname); + end +elseif (qPLOTORG(1)==1 && qPLOTORG(2)==3) || (qPLOTORG(1)==3 && qPLOTORG(2)==1) %% Page is bin + fname = char(binStrdef{qbinArray(qCURRENTPLOT)}); + +elseif (qPLOTORG(1)==2 && qPLOTORG(2)==3) || (qPLOTORG(1)==3 && qPLOTORG(2)==2) + fname = char(chanStrdef{qchanArray(qCURRENTPLOT)}); +else + ERP = ALLERPBls(qCURRENTPLOT); + if isempty(ERP.filename) || strcmp(ERP.filename,'') + ERP.filename = 'still_not_saved!'; + end + if isempty(ERP.erpname) + fname = 'none'; + else + [pathstr, fname, ext] = fileparts(ERP.erpname); + end +end +extfig =''; +[pathstrfig, qFigureName, extfig] = fileparts(qFigureName) ; + + +if isempty(qFigureName) + fig_gui= figure('Name',['<< ' fname ' >> '],... + 'NumberTitle','on','color',qFigbgColor); + % fig_gui_wave = subplot(Numrows+1,1,[2:Numrows+1]); + hbig = subplot(Numrows+1,1,[2:Numrows+1]); + hold on; +end + +if ~isempty(qFigureName) + fig_gui= figure('Name',['<< ' qFigureName ' >> '],... + 'NumberTitle','on','color',qFigbgColor); + hbig = subplot(ceil(Numrows*5)+1,1,[2:ceil(Numrows*5)+1]); + hold on; + % hbig= axes('Parent',fig_gui_wave); +end + +set(fig_gui,'outerposition',get(0,'screensize'));%%Maximum figure +if ~isempty(extfig) + set(fig_gui,'visible','off'); +end + +try + y_scale_def(1) = min([1.1*y_scale_def(1),1.1*qYScales(1)]); + y_scale_def(2) = max([1.1*y_scale_def(2),1.1*qYScales(2)]); +catch +end + +%%--------------Plot ERPwave----------------- +stdalpha = qTransparency; +countPlot = 0; +for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + try + plotdatalabel = qGridposArray(Numofrows,Numofcolumns); + catch + plotdatalabel = 0; + end + + try + labelcbe = qplotArrayStr{plotdatalabel}; + catch + labelcbe = 'no'; + end + try + plotbindata = bindata(plotdatalabel,:,:,:); + catch + plotbindata = []; + end + + if plotdatalabel ~=0 && plotdatalabel<= numel(plotArray) && ~isempty(plotbindata) + countPlot =countPlot +1; + if qPolarityWave + data4plot = squeeze(bindata(plotdatalabel,:,:,1)); + else + data4plot = squeeze(bindata(plotdatalabel,:,:,1))*(-1); + end + + data4plot = reshape(data4plot,numel(timeRangedef),NumOverlay); + for Numofoverlay = 1:NumOverlay + [Xtimerange, bindatatrs] = f_adjustbindtabasedtimedefd(squeeze(data4plot(:,Numofoverlay)), timeRangedef,qtimeRange,fs); + PosIndexsALL = [Numofrows,Numcolumns]; + if isxaxislabel==2 + [~,XtimerangetrasfALL,~,~,~] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexsALL,StepXP); + else + [~,XtimerangetrasfALL,~] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexsALL,StepX,fs); + end + aerror = isnan(squeeze(bindataerror(plotdatalabel,:,Numofoverlay,1))); + [Xerror,yerro] = find(aerror==0); + PosIndexs = [Numofrows,Numofcolumns]; + if ~isempty(yerro) && qSEM>=1 &&stdalpha>0 %SEM + [Xtimerange, bindataerrtrs] = f_adjustbindtabasedtimedefd(squeeze(bindataerror(plotdatalabel,:,Numofoverlay,1)), timeRangedef,qtimeRange,fs); + if isxaxislabel==2 + [bindatatrs1,Xtimerangetrasf,qXtickstransf,TimeAdjustOut,XtimerangeadjustALL] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepXP); + else + [bindatatrs1,Xtimerangetrasf,qXtickstransf] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepX,fs); + end + yt1 = bindatatrs1 - bindataerrtrs.*qSEM; + yt2 = bindatatrs1 + bindataerrtrs.*qSEM; + % ciplot(yt1,yt2, Xtimerangetrasf, qLineColorspec(Numofoverlay,:), stdalpha); + fill(hbig,[Xtimerangetrasf fliplr(Xtimerangetrasf)],[yt2 fliplr(yt1)], qLineColorspec(Numofoverlay,:), 'FaceAlpha', stdalpha, 'EdgeColor', 'none'); + % set(hbig, 'InvertHardcopy', 'off', 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait'); + end + if isxaxislabel==2 + [bindatatrs,Xtimerangetrasf,qXtickstransf,TimeAdjustOut,XtimerangeadjustALL] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepXP); + else + [bindatatrs,Xtimerangetrasf,qXtickstransf] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepX,fs); + end + hplot(Numofoverlay) = plot(hbig,Xtimerangetrasf, bindatatrs,'LineWidth',qLineWidthspec(Numofoverlay),... + 'Color', qLineColorspec(Numofoverlay,:), 'LineStyle',qLineStylespec{Numofoverlay},'Marker',qLineMarkerspec{Numofoverlay}); + % qLegendName{Numofoverlay} = strrep(qLegendName{Numofoverlay},'_','\_'); % trick for dealing with '_'. JLC + % set(hplot(Numofoverlay),'DisplayName', qLegendName{Numofoverlay}); + end + + if numel(OffSetY)==1 && OffSetY==0 + if ~qPolarityWave + YscalesNew = sort(y_scale_def*(-1)); + else + YscalesNew = y_scale_def; + end + set(hbig,'ylim',YscalesNew); + else + if qPolarityWave + ylimleftedge = floor(y_scale_def(1)); + ylimrightedge = ceil(y_scale_def(end))+OffSetY(1); + else + ylimleftedge = -abs(ceil(y_scale_def(end))); + ylimrightedge = ceil(abs(y_scale_def(1)))+OffSetY(1); + end + set(hbig,'ylim',[ylimleftedge,ylimrightedge]); + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------Adjust y axis------------------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + props = get(hbig); + if qPolarityWave + props.YTick = qYticks+OffSetY(Numofrows); + else + props.YTick = fliplr (-1*qYticks)+OffSetY(Numofrows); + end + props.YTickLabel = cell(numel(props.YTick),1); + + + for Numofytick = 1:numel(props.YTick) + props.YTickLabel(Numofytick) = {num2str(props.YTick(Numofytick))}; + end + + [x,y_0] = find(Xtimerange==0); + if isempty(y_0) + y_0 = 1; + end + myY_Crossing = Xtimerangetrasf(y_0); + tick_top = 0; + + if countPlot ==1 + ytick_bottom = -props.TickLength(1)*diff(props.XLim); + ytick_bottomratio = abs(ytick_bottom)/diff(props.XLim); + else + try + ytick_bottom = ytick_bottom; + ytick_bottomratio = ytick_bottomratio; + catch + ytick_bottom = -props.TickLength(1)*diff(props.XLim); + ytick_bottomratio = abs(ytick_bottom)/diff(props.XLim); + end + end + %%add yunits + if qPolarityWave%%Positive up + yunitsypos = 0.98*qYScales(end); + else + yunitsypos = 0.95*abs(qYScales(1)); + end + if strcmpi( datatype,'ERP') + yunitstr = '\muV'; + elseif strcmpi( datatype,'CSD') + yunitstr = '\muV/m^2'; + else + yunitstr = ''; + end + if strcmpi(qYunits,'on') + text(hbig,myY_Crossing+abs(ytick_bottom),yunitsypos+OffSetY(Numofrows),yunitstr, 'FontName',qYlabelfont,'FontSize',qYlabelfontsize,'HorizontalAlignment', 'left', 'Color', qYlabelcolor); + end + + if ~isempty(props.YTick) + ytick_y = repmat(props.YTick, 2, 1); + ytick_x = repmat([tick_top;ytick_bottom] +myY_Crossing, 1, length(props.YTick)); + line(hbig,ytick_x(:,:), ytick_y(:,:), 'color', 'k','LineWidth',1); + try + [~,y_below0] =find(qYticks<0); + if isempty(y_below0) && qYScales(1)<0 + line(hbig,ytick_x(:,:), ones(2,1)*(qYScales(1)+OffSetY(Numofrows)), 'color', 'k','LineWidth',1); + end + [~,y_over0] =find(qYticks>0); + if isempty(y_over0) && qYScales(2)>0 + line(hbig,ytick_x(:,:), ones(2,1)*(qYScales(2)+OffSetY(Numofrows)), 'color', 'k','LineWidth',1); + end + catch + end + end + + if ~isempty(qYScales) && numel(qYScales)==2 %qYScales(end))+OffSetY(1) + if qPolarityWave==0 + qYScalestras = fliplr (-1*qYScales); + else + qYScalestras = qYScales; + end + plot(hbig,ones(numel(qYScalestras),1)*myY_Crossing, qYScalestras+OffSetY(Numofrows),'k','LineWidth',1); + else + if ~isempty(y_scale_def) && numel(unique(y_scale_def))==2 + if qPolarityWave==0 + qYScalestras = fliplr (-1*y_scale_def); + else + qYScalestras = y_scale_def; + end + + plot(hbig,ones(numel(qYScales),1)*myY_Crossing, qYScalestras+OffSetY(Numofrows),'k','LineWidth',1); + else + + end + end + + + nYTicks = length(props.YTick); + for iCount = 1:nYTicks + if qPolarityWave + ytick_label= sprintf(['%.',num2str(qYtickdecimal),'f'],str2num(char(props.YTickLabel(iCount, :)))-OffSetY(Numofrows)); + else + qyticktras = fliplr(-1*qYticks); + ytick_label= sprintf(['%.',num2str(qYtickdecimal),'f'],-qyticktras(iCount)); + end + % end + if str2num(char(ytick_label)) ==0 || (str2num(char(ytick_label))<0.0001 && str2num(char(ytick_label))>0) || (str2num(char(ytick_label))>-0.0001 && str2num(char(ytick_label))<0) + ytick_label = ''; + end + if ~strcmpi(qYticklabel,'on') + ytick_label = ''; + end + text(hbig,myY_Crossing-2*abs(ytick_bottom),props.YTick(iCount), ... + ytick_label, ... + 'HorizontalAlignment', 'right', ... + 'VerticalAlignment', 'middle', ... + 'FontSize', qYlabelfontsize, ... + 'FontName', qYlabelfont, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits,... + 'Color',qYlabelcolor); + end + + %%Minor Y + if qMinorTicksY(1) + set(hbig,'YMinorTick','on') + try + MinorTicksYValue = qMinorTicksY(2:end); + catch + MinorTicksYValue = []; + end + if ~isempty(MinorTicksYValue) + MinorTicksYValue(find(MinorTicksYValueqYScales(end))) = [];%% check the minorticks based on the right edge of yticks + props.YAxis.TickValues = MinorTicksYValue; + if ~isempty( props.YAxis.TickValues) + ytick_y = repmat( props.YAxis.TickValues+OffSetY(Numofrows), 2, 1); + ytick_x = repmat([tick_top;2*ytick_bottom/3] +myY_Crossing, 1, length( props.YAxis.TickValues)); + line(hbig,ytick_x(:,:), ytick_y(:,:), 'color', 'k','LineWidth',1); + end + end + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------Adjust x axis------------------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + props.XTick = qXtickstransf; + props.XTickLabel = cell(numel(qXticks),1); + for Numofytick = 1:numel(props.XTick) + props.XTickLabel(Numofytick) = {num2str(qXticks(Numofytick))}; + end + myX_Crossing = OffSetY(Numofrows); + if countPlot ==1 + xtick_bottom = -props.TickLength(2)*max(props.YLim); + if abs(xtick_bottom)/max(props.YLim) > ytick_bottomratio + xtick_bottom = -ytick_bottomratio*max(props.YLim); + end + else + try + xtick_bottom = xtick_bottom; + catch + xtick_bottom = -props.TickLength(2)*max(props.YLim); + if abs(xtick_bottom)/max(props.YLim) > ytick_bottomratio + xtick_bottom = -ytick_bottomratio*max(props.YLim); + end + end + end + if ~isempty(props.XTick) + xtick_x = repmat(props.XTick, 2, 1); + xtick_y = repmat([xtick_bottom; tick_top] + myX_Crossing, 1, length(props.XTick)); + line(hbig,xtick_x, xtick_y, 'color', 'k','LineWidth',1); + end + [x_xtick,y_xtick] = find(props.XTick==0); + if ~isempty(y_xtick) + props.XTick(y_xtick) = 2*xtick_bottom; + end + plot(hbig,Xtimerangetrasf, myX_Crossing.*ones(numel(Xtimerangetrasf),1),'k','LineWidth',1); + nxTicks = length(props.XTick); + + for iCount = 1:nxTicks + xtick_label = (props.XTickLabel(iCount, :)); + if strcmpi(qXticklabel,'on') + if strcmpi(xtick_label,'0') + xtick_label = ''; + end + else + xtick_label = ''; + end + if qXdisFlag ==1%%in millisecond + xtick_label= sprintf(['%.',num2str(qXtickdecimal),'f'],str2num(char(xtick_label))); + else%% in second + xtick_label= sprintf(['%.',num2str(qXtickdecimal),'f'],str2num(char(xtick_label))/1000); + end + + if strcmpi(qXunits,'on') && (iCount== nxTicks) && qXdisFlag ==1 + xtick_label = strcat(char(xtick_label),32,'ms'); + elseif strcmpi(qXunits,'on') && (iCount== nxTicks) && qXdisFlag ==0 + xtick_label = strcat(char(xtick_label),32,'s'); + end + + text(hbig,props.XTick(iCount), xtick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', qXlabelfontsize, ... + 'FontName', qXlabelfont, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits,... + 'Color',qXlabelcolor); + end + %%-----------------minor X--------------- + % timewindow_bin = Xtimerange(2)-Xtimerange(1); + % xlimrightedge = timewindow_bin*(numel(Xtimerange)*Numcolumns+StepXP*(Numcolumns-1)-1); + set(hbig,'xlim',[Xtimerange(1),Xtimerangetrasf(end)]); + if qMinorTicksX(1) + set(hbig,'XMinorTick','on'); + if isxaxislabel==2 + xlimrightedgemin = TimeAdjustOut; + else + timewindow_bin = Xtimerange(2)-Xtimerange(1); + xlimrightedgemin = timewindow_bin*(numel(Xtimerange)*(Numofcolumns-1)+StepXP*(Numofcolumns-1)); + end + try + MinorTicksXValue = qMinorTicksX(2:end); + catch + MinorTicksXValue = []; + end + if ~isempty(MinorTicksXValue) + MinorTicksXValue(find(MinorTicksXValueXtimerange(end))) = [];%% check the xminorticks based on the right edge of xticks + props.XAxis.TickValues = unique(MinorTicksXValue+xlimrightedgemin); + if ~isempty(props.XAxis.TickValues) + xtick_x = repmat(props.XAxis.TickValues, 2, 1); + xtick_y = repmat([2*xtick_bottom/3; tick_top] + myX_Crossing, 1, length(props.XAxis.TickValues)); + line(hbig,xtick_x, xtick_y, 'color', 'k','LineWidth',1); + end + end + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%------------------channel/bin/erpset label-----------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if ~isempty(qCBELabels) + try + ypercentage=qCBELabels(2); + catch + ypercentage =100; + end + try + iscenter = qCBELabels(3); + catch + iscenter =1; + end + + % if qPolarityWave %%polarity up + ypos_LABEL = (qYScalestras(end)-qYScalestras(1))*(ypercentage)/100+qYScalestras(1); + % else %% negative up + % ypos_LABEL = ((qYScalestras(end)-qYScalestras(1))*(ypercentage)/100+qYScalestras(1)); + % end + try + xpercentage=qCBELabels(1); + catch + xpercentage = 50; + end + xpos_LABEL = (Xtimerangetrasf(end)-Xtimerangetrasf(1))*xpercentage/100 + Xtimerangetrasf(1); + labelcbe = strrep(char(labelcbe),'_','\_'); + try + labelcbe = regexp(labelcbe, '\;', 'split'); + catch + end + if ~iscenter + text(hbig,xpos_LABEL,ypos_LABEL+OffSetY(Numofrows), char(labelcbe), 'FontName',qLabelfont,'FontSize',qLabelfontsize,'HorizontalAlignment', 'center', 'Color', qLabelcolor);%'FontWeight', 'bold', + else + text(hbig,xpos_LABEL,ypos_LABEL+OffSetY(Numofrows), char(labelcbe), 'FontName',qLabelfont,'FontSize',qLabelfontsize,'HorizontalAlignment', 'left', 'Color', qLabelcolor);%'FontWeight', 'bold', + end + end + else + % disp(['Data at',32,'R',num2str(Numofrows),',','C',num2str(Numofcolumns), 32,'is empty!']); + end + try + if isxaxislabel==2 + set(hbig,'xlim',[Xtimerange(1)-(Xtimerange(end)-Xtimerange(1)/10),XtimerangetrasfALL(end)+(Xtimerange(end)-Xtimerange(1))/10]); + else + set(hbig,'xlim',[Xtimerange(1)-(Xtimerange(end)-Xtimerange(1))/10,XtimerangetrasfALL(end)+(Xtimerange(end)-Xtimerange(1))/10]); + end + catch + + end + end%% end of columns + % ylim([(min(OffSetY(:))+qYScales(1)),1.1*(max(OffSetY(:))+qYScales(end))]); +end%% end of rows +set(hbig, 'XTick', [], 'YTick', [],'Box','off', 'Color','none','xcolor','none','ycolor','none'); + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%------------------------------legend name------------------------------%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +try + for Numofoverlay = 1:numel(hplot) + qLegendName{Numofoverlay} = strrep(qLegendName{Numofoverlay},'_','\_'); + LegendName{Numofoverlay} = char(strcat('\color[rgb]{',num2str(qLineColorspec(Numofoverlay,:)),'}',32,qLegendName{Numofoverlay})); + end + sh = subplot(ceil(Numrows*5)+1, 1, 1,'align'); + p = get(sh,'position'); + if qlegcolor ~=1 + try + h_legend = legend(sh,hplot,LegendName);%%,'Interpreter','none' + catch + h_legend = legend(sh,hplot,qLegendName); + end + else + h_legend = legend(sh,hplot,qLegendName); + end + set(h_legend,'FontSize',qLegendFontsize);%% legend name fontsize + set(h_legend,'FontName',qLegendFont);%%legend name font + set(h_legend, 'position', p); + set(h_legend,'NumColumns',qlegcolumns); + + %%increase height of the legend + HeightScaleFactor = 1; + NewHeight = h_legend.Position(4) * HeightScaleFactor; + h_legend.Position(2) = h_legend.Position(2) - (NewHeight - h_legend.Position(4)); + h_legend.Position(4) = NewHeight; + + + legend(sh,'boxoff'); + axis(sh,'off'); +catch + beep; + disp('Cannot display the legend names, please check "qGridposArray" or other parameters!'); +end +set(gcf,'color',qFigbgColor); +prePaperType = get(fig_gui,'PaperType'); +prePaperUnits = get(fig_gui,'PaperUnits'); +preUnits = get(fig_gui,'Units'); +prePaperPosition = get(fig_gui,'PaperPosition'); +prePaperSize = get(fig_gui,'PaperSize'); +% Make changing paper type possible +set(fig_gui,'PaperType',''); + +% Set units to all be the same +set(fig_gui,'PaperUnits','inches'); +set(fig_gui,'Units','inches'); +% Set the page size and position to match the figure's dimensions +paperPosition = get(fig_gui,'PaperPosition'); +position = get(fig_gui,'Position'); +set(fig_gui,'PaperPosition',[0,0,position(3:4)]); +set(fig_gui,'PaperSize',position(3:4)); + +%%save figure with different formats +if ~isempty(extfig) + [C_style,IA_style] = ismember_bc2(extfig,{'.pdf','.svg','.jpg','.png','.tif','.bmp','.eps'}); + figFileName = fullfile(pathstrfig,qFigureName); + try + switch IA_style + case 1 + print(fig_gui,'-dpdf',figFileName); + case 2 + print(fig_gui,'-dsvg',figFileName); + case 3 + print(fig_gui,'-djpeg',figFileName); + case 4 + print(fig_gui,'-dpng',figFileName); + + case 5 + print(fig_gui,'-dtiff',figFileName); + case 6 + print(fig_gui,'-dbmp',figFileName); + case 7 + print(fig_gui,'-depsc',figFileName); + otherwise + print(fig_gui,'-dpdf',figFileName); + end + catch + print(fig_gui,'-dpdf',figFileName); + end +end + +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_preparms_erpwaviewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_preparms_erpwaviewer.m new file mode 100755 index 00000000..bbfe4458 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_preparms_erpwaviewer.m @@ -0,0 +1,746 @@ + +% *** This function is part of EStudio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + + +function OutputViewerpar = f_preparms_erpwaviewer(FigureName,History) +OutputViewerpar = ''; +if nargin<1 + help f_preparms_erpwaviewer(); + return +end + +if nargin<2 + History = 'gui'; +end +try + ALLERPwaviewerin = evalin('base','ALLERPwaviewer'); + ERPwaviewerIN = ALLERPwaviewerin; +catch + beep; + disp('f_preparms_erpwaviewer() error: There is no "ALLERPwaviewer" on Workspace, please run the ERP wave viewer again.'); + return; +end + +ALLERPIN = ERPwaviewerIN.ALLERP; +ERPIN= ERPwaviewerIN.ERP; +CURRENTERPIN = ERPwaviewerIN.CURRENTERP; + +if isempty(CURRENTERPIN) || CURRENTERPIN > length(ALLERPIN) %%checking index of current erpset + CURRENTERPIN =length(ALLERPIN); +end + +%%checking the indices of the selected ERPsets +ERPsetArray = ERPwaviewerIN.SelectERPIdx; +if max(ERPsetArray) >length(ALLERPIN) + ERPsetArray =length(ALLERPIN); +end + +% +%%bin array and channel array +binArray = ERPwaviewerIN.bin; +chanArray = ERPwaviewerIN.chan; +PLOTORG =[1 2 3];%%The default parameters for plotting organization +%%The first element is for Grid; the second one is for Overlay; The last one is for Pages. +try + PLOTORG(1) = ERPwaviewerIN.plot_org.Grid ; + PLOTORG(2) = ERPwaviewerIN.plot_org.Overlay; + PLOTORG(3) = ERPwaviewerIN.plot_org.Pages; +catch + PLOTORG = [1 2 3]; %%"Channels" is Grid; "Bins" is Overlay; "ERPsets" is Pages. +end + + +GridLayoutop =1;%% need to further edit after discussed with Steve +try + GridLayoutop = ERPwaviewerIN.plot_org.gridlayout.op ; +catch + GridLayoutop =1; +end + +[chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPsetArray); + +plotArray = []; +if PLOTORG(1) ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + for Numofchan = 1:numel(chanArray) + try + plotArrayStrdef{Numofchan} = chanStr{plotArray(Numofchan)}; + catch + end + end +elseif PLOTORG(1) == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + for Numofchan = 1:numel(plotArray) + try + plotArrayStrdef{Numofchan} = binStr{plotArray(Numofchan)}; + catch + end + end +elseif PLOTORG(1) == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numofchan = 1:numel(plotArray) + try + plotArrayStrdef{Numofchan} = ALLERPIN(plotArray(Numofchan)).erpname; + catch + plotArrayStrdef{Numofchan} = 'none'; + end + end +end +GridLayoutop=0; +try + plotArrayStr = ERPwaviewerIN.plot_org.gridlayout.columFormat; +catch + plotArrayStr = ''; +end +if isempty(plotArrayStr) + plotArrayStr = plotArrayStrdef; +end + +% +%%Getting the specific setting of each position for Grid +plotBox = f_getrow_columnautowaveplot(plotArray);%% the first element is number of rows and the second element is the number of columns +GridposArray = []; +if GridLayoutop==1 + count = 0; + for Numofrow = 1:plotBox(1) %%organization of Grid + for Numofcolumn = 1:plotBox(2) + count = count +1; + if count> numel(plotArray) + GridposArray(Numofrow,Numofcolumn) =0; + else + GridposArray(Numofrow,Numofcolumn) = plotArray(count); + end + end + end +elseif GridLayoutop==0 + try %%try to use the user defined parameters for "Grid" + plotBox(1) = ERPwaviewerIN.plot_org.gridlayout.rows; + plotBox(2) = ERPwaviewerIN.plot_org.gridlayout.columns; + columFormat = ERPwaviewerIN.plot_org.gridlayout.columFormat; + DataDf = ERPwaviewerIN.plot_org.gridlayout.data; + for Numofrows = 1:plotBox(1) + for Numofcolumns = 1:plotBox(2) + SingleStr = char(DataDf{Numofrows,Numofcolumns}); + [C,IA] = ismember_bc2(SingleStr,columFormat); + if C ==1 + if IA < length(columFormat) + try + GridposArray(Numofrows,Numofcolumns) = plotArray(IA); + catch + GridposArray(Numofrows,Numofcolumns) =0; + end + elseif IA == length(columFormat) %%%If the element is 'None' + GridposArray(Numofrows,Numofcolumns) = 0; + end + else + GridposArray(Numofrows,Numofcolumns) = 0; + end + end + end + catch %%using the default parameters if there are some plorblems when using the defined parameters + count = 0; + for Numofrow = 1:plotBox(1) %%organization of Grid + for Numofcolumn = 1:plotBox(2) + count = count +1; + if count> numel(plotArray) + GridposArray(Numofrow,Numofcolumn) =0; + else + GridposArray(Numofrow,Numofcolumn) = plotArray(count); + end + end + end + end%%End of Try +end + +% +%%---------------line color, line style, line marker,linewidth------------- +LegendName = {''}; +if PLOTORG(2) ==1 %% if the selected Channel is "Grid" + OverlayArray = chanArray; + for Numofchan = 1:numel(chanArray) + LegendName{Numofchan,1} =char(chanStr(chanArray(Numofchan))); + end +elseif PLOTORG(2) == 2 %% if the selected Bin is "Grid" + OverlayArray = binArray; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end +elseif PLOTORG(2) == 3%% if the selected ERPset is "Grid" + OverlayArray = ERPsetArray; + for Numoferpset = 1:numel(ERPsetArray) + try + LegendName{Numoferpset} = ALLERPIN(ERPsetArray(Numoferpset)).erpname; + catch + LegendName{Numoferpset} = ''; + end + end +else + OverlayArray = binArray; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end +end +lineStylrstr = {'solid','dash','dot','dashdot','plus','circle','asterisk'}; +linecolorsrgb = {'[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]',... + '[0.5 0.5 0.5]','[0.94 0.50 0.50]','[0 0.75 1]','[0.57 0.93 0.57]','[1 0.55 0]','[1 0.75 0.80]','[1 0.84 0]',... + '[0 0 0]','[1 0 0]','[0 0 1]','[0 1 0]','[1,0.65 0]','[0 1 1]','[1 0 1]'}'; +LineColorspec = zeros(numel(OverlayArray),3); %% +LineStylespec = cell(1,numel(OverlayArray)); +LineMarkerspec = cell(1,numel(OverlayArray)); +LineWidthspec = ones(1,numel(OverlayArray)); +try + LineData = ERPwaviewerIN.Lines.data; + if ERPwaviewerIN.Lines.auto + LineDataColor = linecolorsrgb; + else + for ii = 1:size(LineData,1) + try + LineDataColor{ii} = LineData{ii,2}; + catch + LineDataColor{ii} = linecolorsrgb{ii}; + end + end + end +catch + [lineNameStr,linecolors,linetypes,linewidths] = f_get_lineset_ERPviewer(numel(OverlayArray)); + lineset_str =table(lineNameStr,linecolors,linetypes,linewidths); + LineData = table2cell(lineset_str); + LineDataColor = linecolorsrgb; +end + +for Numofplot = 1: numel(OverlayArray) %%using RGB or r,g,b,o? + %%determine the specific RGB value for the defined color + if Numofplot <= length(LineDataColor) + cellColor = str2num(LineDataColor{Numofplot}); + if numel(cellColor)~=3 || min(cellColor)<0 || max(cellColor)>1 + LineColorspec(Numofplot,:) = [0 0 0];%% black + else + LineColorspec(Numofplot,:) = cellColor;%% black + end + else + LineColorspec(Numofplot,1) = [0 0 0]; + end + %%Line style + CellStyle = LineData{Numofplot,3}; + [C_style,IA_style] = ismember_bc2(CellStyle,lineStylrstr); + if C_style==1 + switch IA_style %{'solid','dash','dot','dashdot','plus','circle','asterisk'}; + case 1 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = '-'; + case 2 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = '--'; + case 3 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = ':'; + case 4 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = '-.'; + case 5 + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = '+'; + case 6 + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = 'o'; + case 7 + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = '*'; + otherwise + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = 'none'; + end + else + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = 'none'; + end%% end of line style + + %%line width + try + LineWidthspec(1,Numofplot) = LineData{Numofplot,4}; + catch + LineWidthspec(1,Numofplot) =1; + end%% end for setting of line width +end%% end of loop for number of line + +% +%%-----------------------------Setting for legend-------------------------- +FontSizeLeg= 10; +FontLeg= 'Geneva'; +fonttype = {'Courier','Geneva','Helvetica','Monaco','Times'}; +TextcolorLeg = 1; +Legcolumns = 1; +try + for NumofOverlay =1:numel(OverlayArray) + LegendName{NumofOverlay} = char(ERPwaviewerIN.Legend.data{NumofOverlay,2}); + end + FontLegValue = ERPwaviewerIN.Legend.font; + FontLeg = fonttype{FontLegValue}; + FontSizeLeg = ERPwaviewerIN.Legend.fontsize; + TextcolorLeg = ERPwaviewerIN.Legend.textcolor; + Legcolumns = ERPwaviewerIN.Legend.columns; +catch +end + + + +% +%%--------------Chan/Bin/ERPset Labels, font, and fontsize----------------- +CBELabels = [50 100 1]; +CBEFont = 'Geneva'; +CBEFontsize=10; +try + if ERPwaviewerIN.chanbinsetlabel.location.no ==1 + CBELabels = []; + CBEFont = ''; + CBEFontsize=[]; + elseif ERPwaviewerIN.chanbinsetlabel.location.custom==1 + CBELabels(1) = ERPwaviewerIN.chanbinsetlabel.location.xperc; + CBELabels(2) = ERPwaviewerIN.chanbinsetlabel.location.yperc; + CBELabels(3) = ERPwaviewerIN.chanbinsetlabel.location.center; + FontlabelValue = ERPwaviewerIN.chanbinsetlabel.font; + CBEFont = fonttype{FontlabelValue}; + CBEFontsize=ERPwaviewerIN.chanbinsetlabel.fontsize; + end +catch + +end + +%%label textcolor +CBETcolor = [0 0 0]; +try + xlabelFontcolorValue =ERPwaviewerIN.chanbinsetlabel.textcolor; + switch xlabelFontcolorValue + case 1 + CBETcolor = [0 0 0];%% black + case 2 + CBETcolor = [1 0 0];%% red + case 3 + CBETcolor = [0 0 1];%% blue + case 4 + CBETcolor = [0 1 0];%%green + case 5 + CBETcolor = [0.9290 0.6940 0.1250];%%orange + case 6 + CBETcolor = [0 1 1];%%cyan + case 7 + CBETcolor = [1 0 1];%%magenla + otherwise + CBETcolor = [0 0 0];%%black + end +catch +end + + + + +% +%%-----------------------------Polarity------------------------------------ +PolarityWave = 1; +try + PolarityWave = ERPwaviewerIN.polarity; +catch +end + +% +%%-----------------------------standard error------------------------------ +Standerr = 0; +try + StanderrValue = ERPwaviewerIN.SEM.error; + if ~isnumeric(StanderrValue) || isempty(StanderrValue) + Standerr = 0; + else + Standerr = StanderrValue; + end +catch +end + +% +%%-------------------------------Transparency------------------------------ +Transparency = 0; +try + TransparencyValue = ERPwaviewerIN.SEM.trans; + if ~isnumeric(TransparencyValue) || isempty(TransparencyValue) + Transparency = 0; + else + Transparency = TransparencyValue; + end +catch +end + + +% +%%------------------------------Grid space--------------------------------- +Gridspace = [1 10;1 10]; +try + Layoutop = ERPwaviewerIN.plot_org.gridlayout.op; + if Layoutop~=1 + %%for rows + rowgapop = ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPOP; + if rowgapop%%gap + Gridspace(1,1) = 1; + rowgapValue = ERPwaviewerIN.plot_org.gridlayout.rowgap.GTPValue; + if isempty(rowgapValue) || numel(rowgapValue)~=1 || rowgapValue<=0 + rowgapValue = 10; + end + Gridspace(1,2) = rowgapValue; + else%%overlay + Gridspace(1,1) = 2; + rowoverlayValue = ERPwaviewerIN.plot_org.gridlayout.rowgap.OverlayValue; + if isempty(rowoverlayValue) || numel(rowoverlayValue)~=1 || rowoverlayValue<=0 || rowoverlayValue>100 + rowoverlayValue = 40; + end + Gridspace(1,2) = rowoverlayValue; + end + %%for columns + columngapop = ERPwaviewerIN.plot_org.gridlayout.columngap.GTPOP; + if columngapop%%gap + Gridspace(2,1) = 1; + columngapValue = ERPwaviewerIN.plot_org.gridlayout.columngap.GTPValue; + if isempty(columngapValue) || numel(columngapValue)~=1 || columngapValue<=0 + columngapValue = 10; + end + Gridspace(2,2) = columngapValue; + else%% overlay + Gridspace(2,1) = 2; + columnoverlayValue = ERPwaviewerIN.plot_org.gridlayout.columngap.OverlayValue; + if isempty(columnoverlayValue) || numel(columnoverlayValue)~=1 || columnoverlayValue<=0 || columnoverlayValue>100 + columnoverlayValue = 20; + end + Gridspace(2,2) = columnoverlayValue; + end + end +catch +end + + +% +%%-----------------------------Baseline correction------------------------- +Blc = 'none'; +try + Blc = ERPwaviewerIN.baselinecorr; +catch +end + +% +%%---------------------------------x axis---------------------------------- +timeRange = [];%%time range is used to plot the wave(s) +try + timeRange = ERPwaviewerIN.xaxis.timerange; +catch +end +timeticks = []; +try + timeticks = ERPwaviewerIN.xaxis.timeticks; +catch +end +if ~isempty(timeRange) && ~isempty(timeticks) %%check xticks + try + count =0; + XtickDis =[]; + for Numofxtick = 1:numel(timeticks) + if timeticks(Numofxtick) < timeRange(1) || timeticks(Numofxtick) > timeRange(end) + count = count+1; + XtickDis(count) = Numofxtick; + end + end + timeticks(XtickDis) = []; + catch + end +end +xticklabel = 'on'; +try + xticklabelValue = ERPwaviewerIN.xaxis.label; + if xticklabelValue==0 + xticklabel = 'off'; + else + xticklabel = 'on'; + end +catch +end + +xlabelFont = 'Geneva'; +try + xFontlabelValue = ERPwaviewerIN.xaxis.font; + xlabelFont = fonttype{xFontlabelValue}; +catch +end + + +xlabelFontsize = 10; +try + xlabelFontsize =ERPwaviewerIN.xaxis.fontsize; +catch +end + +xlabelFontcolor = [0 0 0]; +try + xlabelFontcolorValue =ERPwaviewerIN.xaxis.fontcolor; + switch xlabelFontcolorValue + case 1 + xlabelFontcolor = [0 0 0];%% black + case 2 + xlabelFontcolor = [1 0 0];%% red + case 3 + xlabelFontcolor = [0 0 1];%% blue + case 4 + xlabelFontcolor = [0 1 0];%%green + case 5 + xlabelFontcolor = [0.9290 0.6940 0.1250];%%orange + case 6 + xlabelFontcolor = [0 1 1];%%cyan + case 7 + xlabelFontcolor = [1 0 1];%%magenla + otherwise + xlabelFontcolor = [0 0 0];%%black + end +catch +end +Xunits = 'on'; +try + XunitsValue = ERPwaviewerIN.xaxis.units; + if XunitsValue==1 + Xunits = 'on'; + else + Xunits = 'off'; + end +catch + +end + +%%Minorticks for x axis +try + MinorticksX(1) = ERPwaviewerIN.xaxis.tminor.disp; + MinorticksX(2:numel(ERPwaviewerIN.xaxis.tminor.step)+1) = ERPwaviewerIN.xaxis.tminor.step; +catch + MinorticksX = [0];%% off +end + +%%Decimals for x ticklabels +Xtickprecision = 0; +try + Xtickprecision= ERPwaviewerIN.xaxis.tickdecimals; +catch + Xtickprecision = 0; +end + +if Xtickprecision<0 || Xtickprecision>6 + Xtickprecision = 0; +end + +%%display x ticks with millisecond or second? +XdispFlag = 1;%% in millisecond +try + XdispFlag = ERPwaviewerIN.xaxis.tdis; +catch +end + +%%%--------------------------------y axis---------------------------------- +Yscales = []; +try + Yscales = ERPwaviewerIN.yaxis.scales ; +catch +end +Yticks = []; +try + Yticks = ERPwaviewerIN.yaxis.ticks; +catch +end +if ~isempty(Yscales) && ~isempty(Yticks) %%check Yticks + try + count =0; + ytickDis =[]; + for Numofytick = 1:numel(Yticks) + if Yticks(Numofytick) < Yscales(1) || Yticks(Numofytick) > Yscales(end) + count = count+1; + ytickDis(count) = Numofytick; + end + end + Yticks(ytickDis) = []; + catch + end +end + +yticklabel = 'on'; +try + yticklabelValue = ERPwaviewerIN.yaxis.label; + if yticklabelValue==0 + yticklabel = 'off'; + else + yticklabel = 'on'; + end +catch +end + +YlabelFont = 'Geneva'; +try + YFontlabelValue = ERPwaviewerIN.yaxis.font; + YlabelFont = fonttype{YFontlabelValue}; +catch +end + +YlabelFontsize = 12; +try + YlabelFontsize =ERPwaviewerIN.yaxis.fontsize; +catch +end + +ylabelFontcolor = [0 0 0]; +try + ylabelFontcolorValue =ERPwaviewerIN.yaxis.fontcolor; + switch ylabelFontcolorValue + case 1 + ylabelFontcolor = [0 0 0];%% black + case 2 + ylabelFontcolor = [1 0 0];%% red + case 3 + ylabelFontcolor = [0 0 1];%% blue + case 4 + ylabelFontcolor = [0 1 0];%%green + case 5 + ylabelFontcolor = [0.9290 0.6940 0.1250];%%orange + case 6 + ylabelFontcolor = [0 1 1];%%cyan + case 7 + ylabelFontcolor = [1 0 1];%%magenla + otherwise + ylabelFontcolor = [0 0 0];%%black + end +catch +end + +yunits = 'on'; +try + yunitsValue = ERPwaviewerIN.yaxis.units; + if yunitsValue==1 + yunits = 'on'; + else + yunits = 'off'; + end +catch + +end + +Ytickprecision = 1; +try + Ytickprecision = ERPwaviewerIN.yaxis.tickdecimals; +catch + Ytickprecision = 1; +end + + +%%Minorticks for y axis +try + MinorticksY(1) = ERPwaviewerIN.yaxis.yminor.disp; + MinorticksY(2:numel(ERPwaviewerIN.yaxis.yminor.step)+1) = ERPwaviewerIN.yaxis.yminor.step; +catch + MinorticksY = [0];%% off +end + + + +%%Background color of figure +figbgdColor = [1 1 1]; +try + figbgdColor = ERPwaviewerIN.figbackgdcolor; +catch + figbgdColor = [1 1 1]; +end + +if ~isnumeric(figbgdColor) || isempty(figbgdColor) || numel(figbgdColor)~=3 || max(figbgdColor)>1 || min(figbgdColor)<0 + figbgdColor =[1 1 1]; +end + + +PagesIndex = ERPwaviewerIN.PageIndex; +if isempty(PagesIndex) + PagesIndex=1; +end + +for ii = 1:length(plotArrayStr)-1 + plotArrayStr_tr{ii} = plotArrayStr{ii}; +end +plotArrayStr = ''; +plotArrayStr = plotArrayStr_tr; + +%%Main function +if ~isempty(FigureName) + [ALLERP, erpcom] = pop_plotERPwaviewer(ALLERPIN,PagesIndex,ERPsetArray, binArray, chanArray,... + 'PLOTORG',PLOTORG,'GridposArray',GridposArray,'LabelsName',plotArrayStr, 'Blc', Blc,'Box',plotBox,'LineColor',LineColorspec,'LineStyle',LineStylespec,... + 'LineMarker',LineMarkerspec,'LineWidth',LineWidthspec,'LegendName',LegendName,'LegendFont',FontLeg,'LegendFontsize',FontSizeLeg,... + 'Labeloc',CBELabels,'Labelfont',CBEFont,'Labelfontsize',CBEFontsize,'YDir',PolarityWave,'SEM',Standerr,'Transparency', Transparency,... + 'GridSpace',Gridspace,'TimeRange',timeRange,'Xticks',timeticks,'Xticklabel',xticklabel,'Xlabelfont',xlabelFont,'Xlabelfontsize',xlabelFontsize,... + 'Xlabelcolor',xlabelFontcolor,'Xunits',Xunits,'MinorTicksX',MinorticksX,... + 'YScales',Yscales,'Yticks',Yticks,'Yticklabel',yticklabel,'Ylabelfont',YlabelFont,'Ylabelfontsize',YlabelFontsize,... + 'Ylabelcolor',ylabelFontcolor,'Yunits',yunits,'MinorTicksY',MinorticksY,'LegtextColor',TextcolorLeg,'Legcolumns',Legcolumns,... + 'FigureName',FigureName,'FigbgColor',figbgdColor,'Labelcolor',CBETcolor,'Ytickdecimal',Ytickprecision,'Xtickdecimal',Xtickprecision,'XtickdisFlag',XdispFlag,'History', History);% +else + OutputViewerpar{1} = ALLERPIN; + OutputViewerpar{2} = PagesIndex; + OutputViewerpar{3} = PLOTORG; + OutputViewerpar{4} = binArray; + OutputViewerpar{5} = chanArray; + OutputViewerpar{6} = GridposArray; + OutputViewerpar{7} = plotArrayStr; + OutputViewerpar{8} = Blc; + OutputViewerpar{9} = plotBox; + OutputViewerpar{10} = LineColorspec; + OutputViewerpar{11} = LineStylespec; + OutputViewerpar{12} = LineMarkerspec; + OutputViewerpar{13} = LineWidthspec; + OutputViewerpar{14} = LegendName; + OutputViewerpar{15} = FontLeg; + OutputViewerpar{16} = FontSizeLeg; + OutputViewerpar{17} = CBELabels; + OutputViewerpar{18} = CBEFont; + OutputViewerpar{19} = CBEFontsize; + OutputViewerpar{20} = PolarityWave; + OutputViewerpar{21} = Standerr; + OutputViewerpar{22} = Transparency; + OutputViewerpar{23} = Gridspace; + OutputViewerpar{24} = timeRange; + OutputViewerpar{25} = timeticks; + OutputViewerpar{26} = xticklabel; + OutputViewerpar{27} = xlabelFont; + OutputViewerpar{28} = xlabelFontsize; + OutputViewerpar{29} = xlabelFontcolor; + OutputViewerpar{30} = Xunits; + OutputViewerpar{31} = MinorticksX; + OutputViewerpar{32} = Yscales; + OutputViewerpar{33} = Yticks; + OutputViewerpar{34} = yticklabel; + OutputViewerpar{35} = YlabelFont; + OutputViewerpar{36} = YlabelFontsize; + OutputViewerpar{37} = ylabelFontcolor; + OutputViewerpar{38} = yunits; + OutputViewerpar{39} = MinorticksY; + OutputViewerpar{40} = TextcolorLeg; + OutputViewerpar{41} = Legcolumns; + OutputViewerpar{42} = FigureName; + OutputViewerpar{43} =ERPsetArray; + OutputViewerpar{44} =CBETcolor; + OutputViewerpar{45} = Ytickprecision; + OutputViewerpar{46} = Xtickprecision; + OutputViewerpar{47} = XdispFlag; +end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_redrawERP_viewer_test.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_redrawERP_viewer_test.m new file mode 100755 index 00000000..8273b4ec --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_redrawERP_viewer_test.m @@ -0,0 +1,1917 @@ +%PURPOSE : Plot EPR waves within one axes + + + +% Author: Guanghui Zhang & Steve J. Luck +% Center for Mind and Brain +% University of California, Davis +% Davis, CA +% 2022 & 2023 + + + +function f_redrawERP_viewer_test() + +global viewer_ERPDAT; +global gui_erp_waviewer; +addlistener(viewer_ERPDAT,'v_messg_change',@V_messg_change); + + +FonsizeDefault = f_get_default_fontsize(); + + +if nargin>1 + help f_redrawERP_viewer; + return; +end + +try + ALLERPwaviewer = evalin('base','ALLERPwaviewer'); + ERPwaviewer = ALLERPwaviewer; +catch + beep; + disp('Please re-run ERP wave viewer.'); + return; +end + +% We first clear the existing axes ready to build a new one +if ishandle( gui_erp_waviewer.ViewAxes ) + delete( gui_erp_waviewer.ViewAxes ); +end + +%Sets the units of your root object (screen) to pixels +set(0,'units','pixels') +%Obtains this pixel information +Pix_SS = get(0,'screensize'); +%Sets the units of your root object (screen) to inches +set(0,'units','inches') +%Obtains this inch information +Inch_SS = get(0,'screensize'); +%Calculates the resolution (pixels per inch) +Res = Pix_SS./Inch_SS; + +%%background color of figure +figbgdColor = ERPwaviewer.figbackgdcolor; +if ~isnumeric(figbgdColor) || isempty(figbgdColor) || numel(figbgdColor)~=3 || max(figbgdColor)>1 || min(figbgdColor)<0 + figbgdColor =[1 1 1]; +end +zoomSpace = estudioworkingmemory('zoomSpace'); +if isempty(zoomSpace) + zoomSpace = 0; +else + if zoomSpace<0 + zoomSpace =0; + end +end +pb_height = 1*Res(4); +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef;%%Get background color +catch + ColorBviewer_def = [0.7765,0.7294,0.8627]; +end +if isempty(ColorBviewer_def) || numel(ColorBviewer_def)~=3 + ColorBviewer_def = [0.7765,0.7294,0.8627]; +end + + +%%determine the page number +pagecurrentNum = ERPwaviewer.PageIndex; +pagesValue = ERPwaviewer.plot_org.Pages; +ERPArray = ERPwaviewer.SelectERPIdx; +chanArray =ERPwaviewer.chan; +binArray = ERPwaviewer.bin; +ALLERPIN = ERPwaviewer.ALLERP; +[chanStr,binStr,diff_mark] = f_geterpschanbin(ALLERPIN,ERPArray); +if pagesValue==1 + pageNum = numel(chanArray); + PageStr = chanStr(chanArray); +elseif pagesValue==2 + pageNum = numel(binArray); + PageStr = binStr(binArray); +else + pageNum = numel(ERPArray); + PageStr = cell(numel(ERPArray),1); + for Numoferpset = 1:numel(ERPArray) + PageStr(Numoferpset,1) = {char(ALLERPIN(ERPArray(Numoferpset)).erpname)}; + end +end + +if pagecurrentNum>pageNum + pagecurrentNum =1; + ERPwaviewer.PageIndex =1; + assignin('base','ALLERPwaviewer',ERPwaviewer); +end + +gui_erp_waviewer.plotgrid = uix.VBox('Parent',gui_erp_waviewer.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorBviewer_def); + +gui_erp_waviewer.pageinfo_box = uiextras.HBox( 'Parent', gui_erp_waviewer.plotgrid,'BackgroundColor',ColorBviewer_def); + +gui_erp_waviewer.erpwaviewer_legend_title = uiextras.HBox( 'Parent', gui_erp_waviewer.plotgrid,'BackgroundColor',ColorBviewer_def); +uicontrol('Parent',gui_erp_waviewer.erpwaviewer_legend_title,'Style','text','String','','FontSize',FonsizeDefault,'FontWeight','bold','BackgroundColor',ColorBviewer_def); + +gui_erp_waviewer.erpwaviewer_legend = uix.ScrollingPanel( 'Parent', gui_erp_waviewer.erpwaviewer_legend_title,'BackgroundColor',figbgdColor); + + +gui_erp_waviewer.plot_wav_legend = uiextras.HBox( 'Parent', gui_erp_waviewer.plotgrid,'BackgroundColor',ColorBviewer_def); +% gui_erp_waviewer.ViewAxes_legend = uix.ScrollingPanel( 'Parent', gui_erp_waviewer.plot_wav_legend,'BackgroundColor',ColorBviewer_def); + +uicontrol('Parent',gui_erp_waviewer.plot_wav_legend,'Style','text','String','','FontSize',FonsizeDefault,'FontWeight','bold','BackgroundColor',ColorBviewer_def); +gui_erp_waviewer.Resize = 0; +gui_erp_waviewer.ViewAxes = uix.ScrollingPanel( 'Parent', gui_erp_waviewer.plot_wav_legend,'BackgroundColor',figbgdColor,'SizeChangedFcn',@WAviewerResize);% + +%%Changed by Guanghui Zhang Dec. 2022-------panel for display the processing procedure for some functions, e.g., filtering +gui_erp_waviewer.zoomin_out_title = uiextras.HBox( 'Parent', gui_erp_waviewer.plotgrid,'BackgroundColor',ColorBviewer_def);%%%Message +uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','text','String','','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); +gui_erp_waviewer.zoom_in = uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','pushbutton','String','Zoom In',... + 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Callback',@zoomin); + +gui_erp_waviewer.zoom_edit = uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','edit','String',num2str(zoomSpace),... + 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Callback',@zoomedit); + +gui_erp_waviewer.zoom_out = uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','pushbutton','String','Zoom Out',... + 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Callback',@zoomout); +uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','text','String','','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); + +gui_erp_waviewer.figuresaveas = uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','pushbutton','String','Save Figure as',... + 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Callback',@figure_saveas); + +gui_erp_waviewer.figureout = uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','pushbutton','String','Create Static /Exportable Plot',... + 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Callback',@figure_out); + +gui_erp_waviewer.Reset = uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','pushbutton','String','Reset',... + 'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Callback',@Panel_Reset); + + +uicontrol('Parent',gui_erp_waviewer.zoomin_out_title,'Style','text','String','','FontSize',FonsizeDefault,'BackgroundColor',ColorBviewer_def); +set(gui_erp_waviewer.zoomin_out_title, 'Sizes', [10 70 70 70 -1 100 170 70 20]); + + +%%Changed by Guanghui Zhang Dec. 2022-------panel for display the processing procedure for some functions, e.g., filtering +gui_erp_waviewer.xaxis_panel = uiextras.HBox( 'Parent', gui_erp_waviewer.plotgrid,'BackgroundColor',ColorBviewer_def);%%%Message +gui_erp_waviewer.Process_messg = uicontrol('Parent',gui_erp_waviewer.xaxis_panel,'Style','text','String','','FontSize',FonsizeDefault+2,'FontWeight','bold','BackgroundColor',ColorBviewer_def); + +%%Setting title +gui_erp_waviewer.pageinfo_str = ['Page',32,num2str(pagecurrentNum),'/',num2str(pageNum),':',PageStr{pagecurrentNum}]; + +gui_erp_waviewer.pageinfo_text = uicontrol('Parent',gui_erp_waviewer.pageinfo_box,'Style','text','String',gui_erp_waviewer.pageinfo_str,'FontSize',FonsizeDefault,'FontWeight','bold','BackgroundColor',ColorBviewer_def); + + +gui_erp_waviewer.pageinfo_minus = uicontrol('Parent',gui_erp_waviewer.pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',@page_minus,'FontSize',FonsizeDefault+5,'BackgroundColor',[1 1 1],'FontWeight','bold'); +% if S_ws_getbinchan.Select_index ==1 +gui_erp_waviewer.pageinfo_minus.Enable = 'off'; +% end +gui_erp_waviewer.pageinfo_edit = uicontrol('Parent',gui_erp_waviewer.pageinfo_box,'Style', 'edit', 'String', num2str(pagecurrentNum),'Callback',@page_edit,'FontSize',FonsizeDefault+2,'BackgroundColor',[1 1 1]); + + +gui_erp_waviewer.pageinfo_plus = uicontrol('Parent',gui_erp_waviewer.pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',@page_plus,'FontSize',FonsizeDefault+5,'BackgroundColor',[1 1 1],'FontWeight','bold'); +% if S_ws_getbinchan.Select_index == numel(S_ws_geterpset) +gui_erp_waviewer.pageinfo_plus.Enable = 'off'; +% end + +if pageNum ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [1 1 1]; + Enable_minus_BackgroundColor = [0 0 0]; +else + if pagecurrentNum ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif pagecurrentNum == pageNum + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp_waviewer.pageinfo_minus.Enable = Enable_minus; +gui_erp_waviewer.pageinfo_plus.Enable = Enable_plus; +gui_erp_waviewer.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp_waviewer.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +set(gui_erp_waviewer.plot_wav_legend, 'Sizes', [10 -1]); +set(gui_erp_waviewer.erpwaviewer_legend_title, 'Sizes', [10 -1]); +set(gui_erp_waviewer.pageinfo_box, 'Sizes', [-1 50 50 50] ); + +gui_erp_waviewer.myerpviewer = axes('Parent', gui_erp_waviewer.ViewAxes,'Color','none','Box','on','FontWeight','bold'); +hold(gui_erp_waviewer.myerpviewer,'on'); +myerpviewer = gui_erp_waviewer.myerpviewer; + +gui_erp_waviewer.myerpviewer_legend = axes('Parent', gui_erp_waviewer.erpwaviewer_legend ,'Color',figbgdColor,'Box','off'); +hold(gui_erp_waviewer.myerpviewer_legend,'on'); +myerpviewerlegend = gui_erp_waviewer.myerpviewer_legend; + +OutputViewerpar = f_preparms_erpwaviewer(''); + +gui_erp_waviewer.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high +gui_erp_waviewer.plotgrid.Heights(2) = 50; % set the first element (pageinfo) to 30px high +gui_erp_waviewer.plotgrid.Heights(4) = 30; % set the second element (x axis) to 30px high +gui_erp_waviewer.plotgrid.Heights(5) = 30; % set the second element (x axis) to 30px high +gui_erp_waviewer.plotgrid.Units = 'pixels'; +if isempty(OutputViewerpar) + disp('Please restart EStudio Wave Viewer'); + return; +end + +f_plotviewerwave(OutputViewerpar{1},OutputViewerpar{2}, OutputViewerpar{3},OutputViewerpar{4},OutputViewerpar{5},OutputViewerpar{6},OutputViewerpar{9},OutputViewerpar{8},OutputViewerpar{10},OutputViewerpar{11},... + OutputViewerpar{12},OutputViewerpar{13},OutputViewerpar{14},OutputViewerpar{15},OutputViewerpar{16},OutputViewerpar{17},OutputViewerpar{18},OutputViewerpar{19},OutputViewerpar{20},OutputViewerpar{21},OutputViewerpar{22},... + OutputViewerpar{23},OutputViewerpar{24},OutputViewerpar{25},OutputViewerpar{26},OutputViewerpar{27},OutputViewerpar{28},OutputViewerpar{29},OutputViewerpar{31},OutputViewerpar{30},OutputViewerpar{32},OutputViewerpar{33},... + OutputViewerpar{34},OutputViewerpar{35},OutputViewerpar{36},OutputViewerpar{37},OutputViewerpar{38},OutputViewerpar{39},OutputViewerpar{7},OutputViewerpar{43}, OutputViewerpar{40},OutputViewerpar{41},OutputViewerpar{44},... + OutputViewerpar{45},OutputViewerpar{46},OutputViewerpar{47},myerpviewer,myerpviewerlegend); + +%% +set(gui_erp_waviewer.myerpviewer, 'XTick', [], 'XTickLabel', []); +set(gui_erp_waviewer.myerpviewer_legend, 'XTick', [], 'YTick', [],'Box','off', 'Color','none','xcolor','none','ycolor','none'); +%%resize the heights based on the number of rows +Fill = 1; +splot_n = size(OutputViewerpar{6},1); +if splot_n*pb_height<(gui_erp_waviewer.plotgrid.Position(4)-gui_erp_waviewer.plotgrid.Heights(1))&&Fill + pb_height = 0.9*(gui_erp_waviewer.plotgrid.Position(4)-gui_erp_waviewer.plotgrid.Heights(1)-gui_erp_waviewer.plotgrid.Heights(2))/splot_n; +else + pb_height = 0.9*pb_height; +end +if zoomSpace <0 + gui_erp_waviewer.ViewAxes.Heights = splot_n*pb_height; +else + gui_erp_waviewer.ViewAxes.Heights = splot_n*pb_height*(1+zoomSpace/100); +end + +widthViewer = gui_erp_waviewer.ViewAxes.Position(3)-gui_erp_waviewer.ViewAxes.Position(2); +if zoomSpace <0 + gui_erp_waviewer.ViewAxes.Widths = widthViewer; +else + gui_erp_waviewer.ViewAxes.Widths = widthViewer*(1+zoomSpace/100); + +end +gui_erp_waviewer.plotgrid.Units = 'normalized'; +gui_erp_waviewer.Resize =1; +end % redrawDemo + + + +%%Resize the GUI automatically as the user changes the size of the window at run-time. +function WAviewerResize(~,~) +global gui_erp_waviewer; +if gui_erp_waviewer.Resize ~= 0 + f_redrawERP_viewer_test(); +end +end + + +%%-------------------------------Page Editor------------------------------- +function page_edit(Source,~) +global viewer_ERPDAT +% addlistener(viewer_ERPDAT,'page_xyaxis',@count_page_xyaxis_change); + +try + ERPwaviewer = evalin('base','ALLERPwaviewer'); +catch + beep; + disp('Error > f_redrawERP_viewer_test() > page_edit().'); + return; +end +pagesValue = ERPwaviewer.plot_org.Pages; + +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + +Pagecurrent = str2num(Source.String); + +if ~isempty(Pagecurrent) && Pagecurrent>0 + + ERPArray = ERPwaviewer.SelectERPIdx; + chanArray =ERPwaviewer.chan; + binArray = ERPwaviewer.bin; + if pagesValue==1 + pageNum = numel(chanArray); + elseif pagesValue==2 + pageNum = numel(binArray); + else + pageNum = numel(ERPArray); + end + + if Pagecurrent<=pageNum + ERPwaviewer.PageIndex = Pagecurrent; + if pagesValue==3 + ERPwaviewer.ERP = ERPwaviewer.ALLERP(ERPArray(Pagecurrent)); + ERPwaviewer.CURRENTERP =ERPArray(Pagecurrent); + end + assignin('base','ALLERPwaviewer',ERPwaviewer); + viewer_ERPDAT.page_xyaxis = viewer_ERPDAT.page_xyaxis+1; + f_redrawERP_viewer_test();%%replot the waves + end +end + +end + +%------------------Display the waveform for proir ERPset-------------------- +function page_minus(~,~) +global viewer_ERPDAT + +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + +try + ERPwaviewer_CHANGE = evalin('base','ALLERPwaviewer'); +catch + beep; + disp('Please re-run ERP wave viewer.'); + return; +end +ERPwaviewer_CHANGE.PageIndex = ERPwaviewer_CHANGE.PageIndex-1; +pagesValue = ERPwaviewer_CHANGE.plot_org.Pages; +ERPArray = ERPwaviewer_CHANGE.SelectERPIdx; +chanArray =ERPwaviewer_CHANGE.chan; +binArray = ERPwaviewer_CHANGE.bin; +if pagesValue==1 + pageNum = numel(chanArray); +elseif pagesValue==2 + pageNum = numel(binArray); +else + pageNum = numel(ERPArray); +end +Pagecurrent = ERPwaviewer_CHANGE.PageIndex; +if ERPwaviewer_CHANGE.PageIndex<= pageNum && ERPwaviewer_CHANGE.PageIndex>0 + if pagesValue==3 + ERPwaviewer_CHANGE.ERP = ERPwaviewer_CHANGE.ALLERP(ERPArray(Pagecurrent)); + ERPwaviewer_CHANGE.CURRENTERP =ERPArray(Pagecurrent); + end + + assignin('base','ALLERPwaviewer',ERPwaviewer_CHANGE); + MessageViewer= char(strcat('Plot prior page (<)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.page_xyaxis = viewer_ERPDAT.page_xyaxis+1;%%change X/Y axis based on the changed pages + viewer_ERPDAT.Process_messg =1; + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; +else + return; +end +end + + +%------------------Display the waveform for next ERPset-------------------- +function page_plus(~,~) +global viewer_ERPDAT +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + +try + ERPwaviewer_CHANGE = evalin('base','ALLERPwaviewer'); +catch + beep; + disp('Please re-run ERP wave viewer.'); + return; +end +ERPwaviewer_CHANGE.PageIndex = ERPwaviewer_CHANGE.PageIndex+1; +pagesValue = ERPwaviewer_CHANGE.plot_org.Pages; +ERPArray = ERPwaviewer_CHANGE.SelectERPIdx; +chanArray =ERPwaviewer_CHANGE.chan; +binArray = ERPwaviewer_CHANGE.bin; +if pagesValue==1 + pageNum = numel(chanArray); +elseif pagesValue==2 + pageNum = numel(binArray); +else + pageNum = numel(ERPArray); +end +Pagecurrent = ERPwaviewer_CHANGE.PageIndex; +if ERPwaviewer_CHANGE.PageIndex<= pageNum && ERPwaviewer_CHANGE.PageIndex>0%% within the page range + if pagesValue==3 + ERPwaviewer_CHANGE.ERP = ERPwaviewer_CHANGE.ALLERP(ERPArray(Pagecurrent)); + ERPwaviewer_CHANGE.CURRENTERP =ERPArray(Pagecurrent); + end + assignin('base','ALLERPwaviewer',ERPwaviewer_CHANGE); + viewer_ERPDAT.page_xyaxis = viewer_ERPDAT.page_xyaxis+1;%%change X/Y axis based on the changed pages + MessageViewer= char(strcat('Plot next page (>)')); + erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + viewer_ERPDAT.Process_messg =1; + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; +else + return; +end + +end + + +%%-------------------------Save figure as---------------------------------- +function figure_saveas(~,~) +global viewer_ERPDAT; +% addlistener(viewer_ERPDAT,'V_messg_change',@V_messg_change); + +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + + +MessageViewer= char(strcat('Save Figure As')); +erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + +pathstr = pwd; +namedef ='Myviewer.pdf'; +[erpfilename, erppathname, indxs] = uiputfile({'*.pdf';'*.svg';'*.jpg';'*.png';'*.tif';'*.bmp';'*.eps'},... + 'Save as',[fullfile(pathstr,namedef)]); + + +if isequal(erpfilename,0) + beep; + viewer_ERPDAT.Process_messg =3; + disp('User selected Cancel') + return +end + +History = 'off'; +[pathstr, erpfilename1, ext] = fileparts(erpfilename) ; + +if isempty(ext) + erpfilename = fullfile(erppathname,char(strcat(erpfilename,'.pdf'))); +else + erpfilename = fullfile(erppathname,erpfilename); +end + +try + viewer_ERPDAT.Process_messg =1; + OutputViewerpar = f_preparms_erpwaviewer(erpfilename,History); + viewer_ERPDAT.Process_messg =2; +catch + viewer_ERPDAT.Process_messg =3; +end + +end + + +%%-----------------Pop figure--------------------------------------------- +function figure_out(~,~) +global viewer_ERPDAT; +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + +ViewerName = estudioworkingmemory('viewername'); +if isempty(ViewerName) + ViewerName = char('My Viewer'); +end +MessageViewer= char(strcat('Create Static/Exportable Plot')); +erpworkingmemory('ERPViewer_proces_messg',MessageViewer); +try + viewer_ERPDAT.Process_messg =1; + OutputViewerpar = f_preparms_erpwaviewer(ViewerName); + viewer_ERPDAT.Process_messg =2; +catch + viewer_ERPDAT.Process_messg =3; +end +end + + + +%%----------------Zoom in------------------------------------------------- +function zoomin(~,~) +global viewer_ERPDAT; + +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end +zoomSpace = estudioworkingmemory('zoomSpace'); +if isempty(zoomSpace) + estudioworkingmemory('zoomSpace',0) +else + if zoomSpace<0 + zoomSpace = 0; + end + zoomSpace =zoomSpace+10; + estudioworkingmemory('zoomSpace',zoomSpace) ; +end +MessageViewer= char(strcat('Zoom In')); +erpworkingmemory('ERPViewer_proces_messg',MessageViewer); +try + viewer_ERPDAT.Process_messg =1; + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; +catch + viewer_ERPDAT.Process_messg =3; +end +end + + +%%Reset each panel that using the default parameters +function Panel_Reset(~,~) +global viewer_ERPDAT; + +MessageViewer= char(strcat('Reset')); +erpworkingmemory('ERPViewer_proces_messg',MessageViewer); + +try + viewer_ERPDAT.Process_messg =1; + viewer_ERPDAT.Reset_Waviewer_panel=1; + estudioworkingmemory('zoomSpace',0); + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; +catch + viewer_ERPDAT.Process_messg =3; +end + +end + + + + +function zoomedit(Source,~) +global viewer_ERPDAT; + +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + +zoomspaceEdit = str2num(Source.String); +MessageViewer= char(strcat('Zoom Editor')); +erpworkingmemory('ERPViewer_proces_messg',MessageViewer); +if ~isempty(zoomspaceEdit) && numel(zoomspaceEdit)==1 && zoomspaceEdit>=0 + estudioworkingmemory('zoomSpace',zoomspaceEdit); + try + viewer_ERPDAT.Process_messg =1; + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; + return; + catch + viewer_ERPDAT.Process_messg =3; + return; + end +else + if isempty(zoomspaceEdit) + fprintf(2,['\n Zoom Editor:The input must be a numeric','.\n']); + viewer_ERPDAT.Process_messg =3; + return; + end + if numel(zoomspaceEdit)>1 + fprintf(2,['\n Zoom Editor:The input must be a single numeric','.\n']); + viewer_ERPDAT.Process_messg =3; + return; + end + if zoomspaceEdit<0 + fprintf(2,['\n Zoom Editor:The input must be a positive numeric','.\n']); + viewer_ERPDAT.Process_messg =3; + return; + end +end + +end + +%%----------------Zoom out------------------------------------------------- +function zoomout(~,~) +global viewer_ERPDAT; + +[messgStr,viewerpanelIndex] = f_check_erpviewerpanelchanges(); +if ~isempty(messgStr) + viewer_ERPDAT.count_twopanels = viewer_ERPDAT.count_twopanels +1; +end + +zoomSpace = estudioworkingmemory('zoomSpace'); +if isempty(zoomSpace) + estudioworkingmemory('zoomSpace',0) +else + zoomSpace =zoomSpace-10; + if zoomSpace <0 + zoomSpace =0; + end + estudioworkingmemory('zoomSpace',zoomSpace) ; +end +MessageViewer= char(strcat('Zoom Out')); +erpworkingmemory('ERPViewer_proces_messg',MessageViewer); +try + viewer_ERPDAT.Process_messg =1; + f_redrawERP_viewer_test(); + viewer_ERPDAT.Process_messg =2; +catch + viewer_ERPDAT.Process_messg =3; +end +end + + +function V_messg_change(~,~) +global viewer_ERPDAT; +global gui_erp_waviewer; +FonsizeDefault = f_get_default_fontsize(); +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef;%%Get background color +catch + ColorBviewer_def = [0.7765,0.7294,0.8627]; +end +if isempty(ColorBviewer_def) + ColorBviewer_def = [0.7765,0.7294,0.8627]; +end +gui_erp_waviewer.Process_messg.BackgroundColor = [0.95 0.95 0.95]; +gui_erp_waviewer.Process_messg.FontSize = FonsizeDefault; +Processed_Method=erpworkingmemory('ERPViewer_proces_messg'); +if viewer_ERPDAT.Process_messg ==1 + gui_erp_waviewer.Process_messg.String = strcat('1- ',Processed_Method,': Running....'); + gui_erp_waviewer.Process_messg.ForegroundColor = [0 0 0]; +elseif viewer_ERPDAT.Process_messg ==2 + gui_erp_waviewer.Process_messg.String = strcat('2- ',Processed_Method,': Complete'); + gui_erp_waviewer.Process_messg.ForegroundColor = [0 0.5 0]; + +elseif viewer_ERPDAT.Process_messg ==3 + gui_erp_waviewer.Process_messg.String = strcat('3- ',Processed_Method,': Error (see Command Window)'); + gui_erp_waviewer.Process_messg.ForegroundColor = [1 0 0]; +else + gui_erp_waviewer.Process_messg.String = strcat('Warning:',Processed_Method,'(see Command Window).'); + pause(0.5); + gui_erp_waviewer.Process_messg.ForegroundColor = [1 0.65 0]; +end +if viewer_ERPDAT.Process_messg ==1 || viewer_ERPDAT.Process_messg==2 || viewer_ERPDAT.Process_messg==3 + pause(0.01); + gui_erp_waviewer.Process_messg.String = ''; + gui_erp_waviewer.Process_messg.BackgroundColor = ColorBviewer_def;%[0.95 0.95 0.95]; +end +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%-------------------------------Plot waves------------------------------%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function f_plotviewerwave(ALLERP,qCURRENTPLOT, qPLOTORG,qbinArray,qchanArray,qGridposArray,plotBox,qBlc,qLineColorspec,qLineStylespec,qLineMarkerspec,qLineWidthspec,... + qLegendName,qLegendFont,qLegendFontsize,qCBELabels,qLabelfont,qLabelfontsize,qPolarityWave,qSEM,qTransparency,qGridspace,qtimeRange,qXticks,qXticklabel,... + qXlabelfont,qXlabelfontsize,qXlabelcolor,qMinorTicksX,qXunits,qYScales,qYticks,qYticklabel,qYlabelfont,qYlabelfontsize,qYlabelcolor,qYunits,qMinorTicksY,qplotArrayStr,... + ERPsetArray,qlegcolor,qlegcolumns,qlabelcolor,qytickprecision,qxtickprecision,qxdisFlag,myerpviewer,myerpviewerlegend) + +hbig = myerpviewer; +if nargin<1 + help f_ploterpserpviewer; + return +end + +if isempty(ALLERP) + msgboxText = 'No ALLERP was found!'; + title_msg = 'EStudio: f_plotviewerwave() error:'; + errorfound(msgboxText, title_msg); + return; +end + +if max(ERPsetArray)>length(ALLERP) + ERPsetArray=length(ALLERP); +end + +[chanStrdef,binStrdef] = f_geterpschanbin(ALLERP,[1:length(ALLERP)]); +qERPArray = ERPsetArray; + + +if nargin<5 + qchanArray = 1:length(chanStrdef); +end + +Existchan = f_existvector([1:length(chanStrdef)],qchanArray); +if Existchan==1 + qchanArray = [1:length(chanStrdef)]; + Existchan =1; +end + + +if nargin<4 + qbinArray = 1:length(binStrdef); +end +Existbin = f_existvector([1:length(binStrdef)],qbinArray); +if Existbin==1 + qbinArray = 1:length(binStrdef); + Existbin = 1; +end + +if nargin<3 + qPLOTORG = [1 2 3];%%Channel is "Grid"; Bin is "Overlay"; ERPst is page +end + +%%check ALLERP and adjust "qPLOTORG" +for Numofselectederp = 1:numel(ERPsetArray) + SrateNum_mp(Numofselectederp,1) = ALLERP(ERPsetArray(Numofselectederp)).srate; + Datype{Numofselectederp} = ALLERP(ERPsetArray(Numofselectederp)).datatype; +end +if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==2 && qPLOTORG(2)==1) + +else + if length(unique(Datype))~=1 + msgboxText = 'Type of data across ERPsets is different!'; + title_msg = 'EStudio: f_plotviewerwave() error:'; + errorfound(msgboxText, title_msg); + return; + end + if length(unique(SrateNum_mp))~=1 + msgboxText = 'Sampling rate varies across ERPsets!'; + title_msg = 'EStudio: f_plotviewerwave() error:'; + errorfound(msgboxText, title_msg); + return; + end +end + +if nargin<2|| isempty(qCURRENTPLOT) + qCURRENTPLOT = 1; +end +if ~isnumeric(qCURRENTPLOT) + msgboxText = 'qCURRENTPLOT must be a numeric!'; + title_msg = 'EStudio: f_plotviewerwave() error:'; + errorfound(msgboxText, title_msg); + return; +end +if qCURRENTPLOT <=0 + msgboxText = 'qCURRENTPLOT must be a positive numeric!'; + title_msg = 'EStudio: f_plotviewerwave() error:'; + errorfound(msgboxText, title_msg); + return; +end + +if qPLOTORG(1) ==1 + plotArray = qchanArray; +elseif qPLOTORG(1) ==2 + plotArray = qbinArray; +elseif qPLOTORG(1) ==3 + plotArray = qERPArray; +else + plotArray = qchanArray; +end +plotBoxdef = f_getrow_columnautowaveplot(plotArray); +if isempty(qPLOTORG) || numel(qPLOTORG)~=3 || numel(unique(qPLOTORG)) ~=3 || min(qPLOTORG)<0 || max(qPLOTORG)>3 + qPLOTORG = [1 2 3]; +end + +if qPLOTORG(2) ==1 %% if the selected Channel is "Grid" + OverlayArraydef = qchanArray; + for Numofchan = 1:numel(qchanArray) + LegendNamedef{Numofchan,1} =char(chanStrdef(qchanArray(Numofchan))); + end +elseif qPLOTORG(2) == 2 %% if the selected Bin is "Grid" + OverlayArraydef = qbinArray; + for Numofbin = 1:numel(qbinArray) + LegendNamedef{Numofbin,1} = char(binStrdef(qbinArray(Numofbin))); + end +elseif qPLOTORG(2) == 3%% if the selected ERPset is "Grid" + OverlayArraydef = qERPArray; + for Numoferpset = 1:numel(qERPArray) + try + LegendNamedef{Numoferpset} = ALLERPIN(qERPArray(Numoferpset)).erpname; + catch + LegendNamedef{Numoferpset} = ''; + end + end +else + OverlayArraydef = qbinArray; + for Numofbin = 1:numel(qbinArray) + LegendNamedef{Numofbin,1} = char(binStr(qbinArray(Numofbin))); + end +end + +LineColordef = [0 0 0;1 0 0;0 0 1;0 1 0;1,0.65 0;0 1 1;1 0 1;0.5 0.5 0.5;0.94 0.50 0.50;0 0.75 1;0.57 0.93 0.57;1 0.55 0;1 0.75 0.80;1 0.84 0];%% get from:https://htmlcolorcodes.com/color-names/ + +LineMarkerdef = {'none','none','none','none','+','o','*'}; +LineStyledef = {'-','--',':','-.','-','-','-',}; +[ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] = f_geterpdata(ALLERP,[1:length(ALLERP)],qPLOTORG); +%%%%%%%%%%%%%%%%%%%%-------------------------------------------------------- + +if qPLOTORG(1) ==1 %% if the selected Channel is "Grid" + plotArray = qchanArray; + for Numofchan = 1:numel(plotArray) + try + plotArrayStrdef{Numofchan} = chanStrdef{plotArray(Numofchan)}; + catch + plotArrayStrdef{Numofchan} = 'no'; + end + end +elseif qPLOTORG(1) == 2 %% if the selected Bin is "Grid" + plotArray = qbinArray; + for Numofbin = 1:numel(plotArray) + try + plotArrayStrdef{Numofbin} = binStrdef{plotArray(Numofbin)}; + catch + plotArrayStrdef{Numofbin} = 'no'; + end + end +elseif qPLOTORG(1) == 3%% if the selected ERPset is "Grid" + plotArray = qERPArray; + for Numoferp = 1:numel(plotArray) + try + plotArrayStrdef{Numoferp} = ALLERP(plotArray(Numoferp)).erpname; + catch + plotArrayStrdef{Numoferp} = 'no'; + end + end +else + plotArray = qchanArray; + for Numofchan = 1:numel(chanArray) + try + plotArrayStrdef{Numofchan} = chanStrdef{plotArray(Numofchan)}; + catch + plotArrayStrdef{Numofchan} = 'no'; + end + end +end + + +if nargin<46 || (qxdisFlag~=1 && qxdisFlag~=0) + qxdisFlag =1; +end +% if qxdisFlag==0 +% timeRangedef = timeRangedef/1000; +% end + +if nargin<45 || qxtickprecision<0 + qxtickprecision =0; +else + qxtickprecision =ceil(qxtickprecision); +end + +if nargin<44 || qytickprecision<0 + qytickprecision =1; +end +qytickprecision = ceil(qytickprecision); + +if nargin<43 + qlabelcolor = [0 0 0]; +end + + +if nargin <42 + qlegcolumns=1; +end + +if qlegcolumns<0 || isempty(qlegcolumns) + qlegcolumns =1; +end + +if nargin <41 + qlegcolor=1; +end + +if isempty(qlegcolor) || (qlegcolor~=1 && qlegcolor~=0) + qlegcolor=1; +end + +if nargin <39 || isempty(qplotArrayStr) + qplotArrayStr = plotArrayStrdef; +end + + +%% +if nargin <38 + qMinorTicksY = 0; +end + +%%display y units? +if nargin<37 + qYunits = 'on'; +end + +%%ylable color +if nargin <36 + qYlabelcolor = [0 0 0]; +end + +%%ylabel fontsize +if nargin<35 + qYlabelfontsize =10; +end + +%%ylable font +if nargin <34 + qYlabelfont = 'Geneva'; +end + +%%display ylabels? +if nargin<33 + qYticklabel = 'on'; +end + +%%yticks +datresh = squeeze(ERPdatadef(qchanArray,:,qbinArray,qERPArray)); +yymax = max(datresh(:)); +yymin = min(datresh(:)); +if abs(yymax)<1 && abs(yymin)<1 + scalesdef(1:2) = [yymin*1.2 yymax*1.1]; % JLC. Mar 11, 2015 +else + scalesdef(1:2) = [floor(yymin*1.2) ceil(yymax*1.1)]; % JLC. Sept 26, 2012 +end +yylim_out = f_erpAutoYLim(ALLERP, qERPArray,qPLOTORG,qbinArray, qchanArray,qCURRENTPLOT); +try + Yscalesdef = yylim_out(qCURRENTPLOT,:); +catch + Yscalesdef = scalesdef; +end +if nargin <32 + if isempty(qYScales) + qYticks = default_amp_ticks_viewer(Yscalesdef); + else + qYticks = default_amp_ticks_viewer(qYScales); + end +end + +%%y scale +if nargin <31 + qYScales = Yscalesdef; +end + +%%display x units? +if nargin <30 + qXunits = 'on'; +end +%%minor of xlabel +if nargin <29 + qMinorTicksX = 0; +end + +%%xlabel color +if nargin <28 + qXlabelcolor = [0 0 0]; +end + +%%xlabel fontsize +if nargin <27 + qXlabelfontsize = 10; +end + + +%%xlabel font +if nargin <26 + qXlabelfont= 'Geneva'; +end + +%%disply xtick labels ? +if nargin<25 + qXticklabel = 'on'; +end + +%%xticks +try + ERPIN = ALLERP(qCURRENTPLOT); +catch + ERPIN = ALLERP(end); +end +if isempty(qtimeRange) + qtimeRange(1) = timeRangedef(1); + qtimeRange(2) = timeRangedef(end); +end +try + [timeticksdef stepX]= default_time_ticks_studio(ERPIN, qtimeRange); + timeticksdef = str2num(char(timeticksdef)); +catch + timeticksdef = []; +end +if nargin<24 + qXticks = timeticksdef; +end + +%%time range of plot wave +if nargin<23 + qtimeRange(1) = timeRangedef(1); + qtimeRange(2) = timeRangedef(end); +end + + +%%Grid space +if nargin<22 + qGridspace =[1 10; 1 10]; +end +if isempty(qGridspace) || numel(qGridspace)~=4 || (size(qGridspace,1)~=2 || size(qGridspace,2)~=2) + qGridspace =[1 10; 1 10]; +else + [rowgs,columgs] = size(qGridspace); + if rowgs~=2 || columgs~=2 + qGridspace =[1 10; 1 10]; + else + if qGridspace(1,1)~=1 && qGridspace(1,1)~=2 + qGridspace(1,1) =1; + end + if (qGridspace(1,1)==1 && qGridspace(1,2)<=0) + qGridspace(1,2) =10; + elseif (qGridspace(1,1)==2 && (qGridspace(1,2)<=0|| qGridspace(1,2)>100)) + qGridspace(1,2) =10; + end + if qGridspace(2,1)~=1 && qGridspace(2,1)~=2 + qGridspace(2,1) =1; + end + if (qGridspace(2,1)==1 && qGridspace(2,2)<=0) + qGridspace(2,2) =10; + elseif (qGridspace(2,1)==2 && (qGridspace(2,2)<=0|| qGridspace(2,2)>=100)) + qGridspace(2,2) =10; + end + end +end + + + +%%Transparency +if nargin <21 + qTransparency = 0; +end + +%%standard error of mean +if nargin <20 + qSME = 0; +end + + +%%polarity of wave; the default is positive up +if nargin <19 + qPolarityWave = 1; +end + +%%fontsize of channel/bin/erpset label +if nargin <18 + qLabelfontsize = 10; +end + +%%font of channel/bin/erpset label +if nargin <17 + qLabelfont= 'Geneva'; +end + +%%location of channel/bin/erpset label +if nargin<16 + qCBELabels =[ ]; +end + +%%fontsize of legend name +if nargin <15 + qLegendFontsize = 10; +end + +%%font of legend name +if nargin <14 + qLegendFont = 'Geneva'; +end + +%%legend name +if nargin < 13 + qLegendName=LegendNamedef; +end + +%%line width +for Numofcolor = 1:numel(OverlayArraydef) + qLineWidthspecdef(1,Numofcolor) =1; +end +if nargin < 12 + qLineWidthspec = qLineWidthspecdef; +end + + +%%line marker +for Numofcolor = 1:numel(OverlayArraydef) + NumIndex = ceil(Numofcolor/7); + try + qLineMarkerspecdef{1,Numofcolor} = LineMarkerdef{NumIndex}; + catch + qLineMarkerspecdef{1,Numofcolor} = 'none'; + end +end +if nargin< 11 + qLineMarkerspec = qLineMarkerspecdef; +end + + +%%line style +for Numofcolor = 1:numel(OverlayArraydef) + NumIndex = ceil(Numofcolor/7); + try + qLineStylespecdef{1,Numofcolor} = LineStyledef{NumIndex}; + catch + qLineStylespecdef{1,Numofcolor} = '-'; + end +end +if nargin< 10 + qLineStylespec = qLineStylespecdef; +end + + +%%line color +for Numofcolor = 1:numel(OverlayArraydef) + Numindex = floor(Numofcolor/14); + if Numindex==0 + try + qLineColorspecdef(Numofcolor,:) = LineColordef(Numofcolor,:); + catch + qLineColorspecdef(Numofcolor,:) = [0 0 0]; + end + elseif Numindex~=0 + if floor(Numofcolor/14) ==ceil(Numofcolor/14) + qLineColorspecdef(Numofcolor,:) = LineColordef(14,:); + else + try + qLineColorspecdef(Numofcolor,:) = LineColordef(Numofcolor-14*Numindex,:); + catch + qLineColorspecdef(Numofcolor,:) = [0 0 0]; + end + end + else + try + qLineColorspecdef(Numofcolor,:) = LineColordef(14,:); + catch + qLineColorspecdef(Numofcolor,:) = [0 0 0]; + end + end +end +if nargin< 9 + qLineColorspec = qLineColorspecdef; +end + +if isempty(qLineColorspec) + qLineColorspec = qLineColorspecdef; +end + +if nargin<8 + qBlc = 'none'; +end + +if nargin<7 || isempty(plotBoxdef) || numel(plotBoxdef)~=2 + plotBox =plotBoxdef; +end + + +NumRows = ceil(plotBox(1)); +NumColumns = ceil(plotBox(2)); +if nargin<6 || isempty(qGridposArray) + count = 0; + for Numofrow = 1:NumRows %%organization of Grid + for Numofcolumn = 1:NumColumns + count = count +1; + if count> numel(plotArray) + GridposArraydef(Numofrow,Numofcolumn) =0; + else + GridposArraydef(Numofrow,Numofcolumn) = plotArray(count); + end + end + end + qGridposArray = GridposArraydef; +end +%%check elements in qGridposArray +plotArray = reshape(plotArray,1,[]); +for Numofrows = 1:size(qGridposArray,1) + for Numofcolumns = 1:size(qGridposArray,2) + SingleGridpos = qGridposArray(Numofrows,Numofcolumns); + if SingleGridpos~=0 + ExistGridops = f_existvector(plotArray,SingleGridpos); + if ExistGridops==1 + qGridposArray(Numofrows,Numofcolumns) =0; + else + [xpos,ypos]= find(plotArray==SingleGridpos); + qGridposArray(Numofrows,Numofcolumns) =ypos; + end + end + end +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%-------------------------------Plot wave-------------------------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +for Numoferpset = 1:length(ALLERP) + DataType{Numoferpset} = ALLERP(Numoferpset).datatype; +end +DataType = unique(DataType); + +ALLERPBls = ALLERP; +% +%%baseline correction +if length(DataType)==1 && strcmpi(char(DataType), 'ERP') + if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==2 && qPLOTORG(2)==1) + try + ERPArraybls = qERPArray(qCURRENTPLOT); + catch + ERPArraybls = qERPArray(end); + end + else + ERPArraybls = qERPArray; + end + for Numoferpset = ERPArraybls + ERP = ALLERP(Numoferpset); + if ~strcmpi(qBlc,'no') && ~strcmpi(qBlc,'none')%% when the baseline correction is "pre","post","whole" + + if strcmpi(qBlc,'pre') + indxtimelock = find(ERP.times==0) ; % zero-time locked + aa = 1; + elseif strcmpi(qBlc,'post') + indxtimelock = length(ERP.times); + aa = find(ERP.times==0); + elseif strcmpi(qBlc,'all') + indxtimelock = length(ERP.times); + aa = 1; + else + fs = ERP.srate; + kktime =1000; + toffsa = abs(round(ERP.xmin*fs))+1; % +1 October 2nd 2008 + blcnum = qBlc/kktime; % from msec to secs 03-28-2009 + % + % Check & fix baseline range + % + if blcnum(1)ERP.xmax + blcnum(2) = ERP.xmax; + end + aa = round(blcnum(1)*fs)+ toffsa; % in samples 12-16-2008 + indxtimelock = round(blcnum(2)*fs) + toffsa; % in samples + end + + for Numofchan = qchanArray + for Numofbin = qbinArray + if Numofchan<= ERP.nchan && Numofbin<= ERP.nbin + baselineV = mean(ERP.bindata(Numofchan,aa:indxtimelock,Numofbin),2); + ERP.bindata(Numofchan,:,Numofbin) = ERP.bindata(Numofchan,:,Numofbin)-baselineV; + end + end + end + end + ALLERPBls(Numoferpset) = ERP; + end + +else + qBlc = 'no'; +end + +datatype =''; +% [ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] +[ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] = f_geterpdata(ALLERPBls,qERPArray,qPLOTORG,qCURRENTPLOT); + +if qPLOTORG(1)==1 && qPLOTORG(2)==2 %% Array is plotnum by samples by datanum + if qCURRENTPLOT> numel(qERPArray) + qCURRENTPLOT= length(qERPArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + % if isempty(timeRangedef) + timeRangedef = ALLERPBls(qERPArray(qCURRENTPLOT)).times; + % end + try + fs= ALLERPBls(qERPArray(qCURRENTPLOT)).srate; + datatype = ALLERPBls(qERPArray(qCURRENTPLOT)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==2 && qPLOTORG(2)==1 + if qCURRENTPLOT> length(qERPArray) + qCURRENTPLOT= length(qERPArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindata = permute(bindata,[3 2 1 4]); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindataerror = permute(bindataerror,[3 2 1 4]); + if isempty(timeRangedef) + timeRangedef = ALLERPBls(qERPArray(qCURRENTPLOT)).times; + end + try + fs= ALLERPBls(qERPArray(qCURRENTPLOT)).srate; + datatype = ALLERPBls(qERPArray(qCURRENTPLOT)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==1 && qPLOTORG(2)==3 %%Grid is channel; Overlay is ERPsets; Page is bin + if qCURRENTPLOT> numel(qbinArray) + qCURRENTPLOT = numel(qbinArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindata = permute(bindata,[1 2 4 3]); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindataerror = permute(bindataerror,[1 2 4 3]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==3 && qPLOTORG(2)==1%%Grid is ERPsets; Overlay is channel + if qCURRENTPLOT> numel(qbinArray) + qCURRENTPLOT = numel(qbinArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindata = permute(bindata,[4 2 1 3]); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray(qCURRENTPLOT),:); + bindataerror = permute(bindataerror,[4 2 1 3]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==2 && qPLOTORG(2)==3%%Grid is bin; Overlay is ERPset; Page is channel + if qCURRENTPLOT> numel(qchanArray) + qCURRENTPLOT = numel(qchanArray); + end + bindata = ERPdatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindata = permute(bindata,[3 2 4 1]); + bindataerror = ERPerrordatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindataerror = permute(bindataerror,[3 2 4 1]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +elseif qPLOTORG(1)==3 && qPLOTORG(2)==2%%Grid is ERPset; Overlay is bin; Page is channel + if qCURRENTPLOT> numel(qchanArray) + qCURRENTPLOT = numel(qchanArray); + end + bindata = ERPdatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindata = permute(bindata,[4 2 3 1]); + bindataerror = ERPerrordatadef(qchanArray(qCURRENTPLOT),:,qbinArray,:); + bindataerror = permute(bindataerror,[4 2 3 1]); + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +else + if qCURRENTPLOT> length(qERPArray) + qCURRENTPLOT= length(qERPArray); + end + bindata = ERPdatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + bindataerror = ERPerrordatadef(qchanArray,:,qbinArray,qCURRENTPLOT); + if isempty(timeRangedef) + timeRangedef = ALLERPBls(qERPArray(qCURRENTPLOT)).times; + end + try + fs= ALLERPBls(qERPArray(end)).srate; + datatype = ALLERPBls(qERPArray(end)).datatype; + catch + fs= ALLERPBls(end).srate; + datatype = ALLERPBls(end).datatype; + end +end +% +if isempty(qtimeRange) + qtimeRange = [timeRangedef(1) timeRangedef(end)]; +end + +Numrows = size(qGridposArray,1); +Numcolumns = size(qGridposArray,2); + +pboxTotal = 1:Numrows*Numcolumns; +corners = linspace(Numrows*Numcolumns-Numcolumns+1,Numrows*Numcolumns,Numcolumns); +pboxplot = setxor(pboxTotal, corners); +if isempty(pboxplot) + pboxplot = 1; +end + +NumOverlay = size(bindata,3); + + +%%get y axis +y_scale_def = [1.1*min(bindata(:)),1.1*max(bindata(:))]; +yMaxdef = ceil(max(bindata(:)))-floor(min(bindata(:))); +try + isyaxislabel = qGridspace(1,1); + Ypert = qGridspace(1,2); +catch + isyaxislabel = 1; + Ypert = 100; +end +if isempty( qYScales) + qYScales = [floor(min(bindata(:))),ceil(max(bindata(:)))]; +end +if isyaxislabel==1 %% y axis GAP + if Ypert<0 + Ypert = 100; + end + if ~isempty(qYScales) + if numel(qYScales)==2 + yscaleall = qYScales(end)-qYScales(1); + else + yscaleall = 2*max(abs(qYScales)); + qYScales = [-max(abs(qYScales)),max(abs(qYScales))]; + end + if yscaleall < y_scale_def(2)-y_scale_def(2) + yscaleall = y_scale_def(2)-y_scale_def(2); + end + + for Numofrows = 1:Numrows + OffSetY(Numofrows) = yscaleall*(Numrows-Numofrows)*(Ypert/100+1); + end + else + for Numofrows = 1:Numrows + OffSetY(Numofrows) = yMaxdef*(Numrows-Numofrows)*(Ypert/100+1); + end + end +else%% y axis Overlay + if Ypert>=100 || Ypert<=0 + Ypert = 40; + end + if ~isempty(qYScales) + if numel(qYScales)==2 + yscaleall = qYScales(end)-qYScales(1); + else + yscaleall = 2*max(abs(qYScales)); + qYScales = [-max(abs(qYScales)),max(abs(qYScales))]; + end + + if yscaleall < y_scale_def(2)-y_scale_def(2) + yscaleall = y_scale_def(2)-y_scale_def(2); + end + + if Numrows ==1 + OffSetY = 0; + else + for Numofrows = 1:Numrows-1 + OffSetY(Numofrows) = yscaleall*(Numrows-Numofrows)*(1-(Ypert/100)); + end + OffSetY(Numrows)=0; + end + else + qYScales = [floor(min(bindata(:))),ceil(max(bindata(:)))]; + if Numrows ==1 + OffSetY = 0; + else + for Numofrows = 1:Numrows-1 + OffSetY(Numofrows) = yMaxdef*(Numrows-Numofrows)*(1-(Ypert/100)); + end + OffSetY(Numrows)=0; + end + end +end + + +%%X axis gap +try + isxaxislabel = qGridspace(2,1); + Xpert = qGridspace(2,2); +catch + isxaxislabel = 1; + Xpert = 10; +end +if isxaxislabel ~=1 && isxaxislabel~=2 + isxaxislabel = 1; +end + + +if isxaxislabel==1 && Xpert<=0 + Xpert =10; +elseif isxaxislabel==2 && (Xpert<=0 || Xpert >=100) + Xpert =40; +end +try + StepX = (timeRangedef(end)-timeRangedef(1))*(Xpert/100); +catch + beep; + disp('ERP.times only has one element.'); + return; +end +StepXP = ceil(StepX/(1000/fs)); + + +%%check yticks +try + count =0; + ytickDis =[]; + for Numofytick = 1:numel(qYticks) + if qYticks(Numofytick) < qYScales(1) || qYticks(Numofytick) > qYScales(end) + count = count+1; + ytickDis(count) = Numofytick; + end + end + qYticks(ytickDis) = []; +catch +end +if isempty(qYticks) + qYticks = str2num(char(default_amp_ticks_viewer(qYScales))); +end + +%%Get the figure name which is to be plotted +if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==1 && qPLOTORG(2)==2) %% Page is ERPset + ERP = ALLERPBls(qCURRENTPLOT); + if isempty(ERP.filename) || strcmp(ERP.filename,'') + ERP.filename = 'still_not_saved!'; + end + if isempty(ERP.erpname) + fname = 'none'; + else + [pathstr, fname, ext] = fileparts(ERP.erpname); + end +elseif (qPLOTORG(1)==1 && qPLOTORG(2)==3) || (qPLOTORG(1)==3 && qPLOTORG(2)==1) %% Page is bin + fname = char(binStrdef{qbinArray(qCURRENTPLOT)}); + +elseif (qPLOTORG(1)==2 && qPLOTORG(2)==3) || (qPLOTORG(1)==3 && qPLOTORG(2)==2) + fname = char(chanStrdef{qchanArray(qCURRENTPLOT)}); +else + ERP = ALLERPBls(qCURRENTPLOT); + if isempty(ERP.filename) || strcmp(ERP.filename,'') + ERP.filename = 'still_not_saved!'; + end + if isempty(ERP.erpname) + fname = 'none'; + else + [pathstr, fname, ext] = fileparts(ERP.erpname); + end +end + +try + y_scale_def(1) = min([1.1*y_scale_def(1),1.1*qYScales(1)]); + y_scale_def(2) = max([1.1*y_scale_def(2),1.1*qYScales(2)]); +catch +end +%%--------------Plot ERPwave----------------- +stdalpha = qTransparency; +countPlot = 0; +for Numofrows = 1:Numrows + for Numofcolumns = 1:Numcolumns + plotdatalabel = qGridposArray(Numofrows,Numofcolumns); + + try + labelcbe = qplotArrayStr{plotdatalabel}; + catch + labelcbe = 'no'; + end + try + plotbindata = bindata(plotdatalabel,:,:,:); + catch + plotbindata = []; + end + + if plotdatalabel ~=0 && plotdatalabel<= numel(plotArray) && ~isempty(plotbindata) + + countPlot =countPlot +1; + + if qPolarityWave + data4plot = squeeze(bindata(plotdatalabel,:,:,1)); + else + data4plot = squeeze(bindata(plotdatalabel,:,:,1))*(-1); + end + data4plot = reshape(data4plot,numel(timeRangedef),NumOverlay); + for Numofoverlay = 1:NumOverlay + [Xtimerange, bindatatrs] = f_adjustbindtabasedtimedefd(squeeze(data4plot(:,Numofoverlay)), timeRangedef,qtimeRange,fs); + PosIndexsALL = [Numofrows,Numcolumns]; + if isxaxislabel==2 + [~,XtimerangetrasfALL,~,~,~] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexsALL,StepXP); + else + [~,XtimerangetrasfALL,~] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexsALL,StepX,fs); + end + + aerror = isnan(squeeze(bindataerror(plotdatalabel,:,Numofoverlay,1))); + [Xerror,yerro] = find(aerror==0); + + PosIndexs = [Numofrows,Numofcolumns]; + if ~isempty(yerro) && qSEM>=1 &&stdalpha>0 %SEM + [Xtimerange, bindataerrtrs] = f_adjustbindtabasedtimedefd(squeeze(bindataerror(plotdatalabel,:,Numofoverlay,1)), timeRangedef,qtimeRange,fs); + if isxaxislabel==2 + [bindatatrs1,Xtimerangetrasf,qXtickstransf,TimeAdjustOut,XtimerangeadjustALL] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepXP); + else + [bindatatrs1,Xtimerangetrasf,qXtickstransf] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepX,fs); + end + yt1 = bindatatrs1 - bindataerrtrs.*qSEM; + yt2 = bindatatrs1 + bindataerrtrs.*qSEM; + % ciplot(yt1,yt2, Xtimerangetrasf, qLineColorspec(Numofoverlay,:), stdalpha); + fill(hbig,[Xtimerangetrasf fliplr(Xtimerangetrasf)],[yt2 fliplr(yt1)], qLineColorspec(Numofoverlay,:), 'FaceAlpha', stdalpha, 'EdgeColor', 'none'); + % set(hbig, 'InvertHardcopy', 'off', 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait'); + end + if isxaxislabel==2 + [bindatatrs,Xtimerangetrasf,qXtickstransf,TimeAdjustOut,XtimerangeadjustALL] = f_adjustdata_xyrange_xyticks_overlay(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepXP); + else + [bindatatrs,Xtimerangetrasf,qXtickstransf] = f_adjustdata_xyrange_xyticks(bindatatrs,Xtimerange,qXticks,OffSetY,Numcolumns,PosIndexs,StepX,fs); + end + hplot(Numofoverlay) = plot(hbig,Xtimerangetrasf, bindatatrs,'LineWidth',qLineWidthspec(Numofoverlay),... + 'Color', qLineColorspec(Numofoverlay,:), 'LineStyle',qLineStylespec{Numofoverlay},'Marker',qLineMarkerspec{Numofoverlay}); + end + + if numel(OffSetY)==1 && OffSetY==0 + if ~qPolarityWave + YscalesNew = sort(y_scale_def*(-1)); + else + YscalesNew = y_scale_def; + end + set(hbig,'ylim',YscalesNew); + else + if qPolarityWave + ylimleftedge = floor(y_scale_def(1)); + ylimrightedge = ceil(y_scale_def(end))+OffSetY(1); + else + ylimleftedge = -abs(ceil(1.05*y_scale_def(end))); + ylimrightedge = ceil(1.05*abs(y_scale_def(1)))+OffSetY(1); + end + set(hbig,'ylim',[ylimleftedge,ylimrightedge]); + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------Adjust y axis------------------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + props = get(hbig); + if qPolarityWave + props.YTick = qYticks+OffSetY(Numofrows); + else + props.YTick = fliplr (-1*qYticks)+OffSetY(Numofrows); + end + props.YTickLabel = cell(numel(props.YTick),1); + + + for Numofytick = 1:numel(props.YTick) + props.YTickLabel(Numofytick) = {num2str(props.YTick(Numofytick))}; + end + + [x,y_0] = find(Xtimerange==0); + if isempty(y_0) + y_0 = 1; + end + myY_Crossing = Xtimerangetrasf(y_0); + tick_top = 0; + if countPlot ==1 + ytick_bottom = -props.TickLength(1)*diff(props.XLim); + ytick_bottomratio = abs(ytick_bottom)/diff(props.XLim); + else + try + ytick_bottom = ytick_bottom; + ytick_bottomratio = ytick_bottomratio; + catch + ytick_bottom = -props.TickLength(1)*diff(props.XLim); + ytick_bottomratio = abs(ytick_bottom)/diff(props.XLim); + end + end + %%add yunits + if qPolarityWave%%Positive up + yunitsypos = 0.98*qYScales(end); + else + yunitsypos = 0.95*abs(qYScales(1)); + end + if strcmpi( datatype,'ERP') + yunitstr = '\muV'; + elseif strcmpi( datatype,'CSD') + yunitstr = '\muV/m^2'; + else + yunitstr = ''; + end + if strcmpi(qYunits,'on') + text(hbig,myY_Crossing+abs(ytick_bottom),yunitsypos+OffSetY(Numofrows),yunitstr, 'FontName',qYlabelfont,'FontSize',qYlabelfontsize,'HorizontalAlignment', 'left', 'Color', qYlabelcolor); + end + if ~isempty(props.YTick) + ytick_y = repmat(props.YTick, 2, 1); + ytick_x = repmat([tick_top;ytick_bottom] +myY_Crossing, 1, length(props.YTick)); + line(hbig,ytick_x(:,:), ytick_y(:,:), 'color', 'k','LineWidth',1); + try + [~,y_below0] =find(qYticks<0); + if isempty(y_below0) && qYScales(1)<0 + line(hbig,ytick_x(:,:), ones(2,1)*(qYScales(1)+OffSetY(Numofrows)), 'color', 'k','LineWidth',1); + end + [~,y_over0] =find(qYticks>0); + if isempty(y_over0) && qYScales(2)>0 + line(hbig,ytick_x(:,:), ones(2,1)*(qYScales(2)+OffSetY(Numofrows)), 'color', 'k','LineWidth',1); + end + catch + end + end + + if ~isempty(qYScales) && numel(qYScales)==2 %qYScales(end))+OffSetY(1) + if qPolarityWave==0 + qYScalestras = fliplr (-1*qYScales); + else + qYScalestras = qYScales; + end + plot(hbig,ones(numel(qYScalestras),1)*myY_Crossing, qYScalestras+OffSetY(Numofrows),'k','LineWidth',1); + else + if ~isempty(y_scale_def) && numel(unique(y_scale_def))==2 + if qPolarityWave==0 + qYScalestras = fliplr (-1*y_scale_def); + else + qYScalestras = y_scale_def; + end + + plot(hbig,ones(numel(qYScales),1)*myY_Crossing, qYScalestras+OffSetY(Numofrows),'k','LineWidth',1); + else + + end + end + nYTicks = length(props.YTick); + for iCount = 1:nYTicks + if qPolarityWave + ytick_label= sprintf(['%.',num2str(qytickprecision),'f'],str2num(char(props.YTickLabel(iCount, :)))-OffSetY(Numofrows)); + else + qyticktras = fliplr (-1*qYticks); + ytick_label= sprintf(['%.',num2str(qytickprecision),'f'],-qyticktras(iCount)); + end + if str2num(char(ytick_label)) ==0 || (str2num(char(ytick_label))<0.0001 && str2num(char(ytick_label))>0) || (str2num(char(ytick_label))>-0.0001 && str2num(char(ytick_label))<0) + ytick_label = ''; + end + if ~strcmpi(qYticklabel,'on') + ytick_label = ''; + end + text(hbig,myY_Crossing-2*abs(ytick_bottom),props.YTick(iCount), ... + ytick_label, ... + 'HorizontalAlignment', 'right', ... + 'VerticalAlignment', 'middle', ... + 'FontSize', qYlabelfontsize, ... + 'FontName', qYlabelfont, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits,... + 'Color',qYlabelcolor); + end + + %%Minor Y + if qMinorTicksY(1) + set(hbig,'YMinorTick','on') + try + MinorTicksYValue = qMinorTicksY(2:end); + catch + MinorTicksYValue = []; + end + if ~isempty(MinorTicksYValue) + MinorTicksYValue(find(MinorTicksYValueqYScales(end))) = [];%% check the minorticks based on the right edge of yticks + props.YAxis.TickValues = MinorTicksYValue; + if ~isempty( props.YAxis.TickValues) + ytick_y = repmat( props.YAxis.TickValues+OffSetY(Numofrows), 2, 1); + ytick_x = repmat([tick_top;2*ytick_bottom/3] +myY_Crossing, 1, length( props.YAxis.TickValues)); + line(hbig,ytick_x(:,:), ytick_y(:,:), 'color', 'k','LineWidth',1); + end + end + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%----------------------Adjust x axis------------------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + props.XTick = qXtickstransf; + props.XTickLabel = cell(numel(qXticks),1); + for Numofytick = 1:numel(props.XTick) + props.XTickLabel(Numofytick) = {num2str(qXticks(Numofytick))}; + end + myX_Crossing = OffSetY(Numofrows); + if countPlot ==1 + xtick_bottom = -props.TickLength(2)*max(props.YLim); + if abs(xtick_bottom)/max(props.YLim) > ytick_bottomratio + xtick_bottom = -ytick_bottomratio*max(props.YLim); + end + else + try + xtick_bottom = xtick_bottom; + catch + xtick_bottom = -props.TickLength(2)*max(props.YLim); + if abs(xtick_bottom)/max(props.YLim) > ytick_bottomratio + xtick_bottom = -ytick_bottomratio*max(props.YLim); + end + end + end + if ~isempty(props.XTick) + xtick_x = repmat(props.XTick, 2, 1); + xtick_y = repmat([xtick_bottom; tick_top] + myX_Crossing, 1, length(props.XTick)); + line(hbig,xtick_x, xtick_y, 'color', 'k','LineWidth',1); + end + [x_xtick,y_xtick] = find(props.XTick==0); + if ~isempty(y_xtick) + props.XTick(y_xtick) = 2*xtick_bottom; + end + plot(hbig,Xtimerangetrasf, myX_Crossing.*ones(numel(Xtimerangetrasf),1),'k','LineWidth',1); + nxTicks = length(props.XTick); + + for iCount = 1:nxTicks + xtick_label = (props.XTickLabel(iCount, :)); + if strcmpi(qXticklabel,'on') + if strcmpi(xtick_label,'0') + xtick_label = ''; + end + else + xtick_label = ''; + end + if qxdisFlag ==1%%in millisecond + xtick_label= sprintf(['%.',num2str(qxtickprecision),'f'],str2num(char(xtick_label))); + else%% in second + xtick_label= sprintf(['%.',num2str(qxtickprecision),'f'],str2num(char(xtick_label))/1000); + end + + if strcmpi(qXunits,'on') && (iCount== nxTicks) && qxdisFlag ==1 + xtick_label = strcat(char(xtick_label),32,'ms'); + elseif strcmpi(qXunits,'on') && (iCount== nxTicks) && qxdisFlag ==0 + xtick_label = strcat(char(xtick_label),32,'s'); + end + text(hbig,props.XTick(iCount), xtick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', qXlabelfontsize, ... + 'FontName', qXlabelfont, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits,... + 'Color',qXlabelcolor); + end + %%-----------------minor X--------------- + if Xtimerange(1)< Xtimerangetrasf(end) + set(hbig,'xlim',[Xtimerange(1),Xtimerangetrasf(end)]); + end + if qMinorTicksX(1) + set(hbig,'XMinorTick','on'); + if isxaxislabel==2 + xlimrightedgemin = TimeAdjustOut; + else + timewindow_bin = Xtimerange(2)-Xtimerange(1); + xlimrightedgemin = timewindow_bin*(numel(Xtimerange)*(Numofcolumns-1)+StepXP*(Numofcolumns-1)); + end + try + MinorTicksXValue = qMinorTicksX(2:end); + catch + MinorTicksXValue = []; + end + if ~isempty(MinorTicksXValue) + MinorTicksXValue(find(MinorTicksXValueXtimerange(end))) = [];%% check the xminorticks based on the right edge of xticks + props.XAxis.TickValues = unique(MinorTicksXValue+xlimrightedgemin); + if ~isempty(props.XAxis.TickValues) + xtick_x = repmat(props.XAxis.TickValues, 2, 1); + xtick_y = repmat([2*xtick_bottom/3; tick_top] + myX_Crossing, 1, length(props.XAxis.TickValues)); + line(hbig,xtick_x, xtick_y, 'color', 'k','LineWidth',1); + end + end + end + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%------------------channel/bin/erpset label-----------------%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if ~isempty(qCBELabels) + try + iscenter = qCBELabels(3); + catch + iscenter =1; + end + try + ypercentage=qCBELabels(2); + catch + ypercentage =100; + end + ypos_LABEL = ((qYScalestras(end)-qYScalestras(1))*(ypercentage)/100+qYScalestras(1)); + try + xpercentage=qCBELabels(1); + catch + xpercentage = 50; + end + xpos_LABEL = (Xtimerangetrasf(end)-Xtimerangetrasf(1))*xpercentage/100 + Xtimerangetrasf(1); + labelcbe = strrep(char(labelcbe),'_','\_'); + try + labelcbe = regexp(labelcbe, '\;', 'split'); + catch + end + if ~iscenter + text(hbig,xpos_LABEL,ypos_LABEL+OffSetY(Numofrows), char(labelcbe), 'FontName',qLabelfont,'FontSize',qLabelfontsize,'HorizontalAlignment', 'center', 'Color', qlabelcolor);%'FontWeight', 'bold', + else + text(hbig,xpos_LABEL,ypos_LABEL+OffSetY(Numofrows), char(labelcbe), 'FontName',qLabelfont,'FontSize',qLabelfontsize,'HorizontalAlignment', 'left', 'Color', qlabelcolor);%'FontWeight', 'bold', + end + end + + else + % disp(['Data at',32,'R',num2str(Numofrows),',','C',num2str(Numofcolumns), 32,'is not defined!']); + end + try + if isxaxislabel==2 + set(hbig,'xlim',[Xtimerange(1)-(Xtimerange(end)-Xtimerange(1)/10),XtimerangetrasfALL(end)+(Xtimerange(end)-Xtimerange(1))/10]); + else + set(hbig,'xlim',[Xtimerange(1)-(Xtimerange(end)-Xtimerange(1))/10,XtimerangetrasfALL(end)+(Xtimerange(end)-Xtimerange(1))/10]); + end + catch + + end + end%% end of columns + +end%% end of rows +set(hbig, 'XTick', [], 'YTick', [],'Box','off', 'Color','none','xcolor','none','ycolor','none'); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%------------------------------legend name------------------------------%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +try + for Numofoverlay = 1:numel(hplot) + qLegendName1 = strrep(qLegendName{Numofoverlay},'_','\_'); + % qLegendName1 = qLegendName{Numofoverlay}; + LegendName{Numofoverlay} = char(strcat('\color[rgb]{',num2str(qLineColorspec(Numofoverlay,:)),'}',qLegendName1)); + end + p = get(myerpviewerlegend,'position'); + if qlegcolor ~=1 + try + h_legend = legend(myerpviewerlegend, hplot,LegendName);%,'interpreter','none' + catch + h_legend = legend(myerpviewerlegend, hplot,qLegendName,'interpreter','none'); + end + else + h_legend = legend(myerpviewerlegend, hplot,qLegendName,'interpreter','none'); + end + set(h_legend,'FontSize',qLegendFontsize);%% legend name fontsize + set(h_legend, 'position', p); + set(h_legend,'FontName',qLegendFont);%%legend name font + set(h_legend,'NumColumns',qlegcolumns); + + legend(myerpviewerlegend,'boxoff'); + set(myerpviewerlegend, 'XTick', [], 'YTick', [],'Box','off', 'Color','none','xcolor','none','ycolor','none'); +catch +end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_setdiffstr.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_setdiffstr.m new file mode 100644 index 00000000..220c4014 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/f_setdiffstr.m @@ -0,0 +1,26 @@ + + + +function diffStr = f_setdiffstr(StrLarger,StrSmall) + + +diffStr = ''; +S_index = []; +count = 0; +for Numofstr = 1:length(StrSmall) + [C,IA] = ismember_bc2(StrSmall{Numofstr},StrLarger); + if C==1 && IA<=length(StrLarger) + count = count+1; + S_index(count) = IA; + end +end + + +diff_index = setdiff([1:length(StrLarger)],S_index); +if ~isempty(diff_index) + + for ii = 1:numel(diff_index) + diffStr{ii} = StrLarger{diff_index(ii)}; + end +end +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/neozeroaxesestudioviewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/neozeroaxesestudioviewer.m new file mode 100755 index 00000000..a5d4a00c --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/neozeroaxesestudioviewer.m @@ -0,0 +1,335 @@ +% This function is a combination of the zeroaxes.m from Andrew Knight and axescenter.m from Matt Fig. +% I just took the best of them to allow the axes look nice (crossing at the origin) and being able to be interactive. +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 +% +% Apr-2015: updated/fixed to deal with Matlab's HG2 update (Matlab 2014b and later). JLC + +function neozeroaxesestudioviewer(type, qXlabelfont,qXlabelfontsize,qXlabelcolor,qYlabelfont,qYlabelfontsize,qYlabelcolor, mcolor,qXticklabel,qYticklabel,qXunits,qMinorTicksX,qMinorTicksY) + +if nargin <13 + isMinorTicksY = 'off'; + MinorYTicks = []; +end + +if qMinorTicksY(1)==1 + isMinorTicksY = 'on'; +else + isMinorTicksY = 'off'; +end + +if strcmpi(isMinorTicksY,'on') + try + MinorYTicks = qMinorTicksY(2:end); + catch + MinorYTicks = []; + end +else + MinorYTicks = []; +end + + + +if nargin<12 + isMinorTicksX = 'off'; + MinorXTicks = []; +end + +if qMinorTicksX(1)==1 + isMinorTicksX = 'on'; +else + isMinorTicksX = 'off'; +end + +if strcmpi(isMinorTicksX,'on') + try + MinorXTicks = qMinorTicksX(2:end); + + catch + MinorXTicks = []; + end +else + MinorXTicks = []; +end + + +if nargin<11 + qXunits = 'on'; +end +if nargin< 10 + qYticklabel = 'on'; +end +if isempty(qYticklabel) + qYticklabel = 'on'; +end + + +if nargin< 9 + qXticklabel = 'on'; +end +if isempty(qXticklabel) + qXticklabel = 'on'; +end + +if nargin<8 + mcolor = []; %[.7 .9 .7]; +end + +if nargin<7 + qYlabelcolor = 'k'; +end +if isempty(qYlabelcolor) + qYlabelcolor = 'k'; +end + +if nargin<6 + qYlabelfontsize = 12; +end +if isempty(qYlabelfontsize) + qYlabelfontsize = 12; +end +if nargin <5 + qYlabelfont = 'Courier'; +end +if isempty(qYlabelfont) + qYlabelfont = 'Courier'; +end + + +if nargin<4 + qXlabelcolor = 'k'; +end + +if nargin<3 + qXlabelfontsize = 12; +end + +if isempty(qXlabelcolor) + qXlabelcolor = 'k'; +end + +if isempty(qXlabelfontsize) + qXlabelfontsize = 12; +end + +if nargin<2 + qXlabelfont = 'Courier'; +end + +if isempty(qXlabelfont) + qXlabelfont = 'Courier'; +end + +if isempty(mcolor) + mcolor = get(gcf,'Color'); +end +linew = 1; % axes line width +holdwason = ishold; +axesin = get(gcf,'CurrentAxes'); % get current axes (old axes) +bdownf = get(gcf,'ButtonDownFcn'); % JLC, May 12th 2008 +posi = get(axesin,'position'); % get axes position + +% create new axes (ax) +ax = axis; +xscale = get(axesin,'XScale'); % get XScale from the old X axis +yscale = get(axesin,'YScale'); % get YScale from the old Y axis +ticklength = get(axesin,'TickLength'); % get TickLength from the old axis +sentido = get(axesin,'YDir'); % get Ydir from the old Y axis + +if type==0 % matlab + set(axesin,'Visible','on'); % make old axes visible + Xaxcolor = [.7 .9 .7]; % Original + Yaxcolor = [.7 .9 .7]; % Original + xxticks = []; + yyticks = []; + xmt = 'off'; + ymt = 'off'; + set(axesin,'FontSize', qXlabelfontsize); +else % zero crossing axes + set(axesin,'Visible','off');% make old axes invisible + Xaxcolor = 1 - mcolor; + Yaxcolor = 1 - mcolor; + xxticks = get(axesin,'XTick'); % get XTick from the old X axis + yyticks = get(axesin,'YTick'); % get YTick from the old Y axis + xmt = get(axesin,'XMinorTick'); % get XMinorTick from the old X axis + ymt = get(axesin,'YMinorTick'); % get YMinorTick from the old Y axis +end + +% get values from the recently created axes +xmin = ax(1); +xmax = ax(2); +ymin = ax(3); +ymax = ax(4); + +% prepare values for new axes +XAxisHeight = ticklength(1); +YAxisWidth = ticklength(1); +f = polyfit([ax(1) ax(2)],[posi(1) posi(1)+posi(3)],1); +XAxisXLimits = polyval(f,[xmin xmax]); +YAxisXLimits = polyval(f,[0 YAxisWidth*abs(xmax - xmin)]); +f = polyfit([ax(3) ax(4)],[posi(2) posi(2)+posi(4)],1); +YAxisYLimits = polyval(f,[ymin ymax]); +XAxisYLimits = polyval(f,[0 XAxisHeight*abs(ymax - ymin)]); +bgcolour = get(gcf,'color'); % gets background color + +% right (new) XY axes intersection in case Y is inversed. +if strcmp(sentido, 'reverse') + Xaxis_y = 2*posi(2)+posi(4)-XAxisYLimits(1); +else + Xaxis_y = XAxisYLimits(1); +end +XAxisPosition = [XAxisXLimits(1) Xaxis_y XAxisXLimits(2) - XAxisXLimits(1) XAxisYLimits(2) - XAxisYLimits(1)]; + +% create new X axis Xaxcolor +AX.hX = axes('position',XAxisPosition,... + 'XLim',[xmin xmax],... + 'box','off',... + 'YTick',[],... + 'TickDir','out',... + 'XScale',xscale,... + 'YColor',bgcolour,... + 'XColor',qXlabelcolor,... + 'LineWidth', linew,... + 'FontSize', qXlabelfontsize,... + 'FontName',qXlabelfont,... + 'color','none'); + +% new Y axis position +YAxisPosition = [YAxisXLimits(1) YAxisYLimits(1) YAxisXLimits(2) - YAxisXLimits(1) YAxisYLimits(2) - YAxisYLimits(1)]; + +% create new Y axis +AX.hY = axes('position',YAxisPosition,... + 'YLim',[ymin ymax],... + 'box','off',... + 'Xtick',[],... + 'TickDir','out',... + 'YScale',yscale,... + 'YColor', qYlabelcolor,... + 'XColor',bgcolour,... + 'LineWidth', linew,... + 'FontSize', qYlabelfontsize,... + 'FontName',qYlabelfont,... + 'color','none',... + 'YDir', sentido); % JLC, May 12th 2008 +% +% Set new axes +% +set(AX.hX,'XTick',xxticks) +set(AX.hY,'YTick',yyticks) +for Numofyyticklabel = 1:numel(yyticks) + yyticklabe{Numofyyticklabel} = num2str(yyticks(Numofyyticklabel)); + +end +AX.hY.YTickLabel = cell(numel(yyticks),1); +set(AX.hY,'YTickLabel',yyticklabe); + +if ~isempty(MinorXTicks) && strcmpi(isMinorTicksX,'on') + try + AX.hX.XAxis.MinorTickValues = MinorXTicks; + catch + end + set(AX.hX,'XMinorTick',isMinorTicksX) +end +% set(AX.hX,'XMinorTick',isMinorTicksX) + +if ~isempty(MinorYTicks) && strcmpi(isMinorTicksY,'on') + try + AX.hY.YAxis.MinorTickValues = MinorYTicks; + catch + end +end +set(AX.hY,'YMinorTick',isMinorTicksY) + +if type==1 + % Get rid of the zero ticks (if necessary) + if ymin<0 && ~strcmp(xscale,'log') + xticks = get(AX.hX,'XTick'); + [rowsx columnsx] = find(xticks==0); + if ~isempty(columnsx) + AX.hX.XTickLabel{columnsx} = ''; + end + end + if xmin<0 && ~strcmp(yscale,'log') + yticks = get(AX.hY,'YTick'); + [rows columns] = find(yticks==0); + if ~isempty(columns) + AX.hY.YTickLabel{columns} = ''; + end + end +end + +set(gcf,'CurrentAxes',axesin) +set(gcf,'ButtonDownFcn',bdownf) + +if ~holdwason + set(AX.hX,'NextPlot','Replace') + set(AX.hY,'NextPlot','Replace') +end + +% Store the handles in appdata of AX. +setappdata(axesin,'CENTERAXES', AX); +if strcmpi(qXticklabel,'off') + set(AX.hX,'XTickLabel',[]); +else + if strcmpi(qXunits,'on') && ~isempty(AX.hX.XTickLabel) +% AX.hX.XTickLabel = cell(numel(AX.hX.XTickLabel),1); + AX.hX.XTickLabel{length(AX.hX.XTickLabel)} = strcat(32,32, AX.hX.XTickLabel{length(AX.hX.XTickLabel)},'ms'); + end +end + +if strcmpi(qYticklabel,'off') + set(AX.hY,'YTickLabel',[]); +end + +% when any property of the old axes changes these functions will keep the new ones updated +% JLC, April 2015 +addlistener(axesin,'XLim', 'PostSet', @(varargin) xylim(varargin{:}, axesin)); +addlistener(axesin,'YLim', 'PostSet', @(varargin) xylim(varargin{:}, axesin)); +addlistener(axesin,'Position', 'PostSet', @(varargin) xylim(varargin{:}, axesin)); + +%----------------------------------------------------------------- +function [] = xylim(varargin) +% Adjusts the x and y limits. +axesin = varargin{3}; +AX = getappdata(axesin); +AX = AX.CENTERAXES; +xlim = get(axesin,'XLim'); +ylim = get(axesin,'YLim'); +xdir = get(axesin,'XDir'); +ydir = get(axesin,'YDir'); +set(AX.hY,'YLim', ylim); +set(AX.hX,'XLim', xlim); +% Adjusts x and y directions +set(AX.hY,'YDir', ydir); +set(AX.hX,'XDir', xdir); +% Adjusts pos +adjpos(axesin) + +%----------------------------------------------------------------- +function [] = adjpos(axesin) +AX = getappdata(axesin); +AX = AX.CENTERAXES; +xlim = get(axesin,'XLim'); +ylim = get(axesin,'YLim'); +% xdir = get(ax,'XDir'); +ydir = get(axesin,'YDir'); +% Adjusts the position. +p = get(axesin,'Position'); +nn = 1000; +ss = linspace(xlim(1), xlim(2), nn); +[aa, bb] = min(abs(ss)); +px0 = bb/nn; % proportion of axis X when Y intersects X +set(AX.hY,'Position',[p(1)+p(3)*px0 p(2) eps p(4)]); % set Y axis new pos +ss = linspace(ylim(1), ylim(2), nn); +[aa, bb] = min(abs(ss)); +if strcmpi(ydir, 'reverse') + py0 = 1-bb/nn; % proportion of axis Y when X intersects Y +else + py0 = bb/nn; % proportion of axis Y when X intersects Y +end +set(AX.hX,'Position',[p(1) p(2)+p(4)*py0 p(3) eps]); % set X axis new pos \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/pop_plotERPwaviewer.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/pop_plotERPwaviewer.m new file mode 100755 index 00000000..1562e8f1 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/pop_plotERPwaviewer.m @@ -0,0 +1,1170 @@ +% PURPOSE: pop_plotERPwaviewer.m +% plot ERP waveforms +% + +% FORMAT: +% +% [ALLERP, erpcom] = pop_plotERPwaviewer(ALLERP,CURRENTPLOT,ERPsetArray,binArray, chanArray,'PLOTORG',PLOTORG,'GridposArray',GridposArray,'LabelsName',LabelsName, 'Blc', Blc,'Box',plotBox,'LineColor',LineColorspec,'LineStyle',LineStylespec,... +% 'LineMarker',LineMarkerspec,'LineWidth',LineWidthspec,'LegendName',LegendName,'LegendFont',FontLeg,'LegendFontsize',FontSizeLeg,... +% 'Labeloc',CBELabels,'Labelfont',CBEFont,'Labelfontsize',CBEFontsize,'YDir',PolarityWave,'SEM',Standerr,'Transparency', Transparency,... +% 'GridSpace',GridSpace,'TimeRange',timeRange,'Xticks',timeticks,'Xticklabel',xticklabel,'Xlabelfont',xlabelFont,'Xlabelfontsize',xlabelFontsize,... +% 'Xlabelcolor',xlabelFontcolor,'Xunits',Xunits,'MinorTicksX',MinorticksX,... +% 'YScales',Yscales,'Yticks',Yticks,'Yticklabel',yticklabel,'Ylabelfont',YlabelFont,'Ylabelfontsize',YlabelFontsize,... +% 'Ylabelcolor',ylabelFontcolor,'Yunits',yunits,'MinorTicksY',MinorticksY,'LegtextColor',TextcolorLeg,'Legcolumns',Legcolumns,'FigureName',FigureName,... +% 'FigbgColor',figbgdColor,'Labelcolor',Labelcolor,'Ytickdecimal',Ytickprecision,'Xtickdecimal',Xtickprecision,'XtickdisFlag',XdisFlag,'Parameterfile',Parameterfile,'History', 'gui'); + +% Inputs: +% +%ALLERP -ALLERPset +%CURRENTPLOT -index of current ERPset/bin/channel(e.g., 1) +%PLOTORG -plot organization including three elements (the default is [1 2 3]) +% First element is for Grid (1 is channel; 2 is bin; 3 is ERPset) +% Second element is for Overlay (1 is channel; 2 is bin; 3 is ERPset) +% Third element is for Page (1 is channel; 2 is bin; 3 is ERPset) +%binArray -index(es) of bin(s) to plot ( 1 2 3 ...) +%chanArray -index(es) of channel(s) to plot ( 5 10 11 ...) +%GridposArray -location and correponding index of each subplot. E.g., +% plot three channels with 2 (rows) x 2 (columns), the default qGridposArray is +% [5,10;11,0]. The each element of GridposArray is the +% index of selected Channel/bin/ERPset. 0 repsents no +% channel/bin/ERP will be dispalyed +%LabelsName -Channel/Bin/ERPset labels e.g., {'Fz','F3','F4'} +%plotBox -ditribution of plotting boxes in rows x columns. +%Blc -string or numeric interval for baseline correction +% reference window: 'no','pre','post','all', or[-100 0] +%LineColor -line color with RGB,e.g., [0 0 0;1 0 0] +%LineStyle -line style e.g., {'-','-'} +%LineMarker -line marker e.g., {'o','*','none'} +%LineWidth -line width e.g., [1 1 1] +%LegendName -legend name e.g., {'Rare','Frequent'} +%LegendFont -font for legend name e.g., 'Courier' or 'Times' +%LegendFontsize -fontsize for legend name (one value) e.g., 12 or 16 +%Labeloc -location for channel/bin/erpset label including three +% elements e.g., [100 100 1]; first and second represent +% the percentage of time range or y scales; the last +% element determine whether display the label (1 or 0) +%Labelfont -label font +%Labelfontsize -label fontsize +%YDir -"Y" axis is inverted (-UP)?: 'yes', 'no'. 1 is positive up and 0 +% is negative up +%'SEM' - plot standard error of the mean (if available). 0 is +% off and other is on. +%Transparency - the default is 0 +%GridSpace - Grid spacing includes two dimensions (2 X 2). The first +% column is Gap (1) or Overlap (2); The second column +% represents the specific values for Gap/Overlap. +%TimeRange -time window is used to display the wave e.g., [-200 800] +%Xticks - ticks for x axes e.g., [-200 0 200 400 600 800] +%Xticklabel -display xticklabels? 1 is on and 0 is off. +%Xlabelfont -font for xtick and xticklabel e.g., 'Courier' +%Xlabelfontsize -fontsize for xticklabel e.g., 12 +%Xlabelcolor -color (RGB) for xticklabels e.g., [0 0 0] +%MinorTicksX - Minor Ticks for x axes +%Xunits -display units for x axes. "on" or "off" +%YScales - y scales e.g., [-6 10] +%Yticks - y ticks e.g., [-6 -3 0 5 10] +%Yticklabel -display yticklabels? 1 is on and 0 is off. +%Ylabelfont -font for yticklabels e.g., 'Courier' +%Ylabelfontsize -fontsize for yticklabels +%Ylabelcolor -color (RGB) for yticks and yticklabels e.g., [0 0 0] +%Yunits -display units for x axes. "on" or "off" +%MinorTicksY - +%LegtextColor -Text color of legend names. 1 is black (default); 0 is +% the same as the color of lines +%Legcolumns -Number of columns for legend names. e.g., 1 or 2,.... +%FigureName -Figure name, e.g., "My Viewer" +%FigbgColor -Background color of figure. The default is [1 1 1] +%Labelcolor -Channel/Bin/ERPset label color in RGB, e.g., [0 0 0] +%Ytickdecimal -determine the number of decimals of y tick labels +% - e.g., -6.0 -3.0 0.0 3.0 6.0 if Ytickdecimal is 1 +%Xtickdecimal -determine the nunmber of decimals of x tick labels +% -e.g., -0.2 0.0 0.2 0.4 0.6 0.8 if Xtickdecimal is 1 +%XtickdisFlag -the way is to display xticks: 1 is in millisecond, 0 is in second + + + +% *** This function is part of ERPLAB Studio *** +% Author: Guanghui Zhang & Steven Luck +% ghzhang@ucdavis.edu, sjluck@ucdavis.edu +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 & 2023 + + +function [ALLERP, erpcom] = pop_plotERPwaviewer(ALLERP,CURRENTPLOT,ERPsetArray,binArray,chanArray,varargin) +% +erpcom = ''; +if nargin < 1 + help pop_plotERPwaviewer + return; +end + +if nargin==1 %with GUI to get other parameters + if isempty(ALLERP) + msgboxText = 'No ALLERP was found!'; + title_msg = 'EStudio: pop_plotERPwaviewer() error:'; + errorfound(msgboxText, title_msg); + return; + end + + CURRENTPLOT = length(ALLERP); + ERP = ALLERP(CURRENTPLOT); + PLOTORG = [1 2 3]; %% "Channels" will be Grid; "Bins" will be Overlay; "ERPsets" will be + if ~iserpstruct(ERP) + msgboxText = 'Invalid ERP structure!'; + title_msg = 'EStudio: pop_plotERPwaviewer() error:'; + errorfound(msgboxText, title_msg); + return + end + if isempty(ERP.bindata) %(ERP.bindata) + msgboxText = 'Cannot plot an empty ERP dataset'; + title_msg = 'EStudio: pop_plotERPwaviewer() error:'; + errorfound(msgboxText, title_msg); + return + end + binArray = 1:ERP.nbin; + chanArray = 1:ERP.nchan;%%Index of channels which will plot + ERPsetArray = [1:length(ALLERP)]; + [chanStr,binStr] = f_geterpschanbin(ALLERP,ERPsetArray); + + if PLOTORG(1) ==1 %% if the selected Channel is "Grid" + plotArray = chanArray; + for Numofchan = 1:numel(chanArray) + try + LabelsName{Numofchan} = chanStr{plotArray(Numofchan)}; + catch + end + end + elseif PLOTORG(1) == 2 %% if the selected Bin is "Grid" + plotArray = binArray; + for Numofbin = 1:numel(plotArray) + try + LabelsName{Numofbin} = binStr{plotArray(Numofbin)}; + catch + end + end + elseif PLOTORG(1) == 3%% if the selected ERPset is "Grid" + plotArray = ERPsetArray; + for Numoferp = 1:numel(plotArray) + try + LabelsName{Numoferp} = ALLERP(plotArray(Numoferp)).erpname; + catch + LabelsName{Numoferp} = 'no'; + end + end + end + plotBox = f_getrow_columnautowaveplot(plotArray); + + count = 0; + for Numofrow = 1:plotBox(1) %%organization of Grid + for Numofcolumn = 1:plotBox(2) + count = count +1; + if count> numel(plotArray) + GridposArray(Numofrow,Numofcolumn) =0; + else + GridposArray(Numofrow,Numofcolumn) = plotArray(count); + end + end + end + if PLOTORG(2) ==1 %% if the selected Channel is "Grid" + OverlayArray = chanArray; + for Numofchan = 1:numel(chanArray) + LegendName{NUmofchan,1} =char(chanStr(chanArray(Numofchan))); + end + elseif PLOTORG(2) == 2 %% if the selected Bin is "Grid" + OverlayArray = binArray; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + elseif PLOTORG(2) == 3%% if the selected ERPset is "Grid" + OverlayArray = ERPsetArray; + for Numoferpset = 1:numel(ERPsetArray) + try + LegendName{Numoferpset} = ALLERPIN(ERPsetArray(Numoferpset)).erpname; + catch + LegendName{Numoferpset} = ''; + end + end + else + OverlayArray = binArray; + for Numofbin = 1:numel(binArray) + LegendName{Numofbin,1} = char(binStr(binArray(Numofbin))); + end + end + [lineNameStr,linecolors,linetypes,linewidths] = f_get_lineset_ERPviewer(numel(OverlayArray)); + lineset_str =table(lineNameStr,linecolors,linetypes,linewidths); + LineData = table2cell(lineset_str); + lineStylrstr = {'solid','dash','dot','dashdot','plus','circle','asterisk'}; + linecolorsstr = {'black','red','blue','green','orange','cyan','magenla'}; + LineColorspec = zeros(numel(OverlayArray),3); %% + LineStylespec = cell(1,numel(OverlayArray)); + LineMarkerspec = cell(1,numel(OverlayArray)); + LineWidthspec = ones(1,numel(OverlayArray)); + + for Numofplot = 1: numel(OverlayArray) %%using RGB or r,g,b,o? + %%determine the specific RGB value for the defined color + CellColor = LineData{Numofplot,2}; + [C_color,IA_color] = ismember_bc2(CellColor,linecolorsstr); + if C_color==1 + switch IA_color%% {'black','red','blue','green','orange','cyan','magenla'}; + case 1 + LineColorspec(Numofplot,:) = [0 0 0];%% black + case 2 + LineColorspec(Numofplot,:) = [1 0 0];%% red + case 3 + LineColorspec(Numofplot,:) = [0 0 1];%% blue + case 4 + LineColorspec(Numofplot,:) = [0 1 0];%%green + case 5 + LineColorspec(Numofplot,:) = [0.9290 0.6940 0.1250];%%orange + case 6 + LineColorspec(Numofplot,:) = [0 1 1];%%cyan + case 7 + LineColorspec(Numofplot,:) = [1 0 1];%%magenla + otherwise + LineColorspec(Numofplot,:) = [0 0 0];%%black + end + else + LineColorspec{Numofplot,1} = [0 0 0]; + end + %%Line style + CellStyle = LineData{Numofplot,3}; + [C_style,IA_style] = ismember_bc2(CellStyle,lineStylrstr); + if C_style==1 + switch IA_style %{'solid','dash','dot','dashdot','plus','circle','asterisk'}; + case 1 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = '-'; + case 2 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = '--'; + case 3 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = ':'; + case 4 + LineMarkerspec{1,Numofplot} = 'none'; + LineStylespec{1,Numofplot} = '-.'; + case 5 + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = '+'; + case 6 + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = 'o'; + case 7 + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = '*'; + otherwise + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = 'none'; + end + else + LineStylespec{1,Numofplot} = '-'; + LineMarkerspec{1,Numofplot} = 'none'; + end%% end of line style + %%line width + try + LineWidthspec(1,Numofplot) = LineData{Numofplot,4}; + catch + LineWidthspec(1,Numofplot) =1; + end%% end for setting of line width + end%% end of loop for number of line + + %%Font and fontsize for legend + FontLeg = 'Geneva'; + FontSizeLeg = 10; + + %%Setting for Channel/Bin/ERP label + CBELabels = [];%location 0 70 1 + CBEFont = 'Geneva';%%font + CBEFontsize=10;%% fontsize + + %%Polarity of wave + PolarityWave =1;%%1.positive up; 0. negative up + + %%standard error + Standerr = 0;%% + + %%Transparency + Transparency = 0;%1. show Transparency; 0. donot show Transparency + + %%Grid space for rows and columns + GridSpace = [1 20;1 20]; + + %%Baseline correction + Blc = 'none'; + + %%---------------------X axis------------------------------------------ + timeRange(1) = ERP.times(1); + timeRange(2) = ERP.times(end); + timeticks = str2num(char(default_time_ticks_studio(ERP, timeRange))); + xticklabel = 'on'; + xlabelFont = 'Geneva'; + xlabelFontsize = 10; + xlabelFontcolor = [0 0 0]; + Xunits = 'on'; + MinorticksX = [0];%% off + + %%---------------------Y axis------------------------------------------ + [Yscales, serror] = erpAutoYLim(ERP); + try + Yticks = str2num(char(default_amp_ticks_viewer(Yscales))); + catch + Yticks = []; + end + yticklabel = 'on'; + YlabelFont = 'Geneva'; + YlabelFontsize = 10; + ylabelFontcolor = [0 0 0]; + yunits = 'on'; + MinorticksY = [0]; + FigureName = 'My Viewer'; + + TextcolorLeg = 1;%% 1. using black color for legend text color; 0. use the same color as lines for legend text + Legcolumns = 1;%%Number of columns for legend name + + figbgdColor = [1 1 1]; + + Labelcolor = [0 0 0]; + + Ytickprecision = 1; + Xtickprecision = 1; + XdisFlag = 1; + Parameterfile = ''; + + [ALLERP, erpcom] = pop_plotERPwaviewer(ALLERP,CURRENTPLOT,ERPsetArray,binArray, chanArray,'PLOTORG',PLOTORG,'GridposArray',GridposArray,'LabelsName',LabelsName, 'Blc', Blc,'Box',plotBox,'LineColor',LineColorspec,'LineStyle',LineStylespec,... + 'LineMarker',LineMarkerspec,'LineWidth',LineWidthspec,'LegendName',LegendName,'LegendFont',FontLeg,'LegendFontsize',FontSizeLeg,... + 'Labeloc',CBELabels,'Labelfont',CBEFont,'Labelfontsize',CBEFontsize,'YDir',PolarityWave,'SEM',Standerr,'Transparency', Transparency,... + 'GridSpace',GridSpace,'TimeRange',timeRange,'Xticks',timeticks,'Xticklabel',xticklabel,'Xlabelfont',xlabelFont,'Xlabelfontsize',xlabelFontsize,... + 'Xlabelcolor',xlabelFontcolor,'Xunits',Xunits,'MinorTicksX',MinorticksX,... + 'YScales',Yscales,'Yticks',Yticks,'Yticklabel',yticklabel,'Ylabelfont',YlabelFont,'Ylabelfontsize',YlabelFontsize,... + 'Ylabelcolor',ylabelFontcolor,'Yunits',yunits,'MinorTicksY',MinorticksY,'LegtextColor',TextcolorLeg,'Legcolumns',Legcolumns,'FigureName',FigureName,... + 'FigbgColor',figbgdColor,'Labelcolor',Labelcolor,'Ytickdecimal',Ytickprecision,'Xtickdecimal',Xtickprecision,'XtickdisFlag',XdisFlag,'Parameterfile',Parameterfile,'History', 'gui'); + + pause(0.1); + return; +end + +% +% Parsing inputs +% +% colordef = getcolorcellerps; %{'k' 'r' 'b' 'g' 'c' 'm' 'y' 'w'};% default colors +p = inputParser; +p.FunctionName = mfilename; +p.CaseSensitive = false; +p.addRequired('ALLERP'); +p.addRequired('CURRENTPLOT', @isnumeric); +p.addRequired('ERPsetArray', @isnumeric);%%Indices of the selected channels +p.addRequired('binArray', @isnumeric);%%Indices of the selected channels +p.addRequired('chanArray', @isnumeric);%%Indices of the selected bins + + + + +%Option(s) +p.addParamValue('PLOTORG',[],@isnumeric);%%contains three elements: the first one is "Grid", the second one is "Overlay", and the last one is "Pages" +p.addParamValue('GridposArray',[], @isnumeric);%%Vector or matrix contains the indices of the selected channels/bins/erpsets for each subplot +p.addParamValue('LabelsName','', @iscell); + +p.addParamValue('Blc', ''); +p.addParamValue('Box', [], @isnumeric); +p.addParamValue('LineColor', [], @isnumeric); +p.addParamValue('LineStyle', '', @iscell); +p.addParamValue('LineMarker', '',@iscell); +p.addParamValue('LineWidth', [], @isnumeric); +p.addParamValue('LegendName', '', @iscell); +p.addParamValue('LegendFont', '', @ischar); +p.addParamValue('LegendFontsize', [], @isnumeric); +p.addParamValue('Labeloc', [], @isnumeric); +p.addParamValue('Labelfont', '', @ischar); +p.addParamValue('Labelfontsize', [],@isnumeric); +p.addParamValue('YDir', [], @isnumeric);%% wave polarity +p.addParamValue('SEM', [], @isnumeric);%% standard error of mean +p.addParamValue('Transparency',[], @isnumeric); +p.addParamValue('GridSpace', [], @isnumeric); +%%----------X axis------------------------ +p.addParamValue('TimeRange', [], @isnumeric); %% time window for x axis +p.addParamValue('Xticks', '', @isnumeric); +p.addParamValue('Xticklabel', '', @ischar); +p.addParamValue('Xlabelfont','',@ischar); +p.addParamValue('Xlabelfontsize', [], @isnumeric);%% +p.addParamValue('Xlabelcolor', [], @isnumeric);%% +p.addParamValue('Xunits', '', @ischar); +p.addParamValue('MinorTicksX', [], @isnumeric);%% donot display minor xticks +%%-------setting for Y axis--------------- +p.addParamValue('YScales', [], @isnumeric); %% y scales for y axis +p.addParamValue('Yticks', '', @isnumeric); +p.addParamValue('Yticklabel', '', @ischar); +p.addParamValue('Ylabelfont','',@ischar); +p.addParamValue('Ylabelfontsize', [], @isnumeric);%% +p.addParamValue('Ylabelcolor', [], @isnumeric);%% +p.addParamValue('Yunits', '', @ischar); +p.addParamValue('MinorTicksY', [], @isnumeric);%% +p.addParamValue('LegtextColor', [], @isnumeric);%% +p.addParamValue('Legcolumns', [], @isnumeric);%% +p.addParamValue('FigureName', '', @ischar);%% + +p.addParamValue('FigbgColor', [], @isnumeric);%% +p.addParamValue('Labelcolor', [], @isnumeric);%% +p.addParamValue('Ytickdecimal', [], @isnumeric); +p.addParamValue('Xtickdecimal', [], @isnumeric); +p.addParamValue('XtickdisFlag', [], @isnumeric); +p.addParamValue('Parameterfile', '', @ischar); + +p.addParamValue('ErrorMsg', '', @ischar); +p.addParamValue('History', '', @ischar); % history from scripting + + + +p.parse(ALLERP,CURRENTPLOT,ERPsetArray,binArray,chanArray,varargin{:}); + +qParameterfile = p.Results.Parameterfile; +p_Results = p.Results; + +parse_paramout = ''; +if ~isempty(qParameterfile) + + if isempty(p_Results.ALLERP) && isempty(qParameterfile.ALLERP) + beep; + fprintf(2,'pop_plotERPwaviewer:No ALLERP is in Parameterfile and imported ALLERP is empty'); + return; + end + + if ~isempty(p_Results.ALLERP) && isempty(qParameterfile.ALLERP) + qParameterfile.ALLERP = p_Results.ALLERP; + CURRENTERP = qParameterfile.CURRENTERP; + if isempty(CURRENTERP)|| CURRENTERP<=0 || CURRENTERP>length(p_Results.ALLERP) + CURRENTERP = length(p_Results.ALLERP); + end + qParameterfile.CURRENTERP = CURRENTERP; + qParameterfile.ERP = qParameterfile.ALLERP(CURRENTERP); + end + + if ~isempty(p_Results.ALLERP) && ~isempty(qParameterfile.ALLERP) + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Select one of them?\n 1. Use imported ALLERP. \n 2. Use ALLERP in Parameterfile.']; + title = 'pop_plotERPwaviewer'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','1', '2','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + + if strcmpi(button,'1') || strcmpi(button,'2') + if strcmpi(button,'1') + qParameterfile.ALLERP = p_Results.ALLERP; + CURRENTERP = qParameterfile.CURRENTERP; + if isempty(CURRENTERP)|| CURRENTERP<=0 || CURRENTERP>length(p_Results.ALLERP) + CURRENTERP = length(p_Results.ALLERP); + end + qParameterfile.CURRENTERP = CURRENTERP; + qParameterfile.ERP = qParameterfile.ALLERP(CURRENTERP); + end + else + beep; + fprintf(2,'pop_plotERPwaviewer: User selected cancel.'); + return; + end + end + [parse_paramout, ErroMessg] = f_erpwave_viewer_update_parameter(qParameterfile,p); + if ~isempty(parse_paramout) + ERPLAB_ERP_Viewer(parse_paramout.ALLERP,parse_paramout.SelectERPIdx,parse_paramout.bin,parse_paramout.chan,parse_paramout) + end + return; +end + +if strcmpi(p_Results.History,'implicit') + shist = 3; % implicit +elseif strcmpi(p_Results.History,'script') + shist = 2; % script +elseif strcmpi(p_Results.History,'gui') + shist = 1; % gui +else + shist = 0; % off +end + +if strcmpi(p_Results.ErrorMsg,'popup') + errormsgtype = 1; % open popup window +else + errormsgtype = 0; % error in red at command window +end + +% +%%check ALLERP +if isempty(ALLERP) + msgboxText = 'No ALLERP was found!'; + title_msg = 'EStudio: pop_plotERPwaviewer() error:'; + errorfound(msgboxText, title_msg); + return; +end + + +qPLOTORG = p_Results.PLOTORG;%%Plot organization +if isempty(qPLOTORG) || numel(qPLOTORG)~=3 || numel(unique(qPLOTORG)) ~=3 || min(qPLOTORG)<0 || max(qPLOTORG)>3 + qPLOTORG = [1 2 3]; +end + + +qERPsetArray = p_Results.ERPsetArray; +if isempty(qERPsetArray) + qERPsetArray = [1:length(ALLERP)]; +end + +if (qPLOTORG(1)==1 && qPLOTORG(2)==2) || (qPLOTORG(1)==2 && qPLOTORG(2)==1) +else + chkerp = f_checkerpsets(ALLERP,qERPsetArray); + if chkerp(3) ==3 + msgboxText = 'Type of data across ERPsets is different!'; + title_msg = 'EStudio: pop_plotERPwaviewer() error:'; + errorfound(msgboxText, title_msg); + return; + end + if chkerp(7) ==7 + msgboxText = 'Sampling rate varies across ERPsets!'; + title_msg = 'EStudio: pop_plotERPwaviewer() error:'; + errorfound(msgboxText, title_msg); + return; + end +end + + +qbinArray = p_Results.binArray; +qchanArray = p_Results.chanArray; +qCURRENTPLOT = p_Results.CURRENTPLOT; +qGridposArray = p_Results.GridposArray; +qLabelsName = p_Results.LabelsName; +if numel(qCURRENTPLOT)~=1 || isempty(qCURRENTPLOT) + qCURRENTPLOT = length(ALLERP); +end + +% qERPArray = [1:length(ALLERP)]; +[chanStrdef,binStrdef] = f_geterpschanbin(ALLERP,qERPsetArray);%%get the bin strings and channel strings across the selected ERPsets +[ERPdatadef,legendNamedef,ERPerrordatadef,timeRangedef] = f_geterpdata(ALLERP,qERPsetArray,qPLOTORG,CURRENTPLOT); + +if min(qbinArray)<0 || min(qbinArray)==0 + msgboxText = ['Invalid bin indexing.\n'... + 'Bin index(ices) must be positive integer(s).']; + if errormsgtype + title_msg = 'EStudio: pop_plotERPwaviewer() invalid bin index'; + errorfound(sprintf(msgboxText), title_msg); + return + else + beep; + error('prog:input', ['EStudio says: ' msgboxText]); + end +end + +if min(qchanArray)<0 || min(qchanArray)==0 + msgboxText = ['Invalid channel indexing.\n'... + 'Channel index(ices) must be positive integer(s).']; + if errormsgtype + title_msg = 'EStudio: pop_plotERPwaviewer() invalid channel index'; + errorfound(sprintf(msgboxText), title_msg); + return + else + beep; + error('prog:input', ['EStudio says: ' msgboxText]); + end +end + + +Existbin = f_existvector([1:length(binStrdef)],qbinArray); +if isempty(qbinArray) || Existbin==1 + qbinArray = [1:length(binStrdef)]; + Existbin = 1; +end + +Existchan = f_existvector([1:length(chanStrdef)],qchanArray); +if isempty(qchanArray) || Existchan==1 + qchanArray = [1:length(chanStrdef)]; + Existchan =1; +end + +%%check the numbers of rows and columns +if qPLOTORG(1) ==1 %% if the selected Channel is "Grid" + plotArray = qchanArray; + for Numofchan = 1:numel(chanArray) + try + LabelsNamedef{Numofchan} = chanStrdef{plotArray(Numofchan)}; + catch + LabelsNamedef{Numofchan} = 'none'; + end + end +elseif qPLOTORG(1) == 2 %% if the selected Bin is "Grid" + plotArray = qbinArray; + for Numofbin = 1:numel(plotArray) + try + LabelsNamedef{Numofbin} = binStrdef{plotArray(Numofbin)}; + catch + LabelsNamedef{Numofbin} = 'none'; + end + end +elseif qPLOTORG(1) == 3%% if the selected ERPset is "Grid" + plotArray = qERPsetArray; + for Numoferp = 1:numel(plotArray) + try + LabelsNamedef{Numoferp} = ALLERP(plotArray(Numoferp)).erpname; + catch + LabelsNamedef{Numoferp} = 'none'; + end + end +else + plotArray = qchanArray; + for Numofchan = 1:numel(chanArray) + try + LabelsNamedef{Numofchan} = chanStrdef{plotArray(Numofchan)}; + catch + LabelsNamedef{Numofchan} = 'none'; + end + end +end + +if isempty(qLabelsName) + qLabelsName =LabelsNamedef; +end + +plotBoxdef = f_getrow_columnautowaveplot(plotArray); +qplotBox = p_Results.Box; + +if isempty(qplotBox) || numel(unique(qplotBox))>2 || min(qplotBox) <1 || numel(qplotBox)~=2 + qplotBox = plotBoxdef; +end + + +NumRows = ceil(qplotBox(1)); +NumColumns = ceil(qplotBox(2)); +count = 0; +for Numofrow = 1:NumRows %%organization of Grid + for Numofcolumn = 1:NumColumns + count = count +1; + if count> numel(plotArray) + GridposArraydef(Numofrow,Numofcolumn) =0; + else + GridposArraydef(Numofrow,Numofcolumn) = plotArray(count); + end + end +end +if isempty(qGridposArray) + qGridposArray = GridposArraydef; +end + +%%check elements in qGridposArray +for Numofrows = 1:size(qGridposArray,1) + for Numofcolumns = 1:size(qGridposArray,2) + SingleGridpos = qGridposArray(Numofrows,Numofcolumns); + if SingleGridpos~=0 + ExistGridops = f_existvector(plotArray,SingleGridpos); + if ExistGridops==1 + qGridposArray(Numofrows,Numofcolumns) =0; + end + end + end +end + +%%-------Baseline correction----------- +qBlc = p_Results.Blc; +if isempty(qBlc) + qBlc = 'none'; +end +if length(qBlc) ==2 + if ~isnumeric(qBlc) %% if the input of baseline correction is string; + qBlc = 'none'; + end +end +if length(qBlc) ==2 && isnumeric(qBlc) + if min(timeRangedef)> min(qBlc) || max(timeRangedef)< max(qBlc) || qBlc(1) == qBlc(2) + qBlc = 'none'; + end + if qBlc(1)> qBlc(2) + qBlc = fliplr(qBlc); + end +end + +%%check the line color +qLineColorspec = p_Results.LineColor; +if qPLOTORG(2) ==1 %% if the selected Channel is "Grid" + OverlayArray = qchanArray; + for Numofchan = 1:numel(qchanArray) + LegendNamedef{Numofchan,1} =char(chanStrdef(qchanArray(Numofchan))); + end +elseif qPLOTORG(2) == 2 %% if the selected Bin is "Grid" + OverlayArray = qbinArray; + for Numofbin = 1:numel(qbinArray) + LegendNamedef{Numofbin,1} = char(binStrdef(qbinArray(Numofbin))); + end +elseif qPLOTORG(2) == 3%% if the selected ERPset is "Grid" + OverlayArray = qERPsetArray; + for Numoferpset = 1:numel(qERPsetArray) + try + LegendNamedef{Numoferpset} = ALLERPIN(qERPsetArray(Numoferpset)).erpname; + catch + LegendNamedef{Numoferpset} = ''; + end + end +else + OverlayArray = qbinArray; + for Numofbin = 1:numel(qbinArray) + LegendNamedef{Numofbin,1} = char(binStr(qbinArray(Numofbin))); + end +end + +LineColordef = [0 0 0;1 0 0;0 0 1;0 1 0;0.9290 0.6940 0.1250;0 1 1;1 0 1]; +LineMarkerdef = {'none','none','none','none','+','o','*'}; +LineStyledef = {'-','--',':','-.','-','-','-',}; +if isempty(qLineColorspec) + for Numofcolor = 1:numel(OverlayArray) + Numindex = 7*floor(Numofcolor/7); + if Numindex==0 + try + qLineColorspec(Numofcolor,:) = LineColordef(Numofcolor,:); + catch + qLineColorspec(Numofcolor,:) = [0 0 0]; + end + elseif Numindex~=0 + try + qLineColorspec(Numofcolor,:) = LineColordef(Numofcolor-Numindex,:); + catch + qLineColorspec(Numofcolor,:) = [0 0 0]; + end + else + try + qLineColorspec(Numofcolor,:) = LineColordef(Numofcolor,:); + catch + qLineColorspec(Numofcolor,:) = [0 0 0]; + end + end + end +end + +%%check line styles +qLineStylespec = p_Results.LineStyle; +if isempty(qLineStylespec) + for Numofcolor = 1:numel(OverlayArray) + NumIndex = ceil(Numofcolor/7); + try + qLineStylespec{1,Numofcolor} = LineStyledef{NumIndex}; + catch + qLineStylespec{1,Numofcolor} = '-'; + end + end +end +%%check line marker +qLineMarkerspec = p_Results.LineMarker; +if isempty(qLineMarkerspec) + for Numofcolor = 1:numel(OverlayArray) + NumIndex = ceil(Numofcolor/7); + try + qLineMarkerspec{1,Numofcolor} = LineMarkerdef{NumIndex}; + catch + qLineMarkerspec{1,Numofcolor} = 'none'; + end + end +end + +%%check line width +qLineWidthspec = p_Results.LineWidth; +if isempty(qLineWidthspec) + for Numofcolor = 1:numel(OverlayArray) + qLineWidthspec(1,Numofcolor) =1; + end +end + +%%legend name +qLegendName = p_Results.LegendName; +if isempty(qLegendName) + qLegendName = LegendNamedef; +end + +%%Legend font +qFontLeg = p_Results.LegendFont; +if isempty(qFontLeg) + qFontLeg = 'Geneva'; +end + +%%legend fontsize +qFontSizeLeg = p_Results.LegendFontsize; +if isempty(qFontSizeLeg) + qFontSizeLeg = 10; +end + +%%Channel/bin/ERPset Label +qCBELabels = p_Results.Labeloc; +if ~isempty(qCBELabels) + if numel(qCBELabels)~=3 + qCBELabels = [0 70 1]; + end + if qCBELabels(1) >100 || qCBELabels(1)<-100 + qCBELabels(1) = 0; + end + if qCBELabels(3) ~=1 && qCBELabels(3)~=0 + qCBELabels(3) = 1; + end +end + +qCBEFont = p_Results.Labelfont; +if isempty(qCBEFont) + qCBEFont ='Geneva'; +end + +qCBEFontsize = p_Results.Labelfontsize; +if isempty(qCBEFontsize) + qCBEFontsize =10; +end + +qPolarityWave = p_Results.YDir; +if isempty(qPolarityWave) || numel(qPolarityWave)~=1 || (qPolarityWave~=1 && qPolarityWave~=0) + qPolarityWave = 1; +end + +%%-----------------------standard error of mean---------------------------- +if isempty(p_Results.SEM) + qStanderr = 0; +end +if numel(p_Results.SEM)~=1 + qStanderr = 0; +elseif p_Results.SEM<0 + qStanderr = 0; +else + qStanderr = ceil(p_Results.SEM); +end + +%%Transparency +TransparencyLabel = p_Results.Transparency; +if isempty(TransparencyLabel) + qTransparency = 0; +else + qTransparency = TransparencyLabel; +end + +%%grid space between rows/or columns +qGridspace = p_Results.GridSpace; +if isempty(qGridspace) || numel(qGridspace)~=4 || (size(qGridspace,1)~=2 || size(qGridspace,2)~=2) + qGridspace =[1 100; 1 20]; +else + [rowgs,columgs] = size(qGridspace); + if rowgs~=2 || columgs~=2 + qGridspace =[1 100; 1 20]; + else + if qGridspace(1,1)~=1 && qGridspace(1,1)~=2 + qGridspace(1,1) =1; + end + if (qGridspace(1,1)==1 && qGridspace(1,2)<=0) + qGridspace(1,2) =100; + elseif (qGridspace(1,1)==2 && (qGridspace(1,2)<=0|| qGridspace(1,2)>100)) + qGridspace(1,2) =100; + end + if qGridspace(2,1)~=1 && qGridspace(2,1)~=2 + qGridspace(2,1) =1; + end + if (qGridspace(2,1)==1 && qGridspace(2,2)<=0) + qGridspace(2,2) =20; + elseif (qGridspace(2,1)==2 && (qGridspace(2,2)<=0|| qGridspace(2,2)>=100)) + qGridspace(2,2) =20; + end + end +end + +%%--------X axis-------------------- +try + ERPIN = ALLERP(CURRENTPLOT); +catch + ERPIN = ALLERP(end); +end +qtimeRange =unique(p_Results.TimeRange); +if isempty(qtimeRange) || numel(qtimeRange)==1 + qtimeRange(1) = timeRangedef(1); + qtimeRange(2) = timeRangedef(end); +end +if qtimeRange(1)> qtimeRange(2) + qtimeRange = fliplr(qtimeRange); +end + +%%xticks +try + [timeticksdef stepX]= default_time_ticks_studio(ERPIN, qtimeRange); + timeticksdef = str2num(char(timeticksdef)); +catch + timeticksdef = []; +end +qXticks = unique(p_Results.Xticks); +if isempty(qXticks) + qXticks =timeticksdef; +end +%%check if each element of xticks exceeds the time range. If so, the +%%corresponding element will be empty +if ~isempty(qtimeRange) && ~isempty(qXticks) %%check xticks + try + count =0; + XtickDis =[]; + for Numofxtick = 1:numel(qXticks) + if qXticks(Numofxtick) < qtimeRange(1) || qXticks(Numofxtick) > qtimeRange(end) + count = count+1; + XtickDis(count) = Numofxtick; + end + end + qXticks(XtickDis) = []; + catch + end +end + +qxticklabel = p_Results.Xticklabel; +if isempty(qxticklabel) + qxticklabel = 'on'; +end + +qXlabelfont = p_Results.Xlabelfont; +if isempty(qXlabelfont) + qXlabelfont = 'Geneva'; +end +qXlabelfontsize = p_Results.Xlabelfontsize; +if isempty(qXlabelfontsize) + qXlabelfontsize =10; +end + +qXlabelcolor = p_Results.Xlabelcolor; +if isempty(qXlabelcolor) + qXlabelcolor = [0 0 0]; +end +if isempty(qXlabelcolor) + qXlabelcolor = [0 0 0]; +end + + +qXunits = p_Results.Xunits; +if isempty(qXunits) + qXunits = 'on'; +end + +qMinorticksX = p_Results.MinorTicksX; +if isempty(qMinorticksX) + qMinorticksX = 0; +end + + +qxtickprecision = p_Results.Xtickdecimal; +if isempty(qxtickprecision)|| qxtickprecision<0 + qxtickprecision =0; +end +qxtickprecision = ceil(qxtickprecision); + +qxdisFlag= p_Results.XtickdisFlag; +if isempty(qxdisFlag)|| (qxdisFlag~=1 && qxdisFlag~=0) + qxdisFlag =1; +end + + +%%----------------------Y axis--------------------------------------------- +datresh = squeeze(ERPdatadef(qchanArray,:,qbinArray,:)); +yymax = max(datresh(:)); +yymin = min(datresh(:)); +if abs(yymax)<1 && abs(yymin)<1 + scalesdef(1:2) = [yymin*1.2 yymax*1.1]; % JLC. Mar 11, 2015 +else + scalesdef(1:2) = [floor(yymin*1.2) ceil(yymax*1.1)]; % JLC. Sept 26, 2012 +end + + +yylim_out = f_erpAutoYLim(ALLERP, qERPsetArray,qPLOTORG,qbinArray, qchanArray); +try + Yscalesdef = yylim_out(qCURRENTPLOT,:); +catch + Yscalesdef = scalesdef; +end +qYscales = p_Results.YScales; +if isempty(qYscales) + qYscales = Yscalesdef; +end +qYticks=p_Results.Yticks; +if isempty(qYticks) && ~isempty(qYticks) %%check Yticks + qYticks = default_amp_ticks_viewer(qYscales); +end +if ~isempty(qYscales) && ~isempty(qYticks) %%check Yticks + try + count =0; + ytickDis =[]; + for Numofytick = 1:numel(qYticks) + if qYticks(Numofytick) < qYscales(1) || qYticks(Numofytick) > qYscales(end) + count = count+1; + ytickDis(count) = Numofytick; + end + end + qYticks(ytickDis) = []; + catch + end +end + +qYticklabel = p_Results.Yticklabel; +if isempty(qYticklabel) + qYticklabel = 'on'; +end + +qYlabelfont = p_Results.Ylabelfont; + +if isempty(qYlabelfont) + qYlabelfont = 'Geneva'; +end + +qYlabelfontsize = p_Results.Ylabelfontsize; +if isempty(qYlabelfontsize) + qYlabelfontsize=10; +end + + +qYlabelcolor = p_Results.Ylabelcolor; +if isempty(qYlabelcolor) + qYlabelcolor = [0 0 0]; +end +if isempty(qYlabelcolor) + qYlabelcolor = [0 0 0]; +end + +qYunits = p_Results.Yunits; +if isempty(qYunits) + qYunits = 'on'; +end + + +qMinorTicksY = p_Results.MinorTicksY; +if isempty(qMinorTicksY) + qMinorTicksY = 0; +end + +qlegcolor = p_Results.LegtextColor;%% +if isempty(qlegcolor) || qlegcolor<0 || numel(qlegcolor)~=1 || (qlegcolor~=0 && qlegcolor~=1) + qlegcolor = 1; +end + +qlegcolumns= p_Results.Legcolumns;%% +if isempty(qlegcolumns) || qlegcolumns<0 || numel(qlegcolumns)~=1 + qlegcolumns =1; +end + + +try + qFigureName = p_Results.FigureName;%% +catch + qFigureName = ''; +end + + +qFigbgColor = p_Results.FigbgColor;%% Figure background color +if isempty(qFigbgColor) || numel(qFigbgColor)~=3 || max(qFigbgColor)>1 || min(qFigbgColor)<0 + qFigbgColor = [1 1 1]; +end + +qLabelcolor = p_Results.Labelcolor;%%label text color +if isempty(qLabelcolor) || size(qLabelcolor,2)~=3 || max(qLabelcolor)>1 || min(qLabelcolor)<0 + qLabelcolor = [0 0 0]; +end + +qYtickdecimal = p_Results.Ytickdecimal; +if isempty(qYtickdecimal) || numel(qYtickdecimal)~=1 || qYtickdecimal<0 + qYtickdecimal =1; +end +if isempty(qFigureName) + qFigureName = 'My Viewer'; +end +if isempty(qLabelsName) + qCBELabels = []; +end +% +%%-------------Plot the ERP wave based on the above parameters------------- +if ~isempty(qFigureName) + f_ploterpserpviewer(ALLERP,qCURRENTPLOT, qPLOTORG,qbinArray,qchanArray,qGridposArray,qplotBox,qBlc,qLineColorspec,qLineStylespec,qLineMarkerspec,qLineWidthspec,... + qLegendName,qFontLeg,qFontSizeLeg,qCBELabels,qCBEFont,qCBEFontsize,qPolarityWave,qStanderr,qTransparency,qGridspace,qtimeRange,qXticks,qxticklabel,... + qXlabelfont,qXlabelfontsize,qXlabelcolor,qMinorticksX,qXunits,qYscales,qYticks,qYticklabel,qYlabelfont,qYlabelfontsize,qYlabelcolor,qYunits,qMinorTicksY,... + qLabelsName,qERPsetArray,qlegcolor,qlegcolumns,qFigureName,qFigbgColor,qLabelcolor,qYtickdecimal,qxtickprecision,qxdisFlag); +end + + + + +% History command +% + +fn = fieldnames(p.Results); +skipfields = {'ALLERP','CURRENTPLOT','ERPsetArray', 'binArray', 'chanArray'}; + +if qMinorticksX(1) ==0 + skipfields{length(skipfields)+1} = 'MinorTicksX'; +end + +if qMinorTicksY(1) ==0 + skipfields{length(skipfields)+1} = 'MinorTicksY'; +end +if isempty(qCBELabels) + skipfields{length(skipfields)+1} = 'Labeloc'; + skipfields{length(skipfields)+1} = 'Labelcolor'; + skipfields{length(skipfields)+1} = 'Labelfontsize'; + skipfields{length(skipfields)+1} = 'Labelfont'; + skipfields{length(skipfields)+1} = 'LabelsName'; +end + + +BinArraystr = vect2colon(qbinArray, 'Sort','yes'); +chanArraystr = vect2colon(qchanArray); +CURRENTPLOTStr = num2str(CURRENTPLOT); +qERPsetArraystr = vect2colon(qERPsetArray); +% PLOTORGstr = vect2colon(qPLOTORG); +erpcom = sprintf( 'ALLERP = pop_plotERPwaviewer( %s, %s, %s,%s, %s', 'ALLERP',CURRENTPLOTStr, qERPsetArraystr, BinArraystr, chanArraystr); + +for q=1:length(fn) + fn2com = fn{q}; % inputname + if ~ismember_bc2(fn2com, skipfields) + fn2res = p.Results.(fn2com); % input value + if ~isempty(fn2res) + if ischar(fn2res) + if ~strcmpi(fn2res,'off') + erpcom = sprintf( '%s, ''%s'', ''%s''', erpcom, fn2com, fn2res); + end + elseif iscell(fn2res) + nn = length(fn2res); + erpcom = sprintf( '%s, ''%s'', {''%s'' ', erpcom, fn2com, fn2res{1}); + for ff=2:nn + erpcom = sprintf( '%s, ''%s'' ', erpcom, fn2res{ff}); + end + erpcom = sprintf( '%s}', erpcom); + elseif isnumeric(fn2res) + if ~ismember_bc2(fn2com,{'LineColor','GridSpace','GridposArray'}) + erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, vect2colon(fn2res,'Repeat','on')); + else + if size(fn2res,1)==1 + fn2res_trans = char(num2str(fn2res)); + else + fn2res_trans = char(num2str(fn2res(1,:))); + for ii = 2:size(fn2res,1) + fn2res_trans = char(strcat(fn2res_trans,';',num2str(fn2res(ii,:)))); + end + end + fn2res = fn2res_trans; + erpcom = sprintf( '%s, ''%s'', [%s', erpcom,fn2com,fn2res); + erpcom = sprintf( '%s]', erpcom); + end + + else + % if ~ismember_bc2(fn2com,{'xscale','yscale'}) + % erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, vect2colon(fn2res,'Repeat','on')); + % else + % xyscalestr = sprintf('[ %.1f %.1f %s ]', fn2res(1), fn2res(2), vect2colon(fn2res(3:end),'Delimiter','off')); + % erpcom = sprintf( '%s, ''%s'', %s', erpcom, fn2com, xyscalestr); + % end + end + end + end +end +erpcom = sprintf( '%s );', erpcom); +% get history from script. ERP +% shist = 1; +switch shist + case 1 % from GUI + displayEquiComERP(erpcom); + case 2 % from script + for i=1:length(ALLERP) + ALLERP(i) = erphistory(ALLERP(i), [], erpcom, 1); + end + case 3 + % implicit + otherwise %off or none + erpcom = ''; + return +end +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/v_ERPDAT.m b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/v_ERPDAT.m new file mode 100755 index 00000000..4c64e02a --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERP wave viewer/v_ERPDAT.m @@ -0,0 +1,130 @@ +classdef v_ERPDAT < handle + properties + ALLERP + ERP + CURRENTERP + Count_ERP + ERP_chan + ERP_bin + Count_currentERP + count_legend + page_xyaxis + Process_messg + count_loadproper + count_twopanels + Reset_Waviewer_panel + end + + events + ALLERP_change + ERP_change + CURRENTERP_change + Count_ERP_change + ERP_chan_change + ERP_bin_change + v_currentERP_change + legend_change + page_xyaxis_change + v_messg_change + count_loadproper_change + count_twopanels_change + Reset_Waviewer_panel_change + end + + methods + %%m1 + function set.ALLERP(obj,value) + obj.ALLERP = value; + notify(obj,'ALLERP_change'); + end + %%m2 + function set.ERP(obj,value) + obj.ERP = value; + notify(obj,'ERP_change'); + end + + %%m3 + %%Modified CurrentERP + function set.CURRENTERP(obj,value) + obj.CURRENTERP = value; + notify(obj,'CURRENTERP_change'); + end + + %%m4 + %%ERP Plotting panel + function set.Count_ERP(obj,value) + obj.Count_ERP = value; + notify(obj,'Count_ERP_change'); + end + + %%m5 + %Modified channels of the selected ERP + function set.ERP_chan(obj,value) + obj.ERP_chan = value; + notify(obj,'ERP_chan_change'); + end + + %%m6 + %Modified bins of the selected ERP + function set.ERP_bin(obj,value) + obj.ERP_bin = value; + notify(obj,'ERP_bin_change'); + end + + + + %%m7 + %Modified bins of the selected ERP + function set.Count_currentERP(obj,value) + obj.Count_currentERP = value; + notify(obj,'v_currentERP_change'); + end + + %%m8 + %capture the changes of legend + function set.count_legend(obj,value) + obj.count_legend = value; + notify(obj,'legend_change'); + end + + %%m9 + %Modify x/y axis based on the changed pages + function set.page_xyaxis(obj,value) + obj.page_xyaxis = value; + notify(obj,'page_xyaxis_change'); + end + + %%%m10 + %Modified bins of the selected ERP + function set.Process_messg(obj,value) + obj.Process_messg = value; + notify(obj,'v_messg_change'); + end + + + %%%m11 + %Modified bins of the selected ERP + function set.count_loadproper(obj,value) + obj.count_loadproper = value; + notify(obj,'count_loadproper_change'); + end + + + %%%m12 + %Modified bins of the selected ERP + function set.count_twopanels(obj,value) + obj.count_twopanels = value; + notify(obj,'count_twopanels_change'); + end + + + %%%m13 + %Modified bins of the selected ERP + function set.Reset_Waviewer_panel(obj,value) + obj.Reset_Waviewer_panel = value; + notify(obj,'Reset_Waviewer_panel_change'); + end + + end + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ERPLAB_ERP_Tab.m b/studio_functions/Functions/EStudio/ERP Tab/ERPLAB_ERP_Tab.m new file mode 100644 index 00000000..d57dafe7 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ERPLAB_ERP_Tab.m @@ -0,0 +1,148 @@ +%%This function is to create ERP Tab + + +% Author: Guanghui Zhang & Steve J. Luck +% Center for Mind and Brain +% University of California, Davis +% Davis, CA +% 2022 & 2023 + + + +function EStudio_gui_erp_totl = ERPLAB_ERP_Tab(EStudio_gui_erp_totl,ColorB_def) +% global observe_ERPDAT; +% global viewer_ERPDAT; +% global EStudio_gui_erp_totl; + +if isempty(ColorB_def) + ColorB_def = [0.7020 0.77 0.85]; +end + +%% Arrange the main interface for ERP panel (Tab3) +EStudio_gui_erp_totl.ViewBox = uix.VBox('Parent', EStudio_gui_erp_totl.tabERP,'BackgroundColor',ColorB_def); +EStudio_gui_erp_totl.ViewPanel = uix.BoxPanel('Parent', EStudio_gui_erp_totl.ViewBox,'TitleColor',ColorB_def,'ForegroundColor','k');% +EStudio_gui_erp_totl.ViewContainer = uicontainer('Parent', EStudio_gui_erp_totl.ViewPanel); + +EStudio_gui_erp_totl.panelscroll = uix.ScrollingPanel('Parent', EStudio_gui_erp_totl.tabERP); +set(EStudio_gui_erp_totl.panelscroll,'BackgroundColor',ColorB_def); +% + Adjust the main layout +set( EStudio_gui_erp_totl.tabERP, 'Widths', [-4, 300]); % Viewpanel and settings panel + + + + + +EStudio_gui_erp_totl.panel_fonts = f_get_default_fontsize(); + +EStudio_gui_erp_totl.settingLayout = uiextras.VBox('Parent', EStudio_gui_erp_totl.panelscroll,'BackgroundColor',ColorB_def); + +% + Create the settings window panels for ERP panel +EStudio_gui_erp_totl.panel{1} = f_ERP_erpsetsGUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(1) = 280; +EStudio_gui_erp_totl.panel{2} = f_ERP_bin_channel_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(2) = 250; +EStudio_gui_erp_totl.panel{3} = f_ERP_plot_setting_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(3) = 230; + +EStudio_gui_erp_totl.panel{4} = f_ERP_plot_scalp_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(4) = 365; + +EStudio_gui_erp_totl.panel{5} = f_ERP_baselinecorr_detrend_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(5) = 220; +EStudio_gui_erp_totl.panel{6} = f_ERP_filtering_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(6) = 245; + +EStudio_gui_erp_totl.panel{7} = f_ERP_chanoperation_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(7) = 350; + +EStudio_gui_erp_totl.panel{8} = f_ERP_binoperation_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(8) = 310; + +EStudio_gui_erp_totl.panel{9} = f_ERP_CSD_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(9) = 450; + +EStudio_gui_erp_totl.panel{10} = f_ERP_spectral_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(10) = 125; +EStudio_gui_erp_totl.panel{11} = f_ERP_measurement_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(11) = 240; +EStudio_gui_erp_totl.panel{12} = f_ERP_grandaverageGUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(12) = 260; + +EStudio_gui_erp_totl.panel{13} = f_ERP_append_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(13) = 120; + +EStudio_gui_erp_totl.panel{14} = f_ERP_history_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(14) = 250; +EStudio_gui_erp_totl.panel{15} = f_erp_informtion_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(15) = 170; +EStudio_gui_erp_totl.panel{16} = f_erp_dataquality_SME_GUI(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(16) = 160; + +EStudio_gui_erp_totl.panel{17} = f_ERP_simulation_panel(EStudio_gui_erp_totl.settingLayout,EStudio_gui_erp_totl.panel_fonts); +EStudio_gui_erp_totl.panelSizes(17) = 820; + +set(EStudio_gui_erp_totl.settingLayout, 'Heights', EStudio_gui_erp_totl.panelSizes); +EStudio_gui_erp_totl.panelscroll.Heights = sum(EStudio_gui_erp_totl.panelSizes); + +%% Hook up the minimize callback and IsMinimized +set( EStudio_gui_erp_totl.panel{1}, 'MinimizeFcn', {@nMinimize, 1} ); +set( EStudio_gui_erp_totl.panel{2}, 'MinimizeFcn', {@nMinimize, 2} ); +set( EStudio_gui_erp_totl.panel{3}, 'MinimizeFcn', {@nMinimize, 3} ); +set( EStudio_gui_erp_totl.panel{4}, 'MinimizeFcn', {@nMinimize, 4} ); +set( EStudio_gui_erp_totl.panel{5}, 'MinimizeFcn', {@nMinimize, 5} ); +set( EStudio_gui_erp_totl.panel{6}, 'MinimizeFcn', {@nMinimize, 6} ); +set( EStudio_gui_erp_totl.panel{7}, 'MinimizeFcn', {@nMinimize, 7} ); +set( EStudio_gui_erp_totl.panel{8}, 'MinimizeFcn', {@nMinimize, 8} ); +set( EStudio_gui_erp_totl.panel{9}, 'MinimizeFcn', {@nMinimize, 9} ); +set( EStudio_gui_erp_totl.panel{10}, 'MinimizeFcn', {@nMinimize, 10} ); +set( EStudio_gui_erp_totl.panel{11}, 'MinimizeFcn', {@nMinimize, 11} ); +set( EStudio_gui_erp_totl.panel{12}, 'MinimizeFcn', {@nMinimize, 12} ); +set( EStudio_gui_erp_totl.panel{13}, 'MinimizeFcn', {@nMinimize, 13} ); +set( EStudio_gui_erp_totl.panel{14}, 'MinimizeFcn', {@nMinimize, 14} ); +set( EStudio_gui_erp_totl.panel{15}, 'MinimizeFcn', {@nMinimize, 15} ); +set( EStudio_gui_erp_totl.panel{16}, 'MinimizeFcn', {@nMinimize, 16} ); +set( EStudio_gui_erp_totl.panel{17}, 'MinimizeFcn', {@nMinimize, 17} ); +%%shrinking Panels 4-17 to just their title-bar +whichpanel = [4:17]; +for Numofpanel = 1:length(whichpanel) + minned = EStudio_gui_erp_totl.panel{whichpanel(Numofpanel)}.IsMinimized; + szs = get( EStudio_gui_erp_totl.settingLayout, 'Sizes' ); + if minned + set( EStudio_gui_erp_totl.panel{whichpanel(Numofpanel)}, 'IsMinimized', false); + szs(whichpanel(Numofpanel)) = EStudio_gui_erp_totl.panelSizes(whichpanel(Numofpanel)); + else + set( EStudio_gui_erp_totl.panel{whichpanel(Numofpanel)}, 'IsMinimized', true); + szs(whichpanel(Numofpanel)) = 25; + end + set( EStudio_gui_erp_totl.settingLayout, 'Sizes', szs ); + EStudio_gui_erp_totl.panelscroll.Heights = sum(szs); +end %% End for shrinking panels 4-10 + +%% + Create the view +p = EStudio_gui_erp_totl.ViewContainer; +EStudio_gui_erp_totl.ViewAxes = uiextras.HBox( 'Parent', p,'BackgroundColor',ColorB_def); + +end + + +function nMinimize( eventSource, eventData, whichpanel ) %#ok +global EStudio_gui_erp_totl; + +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.7020 0.77 0.85]; +end +minned = EStudio_gui_erp_totl.panel{whichpanel}.IsMinimized; +szs = get( EStudio_gui_erp_totl.settingLayout, 'Sizes' ); +if minned + set( EStudio_gui_erp_totl.panel{whichpanel}, 'IsMinimized', false); + szs(whichpanel) = EStudio_gui_erp_totl.panelSizes(whichpanel); +else + set( EStudio_gui_erp_totl.panel{whichpanel}, 'IsMinimized', true); + szs(whichpanel) = 25; +end +set( EStudio_gui_erp_totl.settingLayout, 'Sizes', szs ,'BackgroundColor',ColorB_def); +EStudio_gui_erp_totl.panelscroll.Heights = sum(szs); +set(EStudio_gui_erp_totl.panelscroll,'BackgroundColor',ColorB_def); +end % nMinimize diff --git a/studio_functions/Functions/EStudio/ERP Tab/README.md b/studio_functions/Functions/EStudio/ERP Tab/README.md new file mode 100755 index 00000000..48f4b88c --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/README.md @@ -0,0 +1,14 @@ +# ERPLAB Studio + +![EStudio_v0 016](https://user-images.githubusercontent.com/5137405/85075567-4f6b2a00-b173-11ea-9316-6a7965cb5b81.png) + + + +http://cda.psych.uiuc.edu/matlab_programming_class_2012/guide/GUILayout_v1p10/GUILayout-v1p10/layoutHelp/User%20guide5_2.html + + + + + + +Setting:Color cvl = uisetcolor( cvl,'Value line color') ; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/SignalProcessingToolboxCheck.m b/studio_functions/Functions/EStudio/ERP Tab/SignalProcessingToolboxCheck.m new file mode 100755 index 00000000..03b257ce --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/SignalProcessingToolboxCheck.m @@ -0,0 +1,21 @@ +% Signal Processing Toolbox check +% axs Nov 2020 +function SigProcT_here = SignalProcessingToolboxCheck + +% Get Toolbox list from ver +tbxs = ver; +[a, tbxs_n] = size(tbxs); +tbx_cell = cell(1,tbxs_n); +tbx_cell = {tbxs.Name}; + +SigProcT_here = any(ismember(tbx_cell,'Signal Processing Toolbox')); + +if SigProcT_here == 0 + % if the Signal Processing Toolbox is not found + warning_text = 'Matlab Signal Processing Toolbox has not been found.'; + warning_text2= 'This is required for many ERPLAB functions, especially filters'; + warning(warning_text) + warning(warning_text2) + disp('See Signal Processing Toolbox help here') + +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/check_matlab_version.m b/studio_functions/Functions/EStudio/ERP Tab/check_matlab_version.m new file mode 100755 index 00000000..8f29d625 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/check_matlab_version.m @@ -0,0 +1,35 @@ +% PURPOSE: +% little function to simplify the checking of the version of Matlab +% FORMAT: +% [Matlab_ver_yr] = check_matlab_version +% OUTPUT: +% Matlab_ver_yr - a numeric of the release year {like 2018.5 for Matlab +% R2018b.} +% +% *** This function is part of ERPLAB Toolbox *** +% Andrew X Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2018 + +function [Matlab_ver_yr] = check_matlab_version + +Matlab_ver = version('-release'); +Matlab_ver_yr = str2double(Matlab_ver(1:4)); + + +if strcmp(Matlab_ver(5),'b') + Matlab_ver_yr = Matlab_ver_yr + 0.5; + % signify 'b' releases with a 0.5 added to the year +end + + +% some functions like struct2table don't work in older than 2013b +% let's warn the user + +if Matlab_ver_yr < 2013.5 + errortxt = ['Some ERPLAB functions require a somewhat modern version of Matlab. R2013b is the oldest recommended. You are running R' Matlab_ver]; + warning(errortxt); +end + diff --git a/studio_functions/Functions/EStudio/ERP Tab/createrplabstudioparameters.m b/studio_functions/Functions/EStudio/ERP Tab/createrplabstudioparameters.m new file mode 100755 index 00000000..cfaf65fd --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/createrplabstudioparameters.m @@ -0,0 +1,28 @@ +%%This function is used to create/save the parameters applied in each step. + + + + +function S_OUT = createrplabstudioparameters(S_IN,varargin) +if isempty(varargin) + S_OUT = []; + return; +end + + +S_OUT = S_IN; +current_var = varargin{1}; + +current_var_field = current_var{1}; + +for Numoffilename1 = 1:length(current_var)-1 + current_var1{Numoffilename1} = current_var{Numoffilename1+1}; +end + +for Numoffilename = 1:floor(length(current_var)/2) + S_field_fir.(current_var1{2*(Numoffilename-1)+1}) = current_var1{2*Numoffilename}; +end + +S_OUT.(current_var_field) = S_field_fir; + +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/default_time_ticks_studio.m b/studio_functions/Functions/EStudio/ERP Tab/default_time_ticks_studio.m new file mode 100755 index 00000000..abe7e2b5 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/default_time_ticks_studio.m @@ -0,0 +1,87 @@ +% PURPOSE: subroutine for ploterpGUI.m +% Creates default X ticks for ERPLAB's plotting GUI +% +% FORMAT +% +% def = default_time_ticks(ERP, trange) +% +% INPUTS +% +% ERP - ERPset +% trange - min and max ERP window time in ms +% +% OUTPUT +% +% def - tick values to show in x axis +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2012 + +function [def stepx]= default_time_ticks_studio(ERP,trange,kf) +datatype = checkdatatype(ERP); +if nargin<3 + if strcmpi(datatype, 'ERP') + kf = 100; + else + kf = 10; + end +end + +if strcmpi(datatype, 'ERP') + kktime = 1000; +else + kktime = 1; +end + +% if 100=L1 && length(xtickarray)<=L2 + xm = xtickarray(round(length(xtickarray)/2)); + xtickarray = xtickarray-xm; + xtickarray = xtickarray(xtickarray>=xxs1 & xtickarray<=xxs2 ); + if xxs1<0 && xtickarray(1)>=0 + xtickarray = [ -round((abs(xxs1)/2)) xtickarray]; + xtickarray = unique_bc2(xtickarray); + end + def = {vect2colon(xtickarray,'Delimiter','off')}; + goags = 0; + elseif length(xtickarray)>L2 + stepx = stepx*2; + elseif length(xtickarray). + +function erplabstudioamnesia(warningop) +if nargin<1 + warningop = 0; +end +if warningop>0 + %Warning Message + question = ['Resetting EStudio''s working memory will\n'... + 'Clear all memory and cannot be recovered\n'... + 'Do you want to continue anyway?']; + title = 'EStudio: Reset EStudio''s working memory Confirmation'; + button = askquest(sprintf(question), title); + + if ~strcmpi(button,'yes') + disp('User selected Cancel') + return + end +end +erplab_studio_default_values % script +% check variable at workspace +try + vmemoryerp = evalin('base', 'vmemoryerp'); +catch + vmemoryerp = []; +end +if isempty(vmemoryerp) + fprintf('\n* FYI: EStudio''s working memory variable does not exist at workspace.\n') +else + if isfield(vmemoryerp, 'mshock') + mshock = vmemoryerp.mshock; + else + mshock = 0; + end + clear vmemoryerp + mshock = mshock + 1; + + % + % IMPORTANT: If this strucure (vmemoryerp) is modified then also must be modified the same line at eegplugin_erplab.m + % + vmemoryerp = struct('erplabstudiorel',erplabstudiorel,'erplabstudiover',erplabstudiover,'ColorB',ColorB,'ColorF',ColorF,'fontsizeGUI',fontsizeGUI,... + 'fontunitsGUI',fontunitsGUI,'mshock',mshock, 'errorColorF', errorColorF, 'errorColorB', errorColorB); + assignin('base','vmemoryerp',vmemoryerp); + fprintf('\n* EStudio''s working memory was reset (variable "vmemoryerp", at workspace, was rebuild with default values).\n'); +end + +% check file for memory +p = which('EStudio'); +p = p(1:findstr(p,'EStudio.m')-1); +mfile = fullfile(p,'memoryerpstudio.erpm'); + +if exist(mfile, 'file')==2 + v = load(fullfile(p,'memoryerpstudio.erpm'), '-mat'); + if isfield(v, 'mshock') + mshock = v.mshock; + else + mshock = 0; + end + + recycle on; + delete(mfile) + pause(0.1) + recycle off + mshock = mshock + 1; + fprintf('\n*** EStudio WARNING: EStudio''s working memory was wiped out. Default values will be used.\n\n') + + % + % IMPORTANT: If this file (saved variables inside memoryerp.erpm) is modified then also must be modified the same line at eegplugin_erplab.m + % + save(fullfile(p,'memoryerpstudio.erpm'),'erplabstudiorel','erplabstudiover','ColorB','ColorF','errorColorB', 'errorColorF','fontsizeGUI','fontunitsGUI','mshock'); +else + fprintf('\n* FYI: EStudio''s working memory file does not exist.\n') + return +end +if mshock>=30 && rand>0.8 + fprintf('\n\nIs it not enough???\n\n') +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/export2csv_spectranl_analysis.m b/studio_functions/Functions/EStudio/ERP Tab/export2csv_spectranl_analysis.m new file mode 100755 index 00000000..70210e1c --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/export2csv_spectranl_analysis.m @@ -0,0 +1,220 @@ +% PURPOSE : import the data to be ".CSV" file +% +% FORMAT : +% +% serror = export2csv_spectranl_analysis(ERP, filename, binArray, time, timeunit, electrodes, transpose, precision) +% +% +% INPUTS : +% +% ERP - ERPset (ERPLAB structure) +% filename - filename of outputted file +% binArray - bins to export +% time' - 1=include time values; 0=don't include time values +% electrodes' - 1=include electrode labels; 0=don't include electrode labels +% transpose' - 1= (points=rows) & (electrode=columns) +% 0= (electrode=rows) & (points=column) +% precision' - [float] number of significant digits in output. Default 4. +% +% OUTPUTS +% +% serror - error report. 0 means no errors found; 1 means something went wrong... +% file - csv file +% +% +% See also pop_export2text.m +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon && Eric Foo && Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 & 2023 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2022 The Regents of the University of California +% Created by Javier Lopez-Calderon, Steven Luck and Guanghui ZHANG +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu, and ghzhang@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + + + +function serror = export2csv_spectranl_analysis(ERP, filename, binArray, time, electrodes, transpose, precision) +serror = 0; % no errors +nbin = length(binArray); + +[pathstr, prefname1, ext] = fileparts(filename); + +if strcmp(ext,'') + ext = '.csv'; +end + +binfilename = [ prefname1 ext ]; % ...and add ext +fid = fopen(fullfile(pathstr,binfilename), 'w'); + +try + % disp('Your specified bins have been separated into the following files:')fprintf(fid_text, '\n'); + nbin = ERP.nbin; + nchan = ERP.nchan; + Frebin = numel(ERP.times); + ERPname = ERP.erpname; + fprintf(fid, '%s,%s\n',['Bins:,', num2str(nbin)]); + fprintf(fid, '\n'); + fprintf(fid, '%s,%s\n',['Channels:,', num2str(nchan)]); + fprintf(fid, '\n'); + fprintf(fid, '%s,%s\n',['Frequencies:,', num2str(Frebin)]); + fprintf(fid, '\n'); + fprintf(fid, '%s,%s\n',['ERPset name:,',ERPname]); + + + fprintf(fid, '\n\n\n\n'); + for ibin=1:nbin + + data = ERP.bindata(:,:,binArray(ibin)); + fprintf(fid, '#\n#'); + labx_bin = strcat(num2str(ibin),'-',ERP.bindescr{ibin}); + labx_bin = regexprep(labx_bin,'\\|\/|\*|\#|\$|\@,','_'); + try + labx_bin = strrep(labx_bin,',','-'); + catch + labx_bin= labx_bin; + end + % fprintf(fid, 'Bin: %s\t\n', labx_bin);num2str(ibin) + fprintf(fid, '%s %f \n',strcat('Bin:', labx_bin)); + fprintf(fid, '\n'); + fprintf(fid, '%s\n','#'); + % add time axis + % + if time==1 + % fprintf('bin #%g\n', ibin); + time_val = ERP.times; %Nov 2010 + auxdata = zeros(size(data,1) + 1, size(data,2)); + auxdata(1,:) = time_val; + auxdata(2:end,:) = data; + data = auxdata; clear auxdata; + end + + % + % transpose and write to disk + % + if transpose==0 % no transpose + + % + % writing electrodes + % + headName = ''; + strprintf = ''; + for index = 1:size(data,1) + if time==1 % show time values + tmpind = index-1; + else + tmpind = index; + end + if electrodes==1 + if tmpind > 0 + if ~isempty(ERP.chanlocs) + labx = ''; + labx = ERP.chanlocs(tmpind).labels; + labx = regexprep(labx,'\\|\/|\*|\#|\$|\@','_'); % replace forbidden characters + headName = [headName,strcat(num2str(tmpind),'-',labx),',']; + else + headName = [headName,strcat(num2str(tmpind)),',']; + end + else + headName = [headName,strcat('Frequency (Hz)'),',']; + end + else + % if tmpind > 0 + % headName = [headName,'',',']; + % else + % headName = [headName,strcat('Frequency (Hz)'),',']; + % end + end + if index~= size(data,1) + strprintf = [ strprintf '%.' num2str(precision) 'f,' ]; + else + strprintf = [ strprintf '%.' num2str(precision) 'f\n' ]; + end + + end + + if electrodes==1 + headName(end) = '\'; + headName = [headName,'n']; + fprintf(fid, headName); + end + for jj = 1:size(data,2) + fprintf(fid, strprintf, data(:,jj)); %#ok + end + fprintf(fid, '\n\n\n\n\n'); + else % transpose + + % + % writing electrodes + % + + for index = 1:size(data,1) + headName = ''; + if time==1 + tmpind = index-1; + else + tmpind = index; + end + if electrodes==1 + + if tmpind > 0 + if ~isempty(ERP.chanlocs) + labx = ERP.chanlocs(tmpind).labels; + labx = regexprep(labx,'\\|\/|\*|\#|\$|\@','_'); % replace forbidden characters. + headName = strcat(num2str(tmpind),'-',labx); + else + headName = num2str(tmpind); + end + else + headName = 'Frequency. (Hz)'; + end + end + if electrodes==1 + strprintf = '%s,'; + else + strprintf = ''; + end + for jj = 1:size(data,2) + if jj~= size(data,2) + strprintf = [ strprintf '%.' num2str(precision) 'f,' ]; + else + strprintf = [ strprintf '%.' num2str(precision) 'f\n' ]; + end + end + if electrodes==1 + fprintf(fid,strprintf, headName,data(index, :)); + else + fprintf(fid,strprintf,data(index, :)); + end + end + fprintf(fid, '\n\n\n\n\n'); + end + + end + fclose(fid); + + +catch + serror = 1; %something went wrong +end +fprintf('\n'); diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_ERP_chckbinandchan.m b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_chckbinandchan.m new file mode 100755 index 00000000..f41bf61a --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_chckbinandchan.m @@ -0,0 +1,55 @@ +function [chk, msgboxText] = f_ERP_chckbinandchan(ERP, binArray, chanArray,Bin_Chan_label) +chk=[0 0]; +msgboxText = ''; + +% if numel(Bin_Chan_label)==1 +% Bin_label +% +% end + + +if Bin_Chan_label==1 + if isempty(binArray) + msgboxText = 'You have not specified any bin'; + chk(1) = 1; + return + end + if any(binArray<=0) + msgboxText = sprintf('Invalid bin index.\nPlease specify only positive integer values.'); + chk(1) = 1; + return + end + if any(binArray>ERP.nbin) + msgboxText = sprintf('Bin index out of range!\nYou only have %g bins in this ERPset',ERP.nbin); + chk(1) = 1; + return + end + if length(binArray)~=length(unique_bc2(binArray)) + msgboxText = 'You have specified repeated bins.'; + chk(1) = 1; + return + end +end +if Bin_Chan_label ==2 + if isempty(chanArray) + msgboxText = 'You have not specified any channel'; + chk(2) = 1; + return + end + if any(chanArray<=0) + msgboxText = sprintf('Invalid channel index.\nPlease specify only positive integer values.'); + chk(2) = 1; + return + end + if any(chanArray>ERP.nchan) + msgboxText = sprintf('Channel index out of range!\nYou only have %g channels in this ERPset', ERP.nchan); + chk(2) = 1; + return + end + if length(chanArray)~=length(unique_bc2(chanArray)) + msgboxText = 'You have specified repeated channels.'; + chk(2) = 1; + return + end + return; +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_ERP_chckerpindex.m b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_chckerpindex.m new file mode 100755 index 00000000..0e7f28e6 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_chckerpindex.m @@ -0,0 +1,31 @@ +function [chk, msgboxText] = f_ERP_chckerpindex(ALLERP, SelectedIndex) +chk=0; +msgboxText = ''; + +ALLERPinx = [1:length(ALLERP)]; + +if isempty(SelectedIndex) + msgboxText = 'You have not specified any ERPset'; + chk = 1; + return +end + +if any(SelectedIndex<=0) + msgboxText = sprintf('Invalid ERPset index.\n Please specify only positive integer values.'); + chk= 1; + return +end + + + +if max(SelectedIndex(:))> numel(ALLERPinx) + msgboxText = sprintf('Selected ERPsets'' index out of range of ALLERP!'); + chk= 1; + return +end +if length(SelectedIndex)~=length(unique_bc2(SelectedIndex)) + msgboxText = 'You have specified repeated ERPsets.'; + chk = 1; + return +end + diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_ERP_duplicate.fig b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_duplicate.fig new file mode 100755 index 00000000..d69e9459 Binary files /dev/null and b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_duplicate.fig differ diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_ERP_duplicate.m b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_duplicate.m new file mode 100755 index 00000000..6d17584c --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_duplicate.m @@ -0,0 +1,361 @@ +function varargout = f_ERP_duplicate(varargin) +% F_ERP_DUPLICATE MATLAB code for f_ERP_duplicate.fig +% F_ERP_DUPLICATE, by itself, creates a new F_ERP_DUPLICATE or raises the existing +% singleton*. +% +% H = F_ERP_DUPLICATE returns the handle to a new F_ERP_DUPLICATE or the handle to +% the existing singleton*. +% +% F_ERP_DUPLICATE('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_DUPLICATE.M with the given input arguments. +% +% F_ERP_DUPLICATE('Property','Value',...) creates a new F_ERP_DUPLICATE or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_duplicate_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_duplicate_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_duplicate + +% Last Modified by GUIDE v2.5 24-Jun-2022 06:43:36 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_duplicate_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_duplicate_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_duplicate is made visible. +function f_ERP_duplicate_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_duplicate + +try + ERP = varargin{1}; + currenterp = varargin{2}; + binArray = varargin{3}; + chanArray = varargin{4}; +catch + ERP.erpname = 'No erp was imported'; + ERP.nbin =1; + ERP.nchan = 1; + ERP.chanlocs(1).labels = 'None'; + ERP.bindescr{1} = 'None'; + binArray = 1; + chanArray = 1; + currenterp = []; + ERP.bindata = zeros(1,10,1); +end + +% handles.erpnameor = ERP.erpname; +handles.output = []; +handles.ERP = ERP; + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Duplicate ERPset GUI']) +set(handles.edit_erpname, 'String', ERP.erpname); + +if isempty(currenterp) + set(handles.current_erp_label,'String', ['No active erpset was found'],... + 'FontWeight','Bold', 'FontSize', 16); +else + set(handles.current_erp_label,'String', ['Creat a new erpset # ' num2str(currenterp+1)],... + 'FontWeight','Bold', 'FontSize', 16) +end + + + +listb = {''}; +nbin = ERP.nbin; % Total number of bins +try + for b=1:nbin + listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; + end +catch + listb = ''; +end + + + +%%%set(handles.popupmenu_bins,'String', listb) +handles.listb = listb; +handles.indxlistb = binArray; + + + +nchan = ERP.nchan; % Total number of channels +if ~isfield(ERP.chanlocs,'labels') + for e=1:nchan + ERP.chanlocs(e).labels = ['Ch' num2str(e)]; + end +end +listch = {''}; +try + for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ]; + end +catch + listch = ''; +end +handles.listch = listch; +handles.indxlistch = chanArray; + +set(handles.edit6_bin,'String', vect2colon(binArray, 'Delimiter', 'off')); +set(handles.edit7_chan,'String', vect2colon(chanArray, 'Delimiter', 'off')); + + + +% Color GUI +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + + + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_duplicate_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +% try +% set(handles.menuerp.Children, 'Enable','on'); +% catch +% disp('ERPset menu was not found...') +% end +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + + + +% --- Executes on button press in radio_erpname. +function radio_erpname_Callback(hObject, eventdata, handles) + + + +function edit_erpname_Callback(hObject, eventdata, handles) +erpname = strtrim(get(handles.edit_erpname, 'String')); +if isempty(erpname) + msgboxText = 'You must enter an erpname at least!'; + title = 'EStudio: Duplicate ERPset GUI - empty erpname'; + errorfound(msgboxText, title); + return +end + +% --- Executes during object creation, after setting all properties. +function edit_erpname_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function edit6_bin_Callback(hObject, eventdata, handles) +BinString = str2num(handles.edit6_bin.String); +ERP = handles.ERP; +% [chk, msgboxText] = chckbinandchan(ERP, BinString, []); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1); + +if chk(1) + title = 'EStudio: Duplicate ERPset GUI for bin input!'; + errorfound(msgboxText, title); + return; +end + + + + +% --- Executes during object creation, after setting all properties. +function edit6_bin_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function edit7_chan_Callback(hObject, eventdata, handles) +chanString = str2num(handles.edit7_chan.String); +ERP = handles.ERP; +% [chk, msgboxText] = chckbinandchan(ERP, BinString, []); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],chanString, 2); + +if chk(2) + title = 'EStudio: Duplicate ERPset GUI for channel input!'; + errorfound(msgboxText, title); + return; +end + + +% --- Executes during object creation, after setting all properties. +function edit7_chan_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_bin_browse. +function pushbutton_bin_browse_Callback(hObject, eventdata, handles) +listb = handles.listb; +indxlistb = handles.indxlistb; +indxlistb = indxlistb(indxlistb<=length(listb)); +titlename = 'Select Bin(s)'; + +if get(hObject, 'Value') + %set(handles.pushbutton_browsechan, 'Enable', 'off') + if ~isempty(listb) + bin = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(bin) + set(handles.edit6_bin, 'String', vect2colon(bin, 'Delimiter', 'off')); + handles.indxlistb = bin; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No bin information was found'; + title = 'EStudio: Duplicate ERPset GUI for bin input'; + errorfound(msgboxText, title); + return + end + +end + + +% --- Executes on button press in pushbutton_chan_browse. +function pushbutton_chan_browse_Callback(hObject, eventdata, handles) +listch = handles.listch; +indxlistch = handles.indxlistch; +indxlistch = indxlistch(indxlistch<=length(listch)); +titlename = 'Select Channel(s)'; + +if get(hObject, 'Value') + if ~isempty(listch) + ch = browsechanbinGUI(listch, indxlistch, titlename); + if ~isempty(ch) + set(handles.edit7_chan, 'String', vect2colon(ch, 'Delimiter', 'off')); + handles.indxlistch = ch; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No channel information was found'; + title = 'Duplicate ERPset GUI for channel input'; + errorfound(msgboxText, title); + return + end +end + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +beep; +disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) +erpname = strtrim(get(handles.edit_erpname, 'String')); + +if isempty(erpname) + msgboxText = 'You must enter an erpname at least!'; + title = 'EStudio: Duplicate ERPset GUI - empty erpname'; + errorfound(msgboxText, title); + return +end + + +BinArray = str2num(handles.edit6_bin.String); +ERP = handles.ERP; +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1); + +if chk(1) + title = 'EStudio: Duplicate ERPset GUI for bin input!'; + errorfound(msgboxText, title); + return; +end + + +ChanArray = str2num(handles.edit7_chan.String); +% ERP = handles.ERP; +% [chk, msgboxText] = chckbinandchan(ERP, BinString, []); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],ChanArray, 2); + +if chk(2) + title = 'EStudio: Duplicate ERPset GUI for channel input!'; + errorfound(msgboxText, title); + return; +end + + +ERP.erpname = erpname; + +ERP.bindata = ERP.bindata(ChanArray,:,BinArray); +ERP.nbin = numel(BinArray); +ERP.nchan = numel(ChanArray); +ERP.chanlocs = ERP.chanlocs(ChanArray); +for Numofbin = 1:numel(BinArray) + Bindescr{Numofbin} = ERP.bindescr{BinArray(Numofbin)}; +end +ERP.bindescr = Bindescr; + +ERP.saved = 'no'; +ERP.filepath = ''; +handles.output = ERP; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_ERP_plot_wav.m b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_plot_wav.m new file mode 100755 index 00000000..fd17cf5f --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_ERP_plot_wav.m @@ -0,0 +1,310 @@ + + +function [new_erp_data,Amp_out,Lat_out_trals,Amp,Lat]= f_ERP_plot_wav(ERPIN) +global observe_ERPDAT; + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +S_ws_geterpplot = estudioworkingmemory('geterpplot'); + + +%%Parameter from bin and channel panel +Elecs_shown = S_ws_getbinchan.elecs_shown{S_ws_getbinchan.Select_index}; +Bins = S_ws_getbinchan.bins{S_ws_getbinchan.Select_index}; +Bin_chans = S_ws_getbinchan.bins_chans(S_ws_getbinchan.Select_index); +Elec_list = S_ws_getbinchan.elec_list{S_ws_getbinchan.Select_index}; +Matlab_ver = S_ws_getbinchan.matlab_ver; + + + +%%Parameter from plotting panel +Min_vspacing = S_ws_geterpplot.min_vspacing(S_ws_getbinchan.Select_index); +Min_time = S_ws_geterpplot.min(S_ws_getbinchan.Select_index); +Max_time = S_ws_geterpplot.max(S_ws_getbinchan.Select_index); +Yscale = S_ws_geterpplot.yscale(S_ws_getbinchan.Select_index); +Timet_low =S_ws_geterpplot.timet_low(S_ws_getbinchan.Select_index); +Timet_high =S_ws_geterpplot.timet_high(S_ws_getbinchan.Select_index); +Timet_step=S_ws_geterpplot.timet_step(S_ws_getbinchan.Select_index); +Fill = S_ws_geterpplot.fill(S_ws_getbinchan.Select_index); +Plority_plot = S_ws_geterpplot.Positive_up(S_ws_getbinchan.Select_index); + + +if Bin_chans == 0 + elec_n = S_ws_getbinchan.elec_n(S_ws_getbinchan.Select_index); + max_elec_n = ERPIN.nchan; +else + elec_n = S_ws_getbinchan.bin_n(S_ws_getbinchan.Select_index); + max_elec_n = ERPIN.nbin; +end + + +ndata = 0; +nplot = 0; +if Bin_chans == 0 + ndata = Bins; + nplot = Elecs_shown; +else + ndata = Elecs_shown; + nplot = Bins; +end + + + +[xxx, latsamp, latdiffms] = closest(ERPIN.times, [Min_time Max_time]); +tmin = latsamp(1); +tmax = latsamp(2); + +if tmin < 1 + tmin = 1; +end + +if tmax > numel(ERPIN.times) + tmax = numel(ERPIN.times); +end + + +splot_n = elec_n; + +plot_erp_data = nan(tmax-tmin+1,numel(ndata)); +for i = 1:splot_n + if Bin_chans == 0 + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = ERPIN.bindata(Elecs_shown(i),tmin:tmax,Bins(i_bin))'*Plority_plot; % + end + else + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = ERPIN.bindata(Elecs_shown(i_bin),tmin:tmax,Bins(i))'*Plority_plot; % + end + end +end + + +%%Transfer the original data to what can be used to plot in ERPlab Studio +%%based on the seleted channels and bins, time-window +perc_lim = Yscale; +percentile = perc_lim*3/2; +ind_plot_height = percentile*2; +offset = []; +if Bin_chans == 0 + offset = (numel(Elecs_shown)-1:-1:0)*ind_plot_height; +else + offset = (numel(Bins)-1:-1:0)*ind_plot_height; +end +[~,~,b] = size(plot_erp_data); + +for i = 1:b + plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i); +end + + + +[a,c,b] = size(plot_erp_data); +new_erp_data = zeros(a,b*c); +for i = 1:b + new_erp_data(:,((c*(i-1))+1):(c*i)) = plot_erp_data(:,:,i); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%Find the amplitude and latency based on geterpvalues%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +erp_m_t_p = estudioworkingmemory('geterpvalues'); + +if isempty(erp_m_t_p) + msgboxText = ['EStudio says: Please select the meaurement type of interest and set the related parameters from "ERP measurement tool".']; + title = 'EStudio: ERP measurement tool'; + errorfound(msgboxText, title); + return; +end + + +MeasureName = {'meanbl','peakampbl', 'peaklatbl','fareatlat','fpeaklat','fninteglat','fareaplat','fareanlat',... + 'areat','ninteg','areap','arean','areazt','nintegz','areazp','areazn','instabl'}; +[C,IA] = ismember_bc2({erp_m_t_p.Measure}, MeasureName); +if ~any(IA) || isempty(IA) + IA =1; +end + + +if isempty(erp_m_t_p.latency) + msgboxText = 'Please set a Measurement window'; + title = 'ERPLAB: ERP Measurement Tool'; + errorfound(msgboxText, title); + return; +end +moption = erp_m_t_p.Measure; +latency = erp_m_t_p.latency; +if isempty(moption) + msgboxText = ['EStudio says: User must specify a type of measurement.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; +end +if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + msgboxText = ['EStudio says: ' moption ' only needs 1 latency value.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + end +else + if length(latency)~=2 + msgboxText = ['EStudio says: ' moption ' needs 2 latency values.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + else + if latency(1)>=latency(2) + msgboxText = ['For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.']; + title = 'EStudio: ERP measurement tool-Measurement window'; + errorfound(sprintf(msgboxText), title); + return + end + end +end +binArray =[1:ERPIN.nbin]; +chanArray = [1:ERPIN.nchan]; +Amp = zeros(length(binArray), length(chanArray)); +Lat = []; + +erp_m_t_p.Erpsets = S_ws_geterpset; + + + + +MeasureName = {'meanbl','peakampbl', 'peaklatbl','fareatlat','fpeaklat','fninteglat','fareaplat','fareanlat',... + 'areat','ninteg','areap','arean','areazt','nintegz','areazp','areazn','instabl'}; +[C,IA] = ismember_bc2({erp_m_t_p.Measure}, MeasureName); +if ~any(IA) || isempty(IA) + IA =1; +end + +if isempty(erp_m_t_p.latency) + msgboxText = 'Please set a Measurement window'; + title = 'ERPLAB: ERP Measurement Tool'; + errorfound(msgboxText, title); + return; +end +moption = erp_m_t_p.Measure; +latency = erp_m_t_p.latency; +if isempty(moption) + msgboxText = ['ERPLAB says: User must specify a type of measurement.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; +end +if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + msgboxText = ['ERPLAB says: ' moption ' only needs 1 latency value.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + end +else + if length(latency)~=2 + msgboxText = ['ERPLAB says: ' moption ' needs 2 latency values.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + else + if latency(1)>=latency(2) + msgboxText = ['For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.']; + title = 'EStudio: ERP measurement tool-Measurement window'; + errorfound(sprintf(msgboxText), title); + return + end + end +end + +% ALLERP = evalin('base','ALLERP'); +if isempty(erp_m_t_p.Afraction) + erp_m_t_p.Afraction =0.5; +end + +if strcmp(erp_m_t_p.Peakpolarity,'positive')%check the polirity + polpeak =1; +else + polpeak =0; +end + +if strcmp( erp_m_t_p.Peakreplace,'NaN') + locpeakrep=0; +else + locpeakrep =1; +end + + +if strcmp(erp_m_t_p.Fracreplace,'NaN') + fracmearep =0; +elseif strcmp(erp_m_t_p.Fracreplace,'absolute') + fracmearep=1; +else + fracmearep =2; +end + +[Amp, Lat] = geterpvalues(ERPIN, erp_m_t_p.latency, binArray, chanArray, ... + MeasureName{IA}, erp_m_t_p.Baseline, erp_m_t_p.Component,... + polpeak, erp_m_t_p.Neighborhood, locpeakrep,... + erp_m_t_p.Afraction, fracmearep, erp_m_t_p.InterpFactor,erp_m_t_p.PeakOnset); + +% [ALLERP, Amp, Lat] = pop_geterpvalues(ALLERP, erp_m_t_p.latency, binArray,chanArray,... +% 'Erpsets', Current_ERP, 'Measure',MeasureName{IA}, 'Component', erp_m_t_p.Component,... +% 'Resolution', erp_m_t_p.Resolution, 'Baseline', erp_m_t_p.Baseline, 'Binlabel', erp_m_t_p.Binlabel,... +% 'Peakpolarity',erp_m_t_p.Peakpolarity, 'Neighborhood', erp_m_t_p.Neighborhood, 'Peakreplace', erp_m_t_p.Peakreplace,... +% 'Warning',erp_m_t_p.Warning,'SendtoWorkspace', erp_m_t_p.SendtoWorkspace, 'Append', erp_m_t_p.Append,... +% 'FileFormat', erp_m_t_p.FileFormat,'Afraction', erp_m_t_p.Afraction, 'Mlabel', erp_m_t_p.Mlabel,... +% 'Fracreplace', erp_m_t_p.Fracreplace,'IncludeLat', erp_m_t_p.IncludeLat, 'InterpFactor', erp_m_t_p.InterpFactor,... +% 'PeakOnset',erp_m_t_p.PeakOnset); + +Lat_out_trals = {}; + +for i = 1:splot_n + if Bin_chans == 0 + for i_bin = 1:numel(ndata) + Amp_out_trans(i_bin,i) = Amp(Bins(i_bin),Elecs_shown(i))*Plority_plot; % + if ~isempty(Lat) + Lat_out_trals{i_bin,i} = Lat{Bins(i_bin),Elecs_shown(i)}; + end + end + else + for i_bin = 1:numel(ndata) + Amp_out_trans(i_bin,i) = Amp(Bins(i),Elecs_shown(i_bin))*Plority_plot; % + if ~isempty(Lat) + Lat_out_trals{i_bin,i} = Lat{Bins(i),Elecs_shown(i_bin)}; + end + end + end +end +Amp_out = zeros(c,b); + +if ismember_bc2(moption, {'meanbl','peakampbl','areazt','areazp','areazn', 'nintegz','instabl'}) + for i = 1:b + Amp_out(:,i) = Amp_out_trans(:,i) + ones(size(Amp_out_trans(:,i)))*offset(i); + end +elseif ismember_bc2(moption, {'peaklatbl','fpeaklat','fareatlat', 'fareaplat','fninteglat','fareanlat'}) + + for i = 1:b + Amp_out(:,i) = Amp_out_trans(:,i)*Plority_plot; + end + +end + + + +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_ERPplot_Parameter.m b/studio_functions/Functions/EStudio/ERP Tab/f_ERPplot_Parameter.m new file mode 100755 index 00000000..4345b774 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_ERPplot_Parameter.m @@ -0,0 +1,218 @@ +%Purpose: This function is used to generate the parameters which are applied to get the waveforms of electrodes and bins of interest. + + +%FORMAT: +% +% f_ERPplot_Parameter(ALLERP,Index_selectedERPset) + +% INPUTS : +% +% ALLERP - structure array of ERP structures (ERPsets) +% To read the ERPset from a list in a text file, +% replace ALLERP by the whole filename. +% +% Index_selectedERPset - index of selected ERPset(s),e.g., 1 or [3,4] + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + + +function S_erpplot = f_ERPplot_Parameter(ALLERP,Index_selectedERPset) + + +if nargin<1 + help f_ERPplot_Parameter + return +end + +if nargin==1 + try + Index_selectedERPset = evalin('base','CURRENTERP'); + catch + beep; + disp('No CURRENTERP can be found from Matlab workspace') + return; + end +end + + +if Index_selectedERPset > length(ALLERP) + beep; + disp('The index of the input ERPset is larger than the length of ALLERPSET !!!'); + return; +end + +if isempty(Index_selectedERPset) + beep; + disp('The ERPsets of interest can not be selected!!!'); + return; +end + +S_ws = struct(); + +% checked_ERPset_Index_bin_chan = f_checkerpsets(ALLERP,Index_selectedERPset); + +for NumofselectERP =1:length(Index_selectedERPset) + + if Index_selectedERPset(NumofselectERP)> length(ALLERP)% check if the index exceeds the length of ALLERPsets + msgboxText = 'The selected ERPset does not exsit!!!'; + title = 'EStudio: Bin and Channel Selection'; + errorfound(msgboxText, title); + return; + end + + ERP = ALLERP(Index_selectedERPset(NumofselectERP)); + + % elec_list = cell(numel(ERP.chanlocs),1); + for i=1:length(ERP.chanlocs) + elec_list_get{i} = ERP.chanlocs(i).labels; + end + + if length(elec_list_get)~= size(ERP.bindata,1) + beep; + title = 'EStudio: Bin and Channel Selection'; + msgboxText = strcat('Number of channel''s labels is not equal to number of first demension of ERP.bindata for imported datasets!!!'); + disp(); + errorfound(msgboxText, title); + return; + + end + + elec_list{NumofselectERP} = elec_list_get; + clear elec_list_get; + Check_bin_chan = [0 0]; + first_elec(NumofselectERP) = 1; + if length(ERP.chanlocs) <41 + elec_n(NumofselectERP) = numel(ERP.chanlocs); + elecs_shown{NumofselectERP} = first_elec:first_elec+elec_n(NumofselectERP)-1; + elseif length(ERP.chanlocs) >40 + elec_n(NumofselectERP) =40; + elecs_shown{NumofselectERP} = 1:40; + Check_bin_chan(1) =1; + end + + timemin(NumofselectERP) = ERP.times(1); + timemax(NumofselectERP) = ERP.times(end); + timefirst(NumofselectERP) = timemin(NumofselectERP); + + + % bins = zeros(1,ERP.nbin); + %%Dispay the first 20 bins if the number of bins is exceed 20. + if ERP.nbin<21 + bins{NumofselectERP} =1:ERP.nbin; + bin_n(NumofselectERP) = ERP.nbin; + elseif ERP.nbin>=21 + bins{NumofselectERP} =1:20; + bin_n(NumofselectERP) = 20; + Check_bin_chan(2) =1; + end + + + min(NumofselectERP) = floor(ERP.times(1)/5)*5; + max(NumofselectERP) = ceil(ERP.times(end)/5)*5; + + tmin(NumofselectERP) = (floor((min(NumofselectERP)-ERP.times(1))/2)+1); + tmax(NumofselectERP) = (numel(ERP.times)+ceil((max(NumofselectERP)-ERP.times(end))/2)); + + if tmin(NumofselectERP) < 1 + tmin(NumofselectERP) = 1; + end + + if tmax(NumofselectERP) > numel(ERP.times) + tmax(NumofselectERP) = numel(ERP.times); + + end + + if strcmpi(ERP.erpname,'No ERPset loaded') + tmax(NumofselectERP) = 1; + max(NumofselectERP) =1; + end + min_vspacing(NumofselectERP) = 1.5; + YScale = prctile((ERP.bindata(:)),95)*2/3; + if YScale>= 0&&YScale <=0.1 + prct(NumofselectERP) = 0.1; + elseif YScale< 0&& YScale > -0.1 + prct(NumofselectERP) = -0.1; + else + prct(NumofselectERP) = round(YScale); + end + timet_low(NumofselectERP) = floor(ERP.times(1)/5)*5; + if strcmpi(ERP.erpname,'No ERPset loaded') + timet_high = 1; + stepx =1; + else + timet_high(NumofselectERP) = ceil(ERP.times(end)/5)*5; + [def stepx]= default_time_ticks_studio(ERP); + end + + % timet_step(NumofselectERP) = (ceil(ERP.times(end)/5)*5-floor(ERP.times(1)/5)*5)/5; + timet_step(NumofselectERP) = stepx; + fill_index(NumofselectERP) = 1; + Positive_up_index(NumofselectERP) = 1; + bins_chans(NumofselectERP) = 0; + plot_column(NumofselectERP) = 1; +end + + + + +matlab_ver = version('-release'); +matlab_ver = str2double(matlab_ver(1:4)); + + +data_p_bin_chan = { elec_list, ... + first_elec, ... + elec_n, ... + elecs_shown, ... + timemin, ... + timemax, ... + timefirst, ... + bins, ... + bin_n, ... + matlab_ver, ... + bins_chans, ... + min, ... + max, ... + timet_low, ... + timet_high, ... + timet_step, ... + prct, ... + min_vspacing, ... + fill_index,... + Positive_up_index,... + plot_column}; + +erpvalues_variables = {'geterpplot','timemin',data_p_bin_chan{5},'timemax',data_p_bin_chan{6},'timefirst',data_p_bin_chan{7},... + 'min',data_p_bin_chan{12},'max',data_p_bin_chan{13},... + 'timet_low',data_p_bin_chan{14},'timet_high',data_p_bin_chan{15},... + 'timet_step',data_p_bin_chan{16},'yscale',data_p_bin_chan{17},... + 'min_vspacing',data_p_bin_chan{18},'fill',data_p_bin_chan{19},... + 'Positive_up',data_p_bin_chan{20},'Plot_column',data_p_bin_chan{end}}; +S_erpplot = createrplabstudioparameters(S_ws,erpvalues_variables); + +%%------------------------Chan and bin------------------------------------- + +if strcmp(ALLERP(1).erpname,'No ERPset loaded') + checked_curr_index = 1; +else + checked_curr_index = 0; +end +checked_ERPset_Index = f_checkerpsets(ALLERP,Index_selectedERPset); + + +erpvalues_variables = {'geterpbinchan','elec_list',data_p_bin_chan{1},'first_elec',data_p_bin_chan{2},... + 'elec_n',data_p_bin_chan{3},'elecs_shown',data_p_bin_chan{4},... + 'bins',data_p_bin_chan{8},'bin_n',data_p_bin_chan{9},... + 'matlab_ver',data_p_bin_chan{10},'bins_chans',data_p_bin_chan{11},'Select_index',1,... + 'checked_ERPset_Index',checked_ERPset_Index,'checked_curr_index',checked_curr_index}; +S_erpplot = createrplabstudioparameters(S_erpplot,erpvalues_variables); + + + +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_baseline_geterpvalues.m b/studio_functions/Functions/EStudio/ERP Tab/f_baseline_geterpvalues.m new file mode 100755 index 00000000..ae7cb507 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_baseline_geterpvalues.m @@ -0,0 +1,309 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function S_out = f_baseline_geterpvalues(varargin) + +%%Get the parameters for pop_geterpvalues used in the last time. +def_erpvalue = erpworkingmemory('pop_geterpvalues'); + +try + ALLERP = evalin('base','ALLERP'); + CurrentERPSet = evalin('base','CURRENTERP'); + Current_ERP = evalin('base','ERP'); +catch + return; +end + +if isstruct(ALLERP) + if ~iserpstruct(ALLERP(1)) + ALLERP = []; + nbinx = 1; + nchanx = 1; + else + nbinx = ALLERP(1).nbin; + nchanx = ALLERP(1).nchan; + end +else + ALLERP = []; + nbinx = 1; + nchanx = 1; +end + +if isempty(def_erpvalue) + if isempty(ALLERP) + inp1 = 1; %from hard drive + CurrentERPSet = []; + else + inp1 = 0; %from erpset menu + CurrentERPSet = 1:length(ALLERP); + end + + def_erpvalue = {inp1,CurrentERPSet,'',0,1:nbinx,1:nchanx,'meanbl',... + 1,3,'pre',1,1,5,0,0.5,0,0,0,'',0,1,1}; + +else + if ~isempty(ALLERP) + if isnumeric(def_erpvalue{2}) % JavierLC 11-17-11 + [uu, mm] = unique_bc2(def_erpvalue{2}, 'first'); + erpset_list_sorted = [def_erpvalue{2}(sort(mm))]; + %def_erpvalue{2} = def_erpvalue{2}(def_erpvalue{2}<=length(ALLERP)); + % non-empty check, axs jul17 + erpset_list = erpset_list_sorted(erpset_list_sorted<=length(ALLERP)); + if isempty(erpset_list) + % if nothing in list, just go with current + def_erpvalue{2} = CurrentERPSet; + else + % use JLC's sorting, iff not empty + def_erpvalue{2} = erpset_list; + end + + end + end +end + + +if def_erpvalue{11} == 0 + def_erpvalue{11} = 'off'; +else + def_erpvalue{11} = 'on'; +end + +if def_erpvalue{12} == 0 + def_erpvalue{12} = 'negative'; +else + def_erpvalue{12} = 'positive'; +end + +if def_erpvalue{14}==0 + def_erpvalue{14} = 'NaN'; +else + def_erpvalue{14} = 'absolute'; +end + +if def_erpvalue{16}==0 % Fractional area latency replacement + def_erpvalue{16} = 'NaN'; +else + if ismember_bc2({def_erpvalue{7}}, {'fareatlat', 'fninteglat','fareaplat','fareanlat'}) + def_erpvalue{16} = 'errormsg'; + else + def_erpvalue{16} = 'absolute'; + end +end + +if def_erpvalue{17} == 0 + def_erpvalue{17} = 'off'; +else + def_erpvalue{17} = 'on'; +end + +if def_erpvalue{18} == 0 + def_erpvalue{18} = 'wide'; +else + def_erpvalue{18} = 'long'; +end + + +if def_erpvalue{20} == 0 + def_erpvalue{20} = 'no'; +else + def_erpvalue{20} = 'yes'; +end + +% +S_IN = estudioworkingmemory('geterpvalues'); +if isempty(S_IN) + erpvalues_variables = {'geterpvalues','latency',def_erpvalue{4},... + 'binArray',def_erpvalue{5},... + 'chanArray', def_erpvalue{6},... + 'Erpsets', def_erpvalue{2},... + 'Measure',def_erpvalue{7},... + 'Component',def_erpvalue{8},... + 'Resolution', def_erpvalue{9},... + 'Baseline', def_erpvalue{10},... + 'Binlabel', def_erpvalue{11},... + 'Peakpolarity',def_erpvalue{12},... + 'Neighborhood', def_erpvalue{13},... + 'Peakreplace', def_erpvalue{14},... + 'Filename', def_erpvalue{3},... + 'Warning','on',... + 'SendtoWorkspace', def_erpvalue{17},... + 'Append', '',... + 'FileFormat', def_erpvalue{18},... + 'Afraction',def_erpvalue{15},... + 'Mlabel', def_erpvalue{19},... + 'Fracreplace', def_erpvalue{16},... + 'IncludeLat', def_erpvalue{20},... + 'InterpFactor', def_erpvalue{21},... + 'Viewer', 'off',... + 'PeakOnset',def_erpvalue{22},... + 'History', 'gui'}; + S_OUT = createrplabstudioparameters(S_IN,erpvalues_variables); + estudioworkingmemory('geterpvalues',S_OUT.geterpvalues); + S_IN = S_OUT.geterpvalues; +end + +S_out = S_IN; +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%Judge if the baseline method is character? +%%------------------------GUI start---------------------------------------------- +f_localpeak = figure( 'Name', 'ERP Measurement Tool', ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off'); +f_localpeak.Position(3:4) = [250 120]; + + +% f_localpeak_ll = uiextras.BoxPanel('Parent', f_localpeak, 'Title', ' ', 'Padding', 5); + +BaselineMethod = S_out.Baseline; +if ~ischar(BaselineMethod) + BaselineMethod = 'custom'; + BaselineInterval = S_out.Baseline; +else + BaselineInterval = 0.000; +end + + +gui_baseline = erp_m_t_Baseline_period_gui(); + + function gui_baseline = erp_m_t_Baseline_period_gui() + FontSize_defualt = erpworkingmemory('fontsizeGUI'); + if isempty(FontSize_defualt) + FontSize_defualt = 12; + end + b1 = uiextras.VBox( 'Parent', f_localpeak); + %%---------------------------------Title------------------------------------ + b11 = uiextras.HBox( 'Parent', b1 ); + b111 = uicontrol('Style','text','Parent', b11,'String','Baseline period (in ms)','fontsize',16);%,'FontWeight', 'bold'); + + %%------------------------------Baseline methods--------------------------- + b13 = uiextras.HBox( 'Parent', b1 ); + b131 = uicontrol('Style','text','Parent', b13,'String','Method selection','FontSize',FontSize_defualt);%,'FontWeight', 'bold'); + set(b131, 'horizontalAlignment', 'left'); + Baseline_methods = {'None','Pre','Post','Whole','Custom'}; + lpa_baseline_method = uicontrol('Style', 'popup','Parent',b13,'String',Baseline_methods,'callback',@Baseline_selection,'FontSize',FontSize_defualt); + set(b13, 'Sizes', [150 100]); + if ~isempty(S_out.Baseline) + switch BaselineMethod + case 'none' + set(lpa_baseline_method,'value',1); + case 'pre' + set(lpa_baseline_method,'value',2); + case 'post' + set(lpa_baseline_method,'value',3); + case 'whole' + set(lpa_baseline_method,'value',4); + otherwise + set(lpa_baseline_method,'value',5); + end + end + + %%-----------------Custum define time window for baseline period----------------- + b14 = uiextras.HBox( 'Parent', b1 ); + b141 = uicontrol('Style','text','Parent', b14,'String','Use two latencies','FontSize',FontSize_defualt);%,'FontWeight', 'bold'); + set(b141, 'horizontalAlignment', 'left'); + gui_baseline.lpa_baseline_custom = uicontrol('Style', 'edit','Parent',b14,'String',num2str(BaselineInterval),'callback',@Baseline_custom,'FontSize',FontSize_defualt); + if ~strcmp(BaselineMethod,'custom') + set(gui_baseline.lpa_baseline_custom,'ForegroundColor', [.5 0.5 0.5], 'Enable', 'off','BackgroundColor',[0.800 0.800 0.800]); + set(b141,'ForegroundColor', [.5 0.5 0.5]); + end + set(b14, 'Sizes', [150 100]); + %%------------------------Cancel and Run---------------------------------- + b16 = uiextras.HBox( 'Parent', b1); + uicontrol( 'Parent', b16, 'String', 'Cancel','callback',@Local_peak_cancel,'FontSize',FontSize_defualt); + uicontrol( 'Parent', b16, 'String', 'Run','callback',@Local_peak_run,'FontSize',FontSize_defualt); + + end +%%************************************************************************* +%%****************** subfunctions ************************************* +%%************************************************************************* + +%%-----------------------Baseline method selection------------------------- +%%'None','Pre','Post','Whole','Custum' + function Baseline_selection(Source_Baseline_selection,~) + Values_local_replace = Source_Baseline_selection.Value; + if ~isempty(Values_local_replace) + + if Values_local_replace ==1 + S_out.Baseline = 'none'; + gui_baseline.lpa_baseline_custom.Enable = 'Off'; + BaselineMethod = 'none'; + elseif Values_local_replace==2 + S_out.Baseline = 'pre'; + gui_baseline.lpa_baseline_custom.Enable = 'Off'; + BaselineMethod = 'pre'; + elseif Values_local_replace==3 + S_out.Baseline = 'post'; + gui_baseline.lpa_baseline_custom.Enable = 'Off'; + BaselineMethod = 'post'; + elseif Values_local_replace==4 + S_out.Baseline = 'whole'; + gui_baseline.lpa_baseline_custom.Enable = 'Off'; + BaselineMethod = 'whole'; + else + BaselineMethod = 'custom'; + gui_baseline.lpa_baseline_custom.Enable = 'On'; + end + erp_m_t_Baseline_period_gui(); + end + end + +%%--------------Custum define the baseline period-------------------------- + function Baseline_custom(source_custom,~) + S_out.Baseline = str2num(source_custom.String); + + if isempty(S_out.Baseline) || length(S_out.Baseline)==1 + msgboxText = {'Invalid Baseline range!';'Please enter two numeric values'}; + title = 'EStudio: Local peak amplitude setting'; + errorfound(msgboxText, title); + return; + end + %%Judge the upper/lower intervals + ERP = evalin('base','ERP'); + EpochStart = ERP.times(1); + EpochEnd = ERP.times(end); + if length(S_out.Baseline)==2 + if EpochStart > S_out.Baseline(1) || EpochEnd < S_out.Baseline(2) + msgboxText = {'For the defined two numeric values V1 and V2, where V1>=',num2str(EpochStart),',',32,'V2<=',num2str(EpochEnd)}; + title = 'EStudio: ERP measurement tool- baseline period'; + errorfound(msgboxText, title); + return; + end + end + BaselineInterval = S_out.Baseline; + BaselineMethod = 'custom'; + + end + +%%-----------------------Cancel section----------------------------------- + function Local_peak_cancel(Source_localp_cancel,~) + Values_localp_cancel = Source_localp_cancel.Value; + if ~isempty(Values_localp_cancel) + beep; + disp('User selected Cancel'); + close(f_localpeak); + return; + end + end +%%-----------------------Run selection------------------------------------- + function Local_peak_run(Source_localp_run,~) + Values_localp_run = Source_localp_run.Value; + if ~isempty(Values_localp_run) + S_ws = estudioworkingmemory('geterpvalues'); + + S_ws.Baseline = S_out.Baseline; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + + close(f_localpeak); + return; + end + end +%%%Program end +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_checkerpsets.m b/studio_functions/Functions/EStudio/ERP Tab/f_checkerpsets.m new file mode 100755 index 00000000..7d489941 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_checkerpsets.m @@ -0,0 +1,249 @@ +% PURPOSE : Checking if the number of bins/channels and data type for different ERPsets +% +% FORMAT : +% +% chkerp = f_checkerpsets(ALLERP,indexerp) + +% INPUTS : +% +% ALLERP - structure array of ERP structures (ERPsets) +% To read the ERPset from a list in a text file, +% replace ALLERP by the whole filename. +% +% indexerp - The labels of the selected ERPsets that are to be checked. +% Any label in indexerp should be no more than the length of ALLERPsets. +% If indexerp is empty, all ERPsets will be checked +% +% +%OUTPUT : +% +%chkerp - If either the number of bins/channels or data type varies +% across the selected ERPsets, chkerp will be larger than 0. +% +% +%Example : +% +%chkerp = f_checkerpsets(ALLERP,[1 3 5]); + +% +% ***This function is part of ERP Studio Toolbox*** +% Author: Guanghui ZHANG & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA, USA +% Feb. 2022 + + + +function chkerp = f_checkerpsets(ALLERP,indexerp) + +chkerp = [0 0 0 0 0 0 0]; % no problem + +if nargin <1 + help f_checkerpsets + return; +end + +if nargin ==1 + if ~isstruct(ALLERP) + msgboxText = 'ALLERP is empty'; + title = 'EStudio: f_checkerpsets'; + errorfound(msgboxText, title); + end +end + +if nargin < 2 + indexerp = [1:length(ALLERP)]; +else + if isempty(indexerp) + % msgboxText = 'The index of the checked ERPsets is not numeric'; + % title = 'EStudio: f_checkerpsets'; + % errorfound(msgboxText, title); % not numeric + return; + end +end + +if length(indexerp)==1 + % beep; + chkerp = [0 0 0 0 0 0 0]; + % msgboxText = 'Only one ERPset was checked!'; + % disp(msgboxText); % not numeric + return; + +end + + +nerp = length(ALLERP); + +if max(indexerp)>nerp + % msgboxText = ['ERPset indexing out of range!'... + % 'You only have ' num2str(nerp) ' ERPsets loaded on your ERPset Menu.']; + % % chkerp = 2; % indexing out of range + % title = 'EStudio: f_checkerpsets'; + % errorfound(msgboxText, title); + return +end + + + +if min(indexerp)<1 + msgboxText = ['Invalid ERPset indexing!'... + 'You may use any integer value between 1 and ',32, num2str(nerp)]; + % chkerp = 3; % indexing lesser than 1 + title = 'EStudio: f_checkerpsets'; + errorfound(msgboxText, title); + return +end + +nerp2 = length(indexerp);%% the length of the checked ERPsets + + + +%%-------get the number of bins/channels/datatype for each subject--------- +for k=1:nerp2 + try + kbin(k) = ALLERP(indexerp(k)).nbin; + kchan(k) = ALLERP(indexerp(k)).nchan; + kdtype{k} = ALLERP(indexerp(k)).datatype; + kdlength(k) = ALLERP(indexerp(k)).pnts; + kstartepoch(k) = ALLERP(indexerp(k)).times(1); + kendepoch(k) = ALLERP(indexerp(k)).times(end); + ksrate(k) = ALLERP(indexerp(k)).srate; + catch + msgboxText = ['ERPset',32,num2str(k),32,'has a invalid number of bins/channels/samples or different data type.']; + % chkerp = 4; % invalid number of bins/channel + disp(msgboxText); + break; + end +end + +% if chkerp==4 +% return +% end + +%%--------------------------check the number of bins----------------------- +bintest = length(unique(kbin)); +if bintest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g = %g bins\n', indexerp(j),ALLERP(indexerp(j)).nbin) + end + msgboxText = ['Number of bins across ERPsets is different!'... + 'See detail at command window']; + disp(msgboxText); + chkerp(1) = 1; % Number of bins across ERPsets is different! + % return + % else + % nbin = unique_bc2(kbin); +end + + +%%---------------------------check the number of channels------------------ +chantest = length(unique(kchan)); +if chantest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g = %g channnels\n', indexerp(j),ALLERP(indexerp(j)).nchan) + end + msgboxText = ['Number of channels across ERPsets is different!'... + 'See detail at command window.']; + disp(msgboxText); + chkerp(2) = 2; % Number of channels across ERPsets is different + % return +else + nchan = unique_bc2(kchan); +end + + +%%-------------------check the type of different ERPsets------------------- +dtypetest = length(unique(kdtype)); + +if dtypetest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g has data type ''%s''\n', indexerp(j),ALLERP(indexerp(j)).datatype) + end + beep; + msgboxText = ['Type of data across ERPsets is different!'... + 'See detail at command window.']; + disp(msgboxText); + chkerp(3) = 3; % data type across ERPsets is different + % return +end + + +%-----------------------check the length of ERPsets---------------------- +dlengthtest = length(unique(kdlength)); +if dlengthtest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g = %g time samples\n', indexerp(j),ALLERP(indexerp(j)).pnts) + end + msgboxText = ['Number of samples across ERPsets is different!'... + 'See detail at command window.']; + disp(msgboxText); + chkerp(4) = 4; % data type across ERPsets is different + % return +end + + +%-----------------------check the start time of epoch for the selected ERPsets---------------------- +dlengthtest = length(unique(kstartepoch)); +if dlengthtest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g = %g start time of epoch\n', indexerp(j),kstartepoch(j)) + end + msgboxText = ['Start time of epoch across ERPsets is different!'... + 'See detail at command window.']; + disp(msgboxText); + chkerp(5) = 5; % data type across ERPsets is different + % return +end + + +%-----------------------check the start time of epoch for the selected ERPsets---------------------- +dlengthtest = length(unique(kendepoch)); +if dlengthtest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g = %g end time of epoch\n', indexerp(j),kendepoch(j)) + end + msgboxText = ['End time of epoch across ERPsets is different!'... + 'See detail at command window.']; + disp(msgboxText); + chkerp(6) = 6; % data type across ERPsets is different + % return +end + + + +%-----------------------check sampling rate the selected ERPsets---------------------- +dlengthtest = length(unique(ksrate)); +if dlengthtest>1 + fprintf('Detail:\n') + fprintf('-------\n') + + for j=1:nerp2 + fprintf('Erpset #%g = %g end time of epoch\n', indexerp(j),ksrate(j)) + end + msgboxText = ['Sampling rate across ERPsets is different!'... + 'See detail at command window.']; + disp(msgboxText); + chkerp(7) = 7; % data type across ERPsets is different + % return +end + +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_dq_summary.m b/studio_functions/Functions/EStudio/ERP Tab/f_dq_summary.m new file mode 100755 index 00000000..df39b91c --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_dq_summary.m @@ -0,0 +1,85 @@ +% Write data quality summary to Matlab Command Window +% axs April 2022, ERPLAB + + +function ERP_summary = f_dq_summary(ERP,dq_subfield_name) + +% Check and populate missing args +if exist('ERP','var') == 0 || isempty(ERP) + ERP = evalin('base','ERP'); +end + +if exist('dq_subfield_name','var') == 0 || isempty(dq_subfield_name) + dq_subfield_name = 'aSME'; +end + +if isfield(ERP,'dataquality') == 0 +% beep; +% warning('No Dataquality measures here'); + return; +end + +dq_measure_n = numel(ERP.dataquality); +if dq_measure_n == 1 + if isequal(ERP.dataquality(1).type,'empty') +% beep; +% disp('No Data Quality measures here') + else + dq_subfield = 1; + end +else + for i=1:dq_measure_n + dq_names{i} = ERP.dataquality(i).type; + end + if any(strcmpi(dq_names,dq_subfield_name)) + dq_subfield = find(strcmpi(dq_names,dq_subfield_name) == 1); + else +% beep; + disp('Could not find aSME here'); + return + end + +end +ERP_summary = {0 0 0; 0 0 0; [0 0] [0 0] [0 0]; 0 0 0}; +try +dq_data = ERP.dataquality(dq_subfield).data; + +if any(isnan(dq_data(:))) + beep; +% disp('Warning - NaNs in Data Quality measures') + return; +end + +if isempty(dq_data) +% beep; +% disp('Warning - No value was found in Data Quality measures') + return; +end +median_here = median(dq_data(:),'omitnan'); +[dist, median_loc_i] = min(abs(dq_data(:)-median_here)); +[med_elec,med_tw,med_bin] = ind2sub(size(dq_data),find(dq_data == dq_data(median_loc_i))); + +min_here = min(dq_data(:)); +[min_elec,min_tw,min_bin] = ind2sub(size(dq_data),find(dq_data == min_here)); + +max_here = max(dq_data(:)); +[max_elec,max_tw,max_bin] = ind2sub(size(dq_data),find(dq_data == max_here)); + +ERP_summary{1,1} = dq_data(median_loc_i); +ERP_summary{1,2} = min_here; +ERP_summary{1,3} = max_here; + +ERP_summary{2,1} = med_elec; +ERP_summary{2,2} = min_elec; +ERP_summary{2,3} = max_elec; + +ERP_summary{3,1} = [ERP.dataquality(dq_subfield).times(med_tw,1),ERP.dataquality(dq_subfield).times(med_tw,2)]; +ERP_summary{3,2} = [ERP.dataquality(dq_subfield).times(min_tw,1),ERP.dataquality(dq_subfield).times(med_tw,2)]; +ERP_summary{3,3} = [ERP.dataquality(dq_subfield).times(max_tw,1),ERP.dataquality(dq_subfield).times(max_tw,2)]; + +ERP_summary{4,1} = med_bin; +ERP_summary{4,2} = min_bin; +ERP_summary{4,3} = max_bin; + +catch +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_erp_remv_Calibrate.m b/studio_functions/Functions/EStudio/ERP Tab/f_erp_remv_Calibrate.m new file mode 100755 index 00000000..529e409c --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_erp_remv_Calibrate.m @@ -0,0 +1,53 @@ +% This function is to remove calibration when importing ERPSS files + + +% +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + +function ALLERP = f_erp_remv_Calibrate(ALLERP, ERP_index) + +if nargin<1 + help f_erp_remv_Calibrate + return +end +if nargin<2 + nfile = [1:length(ALLERP)]; +end +nfile = ERP_index; + +for i=1:numel(nfile) + ERP = ALLERP(nfile(i)); + try%Remove the bin with Caliration GH 2022 + binNum = length(ERP.bindescr); + count = 0; + Calib_ind = []; + for jj = 1:binNum + if strcmp(ERP.bindescr{jj},'Calibration') + count = count+1; + Calib_ind(count) = jj; + end + end + bin_remd = setdiff([1:binNum],Calib_ind); + Bindescr =ERP.bindescr; + for kk = 1:numel(bin_remd) + Bindescr_keep{kk} = Bindescr{bin_remd(kk)}; + end + ERP.bindescr = Bindescr_keep; + ERP.nbin = numel(bin_remd); + ERP.bindata = ERP.bindata(:,:,bin_remd); + catch + ERP =ERP; + end + + ALLERP(nfile(i)) = ERP; + clear ERP; + clear Bindescr_keep; +end + + +return + diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_erpset_geterpvalues.m b/studio_functions/Functions/EStudio/ERP Tab/f_erpset_geterpvalues.m new file mode 100755 index 00000000..af5abba4 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_erpset_geterpvalues.m @@ -0,0 +1,289 @@ +% PURPOSE: Finding the users defined path to save the file + + +% [S S_out]= f_erpset_geterpvalues(varargin) + + + + + +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + + +function S_out= f_erpset_geterpvalues(varargin); + +if nargin<1 + help f_erpset_geterpvalues + return +end +S_out = {}; + +if isempty(varargin) + CurrentERPSet = evalin('base','CURRENTERP'); + Current_ERP= evalin('base','ERP'); + %Adding chanArray + erpset = num2str(CurrentERPSet); + if ~exist('S','var') + S_in = {}; + erpvalues_variables = {'geterpvalues','latency','',... + 'binArray',[1:Current_ERP.nbin],... + 'chanArray', [1:Current_ERP.nchan],... + 'Erpsets', erpset,... + 'Measure','meanb1',... + 'Component',0,... + 'Resolution', [3],... + 'Baseline', 'pre',... + 'Binlabel', 'on',... + 'Peakpolarity','positive',... + 'Neighborhood', 5,... + 'Peakreplace', 'absolute',... + 'Filename', '',... + 'Warning','on',... + 'SendtoWorkspace', 'on',... + 'Append', '',... + 'FileFormat', 'wide',... + 'Afraction',0.5,... + 'Mlabel', '',... + 'Fracreplace', 'errormsg',... + 'IncludeLat', '',... + 'InterpFactor', 1,... + 'Viewer', 'off',... + 'PeakOnset',1,... + 'History', ''}; + S_OUT = createrplabstudioparameters(S_in,erpvalues_variables); + assignin('base','S',S_OUT); + S_out = S_OUT.geterpvalues; + else %%If the S exists in the MATLAB workspace + + S_IN = evalin('base','S'); + count_geterpvalues = f_findstring(S_IN,'geterpvalues'); + + if count_geterpvalues ==1 + S_out = S_IN.geterpvalues; + else + + erpvalues_variables = {'geterpvalues','latency','',... + 'binArray',[1:Current_ERP.nbin],... + 'chanArray', [1:Current_ERP.nchan],... + 'Erpsets', erpset,... + 'Measure','meanb1',... + 'Component',0,... + 'Resolution', [3],... + 'Baseline', 'pre',... + 'Binlabel', 'on',... + 'Peakpolarity','positive',... + 'Neighborhood', 5,... + 'Peakreplace', 'absolute',... + 'Filename', '',... + 'Warning','on',... + 'SendtoWorkspace', 'on',... + 'Append', '',... + 'FileFormat', 'wide',... + 'Afraction',0.5,... + 'Mlabel', '',... + 'Fracreplace', 'errormsg',... + 'IncludeLat', '',... + 'InterpFactor', 1,... + 'Viewer', 'off',... + 'PeakOnset',1,... + 'History', '',... + 'ERPselect',1}; + S_OUT = createrplabstudioparameters(S_IN,erpvalues_variables); + assignin('base','S',S_OUT); + S_out = S_OUT.geterpvalues; + end + + end +end + +if ~isempty(varargin) + S_out = varargin{1}; +end + +f_erpset_selection = figure( 'Name', 'ERP Measurement Tool', ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off'); +f_erpset_selection.Position(3:4) = [300 150]; + +Current_ERPset = evalin('base','CURRENTERP'); +ALLERP = evalin('base','ALLERP'); +ERP_selection_label = [1 0 0]; + +erpset_selection_gui() + + + function erpset_selection_gui() + b1 = uiextras.VBox( 'Parent', f_erpset_selection); + + b11 = uiextras.HBox( 'Parent', b1 ); + + b111 = uicontrol('Style','text','Parent', b11,'String','ERPset setting','fontsize',12);%,'FontWeight', 'bold'); + + %%------------------------------------------------------------------- + b12 = uiextras.HBox( 'Parent', b1 ); + + + %%--------------------------Current ERPset------------------------------ + b112= uicontrol('Style','radiobutton','Parent',b12,'String',['Current ERPSet:',32,'[',num2str(Current_ERPset),']',32,ALLERP(Current_ERPset).erpname],'callback',@currenterpset_toggle); % 1B + uiextras.Empty('Parent',b12); + + set(b12,'Sizes',[250 50]); + b_nonzero = find(ERP_selection_label); + + if ~isempty(b_nonzero) + if ~ERP_selection_label(1) + % set(b112,'enable','off', 'ForegroundColor', [.5 0.5 0.5]); + else + set(b112,'value',ERP_selection_label(1) ,'enable','on'); + end + end + %%------------------From Checked ERPsets----------------------------------- + b14 = uiextras.HBox( 'Parent', b1); + + b141 = uicontrol('Style','radiobutton','Parent', b14,'String','Checked ERPsets','callback',@erpset_checked);%,'HandleVisibility','off' + + b142 = uicontrol('Style','pushbutton','Parent', b14,'String','Options'); + if ~isempty(b_nonzero) + if ~ERP_selection_label(2) + % set(b141,'enable','off', 'ForegroundColor', [.5 0.5 0.5]); + set(b142,'enable','off', 'ForegroundColor', [.5 0.5 0.5]); + else + set(b141,'enable','on','value',ERP_selection_label(2) ); + end + end + %%----------------------------ERPsets menu--------------------------------- + b15 = uiextras.HBox( 'Parent', b1); + + b151 = uicontrol('Style','radiobutton','Parent', b15,'String','From ERPset menu','callback',@erpset_menu); + + b152 = uicontrol('Style','pushbutton','Parent', b15,'String','Options','callback',@erpset_menu_select); + + if ~isempty(b_nonzero) + if ~ERP_selection_label(3) + % set(b151,'enable','off', 'ForegroundColor', [.5 0.5 0.5]); + set(b152,'enable','off', 'ForegroundColor', [.5 0.5 0.5]); + else + set(b151,'value',ERP_selection_label(3) ,'enable','on'); + end + end + %%------------------------Cancel and Run---------------------------------- + b16 = uiextras.HBox( 'Parent', b1); + uicontrol( 'Parent', b16, 'String', 'Cancel','callback',@Local_cancel); + uicontrol( 'Parent', b16, 'String', 'Run','callback',@Local_run); + end + + +%%*********************************************************************** +%%****************** subfunctions *********************************** +%%*********************************************************************** + +%%------------------------Current ERPset----------------------------------- + function currenterpset_toggle(source_current_erp,~) + value_currenterp = source_current_erp.Value; + if value_currenterp ==1 + ERP_selection_label(1) = value_currenterp; + ERP_selection_label(2:end) =0; + elseif value_currenterp == 0 + ERP_selection_label(1:end) =0; + end + erpset_selection_gui(); + S_out.Erpsets = Current_ERPset; + end + + +%%------------------------Checked ERPset----------------------------------- + function erpset_checked(Source_checked_ERP,~) + + value_checkederp = Source_checked_ERP.Value; + + if value_checkederp ==1 + ERP_selection_label(2) = value_checkederp; + ERP_selection_label([1 3]) =0; + elseif value_checkederp == 0 + ERP_selection_label(1:end) =0; + end + erpset_selection_gui(); + + end + +%%-----------------------ERPsets from menu--------------------------------- + function erpset_menu(Source_erp_menu,~) + value_currenterp = Source_erp_menu.Value; + if value_currenterp ==1 + ERP_selection_label(3) = value_currenterp; + ERP_selection_label([1 2]) =0; + S_out.Erpsets = [1:length(ALLERP)]; + elseif value_currenterp == 0 + ERP_selection_label(1:end) =0; + end + erpset_selection_gui(); + end + +%%------------Select the ERPsets of interest from menu--------------------- + function erpset_menu_select(~,~) + + if ~isempty(ALLERP) + for Numoferpset = 1:length(ALLERP) + listb{Numoferpset}= ['Erpset',32,num2str(Numoferpset),':',32,ALLERP(Numoferpset).erpname]; + end + indxlistb = 1:length(ALLERP); + titlename = 'Select ERPset(s):'; + + chan_label_select = browsechanbinGUI(listb, indxlistb, titlename); + + if ~isempty(chan_label_select) + S_out.Erpsets = chan_label_select; + + if length(chan_label_select) ==1 + disp(['ERPset(s):',num2str(chan_label_select),32,'will be used for next analysis']) + else + disp(['ERPset(s):',num2str(chan_label_select(1:end-1)),32,'and',32,num2str(chan_label_select(end)),32,'will be used for next analysis']) + end + else + beep; + disp('User selected Cancel') + return + end + + else + msgboxText = 'No ERPset information was found'; + title = 'EStudio: ERP measurement tool input'; + errorfound(msgboxText, title); + return; + end + end + +%%-------------------Cancel---------------------------------------------- + function Local_cancel(Source_localp_cancel,~) + Values_localp_cancel = Source_localp_cancel.Value; + if ~isempty(Values_localp_cancel) + beep; + disp('User selected Cancel'); + close(f_erpset_selection); + S.geterpvalues = S_out; + % varargout{1} = S_out; + return; + end + end +%%-----------------------Run----------------------------------------------- + function Local_run(Source_localp_run,~) + Values_localp_run = Source_localp_run.Value; + if ~isempty(Values_localp_run) + + S= evalin('base','S'); + S.geterpvalues = S_out; + assignin('base','S',S); + close(f_erpset_selection); + % return; + end + end +%%%Program end +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_findstring.m b/studio_functions/Functions/EStudio/ERP Tab/f_findstring.m new file mode 100755 index 00000000..49248e15 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_findstring.m @@ -0,0 +1,43 @@ +% This function is written to check if the string of interest exists in the parent structure +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA +%Feb. 2022 + +% ERPLAB Studio + + +function count = f_findstring(Parent_Structure,String_checked) + +if isempty(Parent_Structure) + msgboxText = 'Parent structure is empty!'; + title = 'EStudio: findstring()'; + errorfound(msgboxText, title); + return; +end + +if isempty(String_checked) + msgboxText = 'The string that to be checked is empty!'; + title = 'EStudio: findstring()'; + errorfound(msgboxText, title); + return; +end +field_Names = fieldnames(Parent_Structure); + +if isempty(field_Names) + msgboxText = 'No field name was found in the parent structure!'; + title = 'EStudio: findstring()'; + errorfound(msgboxText, title); + return; +end + +count = 0; +for Numoffieldname = 1:length(field_Names) + code1 = strcmp(field_Names{Numoffieldname},String_checked); + if code1 ==1 + count =count+1; + end +end + +return; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_getFFTfromERP.m b/studio_functions/Functions/EStudio/ERP Tab/f_getFFTfromERP.m new file mode 100755 index 00000000..0bdb14ba --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_getFFTfromERP.m @@ -0,0 +1,79 @@ +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon and Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2014 & 2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function ERP = f_getFFTfromERP(ERP,iswindowed) + + +if nargin<1 + help f_getFFTfromERP + return; +end + + +if nargin<2 + iswindowed =0; +end +fnyqx = round(ERP.srate/2); +NFFT = 2.^nextpow2(4*fnyqx); +NFFT = NFFT*2; +fs = ERP.srate; +fnyq = fs/2; +nbin = ERP.nbin; +nchan = ERP.nchan; +freq = fnyq*linspace(0,1,NFFT/2); +data4fft = zeros(nchan, NFFT/2, nbin); + +for k=1:nbin + % [freq, data4fft(:,:,k)] = getTrialFFT(ERP.bindata(:,:,k), ERP.srate, 2*nfft, iswindowed); % FFT + datax = ERP.bindata(:,:,k); + L = size(datax,2); + %nchan = size(datax,1); + %FFTdata = zeros(nchan, NFFT/2); + y = datax'; + if iswindowed + y = y.*repmat(hamming(size(y,1)),1,size(y,2)); % data tapered with a Hamming window. + end + Y = fft(y,NFFT)'/L; + fftepo = Y(:,1:NFFT/2); % Complex values + + if rem(NFFT, 2) % odd NFFT excludes Nyquist point + fftepo(:, 2:end) = fftepo(:, 2:end).*2; + else + fftepo(:, 2:end-1) = fftepo(:, 2:end-1).*2; + end + data4fft(:,:,k) = fftepo; +end +ERP.bindata = data4fft; +ERP.binerror = []; +%ERP.pnts = size(ERP.bindata, 2); +ERP.times = freq; +ERP.xmin = min(ERP.times); +ERP.xmax = max(ERP.times); +ERP.datatype = 'EFFT'; + +ERP.pnts = size(ERP.bindata, 2); \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_get_erp_xticklabel_time.m b/studio_functions/Functions/EStudio/ERP Tab/f_get_erp_xticklabel_time.m new file mode 100755 index 00000000..29e17c0d --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_get_erp_xticklabel_time.m @@ -0,0 +1,178 @@ + +% PURPOSE : form the time points based on the defined time range and xtick range; +% +% FORMAT : +% +% [xtick_time, bindata] = f_get_erp_xticklabel_time(ERP, timerange,xtickrange) + +% +% +% INPUTS : +%ERP - ERP structures (ERPsets) + +%timerange - time range where we want to display the wave e.g., [-200 800]. +% In fact, it is fixed that is equal to [ERP.time(1),ERP.times(end)]. + +%xtickrange - x-axis limits, e.g., [-300 900] + +% OUTPUTS : +% +%xtick_time: includes the sampling points for the x-axis limits +%bindata: the length of the "bindata" is equal to that of xtickrange. + + + +% *** This function is part of EStudio Toolbox *** +% Author: Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function [xtick_time, bindata] = f_get_erp_xticklabel_time(ERP, timerange,xtickrange) + + +if nargin<1 + xtick_time = []; + bindata = []; + return; +end + +if nargin<2 + timerange(1) = ERP.times(1); + timerange(2) = ERP.times(end); +end + +if numel(timerange) ==1 + xtick_time = []; + bindata = []; + return; +end + + +if timerange(1)>= timerange(2) + xtick_time = []; + bindata = []; + return; +end + + + +if nargin<3 + xtickrange(1) = ERP.times(1); + xtickrange(2) = ERP.times(end); +end + + +if numel(xtickrange) ==1 + xtick_time = []; + bindata = []; + return; +end + + +if xtickrange(1)>= xtickrange(2) + xtick_time = []; + bindata = []; + return; +end + +time_bin = 1000/ERP.srate; + +[xxx, latsamp, latdiffms] = closest(ERP.times, timerange); +time_range_times = ERP.times(latsamp(1):latsamp(2)); + + +if (xtickrange(1)< timerange(1)) && (xtickrange(2)<= timerange(2)) %% case 1 + [xxx, latsamp, latdiffms] = closest(ERP.times, [timerange(1) xtickrange(2)]); + xtick_time = ERP.times(latsamp(1):latsamp(2)); + for ii = 1:1000000 + xtick_time_first = xtick_time(1)-time_bin; + if xtickrange(1) <= xtick_time_first + xtick_time = [xtick_time_first,xtick_time]; + else + break; + end + end + +elseif (xtickrange(1)< timerange(1)) && (xtickrange(2)> timerange(2))%% case 2 + xtick_time = time_range_times; + for ii = 1:1000000% loop for the left edge + xtick_time_first = xtick_time(1)-time_bin; + if xtickrange(1) <= xtick_time_first + xtick_time = [xtick_time_first,xtick_time]; + else + break; + end + end + + for ii = 1:1000000%Loop for the right edge + xtick_time_last = xtick_time(end)+time_bin; + if xtickrange(2) >= xtick_time_last + xtick_time = [xtick_time,xtick_time_last]; + else + break; + end + end + + +elseif (xtickrange(1)>= timerange(1)) && (xtickrange(2)> timerange(2))%% case 3 + + [xxx, latsamp, latdiffms] = closest(ERP.times, [xtickrange(1) timerange(2)]); + xtick_time = ERP.times(latsamp(1):latsamp(2)); + + for ii = 1:1000000%Loop for the right edge + xtick_time_last = xtick_time(end)+time_bin; + if xtickrange(2) >= xtick_time_last + xtick_time = [xtick_time,xtick_time_last]; + else + break; + end + end + +elseif (xtickrange(1)>= timerange(1)) && (xtickrange(2)<= timerange(2))%%case 4: if the xtick range is within the defined time range + [xxx, latsamp, latdiffms] = closest(ERP.times, xtickrange); + xtick_time = ERP.times(latsamp(1):latsamp(2)); +end + +if abs(xtick_time(1))>abs(xtickrange(1))%%check the first element + xtick_time(1) = []; +end + +if abs(xtick_time(end))>abs(xtickrange(2))%% check the last element + xtick_time(end) = []; +end + +%%------------------------Adjust the data based on the xtick time range------------------------- +bindata = nan(size(ERP.bindata,1),numel(xtick_time),size(ERP.bindata,3)); + +if (xtickrange(1)< timerange(1)) && (xtickrange(2)<= timerange(2)) %% case 1 + [xxx, latsamp_xtick, latdiffms] = closest(xtick_time,[timerange(1),xtick_time(end)]); + [xxx, latsamp_time, latdiffms] = closest(ERP.times,[timerange(1),xtick_time(end)]); + bindata(:,latsamp_xtick(1):latsamp_xtick(2),:) = ERP.bindata(:,latsamp_time(1):latsamp_time(2),:); + +elseif (xtickrange(1)< timerange(1)) && (xtickrange(2)> timerange(2))%% case 2 + [xxx, latsamp_time, latdiffms] = closest(ERP.times,[timerange(1),timerange(end)]); + [xxx, latsamp_xtick, latdiffms] = closest(xtick_time,[ERP.times(latsamp_time(1)),ERP.times(latsamp_time(2))]); + bindata(:,latsamp_xtick(1):latsamp_xtick(2),:) = ERP.bindata(:,latsamp_time(1):latsamp_time(2),:); + +elseif (xtickrange(1)>= timerange(1)) && (xtickrange(2)> timerange(2))%% case 3 + [xxx, latsamp_xtick, latdiffms] = closest(xtick_time,[xtick_time(1),timerange(2)]); + [xxx, latsamp_time, latdiffms] = closest(ERP.times,[xtick_time(1),timerange(2)]); + if numel(latsamp_xtick(1):latsamp_xtick(2)) -numel(latsamp_time(1):latsamp_time(2)) ==1 + latsamp_xtick(2) = latsamp_xtick(2)-1; + end + + bindata(:,latsamp_xtick(1):latsamp_xtick(2),:) = ERP.bindata(:,latsamp_time(1):latsamp_time(2),:); + +elseif (xtickrange(1)>= timerange(1)) && (xtickrange(2)<= timerange(2))%%case 4: if the xtick range is within the defined time range + [xxx, latsamp, latdiffms] = closest(ERP.times, [xtick_time(1),xtick_time(end)]); + bindata= ERP.bindata(:,latsamp(1):latsamp(2),:); +end + + +end + + + diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_geterpxticklabel.m b/studio_functions/Functions/EStudio/ERP Tab/f_geterpxticklabel.m new file mode 100755 index 00000000..5ca330e8 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_geterpxticklabel.m @@ -0,0 +1,109 @@ + +%%This function is to get the xticks and xtick lables if we plot the +%%waveform with two or more columns. + + +% *** This function is part of EStudio Toolbox *** +% Author: Guanghui ZHANG & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + + +function [xtickout,xticklabelout] = f_geterpxticklabel(ERP,xticks_clomn,columNum,timeRange,Timet_step) + +xtickout = []; +xticklabelout = []; +if nargin<2 + help f_geterpxticklabel + return; +end + +if nargin<3 + columNum =1; +end + +%-- only display the waveform within the defined time range, e.g., [-200 800] +if nargin<4 + timeRange(1) = ERP.times(1); + timeRange(2) = ERP.times(end); +end + +if isempty(timeRange) || numel(timeRange) ==1 + timeRange(1) = ERP.times(1); + timeRange(2) = ERP.times(end); +end + + +try + tbin = 1000/ERP.srate; +catch + + disp('Sampling rate should be greater than 0 Hz'); + return; +end + +if nargin <5 + xticks_clomn = []; + [def Timet_step]= default_time_ticks_studio(ERP, timeRange); +end +% if ~isempty(def) +% xticks_clomn = str2num(def{1,1}); +% while xticks_clomn(end)<=timeRange(2) +% xticks_clomn(numel(xticks_clomn)+1) = xticks_clomn(end)+Timet_step; +% if xticks_clomn(end)>timeRange(2) +% xticks_clomn = xticks_clomn(1:end-1); +% break; +% end +% end +% end + +[xtick_time, Bindata] = f_get_erp_xticklabel_time(ERP, [ERP.times(1), ERP.times(end)],timeRange); + + +% Timet_step_pt = ceil(Timet_step/tbin); + +timeRange_start = timeRange(1); +timeRange_end = timeRange(2); +if timeRange_start>0 + timeRange_start = ceil(timeRange_start); + timeRange_end = ceil(timeRange_end); +elseif timeRange_start<0 + timeRange_start = floor(timeRange_start); + timeRange_end = floor(timeRange_end); +end +try +Time_reso = 1000/ERP.srate; +catch + Time_reso = 1; +end +Timet_step_p = ceil(Timet_step/Time_reso); + +if ~isempty(xticks_clomn) + + if columNum==1 + xtickout = xticks_clomn; + for Numofxlabel = 1:numel(xticks) + xticklabelout{Numofxlabel} = num2str(xticks(Numofxlabel)); + end + elseif columNum>1 + + xtickout = xticks_clomn; + + for Numofcolumn = 1:columNum-1 +% xtickout = [xtickout,ones(1,numel(xticks_clomn))*(xtickout(end)+timeRange_end-xticks_clomn(end) +Timet_step) + (xticks_clomn-timeRange_start)+Numofcolumn*tbin]; + xtickout = [xtickout,xticks_clomn+ Numofcolumn*(xtick_time(end)-xtick_time(1)+(Timet_step_p+1)*Time_reso)];%%changed by Guanghui Oct 2022 + end + + count = 0; + for Numofcolumn = 1:columNum + for Numofxlabel = 1:numel(xticks_clomn) + count = count +1; + xticklabelout{count} = num2str(xticks_clomn(Numofxlabel)); + end + end + end +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP.m b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP.m new file mode 100755 index 00000000..b6b2ec98 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP.m @@ -0,0 +1,1027 @@ +%This function is to plot ERP waves with single or multiple columns on one page. + + + +% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + +function f_redrawERP() +% Draw a demo ERP into the axes provided +global observe_ERPDAT; +global EStudio_gui_erp_totl; +% addlistener(observe_ERPDAT,'Messg_change',@Count_Process_messg_change); + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +S_ws_geterpplot = estudioworkingmemory('geterpplot'); + + +%%Parameter from bin and channel panel +% Elecs_shown = estudioworkingmemory('ChanShow'); +Elecs_shown = S_ws_getbinchan.elecs_shown{S_ws_getbinchan.Select_index}; +% if isempty(Elecs_shown) || max(Elecs_shown)> numel(Elecs_shown_all) +% Elecs_shown = Elecs_shown_all; +% end +Bins = S_ws_getbinchan.bins{S_ws_getbinchan.Select_index}; +try + Bin_chans = S_ws_getbinchan.bins_chans(S_ws_getbinchan.Select_index); +catch + Bin_chans = 0; +end +Elec_list = S_ws_getbinchan.elec_list{S_ws_getbinchan.Select_index}; + +Matlab_ver = S_ws_getbinchan.matlab_ver; +%%Parameter from plotting panel +try + Min_vspacing = S_ws_geterpplot.min_vspacing(S_ws_getbinchan.Select_index); + Min_time = S_ws_geterpplot.min(S_ws_getbinchan.Select_index); + Max_time = S_ws_geterpplot.max(S_ws_getbinchan.Select_index); + Yscale = S_ws_geterpplot.yscale(S_ws_getbinchan.Select_index); + Timet_low =S_ws_geterpplot.timet_low(S_ws_getbinchan.Select_index); + Timet_high =S_ws_geterpplot.timet_high(S_ws_getbinchan.Select_index); + Timet_step=S_ws_geterpplot.timet_step(S_ws_getbinchan.Select_index); + Fill = S_ws_geterpplot.fill(S_ws_getbinchan.Select_index); + Plority_plot = S_ws_geterpplot.Positive_up(S_ws_getbinchan.Select_index); + % ColumnNum = S_ws_geterpplot.Plot_column; + ColumnNum = estudioworkingmemory('EStudioColumnNum'); + if isempty(ColumnNum) || numel(ColumnNum)~=1 + ColumnNum =1; + end + +catch + return; +end + +Column_label = ColumnNum; + +if Bin_chans == 0 + elec_n = numel(Elecs_shown); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nchan; +else + elec_n = S_ws_getbinchan.bin_n(S_ws_getbinchan.Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nbin; +end + +% We first clear the existing axes ready to build a new one +if ishandle( EStudio_gui_erp_totl.ViewAxes ) + delete( EStudio_gui_erp_totl.ViewAxes ); +end + + +% Get chan labels +S_chan.chan_label = cell(1,max_elec_n); +S_chan.chan_label_place = zeros(1,max_elec_n); + + +if Bin_chans == 0 + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.chanlocs(Elecs_shown(i)).labels; + end +else + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.bindescr(Bins(i)); + end +end + + +%Sets the units of your root object (screen) to pixels +set(0,'units','pixels') +%Obtains this pixel information +Pix_SS = get(0,'screensize'); +%Sets the units of your root object (screen) to inches +set(0,'units','inches') +%Obtains this inch information +Inch_SS = get(0,'screensize'); +%Calculates the resolution (pixels per inch) +Res = Pix_SS./Inch_SS; + + +pb_height = Min_vspacing*Res(4); %px + + +% Plot data in the main viewer fig +splot_n = elec_n; +tsize = 13; + + +clear pb r_ax plotgrid; +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;%%Get background color +catch + ColorB_def = [0.95 0.95 0.95]; +end +if isempty(ColorB_def) + ColorB_def = [0.95 0.95 0.95]; +end +EStudio_gui_erp_totl.plotgrid = uix.VBox('Parent',EStudio_gui_erp_totl.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorB_def); + +pageinfo_box = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid,'BackgroundColor',ColorB_def); + +EStudio_gui_erp_totl.plot_wav_legend = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid,'BackgroundColor',[1 1 1]); +EStudio_gui_erp_totl.ViewAxes_legend = uix.ScrollingPanel( 'Parent', EStudio_gui_erp_totl.plot_wav_legend,'BackgroundColor',ColorB_def); + +EStudio_gui_erp_totl.ViewAxes = uix.ScrollingPanel( 'Parent', EStudio_gui_erp_totl.plot_wav_legend,'BackgroundColor',[1 1 1]); + + +%%Changed by Guanghui Zhang 2 August 2022-------panel for display the processing procedure for some functions, e.g., filtering +xaxis_panel = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid,'BackgroundColor',ColorB_def);%%%Message +EStudio_gui_erp_totl.Process_messg = uicontrol('Parent',xaxis_panel,'Style','text','String','','FontSize',20,'FontWeight','bold','BackgroundColor',ColorB_def); + +% erpworkingmemory('EStudio_proces_messg',EStudio_gui_erp_totl); + +%%Setting title +EStudio_gui_erp_totl.pageinfo_minus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',{@page_minus,EStudio_gui_erp_totl},'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index ==1 + EStudio_gui_erp_totl.pageinfo_minus.Enable = 'off'; +end + +EStudio_gui_erp_totl.pageinfo_edit = uicontrol('Parent',pageinfo_box,'Style', 'edit', 'String', num2str(S_ws_getbinchan.Select_index),'Callback',{@page_edit,EStudio_gui_erp_totl},'FontSize',20,'BackgroundColor',[1 1 1]); + +if S_ws_getbinchan.Select_index ==1 + EStudio_gui_erp_totl.pageinfo_edit.Enable = 'on'; +end + +EStudio_gui_erp_totl.pageinfo_plus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',{@page_plus,EStudio_gui_erp_totl},'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index == numel(S_ws_geterpset) + EStudio_gui_erp_totl.pageinfo_plus.Enable = 'off'; +end + +pageinfo_str = ['Page',32,num2str(S_ws_getbinchan.Select_index),'/',num2str(numel(S_ws_geterpset)),':',32,observe_ERPDAT.ERP.erpname]; + +pageinfo_text = uicontrol('Parent',pageinfo_box,'Style','text','String',pageinfo_str,'FontSize',14,'FontWeight','bold'); + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [1 1 1]; + Enable_minus_BackgroundColor = [0 0 0]; +else + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; +EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; +EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +% EStudio_gui_erp_totl.pageinfo_edit.ForegroundColor = [1 1 1]; + +set(pageinfo_box, 'Sizes', [50 50 50 -1] ); +set(pageinfo_box,'BackgroundColor',ColorB_def); +set(pageinfo_text,'BackgroundColor',ColorB_def); +%Setting title. END,'BackgroundColor',ColorB_def + +%for i=1:splot_n + +% +%%------------Setting the number of data and plotting--------------------- +ndata = 0; +nplot = 0; +if Bin_chans == 0 %if channels with bin overlay + ndata = Bins; + nplot = Elecs_shown; +else %if bins with channel overlay + ndata = Elecs_shown; + nplot = Bins; +end + +% +timeor = observe_ERPDAT.ERP.times; % original time vector +timex = timeor; +[xxx, latsamp, latdiffms] = closest(timex, [Min_time Max_time]); +tmin = latsamp(1); +tmax = latsamp(2); + +if tmin < 1 + tmin = 1; +end + +if tmax > numel(observe_ERPDAT.ERP.times) + tmax = numel(observe_ERPDAT.ERP.times); +end + +[xtick_time, Bindata] = f_get_erp_xticklabel_time(observe_ERPDAT.ERP, [Min_time Max_time],[Timet_low,Timet_high]); + + +% plot_erp_data = nan(tmax-tmin+1,numel(ndata)); +plot_erp_data = []; +for i = 1:splot_n + if Bin_chans == 0 + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = Bindata(Elecs_shown(i),:,Bins(i_bin))'*Plority_plot; % + end + else + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = Bindata(Elecs_shown(i_bin),:,Bins(i))'*Plority_plot; % + end + end +end +if Yscale==0 + Yscale = max(abs(Bindata(:))); +end +perc_lim = Yscale; +percentile = perc_lim*3/2; +[~,~,b] = size(plot_erp_data); + + +% +%%%------------Setting xticklabels for each row of each wave-------------- +xstep_label = estudioworkingmemory('erp_xtickstep'); +if isempty(xstep_label) + xstep_label =0; +end +if ~xstep_label + [def Timet_step]= default_time_ticks_studio(observe_ERPDAT.ERP, [Timet_low,Timet_high]); + if ~isempty(def) + xticks_clomn = str2num(def{1,1}); + while xticks_clomn(end)<=Timet_high + xticks_clomn(numel(xticks_clomn)+1) = xticks_clomn(end)+Timet_step; + if xticks_clomn(end)>Timet_high + xticks_clomn = xticks_clomn(1:end-1); + break; + end + end + else + xticks_clomn = (Timet_low:Timet_step:Timet_high); + end +else + xticks_clomn = (Timet_low:Timet_step:Timet_high); +end + + +if strcmpi(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + xticks_clomn = [0:1]; +end + + +Timet_step_p = ceil(Timet_step/(1000/observe_ERPDAT.ERP.srate));%% Time points of the gap between columns +if ~strcmpi(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + % + %%----------------------Modify the data into multiple-columns--------------------------------------- + rowNum = ceil(b/Column_label); + plot_erp_data_new = NaN(size(plot_erp_data,1),size(plot_erp_data,2),rowNum*Column_label); + + plot_erp_data_new(:,:,1:size(plot_erp_data,3)) = plot_erp_data; + plot_erp_data_new_trans = []; + + + if Column_label==1 + for Numofrow = 1:rowNum + plot_erp_data_new_trans(:,:,:,Numofrow) = plot_erp_data_new(:,:,(Numofrow-1)*Column_label+1:Numofrow*Column_label); + end + + clear plot_erp_data; + plot_erp_data_new_trans = permute(plot_erp_data_new_trans,[1,3,2,4]) ; + plot_erp_data = reshape(plot_erp_data_new_trans,size(plot_erp_data_new_trans,1)*size(plot_erp_data_new_trans,2),size(plot_erp_data_new_trans,3),size(plot_erp_data_new_trans,4)); + + elseif Column_label>1 + + plot_erp_data_trans_clumns = NaN(size(plot_erp_data_new,1)*Column_label+(Column_label-1)*Timet_step_p,size(plot_erp_data_new,2),rowNum); + for Numofrow = 1:rowNum + Data_column = plot_erp_data_new(:,:,(Numofrow-1)*Column_label+1:Numofrow*Column_label); + for Numofcolumn = 1:Column_label + low_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+1+(Numofcolumn-1)*Timet_step_p; + high_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+(Numofcolumn-1)*Timet_step_p+size(plot_erp_data_new,1); + plot_erp_data_trans_clumns(low_interval:high_interval,:,Numofrow) = squeeze(Data_column(:,:,Numofcolumn)); + end + end + plot_erp_data = plot_erp_data_trans_clumns; + end + + ind_plot_height = percentile*2; % Height of each individual subplot + + offset = []; + if Bin_chans == 0 + offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height; + else + offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height; + end + [~,~,b] = size(plot_erp_data); + for i = 1:b + plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i); + end + + + + r_ax = axes('Parent', EStudio_gui_erp_totl.ViewAxes,'Color','none','Box','on','FontWeight','bold'); + hold(r_ax,'on'); + set(EStudio_gui_erp_totl.plot_wav_legend,'Sizes',[80 -10]); + r_ax_legend = axes('Parent', EStudio_gui_erp_totl.ViewAxes_legend,'Color','none','Box','off'); + hold(r_ax_legend,'on'); + + + try + f_bin = 1000/observe_ERPDAT.ERP.srate; + catch + f_bin = 1; + end + + ts = xtick_time; + ts_colmn = ts; + + % + %%------------------Adjust the data into multiple/single columns------------ + if Column_label>1 % Plotting waveforms with munltiple-columns + xticks_org = xticks_clomn; + for Numofcolumn = 1:Column_label-1 + xticks_clomn_add = [1:numel(ts)+Timet_step_p].*f_bin+(ts_colmn(end).*ones(1,numel(ts)+Timet_step_p)); + ts_colmn = [ts_colmn,xticks_clomn_add]; + end + + X_zero_line(1) =ts(1); + for Numofcolumn = 1:Column_label-1 + if Numofcolumn ==1 + X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin + (Timet_step_p/2)*f_bin; + else + X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin + (Timet_step_p)*f_bin; + end + end + + [xticks,xticks_labels] = f_geterpxticklabel(observe_ERPDAT.ERP,xticks_clomn,Column_label,[Timet_low,Timet_high],Timet_step); + ts = ts_colmn; + Timet_low= ts(1); + Timet_high= ts(end); + for ii =1:100 + if Timet_high size(line_colors,1) + line_colors = get_colors(numel(ndata)); + else + line_colors = line_colors(1:numel(ndata),:,:); + end + end + + if isempty(line_colors) + line_colors = get_colors(numel(ndata)); + end + + line_colors = repmat(line_colors,[splot_n 1]); %repeat the colors once for every plot + + % + %%------------Setting xticklabels for each row -------------- + x_axs = ones(size(new_erp_data,1),1); + for jj = 1:numel(offset)-1 + plot(r_ax,ts,x_axs.*offset(end),'color',[1 1 1],'LineWidth',1); + set(r_ax,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); + myX_Crossing = offset(jj); + props = get(r_ax); + + tick_bottom = -props.TickLength(1)*diff(props.YLim); + if abs(tick_bottom) > abs(Yscale)/5 + try + tick_bottom = - abs(Yscale)/5; + catch + tick_bottom = tick_bottom; + end + elseif abs(tick_bottom)1 + if numel(offset)==jj + kkkk = 1; + else + if abs(Timet_low - xticks(1)) > 1000/observe_ERPDAT.ERP.srate + kkkk = 1; + else + kkkk = 2; + end + end + for iCount = kkkk:nTicks + xtick_label = (props.XTickLabel(iCount, :)); + text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', 12, ... + 'FontName', props.FontName, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits, ... + 'FontWeight', 'bold'); + end + end + end + + + % + %%----------------Start:Remove xticks for the columns without waves in the last row------------------------- + Element_left = numel(nplot) - (ceil(numel(nplot)/Column_label)-1)*Column_label; + plot(r_ax,ts,x_axs.*offset(end),'color', [1 1 1],'LineWidth',1); + set(r_ax,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); + myX_Crossing = offset(end); + props = get(r_ax); + + tick_bottom = -props.TickLength(1)*diff(props.YLim); + if abs(tick_bottom) > abs(Yscale)/5 + try + tick_bottom = - abs(Yscale)/5; + catch + tick_bottom = tick_bottom; + end + elseif abs(tick_bottom)1 + for iCount = 1:ceil(nTicks/Column_label*Element_left) + xtick_label = (props.XTickLabel(iCount, :)); + text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', 12, ... + 'FontName', props.FontName, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits, ... + 'FontWeight', 'bold'); + end + end + %%--------------------------End:Remove xticks for the columns without waves in the last row------------------------- + + % + %%-----------------Get zeroline for each row----------------------------- + row_baseline = NaN(numel(ts),splot_n); + count = 0; + for Numofsplot = 0:splot_n-1 + for Numofcolumn = 1:Column_label + count = count +1; + if count> numel(nplot) + break; + end + low_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+1+(Numofcolumn-1)*Timet_step_p; + high_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+(Numofcolumn-1)*Timet_step_p+size(plot_erp_data_new,1); + row_baseline(low_interval:high_interval,Numofsplot+1) = ones(numel(low_interval:high_interval),1).*offset(Numofsplot+1); + end + end + + + % + %%-------------------------Plotting ERP waves----------------------------- + pb_here = plot(r_ax,ts, [new_erp_data],'LineWidth',1.5); + + set(r_ax, 'XTick', [], 'XTickLabel', []); + + % + %%----------------Marking 0 point (event-locked)-------------------------- + [xxx, latsamp_0, latdiffms_0] = closest(xticks, [0]); + if numel(offset)>1 + if latdiffms_0 ==0 + for Numofcolumn = 1:Column_label + xline(r_ax,xticks((Numofcolumn-1)*numel(xticks_clomn)+latsamp_0),'k-.','LineWidth',1);%%'Color',Marking start time point for each column + end + end + elseif numel(offset)==1 + + for Numofcolumn = 1:numel(nplot) + xline(r_ax,xticks((Numofcolumn-1)*numel(xticks_clomn)+latsamp_0),'k-.','LineWidth',1);%%'Color',Marking start time point for each column + end + end + % + yticks = -perc_lim:perc_lim:((2*percentile*b)-(2*perc_lim)); + ylabs = repmat([-perc_lim 0 perc_lim],[1,b]); + oldlim = [-percentile yticks(end)-perc_lim+percentile]; + top_vspace = max( max( new_erp_data))-oldlim(2); + bot_vspace = min( min( new_erp_data))-oldlim(1); + if top_vspace < 0 + top_vspace = 0; + end + + if bot_vspace > 0 + bot_vspace = 0; + end + newlim = oldlim + [bot_vspace top_vspace]; + set(r_ax,'XLim',[Timet_low,Timet_high],'Ylim',newlim); + + + % + %%--------------Setting color for each wave-------------------------- + % if Column_label>1 + % for i = 0:splot_n-1 + % r_ax.Children(end-i).Color = [1 1 1]; + % end + % end + + % for i = splot_n+1:numel(pb_here) + % pb_here(i).Color = line_colors((i-splot_n),:); + % end + for i = 1:numel(pb_here) + pb_here(i).Color = line_colors(i,:); + end + % + % for i = 1:splot_n-1 + % pb_here(i).Color = [0 0 0]; + % pb_here(i).LineWidth=.01; + % end + + + + + %%------------Marking start time point for each column--------------------- + if Column_label>1 + for ii = 2:numel(X_zero_line) + xline(r_ax,X_zero_line(ii), 'y--','LineWidth',2); + end + end + + for Numofplot = 1:size(row_baseline,2) + plot(r_ax,ts,row_baseline(:,Numofplot),'color',[0 0 0],'LineWidth',1.5); + end + ylabs = [fliplr(-perc_lim:-perc_lim:newlim(1)) ylabs(2:end-1) (yticks(end):perc_lim:newlim(2))-yticks(end)+perc_lim]; + yticks = [fliplr(-perc_lim:-perc_lim:newlim(1)) yticks(2:end-1) yticks(end):perc_lim:newlim(2)]; + + % + %%-------------Name of bin/channel for each subplot-------------------------- + if Column_label==1 + if numel(offset)>1 + count = 0; + for i = 0:numel(offset)-1 + leg_str = ''; + + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',strrep(Elec_list{Elecs_shown(count)},'_','\_')); + else + leg_str = sprintf('%s',strrep(observe_ERPDAT.ERP.bindescr{Bins(count)},'_','\_')); + end + catch + leg_str = ''; + end + text(r_ax,ts(1),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + end + end + + try + if Bin_chans == 0 + leg_str = sprintf('%s',strrep(Elec_list{Elecs_shown(end)},'_','\_')); + else + leg_str = sprintf('%s',strrep(observe_ERPDAT.ERP.bindescr{Bins(end)},'_','\_')); + end + catch%% + leg_str = ''; + end + + try + text(r_ax,ts(1),offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + catch + text(r_ax,ts(1),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end + else%% Getting y ticks and legends for multiple-columns + if numel(offset)>1 + count = 0; + for i = 0:numel(offset)-1 + leg_str = ''; + for Numofcolumn = 1: Column_label + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',strrep(Elec_list{Elecs_shown(count)},'_','\_')); + else + leg_str = sprintf('%s',strrep(observe_ERPDAT.ERP.bindescr{Bins(count)},'_','\_')); + end + catch + leg_str = ''; + end + if Numofcolumn ==1 + text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + else + text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + end + end + end + end + + + count = (numel(offset)-1)*Column_label; + leg_str = ''; + for Numofcolumn = 1:Column_label + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',strrep(Elec_list{Elecs_shown(count)},'_','\_')); + else + leg_str = sprintf('%s',strrep(observe_ERPDAT.ERP.bindescr{Bins(count)},'_','\_')); + end + catch%% + leg_str = ''; + end + try + + if Numofcolumn ==1 + text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + else + text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + end + catch + + if Numofcolumn ==1 + text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + else + text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end + % text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end + end + + end + % + + + % + %%-------------Setting x/yticks and ticklabels-------------------------------- + Ylabels_new = ylabs.*Plority_plot; + [~,Y_label] = find(Ylabels_new == -0); + Ylabels_new(Y_label) = 0; + % xticks = (Min_time:Timet_step:Max_time); + % some options currently only work post Matlab R2016a ,'XLim',[Min_time Max_time],'XLim',[Min_time Max_time] + if Matlab_ver >= 2016 + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','origin',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels); + else + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','bottom',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim, 'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels); + hline(0,'k'); % backup xaxis + end + % if Column_label>1 + % set(r_ax,'XGrid','on','YGrid','on');%,'XDir','reverse' + % end + set(r_ax, 'XTick', [], 'XTickLabel', [],'FontWeight', 'bold'); + r_ax.YAxis.LineWidth = 1.5; + hold(r_ax,'off'); + + + % + %%--------------------------Setting legend--------------------------------- + line_colors_ldg = erpworkingmemory('PWColor'); + if isempty(line_colors_ldg) + line_colors_ldg = get_colors(numel(ndata)); + end + + if size(line_colors_ldg,1)~= numel(ndata) + if numel(ndata)> size(line_colors_ldg,1) + line_colors_ldg = get_colors(numel(ndata)); + else + line_colors_ldg = line_colors_ldg(1:numel(ndata),:,:); + end + end + + for Numofplot = 1:size(plot_erp_data,2) + plot(r_ax_legend,[0 0],'Color',line_colors_ldg(Numofplot,:,:),'LineWidth',3) + end + + if Bin_chans == 0 + Leg_Name = {}; + for Numofbin = 1:numel(Bins) + Leg_Name{Numofbin} = strcat('Bin',num2str(Bins(Numofbin))); + end + else + for Numofchan = 1:numel(Elecs_shown) + Leg_Name{Numofchan} = strrep(Elec_list{Elecs_shown(Numofchan)},'_','\_'); + end + end + legend(r_ax_legend,Leg_Name,'FontSize',14,'TextColor','blue'); + legend(r_ax_legend,'boxoff'); + EStudio_gui_erp_totl.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high + EStudio_gui_erp_totl.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high + EStudio_gui_erp_totl.plotgrid.Units = 'pixels'; + if splot_n*pb_height<(EStudio_gui_erp_totl.plotgrid.Position(4)-EStudio_gui_erp_totl.plotgrid.Heights(1))&&Fill + pb_height = (EStudio_gui_erp_totl.plotgrid.Position(4)-EStudio_gui_erp_totl.plotgrid.Heights(1)-EStudio_gui_erp_totl.plotgrid.Heights(2))/splot_n; + end + + EStudio_gui_erp_totl.ViewAxes.Heights = splot_n*pb_height; + EStudio_gui_erp_totl.plotgrid.Units = 'normalized'; +else + set(EStudio_gui_erp_totl.plot_wav_legend,'Sizes',[80 -10]); + EStudio_gui_erp_totl.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high + EStudio_gui_erp_totl.plotgrid.Heights(3) = 30; +end +% + +end % redrawDemo + + +function colors = get_colors(ncolors) +% Each color gets 1 point divided into up to 2 of 3 groups (RGB). +degree_step = 6/ncolors; +angles = (0:ncolors-1)*degree_step; +colors = nan(numel(angles),3); +for i = 1:numel(angles) + if angles(i) < 1 + colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75; + elseif angles(i) < 2 + colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75; + elseif angles(i) < 3 + colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75; + elseif angles(i) < 4 + colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75; + elseif angles(i) < 5 + colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75; + else + colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75; + end +end + +end + +%------------------Display the waveform for proir ERPset-------------------- +function page_minus(~,~,EStudio_gui_erp_totl) +global observe_ERPDAT; + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +EStudio_gui_erp_totl.pageinfo_edit.String = num2str(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); +% f_redrawERP(); +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; +EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; +EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_edit.String = num2str(S_ws_getbinchan.Select_index); + +MessageViewer= char(strcat('Plot prior page (<)')); +erpworkingmemory('f_ERP_proces_messg',MessageViewer); +observe_ERPDAT.Process_messg =1; +try + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; +catch + observe_ERPDAT.Process_messg =3; +end +observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; +end + +%%Edit the index of ERPsets +function page_edit(Str,~,EStudio_gui_erp_totl) +CurrentERPindex = str2num(Str.String); +global observe_ERPDAT; +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +if ~isempty(CurrentERPindex) && numel(CurrentERPindex)==1 && (CurrentERPindex<= numel(S_ws_geterpset)) + S_ws_getbinchan.Select_index = CurrentERPindex; + Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); + % EStudio_gui_erp_totl.pageinfo_edit.String = num2str(S_ws_getbinchan.Select_index); + if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; + end + observe_ERPDAT.CURRENTERP = Current_erp_Index; + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); + estudioworkingmemory('geterpbinchan',S_ws_getbinchan); + if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; + else + if CurrentERPindex ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [1 1 1]; + elseif CurrentERPindex == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end + end + EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; + EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; + EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; + EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + + MessageViewer= char(strcat('Page Editor')); + erpworkingmemory('f_ERP_proces_messg',MessageViewer); + observe_ERPDAT.Process_messg =1; + try + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + catch + observe_ERPDAT.Process_messg =3; + end +end +observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; +end + + +%------------------Display the waveform for next ERPset-------------------- +function page_plus(~,~,EStudio_gui_erp_totl) +global observe_ERPDAT; +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1; +try + Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +catch + return; +end +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end +EStudio_gui_erp_totl.pageinfo_edit.String = num2str(S_ws_getbinchan.Select_index); +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [1 1 1]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; +EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; +EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + +MessageViewer= char(strcat('Plot next page (>)')); +erpworkingmemory('f_ERP_proces_messg',MessageViewer); +observe_ERPDAT.Process_messg =1; +try + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; +catch + observe_ERPDAT.Process_messg =3; +end +observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_mt_viewer.m b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_mt_viewer.m new file mode 100755 index 00000000..39440c5e --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_mt_viewer.m @@ -0,0 +1,1533 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + + + + + +function f_redrawERP_mt_viewer() +% Draw a demo ERP into the axes provided +% global EStudio_gui_erp_totl; +global observe_ERPDAT; +global EStudio_gui_erp_totl; +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +Select_index = S_ws_getbinchan.Select_index; +S_ws_geterpplot = estudioworkingmemory('geterpplot'); + + +S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); +try + + Viewer_Label = S_ws_geterpvalues.Viewer; +catch + mnamex = '"Viewer" was not selected for the measured ERPset.'; + question = [ '%s\n\n Please select "On" for "Viewer" on the "ERP Measurement Tool" panel .\n']; + title = 'ERPLAB Studio: ERP Measurement Tool'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + return; +end + +if isempty(Viewer_Label) || ~strcmp(Viewer_Label,'on') + mnamex = '"Off" was selected for "Viewer" on the "ERP Measurement Tool" panel.'; + question = [ '%s\n\n Please check "S" on Workspace of Matlab.\n']; + title = 'ERPLAB Studio: ERP Measurement Tool'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + return; +end + + +try + moption = S_ws_geterpvalues.Measure; +catch + mnamex = 'Measurement type was not selected on the "ERP Measurement Tool" panel.'; + question = [ '%s\n\n Please select anyone of measurement types from pop menu of "Measurement Type".\n']; + title = 'ERPLAB Studio: ERP Measurement Tool'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + return; +end + + +try + latency = S_ws_geterpvalues.latency; +catch + mnamex = 'Measurement window was not defined on the "ERP Measurement Tool" panel.'; + question = [ '%s\n\n Please set measurement window on "Measurement window".\n']; + title = 'ERPLAB Studio: ERP Measurement Tool'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + return; +end + +Times_erp_curr = observe_ERPDAT.ERP.times; + +if numel(latency) ==1 + if latency(1)< Times_erp_curr(1) + msgboxText = ['For latency range, lower time limit must be larger than',32,num2str(Times_erp_curr(1)),'.\n']; + title = 'EStudio: ERP measurement tool- Viewer "on". '; + errorfound(sprintf(msgboxText), title); + return + + elseif latency(1)> Times_erp_curr(end) + msgboxText = ['For latency range, upper time limit must be smaller than',32,num2str(Times_erp_curr(end)),'.\n']; + title = 'EStudio: ERP measurement tool- Viewer "on". '; + errorfound(sprintf(msgboxText), title); + return + end + + +else + + if latency(1) < Times_erp_curr(1) + msgboxText = ['For latency range, lower time limit must be larger than',32,num2str(Times_erp_curr(1)),'.\n']; + title = 'EStudio: ERP measurement tool- Viewer "on". '; + errorfound(sprintf(msgboxText), title); + return + + elseif latency(end) > Times_erp_curr(end) + msgboxText = ['For latency range, upper time limit must be smaller than',32,num2str(Times_erp_curr(end)),'.\n']; + title = 'EStudio: ERP measurement tool- Viewer "on". '; + errorfound(sprintf(msgboxText), title); + return + end +end + +%%Parameter from bin and channel panel +Elecs_shown = S_ws_getbinchan.elecs_shown{Select_index}; +Bins = S_ws_getbinchan.bins{Select_index}; +Bin_chans = S_ws_getbinchan.bins_chans(Select_index); +Elec_list = S_ws_getbinchan.elec_list{Select_index}; +Matlab_ver = S_ws_getbinchan.matlab_ver; + + + +%%Parameter from plotting panel +Min_vspacing = S_ws_geterpplot.min_vspacing(Select_index); +Min_time = S_ws_geterpplot.min(Select_index); +Max_time = S_ws_geterpplot.max(Select_index); +Yscale = S_ws_geterpplot.yscale(Select_index); +Timet_low =S_ws_geterpplot.timet_low(Select_index); +Timet_high =S_ws_geterpplot.timet_high(Select_index); +Timet_step=S_ws_geterpplot.timet_step(Select_index); +Fill = S_ws_geterpplot.fill(Select_index); +Plority_plot = S_ws_geterpplot.Positive_up(Select_index); + + +if Bin_chans == 0 + elec_n = S_ws_getbinchan.elec_n(Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(Select_index)).nchan; +else + elec_n = S_ws_getbinchan.bin_n(Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(Select_index)).nbin; +end + +% We first clear the existing axes ready to build a new one +if ishandle( EStudio_gui_erp_totl.ViewAxes ) + delete( EStudio_gui_erp_totl.ViewAxes ); +end + + +% Get chan labels +S_chan.chan_label = cell(1,max_elec_n); +S_chan.chan_label_place = zeros(1,max_elec_n); + + +if Bin_chans == 0 + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.chanlocs(Elecs_shown(i)).labels; + end +else + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.bindescr(Bins(i)); + end +end + + +%Sets the units of your root object (screen) to pixels +set(0,'units','pixels') +%Obtains this pixel information +Pix_SS = get(0,'screensize'); +%Sets the units of your root object (screen) to inches +set(0,'units','inches') +%Obtains this inch information +Inch_SS = get(0,'screensize'); +%Calculates the resolution (pixels per inch) +Res = Pix_SS./Inch_SS; + + +pb_height = Min_vspacing*Res(4); %px + + +% Plot data in the main viewer fig +splot_n = elec_n; +tsize = 13; + +%%Get the background color +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;%%Get background color +catch + ColorB_def = [0. 95 0.95 0.95]; +end +if isempty(ColorB_def) + ColorB_def = [0. 95 0.95 0.95]; +end + +clear pb r_ax plotgrid +EStudio_gui_erp_totl.plotgrid = uiextras.VBox('Parent',EStudio_gui_erp_totl.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorB_def); + +pageinfo_box = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid,'BackgroundColor',ColorB_def); + +EStudio_gui_erp_totl.plot_wav_legend = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid,'BackgroundColor',[1 1 1]); +EStudio_gui_erp_totl.ViewAxes_legend = uix.ScrollingPanel( 'Parent', EStudio_gui_erp_totl.plot_wav_legend,'BackgroundColor',ColorB_def); +EStudio_gui_erp_totl.ViewAxes = uix.ScrollingPanel( 'Parent', EStudio_gui_erp_totl.plot_wav_legend,'BackgroundColor',[1 1 1]); +EStudio_gui_erp_totl.ERP_M_T_Viewer = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid,'BackgroundColor',ColorB_def); +%%-------------------Display the processing procedure----------------------- +%%Changed by Guanghui Zhang 2 August 2022-------panel for display the processing procedure for some functions, e.g., filtering +xaxis_panel = uiextras.HBox( 'Parent', EStudio_gui_erp_totl.plotgrid );%%%Message +EStudio_gui_erp_totl.Process_messg = uicontrol('Parent',xaxis_panel,'Style','text','String','','FontSize',20,'FontWeight','bold','BackgroundColor',ColorB_def); + + +%%Setting title +EStudio_gui_erp_totl.pageinfo_minus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',{@page_minus,EStudio_gui_erp_totl},'FontSize',30,'BackgroundColor',[1 1 1]); +if Select_index ==1 + EStudio_gui_erp_totl.pageinfo_minus.Enable = 'off'; +end + +EStudio_gui_erp_totl.pageinfo_edit = uicontrol('Parent',pageinfo_box,'Style', 'edit', 'String', num2str(S_ws_getbinchan.Select_index),'Callback',{@page_edit,EStudio_gui_erp_totl},'FontSize',20,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index ==1 + EStudio_gui_erp_totl.pageinfo_edit.Enable = 'on'; +end + + +EStudio_gui_erp_totl.pageinfo_plus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',{@page_plus,EStudio_gui_erp_totl},'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index == numel(S_ws_geterpset) + EStudio_gui_erp_totl.pageinfo_plus.Enable = 'off'; +end + +pageinfo_str = ['Page',32,num2str(Select_index),'/',num2str(numel(S_ws_geterpset)),':',32,observe_ERPDAT.ERP.erpname]; +pageinfo_text = uicontrol('Parent',pageinfo_box,'Style','text','String',pageinfo_str,'FontSize',14,'FontWeight','bold'); + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [1 1 1]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; +EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; +EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + +set(pageinfo_box, 'Sizes', [50 50 50 -1] ); +set(pageinfo_box,'BackgroundColor',ColorB_def); +set(pageinfo_text,'BackgroundColor',ColorB_def); +%Setting title. END + +%for i=1:splot_n + +ndata = 0; +nplot = 0; +if Bin_chans == 0 + ndata = Bins; + nplot = Elecs_shown; +else + ndata = Elecs_shown; + nplot = Bins; +end + +%Both equation is incorrect. + +pnts = observe_ERPDAT.ERP.pnts; +timeor = observe_ERPDAT.ERP.times; % original time vector +p1 = timeor(1); +p2 = timeor(end); + +try + intfactor = S_ws_geterpvalues.InterpFactor; +catch + intfactor =1; +end + +if intfactor~=1 + timex = linspace(p1,p2,round(pnts*intfactor)); +else + timex = timeor; +end + + +[xxx, latsamp, latdiffms] = closest(timex, [Min_time Max_time]); +tmin = latsamp(1); +tmax = latsamp(2); + +if tmin < 1 + tmin = 1; +end + +if tmax > numel(timex) + tmax = numel(timex); +end + +try + blc = S_ws_geterpvalues.Baseline; +catch + blc = 'none'; +end + +if intfactor~=1 + Plot_erp_data_TRAN = []; + for Numoftwo = 1:size(observe_ERPDAT.ERP.bindata,3) + for Numofone = 1:size(observe_ERPDAT.ERP.bindata,1) + data = squeeze(observe_ERPDAT.ERP.bindata(Numofone,:,Numoftwo)); + data = spline(timeor, data, timex); % re-sampled data + blv = blvalue2(data, timex, blc); + data = data - blv; + Plot_erp_data_TRAN(Numofone,:,Numoftwo) = data; + end + end + Bindata = Plot_erp_data_TRAN; +else + Bindata = observe_ERPDAT.ERP.bindata; +end + +plot_erp_data = nan(tmax-tmin+1,numel(ndata)); +for i = 1:splot_n + if Bin_chans == 0 + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = Bindata(Elecs_shown(i),tmin:tmax,Bins(i_bin))'*Plority_plot; % + end + else + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = Bindata(Elecs_shown(i_bin),tmin:tmax,Bins(i))'*Plority_plot; % + end + end +end + +perc_lim = Yscale; +percentile = perc_lim*3/2; +%How to get x unique colors? +line_colors = erpworkingmemory('PWColor'); +if size(line_colors,1)~= numel(ndata) + if numel(ndata)> size(line_colors,1) + line_colors = get_colors(numel(ndata)); + else + line_colors = line_colors(1:numel(ndata),:,:); + end +end + +if isempty(line_colors) + line_colors = get_colors(numel(ndata)); +end + +line_colors = repmat(line_colors,[splot_n 1]); %repeat the colors once for every plot + +ind_plot_height = percentile*2; % Height of each individual subplot + +offset = []; +if Bin_chans == 0 + offset = (numel(Elecs_shown)-1:-1:0)*ind_plot_height; +else + offset = (numel(Bins)-1:-1:0)*ind_plot_height; +end +[~,~,Num_plot] = size(plot_erp_data); + +for i = 1:Num_plot + plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i); +end + +if ~strcmpi(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + %pb_ax = uipanel('Parent',EStudio_gui_erp_totl.plotgrid); + r_ax = axes('Parent', EStudio_gui_erp_totl.ViewAxes,'Color',[1 1 1],'Box','on'); + hold(r_ax,'on'); + set(EStudio_gui_erp_totl.plot_wav_legend,'Sizes',[80 -10]); + r_ax_legend = axes('Parent', EStudio_gui_erp_totl.ViewAxes_legend,'Color','none','Box','off'); + hold(r_ax_legend,'on'); + + + set(r_ax,'XLim',[Min_time Max_time]); + ts = timex(tmin:tmax); + [a,Num_data,Num_plot] = size(plot_erp_data); + new_erp_data = zeros(a,Num_plot*Num_data); + for i = 1:Num_plot + new_erp_data(:,((Num_data*(i-1))+1):(Num_data*i)) = plot_erp_data(:,:,i); + end + + % plot_erp_data_fin = [repmat((1:numel(nplot)-1)*ind_plot_height,[numel(ts) 1]) new_erp_data]; + + % pb_here = plot(r_ax,ts,plot_erp_data_fin,'LineWidth',1); + pb_here = plot(r_ax,ts,new_erp_data,'LineWidth',1.5); + hold(r_ax,'on');%Same function as hold on; + r_ax.LineWidth=1.5; + yticks = -perc_lim:perc_lim:((2*percentile*Num_plot)-(2*perc_lim)); + + oldlim = [-percentile yticks(end)-perc_lim+percentile]; + top_vspace = max( max( new_erp_data ) )-oldlim(2); + bot_vspace = min( min( new_erp_data ) )-oldlim(1); + + newlim = oldlim + [bot_vspace top_vspace]; + ylabs = repmat([-perc_lim 0 perc_lim],[1,Num_plot]); + ylabs = [fliplr(-perc_lim:-perc_lim:newlim(1)) ylabs(2:end-1) (yticks(end):perc_lim:newlim(2))-yticks(end)+perc_lim]; + yticks = [fliplr(-perc_lim:-perc_lim:newlim(1)) yticks(2:end-1) yticks(end):perc_lim:newlim(2)]; + + %%%------------Setting xticklabels for each row of each wave-------------- + xstep_label = estudioworkingmemory('erp_xtickstep'); + if isempty(xstep_label) + xstep_label =0; + end + if ~xstep_label + [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [Timet_low,Timet_high]); + xticks = str2num(def{1,1}); + else + xticks = (Timet_low:Timet_step:Timet_high); + end + % estudioworkingmemory('erp_xtickstep',0); + x_axs = ones(size(new_erp_data,1),1); + xticks_label = []; + count = 0; + for jjj = 1:numel(xticks) + if xticks(jjj)< Min_time || xticks(jjj)> Max_time + count = count +1; + xticks_label(count) = jjj; + end + end + % if ~isempty(xticks_label) + % xticks(xticks_label) = []; + % end + for Numofxlabel = 1:numel(xticks) + xticks_labels{Numofxlabel} = num2str(xticks(Numofxlabel)); + end + + try + moption = S_ws_geterpvalues.Measure; + catch + moption = 'meanbl'; + end + + + for jj = 1:numel(offset) + plot(r_ax,ts,x_axs.*offset(end),'color',[1 1 1],'LineWidth',3); + set(r_ax,'XLim',[Timet_low,Timet_high]); + set(r_ax,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); + myX_Crossing = offset(jj); + props = get(r_ax); + + tick_bottom = -props.TickLength(1)*diff(props.YLim); + if abs(tick_bottom) > abs(Yscale)/5 + try + tick_bottom = - abs(Yscale)/5; + catch + tick_bottom = tick_bottom; + end + end + tick_top = 0; + + line(r_ax,props.XLim, [0 0] + myX_Crossing, 'color', 'k','LineWidth',1.5); + + if ~isempty(props.XTick) + xtick_x = repmat(props.XTick, 2, 1); + xtick_y = repmat([tick_bottom; tick_top] + myX_Crossing, 1, length(props.XTick)); + h_ticks = line(r_ax,xtick_x, xtick_y, 'color', 'k','LineWidth',1.5); + end + set(r_ax, 'XTick', [], 'XTickLabel', []); + % tick_bottom = -props.TickLength(1)*diff(props.YLim); + nTicks = length(props.XTick); + h_ticklabels = zeros(size(props.XTick)); + if nTicks>1 + if numel(offset)==jj + kkkk = 1; + else + if abs(Timet_low - xticks(1)) > 1000/observe_ERPDAT.ERP.srate + kkkk = 1; + else + kkkk = 2; + end + end + for iCount = kkkk:nTicks + xtick_label = (props.XTickLabel(iCount, :)); + text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', 12, ... + 'FontName', props.FontName, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits, ... + 'FontWeight', 'bold'); + end + end + end + % end + + %%%Mark the area/latency/amplitude of interest within the defined window. + ERP_mark_area_latency(r_ax,timex(tmin:tmax),moption,plot_erp_data,latency,line_colors,offset,Plority_plot);%cwm = [0 0 0];% white: Background color for measurement window + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % set(r_ax,'XLim',[Timet_low,Timet_high]); + + %%%%%%%%----------------------------- + + [xxx, latsamp,cdiff] = closest(timex, 0); + if cdiff<1000/observe_ERPDAT.ERP.srate + xline(r_ax,timex(latsamp),'k-.','LineWidth',1);%%Marking start time point for each column + end + + if top_vspace < 0 + top_vspace = 0; + end + + if bot_vspace > 0 + bot_vspace = 0; + end + set(r_ax,'XLim',[Timet_low,Timet_high],'Ylim',newlim); + + for i = 1:numel(pb_here) + pb_here(i).Color = line_colors(i,:); + end + + + Ylabels_new = ylabs.*Plority_plot; + [~,Y_label] = find(Ylabels_new == -0); + Ylabels_new(Y_label) = 0; + + + if numel(offset)>1 + count = 0; + for i = 0:numel(offset)-1 + leg_str = ''; + + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',strrep(Elec_list{Elecs_shown(count)},'_','\_')); + else + leg_str = sprintf('%s',strrep(observe_ERPDAT.ERP.bindescr{Bins(count)},'_','\_')); + end + catch + leg_str = ''; + end + text(r_ax,Timet_low,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + + end + end + + try + if Bin_chans == 0 + leg_str = sprintf('%s',strrep(Elec_list{Elecs_shown(end)},'_','\_')); + else + leg_str = sprintf('%s',strrep(observe_ERPDAT.ERP.bindescr{Bins(end)},'_','\_')); + end + catch%% + leg_str = ''; + end + + try + text(r_ax,Timet_low,offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + catch + text(r_ax,Timet_low,Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end + + + % xticks = (Min_time:Timet_step:Max_time); + % some options currently only work post Matlab R2016a + if Matlab_ver >= 2016 + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','origin',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim,'XTick',xticks, ... + 'box','off', 'Color','none','XLim',[Timet_low Timet_high]); + else + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','bottom',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim, 'XTick',xticks,... + 'box','off', 'Color','none','XLim',[Timet_low Timet_high]); + hline(0,'k'); % backup xaxis + end + hold(r_ax,'off'); + % if numel(offset)>1 + set(r_ax, 'XTick', [], 'XTickLabel', []); + % end + %%%%%%%%%%%% + % r_ax.Position(1) =r_ax.Position(1)+0.5; + line_colors_ldg = erpworkingmemory('PWColor'); + if isempty(line_colors_ldg) + line_colors_ldg = get_colors(numel(ndata)); + end + if size(line_colors_ldg,1)~= numel(ndata) + if numel(ndata)> size(line_colors_ldg,1) + line_colors_ldg = get_colors(numel(ndata)); + else + line_colors_ldg = line_colors_ldg(1:numel(ndata),:,:); + end + end + + + for Numofplot = 1:size(plot_erp_data,2) + plot(r_ax_legend,[0 0],'Color',line_colors_ldg(Numofplot,:,:),'LineWidth',3) + end + + if Bin_chans == 0 + Leg_Name = ''; + for Numofbin = 1:numel(Bins) + Leg_Name{Numofbin} = strcat('Bin',num2str(Bins(Numofbin))); + end + + else + for Numofchan = 1:numel(Elecs_shown) + Leg_Name{Numofchan} = strrep(Elec_list{Elecs_shown(Numofchan)},'_','\_'); + end + end + here_lgd = legend(r_ax_legend,Leg_Name,'FontSize',14,'TextColor','blue'); + legend(r_ax_legend,'boxoff'); + + + + %end + EStudio_gui_erp_totl.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high + EStudio_gui_erp_totl.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high + EStudio_gui_erp_totl.plotgrid.Heights(4) = 30; % set the second element (x axis) to 30px high + EStudio_gui_erp_totl.plotgrid.Units = 'pixels'; + if splot_n*pb_height<(EStudio_gui_erp_totl.plotgrid.Position(4)-EStudio_gui_erp_totl.plotgrid.Heights(1))&&Fill + pb_height = (EStudio_gui_erp_totl.plotgrid.Position(4)-EStudio_gui_erp_totl.plotgrid.Heights(1)-EStudio_gui_erp_totl.plotgrid.Heights(2))/splot_n; + end + + EStudio_gui_erp_totl.ViewAxes.Heights = splot_n*pb_height; + % EStudio_gui_erp_totl.ViewAxes.Widths = -10; + EStudio_gui_erp_totl.plotgrid.Units = 'normalized'; + EStudio_gui_erp_totl.plotgrid.Heights =[30 -1 80 30]; + %%%-------------------Display results obtained from "Measurement Tool" Panel--------------------------------- + [~,~,~,Amp,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP); + try + Resolution =S_ws_geterpvalues.Resolution; + catch + Resolution =3; + end + try + moption =S_ws_geterpvalues.Measure; + catch + beep; + disp('Please select one of Measurement type'); + return; + end + + %%Get name for the selected rows (i.e.,bins) and columns (i.e., channels) + RowName = {}; + for Numofbin = 1:numel(Bins) + RowName{Numofbin} = strcat('Bin',num2str(Bins(Numofbin)));%'',':',32,observe_ERPDAT.ERP.bindescr{Bins(Numofbin)} + end + ColumnName = {}; + for Numofsel_chan = 1:numel(Elecs_shown) + ColumnName{Numofsel_chan} = ['',num2str(Elecs_shown(Numofsel_chan)),'.',32,Elec_list{Elecs_shown(Numofsel_chan)}]; + end + + % txt_title = uicontrol('Parent',EStudio_gui_erp_totl.ERP_M_T_Viewer,'Style', 'text', 'String', 'My Example Title'); + try + if ismember_bc2(moption, {'instabl','peaklatbl','fpeaklat','fareatlat','fninteglat','fareaplat','fareanlat','meanbl','peakampbl','areat','ninteg','areap','arean','ninteg','areazt','nintegz','areazp','areazn'}) + Data_display = Amp(Bins,Elecs_shown); + else + Data_display = Lat(Bins,Elecs_shown); + end + + if ismember_bc2(moption,{'arean','areazn'}) + Data_display= -1.*Data_display; + end + + Data_display_tra = {}; + for Numofone = 1:size(Data_display,1) + for Numoftwo = 1:size(Data_display,2) + if ~isnan(Data_display(Numofone,Numoftwo)) + if Bin_chans == 0 + Data_display_tra{Numofone,Numoftwo} = sprintf(['%.',num2str(Resolution),'f'], Data_display(Numofone,Numoftwo)); + else + Data_display_tra{Numoftwo,Numofone} = sprintf(['%.',num2str(Resolution),'f'], Data_display(Numofone,Numoftwo)); + end + + else + if Bin_chans == 0 + Data_display_tra{Numofone,Numoftwo} = ['NaN']; + else + Data_display_tra{Numoftwo,Numofone} = ['NaN']; + end + end + end + end + + EStudio_gui_erp_totl.ERP_M_T_Viewer_table = uitable(EStudio_gui_erp_totl.ERP_M_T_Viewer,'Data',Data_display_tra,'Units','Normalize'); + if Bin_chans == 0 + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.RowName = RowName; + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnName = ColumnName; + else + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.RowName = ColumnName; + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnName = RowName; + end + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.BackgroundColor = line_colors_ldg; + + + if size(Data_display_tra,2)<12 + ColumnWidth = {}; + for Numofchan =1:size(Data_display_tra,2) + ColumnWidth{Numofchan} = EStudio_gui_erp_totl.ERP_M_T_Viewer.Position(3)/size(Data_display_tra,2); + end + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnWidth = ColumnWidth; + elseif size(Data_display_tra,2) ==1 + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnWidth = {EStudio_gui_erp_totl.ERP_M_T_Viewer.Position(3)}; + end + + catch + for Numofbin = 1:observe_ERPDAT.ERP.nbin + Data_display{Numofbin,1} = ''; + end + + RowName = {}; + for Numofbin = 1:observe_ERPDAT.ERP.nbin + RowName{Numofbin} = strcat('Bin',num2str((Numofbin))); + end + EStudio_gui_erp_totl.ERP_M_T_Viewer_table = uitable(EStudio_gui_erp_totl.ERP_M_T_Viewer,'Data',Data_display); + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.RowName = RowName; + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnName = {'No data are avalible'}; + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ColumnWidth = {EStudio_gui_erp_totl.ERP_M_T_Viewer.Position(3)}; + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.BackgroundColor = line_colors_ldg; + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.ForegroundColor = [1 1 1]; + end + + EStudio_gui_erp_totl.ERP_M_T_Viewer_table.FontSize = 12; +else + set(EStudio_gui_erp_totl.plot_wav_legend,'Sizes',[80 -10]); + EStudio_gui_erp_totl.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high + EStudio_gui_erp_totl.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high + EStudio_gui_erp_totl.plotgrid.Heights(4) = 30; + +end +end % redrawDemo + + +function colors = get_colors(ncolors) +% Each color gets 1 point divided into up to 2 of 3 groups (RGB). +degree_step = 6/ncolors; +angles = (0:ncolors-1)*degree_step; +colors = nan(numel(angles),3); +for i = 1:numel(angles) + if angles(i) < 1 + colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75; + elseif angles(i) < 2 + colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75; + elseif angles(i) < 3 + colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75; + elseif angles(i) < 4 + colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75; + elseif angles(i) < 5 + colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75; + else + colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75; + end +end +end + + +%------------------Display the waveform for proir ERPset-------------------- +function page_minus(~,~,EStudio_gui_erp_totl) +global observe_ERPDAT; +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; +EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; +f_redrawERP_mt_viewer(); +EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + +MessageViewer= char(strcat('Plot prior page (<)')); +erpworkingmemory('f_ERP_proces_messg',MessageViewer); +observe_ERPDAT.Process_messg =1; +try + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; +catch + observe_ERPDAT.Process_messg =3; +end +observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; +end + + + +%%Edit the index of ERPsets +function page_edit(Str,~,EStudio_gui_erp_totl) +CurrentERPindex = str2num(Str.String); +global observe_ERPDAT; +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +if ~isempty(CurrentERPindex) && numel(CurrentERPindex)==1 && (CurrentERPindex<= numel(S_ws_geterpset)) + S_ws_getbinchan.Select_index = CurrentERPindex; + Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); + % EStudio_gui_erp_totl.pageinfo_edit.String = num2str(S_ws_getbinchan.Select_index); + if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; + end + observe_ERPDAT.CURRENTERP = Current_erp_Index; + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); + estudioworkingmemory('geterpbinchan',S_ws_getbinchan); + if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; + else + if CurrentERPindex ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [1 1 1]; + elseif CurrentERPindex == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end + end + EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; + EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; + EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; + EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + + MessageViewer= char(strcat('Page Editor')); + erpworkingmemory('f_ERP_proces_messg',MessageViewer); + observe_ERPDAT.Process_messg =1; + try + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + catch + observe_ERPDAT.Process_messg =3; + end +end +observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; +end + + +%------------------Display the waveform for next ERPset-------------------- +function page_plus(~,~,EStudio_gui_erp_totl) +global observe_ERPDAT; +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [1 1 1]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + + + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +EStudio_gui_erp_totl.pageinfo_minus.Enable = Enable_minus; +EStudio_gui_erp_totl.pageinfo_plus.Enable = Enable_plus; +EStudio_gui_erp_totl.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +EStudio_gui_erp_totl.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + +MessageViewer= char(strcat('Plot next page (>)')); +erpworkingmemory('f_ERP_proces_messg',MessageViewer); +observe_ERPDAT.Process_messg =1; +try + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; +catch + observe_ERPDAT.Process_messg =3; +end +observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; +end + + +%%Mark the area or latency/amplitude of interest within defined latecies%%% +function ERP_mark_area_latency(r_ax,timex,moption,plot_erp_data,latency,line_colors,offset,Plority_plot) +try + cwm_backgb = erpworkingmemory('MWColor'); +catch + cwm_backgb=[0.7 0.7 0.7]; +end +if isempty(cwm_backgb) + cwm_backgb=[0.7 0.7 0.7]; +end + +try + cwm = erpworkingmemory('MTLineColor'); +catch + cwm =[0 0 0]; +end +if isempty(cwm) + cwm=[0 0 0]; +end + +global observe_ERPDAT; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Plot area within the defined time-window%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%Set area within the defined time-window for 1.Fractional area latency, 2. Numerical integration/Area between two fixed latencies +mearea = { 'areat', 'areap', 'arean','areazt','areazp','areazn', 'ninteg','nintegz'}; + +[~,Num_data,Num_plot] = size(plot_erp_data); + +if ismember_bc2(moption, mearea) || ismember_bc2(moption, {'fareatlat', 'fareaplat','fninteglat','fareanlat'}) + if numel(latency) ==2 + latx = latency; + [xxx, latsamp] = closest(timex, latx); + datax = plot_erp_data(latsamp(1):latsamp(2),:,:); + end + Time_res = timex(2)-timex(1); + + if ismember_bc2(moption, {'areap', 'fareaplat'}) % positive area + + for Numofstione = 1:size(datax,3) + for Numofstitwo = 1:size(datax,2) + timexx = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check = dataxx-offset(Numofstione); + if Plority_plot==1 + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + elseif Plority_plot ==-1 + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + else + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + end + + if ~isempty(dataxx) && numel(dataxx)>=2 + %%Check isolated point + Check_outlier =[]; + count = 0; + + if (timexx(2)-timexx(1)>Time_res) + count= count +1; + Check_outlier(count) = 1; + end + if numel(dataxx)>=3 + for Numofsample = 2:length(timexx)-1 + if (timexx(Numofsample+1)-timexx(Numofsample)>Time_res) && (timexx(Numofsample)-timexx(Numofsample-1)< Time_res) + count = count+1; + Check_outlier(count) = Numofsample; + end + end + end + dataxx(Check_outlier) = []; + timexx(Check_outlier) = []; + + Check_isolated =[]; + count = 0; + for Numofsample = 1:length(timexx)-1 + if timexx(Numofsample+1)-timexx(Numofsample)>Time_res + count = count+1; + Check_isolated(count) = Numofsample; + end + end + if numel(Check_isolated) ==1 + inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))]; + inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionX2 = [timexx(Check_isolated(1)+1:end),fliplr(timexx(Check_isolated(1)+1:end))]; + inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(1)+1:end))))]; + fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + elseif numel(Check_isolated) >1 + for Numofrange = 1:numel(Check_isolated)-1 + + inBetweenRegionX = [timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))]; + inBetweenRegionY = [squeeze(dataxx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + end + inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))]; + inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionX2 = [timexx(Check_isolated(Numofrange+1)+1:end),fliplr(timexx(Check_isolated(Numofrange+1)+1:end))]; + inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange+1)+1:end))))]; + fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + else + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end + + end + + end + elseif ismember_bc2(moption, {'arean', 'fareanlat'}) % negative area + for Numofstione = 1:size(datax,3) + for Numofstitwo = 1:size(datax,2) + timexx = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check = dataxx-offset(Numofstione); + if Plority_plot==1 + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + elseif Plority_plot ==-1 + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + else + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + end + + %%Check isolated point + if ~isempty(dataxx) && numel(dataxx)>=2 + Check_outlier =[]; + count = 0; + + if (timexx(2)-timexx(1)>Time_res) + count= count +1; + Check_outlier(count) = 1; + end + if numel(dataxx)>=3 + for Numofsample = 2:length(timexx)-1 + if (timexx(Numofsample+1)-timexx(Numofsample)>Time_res) && (timexx(Numofsample)-timexx(Numofsample-1)< Time_res) + count = count+1; + Check_outlier(count) = Numofsample; + end + end + end + dataxx(Check_outlier) = []; + timexx(Check_outlier) = []; + + Check_isolated =[]; + count = 0; + for Numofsample = 1:length(timexx)-1 + if timexx(Numofsample+1)-timexx(Numofsample)>Time_res + count = count+1; + Check_isolated(count) = Numofsample; + end + end + if numel(Check_isolated) ==1 + inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))]; + inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionX2 = [timexx(Check_isolated(1)+1:end),fliplr(timexx(Check_isolated(1)+1:end))]; + inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(1)+1:end))))]; + fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + elseif numel(Check_isolated) >1 + for Numofrange = 1:numel(Check_isolated)-1 + + inBetweenRegionX = [timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))]; + inBetweenRegionY = [squeeze(dataxx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + end + inBetweenRegionX1 = [timexx(1:Check_isolated(1)),fliplr(timexx(1:Check_isolated(1)))]; + inBetweenRegionY1 = [squeeze(dataxx(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexx(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionX2 = [timexx(Check_isolated(Numofrange+1)+1:end),fliplr(timexx(Check_isolated(Numofrange+1)+1:end))]; + inBetweenRegionY2 = [squeeze(dataxx(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexx(Check_isolated(Numofrange+1)+1:end))))]; + fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + else + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end + end + end + + + elseif ismember_bc2(moption, {'ninteg', 'fninteglat'}) % integration(area for negative substracted from area for positive) + for Numofstione = 1:size(datax,3) + for Numofstitwo = 1:size(datax,2) + timexxp = timex(latsamp(1):latsamp(2)); + dataxxp = squeeze(datax(:,Numofstitwo,Numofstione)); + timexxn = timex(latsamp(1):latsamp(2)); + dataxxn = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check = dataxxn-offset(Numofstione); + if Plority_plot==1 + dataxxp(data_check<0) = []; + timexxp(data_check<0) = []; + dataxxn(data_check>0) = []; + timexxn(data_check>0) = []; + + elseif Plority_plot ==-1 + dataxxp(data_check>0) = []; + timexxp(data_check>0) = []; + dataxxn(data_check<0) = []; + timexxn(data_check<0) = []; + else + dataxxp(data_check<0) = []; + timexxp(data_check<0) = []; + dataxxn(data_check>0) = []; + timexxn(data_check>0) = []; + end + + + if ~isempty(dataxxp) && numel(dataxxp)>=2 + %%Check isolated point + Check_outlierp =[]; + count = 0; + + if (timexxp(2)-timexxp(1)>Time_res) + count= count +1; + Check_outlierp(count) = 1; + end + if numel(dataxxp)>=3 + for Numofsample = 2:length(timexxp)-1 + if (timexxp(Numofsample+1)-timexxp(Numofsample)>Time_res) && (timexxp(Numofsample)-timexxp(Numofsample-1)< Time_res) + count = count+1; + Check_outlierp(count) = Numofsample; + end + end + end + dataxxp(Check_outlierp) = []; + timexxp(Check_outlierp) = []; + + Check_isolated =[]; + count = 0; + for Numofsample = 1:length(timexxp)-1 + if timexxp(Numofsample+1)-timexxp(Numofsample)>Time_res + count = count+1; + Check_isolated(count) = Numofsample; + end + end + if numel(Check_isolated) ==1 + inBetweenRegionXp1 = [timexxp(1:Check_isolated(1)),fliplr(timexxp(1:Check_isolated(1)))]; + inBetweenRegionYp1 = [squeeze(dataxxp(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionXp1, inBetweenRegionYp1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionXp2 = [timexxp(Check_isolated(1)+1:end),fliplr(timexxp(Check_isolated(1)+1:end))]; + inBetweenRegionYp2 = [squeeze(dataxxp(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(Check_isolated(1)+1:end))))]; + fill(r_ax,inBetweenRegionXp2, inBetweenRegionYp2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + elseif numel(Check_isolated) >1 + for Numofrange = 1:numel(Check_isolated)-1 + + inBetweenRegionX = [timexxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))]; + inBetweenRegionY = [squeeze(dataxxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + end + inBetweenRegionX1 = [timexxp(1:Check_isolated(1)),fliplr(timexxp(1:Check_isolated(1)))]; + inBetweenRegionY1 = [squeeze(dataxxp(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionX2 = [timexxp(Check_isolated(Numofrange+1)+1:end),fliplr(timexxp(Check_isolated(Numofrange+1)+1:end))]; + inBetweenRegionY2 = [squeeze(dataxxp(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxp(Check_isolated(Numofrange+1)+1:end))))]; + fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + else + inBetweenRegionX = [timexxp,fliplr(timexxp)]; + inBetweenRegionY = [squeeze(dataxxp)',fliplr(offset(Numofstione)*ones(1,numel(timexxp)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end%Positive part end + + if ~isempty(dataxxn) && numel(dataxxn)>=2 + %%Check isolated point + Check_outliern =[]; + count = 0; + + if (timexxn(2)-timexxn(1)>Time_res) + count= count +1; + Check_outliern(count) = 1; + end + if numel(dataxxn)>=3 + for Numofsample = 2:length(timexxn)-1 + if (timexxn(Numofsample+1)-timexxn(Numofsample)>Time_res) && (timexxn(Numofsample)-timexxn(Numofsample-1)< Time_res) + count = count+1; + Check_outliern(count) = Numofsample; + end + end + end + dataxxn(Check_outliern) = []; + timexxn(Check_outliern) = []; + + Check_isolated =[]; + count = 0; + for Numofsample = 1:length(timexxn)-1 + if timexxn(Numofsample+1)-timexxn(Numofsample)>Time_res + count = count+1; + Check_isolated(count) = Numofsample; + end + end + if numel(Check_isolated) ==1 + inBetweenRegionXp1 = [timexxn(1:Check_isolated(1)),fliplr(timexxn(1:Check_isolated(1)))]; + inBetweenRegionYp1 = [squeeze(dataxxn(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionXp1, inBetweenRegionYp1,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionXp2 = [timexxn(Check_isolated(1)+1:end),fliplr(timexxn(Check_isolated(1)+1:end))]; + inBetweenRegionYp2 = [squeeze(dataxxn(Check_isolated(1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(Check_isolated(1)+1:end))))]; + fill(r_ax,inBetweenRegionXp2, inBetweenRegionYp2,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + elseif numel(Check_isolated) >1 + for Numofrange = 1:numel(Check_isolated)-1 + + inBetweenRegionX = [timexxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)),fliplr(timexxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))]; + inBetweenRegionY = [squeeze(dataxxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(Check_isolated(Numofrange)+1:Check_isolated(Numofrange+1)))))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + end + inBetweenRegionX1 = [timexxn(1:Check_isolated(1)),fliplr(timexxn(1:Check_isolated(1)))]; + inBetweenRegionY1 = [squeeze(dataxxn(1:Check_isolated(1)))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(1:Check_isolated(1)))))]; + fill(r_ax,inBetweenRegionX1, inBetweenRegionY1,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + inBetweenRegionX2 = [timexxn(Check_isolated(Numofrange+1)+1:end),fliplr(timexxn(Check_isolated(Numofrange+1)+1:end))]; + inBetweenRegionY2 = [squeeze(dataxxn(Check_isolated(Numofrange+1)+1:end))',fliplr(offset(Numofstione)*ones(1,numel(timexxn(Check_isolated(Numofrange+1)+1:end))))]; + fill(r_ax,inBetweenRegionX2, inBetweenRegionY2,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + else + inBetweenRegionX = [timexxn,fliplr(timexxn)]; + inBetweenRegionY = [squeeze(dataxxn)',fliplr(offset(Numofstione)*ones(1,numel(timexxn)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:).*0.3,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end%%Negative part end + end + end + + elseif ismember_bc2(moption, {'areat', 'fareatlat'})% negative values become positive + + for Numofstione = 1:size(datax,3) + for Numofstitwo = 1:size(datax,2) + timexx = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end + + elseif ismember_bc2(moption, {'areazt','areazp','areazn', 'nintegz'}) + [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP); + if strcmp(moption,'areazt')%% all area were included + + for Numofstione = 1:size(plot_erp_data,3) + for Numofstitwo = 1:size(plot_erp_data,2) + latx = Lat{Numofstitwo,Numofstione}; + [xxx, latsamp] = closest(timex, latx); + datax = plot_erp_data(latsamp(1):latsamp(2),:,:); + timexx = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end + + elseif strcmp(moption,'areazp')%% Only positive area was included + + for Numofstione = 1:size(plot_erp_data,3) + for Numofstitwo = 1:size(plot_erp_data,2) + latx = Lat{Numofstitwo,Numofstione}; + [xxx, latsamp] = closest(timex, latx); + datax = plot_erp_data(latsamp(1):latsamp(2),:,:); + timexx = timex(latsamp(1):latsamp(2)); + timexx_unsl = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check_unsl = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check = dataxx -offset(Numofstione); + if Plority_plot==1 + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + data_check_unsl(data_check>0) =[]; + timexx_unsl(data_check>0) = []; + elseif Plority_plot ==-1 + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + data_check_unsl(data_check<0) =[]; + timexx_unsl(data_check<0) = []; + else + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + data_check_unsl(data_check>0) =[]; + timexx_unsl(data_check>0) = []; + end + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + inBetweenRegionX_unsl = [timexx_unsl,fliplr(timexx_unsl)]; + inBetweenRegionY_unsl = [squeeze(data_check_unsl)',fliplr(offset(Numofstione)*ones(1,numel(timexx_unsl)))]; + fill(r_ax,inBetweenRegionX_unsl, inBetweenRegionY_unsl,[1 1 1],'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + end + end + + + elseif strcmp(moption,'areazn')%% Only positive area was included + + for Numofstione = 1:size(plot_erp_data,3) + for Numofstitwo = 1:size(plot_erp_data,2) + latx = Lat{Numofstitwo,Numofstione}; + [xxx, latsamp] = closest(timex, latx); + datax = plot_erp_data(latsamp(1):latsamp(2),:,:); + timexx = timex(latsamp(1):latsamp(2)); + timexx_unsl = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check_unsl = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check = dataxx -offset(Numofstione); + if Plority_plot==1 + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + data_check_unsl(data_check<0) =[]; + timexx_unsl(data_check<0) = []; + elseif Plority_plot ==-1 + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + data_check_unsl(data_check>0) =[]; + timexx_unsl(data_check>0) = []; + else + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + data_check_unsl(data_check<0) =[]; + timexx_unsl(data_check<0) = []; + end + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + inBetweenRegionX_unsl = [timexx_unsl,fliplr(timexx_unsl)]; + inBetweenRegionY_unsl = [squeeze(data_check_unsl)',fliplr(offset(Numofstione)*ones(1,numel(timexx_unsl)))]; + fill(r_ax,inBetweenRegionX_unsl, inBetweenRegionY_unsl,[1 1 1],'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + end + end + + elseif strcmp(moption,'nintegz')%% Only positive area was included + + for Numofstione = 1:size(plot_erp_data,3) + for Numofstitwo = 1:size(plot_erp_data,2) + latx = Lat{Numofstitwo,Numofstione}; + [xxx, latsamp] = closest(timex, latx); + datax = plot_erp_data(latsamp(1):latsamp(2),:,:); + timexx = timex(latsamp(1):latsamp(2)); + timexx_unsl = timex(latsamp(1):latsamp(2)); + dataxx = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check_unsl = squeeze(datax(:,Numofstitwo,Numofstione)); + data_check = dataxx -offset(Numofstione); + if Plority_plot==1 + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + data_check_unsl(data_check>0) =[]; + timexx_unsl(data_check>0) = []; + elseif Plority_plot ==-1 + dataxx(data_check>0) = []; + timexx(data_check>0) = []; + data_check_unsl(data_check<0) =[]; + timexx_unsl(data_check<0) = []; + else + dataxx(data_check<0) = []; + timexx(data_check<0) = []; + data_check_unsl(data_check>0) =[]; + timexx_unsl(data_check>0) = []; + end + inBetweenRegionX = [timexx,fliplr(timexx)]; + inBetweenRegionY = [squeeze(dataxx)',fliplr(offset(Numofstione)*ones(1,numel(timexx)))]; + fill(r_ax,inBetweenRegionX, inBetweenRegionY,line_colors(Numofstitwo,:,:),'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + inBetweenRegionX_unsl = [timexx_unsl,fliplr(timexx_unsl)];% + inBetweenRegionY_unsl = [squeeze(data_check_unsl)',fliplr(offset(Numofstione)*ones(1,numel(timexx_unsl)))]; + fill(r_ax,inBetweenRegionX_unsl, inBetweenRegionY_unsl,line_colors(Numofstitwo,:,:)*0.5,'FaceAlpha',0.3,'EdgeColor',line_colors(Numofstitwo,:,:)); + + end + end + + + end + end +end + + +if length(latency)==1 + if ismember_bc2(moption, {'areazt','areazp','areazn', 'nintegz'})%% Four options for Numerical integration/Area between two (automatically detected)zero-crossing latencies + xline(r_ax,latency, 'Color', cwm,'LineWidth' ,1); + + else + xline(r_ax,latency, 'Color', cwm,'LineWidth' ,1); + end + if ismember_bc2(moption, 'instabl') + [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP); + + for Numofstione = 1:Num_plot + for Numofstitwo = 1:Num_data + plot(r_ax,latency,squeeze(Amp_out(Numofstitwo,Numofstione)),'Color',line_colors(Numofstitwo,:,:),'Marker','x'); + end + end + + end +elseif length(latency)==2 + Max_values = max(abs(plot_erp_data(:))); + plot_area_up = area(r_ax,[latency latency(2) latency(1)],[-2*Max_values-500,Max_values*2 -2*Max_values-500,Max_values*2]); + plot_area_low = area(r_ax,[latency latency(2) latency(1)],[0,-Max_values*2 0,-Max_values*2]); + + set(plot_area_up,'FaceAlpha',0.2, 'EdgeAlpha', 0.1, 'EdgeColor', cwm,'FaceColor',cwm_backgb); + set(plot_area_low,'FaceAlpha',0.2, 'EdgeAlpha', 0.1, 'EdgeColor', cwm,'FaceColor',cwm_backgb); + + if ismember_bc2(moption, {'peakampbl'})%Local Peak amplitude + + [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP); + for Numofstione = 1:Num_plot + for Numofstitwo = 1:Num_data + line(r_ax, [Lat{Numofstitwo,Numofstione} Lat{Numofstitwo,Numofstione}],[offset(Numofstione),squeeze(Amp_out(Numofstitwo,Numofstione))],'Color',line_colors(Numofstitwo,:,:),'LineWidth',3,'LineStyle','--','Marker','x'); + end + end + + elseif ismember_bc2(moption, { 'fareatlat', 'fareaplat','fninteglat','fareanlat'})%fractional area latency + + + [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP); + for Numofstione = 1:Num_plot + for Numofstitwo = 1:Num_data + Amp_all = squeeze(plot_erp_data(:,Numofstitwo,Numofstione)); + if ~isnan(Amp_out(Numofstitwo,Numofstione)) + [xxx, latsamp, latdiffms] = closest(timex, Amp_out(Numofstitwo,Numofstione)); + line(r_ax, [Amp_out(Numofstitwo,Numofstione) Amp_out(Numofstitwo,Numofstione)],[offset(Numofstione),Amp_all(latsamp)],'Color',line_colors(Numofstitwo,:,:),'LineWidth',3,'LineStyle','--','Marker','x'); + end + end + end + + elseif ismember_bc2(moption, {'peaklatbl','fpeaklat'}) % fractional peak latency && Local peak latency + + [new_erp_data, Amp_out,Lat]= f_ERP_plot_wav(observe_ERPDAT.ERP); + for Numofstione = 1:Num_plot + for Numofstitwo = 1:Num_data + Amp_all = squeeze(plot_erp_data(:,Numofstitwo,Numofstione)); + if ~isnan(Amp_out(Numofstitwo,Numofstione)) + [xxx, latsamp, latdiffms] = closest(timex, Amp_out(Numofstitwo,Numofstione)); + line(r_ax, [Amp_out(Numofstitwo,Numofstione) Amp_out(Numofstitwo,Numofstione)],[offset(Numofstione),Amp_all(latsamp)],'Color',line_colors(Numofstitwo,:,:),'LineWidth',3,'LineStyle','--','Marker','x'); + end + end + end + + end +end + +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_try.m b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_try.m new file mode 100755 index 00000000..87e813f0 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_redrawERP_try.m @@ -0,0 +1,942 @@ +%This function is to plot ERP wave with single or multiple columns on one page. + + + +% Author: Guanghui Zhang & Steve J. Luck & Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + + +function f_redrawERP_try() +% Draw a demo ERP into the axes provided +global gui_erp; +global observe_ERPDAT; + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); + +S_ws_geterpplot = estudioworkingmemory('geterpplot'); + + +%%Parameter from bin and channel panel +Elecs_shown = S_ws_getbinchan.elecs_shown{S_ws_getbinchan.Select_index}; +Bins = S_ws_getbinchan.bins{S_ws_getbinchan.Select_index}; +Bin_chans = S_ws_getbinchan.bins_chans(S_ws_getbinchan.Select_index); +Elec_list = S_ws_getbinchan.elec_list{S_ws_getbinchan.Select_index}; +Matlab_ver = S_ws_getbinchan.matlab_ver; + + + +%%Parameter from plotting panel +try + Min_vspacing = S_ws_geterpplot.min_vspacing(S_ws_getbinchan.Select_index); + Min_time = S_ws_geterpplot.min(S_ws_getbinchan.Select_index); + Max_time = S_ws_geterpplot.max(S_ws_getbinchan.Select_index); + Yscale = S_ws_geterpplot.yscale(S_ws_getbinchan.Select_index); + Timet_low =S_ws_geterpplot.timet_low(S_ws_getbinchan.Select_index); + Timet_high =S_ws_geterpplot.timet_high(S_ws_getbinchan.Select_index); + Timet_step=S_ws_geterpplot.timet_step(S_ws_getbinchan.Select_index); + Fill = S_ws_geterpplot.fill(S_ws_getbinchan.Select_index); + Plority_plot = S_ws_geterpplot.Positive_up(S_ws_getbinchan.Select_index); + ColumnNum = S_ws_geterpplot.Plot_column; +catch + return; +end + +Column_label = ColumnNum(S_ws_getbinchan.Select_index); + +if Bin_chans == 0 + elec_n = S_ws_getbinchan.elec_n(S_ws_getbinchan.Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nchan; +else + elec_n = S_ws_getbinchan.bin_n(S_ws_getbinchan.Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nbin; +end + +% We first clear the existing axes ready to build a new one +if ishandle( gui_erp.ViewAxes ) + delete( gui_erp.ViewAxes ); +end + + +% Get chan labels +S_chan.chan_label = cell(1,max_elec_n); +S_chan.chan_label_place = zeros(1,max_elec_n); + + +if Bin_chans == 0 + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.chanlocs(Elecs_shown(i)).labels; + end +else + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.bindescr(Bins(i)); + end +end + + +%Sets the units of your root object (screen) to pixels +set(0,'units','pixels') +%Obtains this pixel information +Pix_SS = get(0,'screensize'); +%Sets the units of your root object (screen) to inches +set(0,'units','inches') +%Obtains this inch information +Inch_SS = get(0,'screensize'); +%Calculates the resolution (pixels per inch) +Res = Pix_SS./Inch_SS; + + +pb_height = Min_vspacing*Res(4); %px + + +% Plot data in the main viewer fig +splot_n = elec_n; +tsize = 13; + + +clear pb r_ax plotgrid; +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;%%Get background color +catch + ColorB_def = [0.95 0.95 0.95]; +end +if isempty(ColorB_def) + ColorB_def = [0.95 0.95 0.95]; +end +gui_erp.plotgrid = uix.VBox('Parent',gui_erp.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorB_def); + +pageinfo_box = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def); + +gui_erp.plot_wav_legend = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',[1 1 1]); +gui_erp.ViewAxes_legend = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',ColorB_def); + +gui_erp.ViewAxes = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',[1 1 1]); + + +%%Changed by Guanghui Zhang 2 August 2022-------panel for display the processing procedure for some functions, e.g., filtering +xaxis_panel = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def);%%%Message +gui_erp.Process_messg = uicontrol('Parent',xaxis_panel,'Style','text','String','','FontSize',20,'FontWeight','bold','BackgroundColor',ColorB_def); + + +%%Setting title +gui_erp.pageinfo_minus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',@page_minus,'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index ==1 + gui_erp.pageinfo_minus.Enable = 'off'; +end + +gui_erp.pageinfo_plus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',@page_plus,'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index == numel(S_ws_geterpset) + gui_erp.pageinfo_plus.Enable = 'off'; +end + +pageinfo_str = ['Page',32,num2str(S_ws_getbinchan.Select_index),'/',num2str(numel(S_ws_geterpset)),':',32,observe_ERPDAT.ERP.erpname]; + +pageinfo_text = uicontrol('Parent',pageinfo_box,'Style','text','String',pageinfo_str,'FontSize',14,'FontWeight','bold'); + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [1 1 1]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp.pageinfo_minus.Enable = Enable_minus; +gui_erp.pageinfo_plus.Enable = Enable_plus; +gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + +set(pageinfo_box, 'Sizes', [50 50 -1] ); +set(pageinfo_box,'BackgroundColor',ColorB_def); +set(pageinfo_text,'BackgroundColor',ColorB_def); +%Setting title. END,'BackgroundColor',ColorB_def + +%for i=1:splot_n + +% +%%------------Setting the number of data and plotting--------------------- +ndata = 0; +nplot = 0; +if Bin_chans == 0 %if channels with bin overlay + ndata = Bins; + nplot = Elecs_shown; +else %if bins with channel overlay + ndata = Elecs_shown; + nplot = Bins; +end + +% +timeor = observe_ERPDAT.ERP.times; % original time vector +timex = timeor; +[xxx, latsamp, latdiffms] = closest(timex, [Min_time Max_time]); +tmin = latsamp(1); +tmax = latsamp(2); + +if tmin < 1 + tmin = 1; +end + +if tmax > numel(observe_ERPDAT.ERP.times) + tmax = numel(observe_ERPDAT.ERP.times); +end + +plot_erp_data = nan(tmax-tmin+1,numel(ndata)); +for i = 1:splot_n + if Bin_chans == 0 + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i),tmin:tmax,Bins(i_bin))'*Plority_plot; % + end + else + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i_bin),tmin:tmax,Bins(i))'*Plority_plot; % + end + end +end + +perc_lim = Yscale; +percentile = perc_lim*3/2; + +[~,~,b] = size(plot_erp_data); + + +% +%%%------------Setting xticklabels for each row of each wave-------------- +xstep_label = estudioworkingmemory('erp_xtickstep'); +if isempty(xstep_label) + xstep_label =0; +end +if ~xstep_label + [def Timet_step]= default_time_ticks_studio(observe_ERPDAT.ERP, [Min_time,Max_time]); + if ~isempty(def{1,1}) + xticks_clomn = str2num(def{1,1}); + while xticks_clomn(end)<=Max_time + xticks_clomn(numel(xticks_clomn)+1) = xticks_clomn(end)+Timet_step; + if xticks_clomn(end)>Max_time + xticks_clomn = xticks_clomn(1:end-1); + break; + end + end + else + xticks_clomn = (Min_time:Timet_step:Max_time); + end +else + + + xticks_clomn = (Min_time:Timet_step:Max_time); +end +Timet_step_p = ceil(Timet_step/(1000/observe_ERPDAT.ERP.srate));%% Time points of the gap between columns + +% +%%----------------------Modify the data into multiple-columns--------------------------------------- +rowNum = ceil(b/Column_label); +plot_erp_data_new = NaN(size(plot_erp_data,1),size(plot_erp_data,2),rowNum*Column_label); + +plot_erp_data_new(:,:,1:size(plot_erp_data,3)) = plot_erp_data; +plot_erp_data_new_trans = []; + + +if Column_label==1 + for Numofrow = 1:rowNum + plot_erp_data_new_trans(:,:,:,Numofrow) = plot_erp_data_new(:,:,(Numofrow-1)*Column_label+1:Numofrow*Column_label); + end + + clear plot_erp_data; + plot_erp_data_new_trans = permute(plot_erp_data_new_trans,[1,3,2,4]) ; + plot_erp_data = reshape(plot_erp_data_new_trans,size(plot_erp_data_new_trans,1)*size(plot_erp_data_new_trans,2),size(plot_erp_data_new_trans,3),size(plot_erp_data_new_trans,4)); + +elseif Column_label>1 + + plot_erp_data_trans_clumns = NaN(size(plot_erp_data_new,1)*Column_label+(Column_label-1)*Timet_step_p,size(plot_erp_data_new,2),rowNum); + for Numofrow = 1:rowNum + Data_column = plot_erp_data_new(:,:,(Numofrow-1)*Column_label+1:Numofrow*Column_label); + for Numofcolumn = 1:Column_label + low_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+1+(Numofcolumn-1)*Timet_step_p; + high_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+(Numofcolumn-1)*Timet_step_p+size(plot_erp_data_new,1); + plot_erp_data_trans_clumns(low_interval:high_interval,:,Numofrow) = squeeze(Data_column(:,:,Numofcolumn)); + end + end + plot_erp_data = plot_erp_data_trans_clumns; +end + +ind_plot_height = percentile*2; % Height of each individual subplot + +offset = []; +if Bin_chans == 0 + offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height; +else + offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height; +end +[~,~,b] = size(plot_erp_data); +for i = 1:b + plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i); +end + + + +r_ax = axes('Parent', gui_erp.ViewAxes,'Color','none','Box','on','FontWeight','bold'); +hold(r_ax,'on'); +set(gui_erp.plot_wav_legend,'Sizes',[80 -10]); +r_ax_legend = axes('Parent', gui_erp.ViewAxes_legend,'Color','none','Box','off'); +hold(r_ax_legend,'on'); + + +try + f_bin = 1000/observe_ERPDAT.ERP.srate; +catch + f_bin = 1; +end + +ts = observe_ERPDAT.ERP.times(tmin:tmax); +ts_colmn = ts; + +% +%%------------------Adjust the data into multiple/single columns------------ +if Column_label>1 % Plotting waveforms with munltiple-columns + xticks_org = xticks_clomn; + + for Numofcolumn = 1:Column_label-1 + xticks_clomn_add = [1:numel(ts)+Timet_step_p].*f_bin+(ts_colmn(end).*ones(1,numel(ts)+Timet_step_p)); + ts_colmn = [ts_colmn,xticks_clomn_add]; + end + + X_zero_line(1) =ts(1); + for Numofcolumn = 1:Column_label-1 + if Numofcolumn ==1 + X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin + (Timet_step_p/2)*f_bin; + else + X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin + (Timet_step_p)*f_bin; + end + end + + [xticks,xticks_labels] = f_geterpxticklabel(observe_ERPDAT.ERP,xticks_clomn,Column_label,[Min_time Max_time],Timet_step); + ts = ts_colmn; + Min_time = ts(1); + Max_time = ts(end); + +else%% Plotting waveforms with single-column + %%%------------getting xticklabels for each row of each wave-------------- + xticks =xticks_clomn; + X_zero_line(1) =ts(1); + for Numofxlabel = 1:numel(xticks) + xticks_labels{Numofxlabel} = num2str(xticks(Numofxlabel)); + end +end + + +splot_n = size(plot_erp_data,3);%%Adjust the columns + +set(r_ax,'XLim',[Min_time Max_time]); + +[a,c,b] = size(plot_erp_data); +new_erp_data = zeros(a,b*c); +for i = 1:b + new_erp_data(:,((c*(i-1))+1):(c*i)) = plot_erp_data(:,:,i); +end + + +line_colors = erpworkingmemory('PWColor'); +if size(line_colors,1)~= numel(ndata) + if numel(ndata)> size(line_colors,1) + line_colors = get_colors(numel(ndata)); + else + line_colors = line_colors(1:numel(ndata),:,:); + end +end + +if isempty(line_colors) + line_colors = get_colors(numel(ndata)); +end + +line_colors = repmat(line_colors,[splot_n 1]); %repeat the colors once for every plot + + +% +%%------------Setting xticklabels for each row -------------- +x_axs = ones(size(new_erp_data,1),1); +for jj = 1:numel(offset)-1 + plot(r_ax,ts,x_axs.*offset(end),'color',[1 1 1],'LineWidth',1); + set(r_ax,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); + myX_Crossing = offset(jj); + props = get(r_ax); + + tick_bottom = -props.TickLength(1)*diff(props.YLim); + if abs(tick_bottom) > abs(Yscale)/5 + try + tick_bottom = - abs(Yscale)/5; + catch + tick_bottom = tick_bottom; + end + elseif abs(tick_bottom)1 + if numel(offset)==jj + kkkk = 1; + else + kkkk = 2; + end + for iCount = kkkk:nTicks + xtick_label = (props.XTickLabel(iCount, :)); + text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', 12, ... + 'FontName', props.FontName, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits, ... + 'FontWeight', 'bold'); + end + end + +end + +% +%%----------------Start:Remove xticks for the columns without waves in the last row------------------------- +Element_left = numel(nplot) - (ceil(numel(nplot)/Column_label)-1)*Column_label; +x_axset = plot(r_ax,ts,x_axs.*offset(end),'color', [1 1 1],'LineWidth',1); +set(r_ax,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); +myX_Crossing = offset(end); +props = get(r_ax); + +tick_bottom = -props.TickLength(1)*diff(props.YLim); +if abs(tick_bottom) > abs(Yscale)/5 + try + tick_bottom = - abs(Yscale)/5; + catch + tick_bottom = tick_bottom; + end +elseif abs(tick_bottom)1 + for iCount = 1:ceil(nTicks/Column_label*Element_left) + xtick_label = (props.XTickLabel(iCount, :)); + text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', 12, ... + 'FontName', props.FontName, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits, ... + 'FontWeight', 'bold'); + end +end +%%--------------------------End:Remove xticks for the columns without waves in the last row------------------------- + +% +%%-----------------Get zeroline for each row----------------------------- +row_baseline = NaN(numel(ts),splot_n); +count = 0; +for Numofsplot = 0:splot_n-1 + for Numofcolumn = 1:Column_label + count = count +1; + if count> numel(nplot) + + break; + + end + low_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+1+(Numofcolumn-1)*Timet_step_p; + high_interval = size(plot_erp_data_new,1)*(Numofcolumn-1)+(Numofcolumn-1)*Timet_step_p+size(plot_erp_data_new,1); + row_baseline(low_interval:high_interval,Numofsplot+1) = ones(numel(low_interval:high_interval),1).*offset(Numofsplot+1); + end +end + + +% +%%-------------------------Plotting ERP waves----------------------------- +pb_here = plot(r_ax,ts, [new_erp_data],'LineWidth',1.5); + +set(r_ax, 'XTick', [], 'XTickLabel', []); + +% +%%----------------Marking 0 point (event-locked)-------------------------- +[xxx, latsamp_0, latdiffms_0] = closest(xticks, [0]); +if numel(offset)>1 + if latdiffms_0 ==0 + for Numofcolumn = 1:Column_label + xline(r_ax,xticks((Numofcolumn-1)*numel(xticks_clomn)+latsamp_0),'k-.','LineWidth',1);%%'Color',Marking start time point for each column + end + end +elseif numel(offset)==1 + + for Numofcolumn = 1:numel(nplot) + xline(r_ax,xticks((Numofcolumn-1)*numel(xticks_clomn)+latsamp_0),'k-.','LineWidth',1);%%'Color',Marking start time point for each column + end +end +% +yticks = -perc_lim:perc_lim:((2*percentile*b)-(2*perc_lim)); +ylabs = repmat([-perc_lim 0 perc_lim],[1,b]); +oldlim = [-percentile yticks(end)-perc_lim+percentile]; +top_vspace = max( max( new_erp_data))-oldlim(2); +bot_vspace = min( min( new_erp_data))-oldlim(1); +if top_vspace < 0 + top_vspace = 0; +end + +if bot_vspace > 0 + bot_vspace = 0; +end +newlim = oldlim + [bot_vspace top_vspace]; +set(r_ax,'XLim',[Min_time Max_time],'Ylim',newlim); + + +% +%%--------------Setting color for each wave-------------------------- +% if Column_label>1 +% for i = 0:splot_n-1 +% r_ax.Children(end-i).Color = [1 1 1]; +% end +% end + +% for i = splot_n+1:numel(pb_here) +% pb_here(i).Color = line_colors((i-splot_n),:); +% end +for i = 1:numel(pb_here) + pb_here(i).Color = line_colors(i,:); +end +% +% for i = 1:splot_n-1 +% pb_here(i).Color = [0 0 0]; +% pb_here(i).LineWidth=.01; +% end + + + + +%%------------Marking start time point for each column--------------------- +if Column_label>1 + for ii = 2:numel(X_zero_line) + xline(r_ax,X_zero_line(ii), 'y--','LineWidth',2); + end +end + +for Numofplot = 1:size(row_baseline,2) + plot(r_ax,ts,row_baseline(:,Numofplot),'color',[0 0 0],'LineWidth',1.5); +end +ylabs = [fliplr(-perc_lim:-perc_lim:newlim(1)) ylabs(2:end-1) (yticks(end):perc_lim:newlim(2))-yticks(end)+perc_lim]; +yticks = [fliplr(-perc_lim:-perc_lim:newlim(1)) yticks(2:end-1) yticks(end):perc_lim:newlim(2)]; + + + +% +%%-------------Name of bin/channel for each subplot-------------------------- +if Column_label==1 + if numel(offset)>1 + count = 0; + for i = 0:numel(offset)-1 + leg_str = ''; + + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',Elec_list{Elecs_shown(count)}); + else + leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)}); + end + catch + leg_str = ''; + end + text(r_ax,ts(1),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + end + end + + try + if Bin_chans == 0 + leg_str = sprintf('%s',Elec_list{Elecs_shown(end)}); + else + leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(end)}); + end + catch%% + leg_str = ''; + end + + try + text(r_ax,ts(1),offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + catch + text(r_ax,ts(1),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end +else%% Getting y ticks and legends for multiple-columns + if numel(offset)>1 + count = 0; + for i = 0:numel(offset)-1 + leg_str = ''; + for Numofcolumn = 1: Column_label + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',Elec_list{Elecs_shown(count)}); + else + leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)}); + end + catch + leg_str = ''; + end + if Numofcolumn ==1 + text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + else + text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + end + end + end + end + + + count = (numel(offset)-1)*Column_label; + leg_str = ''; + for Numofcolumn = 1:Column_label + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',Elec_list{Elecs_shown(count)}); + else + leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)}); + end + catch%% + leg_str = ''; + end + try + + if Numofcolumn ==1 + text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + else + text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 14); + end + catch + + if Numofcolumn ==1 + text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + else + text(r_ax,X_zero_line(Numofcolumn)+Timet_step/2,Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end + % text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 14); + end + end + +end +% + + +% +%%-------------Setting x/yticks and ticklabels-------------------------------- +Ylabels_new = ylabs.*Plority_plot; +[~,Y_label] = find(Ylabels_new == -0); +Ylabels_new(Y_label) = 0; +% xticks = (Min_time:Timet_step:Max_time); +% some options currently only work post Matlab R2016a ,'XLim',[Min_time Max_time],'XLim',[Min_time Max_time] +if Matlab_ver >= 2016 + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','origin',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim,'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels); +else + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','bottom',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim, 'XTick',xticks, ... + 'box','off', 'Color','none','xticklabels',xticks_labels); + hline(0,'k'); % backup xaxis +end +if Column_label>1 + set(r_ax,'XGrid','on','YGrid','on');%,'XDir','reverse' +end +set(r_ax, 'XTick', [], 'XTickLabel', [],'FontWeight', 'bold'); +r_ax.YAxis.LineWidth = 1.5; + +hold(r_ax,'off'); +% + + + +% +%%--------------------------Setting legend--------------------------------- +line_colors_ldg = erpworkingmemory('PWColor'); +if isempty(line_colors_ldg) + line_colors_ldg = get_colors(numel(ndata)); +end + +if size(line_colors_ldg,1)~= numel(ndata) + if numel(ndata)> size(line_colors_ldg,1) + line_colors_ldg = get_colors(numel(ndata)); + else + line_colors_ldg = line_colors_ldg(1:numel(ndata),:,:); + end +end + +for Numofplot = 1:size(plot_erp_data,2) + plot(r_ax_legend,[0 0],'Color',line_colors_ldg(Numofplot,:,:),'LineWidth',3) +end + +if Bin_chans == 0 + + Leg_Name = {}; + + for Numofbin = 1:numel(Bins) + Leg_Name{Numofbin} = strcat('Bin',num2str(Bins(Numofbin))); + end +else + for Numofchan = 1:numel(Elecs_shown) + Leg_Name{Numofchan} = Elec_list{Numofchan}; + end +end +legend(r_ax_legend,Leg_Name,'FontSize',14,'TextColor','blue'); +legend(r_ax_legend,'boxoff'); +% + +%-------fix scaling shrinkage-------------- +pos_fix = r_ax.Position; +pos_fix(2) = 1; % Start at the bottom +pos_fix(4) = pb_height - 1; % fill the height; + +gui_erp.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high +gui_erp.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high +gui_erp.plotgrid.Units = 'pixels'; +if splot_n*pb_height<(gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1))&&Fill + pb_height = (gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1)-gui_erp.plotgrid.Heights(2))/splot_n; +end + +gui_erp.ViewAxes.Heights = splot_n*pb_height; +gui_erp.plotgrid.Units = 'normalized'; + +end % redrawDemo + + +function colors = get_colors(ncolors) +% Each color gets 1 point divided into up to 2 of 3 groups (RGB). +degree_step = 6/ncolors; +angles = (0:ncolors-1)*degree_step; +colors = nan(numel(angles),3); +for i = 1:numel(angles) + if angles(i) < 1 + colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75; + elseif angles(i) < 2 + colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75; + elseif angles(i) < 3 + colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75; + elseif angles(i) < 4 + colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75; + elseif angles(i) < 5 + colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75; + else + colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75; + end +end +end + + + +%------------------Display the waveform for proir ERPset-------------------- +function page_minus(~,~) +global observe_ERPDAT; +global gui_erp; + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); + + +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end + +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); + + +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); + + +observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp.pageinfo_minus.Enable = Enable_minus; +gui_erp.pageinfo_plus.Enable = Enable_plus; +% f_redrawERP_mt_viewer(); +gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +end + + + + + +%------------------Display the waveform for next ERPset-------------------- +function page_plus(~,~) +global observe_ERPDAT; +global gui_erp; + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); + + + + +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end + +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); + +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); + +observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [1 1 1]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + + + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp.pageinfo_minus.Enable = Enable_minus; +gui_erp.pageinfo_plus.Enable = Enable_plus; +gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +end + + diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.fig b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.fig new file mode 100755 index 00000000..b1502ebb Binary files /dev/null and b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.fig differ diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.m b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.m new file mode 100755 index 00000000..c11257e0 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_spectral_analysis_advance.m @@ -0,0 +1,814 @@ +% +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% Copyright (C) 2022 Guanghui ZHANG & Steven Luck, +% Center for Mind and Brain, University of California, Davis, +% ghzhang@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = f_spectral_analysis_advance(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_spectral_analysis_advance_OpeningFcn, ... + 'gui_OutputFcn', @f_spectral_analysis_advance_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_spectral_analysis_advance_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for f_spectral_analysis_advance +handles.output = []; +try + ERP = varargin{1}; +catch + ERP = []; + ERP = buildERPstruct([]); + ERP.xmin = 0; + ERP.xmax = 0; + ERP.nbin = 1; + ERP.nchan = 1; + +end +handles.ERP = ERP; + +try + def = varargin{2}; +catch + def = {1,[], [], [1 16], 1, 1,1,0}; +end + +bin_chan_label = def{1}; +BinArray = def{2}; +ChanArray = def{3}; +freqRange = def{4}; +Auto_freq = def{5}; +RowNum = def{6}; +ColumnNum = def{7}; + +listb = {''}; +nbin = ERP.nbin; % Total number of bins +try + for b=1:nbin + listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; + end +catch + listb = {}; +end + + +%%%set(handles.popupmenu_bins,'String', listb) +handles.listb = listb; +handles.indxlistb = BinArray; + + +nchan = ERP.nchan; % Total number of channels +if ~isfield(ERP.chanlocs,'labels') + for e=1:nchan + ERP.chanlocs(e).labels = ['Ch' num2str(e)]; + end +end +listch = {''}; +for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ]; +end +handles.listch = listch; +handles.indxlistch = ChanArray; + +for Numofrow = 1:256 + FramString{Numofrow}= num2str(Numofrow); +end + +set(handles.popupmenu_row_num,'String',FramString); +set(handles.popupmenu_column_num,'String',FramString); + +set(handles.popupmenu_row_num,'Value',nchan); + +if bin_chan_label ==1 + set(handles.radiobutton_all_bin_chan,'Value',1); + set(handles.radiobutton_selected_bin_chan,'Value',0); + set(handles.radiobutton_Custom_bin_chan,'Value',0); + set(handles.pushbutton_browse_bin,'Enable','off'); + set(handles.pushbutton_browse_chan,'Enable','off'); + set(handles.edit_bin_custom,'String',num2str(vect2colon([1:ERP.nbin],'Sort', 'on'))); + set(handles.edit_channel_custom,'String',num2str(vect2colon([1:ERP.nchan],'Sort', 'on'))); +elseif bin_chan_label ==2 + set(handles.radiobutton_all_bin_chan,'Value',0); + set(handles.radiobutton_selected_bin_chan,'Value',1); + set(handles.radiobutton_Custom_bin_chan,'Value',0); + set(handles.pushbutton_browse_bin,'Enable','off'); + set(handles.pushbutton_browse_chan,'Enable','off'); + [chk, msgboxText] = chckbinandchan(ERP, BinArray, ChanArray); + if chk(1) + BinString = [1:ERP.nbin]; + else + BinString = BinArray; + end + if chk(2) + ChanString = [1:ERP.nchan]; + else + ChanString = ChanArray; + end + + set(handles.edit_bin_custom,'String',num2str(vect2colon(BinString,'Sort', 'on'))); + set(handles.edit_channel_custom,'String',num2str(vect2colon(ChanString,'Sort', 'on'))); + +elseif bin_chan_label ==3 + set(handles.radiobutton_all_bin_chan,'Value',0); + set(handles.radiobutton_selected_bin_chan,'Value',0); + set(handles.radiobutton_Custom_bin_chan,'Value',1); + set(handles.pushbutton_browse_bin,'Enable','on'); + set(handles.pushbutton_browse_chan,'Enable','on'); +else + set(handles.radiobutton_all_bin_chan,'Value',1); + set(handles.radiobutton_selected_bin_chan,'Value',0); + set(handles.radiobutton_Custom_bin_chan,'Value',0); + set(handles.pushbutton_browse_bin,'Enable','off'); + set(handles.pushbutton_browse_chan,'Enable','off'); + set(handles.edit_bin_custom,'String',num2str(vect2colon([1:ERP.nbin],'Sort', 'on'))); + set(handles.edit_channel_custom,'String',num2str(vect2colon([1:ERP.nchan],'Sort', 'on'))); +end +set(handles.checkbox_freq_ticks_auto,'Value',1); +set(handles.edit_freq_tick_auto,'Enable','off'); + +set(handles.edit_freq_range,'String',num2str(freqRange)); + + + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio',version,' - Plot and save spectrum for the selected ERP GUI ']) +handles = painterplabstudio(handles); +handles = setfonterplabestudio(handles); + +% helpbutton + +% +% Color GUI +% +% handles = painterplab(handles); + +% +% Set font size +% +% handles = setfonterplab(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +% helpbutton + +% UIWAIT makes f_spectral_analysis_advance wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_spectral_analysis_advance_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); + +% --- Executes on button press in radiobutton_all_bin_chan. +function radiobutton_all_bin_chan_Callback(hObject, eventdata, handles) +set(handles.radiobutton_Custom_bin_chan,'Value',0); +set(handles.radiobutton_selected_bin_chan,'Value',0); +set(handles.radiobutton_all_bin_chan,'Value',1); +set(handles.pushbutton_browse_bin,'Enable','off'); +set(handles.pushbutton_browse_chan,'Enable','off'); +BinString = handles.ERP.nbin; +ChanString = handles.ERP.nchan; + +set(handles.edit_bin_custom,'String',num2str(vect2colon(1:BinString,'Sort', 'on'))); +set(handles.edit_channel_custom,'String',num2str(vect2colon(1:ChanString,'Sort', 'on'))); + +% --- Executes on button press in radiobutton_selected_bin_chan. +function radiobutton_selected_bin_chan_Callback(hObject, eventdata, handles) +set(handles.radiobutton_Custom_bin_chan,'Value',0); +set(handles.radiobutton_selected_bin_chan,'Value',1); +set(handles.radiobutton_all_bin_chan,'Value',0); +set(handles.pushbutton_browse_bin,'Enable','off'); +set(handles.pushbutton_browse_chan,'Enable','off'); + +ERP = handles.ERP; + +BinString = handles.indxlistb; +ChanString = handles.indxlistch; +if isempty(BinString) + BinString =[1:ERP.nbin]; +end +if isempty(ChanString) + ChanString =[1:ERP.nchan]; +end +[chk, msgboxText] = chckbinandchan(ERP, BinString, ChanString); +if chk(1) + BinString = 1:ERP.nbin; +end +if chk(2) + ChanString = 1:ERP.nchan; +end +set(handles.edit_bin_custom,'String',num2str(vect2colon(BinString,'Sort', 'on'))); +set(handles.edit_channel_custom,'String',num2str(vect2colon(ChanString,'Sort', 'on'))); + + +% --- Executes on button press in radiobutton_Custom_bin_chan. +function radiobutton_Custom_bin_chan_Callback(hObject, eventdata, handles) +set(handles.radiobutton_Custom_bin_chan,'Value',1); +set(handles.radiobutton_selected_bin_chan,'Value',0); +set(handles.radiobutton_all_bin_chan,'Value',0); +set(handles.pushbutton_browse_bin,'Enable','on'); +set(handles.pushbutton_browse_chan,'Enable','on'); + + +function edit_bin_custom_Callback(hObject, eventdata, handles) +BinString = str2num(handles.edit_bin_custom.String); +ERP = handles.ERP; +% [chk, msgboxText] = chckbinandchan(ERP, BinString, []); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1); + +if chk(1) + title = 'EStudio: Spectral analysis GUI input'; + errorfound(msgboxText, title); + return; +end + + + +% --- Executes during object creation, after setting all properties. +function edit_bin_custom_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function edit_channel_custom_Callback(hObject, eventdata, handles) +ChanString = str2num(handles.edit_channel_custom.String); +ERP = handles.ERP; +[chk, msgboxText] = chckbinandchan(ERP, [], ChanString); + + +if chk(2) + title = 'EStudio: Spectral analysis GUI input'; + errorfound(msgboxText, title); + return; +end + +chanArray = ChanString; +ColumnNum = get(handles.popupmenu_column_num, 'Value'); +RowNum = ceil((numel(chanArray))/ColumnNum); +ColumnNum = ceil((numel(chanArray))/RowNum); +if RowNum<=0 + RowNum=1; +end +set(handles.popupmenu_row_num, 'Value', RowNum); +set(handles.popupmenu_column_num, 'Value', ColumnNum); + +% --- Executes during object creation, after setting all properties. +function edit_channel_custom_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_browse_bin_Callback(hObject, eventdata, handles) +listb = handles.listb; +indxlistb = handles.indxlistb; +indxlistb = indxlistb(indxlistb<=length(listb)); +titlename = 'Select Bin(s)'; + +if get(hObject, 'Value') + %set(handles.pushbutton_browsechan, 'Enable', 'off') + if ~isempty(listb) + bin = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(bin) + set(handles.edit_bin_custom, 'String', vect2colon(bin, 'Delimiter', 'off')); + handles.indxlistb = bin; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No bin information was found'; + title = 'EStudio: Spectral analysis GUI input'; + errorfound(msgboxText, title); + return + end + +end + + + +% --- Executes on button press in pushbutton_browse_chan. +function pushbutton_browse_chan_Callback(hObject, eventdata, handles) +listch = handles.listch; +indxlistch = handles.indxlistch; +indxlistch = indxlistch(indxlistch<=length(listch)); +titlename = 'Select Channel(s)'; + +if get(hObject, 'Value') + if ~isempty(listch) + ch = browsechanbinGUI(listch, indxlistch, titlename); + if ~isempty(ch) + set(handles.edit_channel_custom, 'String', vect2colon(ch, 'Delimiter', 'off')); + handles.indxlistch = ch; + + chanArray = ch; + ColumnNum = get(handles.popupmenu_column_num, 'Value'); + RowNum = ceil((numel(chanArray))/ColumnNum); + if RowNum<=0 + RowNum=1; + end + set(handles.popupmenu_row_num, 'Value', RowNum); + + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No channel information was found'; + title = 'EStudio: Spectral analysis GUI input'; + errorfound(msgboxText, title); + return + end +end + +%Freq. range [min max] in Hz +function edit_freq_range_Callback(hObject, eventdata, handles) +freqx = str2num(get(handles.edit_freq_range, 'String')); +if isempty(freqx) + msgboxText = 'Invalid input for frequency range of interest'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end +if length(freqx)~=2 + msgboxText = 'Please, enter two values'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end + + +if freqx(1)>= freqx(2) + msgboxText = 'The first value must be smaller than the second one!'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end +ERP = handles.ERP; +try + freq_half = ERP.srate/2; +catch + freq_half =freqx(2); +end + +if freqx(2)> freq_half + msgboxText = ['Second value must be smaller than',32,num2str(ERP.srate/2)]; + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(msgboxText, title); + return +end + +Auto_tick = get(handles.checkbox_freq_ticks_auto,'Value'); + +if ~Auto_tick + def_ticks = default_time_ticks(handles.ERP, freqx); + set(handles.edit_freq_tick_auto,'String',num2str(def_ticks{1})); +end + + +% --- Executes during object creation, after setting all properties. +function edit_freq_range_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +% --- Executes on button press in checkbox_freq_ticks_auto. +function checkbox_freq_ticks_auto_Callback(hObject, eventdata, handles) +if get(hObject, 'Value') + set(handles.edit_freq_tick_auto,'Enable','off'); + set(handles.edit_freq_tick_auto,'String',''); +else + set(handles.edit_freq_tick_auto,'Enable','on'); + + freqx = str2num(get(handles.edit_freq_range, 'String')); % XL + if isempty(freqx) + msgboxText = 'Invalid input for frequency range of interest on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return + end + if length(freqx)~=2 + msgboxText = 'Please, enter two values on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return + end + + + if freqx(1)>= freqx(2) + msgboxText = 'The first value must be smaller than the second one on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return + end + if freqx(1)<0 + msgboxText = 'The first value must be larger than 0Hz on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return + end + + ERP = handles.ERP; + if freqx(2)> ERP.srate/2 + msgboxText = ['Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.srate/2),'Hz',32,'on "Freq. range [min max] in Hz"']; + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(msgboxText, title); + return + end + + + def_ticks = default_time_ticks(handles.ERP, freqx); + if ~isempty(def_ticks) + set(handles.edit_freq_tick_auto,'String',num2str(def_ticks{1})); + end +end + + + + + +function edit_freq_tick_auto_Callback(hObject, eventdata, handles) +answer = get(handles.edit_freq_tick_auto,'String'); +nanswer = str2num(strtrim(char(answer))); +if isempty(nanswer) + msgboxText = 'Invalid range of values on freq. ticks!\n'; + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(sprintf(msgboxText), title); + return +end + + + + + + +% --- Executes during object creation, after setting all properties. +function edit_freq_tick_auto_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_freq_tick_auto (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on selection change in popupmenu_row_num. +function popupmenu_row_num_Callback(hObject, eventdata, handles) +chanArraystr = get(handles.edit_channel_custom, 'String'); +chanArray = str2num(chanArraystr); +if isempty(chanArray) + chanArray = [1:handles.ERP.nchan]; +end +RowNum= get(handles.popupmenu_row_num, 'Value'); +ColumnNum = ceil((numel(chanArray))/RowNum); +if ColumnNum<=0 + ColumnNum=1; +end +set(handles.popupmenu_column_num, 'Value', ColumnNum); + + +% --- Executes during object creation, after setting all properties. +function popupmenu_row_num_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu_row_num (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on selection change in popupmenu_column_num. +function popupmenu_column_num_Callback(hObject, eventdata, handles) + +chanArraystr = get(handles.edit_channel_custom, 'String'); +chanArray = str2num(chanArraystr); + +if isempty(chanArray) + chanArray = [1:handles.ERP.nchan]; +end +ColumnNum = get(handles.popupmenu_column_num, 'Value'); +RowNum = ceil((numel(chanArray))/ColumnNum); +if RowNum<=0 + RowNum=1; +end +set(handles.popupmenu_row_num, 'Value', RowNum); + + +% --- Executes during object creation, after setting all properties. +function popupmenu_column_num_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu_column_num (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) + +handles.output = []; +disp('User selected Cancel'); +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +% %-------------------------------------------------------------------------- +% function pushbutton_help_Callback(hObject, eventdata, handles) +% % doc pop_export2text +% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser +%-------------------------------------------------------------------------- +function pushbutton_apply_Callback(hObject, eventdata, handles) + +BinArray = str2num(handles.edit_bin_custom.String); +ChanArray = str2num(handles.edit_channel_custom.String); +ERP = handles.ERP; +[chk, msgboxText] = chckbinandchan(ERP, BinArray, ChanArray); +if chk(1) + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(sprintf(msgboxText), title); + return; +end +if chk(2) + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(sprintf(msgboxText), title); + return; +end + + + +freqRange = str2num(get(handles.edit_freq_range, 'String')); % XL +if isempty(freqRange) + msgboxText = 'Invalid input for frequency range of interest on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end +if length(freqRange)~=2 + msgboxText = 'Please, enter two values on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end + + +if freqRange(1)>= freqRange(2) + msgboxText = 'The first value must be smaller than the second one on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end +if freqRange(1)<0 + msgboxText = 'The first value must be larger than 0Hz on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end + + +if freqRange(2)> ERP.srate/2 + msgboxText = ['Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.srate/2),'Hz',32,'on "Freq. range [min max] in Hz"']; + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(msgboxText, title); + return +end + + + + +if handles.checkbox_freq_ticks_auto.Value + Auto_freq = []; +else + Auto_freq_String = handles.edit_freq_tick_auto.String; + Auto_freq = str2num(Auto_freq_String); +end + +RowNum = handles.popupmenu_row_num.Value; +ColumnNum = handles.popupmenu_column_num.Value; + +if handles.radiobutton_all_bin_chan.Value + bin_chan_label = 1; +elseif handles.radiobutton_selected_bin_chan.Value + bin_chan_label = 2; +elseif handles.radiobutton_Custom_bin_chan.Value + bin_chan_label = 3; +end + + +Save_label = handles.pushbutton_save.Value; + +answer = {bin_chan_label,BinArray, ChanArray,freqRange,Auto_freq,RowNum,ColumnNum,Save_label}; +handles.output = answer; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton_save. +function pushbutton_save_Callback(hObject, eventdata, handles) +BinArray = str2num(handles.edit_bin_custom.String); +ChanArray = str2num(handles.edit_channel_custom.String); +ERP = handles.ERP; +[chk, msgboxText] = chckbinandchan(ERP, BinArray, ChanArray); +if chk(1) + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(sprintf(msgboxText), title); + return; +end +if chk(2) + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(sprintf(msgboxText), title); + return; +end + +freqRange = str2num(get(handles.edit_freq_range, 'String')); % XL +if isempty(freqRange) + msgboxText = 'Invalid input for frequency range of interest on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end +if length(freqRange)~=2 + msgboxText = 'Please, enter two values on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end + + +if freqRange(1)>= freqRange(2) + msgboxText = 'The first value must be smaller than the second one on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end +if freqRange(1)<0 + msgboxText = 'The first value must be larger than 0Hz on "Freq. range [min max] in Hz"'; + title = 'EStudio: f_spectral_analysis_advance().'; + errorfound(msgboxText, title); + return +end + + +if freqRange(2)> ERP.srate/2 + msgboxText = ['Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.srate/2),'Hz',32,'on "Freq. range [min max] in Hz"']; + title = 'ERPLAB Studio: f_ERP_spectral_advance_GUI() error'; + errorfound(msgboxText, title); + return +end + + + + +if handles.checkbox_freq_ticks_auto.Value + Auto_freq = []; +else + Auto_freq_String = handles.edit_freq_tick_auto.String; + Auto_freq = str2num(Auto_freq_String); +end + +RowNum = handles.popupmenu_row_num.Value; +ColumnNum = handles.popupmenu_column_num.Value; + +if handles.radiobutton_all_bin_chan.Value + bin_chan_label = 1; +elseif handles.radiobutton_selected_bin_chan.Value + bin_chan_label = 2; +elseif handles.radiobutton_Custom_bin_chan.Value + bin_chan_label = 3; +end + + +Save_label = handles.pushbutton_save.Value; + +answer = {bin_chan_label,BinArray, ChanArray,freqRange,Auto_freq,RowNum,ColumnNum,Save_label}; +handles.output = answer; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + handles.output = []; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + + + + +function [chk, msgboxText] = chckbinandchan(ERP, binArray, chanArray) +chk=[0 0]; +msgboxText = ''; +if isempty(binArray) + msgboxText = 'You have not specified any bin'; + chk(1) = 1; + % return +end +if any(binArray<=0) + msgboxText = sprintf('Invalid bin index.\nPlease specify only positive integer values.'); + chk(1) = 1; + return +end +if any(binArray>ERP.nbin) + msgboxText = sprintf('Bin index out of range!\nYou only have %g bins in this ERPset',ERP.nbin); + chk(1) = 1; + return +end +if length(binArray)~=length(unique_bc2(binArray)) + msgboxText = 'You have specified repeated bins for plotting.'; + chk(1) = 1; + return +end +if isempty(chanArray) + msgboxText = 'You have not specified any channel'; + chk(2) = 1; + return +end +if any(chanArray<=0) + msgboxText = sprintf('Invalid channel index.\nPlease specify only positive integer values.'); + chk(2) = 1; + return +end +if any(chanArray>ERP.nchan) + msgboxText = sprintf('Channel index out of range!\nYou only have %g channels in this ERPset', ERP.nchan); + chk(2) = 1; + return +end +if length(chanArray)~=length(unique_bc2(chanArray)) + msgboxText = 'You have specified repeated channels for plotting.'; + chk(2) = 1; + return +end diff --git a/studio_functions/Functions/EStudio/ERP Tab/f_testsyntaxtype.m b/studio_functions/Functions/EStudio/ERP Tab/f_testsyntaxtype.m new file mode 100755 index 00000000..23c45a08 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/f_testsyntaxtype.m @@ -0,0 +1,94 @@ +%-------------------------------------------------------------------------- +function [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn, whocall) +val = 1; +formulaArray = FormulaArrayIn; + +if isempty(formulaArray) + return +else + formulaArray = strtrim(cellstr(formulaArray)); +end +nformulas = length(formulaArray); +[expspliter parts] = regexp(formulaArray, '=','match','split'); +ask4fix = 1; +wantfix = 0; +newnumbin = 1; + +for t=1:nformulas + fcomm = formulaArray{t}; + tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013) + + if isempty(tokcommentb) % skip comment symbol + pleft = regexpi(parts{t}{1}, '(\s*nb[in]*\d+)', 'tokens'); + plcom = regexpi(parts{t}{1}, '(\s*b[in]*\d+)', 'tokens'); + + if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For non recursive mode, left side of equation\nmust be define as a new bin.\n'... + 'For instance, nbin1 = ...\n\n'... + 'Do you want that EStudio corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for non recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix = 1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + elseif ~isempty(pleft) && strcmpi(whocall,'recu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For recursive mode, left side of equation cannot\nbe define as a new bin.\n'... + 'For instance, you must write bin1 = ...\n\n'... + 'Do you want that EStudio corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix =1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + %else + % wantfix = 0; + + end + if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC + fprintf('WARNING: equation %s ', formulaArray{t}) + if strcmpi(whocall,'recu') % for recursive mode delete the n in nch + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2})); + else + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*b(\D*)(\d*)',['nb$1' num2str(newnumbin)],'ignorecase')), strtrim(parts{t}{2})); + newnumbin = newnumbin+1; + end + fprintf('was changed to equation %s \n', formulaArray{t}) + end + end +end +% if val==1 +% set(handles.editor,'String', char(formulaArray)); +% end + diff --git a/studio_functions/Functions/EStudio/ERP Tab/geterplabstudiodef.m b/studio_functions/Functions/EStudio/ERP Tab/geterplabstudiodef.m new file mode 100755 index 00000000..670920f5 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/geterplabstudiodef.m @@ -0,0 +1,21 @@ +% PURPOSE: gets current ERPLAB's version +% +% FORMAT: +% +% version = geterplabversion; +% +% or +% +% +% [version reldate] = geterplabversion; % reldate=release date + + +function [version reldate,ColorB_def,ColorF_def,errorColorF_def,ColorBviewer_def] = geterplabstudiodef + +erplab_studio_default_values; +version = erplabstudiover; +reldate = erplabstudiorel; +ColorB_def =ColorB; +ColorF_def=ColorF; +errorColorF_def = errorColorF; +ColorBviewer_def = ColorBviewer; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/mini_viewer.m b/studio_functions/Functions/EStudio/ERP Tab/mini_viewer.m new file mode 100755 index 00000000..f94ce9db --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/mini_viewer.m @@ -0,0 +1,434 @@ +% +% We need a very fancy data structure system. We've got an array of our +% 'pages'. Each page is a structure. Each page has a property 'data'. In order to graph effectively it's 2 +% dimensional. It's a series of X by Y matrices compounded horizontally. +% Each column represents one line of data. Each 'chunk' (Length Y) +% represents one of three things: A bin, a channel, or an ERPset. If we +% were to look at one bin as a chunk, each column could either represent a +% channel or an ERPset. +% +% We can change to this system fairly easily. Replace 'nchan' with +% 'nlines', 'nbin' with 'nplots', etc. Then create a func to turn ERP +% structure into local data structure based on the 3 way intersection of +% channels, bins, and ERPsets. +% + +% [ 1 2 3 1 2 3 +% 1 2 3 1 2 3 +% 1 2 3 1 2 3 ] + +function varargout = mini_viewer(varargin) + parent = uiextras.Empty(); + boxpan = uiextras.Empty(); + inpd = []; + data = []; + olddata = []; + child_vs = {}; + floating = 0<1; + havedat = 0<1; + + % Lines, Plots, Pages + % 1 = Chans, 2 = Bins, 3 = ERPsets + ord = [2 1 3]; + + if nargin == 0 + havedat = 0>1; + elseif nargin == 1 + fig = figure( 'Name', 'ERP Explorer', ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off'); + parent = fig; + data = cell2mat(varargin(1)); + else + data = cell2mat(varargin(1)); + parent = [varargin{2}]; + floating = 1<0; + end + erp_tabs = uiextras.TabPanel('Parent', parent, 'Padding', 5); + + olddata = data; + + data = erp2loc(data); + + data = data{:}; + + drawUI() + ret_v = struct('tabs', erp_tabs, 'data', olddata); + varargout{1} = ret_v; + + function drawUI() + + havedat = numel(data)>0; + + delete(erp_tabs.Children); + if havedat + tabnames = cell(size(data)); + tabs = zeros(size(data)); + [~,a] = size(data); + for i = 1:a + tabs(i) = uix.HBoxFlex( 'Parent', erp_tabs, 'Spacing', 10 ); + dat = data(i); + tabnames(i) = {dat.name}; + end + + erp_tabs.TabNames = tabnames; + erp_tabs.SelectedChild = 1; + erp_tabs.TabSize = 120; + for tabn = 1:numel(tabs) + TAB = tabs(tabn); + cdat = data(tabn); + hbox = uiextras.HBox('Parent', TAB); + boxpan = uiextras.BoxPanel('Parent', hbox); + [d1,d2,d3] = size(cdat.data); + plot_erp_data = cdat.data; +% for i = 1:cdat.nlin +% ndata = 1:cdat.nplot; +% for i_bin = 1:numel(ndata) +% el_shown = 1:cdat.nlin; +% +% plot_erp_data(:,(i_bin+((i-1)*numel(ndata)))) = cdat.data(el_shown(i),1:d2,d3)'; % + (i+1)*S.display_offset; +% end +% end + offset = (repmat(kron(1:cdat.nplot,ones(1,cdat.nlin)),[500 1])-1)*30; + plot_erp_data = plot_erp_data + offset; + drawERP(plot_erp_data,boxpan,cdat) + vpanels = uiextras.VBox('Parent', hbox); + dat_sel = uiextras.BoxPanel('Parent', vpanels,'Title','Data Selector'); + pl_ops = uiextras.BoxPanel('Parent', vpanels,'Title','Plotting Options'); + + % Data Selector + ds_vb = uiextras.VBox('Parent',dat_sel); + ds_grid = uiextras.Grid('Parent',ds_vb); + + uicontrol('Style','text','String','Chans','Parent',ds_grid); + cs = {cdat.channames}; + chan_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',[{'ALL'}, cs{:}],'callback',@temp,'Max',2,'Min',0); + + uicontrol('Style','text','String','Bins','Parent',ds_grid); + bs = cdat.binnames; + bin_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',[{'ALL'}, bs{:}],'callback',@temp,'Max',2,'Min',0); + + set( ds_grid, 'ColumnSizes', [-1 -1], 'RowSizes', [25, -1] ); + + b_c = uicontrol('Style','popupmenu','Parent',ds_vb,'String',{'Channels by Bins','Bins by Channels'},'callback',@temp); + + set( ds_vb, 'Sizes', [-1, 20] ); + + % Plotting Options + pl_grid = uiextras.Grid('Parent',pl_ops); + + tr_pn = uipanel('Parent',pl_grid); + uicontrol('Parent', tr_pn, 'Style','text','String','Range','Position',[0 0 65 25]); + uicontrol('Parent',pl_grid,'Style','text','String','Min'); + uicontrol('Parent',pl_grid,'Style','edit','String','0'); + uicontrol('Parent',pl_grid,'Style','text','String','Max'); + uicontrol('Parent',pl_grid,'Style','edit','String','1000'); + uiextras.Empty('Parent', pl_grid); + uiextras.Empty('Parent', pl_grid); + + tt_pn = uipanel('Parent',pl_grid); + uicontrol('Parent', tt_pn, 'Style','text','String','X Scale','Position',[0 0 65 25]); + uicontrol('Parent',pl_grid,'Style','text','String','Min'); + uicontrol('Parent',pl_grid,'Style','edit','String','0'); + uicontrol('Parent',pl_grid,'Style','text','String','Max'); + uicontrol('Parent',pl_grid,'Style','edit','String','1000'); + uicontrol('Parent',pl_grid,'Style','text','String','Step'); + uicontrol('Parent',pl_grid,'Style','edit','String','200'); + + mc_pn = uipanel('Parent',pl_grid); + uicontrol('Parent', mc_pn, 'Style','text','String','Misc.','Position',[0 0 65 25]); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + + if floating + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + else + tn = tabn; + uicontrol('Parent',pl_grid,'Style','pushbutton','String','Detach','callback',{@detach,tabn}); + uicontrol('Parent',pl_grid,'Style','pushbutton','String','Retach','callback',@retach); + end + + set( pl_grid, 'ColumnSizes', [-1 -1 -1], 'RowSizes', [35 20 25 20 25 20 25] ); + + set( vpanels, 'Sizes', [-1 190] ); + set( hbox, 'Sizes', [-1 200] ); + end + else + empty_tab = uix.HBoxFlex( 'Parent', erp_tabs, 'Spacing', 10 ); + erp_tabs.TabNames = {'Empty'}; + erp_tabs.TabSize = 120; + erp_tabs.SelectedChild = 1; + + hbox = uiextras.HBox('Parent', empty_tab); + boxpan = uiextras.BoxPanel('Parent', hbox); + + vpanels = uiextras.VBox('Parent', hbox); + dat_sel = uiextras.BoxPanel('Parent', vpanels,'Title','Data Selector'); + pl_ops = uiextras.BoxPanel('Parent', vpanels,'Title','Plotting Options'); + + % Data Selector + ds_vb = uiextras.VBox('Parent',dat_sel); + ds_grid = uiextras.Grid('Parent',ds_vb); + + uicontrol('Style','text','String','Chans','Parent',ds_grid); + chan_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',{'ALL'},'callback',@temp,'Max',2,'Min',0); + + uicontrol('Style','text','String','Bins','Parent',ds_grid); + bin_sel = uicontrol('Style','listbox','Parent',ds_grid,'String',{'ALL'},'callback',@temp,'Max',2,'Min',0); + + set( ds_grid, 'ColumnSizes', [-1 -1], 'RowSizes', [25, -1] ); + + b_c = uicontrol('Style','popupmenu','Parent',ds_vb,'String',{'Channels by Bins','Bins by Channels'},'callback',@temp); + + set( ds_vb, 'Sizes', [-1, 20] ); + + % Plotting Options + pl_grid = uiextras.Grid('Parent',pl_ops); + + tr_pn = uipanel('Parent',pl_grid); + uicontrol('Parent', tr_pn, 'Style','text','String','Range','Position',[0 0 65 25]); + uicontrol('Parent',pl_grid,'Style','text','String','Min'); + uicontrol('Parent',pl_grid,'Style','edit','String','0'); + uicontrol('Parent',pl_grid,'Style','text','String','Max'); + uicontrol('Parent',pl_grid,'Style','edit','String','1000'); + uiextras.Empty('Parent', pl_grid); + uiextras.Empty('Parent', pl_grid); + + tt_pn = uipanel('Parent',pl_grid); + uicontrol('Parent', tt_pn, 'Style','text','String','X Scale','Position',[0 0 65 25]); + uicontrol('Parent',pl_grid,'Style','text','String','Min'); + uicontrol('Parent',pl_grid,'Style','edit','String','0'); + uicontrol('Parent',pl_grid,'Style','text','String','Max'); + uicontrol('Parent',pl_grid,'Style','edit','String','1000'); + uicontrol('Parent',pl_grid,'Style','text','String','Step'); + uicontrol('Parent',pl_grid,'Style','edit','String','200'); + + mc_pn = uipanel('Parent',pl_grid); + uicontrol('Parent', mc_pn, 'Style','text','String','Misc.','Position',[0 0 65 25]); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','text','String','a'); + uicontrol('Parent',pl_grid,'Style','pushbutton','String','Detach','callback',@temp); + uicontrol('Parent',pl_grid,'Style','pushbutton','String','Retach','callback',@retach); + + set( pl_grid, 'ColumnSizes', [-1 -1 -1], 'RowSizes', [35 20 25 20 25 20 25] ); + + set( vpanels, 'Sizes', [-1 190] ); + set( hbox, 'Sizes', [-1 200] ); + end + end + + function drawERP(dat,p,terp) + ax = axes('Parent',p,'Color','none','Box','on'); + %set( ax, 'XLim', [min max] ) + ts = terp.times; + [a,c,b] = size(dat); + new_erp_data = zeros(a,b*c); + for j = 1:b + new_erp_data(:,((c*(j-1))+1):(c*j)) = dat(:,:,j); + end + this_plot = plot(ax,ts,new_erp_data); + %boxpan + end + + function detach(~,~,tabn) + %tabn = erp_tabs.SelectedChild; + ddat = data(tabn); + data(tabn) = []; + drawUI(); + child_vs(end+1) = {mini_viewer(ddat)}; + end + + function retach(~,~) + for j = child_vs + j = [j{1}]; + data(end+1) = j.data; + delete(j.tabs.Parent); + end + drawUI(); + child_vs = {}; + end + + function loc = erp2loc(erps) + news = nan(size(erps)); + nerps = numel(erps); + + cs = [erps(1).chanlocs.urchan]; + bs = 1:numel(erps(1).bindescr); + es = {}; + [d1,d2,d3] = size(erps(1).bindata); + for i = erps + [td1,td2,td3] = size(i.bindata); + if td1>d1 + d1=td1; + end + if td2>d2 + d2=td2; + end + if td3>d3 + d3=td3; + end + end + ltdata = nan(d1,d2,d3,0); + for i = erps + for j = [i.chanlocs.urchan] + if ~ismember(j,cs) + cs(end+1) = j; + end + end + for j = 1:numel(i.bindescr) + if ~ismember(j,bs) + bs(end+1) = j; + end + end + es(end+1) = {i.erpname}; + t = i.bindata; + try + if t(d1,d2,d3) == 0 + beep; + end + catch + t(d1,d2,d3) = 0; + end + ltdata(:,:,:,end+1) = t; + end + + nbs = {}; + for i = 1:numel(bs) + tes = {}; + ttes = {}; + for j = 1:numel(erps) + if erps(j).nbin >= i + ttes(end+1) = {erps(j)}; + tes(end+1) = es(j); + end + end + + tcs = []; + for j = ttes + j1 = cell2mat(j); + for k = 1:j1.nchan + if ~ismember(k,tcs) + tcs(end+1) = k; + end + end + end + ttes1 = cell2mat(ttes(1)); + nbs(end+1) = {struct('e',{tes},'b',bs(i),'c',tcs,'n',cell2mat(ttes1.bindescr(i)))}; + end + + ncs = {}; + for i = 1:numel(cs) + tes = {}; + ttes = {}; + for j = 1:numel(erps) + if erps(j).nchan >= i + ttes(end+1) = {erps(j)}; + tes(end+1) = es(j); + end + end + + tbs = []; + for j = ttes + j1 = cell2mat(j); + for k = 1:j1.nbin + if ~ismember(k,tbs) + tbs(end+1) = k; + end + end + end + ttes1 = cell2mat(ttes(1)); + tlb = {ttes1.chanlocs.labels}; + ncs(end+1) = {struct('e',{tes},'b',tbs,'c',cs(i),'n',cell2mat(tlb(i)))}; + end + + nes = {}; + for i = 1:numel(es) + nes(end+1) = {struct('e',es(i),'b',1:erps(i).nbin,'c',1:erps(i).nchan,'n',es(i))}; + end + + % Take [chans bins erpsets] and apply a filter of [2 1 3] or + % something to create desired permutation such as [bins chans + % erpsets]. Now we have [lines plots pages]! + nar = [numel(cs) numel(bs) numel(es)]; + nop = nar(ord); + + ar = {cs bs es}; + op = nar(ord); + + dar = {ncs nbs nes}; + dop = dar(ord); + + s = cell(1,nop(3)); + + for i = 1:nop(3) + % Iterate through all pages here + + % Our data will be + % + % [ a1 a2 a3 b1 b2 b3 + % a1 a2 a3 b1 b2 b3 + % a1 a2 a3 b1 b2 b3 ] + % + + temp1 = dop(3); + temp = temp1{:}{i}; + + % WARN IF BIN OR CHAN DOES NOT EXIST FOR ERPSET + todata = ltdata(temp.c,:,temp.b,find(strcmp(es,temp.e))); + t_s = [0 0 0]; + t_s(ord) = [nop(1) nop(2) 1]; + t_ds_o = ones(1,4); + t_ds = zeros(1,4); + t_ds_o(1:numel(size(todata))) = size(todata); + t_ds(1:numel(size(todata))) = size(todata); + if t_s(1) ~= t_ds(1) + ss = t_ds_o; + ss(1) = t_s(1); + todata(ss(1),ss(2),ss(3),ss(4)) = 0; + end + if t_s(2) ~= t_ds(3) + ss = t_ds_o; + ss(3) = t_s(2); + todata(ss(1),ss(2),ss(3),ss(4)) = 0; + end + if t_s(3) ~= t_ds(4) + ss = t_ds_o; + ss(4) = t_s(3); + todata(ss(1),ss(2),ss(3),ss(4)) = 0; + end + + %if size(todata) ~= [ta tb tc ] + ntdata = reshape(todata,numel(erps(1).times),nop(1)*nop(2)); + + + referp = dop(3); + referp = [referp{:}]; + referp = referp{i}; + + nerp = erps(1); + for j = erps + if j.nbin > nerp.nbin + nerp = j; + end + end + + cl = {nerp.chanlocs.labels}; + + s(i) = {struct('nlin',nop(1),'nplot',nop(2),'data',ntdata,'name',temp.n,'channames',{cl(referp.c)},'binnames',{nerp.bindescr(referp.b)},'erpnames',{referp.e},'times',nerp.times)}; + clear cl nerp j temp1 t_s referp + end + + loc = s; + end + + function temp( src, ~ ) + beep; + end +end \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/ms_to_sample.m b/studio_functions/Functions/EStudio/ERP Tab/ms_to_sample.m new file mode 100755 index 00000000..3657779d --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/ms_to_sample.m @@ -0,0 +1,67 @@ +% FORMAT: +% +% sampval = ms_to_sample(timems,fs,EpochStart, rounding) +% +% INPUTS: +% +% timems - time value in milliseconds +% fs - sampling rate +% +% Optional inputs: +% +% rounding - 1 means round the result {default}, 0 means do not round +% EpochStart - the left interval of epoch in ERP data (in milliseconds). Default 0 +% +% OUTPUT: +% +% sampval - time in samples +% +% EXAMPLES: +% +% 1) For a time serie recorded from 0 to 5 secs, at fs=500 sps, get the sample index at the time 674 ms. +% +%>> sampval = ms_to_sample(674, 500) +% +%sampval = +% +% 338 +% +% 2) For a time serie recorded from -1 to 5 secs, at fs=500 sps, get the sample index at the time 674 ms. +%>> sampval674 = ms_to_sample(674, 500, -1000) +% +%sampval_all = +% +% 838 +% +% +% Author: Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + +function sampval = ms_to_sample(timems,fs,offset) +if nargin<1 + help ms_to_sample + return +end +% if nargin<4 +% rounding = 3; +% end +if nargin<3 + offset = 0; +end +if nargin<2 + error('Two inputs are requiered at least.') +% return; +end + +if timems < offset + beep; + error('Input time shoule be larger than offset!!!') +% return; +end + +% offset = round(offset/50)*50; + +sampval = round((timems-offset)*fs/1000)+1; \ No newline at end of file diff --git a/studio_functions/Functions/EStudio/ERP Tab/redrawERP.m b/studio_functions/Functions/EStudio/ERP Tab/redrawERP.m new file mode 100755 index 00000000..53c05ffd --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/redrawERP.m @@ -0,0 +1,769 @@ +function redrawERP() +% Draw a demo ERP into the axes provided +global gui_erp; +global observe_ERPDAT; + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); + +S_ws_geterpplot = estudioworkingmemory('geterpplot'); + + +%%Parameter from bin and channel panel +Elecs_shown = S_ws_getbinchan.elecs_shown{S_ws_getbinchan.Select_index}; +Bins = S_ws_getbinchan.bins{S_ws_getbinchan.Select_index}; +Bin_chans = S_ws_getbinchan.bins_chans(S_ws_getbinchan.Select_index); +Elec_list = S_ws_getbinchan.elec_list{S_ws_getbinchan.Select_index}; +Matlab_ver = S_ws_getbinchan.matlab_ver; + + + +%%Parameter from plotting panel +try + Min_vspacing = S_ws_geterpplot.min_vspacing(S_ws_getbinchan.Select_index); + Min_time = S_ws_geterpplot.min(S_ws_getbinchan.Select_index); + Max_time = S_ws_geterpplot.max(S_ws_getbinchan.Select_index); + Yscale = S_ws_geterpplot.yscale(S_ws_getbinchan.Select_index); + Timet_low =S_ws_geterpplot.timet_low(S_ws_getbinchan.Select_index); + Timet_high =S_ws_geterpplot.timet_high(S_ws_getbinchan.Select_index); + Timet_step=S_ws_geterpplot.timet_step(S_ws_getbinchan.Select_index); + Fill = S_ws_geterpplot.fill(S_ws_getbinchan.Select_index); + Plority_plot = S_ws_geterpplot.Positive_up(S_ws_getbinchan.Select_index); + ColumnNum = S_ws_geterpplot.Plot_column; +catch + return; +end + +if Bin_chans == 0 + elec_n = S_ws_getbinchan.elec_n(S_ws_getbinchan.Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nchan; +else + elec_n = S_ws_getbinchan.bin_n(S_ws_getbinchan.Select_index); + max_elec_n = observe_ERPDAT.ALLERP(S_ws_geterpset(S_ws_getbinchan.Select_index)).nbin; +end + +% We first clear the existing axes ready to build a new one +if ishandle( gui_erp.ViewAxes ) + delete( gui_erp.ViewAxes ); +end + + +% Get chan labels +S_chan.chan_label = cell(1,max_elec_n); +S_chan.chan_label_place = zeros(1,max_elec_n); + + +if Bin_chans == 0 + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.chanlocs(Elecs_shown(i)).labels; + end +else + for i = 1:elec_n + S_chan.chan_label{i} = observe_ERPDAT.ERP.bindescr(Bins(i)); + end +end + + +%Sets the units of your root object (screen) to pixels +set(0,'units','pixels') +%Obtains this pixel information +Pix_SS = get(0,'screensize'); +%Sets the units of your root object (screen) to inches +set(0,'units','inches') +%Obtains this inch information +Inch_SS = get(0,'screensize'); +%Calculates the resolution (pixels per inch) +Res = Pix_SS./Inch_SS; + + +pb_height = Min_vspacing*Res(4); %px + + +% Plot data in the main viewer fig +splot_n = elec_n; +tsize = 13; + + +clear pb r_ax plotgrid; +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef;%%Get background color +catch + ColorB_def = [0.95 0.95 0.95]; +end +if isempty(ColorB_def) + ColorB_def = [0.95 0.95 0.95]; +end +gui_erp.plotgrid = uix.VBox('Parent',gui_erp.ViewContainer,'Padding',0,'Spacing',0,'BackgroundColor',ColorB_def); + +pageinfo_box = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def); + +gui_erp.plot_wav_legend = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',[1 1 1]); +gui_erp.ViewAxes_legend = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',ColorB_def); + +gui_erp.ViewAxes = uix.ScrollingPanel( 'Parent', gui_erp.plot_wav_legend,'BackgroundColor',[1 1 1]); + + +%%Changed by Guanghui Zhang 2 August 2022-------panel for display the processing procedure for some functions, e.g., filtering +xaxis_panel = uiextras.HBox( 'Parent', gui_erp.plotgrid,'BackgroundColor',ColorB_def);%%%Message +gui_erp.Process_messg = uicontrol('Parent',xaxis_panel,'Style','text','String','','FontSize',20,'FontWeight','bold','BackgroundColor',ColorB_def); + + +%%Setting title +gui_erp.pageinfo_minus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '<','Callback',@page_minus,'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index ==1 + gui_erp.pageinfo_minus.Enable = 'off'; +end + +gui_erp.pageinfo_plus = uicontrol('Parent',pageinfo_box,'Style', 'pushbutton', 'String', '>','Callback',@page_plus,'FontSize',30,'BackgroundColor',[1 1 1]); +if S_ws_getbinchan.Select_index == numel(S_ws_geterpset) + gui_erp.pageinfo_plus.Enable = 'off'; +end + +pageinfo_str = ['Page',32,num2str(S_ws_getbinchan.Select_index),'/',num2str(numel(S_ws_geterpset)),':',32,observe_ERPDAT.ERP.erpname]; + +pageinfo_text = uicontrol('Parent',pageinfo_box,'Style','text','String',pageinfo_str,'FontSize',20,'FontWeight','bold'); + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [1 1 1]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp.pageinfo_minus.Enable = Enable_minus; +gui_erp.pageinfo_plus.Enable = Enable_plus; +gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; + +set(pageinfo_box, 'Sizes', [50 50 -1] ); +set(pageinfo_box,'BackgroundColor',ColorB_def); +set(pageinfo_text,'BackgroundColor',ColorB_def); +%Setting title. END,'BackgroundColor',ColorB_def + +%for i=1:splot_n + +ndata = 0; +nplot = 0; +if Bin_chans == 0 + ndata = Bins; + nplot = Elecs_shown; +else + ndata = Elecs_shown; + nplot = Bins; +end + +% +timeor = observe_ERPDAT.ERP.times; % original time vector +timex = timeor; +[xxx, latsamp, latdiffms] = closest(timex, [Min_time Max_time]); +tmin = latsamp(1); +tmax = latsamp(2); + +if tmin < 1 + tmin = 1; +end + +if tmax > numel(observe_ERPDAT.ERP.times) + tmax = numel(observe_ERPDAT.ERP.times); +end + +plot_erp_data = nan(tmax-tmin+1,numel(ndata)); +for i = 1:splot_n + if Bin_chans == 0 + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i),tmin:tmax,Bins(i_bin))'*Plority_plot; % + end + else + for i_bin = 1:numel(ndata) + plot_erp_data(:,i_bin,i) = observe_ERPDAT.ERP.bindata(Elecs_shown(i_bin),tmin:tmax,Bins(i))'*Plority_plot; % + end + end +end + +perc_lim = Yscale; +percentile = perc_lim*3/2; + +[~,~,b] = size(plot_erp_data); + +%How to get x unique colors? + + +%%----------------------Modify the data into multiple-columns--------------------------------------- +rowNum = ceil(b/ColumnNum(S_ws_getbinchan.Select_index)); +plot_erp_data_new = zeros(size(plot_erp_data,1),size(plot_erp_data,2),rowNum*ColumnNum(S_ws_getbinchan.Select_index)); + +plot_erp_data_new(:,:,1:size(plot_erp_data,3)) = plot_erp_data; +plot_erp_data_new_trans = []; +for Numofrow = 1:rowNum + plot_erp_data_new_trans(:,:,:,Numofrow) = plot_erp_data_new(:,:,(Numofrow-1)*ColumnNum(S_ws_getbinchan.Select_index)+1:Numofrow*ColumnNum(S_ws_getbinchan.Select_index)); +end + +clear plot_erp_data; + +plot_erp_data_new_trans = permute(plot_erp_data_new_trans,[1,3,2,4]) ; +plot_erp_data = reshape(plot_erp_data_new_trans,size(plot_erp_data_new_trans,1)*size(plot_erp_data_new_trans,2),size(plot_erp_data_new_trans,3),size(plot_erp_data_new_trans,4)); + +% Min_time = Min_time*ColumnNum(S_ws_getbinchan.Select_index); +% Max_time = Max_time*ColumnNum(S_ws_getbinchan.Select_index); +ind_plot_height = percentile*2; % Height of each individual subplot + +offset = []; +if Bin_chans == 0 + offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height; +else + offset = (size(plot_erp_data,3)-1:-1:0)*ind_plot_height; +end +[~,~,b] = size(plot_erp_data); + +for i = 1:b + plot_erp_data(:,:,i) = plot_erp_data(:,:,i) + ones(size(plot_erp_data(:,:,i)))*offset(i); +end + + + +r_ax = axes('Parent', gui_erp.ViewAxes,'Color','none','Box','on'); +hold(r_ax,'on'); +set(gui_erp.plot_wav_legend,'Sizes',[80 -10]); +r_ax_legend = axes('Parent', gui_erp.ViewAxes_legend,'Color','none','Box','off'); +hold(r_ax_legend,'on'); + + +Min_time_onecolm = S_ws_geterpplot.min(S_ws_getbinchan.Select_index); +Max_time_onecolm = S_ws_geterpplot.max(S_ws_getbinchan.Select_index); + +try + f_bin = 1000/observe_ERPDAT.ERP.srate; +catch + f_bin = 1; +end + +ts = observe_ERPDAT.ERP.times(tmin:tmax); +ts_colmn = ts; +xticks_clomn = (Min_time:Timet_step:Max_time); +xticks = (Min_time:Timet_step:Max_time); +if ColumnNum(S_ws_getbinchan.Select_index)>1 % Plotting waveforms with munltiple-columns + + for Numofcolumn = 1:ColumnNum(S_ws_getbinchan.Select_index)-1 + ts_colmn = [ts_colmn,ts+ones(1,numel(ts))*(ts_colmn(end)+f_bin-ts(1))]; + xticks_clomn = [xticks_clomn,xticks(2:end)]; + end + X_zero_line(1) =ts(1); + for Numofcolumn = 1:ColumnNum(S_ws_getbinchan.Select_index)-1 + X_zero_line(Numofcolumn+1) = X_zero_line(Numofcolumn)+ ts(end)-ts(1)+f_bin; + end + + ts = ts_colmn; + + Min_time = ts(1); + Max_time = ts(end); + xticks = xticks_clomn; + +else%% Plotting waveforms with single-column + xticks = (Min_time:Timet_step:Max_time); + X_zero_line(1) =ts(1); +end + +for Numofxlabel = 1:numel(xticks) + xticks_labels{Numofxlabel} = num2str(xticks(Numofxlabel)); +end + +splot_n = size(plot_erp_data,3);%%Adjust the columns + +set(r_ax,'XLim',[Min_time Max_time]); + +[a,c,b] = size(plot_erp_data); +new_erp_data = zeros(a,b*c); +for i = 1:b + new_erp_data(:,((c*(i-1))+1):(c*i)) = plot_erp_data(:,:,i); +end + + +line_colors = erpworkingmemory('PWColor'); +if size(line_colors,1)~= numel(ndata) + if numel(ndata)> size(line_colors,1) + line_colors = get_colors(numel(ndata)); + else + line_colors = line_colors(1:numel(ndata),:,:); + end +end + +if isempty(line_colors) + line_colors = get_colors(numel(ndata)); +end + +line_colors = repmat(line_colors,[splot_n 1]); %repeat the colors once for every plot + +if ColumnNum(S_ws_getbinchan.Select_index)>1 + for ii = 1:numel(X_zero_line) + xline_p = xline(r_ax,X_zero_line(ii),'--','Color', [0 0 0],'LineWidth',1.5);%%Marking start time point for each column + xline_p.FontSize = 18; + end + + +end + + +%%%------------Setting xticklabels for each row of each wave-------------- +x_axs = ones(size(new_erp_data,1),1); +if numel(offset)>1 + + for jj = 1:numel(offset) + x_axset = plot(r_ax,ts,x_axs.*offset(jj),'k','LineWidth',1); + set(r_ax,'XTick',[Min_time:Timet_step:Max_time], ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); + end + +end +if numel(offset)>1 + + for jj = 1:numel(offset) + x_axset = plot(r_ax,ts,x_axs.*offset(end-1),'k','LineWidth',1); + set(r_ax,'XTick',[Min_time:Timet_step:Max_time], ... + 'box','off', 'Color','none','xticklabels',xticks_labels,'FontWeight','bold'); + myX_Crossing = offset(jj); + props = get(r_ax); + + tick_bottom = -props.TickLength(1)*diff(props.YLim); + if abs(tick_bottom) > abs(Yscale)/5 + try + tick_bottom = - abs(Yscale)/5; + catch + tick_bottom = tick_bottom; + end + end + tick_top = 0; + + h_xaxis = line(r_ax,props.XLim, [0 0] + myX_Crossing, 'color', 'k'); + + if ~isempty(props.XTick) + xtick_x = repmat(props.XTick, 2, 1); + xtick_y = repmat([tick_bottom; tick_top] + myX_Crossing, 1, length(props.XTick)); + h_ticks = line(r_ax,xtick_x, xtick_y, 'color', 'k'); + end + set(r_ax, 'XTick', [], 'XTickLabel', []); + % tick_bottom = -props.TickLength(1)*diff(props.YLim); + nTicks = length(props.XTick); + h_ticklabels = zeros(size(props.XTick)); + if nTicks>1 + if numel(offset)==jj + kkkk = 1; + else + kkkk = 2; + end + for iCount = kkkk:nTicks + xtick_label = (props.XTickLabel(iCount, :)); + text(r_ax,props.XTick(iCount), tick_bottom + myX_Crossing, ... + xtick_label, ... + 'HorizontalAlignment', 'Center', ... + 'VerticalAlignment', 'Top', ... + 'FontSize', 12, ... + 'FontName', props.FontName, ... + 'FontAngle', props.FontAngle, ... + 'FontUnits', props.FontUnits, ... + 'FontWeight', 'bold'); + end + end + + end +end +%%%%%%%%----------------------------- + +% set(r_ax,'XDir','reverse') + +pb_here = plot(r_ax,ts, [repmat((1:numel(nplot)-1)*ind_plot_height,[numel(ts) 1]) new_erp_data],'LineWidth',1); +r_ax.LineWidth=1.5; +set(r_ax, 'XTick', [], 'XTickLabel', []) + +% +yticks = -perc_lim:perc_lim:((2*percentile*b)-(2*perc_lim)); +ylabs = repmat([-perc_lim 0 perc_lim],[1,b]); +oldlim = [-percentile yticks(end)-perc_lim+percentile]; +top_vspace = max( max( new_erp_data))-oldlim(2); +bot_vspace = min( min( new_erp_data))-oldlim(1); +if top_vspace < 0 + top_vspace = 0; +end + +if bot_vspace > 0 + bot_vspace = 0; +end +newlim = oldlim + [bot_vspace top_vspace]; +set(r_ax,'XLim',[Min_time Max_time],'Ylim',newlim); + + +for i = 0:numel(nplot)-2 + r_ax.Children(end-i).Color = [0 0 0]; +end + + +for i = numel(nplot):numel(pb_here) + pb_here(i).Color = line_colors((i-numel(nplot)+1),:); + +end + +for i = 1:numel(nplot)-1 + pb_here(i).Color = [0 0 0]; +end + + + +ylabs = [fliplr(-perc_lim:-perc_lim:newlim(1)) ylabs(2:end-1) (yticks(end):perc_lim:newlim(2))-yticks(end)+perc_lim]; +yticks = [fliplr(-perc_lim:-perc_lim:newlim(1)) yticks(2:end-1) yticks(end):perc_lim:newlim(2)]; + + + +Ylabels_new = ylabs.*Plority_plot; +[~,Y_label] = find(Ylabels_new == -0); +Ylabels_new(Y_label) = 0; +if ColumnNum(S_ws_getbinchan.Select_index)==1 + % Ylabels_fin = {}; + % count = 0; + % for Numofylabel = numel(Ylabels_new):-1:1 + % + % if Ylabels_new(Numofylabel)==0 + % count =count+1; + % + % if Bin_chans == 0 + % Ylabels_fin{Numofylabel} = strcat(Elec_list{Elecs_shown(count)},'(',num2str(Elecs_shown(count)),')'); + % else + % Ylabels_fin{Numofylabel} = ['Bin',num2str(Bins(count))]; + % end + % else + % Ylabels_fin{Numofylabel} = num2str(roundn(Ylabels_new(Numofylabel),-1)); + % end + % + % end + % else%% Getting y ticks and legends for multiple-columns + % for Numofylabel = numel(Ylabels_new):-1:1 + % Ylabels_fin{Numofylabel} = num2str(roundn(Ylabels_new(Numofylabel),-1)); + % end + if numel(offset)>1 + count = 0; + for i = 0:numel(offset)-1 + leg_str = ''; + for Numofcolumn = 1: ColumnNum(S_ws_getbinchan.Select_index) + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',Elec_list{Elecs_shown(count)}); + else + leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)}); + end + catch + leg_str = ''; + end + text(r_ax,X_zero_line(Numofcolumn),offset(i+1)+offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 18); + end + end + end + + + count = (numel(offset)-1)*ColumnNum(S_ws_getbinchan.Select_index); + leg_str = ''; + for Numofcolumn = 1: ColumnNum(S_ws_getbinchan.Select_index) + count = count+1; + try + if Bin_chans == 0 + leg_str = sprintf('%s',Elec_list{Elecs_shown(count)}); + else + leg_str = sprintf('%s',observe_ERPDAT.ERP.bindescr{Bins(count)}); + end + catch%% + leg_str = ''; + end + try + text(r_ax,X_zero_line(Numofcolumn),offset(end-1)/6,leg_str,'FontWeight','bold','FontSize', 18); + catch + text(r_ax,X_zero_line(Numofcolumn),Yscale/2,leg_str,'FontWeight','bold','FontSize', 18); + end + end + +end + + + + +% xticks = (Min_time:Timet_step:Max_time); +% some options currently only work post Matlab R2016a ,'XLim',[Min_time Max_time],'XLim',[Min_time Max_time] +if Matlab_ver >= 2016 + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','origin',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim,'XTick',[Min_time:Timet_step:Max_time], ... + 'box','off', 'Color','none','xticklabels',xticks_labels); +else + set(r_ax,'FontSize',tsize,'FontWeight','bold','XAxisLocation','bottom',... + 'XGrid','on','YGrid','on','YTick',yticks,'YTickLabel',Ylabels_new, ... + 'YLim',newlim, 'XTick',[Min_time:Timet_step:Max_time], ... + 'box','off', 'Color','none','xticklabels',xticks_labels); + hline(0,'k'); % backup xaxis +end +if numel(offset)>1 + set(r_ax, 'XTick', [], 'XTickLabel', []) +end + +%%%%%%%%%%%% +hold(r_ax,'off'); +% r_ax.Position(2) =r_ax.Position(2)-5; +line_colors_ldg = erpworkingmemory('PWColor'); +if isempty(line_colors_ldg) + line_colors_ldg = get_colors(numel(ndata)); +end + +if size(line_colors_ldg,1)~= numel(ndata) + if numel(ndata)> size(line_colors_ldg,1) + line_colors_ldg = get_colors(numel(ndata)); + else + line_colors_ldg = line_colors_ldg(1:numel(ndata),:,:); + end +end + +for Numofplot = 1:size(plot_erp_data,2) + plot(r_ax_legend,[0 0],'Color',line_colors_ldg(Numofplot,:,:),'LineWidth',3) +end + +if Bin_chans == 0 + + Leg_Name = {}; + + for Numofbin = 1:numel(Bins) + Leg_Name{Numofbin} = strcat('Bin',num2str(Bins(Numofbin))); + + end + +else + for Numofchan = 1:numel(Elecs_shown) + Leg_Name{Numofchan} = Elec_list{Numofchan}; + end +end +legend(r_ax_legend,Leg_Name,'FontSize',14,'TextColor','blue'); +legend(r_ax_legend,'boxoff'); +% title(here_lgd,'Legend'); + +% fix scaling shrinkage +pos_fix = r_ax.Position; +pos_fix(2) = 1; % Start at the bottom +pos_fix(4) = pb_height - 1; % fill the height; + +gui_erp.plotgrid.Heights(1) = 30; % set the first element (pageinfo) to 30px high +gui_erp.plotgrid.Heights(3) = 30; % set the second element (x axis) to 30px high +gui_erp.plotgrid.Units = 'pixels'; +if splot_n*pb_height<(gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1))&&Fill + pb_height = (gui_erp.plotgrid.Position(4)-gui_erp.plotgrid.Heights(1)-gui_erp.plotgrid.Heights(2))/splot_n; +end + +gui_erp.ViewAxes.Heights = splot_n*pb_height; +gui_erp.plotgrid.Units = 'normalized'; + +end % redrawDemo + + +function colors = get_colors(ncolors) +% Each color gets 1 point divided into up to 2 of 3 groups (RGB). +degree_step = 6/ncolors; +angles = (0:ncolors-1)*degree_step; +colors = nan(numel(angles),3); +for i = 1:numel(angles) + if angles(i) < 1 + colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75; + elseif angles(i) < 2 + colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75; + elseif angles(i) < 3 + colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75; + elseif angles(i) < 4 + colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75; + elseif angles(i) < 5 + colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75; + else + colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75; + end +end +end + + + +%------------------Display the waveform for proir ERPset-------------------- +function page_minus(~,~) +global observe_ERPDAT; +global gui_erp; + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); + + +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index-1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end + +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); + + +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); + + +observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 0 0]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp.pageinfo_minus.Enable = Enable_minus; +gui_erp.pageinfo_plus.Enable = Enable_plus; +% f_redrawERP_mt_viewer(); +gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +end + + + + + +%------------------Display the waveform for next ERPset-------------------- +function page_plus(~,~) +global observe_ERPDAT; +global gui_erp; + + +S_ws_geterpset= estudioworkingmemory('selectederpstudio'); +if isempty(S_ws_geterpset) + S_ws_geterpset = observe_ERPDAT.CURRENTERP; + + if isempty(S_ws_geterpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_ws_geterpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); +end + +S_ws_getbinchan = estudioworkingmemory('geterpbinchan'); + + + + +S_ws_getbinchan.Select_index = S_ws_getbinchan.Select_index+1; +Current_erp_Index = S_ws_geterpset(S_ws_getbinchan.Select_index); +if Current_erp_Index > length(observe_ERPDAT.ALLERP) + beep; + disp('Waiting for modifing'); + return; +end + +observe_ERPDAT.CURRENTERP = Current_erp_Index; +observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_erp_Index); + +estudioworkingmemory('geterpbinchan',S_ws_getbinchan); + +observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + + +if length(S_ws_geterpset) ==1 + Enable_minus = 'off'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 0 0]; +else + + if S_ws_getbinchan.Select_index ==1 + Enable_minus = 'off'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [1 1 1]; + elseif S_ws_getbinchan.Select_index == length(S_ws_geterpset) + Enable_minus = 'on'; + Enable_plus = 'off'; + Enable_plus_BackgroundColor = [0 0 0]; + Enable_minus_BackgroundColor = [0 1 0]; + + + else + Enable_minus = 'on'; + Enable_plus = 'on'; + Enable_plus_BackgroundColor = [0 1 0]; + Enable_minus_BackgroundColor = [0 1 0]; + end +end +gui_erp.pageinfo_minus.Enable = Enable_minus; +gui_erp.pageinfo_plus.Enable = Enable_plus; +gui_erp.pageinfo_plus.ForegroundColor = Enable_plus_BackgroundColor; +gui_erp.pageinfo_minus.ForegroundColor = Enable_minus_BackgroundColor; +end + + diff --git a/studio_functions/Functions/EStudio/ERP Tab/sample_to_ms.m b/studio_functions/Functions/EStudio/ERP Tab/sample_to_ms.m new file mode 100755 index 00000000..33e45937 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/sample_to_ms.m @@ -0,0 +1,70 @@ +% FORMAT: +% +% sampval = sample_to_ms(timesam, fs,EpochStart, rounding) +% +% INPUTS: +% +% timesam - time value in time samples +% fs - sampling rate (in Hz) +% +% +% Optional inputs: +% +% rounding - 1 means round the result {default}, 0 means do not round +% EpochStart - the left interval of epoch/trial (e.g., -200ms). Default is 0 ms. + + +% OUTPUT: +% +% sampval - time in milliseconds +% +% EXAMPLES: +% +% 1) For a time serie recorded from 0 to 5 secs, at fs=500 sps, get the time in ms for the sample # 337. +% +% msval = sample_to_ms(337, 500) +% +% msval = +% +% 672 +% +% 2) For a time serie recorded from -1 to 5 secs, at fs=500 sps, get the absolute time in ms for the sample # 337. +% +% msval = sample_to_ms(337, 500, -1000) +% +% msval = +% +% -328 +% +% +% Author: Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% Feb., 2022 + +function msval = sample_to_ms(timesam,fs,offset, rounding) +if nargin<1 + help sample_to_ms + return +end + +if nargin<4 + rounding = 0; +end +% +if nargin < 3 + offset = 0; +end + +if nargin<2 + error('Two inputs are required at least!!!'); +end + + +msval = 1000*(timesam-1)/fs+offset; + +if rounding + msval = round(msval); +end + diff --git a/studio_functions/Functions/EStudio/ERP Tab/working_mem_save_load.m b/studio_functions/Functions/EStudio/ERP Tab/working_mem_save_load.m new file mode 100755 index 00000000..f58a2338 --- /dev/null +++ b/studio_functions/Functions/EStudio/ERP Tab/working_mem_save_load.m @@ -0,0 +1,91 @@ +% PURPOSE: saves or loads the ERPLAB working memory to another location +% +% FORMAT +% +% working_mem_save_load(save_or_load) +% +% INPUT +% +% save_or_load - 1 for save; 2 for load +% +% OUTPUT +% +% Mat-file .erpm written to disk, or memory structure loaded. +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Andrew Stewart +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2016 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + + + +function [wm_loaded] = working_mem_save_load(save_or_load) + +if save_or_load == 1 + + wm_loaded = []; + + % prompt for path with file browser ui + [wm_fname, wm_pathname] = uiputfile({'*.erpm', 'ERP working memory file (*.erpm)'; + '*.*' , 'All Files (*.*)'},'Save working memory file as',... + 'custom_memoryerp.erpm'); + + try + vmemoryerp = evalin('base', 'vmemoryerp'); + + % save + save(fullfile(wm_pathname, wm_fname), 'vmemoryerp'); + + + catch + errordlg('Memory save problem. Perhaps memory was empty?'); + end + + + + + +elseif save_or_load == 2 + + + % prompt for path with file browser ui + [wm_load_fname, wm_load_pathname] = uigetfile({'*.erpm', 'ERP working memory file (*.erpm)'; + '*.*' , 'All Files (*.*)'},'Pick an existing working memory file to load',... + 'custom_memoryerp.erpm'); + if isempty(wm_load_pathname) || length(wm_load_pathname)==1 + beep; + disp('User selected cancel'); + wm_loaded =[]; + return; + end + wm_loaded = load(fullfile(wm_load_pathname,wm_load_fname), '-mat'); + +else + errordlg('WM save function error?'); +end + +end + diff --git a/studio_functions/Functions/EStudio/f_get_default_fontsize.m b/studio_functions/Functions/EStudio/f_get_default_fontsize.m new file mode 100644 index 00000000..bb0af327 --- /dev/null +++ b/studio_functions/Functions/EStudio/f_get_default_fontsize.m @@ -0,0 +1,20 @@ + + + + +function FonsizeDefault = f_get_default_fontsize() + +if ismac + % Code to run on Mac platform + FonsizeDefault = 12; +elseif isunix + % Code to run on Linux platform + FonsizeDefault = 9; +elseif ispc + % Code to run on Windows platform + FonsizeDefault = 9; +else + FonsizeDefault = 9; +end + +end \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/BoxPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/BoxPanel.m new file mode 100644 index 00000000..4c2e741f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/BoxPanel.m @@ -0,0 +1,144 @@ +classdef BoxPanel < uix.BoxPanel + %uiextras.BoxPanel Show one element inside a box panel + % + % obj = uiextras.BoxPanel() creates a box-styled panel object with + % automatic management of the contained widget or layout. The + % properties available are largely the same as the builtin UIPANEL + % object. Where more than one child is added, the currently visible + % child is determined using the SelectedChild property. + % + % obj = uiextras.BoxPanel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' ) + % + % >> f = figure(); + % >> p = uiextras.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 ); + % >> b = uiextras.HBox( 'Parent', p, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} ); + % >> uicontrol( 'Style', 'frame', 'Parent', b, 'Background', 'b' ); + % >> set( b, 'Sizes', [100 -1] ); + % >> p.FontSize = 12; + % >> p.FontWeight = 'bold'; + % >> p.HelpFcn = @(x,y) disp('Help me!'); + % + % See also: uiextras.Panel + % uiextras.TabPanel + % uiextras.HBoxFlex + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + IsDocked + IsMinimized + SelectedChild % deprecated + end + + methods + + function obj = BoxPanel( varargin ) + + % Call uix constructor + obj@uix.BoxPanel( varargin{:} ) + + % Add Enable property + if ~isprop( obj, 'Enable' ) + p = addprop( obj, 'Enable' ); + p.GetMethod = @getEnable; + p.SetMethod = @setEnable; + end + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = getEnable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % getEnable + + function setEnable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % setEnable + + function value = get.IsDocked( obj ) + + % Get + value = obj.Docked; + + end % get.IsDocked + + function set.IsDocked( obj, value ) + + % Get + obj.Docked = value; + + end % set.IsDocked + + function value = get.IsMinimized( obj ) + + % Get + value = obj.Minimized; + + end % get.IsMinimized + + function set.IsMinimized( obj, value ) + + % Get + obj.Minimized = value; + + end % set.IsMinimized + + function value = get.SelectedChild( obj ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + % Get + if isempty( obj.Contents_ ) + value = []; + else + value = 1; + end + + end % get.SelectedChild + + function set.SelectedChild( ~, ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + end % set.SelectedChild + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/CardPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/CardPanel.m new file mode 100644 index 00000000..4ac8b13b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/CardPanel.m @@ -0,0 +1,92 @@ +classdef CardPanel < uix.CardPanel + %uiextras.CardPanel Show one element (card) from a list + % + % obj = uiextras.CardPanel() creates a new card panel which allows + % selection between the different child objects contained, making the + % selected child fill the space available and all other children + % invisible. This is commonly used for creating wizards or quick + % switching between different views of a single data-set. + % + % obj = uiextras.CardPanel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.CardPanel( 'Parent', f, 'Padding', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'b' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'g' ); + % >> p.SelectedChild = 2; + % + % See also: uiextras.Panel + % uiextras.BoxPanel + % uiextras.TabPanel + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + SelectedChild + end + + methods + + function obj = CardPanel( varargin ) + + % Call uix constructor + obj@uix.CardPanel( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.SelectedChild( obj ) + + % Get + value = obj.Selection; + + end % get.SelectedChild + + function set.SelectedChild( obj, value ) + + % Set + obj.Selection = value; + + end % set.SelectedChild + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/Empty.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Empty.m new file mode 100644 index 00000000..af923f55 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Empty.m @@ -0,0 +1,29 @@ +function obj = Empty( varargin ) +%uiextras.Empty Create an empty space +% +% obj = uiextras.Empty() creates an empty space that can be used to add +% gaps between elements in layouts. +% +% obj = uiextras.Empty(param,value,...) also sets one or more property +% values. +% +% See the documentation for more detail and the list of properties. +% +% Examples: +% >> f = figure(); +% >> box = uiextras.HBox( 'Parent', f ); +% >> uicontrol( 'Parent', box, 'Background', 'r' ) +% >> uiextras.Empty( 'Parent', box ) +% >> uicontrol( 'Parent', box, 'Background', 'b' ) + +% Copyright 2009-2020 The MathWorks, Inc. + +% Call uix construction function +obj = uix.Empty( varargin{:} ); + +% Auto-parent +if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); +end + +end % uiextras.Empty \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/Grid.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Grid.m new file mode 100644 index 00000000..062be330 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Grid.m @@ -0,0 +1,142 @@ +classdef Grid < uix.Grid + %uiextras.Grid Container with contents arranged in a grid + % + % obj = uiextras.Grid() creates a new new grid layout with all + % properties set to defaults. The number of rows and columns to use + % is determined from the number of elements in the RowSizes and + % ColumnSizes properties respectively. Child elements are arranged + % down column one first, then column two etc. If there are + % insufficient columns then a new one is added. The output is a new + % layout object that can be used as the parent for other + % user-interface components. The output is a new layout object that + % can be used as the parent for other user-interface components. + % + % obj = uiextras.Grid(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> g = uiextras.Grid( 'Parent', f, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'r' ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'b' ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'g' ) + % >> uiextras.Empty( 'Parent', g ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'c' ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'y' ) + % >> set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 100] ); + % + % See also: uiextras.GridFlex + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + RowSizes % heights of contents, in pixels and/or weights + MinimumRowSizes % minimum heights of contents, in pixels + ColumnSizes % widths of contents, in pixels and/or weights + MinimumColumnSizes % minimum widths of contents, in pixels + end + + methods + + function obj = Grid( varargin ) + + % Call uix constructor + obj@uix.Grid( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.RowSizes( obj ) + + % Get + value = obj.Heights; + + end % get.RowSizes + + function set.RowSizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.RowSizes + + function value = get.MinimumRowSizes( obj ) + + % Get + value = obj.MinimumHeights; + + end % get.MinimumRowSizes + + function set.MinimumRowSizes( obj, value ) + + % Set + obj.MinimumHeights = value; + + end % set.MinimumRowSizes + + function value = get.ColumnSizes( obj ) + + % Get + value = obj.Widths; + + end % get.ColumnSizes + + function set.ColumnSizes( obj, value ) + + % Get + obj.Widths = value; + + end % set.ColumnSizes + + function value = get.MinimumColumnSizes( obj ) + + % Get + value = obj.MinimumWidths; + + end % get.MinimumColumnSizes + + function set.MinimumColumnSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumColumnSizes + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/GridFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/GridFlex.m new file mode 100644 index 00000000..4d3bf7f0 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/GridFlex.m @@ -0,0 +1,160 @@ +classdef GridFlex < uix.GridFlex + %uiextras.GridFlex Container with contents arranged in a resizable grid + % + % obj = uiextras.GridFlex() creates a new new grid layout with + % draggable dividers between elements. The number of rows and columns + % to use is determined from the number of elements in the RowSizes + % and ColumnSizes properties respectively. Child elements are + % arranged down column one first, then column two etc. If there are + % insufficient columns then a new one is added. The output is a new + % layout object that can be used as the parent for other + % user-interface components. The output is a new layout object that + % can be used as the parent for other user-interface components. + % + % obj = uiextras.GridFlex(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> g = uiextras.GridFlex( 'Parent', f, 'Spacing', 5 ); + % >> uicontrol( 'Parent', g, 'Background', 'r' ) + % >> uicontrol( 'Parent', g, 'Background', 'b' ) + % >> uicontrol( 'Parent', g, 'Background', 'g' ) + % >> uiextras.Empty( 'Parent', g ) + % >> uicontrol( 'Parent', g, 'Background', 'c' ) + % >> uicontrol( 'Parent', g, 'Background', 'y' ) + % >> set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 -2] ); + % + % See also: uiextras.Grid + % uiextras.HBoxFlex + % uiextras.VBoxFlex + % uiextras.Empty + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + RowSizes % heights of contents, in pixels and/or weights + MinimumRowSizes % minimum heights of contents, in pixels + ColumnSizes % widths of contents, in pixels and/or weights + MinimumColumnSizes % minimum widths of contents, in pixels + ShowMarkings + end + + methods + + function obj = GridFlex( varargin ) + + % Call uix constructor + obj@uix.GridFlex( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.RowSizes( obj ) + + % Get + value = obj.Heights; + + end % get.RowSizes + + function set.RowSizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.RowSizes + + function value = get.MinimumRowSizes( obj ) + + % Get + value = obj.MinimumHeights; + + end % get.MinimumRowSizes + + function set.MinimumRowSizes( obj, value ) + + % Set + obj.MinimumHeights = value; + + end % set.MinimumRowSizes + + function value = get.ColumnSizes( obj ) + + % Get + value = obj.Widths; + + end % get.ColumnSizes + + function set.ColumnSizes( obj, value ) + + % Get + obj.Widths = value; + + end % set.ColumnSizes + + function value = get.MinimumColumnSizes( obj ) + + % Get + value = obj.MinimumWidths; + + end % get.MinimumColumnSizes + + function set.MinimumColumnSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumColumnSizes + + function value = get.ShowMarkings( obj ) + + % Get + value = obj.DividerMarkings; + + end % get.ShowMarkings + + function set.ShowMarkings( obj, value ) + + % Set + obj.DividerMarkings = value; + + end % set.ShowMarkings + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBox.m new file mode 100644 index 00000000..97f7d011 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBox.m @@ -0,0 +1,113 @@ +classdef HBox < uix.HBox + %uiextras.HBox Arrange elements in a single horizontal row + % + % obj = uiextras.HBox() creates a new horizontal box layout with + % all parameters set to defaults. The output is a new layout object + % that can be used as the parent for other user-interface components. + % + % obj = uiextras.HBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.HBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> set( b, 'Sizes', [-1 100 -2], 'Spacing', 5 ); + % + % >> f = figure(); + % >> b1 = uiextras.VBox( 'Parent', f ); + % >> b2 = uiextras.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', b1, 'Background', 'r' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button1' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button2' ) + % >> set( b1, 'Sizes', [30 -1] ); + % + % See also: uiextras.VBox + % uiextras.HBoxFlex + % uiextras.Grid + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + end + + methods + + function obj = HBox( varargin ) + + % Call uix constructor + obj@uix.HBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Widths ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Widths = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumWidths ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumSizes + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBoxFlex.m new file mode 100644 index 00000000..d97fdeab --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HBoxFlex.m @@ -0,0 +1,122 @@ +classdef HBoxFlex < uix.HBoxFlex + %uiextras.HBoxFlex A dynamically resizable horizontal layout + % + % obj = uiextras.HBoxFlex() creates a new dynamically resizable + % horizontal box layout with all parameters set to defaults. The + % output is a new layout object that can be used as the parent for + % other user-interface components. + % + % obj = uiextras.HBoxFlex(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure( 'Name', 'uiextras.HBoxFlex example' ); + % >> b = uiextras.HBoxFlex( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> uicontrol( 'Parent', b, 'Background', 'y' ) + % >> set( b, 'Sizes', [-1 100 -2 -1], 'Spacing', 5 ); + % + % See also: uiextras.VBoxFlex + % uiextras.HBox + % uiextras.Grid + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + ShowMarkings + end + + methods + + function obj = HBoxFlex( varargin ) + + % Call uix constructor + obj@uix.HBoxFlex( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Widths ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Widths = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumWidths ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumSizes + + function value = get.ShowMarkings( obj ) + + % Get + value = obj.DividerMarkings; + + end % get.ShowMarkings + + function set.ShowMarkings( obj, value ) + + % Set + obj.DividerMarkings = value; + + end % set.ShowMarkings + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/HButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HButtonBox.m new file mode 100644 index 00000000..270d1c09 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/HButtonBox.m @@ -0,0 +1,45 @@ +classdef HButtonBox < uix.HButtonBox + %uiextras.HButtonBox Arrange buttons horizontally in a single row + % + % obj = uiextras.HButtonBox() is a type of HBox specialised for + % arranging a row of buttons, check-boxes or similar graphical + % elements. All buttons are given equal size and by default are + % centered in the drawing area. The justification can be changed as + % required. + % + % obj = uiextras.HButtonBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.HButtonBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'String', 'One' ); + % >> uicontrol( 'Parent', b, 'String', 'Two' ); + % >> uicontrol( 'Parent', b, 'String', 'Three' ); + % >> set( b, 'ButtonSize', [130 35], 'Spacing', 5 ); + % + % See also: uiextras.VButtonBox + % uiextras.HBox + + % Copyright 2009-2020 The MathWorks, Inc. + + methods + + function obj = HButtonBox( varargin ) + %uiextras.HButtonBox Create a new horizontal button box + + % Call uix constructor + obj@uix.HButtonBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/Panel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Panel.m new file mode 100644 index 00000000..edf75cdc --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/Panel.m @@ -0,0 +1,111 @@ +classdef Panel < uix.Panel + %uiextras.Panel Show one element inside a panel + % + % obj = uiextras.Panel() creates a standard UIPANEL object but with + % automatic management of the contained widget or layout. The + % properties available are largely the same as the builtin UIPANEL + % object. Where more than one child is added, the currently visible + % child is determined using the SelectedChild property. + % + % obj = uiextras.Panel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 ); + % >> uicontrol( 'Parent', p, 'Background', 'r' ) + % + % >> f = figure(); + % >> p = uiextras.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 ); + % >> b = uiextras.HBox( 'Parent', p, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} ); + % >> uicontrol( 'Parent', b, 'Background', 'b' ); + % >> set( b, 'Sizes', [100 -1] ); + % + % See also: uipanel + % uiextras.BoxPanel + % uiextras.HBox + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + SelectedChild + end + + methods + + function obj = Panel( varargin ) + + % Call uix constructor + obj@uix.Panel( varargin{:} ) + + % Add Enable property + if ~isprop( obj, 'Enable' ) + p = addprop( obj, 'Enable' ); + p.GetMethod = @getEnable; + p.SetMethod = @setEnable; + end + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = getEnable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % getEnable + + function setEnable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % setEnable + + function value = get.SelectedChild( obj ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + % Get + if isempty( obj.Contents_ ) + value = []; + else + value = 1; + end + + end % get.SelectedChild + + function set.SelectedChild( ~, ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + end % set.SelectedChild + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/TabPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/TabPanel.m new file mode 100644 index 00000000..9ec22907 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/TabPanel.m @@ -0,0 +1,223 @@ +classdef TabPanel < uix.TabPanel + %TabPanel Show one element inside a tabbed panel + % + % obj = uiextras.TabPanel() creates a panel with tabs along one edge + % to allow selection between the different child objects contained. + % + % obj = uiextras.TabPanel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.TabPanel( 'Parent', f, 'Padding', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'b' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'g' ); + % >> p.TabNames = {'Red', 'Blue', 'Green'}; + % >> p.SelectedChild = 2; + % + % See also: uiextras.Panel + % uiextras.BoxPanel + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Callback + end + + properties( Access = private ) + Callback_ = '' % backing for Callback + end + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + SelectedChild + TabEnable + TabNames + TabPosition + TabSize + end + + properties( Access = private ) + SelectionChangedListener % listener + end + + methods + + function obj = TabPanel( varargin ) + + % Call uix constructor + obj@uix.TabPanel( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + % Create listeners + selectionChangedListener = event.listener( obj, ... + 'SelectionChanged', @obj.onSelectionChanged ); + + % Store properties + obj.SelectionChangedListener = selectionChangedListener; + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Callback( obj ) + + % Get + value = obj.Callback_; + + end % get.Callback + + function set.Callback( obj, value ) + + % Check + if ischar( value ) % string + % OK + elseif isa( value, 'function_handle' ) && ... + isequal( size( value ), [1 1] ) % function handle + % OK + elseif iscell( value ) && ndims( value ) == 2 && ... + size( value, 1 ) == 1 && size( value, 2 ) > 0 && ... + isa( value{1}, 'function_handle' ) && ... + isequal( size( value{1} ), [1 1] ) %#ok % cell callback + % OK + else + error( 'uiextras:InvalidPropertyValue', ... + 'Property ''Callback'' must be a valid callback.' ) + end + + % Set + obj.Callback_ = value; + + end % set.Callback + + function value = get.SelectedChild( obj ) + + % Get + value = obj.Selection; + + end % get.SelectedChild + + function set.SelectedChild( obj, value ) + + % Set + obj.Selection = value; + + end % set.SelectedChild + + function value = get.TabEnable( obj ) + + % Get + value = transpose( obj.TabEnables ); + + end % get.TabEnable + + function set.TabEnable( obj, value ) + + % Set + obj.TabEnables = value; + + end % set.TabEnable + + function value = get.TabNames( obj ) + + % Get + value = transpose( obj.TabTitles ); + + end % get.TabNames + + function set.TabNames( obj, value ) + + % Set + obj.TabTitles = value; + + end % set.TabNames + + function value = get.TabPosition( obj ) + + % Get + value = obj.TabLocation; + + end % get.TabPosition + + function set.TabPosition( obj, value ) + + % Set + obj.TabLocation = value; + + end % set.TabPosition + + function value = get.TabSize( obj ) + + % Get + value = obj.TabWidth; + + end % get.TabSize + + function set.TabSize( obj, value ) + + % Set + obj.TabWidth = value; + + end % set.TabSize + + end % accessors + + methods( Access = private ) + + function onSelectionChanged( obj, source, eventData ) + + % Create legacy event data structure + oldEventData = struct( 'Source', eventData.Source, ... + 'PreviousChild', eventData.OldValue, ... + 'SelectedChild', eventData.NewValue ); + + % Call callback + callback = obj.Callback_; + if ischar( callback ) && isequal( callback, '' ) + % do nothing + elseif ischar( callback ) + feval( callback, source, oldEventData ) + elseif isa( callback, 'function_handle' ) + callback( source, oldEventData ) + elseif iscell( callback ) + feval( callback{1}, source, oldEventData, callback{2:end} ) + end + + end % onSelectionChanged + + end % event handlers + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBox.m new file mode 100644 index 00000000..281ba69b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBox.m @@ -0,0 +1,113 @@ +classdef VBox < uix.VBox + %uiextras.VBox Arrange elements vertically in a single column + % + % obj = uiextras.VBox() creates a new vertical box layout with all + % parameters set to defaults. The output is a new layout object that + % can be used as the parent for other user-interface components. + % + % obj = uiextras.VBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.VBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> set( b, 'Sizes', [-1 100 -2], 'Spacing', 5 ); + % + % >> f = figure(); + % >> b1 = uiextras.VBox( 'Parent', f ); + % >> b2 = uiextras.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', b1, 'Background', 'r' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button1' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button2' ) + % >> set( b1, 'Sizes', [30 -1] ); + % + % See also: uiextras.HBox + % uiextras.VBoxFlex + % uiextras.Grid + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + end + + methods + + function obj = VBox( varargin ) + + % Call uix constructor + obj@uix.VBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Heights ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumHeights ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumHeights = value; + + end % set.MinimumSizes + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBoxFlex.m new file mode 100644 index 00000000..3cbe30d9 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VBoxFlex.m @@ -0,0 +1,122 @@ +classdef VBoxFlex < uix.VBoxFlex + %uiextras.VBoxFlex A dynamically resizable vertical layout + % + % obj = uiextras.VBoxFlex() creates a new dynamically resizable + % vertical box layout with all parameters set to defaults. The output + % is a new layout object that can be used as the parent for other + % user-interface components. + % + % obj = uiextras.VBoxFlex(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure( 'Name', 'uiextras.VBoxFlex example' ); + % >> b = uiextras.VBoxFlex( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> uicontrol( 'Parent', b, 'Background', 'y' ) + % >> set( b, 'Sizes', [-1 100 -2 -1], 'Spacing', 5 ); + % + % See also: uiextras.HBoxFlex + % uiextras.VBox + % uiextras.Grid + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + ShowMarkings + end + + methods + + function obj = VBoxFlex( varargin ) + + % Call uix constructor + obj@uix.VBoxFlex( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Heights ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumHeights ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumHeights = value; + + end % set.MinimumSizes + + function value = get.ShowMarkings( obj ) + + % Get + value = obj.DividerMarkings; + + end % get.ShowMarkings + + function set.ShowMarkings( obj, value ) + + % Set + obj.DividerMarkings = value; + + end % set.ShowMarkings + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/VButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VButtonBox.m new file mode 100644 index 00000000..478562ba --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/VButtonBox.m @@ -0,0 +1,45 @@ +classdef VButtonBox < uix.VButtonBox + %uiextras.VButtonBox Arrange buttons vertically in a single column + % + % obj = uiextras.VButtonBox() is a type of VBox specialised for + % arranging a column of buttons, check-boxes or similar graphical + % elements. All buttons are given equal size and by default are + % centered in the drawing area. The justification can be changed as + % required. + % + % obj = uiextras.VButtonBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.VButtonBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'String', 'One' ); + % >> uicontrol( 'Parent', b, 'String', 'Two' ); + % >> uicontrol( 'Parent', b, 'String', 'Three' ); + % >> set( b, 'ButtonSize', [130 35], 'Spacing', 5 ); + % + % See also: uiextras.HButtonBox + % uiextras.VBox + + % Copyright 2009-2020 The MathWorks, Inc. + + methods + + function obj = VButtonBox( varargin ) + %uiextras.VButtonBox Create a new horizontal button box + + % Call uix constructor + obj@uix.VButtonBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structor + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/get.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/get.m new file mode 100644 index 00000000..fa1abd99 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/get.m @@ -0,0 +1,14 @@ +function varargout = get( ~, ~ ) %#ok +%uiextras.get Retrieve a default property value from a parent object +% +% This functionality has been removed. + +% Copyright 2009-2020 The MathWorks, Inc. + +% Check inputs +narginchk( 2, 2 ) + +% Error +error( 'uiextras:Deprecated', 'uiextras.get has been removed.' ) + +end % uiextras.get \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/set.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/set.m new file mode 100644 index 00000000..5e15f637 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/set.m @@ -0,0 +1,14 @@ +function set( ~, ~, ~ ) +%uiextras.set Store a default property value in a parent object +% +% This functionality has been removed. + +% Copyright 2009-2020 The MathWorks, Inc. + +% Check inputs +narginchk( 3, 3 ) + +% Warn +warning( 'uiextras:Deprecated', 'uiextras.set has been removed.' ) + +end % uiextras.set \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uiextras/unset.m b/studio_functions/GUI Layout Toolbox/layout/+uiextras/unset.m new file mode 100644 index 00000000..6ef522ca --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uiextras/unset.m @@ -0,0 +1,14 @@ +function unset( ~, ~, ~ ) +%uiextras.unset Clear a default property value from a parent object +% +% This functionality has been removed. + +% Copyright 2009-2020 The MathWorks, Inc. + +% Check inputs +narginchk( 2, 2 ) + +% Warn +warning( 'uiextras:Deprecated', 'uiextras.unset has been removed.' ) + +end % uiextras.unset \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Container.m b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Container.m new file mode 100644 index 00000000..02d9d3e3 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Container.m @@ -0,0 +1,319 @@ +classdef Container < handle + %uix.mixin.Container Container mixin + % + % uix.mixin.Container is a mixin class used by containers to provide + % various properties and template methods. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Dependent, Access = public ) + Contents % contents in layout order + end + + properties( Access = public, Dependent, AbortSet ) + Padding % space around contents, in pixels + end + + properties( Access = protected ) + Contents_ = gobjects( [0 1] ) % backing for Contents + Padding_ = 0 % backing for Padding + end + + properties( Dependent, Access = protected ) + Dirty % needs redraw + end + + properties( Access = private ) + Dirty_ = false % backing for Dirty + FigureObserver % observer + FigureListener % listener + ChildObserver % observer + ChildAddedListener % listener + ChildRemovedListener % listener + SizeChangedListener % listener + ActivePositionPropertyListeners = cell( [0 1] ) % listeners + end + + methods + + function obj = Container() + %uix.mixin.Container Initialize + % + % c@uix.mixin.Container() initializes the container c. + + % Create observers and listeners + figureObserver = uix.FigureObserver( obj ); + figureListener = event.listener( figureObserver, ... + 'FigureChanged', @obj.onFigureChanged ); + childObserver = uix.ChildObserver( obj ); + childAddedListener = event.listener( ... + childObserver, 'ChildAdded', @obj.onChildAdded ); + childRemovedListener = event.listener( ... + childObserver, 'ChildRemoved', @obj.onChildRemoved ); + sizeChangedListener = event.listener( ... + obj, 'SizeChanged', @obj.onSizeChanged ); + + % Store observers and listeners + obj.FigureObserver = figureObserver; + obj.FigureListener = figureListener; + obj.ChildObserver = childObserver; + obj.ChildAddedListener = childAddedListener; + obj.ChildRemovedListener = childRemovedListener; + obj.SizeChangedListener = sizeChangedListener; + + % Track usage + obj.track() + + end % constructor + + end % structors + + methods + + function value = get.Contents( obj ) + + value = obj.Contents_; + + end % get.Contents + + function set.Contents( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + [tf, indices] = ismember( value, obj.Contents_ ); + assert( isequal( size( obj.Contents_ ), size( value ) ) && ... + numel( value ) == numel( unique( value ) ) && all( tf ), ... + 'uix:InvalidOperation', ... + 'Property ''Contents'' may only be set to a permutation of itself.' ) + + % Call reorder + obj.reorder( indices ) + + end % set.Contents + + function value = get.Padding( obj ) + + value = obj.Padding_; + + end % get.Padding + + function set.Padding( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value >= 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''Padding'' must be a non-negative scalar.' ) + + % Set + obj.Padding_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Padding + + function value = get.Dirty( obj ) + + value = obj.Dirty_; + + end % get.Dirty + + function set.Dirty( obj, value ) + + if value + if obj.isDrawable() % drawable + obj.redraw() % redraw now + else % not drawable + obj.Dirty_ = true; % flag for future redraw + end + end + + end % set.Dirty + + end % accessors + + methods( Access = private, Sealed ) + + function onFigureChanged( obj, ~, eventData ) + %onFigureChanged Event handler + + % Call template method + obj.reparent( eventData.OldFigure, eventData.NewFigure ) + + % Redraw if possible and if dirty + if obj.Dirty_ && obj.isDrawable() + obj.redraw() + obj.Dirty_ = false; + end + + end % onFigureChanged + + function onChildAdded( obj, ~, eventData ) + %onChildAdded Event handler + + % Do nothing if add is internal tree surgery + if isTreeSurgery( eventData.Child ), return, end + + % Call template method + obj.addChild( eventData.Child ) + + end % onChildAdded + + function onChildRemoved( obj, ~, eventData ) + %onChildRemoved Event handler + + % Do nothing if container is being deleted + if strcmp( obj.BeingDeleted, 'on' ), return, end + + % Do nothing if remove is internal tree surgery + if isTreeSurgery( eventData.Child ), return, end + + % Call template method + obj.removeChild( eventData.Child ) + + end % onChildRemoved + + function onSizeChanged( obj, ~, ~ ) + %onSizeChanged Event handler + + % Mark as dirty + obj.Dirty = true; + + end % onSizeChanged + + function onActivePositionPropertyChanged( obj, ~, ~ ) + %onActivePositionPropertyChanged Event handler + + % Mark as dirty + obj.Dirty = true; + + end % onActivePositionPropertyChanged + + end % event handlers + + methods( Abstract, Access = protected ) + + redraw( obj ) + + end % abstract template methods + + methods( Access = protected ) + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to contents + obj.Contents_(end+1,:) = child; + + % Add listeners + if isa( child, 'matlab.graphics.axis.Axes' ) + obj.ActivePositionPropertyListeners{end+1,:} = ... + event.proplistener( child, ... + findprop( child, 'ActivePositionProperty' ), ... + 'PostSet', @obj.onActivePositionPropertyChanged ); + else + obj.ActivePositionPropertyListeners{end+1,:} = []; + end + + % Mark as dirty + obj.Dirty = true; + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from contents + contents = obj.Contents_; + tf = contents == child; + obj.Contents_(tf,:) = []; + + % Remove listeners + obj.ActivePositionPropertyListeners(tf,:) = []; + + % Mark as dirty + obj.Dirty = true; + + end % removeChild + + function reparent( obj, oldFigure, newFigure ) %#ok + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + end % reparent + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder contents + obj.Contents_ = obj.Contents_(indices,:); + + % Reorder listeners + obj.ActivePositionPropertyListeners = ... + obj.ActivePositionPropertyListeners(indices,:); + + % Mark as dirty + obj.Dirty = true; + + end % reorder + + function tf = isDrawable( obj ) + %isDrawable Test for drawability + % + % c.isDrawable() is true if the container c is drawable, and + % false otherwise. To be drawable, a container must be + % rooted. + + tf = ~isempty( obj.FigureObserver.Figure ); + + end % isDrawable + + function track( obj ) + %track Track usage + + persistent TRACKED % single shot + if isempty( TRACKED ) + v = ver( 'layout' ); + try %#ok + uix.tracking( 'UA-82270656-2', v(1).Version, class( obj ) ) + end + TRACKED = true; + end + + end % track + + end % template methods + +end % classdef + +function tf = isTreeSurgery( child ) +%isTreeSurgery Test for internal tree surgery +% +% Certain internal operations perform tree surgery, removing a child +% temporarily and adding it back under an additional node. + +if ~isa( child, 'matlab.graphics.axis.Axes' ) % only certain types + tf = false; +elseif verLessThan( 'MATLAB', '9.5' ) % only certain versions + tf = false; +else % check stack + s = dbstack(); + tf = any( strcmp( 'ScribeStackManager.createLayer', {s.name} ) ); +end + +end % isTreeSurgery \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Flex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Flex.m new file mode 100644 index 00000000..09f0fe3e --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Flex.m @@ -0,0 +1,70 @@ +classdef Flex < handle + %uix.mixin.Flex Flex mixin + % + % uix.mixin.Flex is a mixin class used by flex containers to provide + % various properties and helper methods. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( GetAccess = protected, SetAccess = private ) + Pointer = 'unset' % mouse pointer + end + + properties( Access = private ) + Figure = gobjects( 0 ); % mouse pointer figure + Token = -1 % mouse pointer token + end + + methods + + function delete( obj ) + %delete Destructor + + % Clean up + if ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % destructor + + end % structors + + methods( Access = protected ) + + function setPointer( obj, figure, pointer ) + %setPointer Set pointer + % + % c.setPointer(f,p) sets the pointer for the figure f to p. + + % If set, unset + if obj.Token ~= -1 + obj.unsetPointer() + end + + % Set + obj.Token = uix.PointerManager.setPointer( figure, pointer ); + obj.Figure = figure; + obj.Pointer = pointer; + + end % setPointer + + function unsetPointer( obj ) + %unsetPointer Unset pointer + % + % c.unsetPointer() undoes the previous pointer set. + + % Check + assert( obj.Token ~= -1, 'uix:InvalidOperation', ... + 'Pointer is already unset.' ) + + % Unset + uix.PointerManager.unsetPointer( obj.Figure, obj.Token ); + obj.Figure = gobjects( 0 ); + obj.Pointer = 'unset'; + obj.Token = -1; + + end % unsetPointer + + end % helper methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Panel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Panel.m new file mode 100644 index 00000000..ec718124 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/+mixin/Panel.m @@ -0,0 +1,187 @@ +classdef Panel < uix.mixin.Container + %uix.mixin.Panel Panel mixin + % + % uix.mixin.Panel is a mixin class used by panels to provide various + % properties and template methods. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + Selection % selected contents + end + + properties( Access = protected ) + Selection_ = 0 % backing for Selection + end + + properties( Access = protected ) + G1218142 = false % bug flag + end + + events( NotifyAccess = protected ) + SelectionChanged % selection changed + end + + methods + + function value = get.Selection( obj ) + + value = obj.Selection_; + + end % get.Selection + + function set.Selection( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be of type double.' ) + assert( isequal( size( value ), [1 1] ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be scalar.' ) + assert( isreal( value ) && rem( value, 1 ) == 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be an integer.' ) + n = numel( obj.Contents_ ); + if n == 0 + assert( value == 0, 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be 0 for a container with no children.' ) + else + assert( value >= 1 && value <= n, 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be between 1 and the number of children.' ) + end + + % Set + oldSelection = obj.Selection_; + newSelection = value; + obj.Selection_ = newSelection; + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + % Raise event + notify( obj, 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + + end % set.Selection + + end % accessors + + methods( Access = protected ) + + function addChild( obj, child ) + + % Check for bug + if verLessThan( 'MATLAB', '8.5' ) && strcmp( child.Visible, 'off' ) + obj.G1218142 = true; + end + + % Select new content + oldSelection = obj.Selection_; + newSelection = numel( obj.Contents_ ) + 1; + obj.Selection_ = newSelection; + + % Call superclass method + addChild@uix.mixin.Container( obj, child ) + + % Show selected child + obj.showSelection() + + % Notify selection change + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + + end % addChild + + function removeChild( obj, child ) + + % Adjust selection if required + contents = obj.Contents_; + index = find( contents == child ); + oldSelection = obj.Selection_; + if index < oldSelection + newSelection = oldSelection - 1; + elseif index == oldSelection + newSelection = min( oldSelection, numel( contents ) - 1 ); + else % index > oldSelection + newSelection = oldSelection; + end + obj.Selection_ = newSelection; + + % Call superclass method + removeChild@uix.mixin.Container( obj, child ) + + % Show selected child + obj.showSelection() + + % Notify selection change + if oldSelection ~= newSelection + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + end + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + selection = obj.Selection_; + if selection ~= 0 + obj.Selection_ = find( indices == selection ); + end + + % Call superclass method + reorder@uix.mixin.Container( obj, indices ) + + end % reorder + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Set positions and visibility + selection = obj.Selection_; + children = obj.Contents_; + for ii = 1:numel( children ) + child = children(ii); + if ii == selection + if obj.G1218142 + warning( 'uix:G1218142', ... + 'Selected child of %s is not visible due to bug G1218142. The child will become visible at the next redraw.', ... + class( obj ) ) + obj.G1218142 = false; + else + child.Visible = 'on'; + end + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'on'; + end + else + child.Visible = 'off'; + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'off'; + end + % As a remedy for g1100294, move off-screen too + margin = 1000; + if isa( child, 'matlab.graphics.axis.Axes' ) ... + && strcmp(child.ActivePositionProperty, 'outerposition' ) + child.OuterPosition(1) = -child.OuterPosition(3)-margin; + else + child.Position(1) = -child.Position(3)-margin; + end + end + end + + end % showSelection + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Box.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Box.m new file mode 100644 index 00000000..b06c3cf6 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Box.m @@ -0,0 +1,44 @@ +classdef Box < uix.Container & uix.mixin.Container + %uix.Box Box and grid base class + % + % uix.Box is a base class for containers with spacing between + % contents. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + Spacing = 0 % space between contents, in pixels + end + + properties( Access = protected ) + Spacing_ = 0 % backing for Spacing + end + + methods + + function value = get.Spacing( obj ) + + value = obj.Spacing_; + + end % get.Spacing + + function set.Spacing( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value >= 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''Spacing'' must be a non-negative scalar.' ) + + % Set + obj.Spacing_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Spacing + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/BoxPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/BoxPanel.m new file mode 100644 index 00000000..6e8e0254 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/BoxPanel.m @@ -0,0 +1,646 @@ +classdef BoxPanel < uix.Panel & uix.mixin.Panel + %uix.BoxPanel Box panel + % + % p = uix.BoxPanel(p1,v1,p2,v2,...) constructs a box panel and sets + % parameter p1 to value v1, etc. + % + % A box panel is a decorated container with a title box, border, and + % buttons to dock and undock, minimize, get help, and close. A box + % panel shows one of its contents and hides the others. + % + % See also: uix.Panel, uipanel, uix.CardPanel + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Dependent ) + TitleColor % title background color [RGB] + Minimized % minimized [true|false] + MinimizeFcn % minimize callback + Docked % docked [true|false] + DockFcn % dock callback + HelpFcn % help callback + CloseRequestFcn % close request callback + end + + properties( Dependent, SetAccess = private ) + TitleHeight % title panel height [pixels] + end + + properties( Access = private ) + TitleBox % title bar box + TitleText % title text label + EmptyTitle = '' % title when empty, [] otherwise + TitleAccess = 'public' % 'private' when getting or setting Title, 'public' otherwise + TitleHeight_ = -1 % cache of title text height (-1 denotes stale cache) + MinimizeButton % title button + DockButton % title button + HelpButton % title button + CloseButton % title button + Docked_ = true % backing for Docked + Minimized_ = false % backing for Minimized + end + + properties( Constant, Access = private ) + NullTitle = char.empty( [2 0] ) % an obscure empty string, the actual panel Title + BlankTitle = ' ' % a non-empty blank string, the empty uicontrol String + end + + properties + MaximizeTooltipString = 'Expand this panel' % tooltip string + MinimizeTooltipString = 'Collapse this panel' % tooltip string + UndockTooltipString = 'Undock this panel' % tooltip string + DockTooltipString = 'Dock this panel' % tooltip string + HelpTooltipString = 'Get help on this panel' % tooltip string + CloseTooltipString = 'Close this panel' % tooltip string + end + + methods + + function obj = BoxPanel( varargin ) + %uix.BoxPanel Box panel constructor + % + % p = uix.BoxPanel() constructs a box panel. + % + % p = uix.BoxPanel(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Define default colors + foregroundColor = [1 1 1]; + backgroundColor = [0.05 0.25 0.5]; + + % Set default colors + obj.ForegroundColor = foregroundColor; + + % Create panels and decorations + titleBox = uix.HBox( 'Internal', true, 'Parent', obj, ... + 'Units', 'pixels', 'BackgroundColor', backgroundColor ); + titleText = uix.Text( 'Parent', titleBox, ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'String', obj.BlankTitle, 'HorizontalAlignment', 'left' ); + + % Create buttons + minimizeButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'Enable', 'on' ); + dockButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'Enable', 'on' ); + helpButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'String', '?', ... + 'TooltipString', obj.HelpTooltipString, 'Enable', 'on' ); + closeButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'String', char( 215 ), ... + 'TooltipString', obj.CloseTooltipString, 'Enable', 'on' ); + + % Store properties + obj.Title = obj.NullTitle; + obj.TitleBox = titleBox; + obj.TitleText = titleText; + obj.MinimizeButton = minimizeButton; + obj.DockButton = dockButton; + obj.HelpButton = helpButton; + obj.CloseButton = closeButton; + + % Create listeners + addlistener( obj, 'BorderWidth', 'PostSet', ... + @obj.onBorderWidthChanged ); + addlistener( obj, 'BorderType', 'PostSet', ... + @obj.onBorderTypeChanged ); + addlistener( obj, 'FontAngle', 'PostSet', ... + @obj.onFontAngleChanged ); + addlistener( obj, 'FontName', 'PostSet', ... + @obj.onFontNameChanged ); + addlistener( obj, 'FontSize', 'PostSet', ... + @obj.onFontSizeChanged ); + addlistener( obj, 'FontUnits', 'PostSet', ... + @obj.onFontUnitsChanged ); + addlistener( obj, 'FontWeight', 'PostSet', ... + @obj.onFontWeightChanged ); + addlistener( obj, 'ForegroundColor', 'PostSet', ... + @obj.onForegroundColorChanged ); + addlistener( obj, 'Title', 'PreGet', ... + @obj.onTitleReturning ); + addlistener( obj, 'Title', 'PostGet', ... + @obj.onTitleReturned ); + addlistener( obj, 'Title', 'PostSet', ... + @obj.onTitleChanged ); + + % Draw buttons + obj.redrawButtons() + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.TitleColor( obj ) + + value = obj.TitleBox.BackgroundColor; + + end % get.TitleColor + + function set.TitleColor( obj, value ) + + % Set + obj.TitleBox.BackgroundColor = value; + obj.TitleText.BackgroundColor = value; + obj.MinimizeButton.BackgroundColor = value; + obj.DockButton.BackgroundColor = value; + obj.HelpButton.BackgroundColor = value; + obj.CloseButton.BackgroundColor = value; + + end % set.TitleColor + + function value = get.CloseRequestFcn( obj ) + + value = obj.CloseButton.Callback; + + end % get.CloseRequestFcn + + function set.CloseRequestFcn( obj, value ) + + % Set + obj.CloseButton.Callback = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.CloseRequestFcn + + function value = get.DockFcn( obj ) + + value = obj.DockButton.Callback; + + end % get.DockFcn + + function set.DockFcn( obj, value ) + + % Set + obj.DockButton.Callback = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.DockFcn + + function value = get.HelpFcn( obj ) + + value = obj.HelpButton.Callback; + + end % get.HelpFcn + + function set.HelpFcn( obj, value ) + + % Set + obj.HelpButton.Callback = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.HelpFcn + + function value = get.MinimizeFcn( obj ) + + value = obj.MinimizeButton.Callback; + + end % get.MinimizeFcn + + function set.MinimizeFcn( obj, value ) + + % Set + obj.MinimizeButton.Callback = value; + obj.TitleText.Callback = value; + if isempty( value ) + obj.TitleText.Enable = 'inactive'; + else + obj.TitleText.Enable = 'on'; + end + + % Mark as dirty + obj.redrawButtons() + + end % set.MinimizeFcn + + function value = get.Docked( obj ) + + value = obj.Docked_; + + end % get.Docked + + function set.Docked( obj, value ) + + % Check + assert( islogical( value ) && isequal( size( value ), [1 1] ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''Docked'' must be true or false.' ) + + % Set + obj.Docked_ = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.Docked + + function value = get.Minimized( obj ) + + value = obj.Minimized_; + + end % get.Minimized + + function set.Minimized( obj, value ) + + % Check + assert( islogical( value ) && isequal( size( value ), [1 1] ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''Minimized'' must be true or false.' ) + + % Set + obj.Minimized_ = value; + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + end % set.Minimized + + function value = get.TitleHeight( obj ) + + value = obj.TitleBox.Position(4); + + end % get.TitleHeight + + function set.MaximizeTooltipString( obj, value ) + + % Check + assert( ischar( value ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''MaximizeTooltipString'' must be a string.' ) + + % Set + obj.MaximizeTooltipString = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.MaximizeTooltipString + + function set.MinimizeTooltipString( obj, value ) + + % Check + assert( ischar( value ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''MinimizeTooltipString'' must be a string.' ) + + % Set + obj.MinimizeTooltipString = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.MinimizeTooltipString + + function set.UndockTooltipString( obj, value ) + + % Check + assert( ischar( value ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''UndockTooltipString'' must be a string.' ) + + % Set + obj.UndockTooltipString = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.UndockTooltipString + + function set.DockTooltipString( obj, value ) + + % Check + assert( ischar( value ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''DockTooltipString'' must be a string.' ) + + % Set + obj.DockTooltipString = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.DockTooltipString + + function set.HelpTooltipString( obj, value ) + + % Check + assert( ischar( value ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''HelpTooltipString'' must be a string.' ) + + % Set + obj.HelpTooltipString = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.HelpTooltipString + + function set.CloseTooltipString( obj, value ) + + % assert that value is a char array + assert( ischar( value ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''CloseTooltipString'' must be a string.' ) + + obj.CloseTooltipString = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.CloseTooltipString + + end % accessors + + methods( Access = private ) + + function onBorderWidthChanged( obj, ~, ~ ) + + % Mark as dirty + obj.Dirty = true; + + end % onBorderWidthChanged + + function onBorderTypeChanged( obj, ~, ~ ) + + % Mark as dirty + obj.Dirty = true; + + end % onBorderTypeChanged + + function onFontAngleChanged( obj, ~, ~ ) + + obj.TitleText.FontAngle = obj.FontAngle; + + end % onFontAngleChanged + + function onFontNameChanged( obj, ~, ~ ) + + % Set + obj.TitleText.FontName = obj.FontName; + + % Mark as dirty + obj.TitleHeight_ = -1; + obj.Dirty = true; + + end % onFontNameChanged + + function onFontSizeChanged( obj, ~, ~ ) + + % Set + fontSize = obj.FontSize; + obj.TitleText.FontSize = fontSize; + obj.HelpButton.FontSize = fontSize; + obj.CloseButton.FontSize = fontSize; + obj.DockButton.FontSize = fontSize; + obj.MinimizeButton.FontSize = fontSize; + + % Mark as dirty + obj.TitleHeight_ = -1; + obj.Dirty = true; + + end % onFontSizeChanged + + function onFontUnitsChanged( obj, ~, ~ ) + + fontUnits = obj.FontUnits; + obj.TitleText.FontUnits = fontUnits; + obj.HelpButton.FontUnits = fontUnits; + obj.CloseButton.FontUnits = fontUnits; + obj.DockButton.FontUnits = fontUnits; + obj.MinimizeButton.FontUnits = fontUnits; + + end % onFontUnitsChanged + + function onFontWeightChanged( obj, ~, ~ ) + + obj.TitleText.FontWeight = obj.FontWeight; + + end % onFontWeightChanged + + function onForegroundColorChanged( obj, ~, ~ ) + + foregroundColor = obj.ForegroundColor; + obj.TitleText.ForegroundColor = foregroundColor; + obj.MinimizeButton.ForegroundColor = foregroundColor; + obj.DockButton.ForegroundColor = foregroundColor; + obj.HelpButton.ForegroundColor = foregroundColor; + obj.CloseButton.ForegroundColor = foregroundColor; + + end % onForegroundColorChanged + + function onTitleReturning( obj, ~, ~ ) + + if strcmp( obj.TitleAccess, 'public' ) + + obj.TitleAccess = 'private'; % start + if ischar( obj.EmptyTitle ) + obj.Title = obj.EmptyTitle; + else + obj.Title = obj.TitleText.String; + end + + end + + end % onTitleReturning + + function onTitleReturned( obj, ~, ~ ) + + obj.Title = obj.NullTitle; % unset Title + obj.TitleAccess = 'public'; % finish + + end % onTitleReturned + + function onTitleChanged( obj, ~, ~ ) + + if strcmp( obj.TitleAccess, 'public' ) + + % Set + obj.TitleAccess = 'private'; % start + title = obj.Title; + if isempty( title ) + obj.EmptyTitle = title; % store + obj.TitleText.String = obj.BlankTitle; % set String to blank + else + obj.EmptyTitle = []; % not empty + obj.TitleText.String = title; % set String to title + end + obj.Title = obj.NullTitle; % unset Title + obj.TitleAccess = 'public'; % finish + + % Mark as dirty + obj.TitleHeight_ = -1; + obj.Dirty = true; + + end + + end % onTitleChanged + + end % property event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % p.redraw() redraws the panel. + % + % See also: redrawButtons + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + tX = 1; + tW = max( bounds(3), 1 ); + tH = obj.TitleHeight_; % title height + if tH == -1 % cache stale, refresh + tH = ceil( obj.TitleText.Extent(4) ); + obj.TitleHeight_ = tH; % store + end + tY = 1 + bounds(4) - tH; + p = obj.Padding_; + cX = 1 + p; + cW = max( bounds(3) - 2 * p, 1 ); + cH = max( bounds(4) - tH - 2 * p, 1 ); + cY = tY - p - cH; + contentsPosition = [cX cY cW cH]; + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 + uix.setPosition( obj.Contents_(selection), contentsPosition, 'pixels' ) + end + obj.TitleBox.Position = [tX tY tW tH]; + obj.redrawButtons() + + end % redraw + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Call superclass method + showSelection@uix.mixin.Panel( obj ) + + % If minimized, hide selected contents too + selection = obj.Selection_; + if selection ~= 0 && obj.Minimized_ + child = obj.Contents_(selection); + child.Visible = 'off'; + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'off'; + end + % As a remedy for g1100294, move off-screen too + margin = 1000; + if isa( child, 'matlab.graphics.axis.Axes' ) ... + && strcmp(child.ActivePositionProperty, 'outerposition' ) + child.OuterPosition(1) = -child.OuterPosition(3)-margin; + else + child.Position(1) = -child.Position(3)-margin; + end + end + + end % showSelection + + end % template methods + + methods( Access = private ) + + function redrawButtons( obj ) + %redrawButtons Redraw buttons + % + % p.redrawButtons() redraws the titlebar buttons. + % + % Buttons use unicode arrow symbols: + % https://en.wikipedia.org/wiki/Arrow_%28symbol%29#Arrows_in_Unicode + + % Retrieve button box and buttons + box = obj.TitleBox; + titleText = obj.TitleText; + minimizeButton = obj.MinimizeButton; + dockButton = obj.DockButton; + helpButton = obj.HelpButton; + closeButton = obj.CloseButton; + + % Detach all buttons + titleText.Parent = []; + minimizeButton.Parent = []; + dockButton.Parent = []; + helpButton.Parent = []; + closeButton.Parent = []; + + % Attach active buttons + titleText.Parent = box; + minimize = ~isempty( obj.MinimizeFcn ); + if minimize + minimizeButton.Parent = box; + box.Widths(end) = minimizeButton.Extent(3); + end + dock = ~isempty( obj.DockFcn ); + if dock + dockButton.Parent = box; + box.Widths(end) = dockButton.Extent(3); + end + help = ~isempty( obj.HelpFcn ); + if help + helpButton.Parent = box; + helpButton.TooltipString = obj.HelpTooltipString; + box.Widths(end) = helpButton.Extent(3); + end + close = ~isempty( obj.CloseRequestFcn ); + if close + closeButton.Parent = box; + closeButton.TooltipString = obj.CloseTooltipString; + box.Widths(end) = closeButton.Extent(3); + end + + % Update icons + if obj.Minimized_ + minimizeButton.String = char( 9662 ); + minimizeButton.TooltipString = obj.MaximizeTooltipString; + else + minimizeButton.String = char( 9652 ); + minimizeButton.TooltipString = obj.MinimizeTooltipString; + end + if obj.Docked_ + dockButton.String = char( 8599 ); + dockButton.TooltipString = obj.UndockTooltipString; + else + dockButton.String = char( 8600 ); + dockButton.TooltipString = obj.DockTooltipString; + end + + end % redrawButtons + + end % helper methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ButtonBox.m new file mode 100644 index 00000000..086117a2 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ButtonBox.m @@ -0,0 +1,95 @@ +classdef ButtonBox < uix.Box + %uix.ButtonBox Button box base class + % + % uix.ButtonBox is a base class for containers that lay out buttons. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + ButtonSize % button size, in pixels + HorizontalAlignment % horizontal alignment [left|center|right] + VerticalAlignment % vertical alignment [top|middle|bottom] + end + + properties( Access = protected ) + ButtonSize_ = [60 20] % backing for ButtonSize + HorizontalAlignment_ = 'center' % backing for HorizontalAlignment + VerticalAlignment_ = 'middle' % backing for VerticalAlignment + end + + methods + + function value = get.ButtonSize( obj ) + + value = obj.ButtonSize_; + + end % get.ButtonSize + + function set.ButtonSize( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''ButtonSize'' must be of type double.' ) + assert( isequal( size( value ), [1 2] ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''ButtonSize'' must by 1-by-2.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ) && ~any( value <= 0 ), ... + 'uix:InvalidPropertyValue', ... + 'Elements of property ''ButtonSize'' must be real, finite and positive.' ) + + % Set + obj.ButtonSize_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.ButtonSize + + function value = get.HorizontalAlignment( obj ) + + value = obj.HorizontalAlignment_; + + end % get.HorizontalAlignment + + function set.HorizontalAlignment( obj, value ) + + % Check + assert( ischar( value ), 'uix:InvalidPropertyValue', ... + 'Property ''HorizontalAlignment'' must be a string.' ) + assert( any( strcmp( value, {'left';'center';'right'} ) ), ... + 'Property ''HorizontalAlignment'' must be ''left'', ''center'' or ''right''.' ) + + % Set + obj.HorizontalAlignment_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.HorizontalAlignment + + function value = get.VerticalAlignment( obj ) + + value = obj.VerticalAlignment_; + + end % get.VerticalAlignment + + function set.VerticalAlignment( obj, value ) + + % Check + assert( ischar( value ), 'uix:InvalidPropertyValue', ... + 'Property ''VerticalAlignment'' must be a string.' ) + assert( any( strcmp( value, {'top';'middle';'bottom'} ) ), ... + 'Property ''VerticalAlignment'' must be ''top'', ''middle'' or ''bottom''.' ) + + % Set + obj.VerticalAlignment_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.VerticalAlignment + + end % accessors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/CardPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/CardPanel.m new file mode 100644 index 00000000..3942deca --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/CardPanel.m @@ -0,0 +1,59 @@ +classdef CardPanel < uix.Container & uix.mixin.Panel + %uix.CardPanel Card panel + % + % b = uix.CardPanel(p1,v1,p2,v2,...) constructs a card panel and sets + % parameter p1 to value v1, etc. + % + % A card panel is a standard container (uicontainer) that shows one + % its contents and hides the others. + % + % See also: uix.Panel, uix.BoxPanel, uix.TabPanel, uicontainer + + % Copyright 2009-2020 The MathWorks, Inc. + + methods + + function obj = CardPanel( varargin ) + %uix.CardPanel Card panel constructor + % + % p = uix.CardPanel() constructs a card panel. + % + % p = uix.CardPanel(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + padding = obj.Padding_; + xSizes = uix.calcPixelSizes( bounds(3), -1, 1, padding, 0 ); + ySizes = uix.calcPixelSizes( bounds(4), -1, 1, padding, 0 ); + position = [padding+1 padding+1 xSizes ySizes]; + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 + uix.setPosition( obj.Contents_(selection), position, 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ChildEvent.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildEvent.m new file mode 100644 index 00000000..fa066a3b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildEvent.m @@ -0,0 +1,27 @@ +classdef( Hidden, Sealed ) ChildEvent < event.EventData + %uix.ChildEvent Event data for child event + % + % e = uix.ChildEvent(c) creates event data including the child c. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( SetAccess = private ) + Child % child + end + + methods + + function obj = ChildEvent( child ) + %uix.ChildEvent Event data for child event + % + % e = uix.ChildEvent(c) creates event data including the child + % c. + + % Set properties + obj.Child = child; + + end % constructor + + end % structors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ChildObserver.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildObserver.m new file mode 100644 index 00000000..b3bc02bc --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ChildObserver.m @@ -0,0 +1,223 @@ +classdef ( Hidden, Sealed ) ChildObserver < handle + %uix.ChildObserver Child observer + % + % co = uix.ChildObserver(o) creates a child observer for the graphics + % object o. A child observer raises events when objects are added to + % and removed from the property Children of o. + % + % See also: uix.Node + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = private ) + Root % root node + end + + events( NotifyAccess = private ) + ChildAdded % child added + ChildRemoved % child removed + end + + methods + + function obj = ChildObserver( oRoot ) + %uix.ChildObserver Child observer + % + % co = uix.ChildObserver(o) creates a child observer for the + % graphics object o. A child observer raises events when + % objects are added to and removed from the property Children + % of o. + + % Check + assert( ispositionable( oRoot ) && ... + isequal( size( oRoot ), [1 1] ), 'uix.InvalidArgument', ... + 'Object must be a graphics object.' ) + + % Create root node + nRoot = uix.Node( oRoot ); + childAddedListener = event.listener( oRoot, ... + 'ObjectChildAdded', ... + @(~,e)obj.addChild(nRoot,e.Child) ); + childAddedListener.Recursive = true; + nRoot.addprop( 'ChildAddedListener' ); + nRoot.ChildAddedListener = childAddedListener; + childRemovedListener = event.listener( oRoot, ... + 'ObjectChildRemoved', ... + @(~,e)obj.removeChild(nRoot,e.Child) ); + childRemovedListener.Recursive = true; + nRoot.addprop( 'ChildRemovedListener' ); + nRoot.ChildRemovedListener = childRemovedListener; + + % Add children + oChildren = hgGetTrueChildren( oRoot ); + for ii = 1:numel( oChildren ) + obj.addChild( nRoot, oChildren(ii) ) + end + + % Store properties + obj.Root = nRoot; + + end % constructor + + end % structors + + methods( Access = private ) + + function addChild( obj, nParent, oChild ) + %addChild Add child object to parent node + % + % co.addChild(np,oc) adds the child object oc to the parent + % node np, either as part of construction of the child + % observer co, or in response to an ObjectChildAdded event on + % an object of interest to co. This may lead to ChildAdded + % events being raised on co. + + % Create child node + nChild = uix.Node( oChild ); + nParent.addChild( nChild ) + positionable = ispositionable( oChild ); + if positionable == true + % Add Internal PreSet property listener + internalPreSetListener = event.proplistener( oChild, ... + findprop( oChild, 'Internal' ), 'PreSet', ... + @(~,~)obj.preSetInternal(nChild) ); + nChild.addprop( 'InternalPreSetListener' ); + nChild.InternalPreSetListener = internalPreSetListener; + % Add Internal PostSet property listener + internalPostSetListener = event.proplistener( oChild, ... + findprop( oChild, 'Internal' ), 'PostSet', ... + @(~,~)obj.postSetInternal(nChild) ); + nChild.addprop( 'InternalPostSetListener' ); + nChild.InternalPostSetListener = internalPostSetListener; + else + % Add ObjectChildAdded listener + childAddedListener = event.listener( oChild, ... + 'ObjectChildAdded', ... + @(~,e)obj.addChild(nChild,e.Child) ); + nChild.addprop( 'ChildAddedListener' ); + nChild.ChildAddedListener = childAddedListener; + % Add ObjectChildRemoved listener + childRemovedListener = event.listener( oChild, ... + 'ObjectChildRemoved', ... + @(~,e)obj.removeChild(nChild,e.Child) ); + nChild.addprop( 'ChildRemovedListener' ); + nChild.ChildRemovedListener = childRemovedListener; + end + + % Raise ChildAdded event + if positionable == true && oChild.Internal == false + notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) ) + end + + % Add grandchildren + if positionable == false && isblacklisted( oChild ) == false + oGrandchildren = hgGetTrueChildren( oChild ); + for ii = 1:numel( oGrandchildren ) + obj.addChild( nChild, oGrandchildren(ii) ) + end + end + + end % addChild + + function removeChild( obj, nParent, oChild ) + %removeChild Remove child object from parent node + % + % co.removeChild(np,oc) removes the child object oc from the + % parent node np, in response to an ObjectChildRemoved event + % on an object of interest to co. This may lead to + % ChildRemoved events being raised on co. + + % Get child node + nChildren = nParent.Children; + tf = oChild == [nChildren.Object]; + nChild = nChildren(tf); + + % Raise ChildRemoved event(s) + notifyChildRemoved( nChild ) + + % Delete child node + delete( nChild ) + + function notifyChildRemoved( nc ) + + % Process child nodes + ngc = nc.Children; + for ii = 1:numel( ngc ) + notifyChildRemoved( ngc(ii) ) + end + + % Process this node + oc = nc.Object; + if ispositionable( oc ) == true && oc.Internal == false + notify( obj, 'ChildRemoved', uix.ChildEvent( oc ) ) + end + + end % notifyChildRemoved + + end % removeChild + + function preSetInternal( ~, nChild ) + %preSetInternal Perform property PreSet tasks + % + % co.preSetInternal(n) caches the previous value of the + % property Internal of the object referenced by the node n, to + % enable PostSet tasks to identify whether the value changed. + % This is necessary since Internal AbortSet is false. + + oldInternal = nChild.Object.Internal; + nChild.addprop( 'OldInternal' ); + nChild.OldInternal = oldInternal; + + end % preSetInternal + + function postSetInternal( obj, nChild ) + %postSetInternal Perform property PostSet tasks + % + % co.postSetInternal(n) raises a ChildAdded or ChildRemoved + % event on the child observer co in response to a change of + % the value of the property Internal of the object referenced + % by the node n. + + % Retrieve old and new values + oChild = nChild.Object; + newInternal = oChild.Internal; + oldInternal = nChild.OldInternal; + + % Clean up node + delete( findprop( nChild, 'OldInternal' ) ) + + % Raise event + switch newInternal + case oldInternal % no change + % no event + case true % false to true + notify( obj, 'ChildRemoved', uix.ChildEvent( oChild ) ) + case false % true to false + notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) ) + end + + end % postSetInternal + + end % event handlers + +end % classdef + +function tf = ispositionable( o ) +%ispositionable True for positionable graphics + +p = findprop( o, 'Position' ); +tf = isgraphics( o ) && ~isempty( p ) && ... + isequal( p.GetAccess, 'public' ) && ... + isequal( p.SetAccess, 'public' ) && ... + isequal( size( o.Position ), [1 4] ); + +end % ispositionable + +function tf = isblacklisted( o ) +%isblacklisted True for objects that never have positionable graphics + +tf = isa( o, 'matlab.ui.container.Menu' ) || ... + isa( o, 'matlab.ui.container.Toolbar' ) || ... + isa( o, 'matlab.graphics.shape.internal.AnnotationPane' ); + +end % isblacklisted \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Container.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Container.m new file mode 100644 index 00000000..e071a82b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Container.m @@ -0,0 +1,8 @@ +classdef Container < matlab.ui.container.internal.UIContainer + %uix.Container Container base class + % + % uix.Container is base class for containers that extend uicontainer. + + % Copyright 2009-2020 The MathWorks, Inc. + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Divider.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Divider.m new file mode 100644 index 00000000..8ec39d41 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Divider.m @@ -0,0 +1,346 @@ +classdef ( Hidden ) Divider < matlab.mixin.SetGet + %uix.Divider Draggable divider + % + % d = uix.Divider() creates a divider. + % + % d = uix.Divider(p1,v1,p2,v2,...) creates a divider and sets + % specified property p1 to value v1, etc. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Dependent ) + Parent % parent + Units % units [inches|centimeters|characters|normalized|points|pixels] + Position % position + Visible % visible [on|off] + BackgroundColor % background color [RGB] + HighlightColor % border highlight color [RGB] + ShadowColor % border shadow color [RGB] + Orientation % orientation [vertical|horizontal] + Markings % markings [pixels] + end + + properties( Access = private ) + Control % uicontrol + BackgroundColor_ = get( 0, 'DefaultUicontrolBackgroundColor' ) % backing for BackgroundColor + HighlightColor_ = [1 1 1] % backing for HighlightColor + ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor + Orientation_ = 'vertical' % backing for Orientation + Markings_ = zeros( [0 1] ) % backing for Markings + SizeChangedListener % listener + end + + methods + + function obj = Divider( varargin ) + %uix.Divider Draggable divider + % + % d = uix.Divider() creates a divider. + % + % d = uix.Divider(p1,v1,p2,v2,...) creates a dividerand sets + % specified property p1 to value v1, etc. + + % Create control + control = matlab.ui.control.UIControl( ... + 'Style', 'checkbox', 'Internal', true, ... + 'Enable', 'inactive', 'DeleteFcn', @obj.onDeleted,... + 'Tag', 'uix.Divider' ); + + % Store control + obj.Control = control; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + % Force update + obj.update() + + % Create listener + sizeChangedListener = event.listener( control, 'SizeChanged', ... + @obj.onSizeChanged ); + + % Store listener + obj.SizeChangedListener = sizeChangedListener; + + end % constructor + + function delete( obj ) + %delete Destructor + + control = obj.Control; + if isgraphics( control ) && strcmp( control.BeingDeleted, 'off' ) + delete( control ) + end + + end % destructor + + end % structors + + methods + + function value = get.Parent( obj ) + + value = obj.Control.Parent; + + end % get.Parent + + function set.Parent( obj, value ) + + obj.Control.Parent = value; + + end % set.Parent + + function value = get.Units( obj ) + + value = obj.Control.Units; + + end % get.Units + + function set.Units( obj, value ) + + obj.Control.Units = value; + + end % set.Units + + function value = get.Position( obj ) + + value = obj.Control.Position; + + end % get.Position + + function set.Position( obj, value ) + + obj.Control.Position = value; + + end % set.Position + + function value = get.Visible( obj ) + + value = obj.Control.Visible; + + end % get.Visible + + function set.Visible( obj, value ) + + obj.Control.Visible = value; + + end % set.Visible + + function value = get.BackgroundColor( obj ) + + value = obj.BackgroundColor_; + + end % get.BackgroundColor + + function set.BackgroundColor( obj, value ) + + % Check + assert( isa( value, 'double' ) && ... + isequal( size( value ), [1 3] ) && ... + all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidArgument', ... + 'Property ''BackgroundColor'' must be a valid colorspec.' ) + + % Set + obj.BackgroundColor_ = value; + + % Update + obj.update() + + end % set.BackgroundColor + + function value = get.HighlightColor( obj ) + + value = obj.HighlightColor_; + + end % get.HighlightColor + + function set.HighlightColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''HighlightColor'' must be an RGB triple.' ) + + % Set + obj.HighlightColor_ = value; + + % Update + obj.update() + + end % set.HighlightColor + + function value = get.ShadowColor( obj ) + + value = obj.ShadowColor_; + + end % get.ShadowColor + + function set.ShadowColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''ShadowColor'' must be an RGB triple.' ) + + % Set + obj.ShadowColor_ = value; + + % Update + obj.update() + + end % set.ShadowColor + + function value = get.Orientation( obj ) + + value = obj.Orientation_; + + end % get.Orientation + + function set.Orientation( obj, value ) + + % Check + assert( ischar( value ) && ismember( value, ... + {'horizontal','vertical'} ) ) + + % Set + obj.Orientation_ = value; + + % Update + obj.update() + + end % set.Orientation + + function value = get.Markings( obj ) + + value = obj.Markings_; + + end % get.Markings + + function set.Markings( obj, value ) + + % Check + assert( isa( value, 'double' ) && ndims( value ) == 2 && ... + size( value, 2 ) == 1 && all( isreal( value ) ) && ... + all( ~isinf( value ) ) && all( ~isnan( value ) ) && ... + all( value > 0 ), 'uix:InvalidPropertyValue', ... + 'Property ''Markings'' must be a vector of positive values.' ) %#ok + + % Set + obj.Markings_ = value; + + % Update + obj.update() + + end % set.Markings + + end % accessors + + methods + + function tf = isMouseOver( obj, eventData ) + %isMouseOver Test for mouse over + % + % tf = d.isMouseOver(wmd) tests whether the WindowMouseData + % wmd is consistent with the mouse pointer being over the + % divider d. + % + % This method returns false for dividers that are being + % deleted. + + tf = isvalid( obj ); % initialize + for ii = 1:numel( obj ) + tf(ii) = tf(ii) && ~isempty( eventData.HitObject ) && ... + obj(ii).Control == eventData.HitObject; + end + + end % isMouseOver + + end % methods + + methods( Access = private ) + + function onDeleted( obj, ~, ~ ) + %onDeleted Event handler + + % Call destructor + obj.delete() + + end % onDeleted + + function onSizeChanged( obj, ~, ~ ) + %onSizeChanged Event handler + + % Update + obj.update() + + end % onSizeChanged + + end % event handlers + + methods( Access = private ) + + function update( obj ) + %update Update divider + % + % d.update() updates the divider markings. + + % Get properties + control = obj.Control; + position = control.Position; + backgroundColor = obj.BackgroundColor; + highlightColor = obj.HighlightColor; + shadowColor = obj.ShadowColor; + orientation = obj.Orientation; + markings = obj.Markings; + + % Assemble mask + mask = zeros( floor( position([4 3]) ) - [1 1] ); % initialize + switch orientation + case 'vertical' + markings(markings < 4) = []; + markings(markings > position(4)-6) = []; + for ii = 1:numel( markings ) + marking = markings(ii); + mask(floor( marking ) + [-3 0 3],1:end-1) = 1; + mask(floor( marking ) + [-2 1 4],1:end-1) = 2; + end + case 'horizontal' + markings(markings < 4) = []; + markings(markings > position(3)-6) = []; + for ii = 1:numel( markings ) + marking = markings(ii); + mask(2:end,floor( marking ) + [-3 0 3]) = 1; + mask(2:end,floor( marking ) + [-2 1 4]) = 2; + end + end + + % Assemble color data + cData1 = repmat( backgroundColor(1), size( mask ) ); + cData1(mask==1) = highlightColor(1); + cData1(mask==2) = shadowColor(1); + cData2 = repmat( backgroundColor(2), size( mask ) ); + cData2(mask==1) = highlightColor(2); + cData2(mask==2) = shadowColor(2); + cData3 = repmat( backgroundColor(3), size( mask ) ); + cData3(mask==1) = highlightColor(3); + cData3(mask==2) = shadowColor(3); + cData = cat( 3, cData1, cData2, cData3 ); + + % Set properties + control.ForegroundColor = backgroundColor; + control.BackgroundColor = backgroundColor; + control.CData = cData; + + end % update + + end % methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Empty.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Empty.m new file mode 100644 index 00000000..b9402c38 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Empty.m @@ -0,0 +1,101 @@ +function obj = Empty( varargin ) +%uix.Empty Create an empty space +% +% obj = uix.Empty() creates an empty space that can be used to add gaps +% between elements in layouts. +% +% obj = uix.Empty(param,value,...) also sets one or more property +% values. +% +% See the documentation for more detail and the list of properties. +% +% Examples: +% >> f = figure(); +% >> box = uix.HBox( 'Parent', f ); +% >> uicontrol( 'Parent', box, 'Background', 'r' ) +% >> uix.Empty( 'Parent', box ) +% >> uicontrol( 'Parent', box, 'Background', 'b' ) + +% Copyright 2009-2020 The MathWorks, Inc. + +% Create uicontainer +obj = matlab.ui.container.internal.UIContainer( 'Tag', 'empty', varargin{:} ); + +% Create property for Parent listener +p = addprop( obj, 'ParentListener' ); +p.Hidden = true; + +% Create Parent listener +obj.ParentListener = event.proplistener( obj, ... + findprop( obj, 'Parent' ), 'PostSet', @(~,~)onParentChanged(obj) ); + +% Create property for Parent color listener +p = addprop( obj, 'ParentColorListener' ); +p.Hidden = true; + +% Initialize color and listener +updateColor( obj ) +updateListener( obj ) + +end % uix.Empty + +function onParentChanged( obj ) +%onParentColorChanged Event handler + +% Update color and listener +updateColor( obj ) +updateListener( obj ) + +end % onParentChanged + +function onParentColorChanged( obj ) +%onParentColorChanged Event handler + +% Update color +updateColor( obj ) + +end % onParentColorChanged + +function name = getColorProperty( obj ) +%getColorProperty Get color property + +names = {'Color','BackgroundColor'}; % possible names +for ii = 1:numel( names ) % loop over possible names + name = names{ii}; + if isprop( obj, name ) + return + end +end +error( 'Cannot find color property for %s.', class( obj ) ) + +end % getColorProperty + +function updateColor( obj ) +%updateColor Set uicontainer BackgroundColor to match Parent + +parent = obj.Parent; +if isempty( parent ), return, end +property = getColorProperty( parent ); +color = parent.( property ); +try + obj.BackgroundColor = color; +catch e + warning( e.identifier, e.message ) % rethrow as warning +end + +end % updateColor + +function updateListener( obj ) +%updateListener Create listener to parent color property + +parent = obj.Parent; +if isempty( parent ) + obj.ParentColorListener = []; +else + property = getColorProperty( parent ); + obj.ParentColorListener = event.proplistener( parent, ... + findprop( parent, property ), 'PostSet', ... + @(~,~)onParentColorChanged(obj) ); +end + +end % updateListener \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/FigureData.m b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureData.m new file mode 100644 index 00000000..9ed0a9aa --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureData.m @@ -0,0 +1,25 @@ +classdef ( Hidden, Sealed ) FigureData < event.EventData + %uix.FigureData Event data for FigureChanged on uix.FigureObserver + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( SetAccess = private ) + OldFigure % old figure + NewFigure % new figure + end + + methods( Access = ?uix.FigureObserver ) + + function obj = FigureData( oldFigure, newFigure ) + %uix.FigureData Create event data + % + % d = uix.FigureData(oldFigure,newFigure) + + obj.OldFigure = oldFigure; + obj.NewFigure = newFigure; + + end % constructor + + end % methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/FigureObserver.m b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureObserver.m new file mode 100644 index 00000000..1df743d2 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/FigureObserver.m @@ -0,0 +1,97 @@ +classdef ( Hidden, Sealed ) FigureObserver < handle + %uix.FigureObserver Figure observer + % + % A figure observer raises an event FigureChanged when the figure + % ancestor of a subject changes. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( SetAccess = private ) + Subject % subject + Figure % figure ancestor + end + + properties( Access = private ) + PreSetListeners % listeners to Parent PreGet + PostSetListeners % listeners to Parent PreGet + OldFigure = gobjects( 0 ) % previous figure ancestor + end + + events( NotifyAccess = private ) + FigureChanged + end + + methods + + function obj = FigureObserver( subject ) + %uix.FigureObserver Create figure observer + % + % o = uix.FigureObserver(s) creates a figure observer for the + % subject s. + + % Check + validateattributes( subject, {'matlab.graphics.Graphics'}, ... + {'scalar'}, '', 'subject' ) + + % Store subject + obj.Subject = subject; + + % Set up object + obj.update() + + end % constructor + + end % structors + + methods( Access = private ) + + function update( obj ) + %update Update listeners and Figure property + + % Create fresh listeners + obj.PreSetListeners = event.proplistener.empty( [1 0] ); % clear + obj.PostSetListeners = event.proplistener.empty( [1 0] ); % clear + o = obj.Subject; + while ~isempty( o ) && ~isa( o, 'matlab.ui.Figure' ) + obj.PreSetListeners(end+1) = event.proplistener( o, ... + findprop( o, 'Parent' ), 'PreSet', @obj.onParentPreSet ); + obj.PostSetListeners(end+1) = event.proplistener( o, ... + findprop( o, 'Parent' ), 'PostSet', @obj.onParentPostSet ); + o = o.Parent; + end + + % Store figure + obj.Figure = o; + + end % update + + function onParentPreSet( obj, ~, ~ ) + %onParentPreSet Event handler + + % Store old figure + obj.OldFigure = obj.Figure; + + end % onParentPreSet + + function onParentPostSet( obj, ~, ~ ) + %onParentPostSet Event handler + + % Update object + obj.update() + + % Raise event + oldFigure = obj.OldFigure; + newFigure = obj.Figure; + if ~isequal( oldFigure, newFigure ) + notify( obj, 'FigureChanged', ... + uix.FigureData( oldFigure, newFigure ) ) + end + + % Clear old figure + obj.OldFigure = gobjects( 0 ); + + end % onParentPostSet + + end % private methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Grid.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Grid.m new file mode 100644 index 00000000..db76b881 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Grid.m @@ -0,0 +1,316 @@ +classdef Grid < uix.Box + %uix.Grid Grid + % + % b = uix.Grid(p1,v1,p2,v2,...) constructs a grid and sets parameter + % p1 to value v1, etc. + % + % A grid lays out contents from top to bottom and left to right. + % + % See also: uix.HBox, uix.VBox, uix.GridFlex + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + Widths % widths of contents, in pixels and/or weights + MinimumWidths % minimum widths of contents, in pixels + Heights % heights of contents, in pixels and/or weights + MinimumHeights % minimum heights of contents, in pixels + end + + properties( Access = protected ) + Widths_ = zeros( [0 1] ) % backing for Widths + MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths + Heights_ = zeros( [0 1] ) % backing for Heights + MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights + end + + methods + + function obj = Grid( varargin ) + %uix.Grid Grid constructor + % + % b = uix.Grid() constructs a grid. + % + % b = uix.Grid(p1,v1,p2,v2,...) sets parameter p1 to value v1, + % etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.Widths( obj ) + + value = obj.Widths_; + + end % get.Widths + + function set.Widths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Widths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Widths'' must be real and finite.' ) + n = numel( obj.Contents_ ); + b = numel( obj.Widths_ ); + q = numel( obj.Heights_ ); + c = numel( value ); + r = ceil( n / c ); + if c < min( [1 n] ) + error( 'uix:InvalidPropertyValue' , ... + 'Property ''Widths'' must be non-empty for non-empty contents.' ) + elseif ceil( n / r ) < c + error( 'uix:InvalidPropertyValue' , ... + 'Size of property ''Widths'' must not lead to empty columns.' ) + elseif c > n + error( 'uix:InvalidPropertyValue' , ... + 'Size of property ''Widths'' must be no larger than size of contents.' ) + end + + % Set + obj.Widths_ = value; + if c < b % number of columns decreasing + obj.MinimumWidths_(c+1:end,:) = []; + if r > q % number of rows increasing + obj.Heights_(end+1:r,:) = -1; + obj.MinimumHeights_(end+1:r,:) = 1; + end + elseif c > b % number of columns increasing + obj.MinimumWidths_(end+1:c,:) = -1; + if r < q % number of rows decreasing + obj.Heights_(r+1:end,:) = []; + obj.MinimumHeights_(r+1:end,:) = []; + end + end + + % Mark as dirty + obj.Dirty = true; + + end % set.Widths + + function value = get.MinimumWidths( obj ) + + value = obj.MinimumWidths_; + + end % get.MinimumWidths + + function set.MinimumWidths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumWidths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumWidths'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Widths_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumWidths'' must match size of contents.' ) + + % Set + obj.MinimumWidths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumWidths + + function value = get.Heights( obj ) + + value = obj.Heights_; + + end % get.Heights + + function set.Heights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Heights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Heights'' must be real and finite.' ) + n = numel( obj.Contents_ ); + b = numel( obj.Widths_ ); + q = numel( obj.Heights_ ); + r = numel( value ); + c = ceil( n / r ); + if r < min( [1 n] ) + error( 'uix:InvalidPropertyValue' , ... + 'Property ''Heights'' must be non-empty for non-empty contents.' ) + elseif r > n + error( 'uix:InvalidPropertyValue' , ... + 'Size of property ''Heights'' must be no larger than size of contents.' ) + end + + % Set + obj.Heights_ = value; + if r < q % number of rows decreasing + obj.MinimumHeights_(r+1:end,:) = []; + if c > b % number of columns increasing + obj.Widths_(end+1:c,:) = -1; + obj.MinimumWidths_(end+1:c,:) = 1; + end + elseif r > q % number of rows increasing + obj.MinimumHeights_(end+1:r,:) = 1; + if c < b % number of columns decreasing + obj.Widths_(c+1:end,:) = []; + obj.MinimumWidths_(c+1:end,:) = []; + end + end + + % Mark as dirty + obj.Dirty = true; + + end % set.Heights + + function value = get.MinimumHeights( obj ) + + value = obj.MinimumHeights_; + + end % get.MinimumHeights + + function set.MinimumHeights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumHeights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumHeights'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Heights_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumHeights'' must match size of contents.' ) + + % Set + obj.MinimumHeights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumHeights + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % c.redraw() redraws the container c. + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + c = numel( widths ); + r = numel( heights ); + n = numel( obj.Contents_ ); + xSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xPositions = [cumsum( [0; xSizes(1:end-1,:)] ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, xSizes]; + ySizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yPositions = [bounds(4) - cumsum( ySizes ) - padding - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + [iy, ix] = ind2sub( [r c], transpose( 1:n ) ); + positions = [xPositions(ix,1), yPositions(iy,1), ... + xPositions(ix,2), yPositions(iy,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add column and even a row if necessary + n = numel( obj.Contents_ ); + c = numel( obj.Widths_ ); + r = numel( obj.Heights_ ); + if n == 0 + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + obj.Heights_(end+1,:) = -1; + obj.MinimumHeights_(end+1,:) = 1; + elseif ceil( (n+1)/r ) > c + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + end + + % Call superclass method + addChild@uix.Box( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove column and even row if necessary + n = numel( obj.Contents_ ); + c = numel( obj.Widths_ ); + r = numel( obj.Heights_ ); + if n == 1 + obj.Widths_(end,:) = []; + obj.MinimumWidths_(end,:) = []; + obj.Heights_(end,:) = []; + obj.MinimumHeights_(end,:) = []; + elseif c == 1 + obj.Heights_(end,:) = []; + obj.MinimumHeights_(end,:) = []; + elseif ceil( (n-1)/r ) < c + obj.Widths_(end,:) = []; + obj.MinimumWidths_(end,:) = []; + end + + % Call superclass method + removeChild@uix.Box( obj, child ) + + end % removeChild + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/GridFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/GridFlex.m new file mode 100644 index 00000000..d93038bf --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/GridFlex.m @@ -0,0 +1,473 @@ +classdef GridFlex < uix.Grid & uix.mixin.Flex + %uix.GridFlex Flexible grid + % + % b = uix.GridFlex(p1,v1,p2,v2,...) constructs a flexible grid and + % sets parameter p1 to value v1, etc. + % + % A grid lays out contents from top to bottom and left to right. + % Users can resize contents by dragging the dividers. + % + % See also: uix.HBoxFlex, uix.VBoxFlex, uix.Grid + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + DividerMarkings % divider markings [on|off] + end + + properties( Access = private ) + RowDividers = uix.Divider.empty( [0 1] ) + ColumnDividers = uix.Divider.empty( [0 1] ) + FrontDivider % front divider + DividerMarkings_ = 'on' % backing for DividerMarkings + MousePressListener = event.listener.empty( [0 0] ) % mouse press listener + MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener + MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener + ActiveDivider = 0 % active divider index + ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position + MousePressLocation = [NaN NaN] % mouse press location + BackgroundColorListener % background color listener + end + + methods + + function obj = GridFlex( varargin ) + %uix.GridFlex Flexible grid constructor + % + % b = uix.GridFlex() constructs a flexible grid. + % + % b = uix.GridFlex(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create front divider + frontDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor * 0.75, ... + 'Visible', 'off' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChanged ); + + % Store properties + obj.FrontDivider = frontDivider; + obj.BackgroundColorListener = backgroundColorListener; + + % Set Spacing property (may be overwritten by uix.set) + obj.Spacing = 5; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.DividerMarkings( obj ) + + value = obj.DividerMarkings_; + + end % get.DividerMarkings + + function set.DividerMarkings( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''DividerMarkings'' must be ''on'' or ''off'.' ) + + % Set + obj.DividerMarkings_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.DividerMarkings + + end % accessors + + methods( Access = protected ) + + function onMousePress( obj, source, eventData ) + %onMousePress Handler for WindowMousePress events + + % Check whether mouse is over a divider + locr = find( obj.RowDividers.isMouseOver( eventData ) ); + locc = find( obj.ColumnDividers.isMouseOver( eventData ) ); + if ~isempty( locr ) + loc = locr; + divider = obj.RowDividers(locr); + elseif ~isempty( locc ) + loc = -locc; + divider = obj.ColumnDividers(locc); + else + return + end + + % Capture state at button down + obj.ActiveDivider = loc; + obj.ActiveDividerPosition = divider.Position; + root = groot(); + obj.MousePressLocation = root.PointerLocation; + + % Make sure the pointer is appropriate + obj.updateMousePointer( source, eventData ); + + % Activate divider + frontDivider = obj.FrontDivider; + frontDivider.Position = divider.Position; + frontDivider.Orientation = divider.Orientation; + divider.Visible = 'off'; + frontDivider.Parent = []; + frontDivider.Parent = obj; + frontDivider.Visible = 'on'; + + end % onMousePress + + function onMouseRelease( obj, ~, ~ ) + %onMousePress Handler for WindowMouseRelease events + + % Compute new positions + loc = obj.ActiveDivider; + if loc > 0 + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + divider = obj.RowDividers(loc); + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelHeights = [ip(4); jp(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + oldHeights = obj.Heights_(loc:loc+1); + newPixelHeights = oldPixelHeights - delta * [1;-1]; + if oldHeights(1) < 0 && oldHeights(2) < 0 % weight, weight + newHeights = oldHeights .* newPixelHeights ./ oldPixelHeights; + elseif oldHeights(1) < 0 && oldHeights(2) >= 0 % weight, pixels + newHeights = [oldHeights(1) * newPixelHeights(1) / ... + oldPixelHeights(1); newPixelHeights(2)]; + elseif oldHeights(1) >= 0 && oldHeights(2) < 0 % pixels, weight + newHeights = [newPixelHeights(1); oldHeights(2) * ... + newPixelHeights(2) / oldPixelHeights(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newHeights = newPixelHeights; + end + obj.Heights_(loc:loc+1) = newHeights; + elseif loc < 0 + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = -loc; + jw = -loc + 1; + r = numel( obj.Heights_ ); + ic = r * (-loc-1) + 1; + jc = r * -loc + 1; + divider = obj.ColumnDividers(iw); + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelWidths = [ip(3); jp(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + oldWidths = obj.Widths_(iw:jw); + newPixelWidths = oldPixelWidths + delta * [1;-1]; + if oldWidths(1) < 0 && oldWidths(2) < 0 % weight, weight + newWidths = oldWidths .* newPixelWidths ./ oldPixelWidths; + elseif oldWidths(1) < 0 && oldWidths(2) >= 0 % weight, pixels + newWidths = [oldWidths(1) * newPixelWidths(1) / ... + oldPixelWidths(1); newPixelWidths(2)]; + elseif oldWidths(1) >= 0 && oldWidths(2) < 0 % pixels, weight + newWidths = [newPixelWidths(1); oldWidths(2) * ... + newPixelWidths(2) / oldPixelWidths(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newWidths = newPixelWidths; + end + obj.Widths_(iw:jw) = newWidths; + else + return + end + + % Deactivate divider + obj.FrontDivider.Visible = 'off'; + divider.Visible = 'on'; + + % Reset state at button down + obj.ActiveDivider = 0; + obj.ActiveDividerPosition = [NaN NaN NaN NaN]; + obj.MousePressLocation = [NaN NaN]; + + % Mark as dirty + obj.Dirty = true; + + end % onMouseRelease + + function onMouseMotion( obj, source, eventData ) + %onMouseMotion Handler for WindowMouseMotion events + + loc = obj.ActiveDivider; + if loc == 0 % hovering, update pointer + obj.updateMousePointer( source, eventData ); + elseif loc > 0 % dragging row divider + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelHeights = [ip(4); jp(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [0 delta 0 0]; + else % loc < 0, dragging column divider + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = -loc; + jw = -loc + 1; + r = numel( obj.Heights_ ); + ic = r * (-loc-1) + 1; + jc = r * -loc + 1; + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelWidths = [ip(3); jp(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [delta 0 0 0]; + end + + end % onMouseMotion + + function onBackgroundColorChanged( obj, ~, ~ ) + %onBackgroundColorChanged Handler for BackgroundColor changes + + backgroundColor = obj.BackgroundColor; + highlightColor = min( [backgroundColor / 0.75; 1 1 1] ); + shadowColor = max( [backgroundColor * 0.75; 0 0 0] ); + rowDividers = obj.RowDividers; + for ii = 1:numel( rowDividers ) + rowDivider = rowDividers(ii); + rowDivider.BackgroundColor = backgroundColor; + rowDivider.HighlightColor = highlightColor; + rowDivider.ShadowColor = shadowColor; + end + columnDividers = obj.ColumnDividers; + for jj = 1:numel( columnDividers ) + columnDivider = columnDividers(jj); + columnDivider.BackgroundColor = backgroundColor; + columnDivider.HighlightColor = highlightColor; + columnDivider.ShadowColor = shadowColor; + end + frontDivider = obj.FrontDivider; + frontDivider.BackgroundColor = shadowColor; + + end % onBackgroundColorChanged + + end % event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw contents + % + % c.redraw() redraws the container c. + + % Call superclass method + redraw@uix.Grid( obj ) + + % Create or destroy column dividers + b = numel( obj.ColumnDividers ); % current number of dividers + c = max( [numel( obj.Widths_ )-1 0] ); % required number of dividers + if b < c % create + for ii = b+1:c + columnDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.ColumnDividers(ii,:) = columnDivider; + end + elseif b > c % destroy + % Destroy dividers + delete( obj.ColumnDividers(c+1:b,:) ) + obj.ColumnDividers(c+1:b,:) = []; + % Update pointer + if c == 0 && strcmp( obj.Pointer, 'left' ) + obj.unsetPointer() + end + end + + % Create or destroy row dividers + q = numel( obj.RowDividers ); % current number of dividers + r = max( [numel( obj.Heights_ )-1 0] ); % required number of dividers + if q < r % create + for ii = q+1:r + columnDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'horizontal', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.RowDividers(ii,:) = columnDivider; + end + % Bring front divider to the front + frontDivider = obj.FrontDivider; + frontDivider.Parent = []; + frontDivider.Parent = obj; + elseif q > r % destroy + % Destroy dividers + delete( obj.RowDividers(r+1:q,:) ) + obj.RowDividers(r+1:q,:) = []; + % Update pointer + if r == 0 && strcmp( obj.Pointer, 'top' ) + obj.unsetPointer() + end + end + + % Compute container bounds + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + + % Retrieve size properties + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + + % Compute row divider positions + xRowPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )]; + xRowPositions = repmat( xRowPositions, [r 1] ); + yRowSizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yRowPositions = [bounds(4) - cumsum( yRowSizes(1:r,:) ) - padding - ... + spacing * transpose( 1:r ) + 1, repmat( spacing, [r 1] )]; + rowPositions = [xRowPositions(:,1), yRowPositions(:,1), ... + xRowPositions(:,2), yRowPositions(:,2)]; + + % Compute column divider positions + xColumnSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xColumnPositions = [cumsum( xColumnSizes(1:c,:) ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, repmat( spacing, [c 1] )]; + yColumnPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )]; + yColumnPositions = repmat( yColumnPositions, [c 1] ); + columnPositions = [xColumnPositions(:,1), yColumnPositions(:,1), ... + xColumnPositions(:,2), yColumnPositions(:,2)]; + + % Position row dividers + for ii = 1:r + rowDivider = obj.RowDividers(ii); + rowDivider.Position = rowPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + rowDivider.Markings = cumsum( xColumnSizes ) + ... + spacing * transpose( 0:c ) - xColumnSizes / 2; + case 'off' + rowDivider.Markings = zeros( [0 1] ); + end + end + + % Position column dividers + for ii = 1:c + columnDivider = obj.ColumnDividers(ii); + columnDivider.Position = columnPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + columnDivider.Markings = cumsum( yRowSizes ) + ... + spacing * transpose( 0:r ) - yRowSizes / 2; + case 'off' + columnDivider.Markings = zeros( [0 1] ); + end + end + + end % redraw + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + % Update listeners + if isempty( newFigure ) + mousePressListener = event.listener.empty( [0 0] ); + mouseReleaseListener = event.listener.empty( [0 0] ); + mouseMotionListener = event.listener.empty( [0 0] ); + else + mousePressListener = event.listener( newFigure, ... + 'WindowMousePress', @obj.onMousePress ); + mouseReleaseListener = event.listener( newFigure, ... + 'WindowMouseRelease', @obj.onMouseRelease ); + mouseMotionListener = event.listener( newFigure, ... + 'WindowMouseMotion', @obj.onMouseMotion ); + end + obj.MousePressListener = mousePressListener; + obj.MouseReleaseListener = mouseReleaseListener; + obj.MouseMotionListener = mouseMotionListener; + + % Call superclass method + reparent@uix.Grid( obj, oldFigure, newFigure ) + + % Update pointer + if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % reparent + + end % template methods + + methods( Access = protected ) + + function updateMousePointer ( obj, source, eventData ) + + oldPointer = obj.Pointer; + if any( obj.RowDividers.isMouseOver( eventData ) ) + newPointer = 'top'; + elseif any( obj.ColumnDividers.isMouseOver( eventData ) ) + newPointer = 'left'; + else + newPointer = 'unset'; + end + switch newPointer + case oldPointer % no change + % do nothing + case 'unset' % change, unset + obj.unsetPointer() + otherwise % change, set + obj.setPointer( source, newPointer ) + end + + end % updateMousePointer + + end % helpers methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/HBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/HBox.m new file mode 100644 index 00000000..11ffd9c7 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/HBox.m @@ -0,0 +1,189 @@ +classdef HBox < uix.Box + %uix.HBox Horizontal box + % + % b = uix.HBox(p1,v1,p2,v2,...) constructs a horizontal box and sets + % parameter p1 to value v1, etc. + % + % A horizontal box lays out contents from left to right. + % + % See also: uix.VBox, uix.Grid, uix.HButtonBox, uix.HBoxFlex + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + Widths % widths of contents, in pixels and/or weights + MinimumWidths % minimum widths of contents, in pixels + end + + properties( Access = protected ) + Widths_ = zeros( [0 1] ) % backing for Widths + MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths + end + + methods + + function obj = HBox( varargin ) + %uix.HBox Horizontal box constructor + % + % b = uix.HBox() constructs a horizontal box. + % + % b = uix.HBox(p1,v1,p2,v2,...) sets parameter p1 to value v1, + % etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.Widths( obj ) + + value = obj.Widths_; + + end % get.Widths + + function set.Widths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Widths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Widths'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Widths'' must match size of contents.' ) + + % Set + obj.Widths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Widths + + function value = get.MinimumWidths( obj ) + + value = obj.MinimumWidths_; + + end % get.MinimumWidths + + function set.MinimumWidths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumWidths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumWidths'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Widths_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumWidths'' must match size of contents.' ) + + % Set + obj.MinimumWidths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumWidths + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % c.redraw() redraws the container c. + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + padding = obj.Padding_; + spacing = obj.Spacing_; + c = numel( widths ); + xSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, xSizes]; + yPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )]; + yPositions = repmat( yPositions, [c 1] ); + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to sizes + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + + % Call superclass method + addChild@uix.Box( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from sizes + tf = obj.Contents_ == child; + obj.Widths_(tf,:) = []; + obj.MinimumWidths_(tf,:) = []; + + % Call superclass method + removeChild@uix.Box( obj, child ) + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Widths_ = obj.Widths_(indices,:); + obj.MinimumWidths_ = obj.MinimumWidths_(indices,:); + + % Call superclass method + reorder@uix.Box( obj, indices ) + + end % reorder + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/HBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/HBoxFlex.m new file mode 100644 index 00000000..43a7cdee --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/HBoxFlex.m @@ -0,0 +1,351 @@ +classdef HBoxFlex < uix.HBox & uix.mixin.Flex + %uix.HBoxFlex Flexible horizontal box + % + % b = uix.HBoxFlex(p1,v1,p2,v2,...) constructs a flexible horizontal + % box and sets parameter p1 to value v1, etc. + % + % A horizontal box lays out contents from left to right. Users can + % resize contents by dragging the dividers. + % + % See also: uix.VBoxFlex, uix.GridFlex, uix.HBox, uix.HButtonBox + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + DividerMarkings % divider markings [on|off] + end + + properties( Access = private ) + ColumnDividers = uix.Divider.empty( [0 1] ) % column dividers + FrontDivider % front divider + DividerMarkings_ = 'on' % backing for DividerMarkings + MousePressListener = event.listener.empty( [0 0] ) % mouse press listener + MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener + MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener + ActiveDivider = 0 % active divider index + ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position + MousePressLocation = [NaN NaN] % mouse press location + BackgroundColorListener % background color listener + end + + methods + + function obj = HBoxFlex( varargin ) + %uix.HBoxFlex Flexible horizontal box constructor + % + % b = uix.HBoxFlex() constructs a flexible horizontal box. + % + % b = uix.HBoxFlex(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create front divider + frontDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor * 0.75, ... + 'Visible', 'off' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChanged ); + + % Store properties + obj.FrontDivider = frontDivider; + obj.BackgroundColorListener = backgroundColorListener; + + % Set Spacing property (may be overwritten by uix.set) + obj.Spacing = 5; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.DividerMarkings( obj ) + + value = obj.DividerMarkings_; + + end % get.DividerMarkings + + function set.DividerMarkings( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''DividerMarkings'' must be ''on'' or ''off'.' ) + + % Set + obj.DividerMarkings_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.DividerMarkings + + end % accessors + + methods( Access = protected ) + + function onMousePress( obj, source, eventData ) + %onMousePress Handler for WindowMousePress events + + % Check whether mouse is over a divider + loc = find( obj.ColumnDividers.isMouseOver( eventData ) ); + if isempty( loc ), return, end + + % Capture state at button down + divider = obj.ColumnDividers(loc); + obj.ActiveDivider = loc; + obj.ActiveDividerPosition = divider.Position; + root = groot(); + obj.MousePressLocation = root.PointerLocation; + + % Make sure the pointer is appropriate + obj.updateMousePointer( source, eventData ); + + % Activate divider + frontDivider = obj.FrontDivider; + frontDivider.Position = divider.Position; + divider.Visible = 'off'; + frontDivider.Parent = []; + frontDivider.Parent = obj; + frontDivider.Visible = 'on'; + + end % onMousePress + + function onMouseRelease( obj, ~, ~ ) + %onMousePress Handler for WindowMouseRelease events + + % Compute new positions + loc = obj.ActiveDivider; + if loc > 0 + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = loc; + jw = loc + 1; + ic = loc; + jc = loc + 1; + divider = obj.ColumnDividers(loc); + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelWidths = [ip(3); jp(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + oldWidths = obj.Widths_(iw:jw); + newPixelWidths = oldPixelWidths + delta * [1;-1]; + if oldWidths(1) < 0 && oldWidths(2) < 0 % weight, weight + newWidths = oldWidths .* newPixelWidths ./ oldPixelWidths; + elseif oldWidths(1) < 0 && oldWidths(2) >= 0 % weight, pixels + newWidths = [oldWidths(1) * newPixelWidths(1) / ... + oldPixelWidths(1); newPixelWidths(2)]; + elseif oldWidths(1) >= 0 && oldWidths(2) < 0 % pixels, weight + newWidths = [newPixelWidths(1); oldWidths(2) * ... + newPixelWidths(2) / oldPixelWidths(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newWidths = newPixelWidths; + end + obj.Widths_(iw:jw) = newWidths; + else + return + end + + % Deactivate divider + obj.FrontDivider.Visible = 'off'; + divider.Visible = 'on'; + + % Reset state at button down + obj.ActiveDivider = 0; + obj.ActiveDividerPosition = [NaN NaN NaN NaN]; + obj.MousePressLocation = [NaN NaN]; + + % Mark as dirty + obj.Dirty = true; + + end % onMouseRelease + + function onMouseMotion( obj, source, eventData ) + %onMouseMotion Handler for WindowMouseMotion events + + loc = obj.ActiveDivider; + if loc == 0 % hovering, update pointer + obj.updateMousePointer( source, eventData ); + else % dragging column divider + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = loc; + jw = loc + 1; + ic = loc; + jc = loc + 1; + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelWidths = [ip(3); jp(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [delta 0 0 0]; + end + + end % onMouseMotion + + function onBackgroundColorChanged( obj, ~, ~ ) + %onBackgroundColorChanged Handler for BackgroundColor changes + + backgroundColor = obj.BackgroundColor; + highlightColor = min( [backgroundColor / 0.75; 1 1 1] ); + shadowColor = max( [backgroundColor * 0.75; 0 0 0] ); + columnDividers = obj.ColumnDividers; + for jj = 1:numel( columnDividers ) + columnDivider = columnDividers(jj); + columnDivider.BackgroundColor = backgroundColor; + columnDivider.HighlightColor = highlightColor; + columnDivider.ShadowColor = shadowColor; + end + frontDivider = obj.FrontDivider; + frontDivider.BackgroundColor = shadowColor; + + end % onBackgroundColorChanged + + end % event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw contents + % + % c.redraw() redraws the container c. + + % Call superclass method + redraw@uix.HBox( obj ) + + % Create or destroy column dividers + b = numel( obj.ColumnDividers ); % current number of dividers + c = max( [numel( obj.Widths_ )-1 0] ); % required number of dividers + if b < c % create + for ii = b+1:c + divider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.ColumnDividers(ii,:) = divider; + end + elseif b > c % destroy + % Destroy dividers + delete( obj.ColumnDividers(c+1:b,:) ) + obj.ColumnDividers(c+1:b,:) = []; + % Update pointer + if c == 0 && strcmp( obj.Pointer, 'left' ) + obj.unsetPointer() + end + end + + % Compute container bounds + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + + % Retrieve size properties + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + padding = obj.Padding_; + spacing = obj.Spacing_; + + % Compute column divider positions + xColumnSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xColumnPositions = [cumsum( xColumnSizes(1:c,:) ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, repmat( spacing, [c 1] )]; + yColumnPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )]; + yColumnPositions = repmat( yColumnPositions, [c 1] ); + columnPositions = [xColumnPositions(:,1), yColumnPositions(:,1), ... + xColumnPositions(:,2), yColumnPositions(:,2)]; + + % Position column dividers + for ii = 1:c + columnDivider = obj.ColumnDividers(ii); + columnDivider.Position = columnPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + columnDivider.Markings = columnPositions(ii,4)/2; + case 'off' + columnDivider.Markings = zeros( [0 1] ); + end + end + + end % redraw + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + % Update listeners + if isempty( newFigure ) + mousePressListener = event.listener.empty( [0 0] ); + mouseReleaseListener = event.listener.empty( [0 0] ); + mouseMotionListener = event.listener.empty( [0 0] ); + else + mousePressListener = event.listener( newFigure, ... + 'WindowMousePress', @obj.onMousePress ); + mouseReleaseListener = event.listener( newFigure, ... + 'WindowMouseRelease', @obj.onMouseRelease ); + mouseMotionListener = event.listener( newFigure, ... + 'WindowMouseMotion', @obj.onMouseMotion ); + end + obj.MousePressListener = mousePressListener; + obj.MouseReleaseListener = mouseReleaseListener; + obj.MouseMotionListener = mouseMotionListener; + + % Call superclass method + reparent@uix.HBox( obj, oldFigure, newFigure ) + + % Update pointer + if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % reparent + + end % template methods + + methods( Access = protected ) + + function updateMousePointer ( obj, source, eventData ) + + oldPointer = obj.Pointer; + if any( obj.ColumnDividers.isMouseOver( eventData ) ) + newPointer = 'left'; + else + newPointer = 'unset'; + end + switch newPointer + case oldPointer % no change + % do nothing + case 'unset' % change, unset + obj.unsetPointer() + otherwise % change, set + obj.setPointer( source, newPointer ) + end + + end % updateMousePointer + + end % helpers methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/HButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/HButtonBox.m new file mode 100644 index 00000000..0f71f733 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/HButtonBox.m @@ -0,0 +1,95 @@ +classdef HButtonBox < uix.ButtonBox + %uix.HButtonBox Horizontal button box + % + % b = uix.HButtonBox(p1,v1,p2,v2,...) constructs a horizontal button + % box and sets parameter p1 to value v1, etc. + % + % A horizontal button box lays out equally sized buttons from left to + % right. + % + % See also: uix.VButtonBox + + % Copyright 2009-2020 The MathWorks, Inc. + + methods + + function obj = HButtonBox( varargin ) + %uix.HButtonBox Horizontal button box constructor + % + % b = uix.HButtonBox() constructs a horizontal button box. + % + % b = uix.HButtonBox(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + buttonSize = obj.ButtonSize_; + padding = obj.Padding_; + spacing = obj.Spacing_; + c = numel( obj.Contents_ ); + if 2 * padding + (c-1) * spacing + c * buttonSize(1) > bounds(3) + xSizes = uix.calcPixelSizes( bounds(3), -ones( [c 1] ), ... + ones( [c 1] ), padding, spacing ); % shrink to fit + else + xSizes = repmat( buttonSize(1), [c 1] ); + end + switch obj.HorizontalAlignment + case 'left' + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ... + padding + spacing * transpose( 0:c-1 ) + 1, xSizes]; + case 'center' + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ... + spacing * transpose( 0:c-1 ) + bounds(3) / 2 - ... + sum( xSizes ) / 2 - spacing * (c-1) / 2 + 1, ... + xSizes]; + case 'right' + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ... + spacing * transpose( 0:c-1 ) + bounds(3) - ... + sum( xSizes ) - spacing * (c-1) - padding + 1, ... + xSizes]; + end + if 2 * padding + buttonSize(2) > bounds(4) + ySizes = repmat( uix.calcPixelSizes( bounds(4), -1, 1, ... + padding, spacing ), [c 1] ); % shrink to fit + else + ySizes = repmat( buttonSize(2), [c 1] ); + end + switch obj.VerticalAlignment + case 'top' + yPositions = [bounds(4) - ySizes - padding + 1, ySizes]; + case 'middle' + yPositions = [(bounds(4) - ySizes) / 2 + 1, ySizes]; + case 'bottom' + yPositions = [repmat( padding, [c 1] ) + 1, ySizes]; + end + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Node.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Node.m new file mode 100644 index 00000000..e5e180fa --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Node.m @@ -0,0 +1,93 @@ +classdef ( Hidden ) Node < dynamicprops + %uix.Node Node + % + % n = uix.Node(o) creates a node for the handle o. + % + % Node is a helper class for managing trees of objects and associated + % listeners. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( SetAccess = private ) + Object % object + Children = uix.Node.empty( [0 1] ) % children + end + + properties( Access = private ) + ChildListeners = event.listener.empty( [0 1] ) % internal listeners + end + + methods + + function obj = Node( object ) + %uix.Node Node + % + % n = uix.Node(o) creates a node for the handle o. + + % Check + assert( isa( object, 'handle' ) && ... + isequal( size( object ), [1 1] ) && isvalid( object ), ... + 'uix:InvalidArgument', 'Object must be a handle.' ) + + % Set properties + obj.Object = object; + + end % constructor + + end % structors + + methods + + function addChild( obj, child ) + %addChild Add child + % + % n.addChild(c) adds the child node c to the parent node n. + + % Check + assert( isa( child, 'uix.Node' ) && ... + isequal( size( child ), [1 1] ), ... + 'uix:InvalidArgument', 'Invalid node.' ) + + % Add + childListener = event.listener( child, ... + 'ObjectBeingDestroyed', @obj.onChildDeleted ); + obj.Children(end+1,:) = child; + obj.ChildListeners(end+1,:) = childListener; + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % n.removeChild(c) removes the child node c from the parent + % node n. + + % Check + assert( isa( child, 'uix.Node' ) && ... + isequal( size( child ), [1 1] ), ... + 'uix:InvalidArgument', 'Invalid node.' ) + assert( ismember( child, obj.Children ), ... + 'uix:ItemNotFound', 'Node not found.' ) + + % Remove + tf = child == obj.Children; + obj.Children(tf,:) = []; + obj.ChildListeners(tf,:) = []; + + end % removeChild + + end % public methods + + methods( Access = private ) + + function onChildDeleted( obj, source, ~ ) + %onChildDeleted Event handler for deletion of child nodes + + % Remove + obj.removeChild( source ) + + end % onChildDeleted + + end % event handlers + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Panel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Panel.m new file mode 100644 index 00000000..0a416b8e --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Panel.m @@ -0,0 +1,58 @@ +classdef Panel < matlab.ui.container.Panel & uix.mixin.Panel + %uix.Panel Standard panel + % + % b = uix.Panel(p1,v1,p2,v2,...) constructs a standard panel and sets + % parameter p1 to value v1, etc. + % + % A card panel is a standard panel (uipanel) that shows one its + % contents and hides the others. + % + % See also: uix.CardPanel, uix.BoxPanel, uipanel + + % Copyright 2009-2020 The MathWorks, Inc. + + methods + + function obj = Panel( varargin ) + %uix.Panel Standard panel constructor + % + % p = uix.Panel() constructs a standard panel. + % + % p = uix.Panel(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + padding = obj.Padding_; + xSizes = uix.calcPixelSizes( bounds(3), -1, 1, padding, 0 ); + ySizes = uix.calcPixelSizes( bounds(4), -1, 1, padding, 0 ); + position = [padding+1 padding+1 xSizes ySizes]; + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 + uix.setPosition( obj.Contents_(selection), position, 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/PointerManager.m b/studio_functions/GUI Layout Toolbox/layout/+uix/PointerManager.m new file mode 100644 index 00000000..b4b5d6c0 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/PointerManager.m @@ -0,0 +1,152 @@ +classdef ( Hidden, Sealed ) PointerManager < handle + %uix.PointerManager Pointer manager + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( SetAccess = private ) + Figure % figure + end + + properties( Access = private ) + Tokens % tokens + Pointers % pointers + NextToken % next token + PointerListener % listener + end + + methods( Access = private ) + + function obj = PointerManager( figure ) + %uix.PointerManager Create pointer manager + % + % m = uix.PointerManager(f) creates a pointer manager for the + % figure f. + + obj.Figure = figure; + obj.Tokens = 0; + obj.Pointers = {figure.Pointer}; + obj.NextToken = 1; + obj.PointerListener = event.proplistener( figure, ... + findprop( figure, 'Pointer' ), 'PostSet', ... + @obj.onPointerChanged ); + + end % constructor + + end % structors + + methods( Access = private ) + + function doSetPointer( obj, token, pointer ) + %doSetPointer Set pointer + % + % m.doSetPointer(t,p) sets the pointer to p with the token t. + + % Remove old entry + tf = obj.Tokens == token; + obj.Tokens(tf) = []; + obj.Pointers(tf) = []; + + % Add new entry + obj.Tokens(end+1) = token; + obj.Pointers{end+1} = pointer; + + % Set pointer + obj.PointerListener.Enabled = false; + obj.Figure.Pointer = pointer; + obj.PointerListener.Enabled = true; + + end % doSetPointer + + function doUnsetPointer( obj, token ) + %doUnsetPointer Unset pointer + % + % m.doUnsetPointer(s) unsets the pointer with the token t. + + % Remove old entry + tf = obj.Tokens == token; + obj.Tokens(tf) = []; + obj.Pointers(tf) = []; + + % Update pointer + obj.PointerListener.Enabled = false; + obj.Figure.Pointer = obj.Pointers{end}; + obj.PointerListener.Enabled = true; + + end % doUnsetPointer + + end % private methods + + methods + + function onPointerChanged( obj, ~, ~ ) + %onPointerChanged Event handler + + % Log as unknown setter + obj.doSetPointer( 0, obj.Figure.Pointer ) + + end % onPointerChanged + + end % event handlers + + methods( Static ) + + function token = setPointer( figure, pointer ) + %setPointer Set pointer + % + % t = uix.PointerManager.setPointer(f,p) sets the pointer of + % the figure f to p. The returned token t can be used + % subsequently to unset the pointer. + + % Get pointer manager + obj = uix.PointerManager.getInstance( figure ); + + % Retrieve token + token = obj.NextToken; + + % Set + obj.doSetPointer( token, pointer ) + + % Increment token + obj.NextToken = token + 1; + + end % setPointer + + function unsetPointer( figure, token ) + %unsetPointer Unset pointer + % + % uix.PointerManager.unsetPointer(f,t) unsets the pointer of + % the figure f using the token t. + + % Check ID + validateattributes( token, {'numeric'}, {'scalar','integer','>',0} ) + + % Get pointer manager + obj = uix.PointerManager.getInstance( figure ); + + % Unset + obj.doUnsetPointer( token ) + + end % unsetPointer + + function obj = getInstance( figure ) + %getInstance Get pointer manager + % + % m = uix.PointerManager.getInstance(f) gets the pointer + % manager for the figure f. + + % Get pointer manager + name = 'UIxPointerManager'; + if isprop( figure, name ) % existing, retrieve + obj = figure.( name ); + else % new, create and store + obj = uix.PointerManager( figure ); + p = addprop( figure, name ); + p.Hidden = true; + figure.( name ) = obj; + end + + end % getInstance + + end % static methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_NotSelected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_NotSelected.png new file mode 100644 index 00000000..30d4bb42 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_NotSelected.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_Selected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_Selected.png new file mode 100644 index 00000000..c0c8b56d Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NoEdge_Selected.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NoEdge.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NoEdge.png new file mode 100644 index 00000000..30bf1da2 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NoEdge.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NotSelected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NotSelected.png new file mode 100644 index 00000000..c6aca7c4 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_NotSelected.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_Selected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_Selected.png new file mode 100644 index 00000000..e96782b3 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_NotSelected_Selected.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NoEdge.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NoEdge.png new file mode 100644 index 00000000..f23a1b09 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NoEdge.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NotSelected.png b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NotSelected.png new file mode 100644 index 00000000..4758ca3f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layout/+uix/Resources/tab_Selected_NotSelected.png differ diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/ScrollingPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/ScrollingPanel.m new file mode 100644 index 00000000..b2834cca --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/ScrollingPanel.m @@ -0,0 +1,698 @@ +classdef ScrollingPanel < uix.Container & uix.mixin.Panel + %uix.ScrollingPanel Scrolling panel + % + % p = uix.ScrollingPanel(p1,v1,p2,v2,...) constructs a scrolling panel + % and sets parameter p1 to value v1, etc. + % + % A scrolling panel is a standard container (uicontainer) that shows + % one its contents and hides the others. + % + % See also: uix.Panel, uix.BoxPanel, uix.TabPanel, uicontainer + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Dependent ) + Heights % heights of contents, in pixels and/or weights + MinimumHeights % minimum heights of contents, in pixels + VerticalOffsets % vertical offsets of contents, in pixels + VerticalSteps % vertical slider steps, in pixels + Widths % widths of contents, in pixels and/or weights + MinimumWidths % minimum widths of contents, in pixels + HorizontalOffsets % horizontal offsets of contents, in pixels + HorizontalSteps % horizontal slider steps, in pixels + MouseWheelEnabled % mouse wheel scrolling enabled [on|off] + end + + properties( Access = protected ) + Heights_ = zeros( [0 1] ) % backing for Heights + MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights + Widths_ = zeros( [0 1] ) % backing for Widths + MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths + HorizontalSliders = matlab.ui.control.UIControl.empty( [0 1] ) % sliders + VerticalSliders = matlab.ui.control.UIControl.empty( [0 1] ) % sliders + BlankingPlates = matlab.ui.control.UIControl.empty( [0 1] ) % blanking plates + HorizontalSteps_ = zeros( [0 1] ) % steps + VerticalSteps_ = zeros( [0 1] ) % steps + end + + properties( Access = private ) + MouseWheelListener = [] % mouse listener + MouseWheelEnabled_ = 'on' % backing for MouseWheelEnabled + ScrollingListener = [] % slider listener + ScrolledListener = [] % slider listener + BackgroundColorListener % property listener + end + + properties( Constant, Access = protected ) + SliderSize = 20 % slider size, in pixels + SliderStep = 10 % slider step, in pixels + end + + events( NotifyAccess = private ) + Scrolling + Scrolled + end + + methods + + function obj = ScrollingPanel( varargin ) + %uix.ScrollingPanel Scrolling panel constructor + % + % p = uix.ScrollingPanel() constructs a scrolling panel. + % + % p = uix.ScrollingPanel(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChanged ); + + % Store properties + obj.BackgroundColorListener = backgroundColorListener; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.Heights( obj ) + + value = obj.Heights_; + + end % get.Heights + + function set.Heights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Heights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Heights'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Heights'' must match size of contents.' ) + + % Set + obj.Heights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Heights + + function value = get.MinimumHeights( obj ) + + value = obj.MinimumHeights_; + + end % get.MinimumHeights + + function set.MinimumHeights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumHeights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumHeights'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Heights_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumHeights'' must match size of contents.' ) + + % Set + obj.MinimumHeights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumHeights + + function value = get.VerticalOffsets( obj ) + + sliders = obj.VerticalSliders; + if isempty( sliders ) + value = zeros( size( sliders ) ); + else + value = -vertcat( sliders.Value ) - 1; + value(value<0) = 0; + end + + end % get.VerticalOffsets + + function set.VerticalOffsets( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''VerticalOffsets'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''VerticalOffsets'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''VerticalOffsets'' must match size of contents.' ) + + % Set + sliders = obj.VerticalSliders; + for ii = 1:numel( sliders ) + sliders(ii).Value = -value(ii) - 1; + end + + % Mark as dirty + obj.Dirty = true; + + end % set.VerticalOffsets + + function value = get.VerticalSteps( obj ) + + value = obj.VerticalSteps_; + + end % get.VerticalSteps + + function set.VerticalSteps( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''VerticalSteps'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ) && all( value > 0 ), ... + 'uix:InvalidPropertyValue', ... + 'Elements of property ''VerticalSteps'' must be real, finite and positive.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''VerticalSteps'' must match size of contents.' ) + + % Set + obj.VerticalSteps_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.VerticalSteps + + function value = get.Widths( obj ) + + value = obj.Widths_; + + end % get.Widths + + function set.Widths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Widths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Widths'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Widths'' must match size of contents.' ) + + % Set + obj.Widths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Widths + + function value = get.MinimumWidths( obj ) + + value = obj.MinimumWidths_; + + end % get.MinimumWidths + + function set.MinimumWidths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumWidths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumWidths'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Widths_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumWidths'' must match size of contents.' ) + + % Set + obj.MinimumWidths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumWidths + + function value = get.HorizontalOffsets( obj ) + + sliders = obj.HorizontalSliders; + if isempty( sliders ) + value = zeros( size( sliders ) ); + else + value = vertcat( sliders.Value ); + value(value<0) = 0; + end + + end % get.HorizontalOffsets + + function set.HorizontalOffsets( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''HorizontalOffsets'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''HorizontalOffsets'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''HorizontalOffsets'' must match size of contents.' ) + + % Set + sliders = obj.HorizontalSliders; + for ii = 1:numel( sliders ) + sliders(ii).Value = value(ii); + end + + % Mark as dirty + obj.Dirty = true; + + end % set.HorizontalOffsets + + function value = get.HorizontalSteps( obj ) + + value = obj.HorizontalSteps_; + + end % get.HorizontalSteps + + function set.HorizontalSteps( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''HorizontalSteps'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ) && all( value > 0 ), ... + 'uix:InvalidPropertyValue', ... + 'Elements of property ''HorizontalSteps'' must be real, finite and positive.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''HorizontalSteps'' must match size of contents.' ) + + % Set + obj.HorizontalSteps_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.HorizontalSteps + + function value = get.MouseWheelEnabled( obj ) + + value = obj.MouseWheelEnabled_; + + end % get.MouseWheelEnabled + + function set.MouseWheelEnabled( obj, value ) + + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''MouseWheelEnabled'' must ''on'' or ''off''.' ) + listener = obj.MouseWheelListener; + if ~isempty( listener ) + listener.Enabled = strcmp( value, 'on' ); + end + obj.MouseWheelEnabled_ = value; + + end % set.MouseWheelEnabled + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + + % Return if no contents + selection = obj.Selection_; + if selection == 0, return, end + + % Retrieve width and height of selected contents + contentsWidth = obj.Widths_(selection); + minimumWidth = obj.MinimumWidths_(selection); + contentsHeight = obj.Heights_(selection); + minimumHeight = obj.MinimumHeights_(selection); + + % Retrieve selected contents and corresponding decorations + child = obj.Contents_(selection); + vSlider = obj.VerticalSliders(selection); + hSlider = obj.HorizontalSliders(selection); + plate = obj.BlankingPlates(selection); + + % Compute dimensions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + width = bounds(3); + height = bounds(4); + sliderSize = obj.SliderSize; % slider size + vSliderWidth = sliderSize * ... + (contentsHeight > height | ... + minimumHeight > height); % first pass + hSliderHeight = sliderSize * ... + (contentsWidth > width - vSliderWidth | ... + minimumWidth > width - vSliderWidth); + vSliderWidth = sliderSize * ... + (contentsHeight > height - hSliderHeight | ... + minimumHeight > height - hSliderHeight); % second pass + vSliderWidth = min( vSliderWidth, width ); % limit + hSliderHeight = min( hSliderHeight, height ); % limit + vSliderHeight = height - hSliderHeight; + hSliderWidth = width - vSliderWidth; + widths = uix.calcPixelSizes( width, ... + [contentsWidth;vSliderWidth], ... + [minimumWidth;vSliderWidth], 0, 0 ); + contentsWidth = widths(1); % to be offset + heights = uix.calcPixelSizes( height, ... + [contentsHeight;hSliderHeight], ... + [minimumHeight;hSliderHeight], 0, 0 ); + contentsHeight = heights(1); % to be offset + + % Compute positions + contentsPosition = [1 1+hSliderHeight+vSliderHeight-contentsHeight contentsWidth contentsHeight]; + vSliderPosition = [1+hSliderWidth 1+hSliderHeight vSliderWidth vSliderHeight]; + hSliderPosition = [1 1 hSliderWidth hSliderHeight]; + platePosition = [1+hSliderWidth 1 vSliderWidth hSliderHeight]; + + % Compute and set vertical slider properties + if vSliderWidth == 0 || vSliderHeight == 0 || vSliderHeight <= vSliderWidth + % Slider is invisible or incorrectly oriented + set( vSlider, 'Style', 'text', 'Enable', 'inactive', ... + 'Position', vSliderPosition, ... + 'Min', 0, 'Max', 1, 'Value', 1 ) + else + % Compute properties + vSliderMin = 0; + vSliderMax = contentsHeight - vSliderHeight; + vSliderValue = -vSlider.Value; % negative sign convention + vSliderValue = max( vSliderValue, vSliderMin ); % limit + vSliderValue = min( vSliderValue, vSliderMax ); % limit + vStep = obj.VerticalSteps_(selection); + vSliderStep(1) = min( vStep / vSliderMax, 1 ); + vSliderStep(2) = max( vSliderHeight / vSliderMax, vSliderStep(1) ); + contentsPosition(2) = contentsPosition(2) + vSliderValue; + % Set properties + set( vSlider, 'Style', 'slider', 'Enable', 'on', ... + 'Position', vSliderPosition, ... + 'Min', -vSliderMax, 'Max', -vSliderMin, ... + 'Value', -vSliderValue, 'SliderStep', vSliderStep ) + end + + % Compute and set horizontal slider properties + if hSliderHeight == 0 || hSliderWidth == 0 || hSliderWidth <= hSliderHeight + % Slider is invisible or incorrectly oriented + set( hSlider, 'Style', 'text', 'Enable', 'inactive', ... + 'Position', hSliderPosition, ... + 'Min', -1, 'Max', 0, 'Value', -1 ) + else + % Compute properties + hSliderMin = 0; + hSliderMax = contentsWidth - hSliderWidth; + hSliderValue = hSlider.Value; % positive sign convention + hSliderValue = max( hSliderValue, hSliderMin ); % limit + hSliderValue = min( hSliderValue, hSliderMax ); % limit + hStep = obj.HorizontalSteps_(selection); + hSliderStep(1) = min( hStep / hSliderMax, 1 ); + hSliderStep(2) = max( hSliderWidth / hSliderMax, hSliderStep(1) ); + contentsPosition(1) = contentsPosition(1) - hSliderValue; + % Set properties + set( hSlider, 'Style', 'slider', 'Enable', 'on', ... + 'Position', hSliderPosition, ... + 'Min', hSliderMin, 'Max', hSliderMax, ... + 'Value', hSliderValue, 'SliderStep', hSliderStep ) + end + + % Set contents and blanking plate positions + uix.setPosition( child, contentsPosition, 'pixels' ) + set( plate, 'Position', platePosition ) + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Create decorations + verticalSlider = matlab.ui.control.UIControl( ... + 'Internal', true, 'Parent', obj, ... + 'Units', 'pixels', 'Style', 'slider', ... + 'BackgroundColor', obj.BackgroundColor ); + horizontalSlider = matlab.ui.control.UIControl( ... + 'Internal', true, 'Parent', obj, ... + 'Units', 'pixels', 'Style', 'slider', ... + 'BackgroundColor', obj.BackgroundColor ); + blankingPlate = matlab.ui.control.UIControl( ... + 'Internal', true, 'Parent', obj, ... + 'Units', 'pixels', 'Style', 'text', 'Enable', 'inactive', ... + 'BackgroundColor', obj.BackgroundColor ); + + % Add to sizes + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + obj.Heights_(end+1,:) = -1; + obj.MinimumHeights_(end+1,:) = 1; + obj.VerticalSliders(end+1,:) = verticalSlider; + obj.HorizontalSliders(end+1,:) = horizontalSlider; + obj.BlankingPlates(end+1,:) = blankingPlate; + obj.VerticalSteps_(end+1,:) = obj.SliderStep; + obj.HorizontalSteps_(end+1,:) = obj.SliderStep; + obj.updateSliderListeners() + + % Call superclass method + addChild@uix.mixin.Panel( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Identify child + tf = obj.Contents_ == child; + + % Destroy decorations + delete( obj.VerticalSliders(tf,:) ) + delete( obj.HorizontalSliders(tf,:) ) + delete( obj.BlankingPlates(tf,:) ) + + % Remove from sizes + obj.Widths_(tf,:) = []; + obj.MinimumWidths_(tf,:) = []; + obj.Heights_(tf,:) = []; + obj.MinimumHeights_(tf,:) = []; + obj.VerticalSliders(tf,:) = []; + obj.HorizontalSliders(tf,:) = []; + obj.BlankingPlates(tf,:) = []; + obj.VerticalSteps_(tf,:) = []; + obj.HorizontalSteps_(tf,:) = []; + obj.updateSliderListeners() + + % Call superclass method + removeChild@uix.mixin.Panel( obj, child ) + + end % removeChild + + function reparent( obj, ~, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + if isempty( newFigure ) + obj.MouseWheelListener = []; + else + listener = event.listener( newFigure, ... + 'WindowScrollWheel', @obj.onMouseScrolled ); + listener.Enabled = strcmp( obj.MouseWheelEnabled_, 'on' ); + obj.MouseWheelListener = listener; + end + + end % reparent + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Widths_ = obj.Widths_(indices,:); + obj.MinimumWidths_ = obj.MinimumWidths_(indices,:); + obj.Heights_ = obj.Heights_(indices,:); + obj.MinimumHeights_ = obj.MinimumWidths_(indices,:); + obj.VerticalSliders = obj.VerticalSliders(indices,:); + obj.HorizontalSliders = obj.HorizontalSliders(indices,:); + obj.BlankingPlates = obj.BlankingPlates(indices,:); + obj.VerticalSteps_ = obj.VerticalSteps_(indices,:); + obj.HorizontalSteps_ = obj.HorizontalSteps_(indices,:); + + % Call superclass method + reorder@uix.mixin.Panel( obj, indices ) + + end % reorder + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Call superclass method + showSelection@uix.mixin.Panel( obj ) + + % Show and hide sliders based on selection + selection = obj.Selection_; + for ii = 1:numel( obj.Contents_ ) + if ii == selection + obj.VerticalSliders(ii).Visible = 'on'; + obj.HorizontalSliders(ii).Visible = 'on'; + obj.BlankingPlates(ii).Visible = 'on'; + else + obj.VerticalSliders(ii).Visible = 'off'; + obj.HorizontalSliders(ii).Visible = 'off'; + obj.BlankingPlates(ii).Visible = 'off'; + end + end + + end % showSelection + + end % template methods + + methods( Access = private ) + + function onSliderScrolling( obj, ~, ~ ) + %onSliderScrolling Event handler + + % Mark as dirty + obj.Dirty = true; + + % Raise event + notify( obj, 'Scrolling' ) + + end % onSliderScrolling + + function onSliderScrolled( obj, ~, ~ ) + %onSliderScrolled Event handler + + % Mark as dirty + obj.Dirty = true; + + % Raise event + notify( obj, 'Scrolled' ) + + end % onSliderScrolled + + function onMouseScrolled( obj, ~, eventData ) + %onMouseScrolled Event handler + + sel = obj.Selection_; + if sel == 0 + return + else + % Get pointer position and panel bounds + pp = getpixelposition( obj, true ); + f = ancestor( obj, 'figure' ); + cpu = f.CurrentPoint; % figure Units + cpwhu = [cpu 0 0]; % [x y] to [x y w h] for hgconvertunits + cpwh = hgconvertunits( f, cpwhu, f.Units, 'pixels', obj ); % pixels + cp = cpwh(1:2); % [x y w h] to [x y] + + % Check that pointer is over panel + if cp(1) < pp(1) || cp(1) > pp(1) + pp(3) || ... + cp(2) < pp(2) || cp(2) > pp(2) + pp(4), return, end + % Scroll + if strcmp( obj.VerticalSliders(sel).Enable, 'on' ) % scroll vertically + delta = eventData.VerticalScrollCount * ... + eventData.VerticalScrollAmount * obj.VerticalSteps(sel); + obj.VerticalOffsets(sel) = obj.VerticalOffsets(sel) + delta; + elseif strcmp( obj.HorizontalSliders(sel).Enable, 'on' ) % scroll horizontally + delta = eventData.VerticalScrollCount * ... + eventData.VerticalScrollAmount * obj.HorizontalSteps(sel); + obj.HorizontalOffsets(sel) = obj.HorizontalOffsets(sel) + delta; + end + % Raise event + notify( obj, 'Scrolled' ) + end + + end % onMouseScrolled + + function onBackgroundColorChanged( obj, ~, ~ ) + %onBackgroundColorChanged Handler for BackgroundColor changes + + set( obj.HorizontalSliders, 'BackgroundColor', obj.BackgroundColor ) + set( obj.VerticalSliders, 'BackgroundColor', obj.BackgroundColor ) + set( obj.BlankingPlates, 'BackgroundColor', obj.BackgroundColor ) + + end % onBackgroundColorChanged + + end % event handlers + + methods( Access = private ) + + function updateSliderListeners( obj ) + %updateSliderListeners Update listeners to slider events + + if isempty( obj.VerticalSliders ) + obj.ScrollingListener = []; + obj.ScrolledListener = []; + else + obj.ScrollingListener = event.listener( ... + [obj.VerticalSliders; obj.HorizontalSliders], ... + 'ContinuousValueChange', @obj.onSliderScrolling ); + obj.ScrolledListener = event.listener( ... + [obj.VerticalSliders; obj.HorizontalSliders], ... + 'Action', @obj.onSliderScrolled ); + end + + end % updateSliderListeners + + end % helpers + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/SelectionData.m b/studio_functions/GUI Layout Toolbox/layout/+uix/SelectionData.m new file mode 100644 index 00000000..d5ad69a5 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/SelectionData.m @@ -0,0 +1,30 @@ +classdef( Hidden, Sealed ) SelectionData < event.EventData + %uix.SelectionData Event data for selection event + % + % e = uix.SelectionData(o,n) creates event data including the old + % value o and the new value n. + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( SetAccess = private ) + OldValue % old value + NewValue % newValue + end + + methods + + function obj = SelectionData( oldValue, newValue ) + %uix.SelectionData Event data for selection event + % + % e = uix.SelectionData(o,n) creates event data including the + % old value o and the new value n. + + % Set properties + obj.OldValue = oldValue; + obj.NewValue = newValue; + + end % constructor + + end % structors + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/TabPanel.m b/studio_functions/GUI Layout Toolbox/layout/+uix/TabPanel.m new file mode 100644 index 00000000..2bc579f8 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/TabPanel.m @@ -0,0 +1,946 @@ +classdef TabPanel < uix.Container & uix.mixin.Panel + %uix.TabPanel Tab panel + % + % p = uix.TabPanel(p1,v1,p2,v2,...) constructs a tab panel and sets + % parameter p1 to value v1, etc. + % + % A tab panel shows one of its contents and hides the others according + % to which tab is selected. + % + % From R2014b, MATLAB provides uitabgroup and uitab as standard + % components. Consider using uitabgroup and uitab for new code if + % these meet your requirements. + % + % See also: uitabgroup, uitab, uix.CardPanel + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + FontAngle % font angle + FontName % font name + FontSize % font size + FontWeight % font weight + FontUnits % font weight + ForegroundColor % tab text color [RGB] + HighlightColor % border highlight color [RGB] + ShadowColor % border shadow color [RGB] + end + + properties + SelectionChangedFcn = '' % selection change callback + end + + properties( Access = public, Dependent, AbortSet ) + TabEnables % tab enable states + TabLocation % tab location [top|bottom] + TabTitles % tab titles + TabContextMenus % tab context menus + TabWidth % tab width + end + + properties( Access = private ) + FontAngle_ = get( 0, 'DefaultUicontrolFontAngle' ) % backing for FontAngle + FontName_ = get( 0, 'DefaultUicontrolFontName' ) % backing for FontName + FontSize_ = get( 0, 'DefaultUicontrolFontSize' ) % backing for FontSize + FontWeight_ = get( 0, 'DefaultUicontrolFontWeight' ) % backing for FontWeight + FontUnits_ = get( 0, 'DefaultUicontrolFontUnits' ) % backing for FontUnits + ForegroundColor_ = get( 0, 'DefaultUicontrolForegroundColor' ) % backing for ForegroundColor + HighlightColor_ = [1 1 1] % backing for HighlightColor + ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor + ParentBackgroundColor = get( 0, 'DefaultUicontrolForegroundColor' ) % default parent background color + Tabs = gobjects( [0 1] ) % tabs + TabListeners = event.listener.empty( [0 1] ) % tab listeners + TabLocation_ = 'top' % backing for TabPosition + TabHeight = -1 % cache of tab height (-1 denotes stale cache) + TabWidth_ = 50 % backing for TabWidth + Dividers % tab dividers + BackgroundColorListener % listener + SelectionChangedListener % listener + ParentListener % listener + ParentBackgroundColorListener % listener + end + + properties( Access = private, Constant ) + FontNames = listfonts() % all available font names + DividerMask = uix.TabPanel.getDividerMask() % divider image data + DividerWidth = 8 % divider width + TabMinimumHeight = 9 % tab minimum height + Tint = 0.85 % tint factor for unselected tabs + end + + methods + + function obj = TabPanel( varargin ) + %uix.TabPanel Tab panel constructor + % + % p = uix.TabPanel() constructs a tab panel. + % + % p = uix.TabPanel(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create dividers + dividers = matlab.ui.control.UIControl( 'Internal', true, ... + 'Parent', obj, 'Units', 'pixels', 'Style', 'checkbox',... + 'Tag', 'TabPanelDividers' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChanged ); + selectionChangedListener = event.listener( obj, ... + 'SelectionChanged', @obj.onSelectionChanged ); + parentListener = event.proplistener( obj, ... + findprop( obj, 'Parent' ), 'PostSet', ... + @obj.onParentChanged ); + + % Store properties + obj.Dividers = dividers; + obj.BackgroundColorListener = backgroundColorListener; + obj.SelectionChangedListener = selectionChangedListener; + obj.ParentListener = parentListener; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.FontAngle( obj ) + + value = obj.FontAngle_; + + end % get.FontAngle + + function set.FontAngle( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'normal','italic','oblique'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontAngle'' must be ''normal'', ''italic'' or ''oblique''.' ) + + % Set + obj.FontAngle_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontAngle = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontAngle + + function value = get.FontName( obj ) + + value = obj.FontName_; + + end % get.FontName + + function set.FontName( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, obj.FontNames ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontName'' must be a valid font name.' ) + + % Set + obj.FontName_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontName = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontName + + function value = get.FontSize( obj ) + + value = obj.FontSize_; + + end % get.FontSize + + function set.FontSize( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value > 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontSize'' must be a positive scalar.' ) + + % Set + obj.FontSize_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontSize = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontSize + + function value = get.FontWeight( obj ) + + value = obj.FontWeight_; + + end % get.FontWeight + + function set.FontWeight( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'normal','bold'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontWeight'' must be ''normal'' or ''bold''.' ) + + % Set + obj.FontWeight_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontWeight = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontWeight + + function value = get.FontUnits( obj ) + + value = obj.FontUnits_; + + end % get.FontUnits + + function set.FontUnits( obj, value ) + + % Check + assert( ischar( value ) && ... + any( strcmp( value, {'inches','centimeters','points','pixels'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontUnits'' must be ''inches'', ''centimeters'', ''points'' or ''pixels''.' ) + + % Compute size in new units + oldUnits = obj.FontUnits_; + oldSize = obj.FontSize_; + newUnits = value; + newSize = oldSize * convert( oldUnits ) / convert( newUnits ); + + % Set size and units + obj.FontSize_ = newSize; + obj.FontUnits_ = newUnits; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontUnits = newUnits; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + function factor = convert( units ) + %convert Compute conversion factor to points + % + % f = convert(u) computes the conversion factor from units + % u to points. For example, convert('inches') since 1 + % inch equals 72 points. + + persistent SCREEN_PIXELS_PER_INCH + if isequal( SCREEN_PIXELS_PER_INCH, [] ) % uninitialized + SCREEN_PIXELS_PER_INCH = get( 0, 'ScreenPixelsPerInch' ); + end + + switch units + case 'inches' + factor = 72; + case 'centimeters' + factor = 72 / 2.54; + case 'points' + factor = 1; + case 'pixels' + factor = 72 / SCREEN_PIXELS_PER_INCH; + end + + end % convert + + end % set.FontUnits + + function value = get.ForegroundColor( obj ) + + value = obj.ForegroundColor_; + + end % get.ForegroundColor + + function set.ForegroundColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''ForegroundColor'' must be an RGB triple.' ) + + % Set + obj.ForegroundColor_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.ForegroundColor = value; + end + + end % set.ForegroundColor + + function value = get.HighlightColor( obj ) + + value = obj.HighlightColor_; + + end % get.HighlightColor + + function set.HighlightColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''HighlightColor'' must be an RGB triple.' ) + + % Set + obj.HighlightColor_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.HighlightColor + + function set.SelectionChangedFcn( obj, value ) + + % Check + if ischar( value ) % string + % OK + elseif isa( value, 'function_handle' ) && ... + isequal( size( value ), [1 1] ) % function handle + % OK + elseif iscell( value ) && ndims( value ) == 2 && ... + size( value, 1 ) == 1 && size( value, 2 ) > 0 && ... + isa( value{1}, 'function_handle' ) && ... + isequal( size( value{1} ), [1 1] ) %#ok % cell callback + % OK + else + error( 'uix:InvalidPropertyValue', ... + 'Property ''SelectionChangedFcn'' must be a valid callback.' ) + end + + % Set + obj.SelectionChangedFcn = value; + + end % set.SelectionChangedFcn + + function value = get.ShadowColor( obj ) + + value = obj.ShadowColor_; + + end % get.ShadowColor + + function set.ShadowColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''ShadowColor'' must be an RGB triple.' ) + + % Set + obj.ShadowColor_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.ShadowColor + + function value = get.TabEnables( obj ) + + value = get( obj.Tabs, {'Enable'} ); + value(strcmp( value, 'inactive' )) = {'on'}; + + end % get.TabEnables + + function set.TabEnables( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Retrieve tabs + tabs = obj.Tabs; + tabListeners = obj.TabListeners; + + % Check + assert( iscellstr( value ) && ... + isequal( size( value ), size( tabs ) ) && ... + all( strcmp( value, 'on' ) | strcmp( value, 'off' ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabEnables'' should be a cell array of strings ''on'' or ''off'', one per tab.' ) + + % Set + tf = strcmp( value, 'on' ); + value(tf) = {'inactive'}; + for ii = 1:numel( tabs ) + tabs(ii).Enable = value{ii}; + tabListeners(ii).Enabled = tf(ii); + end + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + end % set.TabEnables + + function value = get.TabLocation( obj ) + + value = obj.TabLocation_; + + end % get.TabLocation + + function set.TabLocation( obj, value ) + + % Check + assert( ischar( value ) && ... + any( strcmp( value, {'top','bottom'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabLocation'' should be ''top'' or ''bottom''.' ) + + % Set + obj.TabLocation_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.TabLocation + + function value = get.TabTitles( obj ) + + value = get( obj.Tabs, {'String'} ); + + end % get.TabTitles + + function set.TabTitles( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Retrieve tabs + tabs = obj.Tabs; + + % Check + assert( iscellstr( value ) && ... + isequal( size( value ), size( tabs ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabTitles'' should be a cell array of strings, one per tab.' ) + + % Set + n = numel( tabs ); + for ii = 1:n + tabs(ii).String = value{ii}; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.TabTitles + + function value = get.TabContextMenus( obj ) + + tabs = obj.Tabs; + n = numel( tabs ); + value = cell( [n 1] ); + for ii = 1:n + value{ii} = tabs(ii).UIContextMenu; + end + + end % get.TabContextMenus + + function set.TabContextMenus( obj, value ) + + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tabs(ii).UIContextMenu = value{ii}; + end + + end % set.TabContextMenus + + function value = get.TabWidth( obj ) + + value = obj.TabWidth_; + + end % get.TabWidth + + function set.TabWidth( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value ~= 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabWidth'' must be a non-zero scalar.' ) + + % Set + obj.TabWidth_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.TabWidth + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + w = ceil( bounds(1) + bounds(3) ) - floor( bounds(1) ); % width + h = ceil( bounds(2) + bounds(4) ) - floor( bounds(2) ); % height + p = obj.Padding_; % padding + tabs = obj.Tabs; + n = numel( tabs ); % number of tabs + tH = obj.TabHeight; % tab height + if tH == -1 % cache stale, refresh + if n > 0 + cTabExtents = get( tabs, {'Extent'} ); + tabExtents = vertcat( cTabExtents{:} ); + tH = max( tabExtents(:,4) ); + end + tH = max( tH, obj.TabMinimumHeight ); % apply minimum + tH = ceil( tH ); % round up + obj.TabHeight = tH; % store + end + cH = max( [h - 2 * p - tH, 1] ); % contents height + switch obj.TabLocation_ + case 'top' + cY = 1 + p; % contents y + tY = cY + cH + p; % tab y + case 'bottom' + tY = 1; % tab y + cY = tY + tH + p; % contents y + end + cX = 1 + p; % contents x + cW = max( [w - 2 * p, 1] ); % contents width + tW = obj.TabWidth_; % tab width + dW = obj.DividerWidth; % tab divider width + if tW < 0 && n > 0 % relative + tW = max( ( w - (n+1) * dW ) / n, 1 ); + end + tW = ceil( tW ); % round up + for ii = 1:n + tabs(ii).Position = [1 + (ii-1) * tW + ii * dW, tY, tW, tH]; + end + obj.Dividers.Position = [0 tY w+1 tH]; + contentsPosition = [cX cY cW cH]; + + % Redraw tabs + obj.redrawTabs() + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 && strcmp( obj.TabEnables{selection}, 'on' ) + uix.setPosition( obj.Contents_(selection), contentsPosition, 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Create new tab + n = numel( obj.Tabs ); + tab = matlab.ui.control.UIControl( 'Internal', true, ... + 'Parent', obj, 'Style', 'text', 'Enable', 'inactive', ... + 'Units', 'pixels', 'FontUnits', obj.FontUnits_, ... + 'FontSize', obj.FontSize_, 'FontName', obj.FontName_, ... + 'FontAngle', obj.FontAngle_, 'FontWeight', obj.FontWeight_, ... + 'ForegroundColor', obj.ForegroundColor_, ... + 'String', sprintf( 'Page %d', n + 1 ) ); + tabListener = event.listener( tab, 'ButtonDown', @obj.onTabClicked ); + obj.Tabs(n+1,:) = tab; + obj.TabListeners(n+1,:) = tabListener; + + % Mark as dirty + obj.TabHeight = -1; + + % Check for bug + if verLessThan( 'MATLAB', '8.5' ) && strcmp( child.Visible, 'off' ) + obj.G1218142 = true; + end + + % Select new content + oldSelection = obj.Selection_; + if numel( obj.Contents_ ) == 0 + newSelection = 1; + obj.Selection_ = newSelection; + else + newSelection = oldSelection; + end + + % Call superclass method + addChild@uix.mixin.Container( obj, child ) + + % Show selected child + obj.showSelection() + + % Notify selection change + if oldSelection ~= newSelection + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + end + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Find index of removed child + contents = obj.Contents_; + index = find( contents == child ); + + % Remove tab + delete( obj.Tabs(index) ) + obj.Tabs(index,:) = []; + obj.TabListeners(index,:) = []; + + % Call superclass method + removeChild@uix.mixin.Panel( obj, child ) + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Tabs = obj.Tabs(indices,:); + obj.TabListeners = obj.TabListeners(indices,:); + + % Call superclass method + reorder@uix.mixin.Panel( obj, indices ) + + end % reorder + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + if ~isequal( oldFigure, newFigure ) + contextMenus = obj.TabContextMenus; + for ii = 1:numel( contextMenus ) + contextMenu = contextMenus{ii}; + if ~isempty( contextMenu ) + contextMenu.Parent = newFigure; + end + end + end + + % Call superclass method + reparent@uix.mixin.Panel( obj, oldFigure, newFigure ) + + end % reparent + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Call superclass method + showSelection@uix.mixin.Panel( obj ) + + % If not enabled, hide selected contents too + selection = obj.Selection_; + if selection ~= 0 && strcmp( obj.TabEnables{selection}, 'off' ) + child = obj.Contents_(selection); + child.Visible = 'off'; + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'off'; + end + % As a remedy for g1100294, move off-screen too + margin = 1000; + if isa( child, 'matlab.graphics.axis.Axes' ) ... + && strcmp(child.ActivePositionProperty, 'outerposition' ) + child.OuterPosition(1) = -child.OuterPosition(3)-margin; + else + child.Position(1) = -child.Position(3)-margin; + end + end + + end % showSelection + + end % template methods + + methods( Access = private ) + + function redrawTabs( obj ) + %redrawTabs Redraw tabs + % + % p.redrawTabs() redraws the tabs. + + % Get relevant properties + selection = obj.Selection_; + tabs = obj.Tabs; + t = numel( tabs ); + dividers = obj.Dividers; + + % Handle no tabs as a special case + if t == 0 + dividers.Visible = 'off'; % hide + return + end + + % Repaint tabs + backgroundColor = obj.BackgroundColor; + for ii = 1:t + tab = tabs(ii); + if ii == selection + tab.BackgroundColor = backgroundColor; + else + tab.BackgroundColor = obj.Tint * backgroundColor; + end + end + + % Repaint dividers + d = t + 1; + dividerNames = repmat( 'F', [d 2] ); % initialize + dividerNames(1,1) = 'E'; % end + dividerNames(end,2) = 'E'; % end + if selection ~= 0 + dividerNames(selection,2) = 'T'; % selected + dividerNames(selection+1,1) = 'T'; % selected + end + tH = obj.TabHeight; + assert( tH >= obj.TabMinimumHeight, 'uix:InvalidState', ... + 'Cannot redraw tabs with invalid TabHeight.' ) + tW = obj.Tabs(1).Position(3); + dW = obj.DividerWidth; + allCData = zeros( [tH 0 3] ); % initialize + map = [obj.ShadowColor; obj.BackgroundColor; ... + obj.Tint * obj.BackgroundColor; obj.HighlightColor;... + obj.ParentBackgroundColor]; + for ii = 1:d + % Select mask + iMask = obj.DividerMask.( dividerNames(ii,:) ); + % Resize + iData = repmat( iMask(5,:), [tH 1] ); + iData(1:4,:) = iMask(1:4,:); + iData(end-3:end,:) = iMask(end-3:end,:); + % Convert to RGB + cData = ind2rgb( iData+1, map ); + % Orient + switch obj.TabLocation_ + case 'bottom' + cData = flipud( cData ); + end + % Insert + allCData(1:tH,(ii-1)*(dW+tW)+(1:dW),:) = cData; % center + if ii > 1 % extend left under transparent uicontrol edge + allCData(1:tH,(ii-1)*(dW+tW),:) = cData(:,1,:); + end + if ii < d % extend right under transparent uicontrol edge + allCData(1:tH,(ii-1)*(dW+tW)+dW+1,:) = cData(:,end,:); + end + end + dividers.CData = allCData; % paint + dividers.BackgroundColor = obj.ParentBackgroundColor; + dividers.Visible = 'on'; % show + + end % redrawTabs + + end % helper methods + + methods( Access = private ) + + function onTabClicked( obj, source, ~ ) + + % Update selection + oldSelection = obj.Selection_; + newSelection = find( source == obj.Tabs ); + if oldSelection == newSelection, return, end % abort set + obj.Selection_ = newSelection; + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + % Notify selection change + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + + end % onTabClicked + + function onBackgroundColorChanged( obj, ~, ~ ) + + % Mark as dirty + obj.Dirty = true; + + end % onBackgroundColorChanged + + function onSelectionChanged( obj, source, eventData ) + + % Call callback + callback = obj.SelectionChangedFcn; + if ischar( callback ) && isequal( callback, '' ) + % do nothing + elseif ischar( callback ) + feval( callback, source, eventData ) + elseif isa( callback, 'function_handle' ) + callback( source, eventData ) + elseif iscell( callback ) + feval( callback{1}, source, eventData, callback{2:end} ) + end + + end % onSelectionChanged + + function onParentChanged( obj, ~, ~ ) + + % Update ParentBackgroundColor and ParentBackgroundColor + if isprop( obj.Parent, 'BackgroundColor' ) + prop = 'BackgroundColor'; + elseif isprop( obj.Parent, 'Color' ) + prop = 'Color'; + else + prop = []; + end + + if ~isempty( prop ) + obj.ParentBackgroundColorListener = event.proplistener( obj.Parent, ... + findprop( obj.Parent, prop ), 'PostSet', ... + @( src, evt ) obj.updateParentBackgroundColor( prop ) ); + else + obj.ParentBackgroundColorListener = []; + end + + obj.updateParentBackgroundColor( prop ); + + end % onParentChanged + + function updateParentBackgroundColor( obj, prop ) + + if isempty( prop ) + obj.ParentBackgroundColor = obj.BackgroundColor; + else + obj.ParentBackgroundColor = obj.Parent.(prop); + end + + % Mark as dirty + obj.Dirty = true; + + end + + end % event handlers + + methods( Access = private, Static ) + + function mask = getDividerMask() + %getDividerMask Get divider image data + % + % m = uix.TabPanel.getDividerMask() returns the image masks + % for tab panel dividers. Mask entries are 0 (shadow), 1 + % (background), 2 (tint) and 3 (highlight). + + mask.EF = indexColor( uix.loadIcon( 'tab_NoEdge_NotSelected.png' ) ); + mask.ET = indexColor( uix.loadIcon( 'tab_NoEdge_Selected.png' ) ); + mask.FE = indexColor( uix.loadIcon( 'tab_NotSelected_NoEdge.png' ) ); + mask.FF = indexColor( uix.loadIcon( 'tab_NotSelected_NotSelected.png' ) ); + mask.FT = indexColor( uix.loadIcon( 'tab_NotSelected_Selected.png' ) ); + mask.TE = indexColor( uix.loadIcon( 'tab_Selected_NoEdge.png' ) ); + mask.TF = indexColor( uix.loadIcon( 'tab_Selected_NotSelected.png' ) ); + + function mask = indexColor( rgbMap ) + %indexColor Returns a map of index given an RGB map + % + % mask = indexColor( rgbMap ) returns a mask of color + % index based on the supplied rgbMap. + % black : 0 + % red : 1 + % yellow : 2 + % white : 3 + % blue : 4 + mask = nan( size( rgbMap, 1 ),size( rgbMap, 2 ) ); + % Black + colorIndex = isColor( rgbMap, [0 0 0] ); + mask(colorIndex) = 0; + % Red + colorIndex = isColor( rgbMap, [1 0 0] ); + mask(colorIndex) = 1; + % Yellow + colorIndex = isColor( rgbMap, [1 1 0] ); + mask(colorIndex) = 2; + % White + colorIndex = isColor( rgbMap, [1 1 1] ); + mask(colorIndex) = 3; + % Blue + colorIndex = isColor( rgbMap, [0 0 1] ); + mask(colorIndex) = 4; + % Nested + function boolMap = isColor( map, color ) + %isColor Return a map of boolean where map is equal to color + boolMap = all( bsxfun( @eq, map, permute( color, [1 3 2] ) ), 3 ); + end + end + + end % getDividerMask + + end % static helper methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/Text.m b/studio_functions/GUI Layout Toolbox/layout/+uix/Text.m new file mode 100644 index 00000000..30f7a23a --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/Text.m @@ -0,0 +1,545 @@ +classdef ( Hidden ) Text < matlab.mixin.SetGet + %uix.Text Text control + % + % t = uix.Text(p1,v1,p2,v2,...) constructs a text control and sets + % parameter p1 to value v1, etc. + % + % A text control adds functionality to a uicontrol of Style text: + % * Set VerticalAlignment to 'top', 'middle' or 'bottom' + % * Fire a Callback when the user clicks on the text + % + % See also: uicontrol + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Dependent ) + BackgroundColor + end + + properties( Dependent, SetAccess = private ) + BeingDeleted + end + + properties( Dependent ) + Callback + DeleteFcn + Enable + end + + properties( Dependent, SetAccess = private ) + Extent + end + + properties( Dependent ) + FontAngle + FontName + FontSize + FontUnits + FontWeight + ForegroundColor + HandleVisibility + HorizontalAlignment + Parent + Position + String + Tag + TooltipString + end + + properties( Dependent, SetAccess = private ) + Type + end + + properties( Dependent ) + UIContextMenu + Units + UserData + VerticalAlignment + Visible + end + + properties( Access = private ) + Container % container + Checkbox % checkbox, used for label + Screen % text, used for covering checkbox + VerticalAlignment_ = 'top' % backing for VerticalAlignment + Dirty = false % flag + FigureObserver % observer + FigureListener % listener + end + + properties( Constant, Access = private ) + Margin = checkBoxLabelOffset() % checkbox size + end + + methods + + function obj = Text( varargin ) + %uix.Text Text control + % + % t = uix.Text(p1,v1,p2,v2,...) constructs a text control and + % sets parameter p1 to value v1, etc. + + % Create graphics + container = uicontainer( 'Parent', [], ... + 'Units', get( 0, 'DefaultUicontrolUnits' ), ... + 'Position', get( 0, 'DefaultUicontrolPosition' ), ... + 'SizeChangedFcn', @obj.onResized ); + checkbox = uicontrol( 'Parent', container, ... + 'HandleVisibility', 'off', ... + 'Style', 'checkbox', 'Units', 'pixels', ... + 'HorizontalAlignment', 'center', ... + 'Enable', 'inactive' ); + screen = uicontrol( 'Parent', container, ... + 'HandleVisibility', 'off', ... + 'Style', 'text', 'Units', 'pixels' ); + + % Create observers and listeners + figureObserver = uix.FigureObserver( container ); + figureListener = event.listener( figureObserver, ... + 'FigureChanged', @obj.onFigureChanged ); + + % Store properties + obj.Container = container; + obj.Checkbox = checkbox; + obj.Screen = screen; + obj.FigureObserver = figureObserver; + obj.FigureListener = figureListener; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + function delete( obj ) + %delete Destructor + + delete( obj.Container ) + + end % destructor + + end % structors + + methods + + function value = get.BackgroundColor( obj ) + + value = obj.Checkbox.BackgroundColor; + + end % get.BackgroundColor + + function set.BackgroundColor( obj, value ) + + obj.Container.BackgroundColor = value; + obj.Checkbox.BackgroundColor = value; + obj.Screen.BackgroundColor = value; + + end % set.BackgroundColor + + function value = get.BeingDeleted( obj ) + + value = obj.Checkbox.BeingDeleted; + + end % get.BeingDeleted + + function value = get.Callback( obj ) + + value = obj.Checkbox.Callback; + + end % get.Callback + + function set.Callback( obj, value ) + + obj.Checkbox.Callback = value; + + end % set.Callback + + function value = get.DeleteFcn( obj ) + + value = obj.Checkbox.DeleteFcn; + + end % get.DeleteFcn + + function set.DeleteFcn( obj, value ) + + obj.Checkbox.DeleteFcn = value; + + end % set.DeleteFcn + + function value = get.Enable( obj ) + + value = obj.Checkbox.Enable; + + end % get.Enable + + function set.Enable( obj, value ) + + obj.Checkbox.Enable = value; + + end % set.Enable + + function value = get.Extent( obj ) + + value = obj.Checkbox.Extent; + + end % get.Extent + + function value = get.FontAngle( obj ) + + value = obj.Checkbox.FontAngle; + + end % get.FontAngle + + function set.FontAngle( obj, value ) + + % Set + obj.Checkbox.FontAngle = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontAngle + + function value = get.FontName( obj ) + + value = obj.Checkbox.FontName; + + end % get.FontName + + function set.FontName( obj, value ) + + % Set + obj.Checkbox.FontName = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontName + + function value = get.FontSize( obj ) + + value = obj.Checkbox.FontSize; + + end % get.FontSize + + function set.FontSize( obj, value ) + + % Set + obj.Checkbox.FontSize = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontSize + + function value = get.FontUnits( obj ) + + value = obj.Checkbox.FontUnits; + + end % get.FontUnits + + function set.FontUnits( obj, value ) + + obj.Checkbox.FontUnits = value; + + end % set.FontUnits + + function value = get.FontWeight( obj ) + + value = obj.Checkbox.FontWeight; + + end % get.FontWeight + + function set.FontWeight( obj, value ) + + % Set + obj.Checkbox.FontWeight = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontWeight + + function value = get.ForegroundColor( obj ) + + value = obj.Checkbox.ForegroundColor; + + end % get.ForegroundColor + + function set.ForegroundColor( obj, value ) + + obj.Checkbox.ForegroundColor = value; + + end % set.ForegroundColor + + function value = get.HandleVisibility( obj ) + + value = obj.Container.HandleVisibility; + + end % get.HandleVisibility + + function set.HandleVisibility( obj, value ) + + obj.Container.HandleVisibility = value; + + end % set.HandleVisibility + + function value = get.HorizontalAlignment( obj ) + + value = obj.Checkbox.HorizontalAlignment; + + end % get.HorizontalAlignment + + function set.HorizontalAlignment( obj, value ) + + % Set + obj.Checkbox.HorizontalAlignment = value; + + % Mark as dirty + obj.setDirty() + + end % set.HorizontalAlignment + + function value = get.Parent( obj ) + + value = obj.Container.Parent; + + end % get.Parent + + function set.Parent( obj, value ) + + obj.Container.Parent = value; + + end % set.Parent + + function value = get.Position( obj ) + + value = obj.Container.Position; + + end % get.Position + + function set.Position( obj, value ) + + obj.Container.Position = value; + + end % set.Position + + function value = get.String( obj ) + + value = obj.Checkbox.String; + + end % get.String + + function set.String( obj, value ) + + % Set + obj.Checkbox.String = value; + + % Mark as dirty + obj.setDirty() + + end % set.String + + function value = get.Tag( obj ) + + value = obj.Checkbox.Tag; + + end % get.Tag + + function set.Tag( obj, value ) + + obj.Checkbox.Tag = value; + + end % set.Tag + + function value = get.TooltipString( obj ) + + value = obj.Checkbox.TooltipString; + + end % get.TooltipString + + function set.TooltipString( obj, value ) + + obj.Checkbox.TooltipString = value; + + end % set.TooltipString + + function value = get.Type( obj ) + + value = obj.Checkbox.Type; + + end % get.Type + + function value = get.UIContextMenu( obj ) + + value = obj.Checkbox.UIContextMenu; + + end % get.UIContextMenu + + function set.UIContextMenu( obj, value ) + + obj.Checkbox.UIContextMenu = value; + + end % set.UIContextMenu + + function value = get.Units( obj ) + + value = obj.Container.Units; + + end % get.Units + + function set.Units( obj, value ) + + obj.Container.Units = value; + + end % set.Units + + function value = get.UserData( obj ) + + value = obj.Checkbox.UserData; + + end % get.UserData + + function set.UserData( obj, value ) + + obj.Checkbox.UserData = value; + + end % set.UserData + + function value = get.VerticalAlignment( obj ) + + value = obj.VerticalAlignment_; + + end % get.VerticalAlignment + + function set.VerticalAlignment( obj, value ) + + % Check + assert( ischar( value ) && ... + any( strcmp( value, {'top','middle','bottom'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''VerticalAlignment'' must be ''top'', ''middle'' or ''bottom''.' ) + + % Set + obj.VerticalAlignment_ = value; + + % Mark as dirty + obj.setDirty() + + end % set.VerticalAlignment + + function value = get.Visible( obj ) + + value = obj.Container.Visible; + + end % get.Visible + + function set.Visible( obj, value ) + + obj.Container.Visible = value; + + end % set.Visible + + end % accessors + + methods( Access = private ) + + function onResized( obj, ~, ~ ) + %onResized Event handler + + % Rooted, so redraw + obj.redraw() + + end % onResized + + function onFigureChanged( obj, ~, eventData ) + + % If rooted, redraw + if isempty( eventData.OldFigure ) && ... + ~isempty( eventData.NewFigure ) && obj.Dirty + obj.redraw() + end + + end % onFigureChanged + + end % event handlers + + methods( Access = private ) + + function setDirty( obj ) + %setDirty Mark as dirty + % + % t.setDirty() marks the text control t as dirty. If the text + % control is rooted then it is redrawn immediately. If not + % then the redraw is queued for when it is next rooted. + + if isempty( obj.FigureObserver.Figure ) + obj.Dirty = true; % set flag + else + obj.Dirty = false; % unset flag + obj.redraw() % redraw + end + + end % setDirty + + function redraw( obj ) + %redraw Redraw + % + % t.redraw() redraws the text control t. Note that this + % requires the text control to be rooted. Methods should + % request redraws using setDirty, rather than calling redraw + % directly. + + c = obj.Container; + b = obj.Checkbox; + s = obj.Screen; + bo = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', c ); % bounds + m = obj.Margin; + e = b.Extent; + switch b.HorizontalAlignment + case 'left' + x = 1 - m; + case 'center' + x = 1 + bo(3)/2 - e(3)/2 - m; + case 'right' + x = 1 + bo(3) - e(3) - m; + end + w = e(3) + m; + switch obj.VerticalAlignment_ + case 'top' + y = 1 + bo(4) - e(4); + case 'middle' + y = 1 + bo(4)/2 - e(4)/2; + case 'bottom' + y = 1; + end + h = e(4); + b.Position = [x y w h]; + s.Position = [x y m h]; + + end % redraw + + end % helpers + +end % classdef + +function o = checkBoxLabelOffset() +%checkBoxLabelOffset Horizontal offset to checkbox label + +if ismac + o = 20; +else + if verLessThan( 'MATLAB', '8.6' ) % R2015b + o = 18; + else + o = 16; + end +end + +end % margin \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/VBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/VBox.m new file mode 100644 index 00000000..aee41605 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/VBox.m @@ -0,0 +1,189 @@ +classdef VBox < uix.Box + %uix.VBox Vertical box + % + % b = uix.VBox(p1,v1,p2,v2,...) constructs a vertical box and sets + % parameter p1 to value v1, etc. + % + % A vertical box lays out contents from top to bottom. + % + % See also: uix.HBox, uix.Grid, uix.VButtonBox, uix.VBoxFlex + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + Heights % heights of contents, in pixels and/or weights + MinimumHeights % minimum heights of contents, in pixels + end + + properties( Access = protected ) + Heights_ = zeros( [0 1] ) % backing for Heights + MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights + end + + methods + + function obj = VBox( varargin ) + %uix.VBox Vertical box constructor + % + % b = uix.VBox() constructs a horizontal box. + % + % b = uix.VBox(p1,v1,p2,v2,...) sets parameter p1 to value v1, + % etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.Heights( obj ) + + value = obj.Heights_; + + end % get.Heights + + function set.Heights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Heights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Heights'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Heights'' must match size of contents.' ) + + % Set + obj.Heights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Heights + + function value = get.MinimumHeights( obj ) + + value = obj.MinimumHeights_; + + end % get.MinimumHeights + + function set.MinimumHeights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumHeights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumHeights'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Heights_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumHeights'' must match size of contents.' ) + + % Set + obj.MinimumHeights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumHeights + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % c.redraw() redraws the container c. + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + r = numel( heights ); + xPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )]; + xPositions = repmat( xPositions, [r 1] ); + ySizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yPositions = [bounds(4) - cumsum( ySizes ) - padding - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to sizes + obj.Heights_(end+1,:) = -1; + obj.MinimumHeights_(end+1,:) = 1; + + % Call superclass method + addChild@uix.Box( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from sizes + tf = obj.Contents_ == child; + obj.Heights_(tf,:) = []; + obj.MinimumHeights_(tf,:) = []; + + % Call superclass method + removeChild@uix.Box( obj, child ) + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Heights_ = obj.Heights_(indices,:); + obj.MinimumHeights_ = obj.MinimumHeights_(indices,:); + + % Call superclass method + reorder@uix.Box( obj, indices ) + + end % reorder + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/VBoxFlex.m b/studio_functions/GUI Layout Toolbox/layout/+uix/VBoxFlex.m new file mode 100644 index 00000000..10275490 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/VBoxFlex.m @@ -0,0 +1,351 @@ +classdef VBoxFlex < uix.VBox & uix.mixin.Flex + %uix.VBoxFlex Flexible vertical box + % + % b = uix.VBoxFlex(p1,v1,p2,v2,...) constructs a flexible vertical box + % and sets parameter p1 to value v1, etc. + % + % A vertical box lays out contents from top to bottom. Users can + % resize contents by dragging the dividers. + % + % See also: uix.HBoxFlex, uix.GridFlex, uix.VBox, uix.VButtonBox + + % Copyright 2009-2020 The MathWorks, Inc. + + properties( Access = public, Dependent, AbortSet ) + DividerMarkings % divider markings [on|off] + end + + properties( Access = private ) + RowDividers = uix.Divider.empty( [0 1] ) % row dividers + FrontDivider % front divider + DividerMarkings_ = 'on' % backing for DividerMarkings + MousePressListener = event.listener.empty( [0 0] ) % mouse press listener + MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener + MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener + ActiveDivider = 0 % active divider index + ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position + MousePressLocation = [NaN NaN] % mouse press location + BackgroundColorListener % background color listener + end + + methods + + function obj = VBoxFlex( varargin ) + %uix.VBoxFlex Flexible vertical box constructor + % + % b = uix.VBoxFlex() constructs a flexible vertical box. + % + % b = uix.VBoxFlex(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create front divider + frontDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'horizontal', ... + 'BackgroundColor', obj.BackgroundColor * 0.75, ... + 'Visible', 'off' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChanged ); + + % Store properties + obj.FrontDivider = frontDivider; + obj.BackgroundColorListener = backgroundColorListener; + + % Set Spacing property to 5 (may be overwritten by uix.set) + obj.Spacing = 5; + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods + + function value = get.DividerMarkings( obj ) + + value = obj.DividerMarkings_; + + end % get.DividerMarkings + + function set.DividerMarkings( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''DividerMarkings'' must be ''on'' or ''off'.' ) + + % Set + obj.DividerMarkings_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.DividerMarkings + + end % accessors + + methods( Access = protected ) + + function onMousePress( obj, source, eventData ) + %onMousePress Handler for WindowMousePress events + + % Check whether mouse is over a divider + loc = find( obj.RowDividers.isMouseOver( eventData ) ); + if isempty( loc ), return, end + + % Capture state at button down + divider = obj.RowDividers(loc); + obj.ActiveDivider = loc; + obj.ActiveDividerPosition = divider.Position; + root = groot(); + obj.MousePressLocation = root.PointerLocation; + + % Make sure the pointer is appropriate + obj.updateMousePointer( source, eventData ); + + % Activate divider + frontDivider = obj.FrontDivider; + frontDivider.Position = divider.Position; + divider.Visible = 'off'; + frontDivider.Parent = []; + frontDivider.Parent = obj; + frontDivider.Visible = 'on'; + + end % onMousePress + + function onMouseRelease( obj, ~, ~ ) + %onMousePress Handler for WindowMouseRelease events + + % Compute new positions + loc = obj.ActiveDivider; + if loc > 0 + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + divider = obj.RowDividers(loc); + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelHeights = [ip(4); jp(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + oldHeights = obj.Heights_(loc:loc+1); + newPixelHeights = oldPixelHeights - delta * [1;-1]; + if oldHeights(1) < 0 && oldHeights(2) < 0 % weight, weight + newHeights = oldHeights .* newPixelHeights ./ oldPixelHeights; + elseif oldHeights(1) < 0 && oldHeights(2) >= 0 % weight, pixels + newHeights = [oldHeights(1) * newPixelHeights(1) / ... + oldPixelHeights(1); newPixelHeights(2)]; + elseif oldHeights(1) >= 0 && oldHeights(2) < 0 % pixels, weight + newHeights = [newPixelHeights(1); oldHeights(2) * ... + newPixelHeights(2) / oldPixelHeights(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newHeights = newPixelHeights; + end + obj.Heights_(loc:loc+1) = newHeights; + else + return + end + + % Deactivate divider + obj.FrontDivider.Visible = 'off'; + divider.Visible = 'on'; + + % Reset state at button down + obj.ActiveDivider = 0; + obj.ActiveDividerPosition = [NaN NaN NaN NaN]; + obj.MousePressLocation = [NaN NaN]; + + % Mark as dirty + obj.Dirty = true; + + end % onMouseRelease + + function onMouseMotion( obj, source, eventData ) + %onMouseMotion Handler for WindowMouseMotion events + + loc = obj.ActiveDivider; + if loc == 0 % hovering, update pointer + obj.updateMousePointer( source, eventData ); + else % dragging row divider + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + contents = obj.Contents_; + ip = uix.getPosition( contents(ic), 'pixels' ); + jp = uix.getPosition( contents(jc), 'pixels' ); + oldPixelHeights = [ip(4); jp(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [0 delta 0 0]; + end + + end % onMouseMotion + + function onBackgroundColorChanged( obj, ~, ~ ) + %onBackgroundColorChanged Handler for BackgroundColor changes + + backgroundColor = obj.BackgroundColor; + highlightColor = min( [backgroundColor / 0.75; 1 1 1] ); + shadowColor = max( [backgroundColor * 0.75; 0 0 0] ); + rowDividers = obj.RowDividers; + for ii = 1:numel( rowDividers ) + rowDivider = rowDividers(ii); + rowDivider.BackgroundColor = backgroundColor; + rowDivider.HighlightColor = highlightColor; + rowDivider.ShadowColor = shadowColor; + end + frontDivider = obj.FrontDivider; + frontDivider.BackgroundColor = shadowColor; + + end % onBackgroundColorChanged + + end % event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw contents + % + % c.redraw() redraws the container c. + + % Call superclass method + redraw@uix.VBox( obj ) + + % Create or destroy row dividers + q = numel( obj.RowDividers ); % current number of dividers + r = max( [numel( obj.Heights_ )-1 0] ); % required number of dividers + if q < r % create + for ii = q+1:r + divider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'horizontal', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.RowDividers(ii,:) = divider; + end + elseif q > r % destroy + % Destroy dividers + delete( obj.RowDividers(r+1:q,:) ) + obj.RowDividers(r+1:q,:) = []; + % Update pointer + if r == 0 && strcmp( obj.Pointer, 'top' ) + obj.unsetPointer() + end + end + + % Compute container bounds + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + + % Retrieve size properties + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + + % Compute row divider positions + xRowPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )]; + xRowPositions = repmat( xRowPositions, [r 1] ); + yRowSizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yRowPositions = [bounds(4) - cumsum( yRowSizes(1:r,:) ) - padding - ... + spacing * transpose( 1:r ) + 1, repmat( spacing, [r 1] )]; + rowPositions = [xRowPositions(:,1), yRowPositions(:,1), ... + xRowPositions(:,2), yRowPositions(:,2)]; + + % Position row dividers + for ii = 1:r + rowDivider = obj.RowDividers(ii); + rowDivider.Position = rowPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + rowDivider.Markings = rowPositions(ii,3)/2; + case 'off' + rowDivider.Markings = zeros( [0 1] ); + end + end + + end % redraw + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + % Update listeners + if isempty( newFigure ) + mousePressListener = event.listener.empty( [0 0] ); + mouseReleaseListener = event.listener.empty( [0 0] ); + mouseMotionListener = event.listener.empty( [0 0] ); + else + mousePressListener = event.listener( newFigure, ... + 'WindowMousePress', @obj.onMousePress ); + mouseReleaseListener = event.listener( newFigure, ... + 'WindowMouseRelease', @obj.onMouseRelease ); + mouseMotionListener = event.listener( newFigure, ... + 'WindowMouseMotion', @obj.onMouseMotion ); + end + obj.MousePressListener = mousePressListener; + obj.MouseReleaseListener = mouseReleaseListener; + obj.MouseMotionListener = mouseMotionListener; + + % Call superclass method + reparent@uix.VBox( obj, oldFigure, newFigure ) + + % Update pointer + if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % reparent + + end % template methods + + methods( Access = protected ) + + function updateMousePointer ( obj, source, eventData ) + + oldPointer = obj.Pointer; + if any( obj.RowDividers.isMouseOver( eventData ) ) + newPointer = 'top'; + else + newPointer = 'unset'; + end + switch newPointer + case oldPointer % no change + % do nothing + case 'unset' % change, unset + obj.unsetPointer() + otherwise % change, set + obj.setPointer( source, newPointer ) + end + + end % updateMousePointer + + end % helpers methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/VButtonBox.m b/studio_functions/GUI Layout Toolbox/layout/+uix/VButtonBox.m new file mode 100644 index 00000000..1f32d500 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/VButtonBox.m @@ -0,0 +1,93 @@ +classdef VButtonBox < uix.ButtonBox + %uix.VButtonBox Vertical button box + % + % b = uix.VButtonBox(p1,v1,p2,v2,...) constructs a vertical button box + % and sets parameter p1 to value v1, etc. + % + % A vertical button box lays out equally sized buttons from top to + % bottom. + % + % See also: uix.HButtonBox + + % Copyright 2009-2020 The MathWorks, Inc. + + methods + + function obj = VButtonBox( varargin ) + %uix.VButtonBox Vertical button box constructor + % + % b = uix.VButtonBox() constructs a vertical button box. + % + % b = uix.VButtonBox(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + try + uix.set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + buttonSize = obj.ButtonSize_; + padding = obj.Padding_; + spacing = obj.Spacing_; + r = numel( obj.Contents_ ); + if 2 * padding + buttonSize(1) > bounds(3) + xSizes = repmat( uix.calcPixelSizes( bounds(3), -1, 1, ... + padding, spacing ), [r 1] ); % shrink to fit + else + xSizes = repmat( buttonSize(1), [r 1] ); + end + switch obj.HorizontalAlignment + case 'left' + xPositions = [repmat( padding, [r 1] ) + 1, xSizes]; + case 'center' + xPositions = [(bounds(3) - xSizes) / 2 + 1, xSizes]; + case 'right' + xPositions = [bounds(3) - xSizes - padding + 1, xSizes]; + end + if 2 * padding + (r-1) * spacing + r * buttonSize(2) > bounds(4) + ySizes = uix.calcPixelSizes( bounds(4), -ones( [r 1] ), ... + ones( [r 1] ), padding, spacing ); % shrink to fit + else + ySizes = repmat( buttonSize(2), [r 1] ); + end + switch obj.VerticalAlignment + case 'top' + yPositions = [bounds(4) - padding - cumsum( ySizes ) - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + case 'middle' + yPositions = [bounds(4) / 2 + sum( ySizes ) / 2 + ... + spacing * (r-1) / 2 - cumsum( ySizes ) - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + case 'bottom' + yPositions = [sum( ySizes ) + spacing * (r-1) - ... + cumsum( ySizes ) - spacing * transpose( 0:r-1 ) + ... + padding + 1, ySizes]; + end + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/calcPixelSizes.m b/studio_functions/GUI Layout Toolbox/layout/+uix/calcPixelSizes.m new file mode 100644 index 00000000..24b35e7b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/calcPixelSizes.m @@ -0,0 +1,46 @@ +function pSizes = calcPixelSizes( pTotal, mSizes, pMinima, pPadding, pSpacing ) +%calcPixelSizes Calculate child sizes in pixels +% +% pSizes = uix.calcPixelSizes(total,mSizes,minSizes,padding,spacing) +% computes child sizes (in pixels) given total available size (in pixels), +% child sizes (in pixels and/or relative), minimum child sizes (in +% pixels), padding (in pixels) and spacing (in pixels). +% +% Notes: +% * All children are at least as large as the minimum specified size +% * Relative sizes are respected for children larger than then minimum +% specified size +% * Children may extend beyond the total available size if the minimum +% sizes, padding and spacing are too large + +% Copyright 2009-2020 The MathWorks, Inc. + +% Initialize +pSizes = NaN( size( mSizes ) ); % output +n = numel( mSizes ); % need this later + +% Apply absolute sizes +a = mSizes >= 0; % absolute +pSizes(a) = max( mSizes(a), pMinima(a) ); + +while true + + u = isnan( pSizes ); % unsolved + pUnsolvedTotal = pTotal - max( (n-1), 0 ) * pSpacing ... + - 2 * sign( n ) * pPadding - sum( pSizes(~u) ); + pUnsolvedSizes = mSizes(u) / sum( mSizes(u) ) * pUnsolvedTotal; + pUnsolvedMinima = pMinima(u); + s = pUnsolvedSizes < pUnsolvedMinima; % small + if any( s ) + pUnsolvedSizes(s) = pUnsolvedMinima(s); + pUnsolvedSizes(~s) = NaN; + pSizes(u) = pUnsolvedSizes; + % repeat + else + pSizes(u) = pUnsolvedSizes; + break % done + end + +end + +end % calcPixelSizes \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/getPosition.m b/studio_functions/GUI Layout Toolbox/layout/+uix/getPosition.m new file mode 100644 index 00000000..bd9cb608 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/getPosition.m @@ -0,0 +1,42 @@ +function p = getPosition( o, u ) +%getPosition Get position of graphics object +% +% p = getPosition(o,u) sets the position of a graphics object o with units +% u. +% +% In contrast to getting the Position property directly, this function +% honors the ActivePositionProperty of axes. + +% Copyright 2009-2020 The MathWorks, Inc. + +% Get position +if ~isempty( findprop( o, 'ActivePositionProperty' ) ) + switch o.ActivePositionProperty + case 'position' + q = o.Position; + case 'outerposition' + q = o.OuterPosition; + otherwise + error( 'uix:InvalidState', ... + 'Unknown value ''%s'' for property ''ActivePositionProperty'' of %s.', ... + o.ActivePositionProperty, class( o ) ) + end +else + q = o.Position; +end + +% Get units +if ~isempty( findprop( o, 'Units' ) ) + v = o.Units; +else + v = 'pixels'; +end + +% Convert +if strcmp( u, v ) % trivial + p = q; +else % conversion required + p = hgconvertunits( ancestor( o, 'figure' ), q, v, u, o.Parent ); +end + +end % getPosition \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/loadIcon.m b/studio_functions/GUI Layout Toolbox/layout/+uix/loadIcon.m new file mode 100644 index 00000000..607c1d24 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/loadIcon.m @@ -0,0 +1,101 @@ +function cdata = loadIcon( filename, bgcol ) +%loadIcon Load an icon and set the transparent color +% +% cdata = uix.loadIcon(filename) loads the icon from the specified +% filename. For PNG files with transparency, the transparent pixels are +% set to NaN. For other files, pixels that are pure green are set to +% transparent (i.e., "green screen"). The resulting cdata is an RGB +% double array. +% +% cdata = uix.loadIcon(filename,bgcol) tries to merge the color data with +% the specified background colour bgcol. Fully transparent pixels are +% still set to NaN, but partially transparent pixels are merged with the +% background. +% +% See also: imread + +% Copyright 2009-2020 The MathWorks, Inc. + +% Check inputs +narginchk( 1, 2 ) +if nargin < 2 + bgcol = get( 0, 'DefaultUIControlBackgroundColor' ); +end + +% First try normally +thisDir = fileparts( mfilename( 'fullpath' ) ); +iconDir = fullfile( thisDir, 'Resources' ); +if exist( filename, 'file' ) + [cdata, map, alpha] = imread( filename ); +elseif exist( fullfile( iconDir, filename ), 'file' ) + [cdata, map, alpha] = imread( fullfile( iconDir, filename ) ); +else + error( 'uix:FileNotFound', 'Cannot open file ''%s''.', filename ) +end + +% Convert indexed images to RGB +if ~isempty( map ) + cdata = ind2rgb( cdata, map ); +end + +% Convert to double before applying transparency +cdata = convertToDouble( cdata ); + +% Handle transparency +[rows, cols, ~] = size( cdata ); +if ~isempty( alpha ) + + % Transparency specified + alpha = convertToDouble( alpha ); + f = find( alpha==0 ); + if ~isempty( f ) + cdata(f) = NaN; + cdata(f + rows*cols) = NaN; + cdata(f + 2*rows*cols) = NaN; + end + % Now blend partial alphas + f = find( alpha(:)>0 & alpha(:)<1 ); + if ~isempty(f) + cdata(f) = cdata(f).*alpha(f) + bgcol(1)*(1-alpha(f)); + cdata(f + rows*cols) = cdata(f + rows*cols).*alpha(f) + bgcol(2)*(1-alpha(f)); + cdata(f + 2*rows*cols) = cdata(f + 2*rows*cols).*alpha(f) + bgcol(3)*(1-alpha(f)); + end + +else + + % Do a "green screen", treating anything pure-green as transparent + f = find( cdata(:,:,1)==0 & cdata(:,:,2)==1 & cdata(:,:,3)==0 ); + cdata(f) = NaN; + cdata(f + rows*cols) = NaN; + cdata(f + 2*rows*cols) = NaN; + +end + +end % uix.loadIcon + +% ------------------------------------------------------------------------- + +function cdata = convertToDouble( cdata ) +%convertToDouble Convert image data to double in the range [0,1] +% +% cdata = convertToDouble(cData) + +switch lower( class( cdata ) ) + case 'double' + % do nothing + case 'single' + cdata = double( cdata ); + case 'uint8' + cdata = double( cdata ) / 255; + case 'uint16' + cdata = double( cdata ) / 65535; + case 'int8' + cdata = ( double( cdata ) + 128 ) / 255; + case 'int16' + cdata = ( double( cdata ) + 32768 ) / 65535; + otherwise + error( 'uix:InvalidArgument', ... + 'Image data of type ''%s'' is not supported.', class( cdata ) ) +end + +end % convertToDouble \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/set.m b/studio_functions/GUI Layout Toolbox/layout/+uix/set.m new file mode 100644 index 00000000..9c54979c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/set.m @@ -0,0 +1,16 @@ +function set( obj, varargin ) +%uix.set Set property values +% +% uix.set(o,p1,v1,p2,v2,...) sets property p1 of the object o to value v1, +% property p2 to value v2, etc. +% +% In contrast to builtin set, querying possible values is not supported. + +% Copyright 2009-2020 The MathWorks, Inc. + +if nargin == 1, return, end +assert( rem( nargin, 2 ) == 1, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) +set( obj, varargin{:} ) + +end % set \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/setPosition.m b/studio_functions/GUI Layout Toolbox/layout/+uix/setPosition.m new file mode 100644 index 00000000..e493bf77 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/setPosition.m @@ -0,0 +1,36 @@ +function setPosition( o, p, u ) +%setPosition Set position of graphics object +% +% setPosition(o,p,u) sets the position of a graphics object o to value p +% with units u. +% +% In contrast to setting the Position property directly, this function +% honors the ActivePositionProperty of axes. + +% Copyright 2009-2020 The MathWorks, Inc. + +% Set units +if ~isempty( findprop( o, 'Units' ) ) + o.Units = u; +else + assert( strcmp( u, 'pixels' ), 'uix:InvalidOperation', ... + 'Objects without property ''Units'' have units of ''pixels''.' ) +end + +% Set position +if ~isempty( findprop( o, 'ActivePositionProperty' ) ) + switch o.ActivePositionProperty + case 'position' + o.Position = p; + case 'outerposition' + o.OuterPosition = p; + otherwise + error( 'uix:InvalidState', ... + 'Unknown value ''%s'' for property ''ActivePositionProperty'' of %s.', ... + o.ActivePositionProperty, class( o ) ) + end +else + o.Position = p; +end + +end % setPosition \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/+uix/tracking.m b/studio_functions/GUI Layout Toolbox/layout/+uix/tracking.m new file mode 100644 index 00000000..84eaee14 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/+uix/tracking.m @@ -0,0 +1,228 @@ +function varargout = tracking( varargin ) +%tracking Track anonymized usage data +% +% tracking(p,v,id) tracks usage to the property p for the product version +% v and identifier id. No personally identifiable information is tracked. +% +% r = tracking(...) returns the server response r, for debugging purposes. +% +% tracking('on') turns tracking on. tracking('off') turns tracking off. +% tracking('query') returns the tracking state. + +% tracking('spoof') sets the tracking settings -- domain, language, +% client, MATLAB version, operating system version -- to spoof values. +% tracking('reset') sets the tracking settings to normal values. +% +% [t,s] = tracking('query') returns the tracking state t and settings s. + +% Copyright 2009-2020 The MathWorks, Inc. + +persistent STATE USERNAME DOMAIN LANGUAGE CLIENT MATLAB OS +if isempty( STATE ) + STATE = getpref( 'Tracking', 'State', 'on' ); + if strcmp( STATE, 'snooze' ) % deprecated + setpref( 'Tracking', 'State', 'on' ) + STATE = 'on'; + end + if ispref( 'Tracking', 'Date' ) % deprecated + rmpref( 'Tracking', 'Date' ) + end + USERNAME = getenv( 'USERNAME' ); + reset() +end % initialize + +switch nargin + case 1 + switch varargin{1} + case {'on','off'} + STATE = varargin{1}; + setpref( 'Tracking', 'State', varargin{1} ) % persist + case 'spoof' + spoof() + case 'reset' + reset() + case 'query' + varargout{1} = STATE; + varargout{2} = query(); + otherwise + error( 'tracking:InvalidArgument', ... + 'Valid options are ''on'', ''off'' and ''query''.' ) + end + case 3 + switch nargout + case 0 + if strcmp( STATE, 'off' ), return, end + uri = 'https://www.google-analytics.com/collect'; + track( uri, varargin{:} ); + case 1 + uri = 'https://www.google-analytics.com/debug/collect'; + varargout{1} = track( uri, varargin{:} ); + otherwise + nargoutchk( 0, 1 ) + end + otherwise + narginchk( 3, 3 ) +end % switch + + function reset() + %reset Set normal settings + + DOMAIN = lower( getenv( 'USERDOMAIN' ) ); + LANGUAGE = char( java.util.Locale.getDefault() ); + CLIENT = getpref( 'Tracking', 'Client', uuid() ); + MATLAB = matlab(); + OS = os(); + + end % reset + + function spoof() + %spoof Set spoof settings + + DOMAIN = randomDomain(); + LANGUAGE = randomLanguage(); + CLIENT = randomClient(); + MATLAB = randomMatlab(); + OS = randomOs(); + + end % spoof + + function s = query() + %query Return settings + + s.Username = USERNAME; + s.Domain = DOMAIN; + s.Language = LANGUAGE; + s.Client = CLIENT; + s.Matlab = MATLAB; + s.Os = OS; + + end % query + + function varargout = track( uri, p, v, s ) + %track Do tracking + + a = sprintf( '%s/%s (%s)', MATLAB, v, OS ); + if isdeployed() + ds = 'deployed'; + elseif strcmp( DOMAIN, 'mathworks' ) + ds = DOMAIN; + else + ds = 'unknown'; + end + pv = {'v', '1', 'tid', p, 'ua', escape( a ), 'ul', LANGUAGE, ... + 'cid', CLIENT, 'ht', 'pageview', ... + 'dp', sprintf( '/%s', s ), 'ds', ds}; + [varargout{1:nargout}] = urlread( uri, 'Post', pv ); + + end % track + +end % tracking + +function s = randomDomain() +%randomDomain Random domain string + +switch randi( 4 ) + case 1 + s = 'mathworks'; + otherwise + s = hash( uuid() ); +end + +end % randomDomain + +function s = randomLanguage() +%randomLanguage Random language string + +lo = java.util.Locale.getAvailableLocales(); +s = char( lo(randi( numel( lo ) )) ); + +end % randomLanguage + +function s = randomClient() +%randomClient Random client identifier + +s = uuid(); + +end % randomClient + +function s = matlab() +%matlab MATLAB version string + +v = ver( 'MATLAB' ); +s = v.Release; +s(s=='('|s==')') = []; + +end % matlab + +function s = randomMatlab() +%randomMatlab Random MATLAB version string + +releases = {'R2014b' 'R2015a' 'R2015b' 'R2016a' 'R2016b'}; +s = releases{randi( numel( releases ) )}; + +end % randomMatlab + +function s = os() +%os Operating system string + +if ispc() + s = sprintf( 'Windows NT %s', ... + char( java.lang.System.getProperty( 'os.version' ) ) ); +elseif isunix() + s = 'Linux x86_64'; +elseif ismac() + s = sprintf( 'Macintosh; Intel OS X %s', ... + strrep( char( java.lang.System.getProperty( 'os.version' ) ), ' ', '_' ) ); +else + s = 'unknown'; +end + +end % os + +function s = randomOs() +%randomOs Random operating system string + +switch randi( 3 ) + case 1 + versions = [5.1 5.2 6 6.1 6.2 6.3 10]; + s = sprintf( 'Windows NT %.1f', ... + versions(randi( numel( versions ) )) ); + case 2 + s = 'Linux x86_64'; + case 3 + s = sprintf( 'Macintosh; Intel OS X 10_%d', ... + randi( [10 12] ) ); +end + +end % randomOs + +function s = escape( s ) +%escape Escape string + +s = char( java.net.URLEncoder.encode( s, 'UTF-8' ) ); + +end % escape + +function h = hash( s ) +%hash Hash string +% +% See also: rptgen.hash + +persistent MD5 +if isempty( MD5 ) + MD5 = java.security.MessageDigest.getInstance( 'MD5' ); +end + +MD5.update( uint8( s(:) ) ); +h = typecast( MD5.digest, 'uint8' ); +h = dec2hex( h )'; +h = lower( h(:) )'; + +end % hash + +function s = uuid() +%uuid Unique identifier + +s = char( java.util.UUID.randomUUID() ); + +end % uuid \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layout/Contents.m b/studio_functions/GUI Layout Toolbox/layout/Contents.m new file mode 100644 index 00000000..42a7f207 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/Contents.m @@ -0,0 +1,27 @@ +% GUI Layout Toolbox +% Version 2.3.5 (R2020b) 31-October-2020 +% +% Panels +% uix.Panel - arrange a single element inside a standard panel +% uix.CardPanel - show one element from a list +% uix.BoxPanel - arrange a single element inside a panel with a boxed title +% uix.TabPanel - arrange elements in a panel with tabs for selecting which is visible +% uix.ScrollingPanel - arrange a single element inside a scrollable panel +% +% Boxes +% uix.HBox - arrange elements horizontally in a single row +% uix.VBox - arrange elements vertically in a single column +% uix.HBoxFlex - arrange elements horizontally with draggable dividers +% uix.VBoxFlex - arrange elements vertically with draggable dividers +% uix.HButtonBox - arrange buttons horizontally in a single row +% uix.VButtonBox - arrange buttons vertically in a single column +% +% Grids +% uix.Grid - arrange elements in a two-dimensional grid +% uix.GridFlex - arrange elements in a two-dimensional grid with draggable dividers +% +% Other +% uix.Empty - create an empty space +% uix.tracking - track anonymized usage data + +% Copyright 2009-2020 The MathWorks, Inc. diff --git a/studio_functions/GUI Layout Toolbox/layout/layoutRoot.m b/studio_functions/GUI Layout Toolbox/layout/layoutRoot.m new file mode 100644 index 00000000..f9726478 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layout/layoutRoot.m @@ -0,0 +1,17 @@ +function folder = layoutRoot() +%layoutRoot Folder containing the GUI Layout Toolbox +% +% folder = layoutRoot() returns the full path to the folder containing +% the GUI Layout Toolbox. +% +% Examples: +% >> folder = layoutRoot() +% folder = 'C:\tools\layouts2\layout' +% +% See also: layoutVersion + +% Copyright 2009-2020 The MathWorks, Inc. + +folder = fileparts( mfilename( 'fullpath' ) ); + +end % layoutRoot \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/AxesExample.html b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesExample.html new file mode 100644 index 00000000..9190c604 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesExample.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/AxesLegendsColorbars.html b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesLegendsColorbars.html new file mode 100644 index 00000000..3b8e3b36 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/AxesLegendsColorbars.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/BoxPanelFancyStuff.html b/studio_functions/GUI Layout Toolbox/layoutdoc/BoxPanelFancyStuff.html new file mode 100644 index 00000000..ade0fa6a --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/BoxPanelFancyStuff.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Compiling.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Compiling.html new file mode 100644 index 00000000..5e762277 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Compiling.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/ExampleApp.html b/studio_functions/GUI Layout Toolbox/layoutdoc/ExampleApp.html new file mode 100644 index 00000000..4dfbaa5f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/ExampleApp.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples.html new file mode 100644 index 00000000..51160f2d --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples.html @@ -0,0 +1,88 @@ + + + + + + + + Examples + + + + + + + + + + + +
GUI Layout Toolbox 2.3.5previous pagenext page
+ +

Examples Go back up one level

+ +

The following examples are provided as part of this documentation. Click + the name of any example to go to the corresponding page.

+ +

Basics

+
+
Layout hierarchy
+
Using layouts inside layouts to produce more complex designs
+
+ +

Using axes

+
+
Positioning axes
+
Using the different axes position properties.
+ +
Axes legends and colorbars
+
How to work with axes that may also have legends and/or colorbars.
+
+ +

Using panels

+
+
Context help
+
Adding context-sensitive help using panels.
+ +
Minimize and maximize
+
Creating a user interface with panels that can be minimized and + maximized.
+ +
Dock and undock
+
Creating a user interface with panels that can be undocked into + separate windows.
+
+ +

Visible

+
+
Show and hide
+
Showing and hiding a layout and its contents.
+
+ +

Applications

+
+
Building a complete application
+
Using layouts together to produce a complete application.
+
+ + +
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/axesexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/axesexample.m new file mode 100644 index 00000000..aaf49542 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/axesexample.m @@ -0,0 +1,41 @@ +%% Axes inside layouts +% This example demonstrates how axes are affected by being placed into +% layouts. The layouts take into account the "ActivePositionProperty" in +% order to determine whether to set the "Position" or "OuterPosition" +% (default) property of the axes. + +% Copyright 2009-2020 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'Axes inside layouts', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off' ); + +%% Create the layout +% The layout involves two axes side by side. This is done using a +% flexible horizontal box. The left-hand axes is left with the +% ActivePositionProperty set to "outerposition", but the right-hand axes is +% switched to use "Position" +hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3); +axes1 = axes( 'Parent', hbox, ... + 'ActivePositionProperty', 'outerposition' ); +axes2 = axes( 'Parent', hbox, ... + 'ActivePositionProperty', 'Position' ); +set( hbox, 'Widths', [-2 -1] ); + +%% Fill the axes +% Using "OuterPosition" (left-hand axes) is the normal mode and looks good +% for virtually any plot type. Using "Position" is only really useful for +% 2D plots with the axes turned off, such as images +x = membrane( 1, 15 ); +surf( axes1, x ); +lighting( axes1, 'gouraud' ); +shading( axes1, 'interp' ); +l = light( 'Parent', axes1 ); +camlight( l, 'head' ); +axis( axes1, 'tight' ); + +imagesc( x, 'Parent', axes2 ); +set( axes2, 'xticklabel', [], 'yticklabel', [] ); \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/callbackexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/callbackexample.m new file mode 100644 index 00000000..415aa47b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/callbackexample.m @@ -0,0 +1,47 @@ +function callbackexample() + +% Copyright 2009-2020 The MathWorks, Inc. + +% Create application data +colorNames = { + 'Red' + 'Orange' + 'Yellow' + 'Green' + 'Blue' + 'Indigo' + 'Violet' + }; +colorValues = [ + 1.0 0.2 0.2 + 1.0 0.6 0.2 + 1.0 1.0 0.4 + 0.6 1.0 0.6 + 0.2 0.4 1.0 + 0.4 0.1 0.6 + 0.7 0.5 1.0 + ]; + +% Layout the interface +f = figure(); +p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'TitlePosition', 'CenterTop'); +b = uix.HBoxFlex( 'Parent', p, 'Spacing', 5, 'Padding', 5 ); +hList = uicontrol( 'Style', 'listbox', 'Parent', b, ... + 'String', colorNames, ... + 'Back', 'w' ); +hButton = uicontrol( 'Parent', b, ... + 'Background', colorValues(1,:), ... + 'String', colorNames{1} ); +set( b, 'Widths', [-1 -3] ); + +% Add user interactions +set( hList, 'Callback', @onChangeColor ); + + + function onChangeColor( source, ~ ) + idx = get( source, 'Value' ); + set( hButton, 'Background', colorValues(idx,:), 'String', colorNames{idx} ) + end % onChangeColor + + +end % main \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/colorbarexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/colorbarexample.m new file mode 100644 index 00000000..d873c690 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/colorbarexample.m @@ -0,0 +1,29 @@ +%% Axes with colorbars inside layouts +% This example demonstrates how to correctly layout axes that have +% associated legends or colorbars by grouping them together using a +% uicontainer. + +% Copyright 2009-2020 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'Axes legend and colorbars', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off' ); + +%% Create the layout +% The layout involves two axes side by side. Each axes is placed into a +% uicontainer so that the legend and colorbar are "grouped" with the axes. +hbox = uix.VBoxFlex('Parent', window, 'Spacing', 3); +axes1 = axes( 'Parent', uicontainer('Parent', hbox) ); +axes2 = axes( 'Parent', uicontainer('Parent', hbox) ); + +%% Add decorations +% Give the first axes a colorbar and the second axes a legend. +surf( axes1, membrane( 1, 15 ) ); +colorbar( axes1 ); + +theta = 0:360; +plot( axes2, theta, sind(theta), theta, cosd(theta) ); +legend( axes2, 'sin', 'cos', 'Location', 'NorthWestOutside' ); \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/demoBrowser.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/demoBrowser.m new file mode 100644 index 00000000..3d2b17da --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/demoBrowser.m @@ -0,0 +1,209 @@ +function demoBrowser() +%demoBrowser: an example of using layouts to build a user interface +% +% demoBrowser() opens a simple GUI that allows several of MATLAB's +% built-in demos to be viewed. It aims to demonstrate how multiple +% layouts can be used to create a good-looking user interface that +% retains the correct proportions when resized. It also shows how to +% hook-up callbacks to interpret user interaction. +% +% See also: Layouts + +% Copyright 2009-2020 The MathWorks, Inc. + +% Data is shared between all child functions by declaring the variables +% here (they become global to the function). We keep things tidy by putting +% all GUI stuff in one structure and all data stuff in another. As the app +% grows, we might consider making these objects rather than structures. +data = createData(); +gui = createInterface( data.DemoNames ); + +% Now update the GUI with the current data +updateInterface(); +redrawDemo(); + +% Explicitly call the demo display so that it gets included if we deploy +displayEndOfDemoMessage('') + +%-------------------------------------------------------------------------% + function data = createData() + % Create the shared data-structure for this application + demoList = { + 'Complex surface' 'cplxdemo' + 'Cruller' 'cruller' + 'Earth' 'earthmap' + 'Four linked tori' 'tori4' + 'Klein bottle' 'xpklein' + 'Klein bottle (1)' 'klein1' + 'Knot' 'knot' + 'Logo' 'logo' + 'Spherical Surface Harmonic' 'spharm2' + 'Werner Boy''s Surface' 'wernerboy' + }; + selectedDemo = 8; + data = struct( ... + 'DemoNames', {demoList(:,1)'}, ... + 'DemoFunctions', {demoList(:,2)'}, ... + 'SelectedDemo', selectedDemo ); + end % createData + +%-------------------------------------------------------------------------% + function gui = createInterface( demoList ) + % Create the user interface for the application and return a + % structure of handles for global use. + gui = struct(); + % Open a window and add some menus + gui.Window = figure( ... + 'Name', 'Gallery browser', ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off' ); + + % + File menu + gui.FileMenu = uimenu( gui.Window, 'Label', 'File' ); + uimenu( gui.FileMenu, 'Label', 'Exit', 'Callback', @onExit ); + + % + View menu + gui.ViewMenu = uimenu( gui.Window, 'Label', 'View' ); + for ii=1:numel( demoList ) + uimenu( gui.ViewMenu, 'Label', demoList{ii}, 'Callback', @onMenuSelection ); + end + + % + Help menu + helpMenu = uimenu( gui.Window, 'Label', 'Help' ); + uimenu( helpMenu, 'Label', 'Documentation', 'Callback', @onHelp ); + + + % Arrange the main interface + mainLayout = uix.HBoxFlex( 'Parent', gui.Window, 'Spacing', 3 ); + + % + Create the panels + controlPanel = uix.BoxPanel( ... + 'Parent', mainLayout, ... + 'Title', 'Select a demo:' ); + gui.ViewPanel = uix.BoxPanel( ... + 'Parent', mainLayout, ... + 'Title', 'Viewing: ???', ... + 'HelpFcn', @onDemoHelp ); + gui.ViewContainer = uicontainer( ... + 'Parent', gui.ViewPanel ); + + % + Adjust the main layout + set( mainLayout, 'Widths', [-1,-2] ); + + + % + Create the controls + controlLayout = uix.VBox( 'Parent', controlPanel, ... + 'Padding', 3, 'Spacing', 3 ); + gui.ListBox = uicontrol( 'Style', 'list', ... + 'BackgroundColor', 'w', ... + 'Parent', controlLayout, ... + 'String', demoList(:), ... + 'Value', 1, ... + 'Callback', @onListSelection); + gui.HelpButton = uicontrol( 'Style', 'PushButton', ... + 'Parent', controlLayout, ... + 'String', 'Help for ', ... + 'Callback', @onDemoHelp ); + set( controlLayout, 'Heights', [-1 28] ); % Make the list fill the space + + % + Create the view + p = gui.ViewContainer; + gui.ViewAxes = axes( 'Parent', p ); + + + end % createInterface + +%-------------------------------------------------------------------------% + function updateInterface() + % Update various parts of the interface in response to the demo + % being changed. + + % Update the list and menu to show the current demo + set( gui.ListBox, 'Value', data.SelectedDemo ); + % Update the help button label + demoName = data.DemoNames{ data.SelectedDemo }; + set( gui.HelpButton, 'String', ['Help for ',demoName] ); + % Update the view panel title + set( gui.ViewPanel, 'Title', sprintf( 'Viewing: %s', demoName ) ); + % Untick all menus + menus = get( gui.ViewMenu, 'Children' ); + set( menus, 'Checked', 'off' ); + % Use the name to work out which menu item should be ticked + whichMenu = strcmpi( demoName, get( menus, 'Label' ) ); + set( menus(whichMenu), 'Checked', 'on' ); + end % updateInterface + +%-------------------------------------------------------------------------% + function redrawDemo() + % Draw a demo into the axes provided + + % We first clear the existing axes ready to build a new one + if ishandle( gui.ViewAxes ) + delete( gui.ViewAxes ); + end + + % Some demos create their own figure. Others don't. + fcnName = data.DemoFunctions{data.SelectedDemo}; + switch upper( fcnName ) + case 'LOGO' + % These demos open their own windows + evalin( 'base', fcnName ); + gui.ViewAxes = gca(); + fig = gcf(); + set( fig, 'Visible', 'off' ); + + otherwise + % These demos need a window opening + fig = figure( 'Visible', 'off' ); + evalin( 'base', fcnName ); + gui.ViewAxes = gca(); + end + % Now copy the axes from the demo into our window and restore its + % state. + cmap = colormap( gui.ViewAxes ); + set( gui.ViewAxes, 'Parent', gui.ViewContainer ); + colormap( gui.ViewAxes, cmap ); + rotate3d( gui.ViewAxes, 'on' ); + % Get rid of the demo figure + close( fig ); + end % redrawDemo + +%-------------------------------------------------------------------------% + function onListSelection( src, ~ ) + % User selected a demo from the list - update "data" and refresh + data.SelectedDemo = get( src, 'Value' ); + updateInterface(); + redrawDemo(); + end % onListSelection + +%-------------------------------------------------------------------------% + function onMenuSelection( src, ~ ) + % User selected a demo from the menu - work out which one + demoName = get( src, 'Label' ); + data.SelectedDemo = find( strcmpi( demoName, data.DemoNames ), 1, 'first' ); + updateInterface(); + redrawDemo(); + end % onMenuSelection + + +%-------------------------------------------------------------------------% + function onHelp( ~, ~ ) + % User has asked for the documentation + doc layout + end % onHelp + +%-------------------------------------------------------------------------% + function onDemoHelp( ~, ~ ) + % User wnats documentation for the current demo + showdemo( data.DemoFunctions{data.SelectedDemo} ); + end % onDemoHelp + +%-------------------------------------------------------------------------% + function onExit( ~, ~ ) + % User wants to quit out of the application + delete( gui.Window ); + end % onExit + +end % EOF \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/displayEndOfDemoMessage.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/displayEndOfDemoMessage.m new file mode 100644 index 00000000..cd1ef215 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/displayEndOfDemoMessage.m @@ -0,0 +1,4 @@ +function displayEndOfDemoMessage(filename) +% Dummy function - do nothing. + +% Copyright 2009-2020 The MathWorks, Inc. diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/dockexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/dockexample.m new file mode 100644 index 00000000..a03aef78 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/dockexample.m @@ -0,0 +1,74 @@ +function dockexample() +%DOCKEXAMPLE: An example of using the panelbox dock/undock functionality + +% Copyright 2009-2020 The MathWorks, Inc. + +% Create the window and main layout +fig = figure( 'Name', 'Dockable GUI example', ...' + 'NumberTitle', 'off', ... + 'Toolbar', 'none', ... + 'MenuBar', 'none', ... + 'CloseRequestFcn', @nCloseAll ); +box = uix.HBox( 'Parent', fig ); + +% Add three panels to the box +panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box ); +panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box ); +panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box ); + +% Add some contents +uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); +box1 = uix.VBox( 'Parent', panel{3} ); +box2 = uix.HBox( 'Parent', box1 ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', box1 ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 4', 'Parent', box2 ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 5', 'Parent', box2 ); + +% Set the dock/undock callback +set( panel{1}, 'DockFcn', {@nDock, 1} ); +set( panel{2}, 'DockFcn', {@nDock, 2} ); +set( panel{3}, 'DockFcn', {@nDock, 3} ); + +%-------------------------------------------------------------------------% + function nDock( eventSource, eventData, whichpanel ) %#ok + % Set the flag + panel{whichpanel}.Docked = ~panel{whichpanel}.Docked; + if panel{whichpanel}.Docked + % Put it back into the layout + newfig = get( panel{whichpanel}, 'Parent' ); + set( panel{whichpanel}, 'Parent', box ); + delete( newfig ); + else + % Take it out of the layout + pos = getpixelposition( panel{whichpanel} ); + newfig = figure( ... + 'Name', get( panel{whichpanel}, 'Title' ), ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'CloseRequestFcn', {@nDock, whichpanel} ); + figpos = get( newfig, 'Position' ); + set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] ); + set( panel{whichpanel}, 'Parent', newfig, ... + 'Units', 'Normalized', ... + 'Position', [0 0 1 1] ); + end + end % nDock + +%-------------------------------------------------------------------------% + function nCloseAll( ~, ~ ) + % User wished to close the application, so we need to tidy up + + % Delete all windows, including undocked ones. We can do this by + % getting the window for each panel in turn and deleting it. + for ii=1:numel( panel ) + if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' ) + figh = ancestor( panel{ii}, 'figure' ); + delete( figh ); + end + end + + end % nCloseAll + +end % Main function diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/gridflexpositioning.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/gridflexpositioning.m new file mode 100644 index 00000000..d3d90b3f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/gridflexpositioning.m @@ -0,0 +1,25 @@ +% Copyright 2009-2020 The MathWorks, Inc. + +f = figure(); + +% Box Panel +p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 ); + +% HBox +b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5 ); + +% uicontrol +uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} ); + +% Grid Flex +g = uix.GridFlex( 'Parent', b, 'Spacing', 5 ); +uicontrol( 'Parent', g, 'Background', 'r' ); +uicontrol( 'Parent', g, 'Background', 'b' ); +uicontrol( 'Parent', g, 'Background', 'g' ); +uix.Empty( 'Parent', g ); +uicontrol( 'Parent', g, 'Background', 'c' ); +uicontrol( 'Parent', g, 'Background', 'y' ); +set( g, 'Widths', [-1 100 -2], 'Heights', [-1 -2] ); + +% set HBox elements sizes +set( b, 'Widths', [100 -1] ); diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.fig b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.fig new file mode 100644 index 00000000..1f1ceca0 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.fig differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.m new file mode 100644 index 00000000..30978d30 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/guideApp.m @@ -0,0 +1,106 @@ +function varargout = guideApp(varargin) +% GUIDEAPP MATLAB code for guideApp.fig +% GUIDEAPP, by itself, creates a new GUIDEAPP or raises the existing +% singleton*. +% +% H = GUIDEAPP returns the handle to a new GUIDEAPP or the handle to +% the existing singleton*. +% +% GUIDEAPP('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in GUIDEAPP.M with the given input arguments. +% +% GUIDEAPP('Property','Value',...) creates a new GUIDEAPP or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before guideApp_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to guideApp_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Copyright 2009-2020 The MathWorks, Inc. + +% Edit the above text to modify the response to help guideApp + +% Last Modified by GUIDE v2.5 21-Jul-2010 07:36:25 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @guideApp_OpeningFcn, ... + 'gui_OutputFcn', @guideApp_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before guideApp is made visible. +function guideApp_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to guideApp (see VARARGIN) + +% Choose default command line output for guideApp +handles.output = hObject; + +% Update handles structure +guidata(hObject, handles); + +% Put a layout in the panel +g = uix.GridFlex( 'Parent', handles.uipanel1, ... + 'Units', 'Normalized', 'Position', [0 0 1 1], ... + 'Spacing', 5 ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 1' ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 2' ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 3' ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 4' ); +g.Heights = [-1 -1]; + +% UIWAIT makes guideApp wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = guideApp_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + + +% --- Executes on button press in pushbutton1. +function pushbutton1_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pushbutton2. +function pushbutton2_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pushbutton3. +function pushbutton3_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/hierarchyexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/hierarchyexample.m new file mode 100644 index 00000000..08c39689 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/hierarchyexample.m @@ -0,0 +1,33 @@ +%% A Hierarchy of Layouts Example +% This example shows how to use layouts within other layouts to achieve +% more complex user interface designs with the right mix of variable and +% fixed sized components. + +% Copyright 2009-2020 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'A Layout Hierarchy Example', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off', ... + 'Position', 200*ones(1,4) ); + +%% Create the first layout (vertical box) +% Inside this vertical box we place the axes +vbox = uix.VBox( 'Parent', window ); +axes( 'Parent', vbox ); + +%% Create the second layout (horizontal box) +% Inside this horizontal box we place two buttons +hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 ); +uicontrol( 'Parent', hbox, ... + 'String', 'Button 1' ); +uicontrol( 'Parent', hbox, ... + 'String', 'Button 2' ); + +%% Set the sizes +% We want the axes to grow with the window so set the first size to be -1 +% (which means variable size with wieght 1) and the buttons to stay fixed +% height so set the second size to 35 (fixed height of 35 pixels) +set( vbox, 'Heights', [-1 35] ) diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/minimizeexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/minimizeexample.m new file mode 100644 index 00000000..3eef1661 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/minimizeexample.m @@ -0,0 +1,54 @@ +function minimizeexample() +%MINIMIZEEXAMPLE: An example of using the panelbox minimize/maximize + +% Copyright 2009-2020 The MathWorks, Inc. + +width = 200; +pheightmin = 20; +pheightmax = 100; + +% Create the window and main layout +fig = figure( 'Name', 'Collapsable GUI', ...' + 'NumberTitle', 'off', ... + 'Toolbar', 'none', ... + 'MenuBar', 'none' ); +box = uix.VBox( 'Parent', fig ); + +panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box ); +panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box ); +panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box ); +set( box, 'Heights', pheightmax*ones(1,3) ); + +% Add some contents +uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} ); + +% Resize the window +pos = get( fig, 'Position' ); +set( fig, 'Position', [pos(1,1:2),width,sum(box.Heights)] ); + +% Hook up the minimize callback +set( panel{1}, 'MinimizeFcn', {@nMinimize, 1} ); +set( panel{2}, 'MinimizeFcn', {@nMinimize, 2} ); +set( panel{3}, 'MinimizeFcn', {@nMinimize, 3} ); + +%-------------------------------------------------------------------------% + function nMinimize( eventSource, eventData, whichpanel ) %#ok + % A panel has been maximized/minimized + s = get( box, 'Heights' ); + pos = get( fig, 'Position' ); + panel{whichpanel}.Minimized = ~panel{whichpanel}.Minimized; + if panel{whichpanel}.Minimized + s(whichpanel) = pheightmin; + else + s(whichpanel) = pheightmax; + end + set( box, 'Heights', s ); + + % Resize the figure, keeping the top stationary + delta_height = pos(1,4) - sum( box.Heights ); + set( fig, 'Position', pos(1,:) + [0 delta_height 0 -delta_height] ); + end % nMinimize + +end % EOF diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/paneltabexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/paneltabexample.m new file mode 100644 index 00000000..f9bb3938 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/paneltabexample.m @@ -0,0 +1,59 @@ +%% A TabPanel Example +% This example shows how to use tabs within a layout. It also shows how to +% use the TabPanel Callback property to update other GUI elements when the +% visible tab is changed. + +% Copyright 2009-2020 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'A TabPanel example', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off' ); + +%% Create the layout +% The layout involves two panels side by side. This is done using a +% flexible horizontal box. The left-hand side is filled with a standard +% panel and the right-hand side with some tabs. +hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3); +panel = uix.Panel( ... + 'Parent', hbox, ... + 'Padding', 5, ... + 'Title', 'Left' ); +tabpanel = uix.TabPanel( 'Parent', ... + hbox, ... + 'Padding', 0); + +%% Add a list on the left +% Note that we link the callbacks from the list to the tab selection and +% the tab callback to the list such that they are kept in sync. +panellist = uicontrol( 'Style', 'list', ... + 'Parent', panel, ... + 'String', {'1', '2', '3'}, ... + 'BackgroundColor', 'w', ... + 'Callback', @(a,b) set( tabpanel, 'Selection', get( a, 'Value' ) ) ); +set( tabpanel, 'SelectionChangedFcn', @(a,b) set( panellist, 'Value', b.NewValue ) ); + +%% Create some contents +% Each tab is filled with a list box showing some numbers +htab1 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '1'); +uicontrol( 'Style', 'listbox', 'Parent', htab1, ... + 'String', {'1', '1', '1'}, ... + 'BackgroundColor', 'w' ); + +htab2 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '2'); +uicontrol( 'Style', 'listbox', 'Parent', htab2, ... + 'String', {'2', '2', '2'}, ... + 'BackgroundColor', 'w' ); + +htab3 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '3'); +uicontrol( 'Style', 'listbox', 'Parent', htab3, ... + 'String', {'3', '3', '3'}, ... + 'BackgroundColor', 'w' ); + +%% Update the tab titles +tabpanel.TabTitles = {'1', '2', '3'}; + +%% Show the first tab +tabpanel.Selection = 1; \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/visibleexample.m b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/visibleexample.m new file mode 100644 index 00000000..49cb0985 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Examples/visibleexample.m @@ -0,0 +1,30 @@ +%% Showing/hiding a panel +% +% This example opens a simple user-interface with a panel full of +% buttons. We can then show/hide the entire panel in one go. Note +% that the previous state of the buttons is preserved. + +% Copyright 2009-2020 The MathWorks, Inc. + +%% Open a window and add a panel +fig = figure( 'Name', 'Visible example', ... + 'Position', [100 100 150 250], ... + 'MenuBar', 'none', ... + 'ToolBar', 'none', ... + 'NumberTitle', 'off' ); +panel = uix.BoxPanel( 'Parent', fig, 'Title', 'Panel' ); + +%% Put some buttons inside the panel +box = uix.VButtonBox( 'Parent', panel ); +uicontrol( 'Parent', box, 'String', 'Button 1' ); +uicontrol( 'Parent', box, 'String', 'Button 2' ); +uicontrol( 'Parent', box, 'String', 'Button 3', 'Visible', 'off' ); +uicontrol( 'Parent', box, 'String', 'Button 4' ); +uicontrol( 'Parent', box, 'String', 'Button 5', 'Visible', 'off' ); +uicontrol( 'Parent', box, 'String', 'Button 6' ); + +%% Try disabling the panel +set( panel, 'Visible', 'off' ); + +%% Try enabling the panel +set( panel, 'Visible', 'on' ); \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference.html new file mode 100644 index 00000000..93363cab --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference.html @@ -0,0 +1,190 @@ + + + + + + + + Function reference + + + + + + + + + + + +
GUI Layout Toolbox 2.3.5previous pagenext page
+ +

Function reference Go back up one level

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

1: Panels

+ + + + + + + + + + + + + + + + + + +
1.1 uix.PanelArrange a single element inside a standard panel
1.2 uix.CardPanelShow one element (card) from a list
1.3 uix.BoxPanelArrange a single element in a panel with boxed title
1.4 uix.TabPanelArrange elements in a panel with tabs for selecting which is visible
1.5 uix.ScrollingPanelArrange a single element inside a scrollable panel

2: Boxes

+ + + + + + + + + + + + + + + + + + + + +
2.1 uix.HBoxArrange elements horizontally in a single row
2.2 uix.VBoxArrange elements vertically in a single column
2.3 uix.HBoxFlexArrange elements horizontally with draggable dividers
2.4 uix.VBoxFlexArrange elements vertically with draggable dividers
2.5 uix.HButtonBoxArrange buttons horizontally in a single row
2.6 uix.VButtonBoxArrange buttons vertically in a single column

3: Grids

+ + + + + + + +
3.1 uix.GridArrange elements in a two dimensional grid
3.2 uix.GridFlexArrange elements in a two dimensional grid with draggable dividers

4: Other functions

+ + + + + + + +
4.1 uix.EmptyCreate an empty space
4.2 uix.trackingTrack usage
4.3 layoutRootReturn the folder containing the GUI layout toolbox
+
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_1.html new file mode 100644 index 00000000..aceb184d --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_1.html @@ -0,0 +1,83 @@ + + + + + + + uix.Panel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.1: uix.Panel Go back up one level

+ + + +
+

Arrange a single element inside a standard panel

+
+
obj = uix.Panel( )
+
creates a standard uipanel object but with automatic management + of the contained widget or layout. The properties available are largely + the same as the builtin uipanel object. Where more than one child is + added, the currently visible child is determined using the Selection property.
+ +
obj = uix.Panel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.Panel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
BorderType none | etchedin | etchedout | beveledin | beveledout | lineType of border around the uipanel area.
BorderWidth positive integerWidth of the panel border.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
FontAngle normal | italic | obliqueTitle font angle.
FontName stringTitle font name (e.g. Arial, Helvetica etc).
FontSize positive integerTitle font size.
FontUnits inches | centimeters | normalized | points | pixelsTitle font units for measuring size.
FontWeight light | normal | demi | boldTitle font weight.
ForegroundColor colorspecTitle font color and/or color of 2-D border line.
HighlightColor colorspec3-D frame highlight color.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
ShadowColor colorspec3-D frame shadow color.
Tag stringTag to associate with layout.
Title stringTitle string.
TitlePosition lefttop | centertop | righttop | leftbottom | centerbottom | rightbottomLocation of title string in relation to the panel.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' )
+

+

+

+ +
f = figure();
+p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'TitlePosition', 'CenterTop');
+b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5  );
+uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+uicontrol( 'Parent', b, 'Background', 'b' );
+set( b, 'Widths', [100 -1] );
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_2.html new file mode 100644 index 00000000..57991f02 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_2.html @@ -0,0 +1,77 @@ + + + + + + + uix.CardPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.2: uix.CardPanel Go back up one level

+ + + +
+

Show one element (card) from a list

+
+
obj = uix.CardPanel( )
+
creates a new card panel which allows + selection between the different child objects contained, making the + selected child fill the space available and all other children + invisible. This is commonly used for creating wizards or quick + switching between different views of a single data-set.
+ +
obj = uix.CardPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.CardPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+p = uix.CardPanel( 'Parent', f, 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' );
+uicontrol( 'Parent', p, 'Background', 'b' );
+uicontrol( 'Parent', p, 'Background', 'g' );
+p.Selection = 2;
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_3.html new file mode 100644 index 00000000..c803a727 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_3.html @@ -0,0 +1,87 @@ + + + + + + + uix.BoxPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.3: uix.BoxPanel Go back up one level

+ + + +
+

Arrange a single element in a panel with boxed title

+
+
obj = uix.BoxPanel( )
+
creates a box-styled panel object with + automatic management of the contained widget or layout. The + properties available are largely the same as the builtin UIPANEL + object. Where more than one child is added, the currently visible + child is determined using the Selection property.
+ +
obj = uix.BoxPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.BoxPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
BorderType none | etchedin | etchedout | beveledin | beveledout | lineType of border around the title and content areas.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
CloseRequestFcn function_handleFunction to call when the panel close icon is clicked. Note that if empty, no close button is shown.
CloseTooltipString stringCustom tooltip string for close button. Note that if CloseRequestFcn is empty, no close button is shown.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Docked logicalIs this panel in a docked state. See advanced maneuvers with panels for details.
DockFcn function handleFunction to call when panel is docked or undocked. Note that if empty, no dock button is shown. See advanced maneuvers with panels for details.
DockTooltipString stringCustom tooltip string for dock button (when panel is undocked). Note that if DockFcn is empty, no dock button is shown.
FontAngle normal | italic | obliqueTitle font angle.
FontName stringTitle font name (e.g. Arial, Helvetica etc).
FontSize positive integerTitle font size.
FontUnits inches | centimeters | normalized | points | pixelsTitle font units for measuring size.
FontWeight light | normal | demi | boldTitle font weight.
ForegroundColor colorspecTitle font color and/or color of 2-D border line.
HelpFcn function handleFunction to call when the help icon is clicked. Note that if empty, no help button is shown. See advanced maneuvers with panels for details.
HelpTooltipString stringCustom tooltip string for help button. Note that if HelpFcn is empty, no help button is shown.
HighlightColor colorspec3-D frame highlight color.
MaximizeTooltipString stringCustom tooltip string for minimize button (when panel is minimized). Note that if MinimizeFcn is empty, no minimize button is shown.
Minimized logicalIs this panel in a minimized state. See advanced maneuvers with panels for details.
MinimizeFcn function handleFunction to call when panel is minimized or maximized. Note that if empty, no minimize button is shown. See advanced maneuvers with panels for details.
MinimizeTooltipString stringCustom tooltip string for minimize button (when panel is maximized). Note that if MinimizeFcn is empty, no minimize button is shown.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
ShadowColor colorspec3-D frame shadow color.
Tag stringTag to associate with layout.
Title stringTitle string.
TitleColor colorspeccolor for the title bar background.
Type stringType of graphics object.
UndockTooltipString stringCustom tooltip string for dock button (when panel is docked). Note that if DockFcn is empty, no dock button is shown.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility. See the visible example for more details.
+ +

For example:

+
f = figure();
+p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' )
+

+

+

+ +
f = figure();
+p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5  );
+uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+uicontrol( 'Parent', b, 'Background', 'b' );
+set( b, 'Widths', [100 -1] );
+p.FontSize = 12;
+p.FontWeight = 'bold';
+p.HelpFcn = @(x,y) disp('Help me!');
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_4.html new file mode 100644 index 00000000..272fc42f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_4.html @@ -0,0 +1,75 @@ + + + + + + + uix.TabPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.4: uix.TabPanel Go back up one level

+ + + +
+

Arrange elements in a panel with tabs for selecting which is visible

+
+
obj = uix.TabPanel( )
+
creates a panel with tabs along one edge + to allow selection between the different child objects contained.
+ +
obj = uix.TabPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.TabPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
FontAngle normal | italic | obliqueTitle font angle.
FontName stringTitle font name (e.g. Arial, Helvetica etc).
FontSize positive integerTitle font size.
FontUnits inches | centimeters | normalized | points | pixelsTitle font units for measuring size.
FontWeight light | normal | demi | boldTitle font weight.
ForegroundColor colorspecTitle font color and/or color of 2-D border line.
HighlightColor colorspec3-D frame highlight color.
ShadowColor colorspec3-D frame shadow color.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
SelectionChangedFcn function_handleFunction to call when the selected tab is changed. The event-data supplied has fields OldValue and NewValue giving the previously selected and newly selected tab indices.
TabContextMenus cell array of context menusThe context menu (or []) for each tab.
TabEnables cell array of on | offA list of the enabled state of each tab (default is all 'on').
TabTitles cell array of stringsA list of the names of the tabs with one entry per tab.
TabWidth positive integerWidth of each tab in pixels (default 50).
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+p = uix.TabPanel( 'Parent', f, 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' );
+uicontrol( 'Parent', p, 'Background', 'b' );
+uicontrol( 'Parent', p, 'Background', 'g' );
+p.TabTitles = {'Red', 'Blue', 'Green'};
+p.Selection = 2;
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_5.html new file mode 100644 index 00000000..2a5b9102 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference1_5.html @@ -0,0 +1,76 @@ + + + + + + + uix.ScrollingPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.5: uix.ScrollingPanel Go back up one level

+ + + +
+

Arrange a single element inside a panel and provide scrollbars if the panel is smaller than the element

+
+
obj = uix.ScrollingPanel( )
+
creates a new scrolling panel.
+ +
obj = uix.ScrollingPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.ScrollingPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Heights double vectorHeight of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
HorizontalOffsets double vectorHorizontal offset of each of the children. Each value is limited to between 0 and the difference between the width of child and the width of the panel. The size of this vector must always match the size of Contents.
HorizontalSteps positive double vectorHorizontal slider step for each of the children. The size of this vector must always match the size of Contents.
MinimumHeights double vectorMinimum height in pixels of each of the children. The size of this vector must match the size of Contents.
MinimumWidths double vectorMinimum width in pixels of each of the children. The size of this vector must match the size of Contents.
MouseWheelEnabled on | offMouse wheel scrolling status (default 'on').
Padding positive integerThis property is not honored by this class.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
VerticalOffsets double vectorVertical offset of each of the children. Each value is limited to between 0 and the difference between the height of child and the height of the panel. The size of this vector must always match the size of Contents.
VerticalSteps positive double vectorVertical slider step for each of the children. The size of this vector must always match the size of Contents.
Visible on | offVisibility.
Widths double vectorWidth of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+ +

For example:

+
f = figure( 'Name', 'uix.ScrollingPanel Help Example' );
+f.Position(3:4) = 400;
+p = uix.ScrollingPanel( 'Parent', f );
+a = axes( 'Parent', p );
+[x, y, z] = peaks();
+surf( a, x, y, z )
+a.ActivePositionProperty = 'position';
+set( p, 'Widths', 600, 'Heights', 600, 'HorizontalOffsets', 100, 'VerticalOffsets', 100 )
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_1.html new file mode 100644 index 00000000..334aa25d --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_1.html @@ -0,0 +1,88 @@ + + + + + + + uix.HBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.1: uix.HBox Go back up one level

+ + + + + + +
+

Arrange elements horizontally in a single row

+
+
obj = uix.HBox( )
+
creates a new horizontal box layout with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.HBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.HBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
MinimumWidths double vectorMinimum width in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+ +

For example:

+
f = figure();
+b = uix.HBox( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+set( b, 'Widths', [-1 100 -2], 'Spacing', 5 );
+

+

+

+ +
f = figure();
+b1 = uix.VBox( 'Parent', f );
+uicontrol( 'Parent', b1, 'Background', 'r' )
+b2 = uix.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 );
+uicontrol( 'Parent', b2, 'String', 'Button1' )
+uicontrol( 'Parent', b2, 'String', 'Button2' )
+set( b1, 'Widths', [30 -1] );
+

+

+

+ + +
See also:
  • uix.VBox - for creating a vertical arrangement
  • uix.HBoxFlex - for creating a horizontal arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_2.html new file mode 100644 index 00000000..4c9f6724 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_2.html @@ -0,0 +1,87 @@ + + + + + + + uix.VBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.2: uix.VBox Go back up one level

+ + + + + +
+

Arrange elements vertically in a single column

+
+
obj = uix.VBox( )
+
creates a new vertical box layout with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.VBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.VBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Heights double vectorHeight of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
MinimumHeights double vectorMinimum height in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+b = uix.VBox( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+set( b, 'Heights', [-1 100 -2], 'Spacing', 5 );
+

+

+

+ +
f = figure();
+b1 = uix.VBox( 'Parent', f );
+uicontrol( 'Parent', b1, 'Background', 'r' )
+b2 = uix.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 );
+uicontrol( 'Parent', b2, 'String', 'Button1' )
+uicontrol( 'Parent', b2, 'String', 'Button2' )
+set( b1, 'Heights', [30 -1] );
+

+

+

+ + +
See also:
  • uix.HBox - for creating a horizontal arrangement
  • uix.VBoxFlex - for creating a vertical arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_3.html new file mode 100644 index 00000000..8c933031 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_3.html @@ -0,0 +1,79 @@ + + + + + + + uix.HBoxFlex + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.3: uix.HBoxFlex Go back up one level

+ + + + + + + +
+

Arrange elements horizontally with draggable dividers

+
+
obj = uix.HBoxFlex( )
+
creates a new horizontal box layout with draggable dividers and with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.HBoxFlex( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.HBoxFlex properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DividerMarkings on | offShow markings on the draggable dividers (default 'on').
MinimumWidths double vectorMinimum width in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout (default 5).
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+ +

For example:

+
f = figure( 'Name', 'uix.HBoxFlex example' );
+b = uix.HBoxFlex( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+uicontrol( 'Parent', b, 'Background', 'y' )
+set( b, 'Widths', [-1 100 -2 -1], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.HBox - for creating a horizontal arrangement
  • uix.VBoxFlex - for creating a vertical arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_4.html new file mode 100644 index 00000000..99e656c6 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_4.html @@ -0,0 +1,78 @@ + + + + + + + uix.VBoxFlex + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.4: uix.VBoxFlex Go back up one level

+ + + + + + + +
+

Arrange elements vertically with draggable dividers

+
+
obj = uix.VBoxFlex( )
+
creates a new vertical box layout with draggable dividers and with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.VBoxFlex( prop, value, ... )
+
also sets one or more property values from the list below.
+
+ +

uix.VBoxFlex properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DividerMarkings on | offShow markings on the draggable dividers (default 'on').
Heights double vectorHeight of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
MinimumHeights double vectorMinimum height in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout (default 5).
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ + +

For example:

+
f = figure( 'Name', 'uix.VBoxFlex example' );
+b = uix.VBoxFlex( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+uicontrol( 'Parent', b, 'Background', 'y' )
+set( b, 'Heights', [-1 100 -2 -1], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.VBox - for creating a vertical arrangement
  • uix.HBoxFlex - for creating a horizontal arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_5.html new file mode 100644 index 00000000..27c84dff --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_5.html @@ -0,0 +1,80 @@ + + + + + + + uix.HButtonBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.5: uix.HButtonBox Go back up one level

+ + + + + + +
+

Arrange buttons horizontally in a single row

+
+
obj = uix.HButtonBox( )
+
is a type of HBox specialised for + arranging a row of buttons, check-boxes or similar graphical + elements. All buttons are given equal size and by default are + centered in the drawing area. The justification can be changed as + required.
+ +
obj = uix.HButtonBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.HButtonBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
ButtonSize [w h]The size for the buttons (all are given equal size).
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
HorizontalAlignment left | center | rightThe horizontal position of the buttons.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
VerticalAlignment top | middle | bottomThe vertical position of the buttons.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+b = uix.HButtonBox( 'Parent', f );
+uicontrol( 'Parent', b, 'String', 'One' );
+uicontrol( 'Parent', b, 'String', 'Two' );
+uicontrol( 'Parent', b, 'String', 'Three' );
+set( b, 'ButtonSize', [130 35], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.VButtonBox - for creating a vertical arrangement of buttons
  • uix.HBox - for creating a general horizontal arrangement
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_6.html new file mode 100644 index 00000000..a9d9304c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference2_6.html @@ -0,0 +1,81 @@ + + + + + + + uix.VButtonBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.6: uix.VButtonBox Go back up one level

+ + + + + + +
+

Arrange buttons vertically in a single column

+
+
obj = uix.VButtonBox( )
+
is a type of VBox specialised for + arranging a column of buttons, check-boxes or similar graphical + elements. All buttons are given equal size and by default are + centered in the drawing area. The justification can be changed as + required.
+ +
obj = uix.VButtonBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.VButtonBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
ButtonSize [w h]The size for the buttons (all are given equal size).
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
HorizontalAlignment left | center | rightThe horizontal position of the buttons.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
VerticalAlignment top | middle | bottomThe vertical position of the buttons.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+b = uix.VButtonBox( 'Parent', f );
+uicontrol( 'Parent', b, 'String', 'One' );
+uicontrol( 'Parent', b, 'String', 'Two' );
+uicontrol( 'Parent', b, 'String', 'Three' );
+set( b, 'ButtonSize', [130 35], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.HButtonBox - for creating a horizontal arrangement of buttons
  • uix.VBox - for creating a general vertical arrangement
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_1.html new file mode 100644 index 00000000..24a71509 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_1.html @@ -0,0 +1,82 @@ + + + + + + + uix.Grid + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

3.1: uix.Grid Go back up one level

+ + + +
+

Arrange elements in a two dimensional grid

+
+
obj = uix.Grid( )
+
creates a new new grid layout with all properties set to defaults. The number of rows and + columns to use is determined from the number of elements in the + Heights and Widths properties respectively. Child elements are + arranged down column one first, then column two etc. If there are insufficient + columns then a new one is added. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.Grid( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.Grid properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Heights double vectorHeight of each of the rows. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the columns. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
+ +

For example:

+
f = figure();
+g = uix.Grid( 'Parent', f, 'Spacing', 5 );
+uicontrol( 'Parent', g, 'Background', 'r' )
+uicontrol( 'Parent', g, 'Background', 'b' )
+uicontrol( 'Parent', g, 'Background', 'g' )
+uix.Empty( 'Parent', g )
+uicontrol( 'Parent', g, 'Background', 'c' )
+uicontrol( 'Parent', g, 'Background', 'y' )
+set( g, 'Widths', [-1 100 -2], 'Heights', [-1 100] );
+

+

+

+ + +
See also:
  • uix.GridFlex - for creating a grid arrangement with draggable dividers
+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_2.html new file mode 100644 index 00000000..2d709f41 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference3_2.html @@ -0,0 +1,84 @@ + + + + + + + uix.GridFlex + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

3.2: uix.GridFlex Go back up one level

+ + + + +
+

Arrange elements in a two dimensional grid with draggable dividers

+
+
obj = uix.GridFlex( )
+
creates a new new grid layout with draggable dividers between elements. The number of rows and + columns to use is determined from the number of elements in the + Heights and Widths properties respectively. Child elements are + arranged down column one first, then column two etc. If there are insufficient + columns then a new one is added. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.GridFlex( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.GridFlex properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DividerMarkings on | offShow markings on the draggable dividers (default 'on').
Heights double vectorHeight of each of the rows. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout (default 5).
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the columns. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
+ +

For example:

+
f = figure();
+g = uix.GridFlex( 'Parent', f, 'Spacing', 5 );
+uicontrol( 'Parent', g, 'Background', 'r' )
+uicontrol( 'Parent', g, 'Background', 'b' )
+uicontrol( 'Parent', g, 'Background', 'g' )
+uix.Empty( 'Parent', g )
+uicontrol( 'Parent', g, 'Background', 'c' )
+uicontrol( 'Parent', g, 'Background', 'y' )
+set( g, 'Widths', [-1 100 -2], 'Heights', [-1 -2] );
+

+

+

+ + +
See also:
  • uix.Grid - for creating a grid arrangement
+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_1.html new file mode 100644 index 00000000..0afb71ab --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_1.html @@ -0,0 +1,69 @@ + + + + + + + uix.Empty + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

4.1: uix.Empty Go back up one level

+ + +

Create an empty space

+
+
obj = uix.Empty( )
+
creates an empty space object that can be + used in layouts to add gaps between other elements.
+ +
obj = uix.Empty( param, value, ... )
+
also sets one or more property values.
+ +
+ +

uix.Empty properties

+

The empty space is achieved using a container that monitors + its parent's color and changes its own to match.

+
PropertyValueDescription
BeingDeleted on | offDeletion status.
HandleVisibility on | offVisibility of the object.
Parent empty GraphicsPlaceholder array | figure | containerParent of the object.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Tag stringTag to associate with object.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+box = uix.HBox( 'Parent', f, 'Spacing', 5 );
+uicontrol( 'Parent', box, 'Background', 'r' )
+uix.Empty( 'Parent', box )
+uicontrol( 'Parent', box, 'Background', 'g' )
+

+ +
See also:
  • uix.HBox - for arranging widgets horizontally
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_2.html new file mode 100644 index 00000000..9bbc620f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_2.html @@ -0,0 +1,63 @@ + + + + + + + uix.tracking + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

4.2: uix.tracking Go back up one level

+ + +

tracks anonymized usage data

+
+
uix.tracking( p, v, id )
+
tracks usage to the property p for the version v and identifier id using Google Analytics.
+
uix.tracking( state )
+
turns tracking on or off.
+
state = uix.tracking( 'query' )
+
queries whether tracking is on or off.
+ +
+ +

For example:

+
uix.tracking('UA-45678-9','1.2.3','featurename')
+ +
uix.tracking('on')
+ +
state = uix.tracking('query')
+

state = 'on'

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_3.html new file mode 100644 index 00000000..9955a1d3 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Function_reference4_3.html @@ -0,0 +1,57 @@ + + + + + + + layoutRoot + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

4.3: layoutRoot Go back up one level

+ + + + +

returns the folder containing the GUI layout toolbox

+
+
folder = layoutRoot( )
+
returns the full path to the folder containing the GUI Layout Toolbox.
+ +
+ +

For example:

+
folder = layoutRoot()
+

folder = 'C:\tools\glt2'

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + +> diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/GUI Layout.html b/studio_functions/GUI Layout Toolbox/layoutdoc/GUI Layout.html new file mode 100644 index 00000000..c0141bd5 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/GUI Layout.html @@ -0,0 +1,5 @@ + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started.html new file mode 100644 index 00000000..2ed741a6 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started.html @@ -0,0 +1,85 @@ + + + + + + + + Getting Started + + + + + + + + + + + +
GUI Layout Toolbox 2.3.5previous pagenext page
+ +

Getting Started Go back up one level

+

+ This chapter gives an overview of this package, including its purpose, +how to install it and any known issues at the time of release. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Contents

+
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started1.html new file mode 100644 index 00000000..6c6f9c78 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started1.html @@ -0,0 +1,54 @@ + + + + + + + What is GUI Layout Toolbox? + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

1: What is GUI Layout Toolbox? Go back up one level

+ + +

GUI Layout Toolbox provides a package of MATLAB objects that allow for complex + arrangement of graphical user interface elements within a figure window. The + main capabilities provided are:

+
    +
  • Automatic element arrangement horizontally, vertically or in grids
  • +
  • Ability to specify fixed sizes or resizing weights for each element
  • +
  • Ability to "nest" layouts to produce virtually any element arrangement
  • +
  • Divider bars for user-resizing of elements
  • +
+

These element arrangement capabilities are designed to match those found as + standard in other user-interface toolkits such as Java Swing, GTK, QT etc.

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started2.html new file mode 100644 index 00000000..e93586d3 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started2.html @@ -0,0 +1,150 @@ + + + + + + + Compatibility considerations + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

2: Compatibility considerations Go back up one level

+ + + + + + + +

Section contents:

+ + +
    +
+ + +
    +
+

+ +

 2.1: Minimum MATLAB version Go back up one level

+ +

This is version 2 of GUI Layout Toolbox, designed to work with the new + MATLAB graphics system that was introduced in R2014b.

+

Version 1 works with MATLAB releases prior to R2014b that use the old + graphics system.

+

+ +

 2.2: Compatibility with version 1 Go back up one level

+ +

If you are upgrading from version 1, there are a number of compatibility + considerations:

+ +

Package name

+

Version 1 classes were contained in the package "uiextras". Version 2 classes are +contained in the package "uix". In version 2, a package "uiextras" is included +to provide support for legacy code. Classes in "uiextras" extend +corresponding classes in "uix", and contain only compatibility-related +code.

+ +

Contents property

+

The contents of version 1 objects were accessible via the property Children. +The contents of version 2 objects are accessible via the property Contents. +Version 2 objects also provide a property Children, but this controls the +vertical stacking order rather than the layout order. Legacy code that accesses +Children will run without error, but will not achieve the desired change in +layout order, and should be modified to access Contents instead.

+ +

An upcoming release of version 1 will include support for code that references +contents via Contents. That way, code modified to work in version 2 will also +work in version 1.

+ +

The background to this change is as follows. Version 1 objects were wrappers +for built-in graphics objects, and presented contents in layout order via +the property Children. Version 2 objects extend built-in graphics objects, +and as such, inherit properties, methods and events. One such property is +Children which is used to control the top-to-bottom stacking order. +MATLAB stacking rules, e.g. controls are always on top of axes, mean that +some reasonable layout orders may be invalid stacking orders, so a new +property for layout order is required.

+ +

Auto-parenting

+

The new MATLAB graphics system introduces unparented objects, i.e. those with property Parent +empty. The new system also introduces a separation between formal class constructors, e.g. +matlab.ui.container.Panel, and informal construction functions, e.g. uipanel. +Construction functions are auto-parenting, i.e. if Parent is not specified then it is set to +gcf, whereas class constructors return objects with Parent empty unless +explicitly specified. Version 2 presents a formal interface of class constructors which follow this new +convention.

+ +

Classes in "uiextras" are auto-parenting so the behavior of legacy code is +unchanged. However, best practice is to specify parent explicitly during +construction.

+ +

Defaults mechanism

+

Version 1 provided a defaults mechanism (uiextras.get, uiextras.set +and uiextras.unset) that mimicked get and set in the MATLAB +graphics system itself. This feature has been removed from version 2. Users should use an +alternative programming pattern, e.g. factory function, to create objects with standard settings.

+ +

Enable and disable

+

Version 1 provided a mechanism to enable and disable container contents using the property +Enable. This feature has been removed from version 2. Users should enable and disable +controls directly rather than via containers.

+

For more commentary, see this article.

+ +

Other property name changes

+

A number of property names have changed to achieve greater consistency +across the package. For example, RowSizes and ColumnSizes in +uiextras.Grid are now Heights and Widths in uix.Grid. The package +"uiextras" provides support for legacy property names.

+
    +
  • RowSizes in "uiextras" is Heights in "uix"
  • +
  • ColumnSizes in "uiextras" is Widths in "uix"
  • +
  • ShowMarkings in "uiextras" is DividerMarkings in "uix"
  • +
+ +

Property shape changes

+

Version 2 contents companion properties are now of the same size as Contents, +i.e. column vectors. In version 1, these properties were row vectors. The +package "uiextras" provides support for legacy property values.

+ +

Tab selection behavior

+

In version 1, after adding a tab to a tab panel, the new tab is selected.

+

In version 2, the original selection is preserved, except if the tab panel was + empty, in which case the new tab is selected. This is consistent with the + behavior of uitabgroup.

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started3.html new file mode 100644 index 00000000..4964873c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started3.html @@ -0,0 +1,226 @@ + + + + + + + Release notes + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

3: Release notes Go back up one level

+ +

+ The GUI Layout Toolbox version numbers take the form major.minor.iter. The + current version you have installed can be checked by typing ver + at the MATLAB command prompt. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Section contents:

+ + +
    +
+ + +
    +
+

+ +

 3.1: Version 2.3.5 Go back up one level

+ +
    +
  • Released 31 October 2020
  • +
  • Updated for compatibility with R2020b uipanels
  • +
  • Fixed G1959226 "Scrolling panel scrollbars and blanking plate do not match + background color"
  • +
  • Fixed G1959228 "Scrolling panel sliders remain after child is deleted"
  • +
+

+ +

 3.2: Version 2.3.4 Go back up one level

+ +
    +
  • Released 31 January 2019
  • +
  • Fixed G1910801 "Scrolling panel does not work in figure with Units other than 'pixels'"
  • +
  • Fixed G1911845 "Unexpected reordering of contents as axes toolbar causes axes to be removed and readded"
  • +
+

+ +

 3.3: Version 2.3.3 Go back up one level

+ +
    +
  • Released 25 October 2018
  • +
  • Updated for compatibility with R2018b axes toolbars
  • +
  • Fixed G1804440 "Flex containers position axes incorrectly when ActivePositionProperty is outerposition"
  • +
+

+ +

 3.4: Version 2.3.2 Go back up one level

+ +
    +
  • Released 1 May 2018
  • +
  • Set tooltip strings for BoxPanel dock/undock, minimize/maximize, help and close buttons
  • +
  • Set default padding for flex containers to 5 so that dividers are visible
  • +
  • Scroll uix.ScrollingPanel using mouse wheel for variable-sized contents
  • +
  • Fixed G1358897 "BoxPanel title is truncated on Mac high DPI display"
  • +
  • Fixed G1695618 "Warning on mouse motion while deleting HBoxFlex, VBoxFlex or GridFlex"
  • +
+

+ +

 3.5: Version 2.3.1 Go back up one level

+ +
    +
  • Released 31 January 2017
  • +
  • Specify minimum width and height of contents in uix.ScrollingPanel
  • +
  • Update contents position while dragging uix.ScrollingPanel scrollbox
  • +
  • Scroll uix.ScrollingPanel using mouse wheel
  • +
  • Updated toolbox logo
  • +
+

+ +

 3.6: Version 2.3 Go back up one level

+ +
    +
  • Released 24 November 2016
  • +
  • Added scrolling panel
  • +
  • Expand and collapse box panel by clicking on title
  • +
  • Fixed G1493103 "Error on construction behavior is inconstistent with builtin objects"
  • +
+

+ +

 3.7: Version 2.2.2 Go back up one level

+ +
    +
  • Released 22 August 2016
  • +
  • Fixed G1175938 "Cannot use data cursor mode with GUI Layout Toolbox containers"
  • +
  • Fixed G1367337 "Update flex container pointer on mouse press event"
  • +
  • Fixed G1380756 "Space behind TabPanel tabs should match parent color"
  • +
  • Added anonymous tracking of version, operating system and usage to help + us prioritize the improvements we should work on
  • +
+

+ +

 3.8: Version 2.2.1 Go back up one level

+ +
    +
  • Released 26 February 2016
  • +
  • Fixed G1346921 "Mouse pointer gets confused when moving between adjacent flex containers"
  • +
  • Fixed G1357340 "BoxPanel property ForegroundColor is initialized incorrectly"
  • +
+

+ +

 3.9: Version 2.2 Go back up one level

+ +
    +
  • Released 18 December 2015
  • +
  • Improved box panel title bar appearance
  • +
  • Changed selection behavior of uix.TabGroup to match that of uitabgroup when the selected tab is removed
  • +
  • Fixed G1253937 "uix.TabPanel/redrawTabs fails" (R2015b)
  • +
  • Fixed G1292238 "uix.BoxPanel/redrawBorders fails" (R2015b)
  • +
  • Fixed G1330841 "mouse-over-divider detection does not work for docked figures" (all)
  • +
  • Fixed G1332109 "uix.Empty background color does not match that of its Parent" (all)
  • +
  • Fixed G1334867 "cannot add axes to container" (R2016a prerelease)
  • +
  • Removed internal helper classes uix.AncestryObserver, uix.LocationObserver, uix.VisibilityObserver
  • +
+

+ +

 3.10: Version 2.1.2 Go back up one level

+ +
    +
  • Released 29 May 2015
  • +
  • Fixed G1250248 "uix.Empty becomes visible in a panel"
  • +
  • Fixed G1250249 "missing property Selection of uix.BoxPanel"
  • +
  • Fixed G1250808 "uix.TabPanel context menus are orphaned when reparenting to a different figure"
  • +
+

+ +

 3.11: Version 2.1.1 Go back up one level

+ +
    +
  • Released 15 May 2015
  • +
  • Added context menus on uix.TabPanel tab labels (G1245669)
  • +
  • Fixed G1164656 "cannot set relative tab widths"
  • +
  • Fixed G1019441 "property RowSizes of uiextras.GridFlex sets heights not widths"
  • +
  • Fixed G1165274 "missing properties RowSizes, MinimumRowSizes, ColumnSizes, + MinimumColumnSizes of uiextras.Grid, uiextras.GridFlex"
  • +
  • Fixed G1218142 "contents are lost when reordering via property Children"
  • +
  • Protected against G1136196 "segv when setting child visibility from 'off' to 'on' in response to being reparented"
  • +
+

+ +

 3.12: Version 2.1 Go back up one level

+ +
    +
  • Released 2 October 2014
  • +
  • Initial version for MATLAB R2014b
  • +
  • Versions 2.0.x were for prerelease testing
  • +
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started4.html new file mode 100644 index 00000000..7c103b9d --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started4.html @@ -0,0 +1,51 @@ + + + + + + + Installation + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

4: Installation Go back up one level

+ + +

+ GUI Layout Toolbox is provided as a MATLAB toolbox file (.mltbx). +

+

+ For instructions on installing and uninstalling, see the section on + managing toolboxes + in the MATLAB documentation. +

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started5.html new file mode 100644 index 00000000..a0cc61cb --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started5.html @@ -0,0 +1,55 @@ + + + + + + + Support + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

5: Support Go back up one level

+ + +

+ This toolbox is not a MathWorks supported product. However, if you + have problems, suggestions or other comments, please contact the + authors: +

+ +

If you like this toolbox, help others to find it by leaving a rating + and comment on the MATLAB Central File Exchange. +

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started6.html new file mode 100644 index 00000000..c9ca3e27 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/Getting_Started6.html @@ -0,0 +1,49 @@ + + + + + + + Acknowledgements + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

6: Acknowledgements Go back up one level

+ +

The authors wish to acknowledge the earlier contributions of the following MathWorks + consultants to this area:

+
    +
  • Brad Phelan
  • +
  • Malcolm Wood
  • +
  • Richard Lang
  • +
  • Paul Kerr-Delworth
  • +
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + +> diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/HierarchyExample.html b/studio_functions/GUI Layout Toolbox/layoutdoc/HierarchyExample.html new file mode 100644 index 00000000..d9859f5f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/HierarchyExample.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Border.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Border.png new file mode 100644 index 00000000..0e58e8ac Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Border.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxInBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxInBox.png new file mode 100644 index 00000000..799d725c Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxInBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel.png new file mode 100644 index 00000000..94aef688 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel2.png new file mode 100644 index 00000000..af9ca016 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanel2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample1.png new file mode 100644 index 00000000..dc94dfa4 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample2.png new file mode 100644 index 00000000..be25fcdb Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample3.png new file mode 100644 index 00000000..577ac4e7 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample4.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample4.png new file mode 100644 index 00000000..15a7b66f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelDockExample4.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelHelpExample.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelHelpExample.png new file mode 100644 index 00000000..1a295b83 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelHelpExample.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample1.png new file mode 100644 index 00000000..d9df27b4 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample2.png new file mode 100644 index 00000000..28f290d4 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample3.png new file mode 100644 index 00000000..93b3072f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/BoxPanelMinimizeExample3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CardPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CardPanel.png new file mode 100644 index 00000000..db0ab356 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CardPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CombineBoxes.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CombineBoxes.png new file mode 100644 index 00000000..87db36e4 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/CombineBoxes.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsFigure.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsFigure.png new file mode 100644 index 00000000..e0446a13 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsFigure.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem1.png new file mode 100644 index 00000000..2c228e4e Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem2.png new file mode 100644 index 00000000..1065eac5 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/DefaultsSystem2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Empty.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Empty.png new file mode 100644 index 00000000..4f470418 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Empty.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample1.png new file mode 100644 index 00000000..0f46c6f2 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample2.png new file mode 100644 index 00000000..3d8be827 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample3.png new file mode 100644 index 00000000..b3f62e72 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/EnableExample3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Grid.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Grid.png new file mode 100644 index 00000000..47ab7812 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Grid.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/GridFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/GridFlex.png new file mode 100644 index 00000000..76b64c51 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/GridFlex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBox.png new file mode 100644 index 00000000..2c537518 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBoxFlex.png new file mode 100644 index 00000000..91a2a3ae Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HBoxFlex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HButtonBox.png new file mode 100644 index 00000000..c7954468 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/HButtonBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel.png new file mode 100644 index 00000000..a371495f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel2.png new file mode 100644 index 00000000..863de735 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/Panel2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/ScrollingPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/ScrollingPanel.png new file mode 100644 index 00000000..9d806848 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/ScrollingPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/TabPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/TabPanel.png new file mode 100644 index 00000000..2af8973e Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/TabPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBox.png new file mode 100644 index 00000000..fd703c91 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBoxFlex.png new file mode 100644 index 00000000..d02fc828 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VBoxFlex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VButtonBox.png new file mode 100644 index 00000000..889d828c Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VButtonBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample1.png new file mode 100644 index 00000000..a15a62ca Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample2.png new file mode 100644 index 00000000..c314bc82 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample3.png new file mode 100644 index 00000000..65e6085f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/VisibleExample3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_inner.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_inner.png new file mode 100644 index 00000000..5a9fad17 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_inner.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_2.png new file mode 100644 index 00000000..3f9f29f1 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_3.png new file mode 100644 index 00000000..a89912e9 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_layout_example_3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_outer.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_outer.png new file mode 100644 index 00000000..39858c43 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/axes_outer.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example2.png new file mode 100644 index 00000000..1605cb61 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example3.png new file mode 100644 index 00000000..bccb0294 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example4.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example4.png new file mode 100644 index 00000000..b5cec6b7 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example4.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example5.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example5.png new file mode 100644 index 00000000..00dbadd5 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example5.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example6.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example6.png new file mode 100644 index 00000000..9d1f70b3 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example6.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_tab.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_tab.png new file mode 100644 index 00000000..98783ed8 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_tab.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_vbox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_vbox.png new file mode 100644 index 00000000..488072fa Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/basics_example_vbox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BorderLayout.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BorderLayout.png new file mode 100644 index 00000000..665011d3 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BorderLayout.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BoxPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BoxPanel.png new file mode 100644 index 00000000..dc9bb2a0 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_BoxPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_CardPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_CardPanel.png new file mode 100644 index 00000000..1d0166a9 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_CardPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Grid.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Grid.png new file mode 100644 index 00000000..afec6e5b Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Grid.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_GridFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_GridFlex.png new file mode 100644 index 00000000..69e854f9 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_GridFlex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBox.png new file mode 100644 index 00000000..916a4979 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBoxFlex.png new file mode 100644 index 00000000..c161f950 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HBoxFlex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HButtonBox.png new file mode 100644 index 00000000..3a327a3f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_HButtonBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Panel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Panel.png new file mode 100644 index 00000000..ccfcff59 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_Panel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_ScrollingPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_ScrollingPanel.png new file mode 100644 index 00000000..7f1ff089 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_ScrollingPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_TabPanel.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_TabPanel.png new file mode 100644 index 00000000..412b0de3 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_TabPanel.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBox.png new file mode 100644 index 00000000..14b5e5b1 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBoxFlex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBoxFlex.png new file mode 100644 index 00000000..867daf87 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VBoxFlex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VButtonBox.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VButtonBox.png new file mode 100644 index 00000000..53bbaaf9 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bigicon_VButtonBox.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bookicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bookicon.gif new file mode 100644 index 00000000..7f86c41b Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/bookicon.gif differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_2.png new file mode 100644 index 00000000..928c5a8f Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_3.png new file mode 100644 index 00000000..cd48e213 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/colorbar_example_3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser1.png new file mode 100644 index 00000000..6186138a Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser2.png new file mode 100644 index 00000000..88b579ad Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser3.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser3.png new file mode 100644 index 00000000..096d9ef5 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser3.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser4.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser4.png new file mode 100644 index 00000000..5129b573 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoBrowser4.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoicon.gif new file mode 100644 index 00000000..c89e7acb Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/demoicon.gif differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/deploy.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/deploy.png new file mode 100644 index 00000000..eae1f872 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/deploy.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/greenarrowicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/greenarrowicon.gif new file mode 100644 index 00000000..5c5d0e40 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/greenarrowicon.gif differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide1.png new file mode 100644 index 00000000..ce9b11e1 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide2.png new file mode 100644 index 00000000..4e328f4a Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/guide2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ex.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ex.png new file mode 100644 index 00000000..50c5df29 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ex.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_fx.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_fx.png new file mode 100644 index 00000000..5ac8b7b8 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_fx.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_gs.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_gs.png new file mode 100644 index 00000000..2ab38963 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_gs.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_rn.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_rn.png new file mode 100644 index 00000000..142c6c0b Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_rn.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ug.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ug.png new file mode 100644 index 00000000..68381b54 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/help_ug.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/leftarrow.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/leftarrow.png new file mode 100644 index 00000000..b8ffd424 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/leftarrow.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pageicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pageicon.gif new file mode 100644 index 00000000..3d35fdb0 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pageicon.gif differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pagesicon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pagesicon.gif new file mode 100644 index 00000000..9278b1f1 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/pagesicon.gif differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/reficon.gif b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/reficon.gif new file mode 100644 index 00000000..44b05482 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/reficon.gif differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/rightarrow.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/rightarrow.png new file mode 100644 index 00000000..4bdf3ec9 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/rightarrow.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/titleimage.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/titleimage.png new file mode 100644 index 00000000..b9cd50bf Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/titleimage.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/uparrow.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/uparrow.png new file mode 100644 index 00000000..4590b67b Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/uparrow.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed1.png new file mode 100644 index 00000000..003f4428 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed2.png new file mode 100644 index 00000000..2d83f5ca Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_fixed2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_1.png new file mode 100644 index 00000000..7ba448a8 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_2.png new file mode 100644 index 00000000..185fad3a Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout0_2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout1.png new file mode 100644 index 00000000..185fad3a Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout2.png new file mode 100644 index 00000000..c8780a82 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno1.png new file mode 100644 index 00000000..30119a80 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno2.png new file mode 100644 index 00000000..dda90125 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_layout_anno2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized1.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized1.png new file mode 100644 index 00000000..94ce5e42 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized1.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized2.png b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized2.png new file mode 100644 index 00000000..fa4e8c59 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/Images/why_normalized2.png differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/LayoutsGUIDE.html b/studio_functions/GUI Layout Toolbox/layoutdoc/LayoutsGUIDE.html new file mode 100644 index 00000000..7feb0d60 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/LayoutsGUIDE.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/PanelDock.html b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelDock.html new file mode 100644 index 00000000..f04afe41 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelDock.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/PanelHelp.html b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelHelp.html new file mode 100644 index 00000000..12a7c42f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelHelp.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/PanelMinimize.html b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelMinimize.html new file mode 100644 index 00000000..d5d586de --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/PanelMinimize.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide.html new file mode 100644 index 00000000..2d81313a --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide.html @@ -0,0 +1,95 @@ + + + + + + + + User guide + + + + + + + + + + + +
GUI Layout Toolbox 2.3.5previous pagenext page
+ +

User guide Go back up one level

+

+ This chapter describes the purpose and overall design of the layout + tools that the toolbox provides. It also provides some examples of + creating some user interfaces using layouts. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Contents

+
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1.html new file mode 100644 index 00000000..57ac73c7 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1.html @@ -0,0 +1,76 @@ + + + + + + + Understanding layouts + + + + + + + + + +
User_guideprevious pagenext page
+ + +

1: Understanding layouts Go back up one level

+ +

The purpose of a "layout" is to manage the positioning of one + or more user-interface components. This means that instead of + worrying about the exact position of each user interface component + you instead worry about the relative positioning of them; are they + arranged in a vertical list, horizontal list, a grid pattern, etc.

+

The best way to understand what layouts are and why they are a good user-interface + design tool is to see some examples. The sections below go through the + basics of building an interface using layouts and how to build complex + interfaces using them.

+ + + + + + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_1.html new file mode 100644 index 00000000..f12c0c16 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_1.html @@ -0,0 +1,88 @@ + + + + + + + Layout basics + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.1: Layout basics Go back up one level

+ +

To see how layouts work, let's use the most basic layout, + a horizontal list (or box). We first create a window:

+ +
f = figure();
+
+ +

Now let's create the horizontal layout and add it to the figure. Note + that in common with other MATLAB graphics objects, one object is added to + another by setting the Parent property - this will automatically + adjust the list of Children in the parent object. The job of a + horizontal box layout is to arrange its contents in a horizontal line, + setting the position of each element to best fill the space:

+ +
layout = uix.HBox( 'Parent', f );
+
+

Nothing's changed! That's because the layout is for arranging + other user-interface components - it doesn't draw anything itself. Let's + add some buttons. Note how after creating each button the existing contents + of the box make room for the new addition; we don't need to set the position of + any user-interface component!

+ +
uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

..

+
+

Other layouts work in exactly the same way, although visually + the end-result is quite different:

+ +
f = figure();
+layout = uix.VBox( 'Parent', f );
+uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

+
+ +
f = figure();
+layout = uix.TabPanel( 'Parent', f );
+uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

+
+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_2.html new file mode 100644 index 00000000..16bed6ef --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_2.html @@ -0,0 +1,65 @@ + + + + + + + Types of layout + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.2: Types of layout Go back up one level

+ +

The layouts in this toolbox come in three forms:

+
    +
  1. Panels: show a single child element with some decoration. Other children + of the layout are hidden from view. The visible child can be switched. Available + panels include + Panel, + CardPanel, + BoxPanel, + TabPanel and + ScrollingPanel.
  2. + +
  3. Boxes: arrange children linearly in a single row or column. Available boxes include + HBox, + VBox, + HBoxFlex and + VBoxFlex.
  4. + +
  5. Grids: (also known as tables) arrange children in a two-dimensional grid. Available grids include + Grid and + GridFlex.
  6. + +
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_3.html new file mode 100644 index 00000000..4cd20b6e --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_3.html @@ -0,0 +1,94 @@ + + + + + + + Sizes and units + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.3: Sizes and units Go back up one level

+ +

In the previous section we noted that when using layouts + you never need to set the position or size of a user-interface + component yourself - the layouts take care of it. So how do + you control the sizes of the components?

+

Each layout that arranges multiple items within its drawing area + has a sizing property: for horizontal boxes this is Widths + and for vertical boxes Heights; for grids we have both Widths + and Heights. These all obey the same convention:

+
    +
  1. Positive numbers indicate sizes in pixels (similar to "pixel" units)
  2. +
  3. Negative numbers indicate a weighting for variable sizing (similar to "normalized" units)
  4. +
+

By default all sizes are set to -1 (variable size with unit weighting).

+

Let's take a simple example:

+ +
f = figure();
+layout = uix.HBox( 'Parent', f );
+uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

+
+

We can set the middle element to be twice as wide as the others + (but still variable width) by setting its weight to -2 with the others at -1:

+ +
layout.Widths = [-1 -2 -1]
+

+
+

Alternatively we might want the first element to have a + fixed width of 100 pixels with the others filling any remaining + space equally:

+ +
layout.Widths = [100 -1 -1]
+

+
+ +

This ability to mix fixed and variable sized elements is + crucial in interface design. It really comes into its own when building + a hierarchy of layouts, described next.

+ + + +

  +  1.3.1: + Minimum sizes Go back up one level

+

Many of the multi-element layouts also provide a MinimumWidths + or MinimumHeights + property to prevent an element becoming too small. This is measured in + pixels and defaults to one pixel. Take care to ensure that the available + space is at least the sum of the minimum sizes, plus any padding and + spacing.

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_4.html new file mode 100644 index 00000000..9186be9e --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_4.html @@ -0,0 +1,92 @@ + + + + + + + Layout hierarchies + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.4: Layout hierarchies Go back up one level

+ +

Consider the following simple interface:

+
+

Instead of thinking of this in terms of three elements that need + positioning, we can break it up into two simple linear ("box") arrangements: + a vertical box with the axes at the top and a control area at the bottom and + a horizontal box containing two buttons:

+
.
+

By placing the second layout (horizontal box) inside the first (vertical box) + we arrive at the complete layout. Since the sizes of the elements in each list + can be set to be fixed or flexible we can achieve a user-interface that is not just + arranged correctly when created, but also behaves well when resized.

+
+

Note that the buttons have stayed fixed height as the window grows and the + axes grow to fill the remaining space.

+ + +

  +  1.4.1: + Code: Go back up one level

+

The example above can be created programmically pretty + much as described in text + (the completed example code is here: + [ view + | edit + | run ] + )

+

1. Open a window

+
f = figure( 'Position', 200*ones(1,4) );
+

2. Create the first layout (vertical box)
Inside this vertical box + we place the axes

+
vbox = uix.VBox( 'Parent', f );
+axes( 'Parent', vbox );
+

+
+

3. Create the second layout (horizontal box)
Inside this horizontal box + we place two buttons

+
hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 2' );
+

+
+

4. Set the sizes
We want the axes to grow with the window so + set the first size to be -1 (which means variable size with wieght 1) and the buttons to stay fixed height so set the +second size to 35 (fixed height of 35 pixels)

+
set( vbox, 'Heights', [-1 35] )
+

+
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_5.html new file mode 100644 index 00000000..64340bcc --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide1_5.html @@ -0,0 +1,105 @@ + + + + + + + Why use layouts? + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.5: Why use layouts? Go back up one level

+ +

MATLAB ships with a GUI design tool called GUIDE. This + doesn't use layouts, but forces users to manually position each element. This approach + is a much faster way to build simple user-interfaces, so why would you want to +use layouts?

+

The over-riding reason for using layouts or layout managers is + to gain control of the resizing behaviour of the interface without + having to write a complex "ResizeFcn". If you simply position user-interface elements + directly (either using GUIDE or programmatically), you + have two choices about what happens when the window resizes: +

+

For example:

+ 1. The user-interface components scale with the window (normalised units)
We didn't really want the buttons to grow but everything resizes in proportion.
+
f = figure( 'Position', 200*ones(1,4) );
+axes( 'Parent', f, ...
+    'Units', 'Normalized', ...
+    'OuterPosition', [0.02 0.2 0.96 0.8] );
+uicontrol( 'Parent', f, ...
+    'Units', 'Normalized', ...
+    'Position', [0.02 0.02 0.46 0.16], ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', f, ...
+    'Units', 'Normalized', ...
+    'Position', [0.52 0.02 0.46 0.16], ...
+    'String', 'Button 2' );
+

.

+ + 2. The user-interface components stay fixed and the window resize creates empty space (pixel units)
Although the buttons don't now grow, neither does the axes, which looks very odd.
+
f = figure( 'Position', 200*ones(1,4) );
+axes( 'Parent', f, ...
+    'Units', 'Pixels', ...
+    'OuterPosition', [10 35 190 175] );
+uicontrol( 'Parent', f, ...
+    'Units', 'Pixels', ...
+    'Position', [5 5 90 25], ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', f, ...
+    'Units', 'Pixels', ...
+    'Position', [105 5 90 25], ...
+    'String', 'Button 2' );
+

.

+ +

Neither of these alternatives is particularly useful for a serious + user-interface. Typically there are user-interface components that should + be fixed size: icons, buttons, selectors etc; and others that should resize + with the window: graphs, images, prose text etc. To achieve this one needs + to be able to specify which interface components should be fixed size and + which variable. Over the last two decades, layouts have been shown to be + the method of choice for achieving this.

+

For example:

+ Using layouts, some user-interface components scale with the window, others stay fixed +
f = figure( 'Position', 200*ones(1,4) );
+vbox = uix.VBox( 'Parent', f );
+axes( 'Parent', vbox );
+hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 2' );
+set( vbox, 'Heights', [-1 35] )
+

.

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2.html new file mode 100644 index 00000000..cdf0f1c7 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2.html @@ -0,0 +1,68 @@ + + + + + + + Positioning axes + + + + + + + + + +
User_guideprevious pagenext page
+ + +

2: Positioning axes Go back up one level

+ + +

+ Unlike other MATLAB user interface components, axes + have two position properties: Position and + OuterPosition. This means one has some extra + options as to how the layout will arrange the axes. +

+ + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_1.html new file mode 100644 index 00000000..037e15a7 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_1.html @@ -0,0 +1,62 @@ + + + + + + + Position vs OuterPosition + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

2.1: Position vs OuterPosition Go back up one level

+ +

Typically one + would position some axes using their OuterPosition so that the + axis labels, title and other annotations are all contained within the + specified area. Sometimes, particularly if drawing images, one might want + to instead make the axes canvas (the white bit!) fill the specified area. + This is done by setting the Position property instead. +

+ +

For example:

+
figure
+axes( 'Units', 'Normalized', 'OuterPosition', [0 0 1 1] )
+                    
+

+ +
figure
+axes( 'Units', 'Normalized', 'Position', [0 0 1 1] )
+                    
+

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_2.html new file mode 100644 index 00000000..ade94859 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_2.html @@ -0,0 +1,92 @@ + + + + + + + Axes inside layouts + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

2.2: Axes inside layouts Go back up one level

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+

+ When using layouts to position axes, the position property + is set by the layout, not the user. Whether the Position + or OuterPosition property is used is determined by the + ActivePositionProperty property of the axes. + Note that the default setting is "outerposition". +

+

+ The following example illustrates the two usages. +

+ +

Open a window

+

Open a new figure window and remove the toolbar and menus.

+
window = figure( 'Name', 'Axes inside layouts', ...
+            'MenuBar', 'none', ...
+            'Toolbar', 'none', ...
+            'NumberTitle', 'off' );
+
+

Create the layout

+

The layout involves two axes side by side. This is done using a flexible horizontal box. The left-hand axes is left with the ActivePositionProperty set to "outerposition", but the right-hand axes is switched to use Position.

+
hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3);
+axes1 = axes( 'Parent', hbox, ...
+    'ActivePositionProperty', 'outerposition' );
+axes2 = axes( 'Parent', hbox, ...
+    'ActivePositionProperty', 'Position' );
+set( hbox, 'Widths', [-2 -1] );
+

+
+ +

Fill the axes

+

Using OuterPosition (left-hand axes) is the normal mode and looks good for virtually any plot type. Using Position is only really useful for 2D plots with the axes turned off, such as images.

+
x = membrane( 1, 15 );
+surf( axes1, x );
+lighting( axes1, 'gouraud' );
+shading( axes1, 'interp' );
+l = light( 'Parent', axes1 );
+camlight( l, 'head' );
+axis( axes1, 'tight' );
+
+imagesc( x, 'Parent', axes2 );
+set( axes2, 'xticklabel', [], 'yticklabel', [] );
+

+
+

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_3.html new file mode 100644 index 00000000..fb600398 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide2_3.html @@ -0,0 +1,85 @@ + + + + + + + Colorbars and legends + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

2.3: Colorbars and legends Go back up one level

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+

+ When using layouts to position axes that can also have a + colorbar or legend it is very important to group the axes + with its colorbar and legend by putting them inside a uicontainer. +

+

+ The following example illustrates this. +

+ +

Open a window

+

Open a new figure window and remove the toolbar and menus.

+
window = figure( 'Name', 'Axes legend and colorbars', ...
+            'MenuBar', 'none', ...
+            'Toolbar', 'none', ...
+            'NumberTitle', 'off' );
+
+ +

Create the layout

+

The layout involves two axes side by side. Each axes is placed into a uicontainer so that the legend and colorbar are "grouped" with the axes.

+
hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3);
+axes1 = axes( 'Parent', uicontainer('Parent', hbox) );
+axes2 = axes( 'Parent', uicontainer('Parent', hbox) );
+

+
+ +

Add decorations

+

Give the first axes a colorbar and the second axes a legend.

+
surf( axes1, membrane( 1, 15 ) );
+colorbar( axes1 );
+
+theta = 0:360; +plot( axes2, theta, sind(theta), theta, cosd(theta) ); +legend( axes2, 'sin', 'cos', 'Location', 'NorthWestOutside' );
+

+
+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3.html new file mode 100644 index 00000000..ae9dec48 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3.html @@ -0,0 +1,57 @@ + + + + + + + Controlling visibility + + + + + + + + + +
User_guideprevious pagenext page
+ + +

3: Controlling visibility Go back up one level

+ +

The examples in this section show the effect of setting the + Visible property on a layout object.

+ + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3_1.html new file mode 100644 index 00000000..8a2f9cd3 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide3_1.html @@ -0,0 +1,84 @@ + + + + + + + Visible example + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

3.1: Visible example Go back up one level

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+

+ This example shows how the Visible property can be + used to hide whole sections of an interface. +

+ + Open a window and add a panel +
fig = figure( 'Name', 'Visible example', ...
+    'Position', [100 100 150 250], ...
+    'MenuBar', 'none', ...
+    'ToolBar', 'none', ...
+    'NumberTitle', 'off' );
+panel = uix.BoxPanel( 'Parent', fig, 'Title', 'Panel' );
+

+
+ + Put some buttons inside the panel +
box = uix.VButtonBox( 'Parent', panel );
+uicontrol( 'Parent', box, 'String', 'Button 1' );
+uicontrol( 'Parent', box, 'String', 'Button 2' );
+uicontrol( 'Parent', box, 'String', 'Button 3', 'Visible', 'off' );
+uicontrol( 'Parent', box, 'String', 'Button 4' );
+uicontrol( 'Parent', box, 'String', 'Button 5', 'Visible', 'off' );
+uicontrol( 'Parent', box, 'String', 'Button 6' );
+

+
+ + Try hiding the panel +
set( panel, 'Visible', 'off' );
+

+
+ + Try showing the panel. Note that the original Visible state of each button is remembered. +
set( panel, 'Visible', 'on' );
+

+
+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4.html new file mode 100644 index 00000000..04e4fb9f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4.html @@ -0,0 +1,71 @@ + + + + + + + Advanced maneuvers with panels + + + + + + + + + +
User_guideprevious pagenext page
+ + +

4: Advanced maneuvers with panels Go back up one level

+ +

+ The uix.BoxPanel provides some extra buttons + and callbacks that can be used to design advanced user-interface + layouts. In particular, the sections below illustrate how to create + interfaces with context help, and panels that can be minimized or undocked. +

+ + + + + + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_1.html new file mode 100644 index 00000000..48e7bcfb --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_1.html @@ -0,0 +1,62 @@ + + + + + + + Context help + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

4.1: Context help Go back up one level

+ +

+ When a uix.BoxPanel has its HelpFcn + filled in, a help button (?) is shown in the upper-right of the + title-bar. When the user clicks this button the specified function + is called. +

+

For example:

+ Here we hookup the HelpFcn to simply bring up + the MATLAB documentation for each command. Clicking any of the "?" buttons + will cause the MATLAB help browser to open. +
f = figure( 'Name', 'uix.BoxPanel Help Example' );
+b = uix.HBox( 'Parent', f );
+uix.BoxPanel( 'Parent', b, 'Title', 'sin', 'HelpFcn', @(a,b) doc('sin') );
+uix.BoxPanel( 'Parent', b, 'Title', 'cos', 'HelpFcn', @(a,b) doc('cos') );
+uix.BoxPanel( 'Parent', b, 'Title', 'tan', 'HelpFcn', @(a,b) doc('tan') );
+
+

+ + + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_2.html new file mode 100644 index 00000000..dd9405ce --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_2.html @@ -0,0 +1,140 @@ + + + + + + + Minimize and maximize + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

4.2: Minimize and maximize Go back up one level

+ +

+ When a uix.BoxPanel has its MinimizeFcn + filled in, a minimize/maximize button (▴/▾) is shown in the upper-right of the + title-bar. When the user clicks this button the specified function + is called. Since the behaviour of the parent container is + different in different use-cases, it is up to the user to write + some code to actually resize the panel. Note that minimizing + a panel to its title-bar only really makes sense inside a + uix.VBox or uix.VBoxFlex. +

+

The following simple example shows how to add minimize/maximize + functionality to a box full of panels. Save the code into + a file called "minimizeexample.m" to run it.

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+ + +

Create the layout with three panels

+

Open a new figure window and add three panels.

+
function minimizeexample()
+width = 200;
+pheightmin = 20;
+pheightmax = 100;
+
+% Create the window and main layout
+fig = figure( 'Name', 'Collapsable GUI example', ...
+              'NumberTitle', 'off', ...
+              'Toolbar', 'none', ...
+              'MenuBar', 'none' );
+box = uix.VBox( 'Parent', fig );
+
+panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
+panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
+panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
+set( box, 'Heights', pheightmax*ones(1,3) );
+
+% Add some contents.
+uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} );
+
+% Resize the window
+pos = get( fig, 'Position' );
+set( fig, 'Position', [pos(1,1:2),width,sum(box.Heights)] );
+

+
+ +

Add the minimize/maximize callback

+

We set each panel to call the same minimize/maximize function. + This function is nested inside the main function so that it has access + to the main function's variables. A better way to do this is to make the +main function into a class, but this nested-function approach is fine +for simple applications.

+

Note that as soon as we set the "MinimizeFcn" property the minimize/maximize + icon appears in the top-right of each panel. We use a cell-array to pass an + extra argument, the panel number, to the minimize function. This extra argument appears after the usual + eventSource and eventData arguments.

+
% Hook up the minimize callback.
+set( panel{1}, 'MinimizeFcn', {@nMinimize, 1} );
+set( panel{2}, 'MinimizeFcn', {@nMinimize, 2} );
+set( panel{3}, 'MinimizeFcn', {@nMinimize, 3} );
+
+%-------------------------------------------------------------------------%
+ function nMinimize( eventSource, eventData, whichpanel ) + % A panel has been maximized/minimized + s = get( box, 'Heights' ); + pos = get( fig, 'Position' ); + panel{whichpanel}.Minimized = ~panel{whichpanel}.Minimized; + if panel{whichpanel}.Minimized + s(whichpanel) = pheightmin; + else + s(whichpanel) = pheightmax; + end  + set( box, 'Heights', s ); + + % Resize the figure, keeping the top stationary + delta_height = pos(1,4) - sum( box.Heights ); + set( fig, 'Position', pos(1,:) + [0 delta_height 0 -delta_height] ); + end % Minimize  + +end % Main function
+

+
+ + +

Click the minimize buttons

+

Minimizing the middle panel causes it to shrink to just its + title-bar and the window shrinks accordingly. The + "Minimize" icon is replaced by a "Maximise" icon.

+

+

Re-maximizing the panel would + cause it to re-appear in full and the window to grow again.

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_3.html new file mode 100644 index 00000000..00e25e98 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide4_3.html @@ -0,0 +1,154 @@ + + + + + + + Dock and undock + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

4.3: Dock and undock Go back up one level

+ + +

+ When a uix.BoxPanel has its DockFcn + filled in, a dock/undock button (↘/↗) is shown in the upper-right of the + title-bar. When the user clicks this button the specified function + is called. Since re-docking the panel into its previous parent + depends on the type of parent, it is up to the user to write + some code to actually extract or insert the panel. +

+

The following simple example shows how to add dock/undock + functionality to a box full of panels. Save the code into + a file called "dockexample.m" to run it.

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+ +

Create the layout with three panels

+

Open a new figure window and add three panels.

+
function dockexample()
+% Create the window and main layout
+fig = figure( 'Name', 'Dockable GUI example', ...
+              'NumberTitle', 'off', ...
+              'Toolbar', 'none', ...
+              'MenuBar', 'none', ...
+              'CloseRequestFcn', @nCloseAll );
+box = uix.HBox( 'Parent', fig );
+
+% Add three panels to the box
+panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
+panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
+panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
+
+% Add some contents
+uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} );
+

+
+ +

Add the dock/undock callback

+

We set each panel to call the same dock/undock function. + This function is nested inside the main function so that it has access + to the main function's variables. A better way to do this is to make the +main function into a class, but this nested-function approach is fine +for simple applications.

+

Note that as soon as we set the "DockFcn" property the Dock/Undock + icon appears in the top-right of each panel. We use a cell-array to pass an + extra argument, the panel number, to the minimize function. This extra argument appears after the usual + eventSource and eventData arguments.

+
% Set the dock/undock callback
+set( panel{1}, 'DockFcn', {@nDock, 1} ); +set( panel{2}, 'DockFcn', {@nDock, 2} ); +set( panel{3}, 'DockFcn', {@nDock, 3} ); + +%-------------------------------------------------------------------------%
+ function nDock( eventSource, eventData, whichpanel ) + % Set the flag + panel{whichpanel}.Docked = ~panel{whichpanel}.Docked; + if panel{whichpanel}.Docked + % Put it back into the layout + newfig = get( panel{whichpanel}, 'Parent' ); + set( panel{whichpanel}, 'Parent', box ); + delete( newfig ); + else  + % Take it out of the layout + pos = getpixelposition( panel{whichpanel} ); + newfig = figure( ... + 'Name', get( panel{whichpanel}, 'Title' ), ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'CloseRequestFcn', {@nDock, whichpanel} ); + figpos = get( newfig, 'Position' ); + set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] ); + set( panel{whichpanel}, 'Parent', newfig, ... + 'Units', 'Normalized', ... + 'Position', [0 0 1 1] ); + end  + end % nDock
+ + +

Add the close callback

+

If the user closes the main window we need to also close any + other windows that were created. This can be done by finding + the window that contains each panel and deleting it.

+
%-------------------------------------------------------------------------%
+ function nCloseAll( ~, ~ ) + for ii=1:numel( panel ) + if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' ) + figh = ancestor( panel{ii}, 'figure' ); + delete( figh ); + end  + end  + + end % nCloseAll +end % Main function
+

+
+ +

Click the dock buttons

+

Undocking the middle panel causes the other two to fill the + vacated space. The undocked panel appears in its own window, with the + "Undock" icon replaced by a "Dock" icon.

+

.

+

Re-docking the panel would + cause it to be appended to the right of the list in the original window. Closing the main window + causes all panels, docked or undocked, and their enclosing windows to be closed.

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide5.html new file mode 100644 index 00000000..a3df08ac --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide5.html @@ -0,0 +1,84 @@ + + + + + + + Using layouts inside GUIDE GUIs + + + + + + + + + +
User_guideprevious pagenext page
+ + +

5: Using layouts inside GUIDE GUIs Go back up one level

+ + +

Whilst the layouts in this toolbox do not integrate into the + MATLAB Graphical User Interface Design Environment (GUIDE), it + is possible to insert layouts into a GUIDE-built GUI as follows:

+

Create the GUIDE GUI

+

Create you GUIDE application as usual, placing a panel where you + want to insert the layout. You can turn the panel border and title + off if you do not want them.

+
+ +

Insert the layout

+

Edit the "OpeningFcn" in the GUIDE-created code and insert your + layout into the panel, making it fill the space. In the example below +four boxpanels are inserted into a grid, which itself is placed inside + uipanel1:

+ +
% --- Executes just before guideApp is made visible. 
+function guideApp_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for guideApp 
+handles.output = hObject;
+
+% Update handles structure 
+guidata(hObject, handles);
+
+% Put a layout in the panel 
+g = uix.GridFlex( 'Parent', handles.uipanel1, ...
+    'Units', 'Normalized', 'Position', [0 0 1 1], ...
+    'Spacing', 5 );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 1' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 2' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 3' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 4' );
+g.Heights = [-1 -1];
+

+
+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide6.html new file mode 100644 index 00000000..d07f9d22 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide6.html @@ -0,0 +1,56 @@ + + + + + + + Deploying GUIs using the MATLAB Compiler + + + + + + + + + +
User_guideprevious pagenext page
+ + +

6: Deploying GUIs using the MATLAB Compiler Go back up one level

+ + + +

Applications built using these layout tools can be deployed as standalone + executables using the MATLAB Compiler in + the same way as any other MATLAB application. There is, however, one thing to watch out for:

+
    +
  • You must explicitly include the "Resources" folder within the +uix package
  • +
+

Example

+

Below is a screen-shot of the deploytool setup + used to build the example application. + The "Resources" folder from the toolbox has been explicitly added as a +shared resource so that the mouse-pointers and panel icons continue to work.

+

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7.html new file mode 100644 index 00000000..7a9db9fd --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7.html @@ -0,0 +1,90 @@ + + + + + + + A complete example + + + + + + + + + +
User_guideprevious pagenext page
+ + +

7: A complete example Go back up one level

+ + + + +

The following example application uses many of the layout features + discussed above in order to create a good-looking user interface that + scales well when resized. It is not designed to showcase all the + layout functionality, but shows how callbacks are added to provide + user interaction. It also exemplifies separating the data from the GUI, + a fundamental part of creating modular and maintainable applications.

+

The full application is available here:

+ + + + + + + + + + + + + + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_1.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_1.html new file mode 100644 index 00000000..d5ce65aa --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_1.html @@ -0,0 +1,105 @@ + + + + + + + Application structure + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.1: Application structure Go back up one level

+ + +

There are many ways to build graphical applications in MATLAB, but + here we will take a very simple approach. If the application were to become +larger and more complex, this approach would be changed to better mitigate + the complexity. Some notes on this are contained at the end.

+ +

The application is structured as a single function with callbacks and other helper + functions stored as "nested" subfunctions, i.e. functions inside the main function. This has + the advantage that the nested subfunctions can share access to any variables + declared in the main function. This is also a risk as anything we accidentally + declare in the main function becomes "global" within the application. For that reason + all logic is put into subfunctions and we restrict the main + function to just declaring two shared variables:

+
    +
  • data: a structure containing all shared data
  • +
  • gui: a structure containing handles to GUI widgets
  • +
+

+function demoBrowser()
+
+   % Declare shared variables
+   data = createData();
+   gui = createInterface( data.DemoNames );
+
+   % Now update the GUI with the current data
+   updateInterface();
+   redrawDemo();
+   
+   % Helper subfunctions.
+   function data = createData() ... end;
+   function gui = createInterface(names) ... end;
+   function updateInterface() ... end;
+   function redrawDemo() ... end;
+
+   % Callback subfunctions.
+   function onMenuSelection() ... end;
+   function onListSelection() ... end;
+   function onDemoHelp() ... end;
+   function onHelp() ... end;
+   function onExit() ... end;
+
+end  % Main function
+
+ +

Note that all of the work is done in subfunctions. Most subfunctions +are callbacks executed when a button is pressed or a menu selected. The four used +at startup are helper functions:

+
    +
  • createData: build the structure which contains all application data
  • +
  • createInterface: build the user interface
  • +
  • updateInterface: update selectors etc in response to a change in the data
  • +
  • redrawDemo: redraw the plot part of the interface
  • +
+

We will not dig into all the subfunctions and callbacks, but instead + concentrate on the GUI creation (createInterface) + and update (updateInterface).

+ +

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_2.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_2.html new file mode 100644 index 00000000..ccc55e4a --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_2.html @@ -0,0 +1,105 @@ + + + + + + + createInterface + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.2: createInterface Go back up one level

+ +

The interface creation is handled in the createInterface + subfunction. This has two distinct sections: menu building and widget arrangement. + The menus are built using the standard MATLAB menu building command uimenu, + so let's concentrate on the widget arrangement.

+ +

The top-level layout is a horizontal arrangement, placing the controls +to the left of the main plot. We make the layout draggable by using the +"flex" variant of HBox, and put a panel in each side. Note that setting the +"HelpFcn" for the view panel adds a small "?" icon for bringing up help. See +here for more details.

+

+% Add the contents
+mainLayout = uix.HBoxFlex( 'Parent', gui.Window, 'Spacing', 3 );
+
+% Create the panels
+controlPanel = uix.BoxPanel( ...
+   'Parent', mainLayout, ...
+   'Title', 'Select a demo:' );
+gui.ViewPanel = uix.BoxPanel( ...
+   'Parent', mainLayout, ...
+   'Title', 'Viewing: ???', ...
+   'HelpFcn', @onDemoHelp );
+
+% Adjust the main layout
+set( mainLayout, 'Widths', [-1,-2] ); +
+

+
+

The controls panel is filled with a vertical layout containing the listbox +and a button. Note the callbacks that are specified for both the list and button. These +both call further subfunctions that are able to access the common "data" and "gui" +shared structures.

+

+% Create the controls
+controlLayout = uix.VBox( 'Parent', controlPanel, ...
+   'Padding', 3, 'Spacing', 3 );
+gui.ListBox = uicontrol( 'Style', 'list', ...
+   'BackgroundColor', 'w', ...
+   'Parent', controlLayout, ...
+   'String', demoList(:), ...
+   'Value', 1, ...
+   'Callback', @onListSelection);
+gui.HelpButton = uicontrol( 'Style', 'PushButton', ...
+   'Parent', controlLayout, ...
+   'String', 'Help for <demo>', ...
+   'Callback', @onDemoHelp );
+set( controlLayout, 'Heights', [-1 28] ); % Make the list fill the space
+
+

+
+

Finally, the view itself is simply an axes placed inside the view panel:

+

+% Create the view
+gui.ViewAxes = axes( 'Parent', gui.ViewPanel );
+   
+

+
+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_3.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_3.html new file mode 100644 index 00000000..9bf8a672 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_3.html @@ -0,0 +1,70 @@ + + + + + + + updateInterface + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.3: updateInterface Go back up one level

+ +

The second subfunction we will look at, updateInterface, uses the + current selections to update the interface. This uses the structure + "data" to update various parts of the interface. For this simple example this just means: +

+

1. Update the selected item in the listbox

+
set( gui.ListBox, 'Value', data.SelectedDemo );
+

2. Update the help button label

+
demoName = data.DemoNames{ data.SelectedDemo };
set( gui.HelpButton, 'String', ['Help for ',demoName] );
+

3. Update the view panel title

+
set( gui.ViewPanel, 'Title', sprintf( 'Viewing: %s', demoName ) );
+

4. Update the ticked menu

+
menus = get( gui.ViewMenu, 'Children' );
+set( menus, 'Checked', 'off' );
+% Use the name to work out which menu item should be ticked
+whichMenu = strcmpi( demoName, get( menus, 'Label' ) );
+set( menus(whichMenu), 'Checked', 'on' );
+
+

+

In general, this update function is called whenever the underlying + shared "data" structure is changed. This happens when the user clicks + a button, selects a list item or a menu. Next we will look at a typical + callback.

+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_4.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_4.html new file mode 100644 index 00000000..abf373ed --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_4.html @@ -0,0 +1,70 @@ + + + + + + + onListSelection + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.4: onListSelection Go back up one level

+ +

Finally, let's have a look at how one of the callbacks works: "onListSelection", the function + that is called when an item is selected in the listbox. The other + callbacks obey the same pattern.

+

The basic rule of thumb is that a callback should not update any part of + the user interface directly - it's job is to respond to user interaction by changing the "data" structure. + In this example, each callback changes the underlying data structure + then asks the interface to refresh. This might mean that things update in the +interface that don't need to, but ensures the callbacks remain simple and that all +interface update logic is in one place. Extending this to more granular interface updates + is straightforward. See Scalability for more details.

+

For the listbox callback, the "src" argument is a handle to the + listbox and we simply need to update the SelectedDemo field of "data" + to reflect the new selection. We then ask the rest of the interface to + update in response to the change. +

+

+                % User selected a demo from the list - update "data" and refresh
+data.SelectedDemo = get( src, 'Value' );
+updateInterface();
+redrawDemo();
+

+
+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_5.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_5.html new file mode 100644 index 00000000..3730b54f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_5.html @@ -0,0 +1,61 @@ + + + + + + + Running it + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.5: Running it Go back up one level

+ +

When the main function is launched (click + here) + it first creates the data, then the GUI, then updates the GUI using the data. At this point the + function exits and control is returned to the command prompt. Note, however, + that the GUI is still onscreen and will still respond to user interaction.

+

This works because the "shared" variables in the main function are not cleared when the + function exits. They are only cleared once the GUI is closed. This is a slightly + unusual, but very useful, feature of using nested functions for building + applications.

+

For example:

+
>> demoBrowser
+

+ +

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_6.html b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_6.html new file mode 100644 index 00000000..f4940c7b --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/User_guide7_6.html @@ -0,0 +1,60 @@ + + + + + + + Scalability + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.6: Scalability Go back up one level

+ +

As applications get bigger the code gets more complex. The simple + application structure used here does not scale well to large applications, + however some small adjustments can make life much better:

+
    +
  • Convert the "data" structure into a handle object. This allows + a single "data" object to be shared between mutliple graphical interfaces, and in turn means that the interface + need not be built as a single monolithic entity.
  • +
  • Use the events system to trigger updates + to specific parts of the GUI in response to bits of the data object changing. This removes the need + for a single large "UpdateInterface" function and reduces coupling between parts of the interface. For example, + the "SelectedDemo" property would have an associated event such that when it is changed by a callback (or from the command-line) it + notifies other interface components of the change. Each interface component (or group thereof) can + just listen for the events that affect it.
  • +
+

Advice on how to build large-scale applications is beyond the scope + of this document. If you need help in this area, please contact your MathWorks + account manager who will be able to put you in touch with a technical specialist.

+ + +
+ + + + + + + + + + © 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + +> diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/VisibleExample.html b/studio_functions/GUI Layout Toolbox/layoutdoc/VisibleExample.html new file mode 100644 index 00000000..ac5f7cf3 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/VisibleExample.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/about.html b/studio_functions/GUI Layout Toolbox/layoutdoc/about.html new file mode 100644 index 00000000..8e7fc660 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/about.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/atoz.html b/studio_functions/GUI Layout Toolbox/layoutdoc/atoz.html new file mode 100644 index 00000000..550482a0 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/atoz.html @@ -0,0 +1,181 @@ + + + + + GUI Layout Toolbox documentation: Index + + +
+ GUI Layout Toolbox 2.3.5 +
+

Alphabetical index

+
+ A - + B - + C - + D - + E - + F - + G - + H - + I - + J - + K - + L - + M +
+ N - + O - + P - + Q - + R - + S - + T - + U - + V - + W - + X - + Y - + Z +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

A

A complete exampleA complete example (User guide: 7)
AboutWhat is GUI Layout Toolbox? (Getting Started: 1)
AcknowledgementsAcknowledgements (Getting Started: 6)
Advanced maneuvers with panelsAdvanced maneuvers with panels (User guide: 4)
Application designA complete example (User guide: 7)
Application structureApplication structure (User guide: 7.1)
axesPositioning axes (User guide: 2)
Axes inside layoutsAxes inside layouts (User guide: 2.2)

B

Boxuix.HBox (Function reference: 2.1)
 uix.VBox (Function reference: 2.2)
 uix.HBoxFlex (Function reference: 2.3)
 uix.VBoxFlex (Function reference: 2.4)
BoxesBoxes (Function reference: 2)
BoxPaneluix.BoxPanel (Function reference: 1.3)
Button boxuix.HButtonBox (Function reference: 2.5)
 uix.VButtonBox (Function reference: 2.6)

C

CallbacksA complete example (User guide: 7)
CardPaneluix.CardPanel (Function reference: 1.2)
Colorbars and legendsColorbars and legends (User guide: 2.3)
Compatibility considerationsCompatibility considerations (Getting Started: 2)
CompilerDeploying GUIs using the MATLAB Compiler (User guide: 6)
Context helpContext help (User guide: 4.1)
Controlling visibilityControlling visibility (User guide: 3)
createInterfacecreateInterface (User guide: 7.2)

D

Deploying GUIs using the MATLAB CompilerDeploying GUIs using the MATLAB Compiler (User guide: 6)
Dock and undockDock and undock (User guide: 4.3)
Draggable dividersuix.HBoxFlex (Function reference: 2.3)
 uix.VBoxFlex (Function reference: 2.4)
 uix.GridFlex (Function reference: 3.2)

E

Emptyuix.Empty (Function reference: 4.1)
Examples(Examples)

F

Flexible layoutuix.HBoxFlex (Function reference: 2.3)
 uix.VBoxFlex (Function reference: 2.4)
FolderlayoutRoot (Function reference: 4.3)
Function reference(Function reference)

G

Getting Started(Getting Started)
Griduix.Grid (Function reference: 3.1)
GridFlexuix.GridFlex (Function reference: 3.2)
GridsGrids (Function reference: 3)
GUIDEUsing layouts inside GUIDE GUIs (User guide: 5)

H

HBoxuix.HBox (Function reference: 2.1)
HBoxFlexuix.HBoxFlex (Function reference: 2.3)
HButtonBoxuix.HButtonBox (Function reference: 2.5)
HelpSupport (Getting Started: 5)
Horizontal button layoutuix.HButtonBox (Function reference: 2.5)
Horizontal layoutuix.HBox (Function reference: 2.1)
 uix.HBoxFlex (Function reference: 2.3)

I

InstallationInstallation (Getting Started: 4)
Installation folderlayoutRoot (Function reference: 4.3)

L

Layout basicsLayout basics (User guide: 1.1)
Layout hierarchiesLayout hierarchies (User guide: 1.4)
layoutRootlayoutRoot (Function reference: 4.3)

M

MATLAB CompilerDeploying GUIs using the MATLAB Compiler (User guide: 6)
Minimize and maximizeMinimize and maximize (User guide: 4.2)
Minimum sizesSizes and units (User guide: 1.3.1)

O

onListSelectiononListSelection (User guide: 7.4)
Other functionsOther functions (Function reference: 4)

P

Paneluix.Panel (Function reference: 1.1)
PanelsPanels (Function reference: 1)
Position vs OuterPositionPosition vs OuterPosition (User guide: 2.1)
Positioning axesPositioning axes (User guide: 2)

R

Release notesRelease notes (Getting Started: 3)
RootlayoutRoot (Function reference: 4.3)
Running itRunning it (User guide: 7.5)

S

ScalabilityScalability (User guide: 7.6)
ScrollingPaneluix.ScrollingPanel (Function reference: 1.5)
Sizes and unitsSizes and units (User guide: 1.3)
SupportSupport (Getting Started: 5)

T

TabPaneluix.TabPanel (Function reference: 1.4)
Trackinguix.tracking (Function reference: 4.2)
Types of layoutTypes of layout (User guide: 1.2)

U

uix.BoxPaneluix.BoxPanel (Function reference: 1.3)
uix.CardPaneluix.CardPanel (Function reference: 1.2)
uix.Emptyuix.Empty (Function reference: 4.1)
uix.Griduix.Grid (Function reference: 3.1)
uix.GridFlexuix.GridFlex (Function reference: 3.2)
uix.HBoxuix.HBox (Function reference: 2.1)
uix.HBoxFlexuix.HBoxFlex (Function reference: 2.3)
uix.HButtonBoxuix.HButtonBox (Function reference: 2.5)
uix.Paneluix.Panel (Function reference: 1.1)
uix.ScrollingPaneluix.ScrollingPanel (Function reference: 1.5)
uix.TabPaneluix.TabPanel (Function reference: 1.4)
uix.trackinguix.tracking (Function reference: 4.2)
uix.VBoxuix.VBox (Function reference: 2.2)
uix.VBoxFlexuix.VBoxFlex (Function reference: 2.4)
uix.VButtonBoxuix.VButtonBox (Function reference: 2.6)
Understanding layoutsUnderstanding layouts (User guide: 1)
UndockDock and undock (User guide: 4.3)
UninstallInstallation (Getting Started: 4)
updateInterfaceupdateInterface (User guide: 7.3)
User guide(User guide)
Using layouts inside GUIDE GUIsUsing layouts inside GUIDE GUIs (User guide: 5)

V

VBoxuix.VBox (Function reference: 2.2)
VBoxFlexuix.VBoxFlex (Function reference: 2.4)
VButtonBoxuix.VButtonBox (Function reference: 2.6)
Vertical button layoutuix.VButtonBox (Function reference: 2.6)
Vertical layoutuix.VBox (Function reference: 2.2)
 uix.VBoxFlex (Function reference: 2.4)
Visible exampleVisible example (User guide: 3.1)

W

What is GUI Layout Toolbox?What is GUI Layout Toolbox? (Getting Started: 1)
Why use layouts?Why use layouts? (User guide: 1.5)
+
+ + +
+ Back to Top +
+ © 2020 The MathWorks Inc + Terms of Use + Patents + Trademarks + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/compatibility.html b/studio_functions/GUI Layout Toolbox/layoutdoc/compatibility.html new file mode 100644 index 00000000..b2d0ee7c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/compatibility.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserCreateInterface.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserCreateInterface.html new file mode 100644 index 00000000..a898794f --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserCreateInterface.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserOnListSelection.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserOnListSelection.html new file mode 100644 index 00000000..5716a18d --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserOnListSelection.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserRun.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserRun.html new file mode 100644 index 00000000..7e1365fe --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserRun.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserScalability.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserScalability.html new file mode 100644 index 00000000..e0958b95 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserScalability.html @@ -0,0 +1 @@ + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserStructure.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserStructure.html new file mode 100644 index 00000000..ce85576a --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserStructure.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserUpdateInterface.html b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserUpdateInterface.html new file mode 100644 index 00000000..83048e5d --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/demoBrowserUpdateInterface.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/doc.css b/studio_functions/GUI Layout Toolbox/layoutdoc/doc.css new file mode 100644 index 00000000..8a52a82c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/doc.css @@ -0,0 +1,95 @@ + H4 { color: rgb(153,0,0); + font-family: Arial,Helvetica,sans-serif; + font-weight: bold; + font-size: smallnormal; + } + + H3 { color: rgb(153,0,0); + font-family: Arial,Helvetica,sans-serif; + font-weight: bold; + font-size: large; + } + + H2 { color: rgb(153,0,0); + font-weight: bold; + font-size: x-large; + font-family: Arial,Helvetica,sans-serif; + } + + H1 { color: rgb(10,0,0); + font-weight: bold; + font-size: xx-large; + font-family: Arial,Helvetica,sans-serif; + } + + P { font-weight: normal; + font-style: normal; + color: rgb(0, 0, 32); + font-family: Arial,Helvetica,sans-serif; + text-decoration: none; + } + + LI { font-weight: normal; + font-style: normal; + color: rgb(0, 0, 32); + font-family: Arial,Helvetica,sans-serif; + text-decoration: none; + } + + A { font-weight: normal; + font-style: normal; + color: rgb(0,0,180, 0, 0); + font-family: Arial,Helvetica,sans-serif; + text-decoration: none; + } + + CODE { font-family: Courier New,Courier,monospace; + color: #000044; + font-size: -1; + } +CODE.FUNCTION { + color: #0000EE; + font-weight: bold; +} +CODE.INARG { + color: #008800; + font-weight: bold; +} +CODE.OUTARG { + color: #880000; + font-weight: bold; + } +CODE.COMMENT { + color: #008800; +} +CODE.STRING { + color: #DD00FF; +} + +TABLE.PROPERTYTABLE { + border-width: 3; + border-style: inset; + border-color: #777777; + cellpadding: 4; + cellspacing: 0; +} +TH.PROPERTYTABLE { + font-weight: bold; + color: #000000; + border-width: 2; + border-style: inset; + background-color: #b2b2b2; +} +TD.PROPERTYTABLE { + font-weight: normal; + color: #000000; + border-width: 2; + border-style: inset; + background-color: #f2f2f2; +} + +PRE { font-family: Courier New,Courier,monospace; + color: #000044; + font-size: -1; +} + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/frames.html b/studio_functions/GUI Layout Toolbox/layoutdoc/frames.html new file mode 100644 index 00000000..3b236e26 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/frames.html @@ -0,0 +1,12 @@ + + + + GUI Layout Documentation + + + + + + + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpindex.xml b/studio_functions/GUI Layout Toolbox/layoutdoc/helpindex.xml new file mode 100644 index 00000000..8d828521 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/helpindex.xml @@ -0,0 +1,118 @@ + + + + +A complete example +About +Acknowledgements +Advanced maneuvers with panels +Application design +Application structure +axes +Axes inside layouts +Box + uix.HBox (Function reference: 2.1) + uix.VBox (Function reference: 2.2) + uix.HBoxFlex (Function reference: 2.3) + uix.VBoxFlex (Function reference: 2.4) + +Boxes +BoxPanel +Button box + uix.HButtonBox (Function reference: 2.5) + uix.VButtonBox (Function reference: 2.6) + +Callbacks +CardPanel +Colorbars and legends +Compatibility considerations +Compiler +Context help +Controlling visibility +createInterface +Deploying GUIs using the MATLAB Compiler +Dock and undock +Draggable dividers + uix.HBoxFlex (Function reference: 2.3) + uix.VBoxFlex (Function reference: 2.4) + uix.GridFlex (Function reference: 3.2) + +Empty +Examples +Flexible layout + uix.HBoxFlex (Function reference: 2.3) + uix.VBoxFlex (Function reference: 2.4) + +Folder +Function reference +Getting Started +Grid +GridFlex +Grids +GUIDE +HBox +HBoxFlex +HButtonBox +Help +Horizontal button layout +Horizontal layout + uix.HBox (Function reference: 2.1) + uix.HBoxFlex (Function reference: 2.3) + +Installation +Installation folder +Layout basics +Layout hierarchies +layoutRoot +MATLAB Compiler +Minimize and maximize +Minimum sizes +onListSelection +Other functions +Panel +Panels +Position vs OuterPosition +Positioning axes +Release notes +Root +Running it +Scalability +ScrollingPanel +Sizes and units +Support +TabPanel +Tracking +Types of layout +uix.BoxPanel +uix.CardPanel +uix.Empty +uix.Grid +uix.GridFlex +uix.HBox +uix.HBoxFlex +uix.HButtonBox +uix.Panel +uix.ScrollingPanel +uix.TabPanel +uix.tracking +uix.VBox +uix.VBoxFlex +uix.VButtonBox +Understanding layouts +Undock +Uninstall +updateInterface +User guide +Using layouts inside GUIDE GUIs +VBox +VBoxFlex +VButtonBox +Vertical button layout +Vertical layout + uix.VBox (Function reference: 2.2) + uix.VBoxFlex (Function reference: 2.4) + +Visible example +What is GUI Layout Toolbox? +Why use layouts? + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfe b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfe new file mode 100644 index 00000000..db432f76 Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfe differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfs b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfs new file mode 100644 index 00000000..1f92793e Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.cfs differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.si b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.si new file mode 100644 index 00000000..d69cdbcf Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/_0.si differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments.gen b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments.gen new file mode 100644 index 00000000..63a7ec9a Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments.gen differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments_1 b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments_1 new file mode 100644 index 00000000..da81286a Binary files /dev/null and b/studio_functions/GUI Layout Toolbox/layoutdoc/helpsearch-v3/segments_1 differ diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.html b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.html new file mode 100644 index 00000000..2e1b12f9 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.html @@ -0,0 +1,37 @@ + + + + Table of Contents + + + + +  GUI Layout

+ +  
 Getting Started
+      1. What is GUI Layout Toolbox?
+      2. Compatibility considerations
+      3. Release notes
+      4. Installation
+      5. Support
+      6. Acknowledgements
+
+ +   Examples
+
+ +   User guide
+      1. Understanding layouts
+      2. Positioning axes
+      3. Controlling visibility
+      4. Advanced maneuvers with panels
+      5. Using layouts inside GUIDE GUIs
+      6. Deploying GUIs using the MATLAB Compiler
+      7. A complete example
+
+ +   Function reference
+
+   Index + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.xml b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.xml new file mode 100644 index 00000000..499b9bb4 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/helptoc.xml @@ -0,0 +1,12 @@ + + + + + GUI Layout + Getting Started1. What is GUI Layout Toolbox?2. Compatibility considerations3. Release notes4. Installation5. Support6. Acknowledgements + Examples + User guide1. Understanding layouts1.1. Layout basics1.2. Types of layout1.3. Sizes and units1.4. Layout hierarchies1.5. Why use layouts?2. Positioning axes2.1. Position vs OuterPosition2.2. Axes inside layouts2.3. Colorbars and legends3. Controlling visibility3.1. Visible example4. Advanced maneuvers with panels4.1. Context help4.2. Minimize and maximize4.3. Dock and undock5. Using layouts inside GUIDE GUIs6. Deploying GUIs using the MATLAB Compiler7. A complete example7.1. Application structure7.2. createInterface7.3. updateInterface7.4. onListSelection7.5. Running it7.6. Scalability + Function reference1. Panels1.1. uix.Panel1.2. uix.CardPanel1.3. uix.BoxPanel1.4. uix.TabPanel1.5. uix.ScrollingPanel2. Boxes2.1. uix.HBox2.2. uix.VBox2.3. uix.HBoxFlex2.4. uix.VBoxFlex2.5. uix.HButtonBox2.6. uix.VButtonBox3. Grids3.1. uix.Grid3.2. uix.GridFlex4. Other functions4.1. uix.Empty4.2. uix.tracking4.3. layoutRoot + Index + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/index.html b/studio_functions/GUI Layout Toolbox/layoutdoc/index.html new file mode 100644 index 00000000..5c68954c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/index.html @@ -0,0 +1,54 @@ + + + + + + GUI Layout Toolbox + + + + + + +

GUI Layout Toolbox

+ Version: 2.3.5 +

+ GUI Layout Toolbox is a layout manager for creating MATLAB graphical user + interfaces that resize gracefully. The classes supplied can be used in + combination to produce virtually any user interface layout. +

+ +
    +
  • Arrange MATLAB user interface components horizontally, vertically or in grids
  • +
  • Mix fixed- and variable-size components
  • +
  • Resize components interactively by dragging dividers
  • +
  • Show and hide components using tabs and panels
  • +
  • Show part of a large component in a scrollable panel
  • +
+ +

+ This toolbox was developed by + David Sampson and + Ben Tordoff from the + Consulting Services group + at MathWorks. +

+
title
+

Contents:

+ + + + + + + +
iconGetting Started: Introductory notes and installation instructions
iconExamples: A list of the examples that are provided in the documentation
iconUser guide: Describes how to use these tools
iconFunction reference: A list of the available functions
iconIndex: Alphabetical index of sections, functions and concepts
+
+ +
+

© 2020 The MathWorks Ltd + Terms of Use + Patents + Trademarks

+ + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/info.xml b/studio_functions/GUI Layout Toolbox/layoutdoc/info.xml new file mode 100644 index 00000000..ef78de74 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/info.xml @@ -0,0 +1,11 @@ + + + + +14 +GUI Layout +toolbox +$toolbox/matlab/icons/bookicon.gif +../layoutdoc + + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/layoutDocRoot.m b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutDocRoot.m new file mode 100644 index 00000000..3ae3cc13 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutDocRoot.m @@ -0,0 +1,12 @@ +function folder = layoutDocRoot() +%layoutDocRoot Return the location of the GUI Layout Toolbox documentation. +% +% folder = layoutDocRoot() +% +% See also: layoutRoot + +% Copyright 2014 The MathWorks, Inc. + +folder = fileparts( mfilename( 'fullpath' ) ); + +end % layoutDocRoot \ No newline at end of file diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/layoutRoot.html b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutRoot.html new file mode 100644 index 00000000..60ea04fe --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/layoutRoot.html @@ -0,0 +1 @@ + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/releasenotes.html b/studio_functions/GUI Layout Toolbox/layoutdoc/releasenotes.html new file mode 100644 index 00000000..b5881263 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/releasenotes.html @@ -0,0 +1 @@ + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/termsOfUse.m b/studio_functions/GUI Layout Toolbox/layoutdoc/termsOfUse.m new file mode 100644 index 00000000..386c744e --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/termsOfUse.m @@ -0,0 +1,8 @@ +function termsOfUse + if verLessThan('matlab','8.5') + helpview([matlabroot,'/license.txt']) + else + helpview([matlabroot,'/license_agreement.txt']) + end +end + diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.BoxPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.BoxPanel.html new file mode 100644 index 00000000..d0f551a1 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.BoxPanel.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.CardPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.CardPanel.html new file mode 100644 index 00000000..b439ef14 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.CardPanel.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Empty.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Empty.html new file mode 100644 index 00000000..18194480 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Empty.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Grid.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Grid.html new file mode 100644 index 00000000..eb460a34 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Grid.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.GridFlex.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.GridFlex.html new file mode 100644 index 00000000..4d9c55be --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.GridFlex.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBox.html new file mode 100644 index 00000000..02857cad --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBox.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBoxFlex.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBoxFlex.html new file mode 100644 index 00000000..6988221c --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HBoxFlex.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HButtonBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HButtonBox.html new file mode 100644 index 00000000..471742fb --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.HButtonBox.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Panel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Panel.html new file mode 100644 index 00000000..27078921 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.Panel.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.ScrollingPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.ScrollingPanel.html new file mode 100644 index 00000000..403cd9c9 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.ScrollingPanel.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.TabPanel.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.TabPanel.html new file mode 100644 index 00000000..740483a7 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.TabPanel.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBox.html new file mode 100644 index 00000000..d53bef34 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBox.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBoxFlex.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBoxFlex.html new file mode 100644 index 00000000..3e8d63c6 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VBoxFlex.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VButtonBox.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VButtonBox.html new file mode 100644 index 00000000..ebf2e984 --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.VButtonBox.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/layoutdoc/uix.tracking.html b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.tracking.html new file mode 100644 index 00000000..bdce69af --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/layoutdoc/uix.tracking.html @@ -0,0 +1 @@ + > diff --git a/studio_functions/GUI Layout Toolbox/license.txt b/studio_functions/GUI Layout Toolbox/license.txt new file mode 100644 index 00000000..60c73dcb --- /dev/null +++ b/studio_functions/GUI Layout Toolbox/license.txt @@ -0,0 +1,26 @@ +Copyright (c) 2020, The MathWorks, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* In all cases, the software is, and all modifications and derivatives of the + software shall be, licensed to you solely for use in conjunction with + MathWorks products and service offerings. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/studio_functions/GUIs/ERP Tab/binoper_studioGUI.fig b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.fig new file mode 100755 index 00000000..0489a3c6 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/binoper_studioGUI.m b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.m new file mode 100755 index 00000000..5a66387f --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/binoper_studioGUI.m @@ -0,0 +1,862 @@ + +% Note: very preliminary alfa version. Only for testing purpose. May 2008 +% +% HELP PENDING for this function +% Write erplab at command window for help +% +% +% Bin Operations: +% +% The ‘Bin Operations’ function allows you to compute RUN bins that are linear +% combinations of the bins in the current ERP structure. For example, you can +% average multiple bins together, and you can compute difference waves. It operates in the same manner as Channel Operations. That is, you create equations that look like this: “bin6 = 0.5*bin3 – 0.5*bin2”. This is like a simplified version of the erpmanip program in ERPSS. We will eventually create a more sophisticated version that has the same power as erpmanip. +% +% Your bins are stored in a Matlab structure named ERP, at binavg field +% (ERP.binvg). This field has 3 dimensions: +% +% row = channels +% column = points (signal) +% depth = bin's slot (bin index). +% +% So, the depth dimension will increase as you define a RUN bin, correctly +% numbered (sorted). To create a RUN bin you have simply to use an algebraic expression for that bin. +% +% Example: +% +% Currently you have 4 bins created, and now you need to create a RUN bin +% (bin 5) with the difference between bin 2 and 4. So, you should go to Bin +% Operation, at the ERPLAB menu, and this will pop up a RUN GUI. At the editing window enter the next simple expression: +% +% bin5 = bin2 - bin4 label Something Important +% +% and press APPEND. +% +% Note1: You can also write in a short style expression: b5 = b2 - b4. +% +% For label setting you could use : ...label Something Important or +% ....label = Something Important +% +% If you do not define a label, binoperator will use a short expression of +% the current formula as a label, BIN5: B2-B4 +% +% In case you need to create more than one RUN bin, you will need to enter +% a carriage return at the end of each expression (formula) as you are writing +% a list of algebraic expressions. +% +% Example: +% +% b5 = b2 - b4 label bla-bla +% b6 = (b1+b3)/2 label= attended or b6 = 0.5*b1 + 0.5*b3 ... +% b7 = abs(b5) label rectified or b7 = sqrt(b5^2) ... +% +% and press APPEND. +% +% Note 2: You already realized you can use bins just predefined in your list, +% so be cautious with this predefinition to avoid mistakes in long lists. +% +% Note 3: Also you can use more complex expressions as this: +% bin8 = (b1+b2)/2 - (b3+b4)/2 +% or, eventually, something much weirder as this b9 = sqrt(b2^2 + b3^2) +% +% Finally, you can save and load your formulas in order to avoid to rewrite +% it more than one time. Use EXPORT & IMPORT buttons for this, +% respectively. +% +% See pop_binoperator() +% +% Author: Javier Lopez-Calderon & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +% Begin initialization code - DO NOT EDIT + +function varargout = binoper_studioGUI(varargin) +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @binoper_studioGUI_OpeningFcn, ... + 'gui_OutputFcn', @binoper_studioGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function binoper_studioGUI_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for binoper_studioGUI +handles.output = []; +try + ERP = varargin{1}; + % + % Prepare List of current Bins + % + listb = []; + nbinmax = ERP.nbin; + for b=1:nbinmax + listb{b} = ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; + end + chanlocs = ERP.chanlocs; + bindescr = ERP.bindescr; +catch + ERP = []; + listb = ''; + nbinmax = 1; + chanlocs = []; +end +try + def = varargin{2}; + formulas = def{1}; + wbmsgon = def{2}; +catch + formulas = []; + wbmsgon = 1; +end + +example{1} = 'b$ = (b1+b3)/2 label attended left'; +example{2} = 'B$ = (B1+B3+B5)/3 label = attended left'; +example{3} = 'bin$ = sqrt(bin1^2+bin3^2) label distance'; +example{4} = 'b$ = (b1-b3)/(b1+b3) label = Special'; +example{5} = 'b$ = 0.5*b1+0.5*b3 label = attended left'; +example{6} = 'b$ = wavgbin(1,3) label = attended left (weighted)'; +example{7} = 'BIN$ = 0.5*b1 + 0.5*b3 label attended left'; +example{8} = sprintf('L=[1 3 5 7 9]\nR=[2 4 6 8 10]\nB$ = 0.5*b3@L + 0.5*b4@R label GLOBAL CONTRA'); + +handles.nbinmax = nbinmax; +handles.example = example; +handles.exacounter = 0; +handles.listname = []; +handles.chanlocs = chanlocs; +handles.bindescr = bindescr; + +% +% Name & version +% +erplab_studio_default_values; +version = erplabstudiover; + +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Bin Operation GUI']) + +%formulas = erpworkingmemory('binformulas'); + +label1 = 'Send file rather than individual equations'; +label2 = '(creates compact history)'; +set(handles.checkbox_sendfile2history, 'string',[label1 '
' label2]); +set(handles.listbox_bin,'String', listb) + +% +% Gui memory +% +binopGUI = erpworkingmemory('binopGUI'); + +if isempty(binopGUI) + set(handles.button_recursive,'Value', 1); % default is Modify existing ERPset (recursive updating) + set(handles.button_savelist, 'Enable','off') + + % + % File List + % + set(handles.edit_filelist,'String',''); + set(handles.checkbox_sendfile2history,'Value',0) +else + if binopGUI.emode==0 + set(handles.button_recursive,'Value', 1); + set(handles.button_no_recu,'Value', 0); + else + set(handles.button_recursive,'Value', 0); + set(handles.button_no_recu,'Value', 1); + end + if binopGUI.hmode==0 + set(handles.checkbox_sendfile2history,'Value', 0); + else + set(handles.checkbox_sendfile2history,'Value', 1); + end + set(handles.edit_filelist,'String', binopGUI.listname ); +end +if isempty(formulas) + set(handles.editor,'String',''); +else + if iscell(formulas) + set(handles.editor, 'String', formulas) + else + try + fid_formula = fopen( formulas ); + + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); + compacteditor(hObject, eventdata, handles); + set(handles.editor,'String',formulas); + fclose(fid_formula); + set(handles.button_savelist, 'Enable','on') + catch + end + end +end +%wbmsgon = erpworkingmemory('wbmsgon'); +if isempty(wbmsgon) || wbmsgon==0 + set(handles.bwarning,'Value', 0) +elseif wbmsgon==1 + set(handles.bwarning,'Value', 1) +else + set(handles.bwarning,'Value', 1) +end + +% +% Color GUI +% +handles = painterplabstudio(handles); + +% +% Set font size +% +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +helpbutton + +drawnow +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = binoper_studioGUI_OutputFcn(hObject, eventdata, handles) +% Get default command line output from handles structure + +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.5) + +%-------------------------------------------------------------------------- +function editor_Callback(hObject, eventdata, handles) + +compacteditor(hObject, eventdata, handles); + +handles.listname = []; +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function editor_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_help_Callback(hObject, eventdata, handles) +% doc pop_binoperator +web https://github.com/lucklab/erplab/wiki/ERP-Bin-Operations -browser + +%-------------------------------------------------------------------------- +function RUN_Callback(hObject, eventdata, handles) + +listname = handles.listname; +compacteditor(hObject, eventdata, handles); +formulalist = get(handles.editor,'String'); +wbmsgon = get(handles.bwarning,'Value'); + +if strcmp(formulalist,'') + msgboxText = 'You have not yet written a formula!'; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(msgboxText, title); + return +end +if size(formulalist,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end + +% +% Check formulas +% +if get(handles.button_recursive,'Value') + editormode = 0; +else + editormode = 1; +end +[option, recall, goeson] = checkformulas(cellstr(formulalist), 'binoperGUI', editormode); +if goeson==0 + return +end +if isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1 + BackERPLABcolor = [ 1 1 0]; + question = ['Equations at editor window have not been saved yet.\n'... + 'What would you like to do?']; + title = 'WARNING: Save List of edited bins'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Save and run','Run without saving', 'Cancel','Run without saving'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Save and run') + fullname = savelist(hObject, eventdata, handles); + listname = fullname; + handles.output = {listname, wbmsgon}; % sent filenam string) + elseif strcmpi(button,'Run without saving') + handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) + elseif strcmpi(button,'Cancel') || strcmpi(button,'') + handles.output = []; + handles.listname = []; + % Update handles structure + guidata(hObject, handles); + return + end +elseif isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 + handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) +elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1 + handles.output = {listname, wbmsgon}; % sent filename string +elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 + handles.output = {cellstr(formulalist), wbmsgon}; % sent like a cell string (with formulas) +end + +% erpworkingmemory('binformulas', formulalist); +% +% memory for Gui +% +binopGUI.emode = editormode; +binopGUI.hmode = get(handles.checkbox_sendfile2history,'Value'); +binopGUI.listname = listname; +erpworkingmemory('binopGUI', binopGUI); + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function eraser_Callback(hObject, eventdata, handles) +set(handles.editor, 'String','') +handles.output = []; +disp('Formulas were erased.') +set(handles.button_savelist, 'Enable','off') + +handles.listname = []; +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function help_Callback(hObject, eventdata, handles) + +fprintf('\n\n\n\n\n') +help pop_binoperator + +%-------------------------------------------------------------------------- +function button_saveaslist_Callback(hObject, eventdata, handles) +compacteditor(hObject, eventdata, handles); +fulltext = strtrim(get(handles.editor,'String')); + +if size(fulltext,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end +if ~strcmp(fulltext,'') + fullname = savelist(hObject, eventdata, handles); + if isempty(fullname) + return + end + set(handles.edit_filelist, 'String', fullname ) + set(handles.button_savelist, 'Enable', 'on') + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); +else + set(handles.button_saveaslist,'Enable','off') + msgboxText = 'You have not yet written a formula!'; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_saveaslist,'Enable','on') + return +end + +%-------------------------------------------------------------------------- +function button_loadlist_Callback(hObject, eventdata, handles) + +[filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file'); +if isequal(filename,0) + disp('User selected Cancel') + return +else + fullname = fullfile(filepath, filename); + disp(['pop_binoperation(): For formulas-file, user selected ', fullname]) +end +set(handles.edit_filelist,'String',fullname); +fid_formula = fopen( fullname ); +try + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); +catch + serr = lasterror; + msgboxText = ['Please, check your file:\n '... + fullname '\n'... + serr.message]; + title = 'ERPLAB: pop_binoperation() error:'; + errorfound(sprintf(msgboxText), title); + return +end +if size(formulas,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end + +compacteditor(hObject, eventdata, handles); +set(handles.editor,'String',formulas); +fclose(fid_formula); +set(handles.button_savelist, 'Enable','on') +handles.listname = fullname; + +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function listbox_bin_Callback(hObject, eventdata, handles) + +numbin = get(hObject, 'Value'); +if isempty(numbin) + return +end +linet = get(handles.editor, 'Value'); +if linet == 0 + linet = 1; +end +formulas = cellstr(get(handles.editor, 'String')); +formulas{linet} = [formulas{linet} 'b' num2str(numbin)]; +set(handles.editor, 'String', char(formulas)); + +%-------------------------------------------------------------------------- +function listbox_bin_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function button_example_Callback(hObject, eventdata, handles) +nbinmax = handles.nbinmax; +example = handles.example; +exacounter = handles.exacounter; +exacounter = exacounter + 1; + +if get(handles.button_no_recu,'Value') + prechar = 'n'; +else + prechar = ''; +end + +text = cellstr(get(handles.editor, 'String')); + +if isempty([text{:}]) || exacounter>length(example) + exacounter = 1; +end +if length(text)==1 && strcmp(text{1}, '') + exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter))); + text{1} = [prechar exacurr]; +else + exacurr = char(regexprep(example{exacounter},'\$',num2str(nbinmax+exacounter))); + text{end+1} = [prechar exacurr]; +end + +set(handles.editor, 'String', char(text)); +handles.exacounter = exacounter; +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function fullname = savelist(hObject, eventdata, handles) +fulltext = char(get(handles.editor,'String')); +if isempty(fulltext) + return +end +fullnamepre = get(handles.edit_filelist,'String'); + +% +% Save OUTPUT file +% +[filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save formulas-file as', fullnamepre); + +if isequal(filename,0) + disp('User selected Cancel') + fullname = []; + return +else + [px, fname, ext] = fileparts(filename); + + if strcmp(ext,'') + + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; + end + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); + set(handles.button_savelist, 'Enable','on') +end + +%-------------------------------------------------------------------------- +function compacteditor(hObject, eventdata, handles) +texteditor = strtrim(get(handles.editor,'String')); +if isempty(texteditor) + return +end + +formul = cellstr(texteditor); +nfl = length(formul); +k = 1; +formulalist = cell(1); + +for i=1:nfl + if ~strcmp(formul{i},'') + formulalist{k} = formul{i}; + k = k+1; + end +end + +formulalist = strtrimx(formulalist); +set(handles.editor,'String', char(formulalist)); + +%-------------------------------------------------------------------------- +function button_savelist_Callback(hObject, eventdata, handles) +compacteditor(hObject, eventdata, handles); +fulltext = strtrim(get(handles.editor,'String')); +if size(fulltext,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end +if ~strcmp(fulltext,'') + fullname = get(handles.edit_filelist, 'String'); + if ~strcmp(fullname,'') + + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); + disp(['Saving equation list at ' fullname '']) + else + button_saveaslist_Callback(hObject, eventdata, handles) + return + end +else + set(handles.button_saveaslist,'Enable','off') + msgboxText = 'You have not yet written a formula!'; + title = 'ERPLAB: binoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_saveaslist,'Enable','on') + return +end + +%-------------------------------------------------------------------------- +function checkbox_sendfile2history_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_filelist_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_filelist_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function button_clearfile_Callback(hObject, eventdata, handles) +set(handles.edit_filelist,'String',''); +set(handles.button_savelist, 'Enable', 'off') + +%-------------------------------------------------------------------------- +function button_recursive_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.button_no_recu,'Value',0) + val = testsyntaxtype(hObject, eventdata, handles, 'recu'); + + if val==0; + set(handles.button_recursive, 'Value', 0) + set(handles.button_no_recu, 'Value', 1) + end + + %%% handles = editorbackup(hObject, eventdata, handles); + %%% Update handles structure + %%guidata(hObject, handles); +else + set(hObject,'Value',1) +end + +% % % if get(hObject,'Value')==0 +% % % set(hObject,'Value',1) +% % % else +% % % set(handles.button_no_recu,'Value',0) +% % % end + +%-------------------------------------------------------------------------- +function button_no_recu_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.button_recursive,'Value',0) + val = testsyntaxtype(hObject, eventdata, handles, 'norecu'); + if val==0 + set(handles.button_recursive, 'Value', 1) + set(handles.button_no_recu, 'Value', 0) + end + %%% handles = editorbackup(hObject, eventdata, handles); + %%% Update handles structure + %%%guidata(hObject, handles); +else + set(hObject,'Value',1) +end + +% % % if get(hObject,'Value')==0 +% % % set(hObject,'Value',1) +% % % else +% % % set(handles.button_recursive,'Value',0) +% % % end + +%-------------------------------------------------------------------------- +function val = testsyntaxtype(hObject, eventdata, handles, whocall) +val = 1; +formulaArray = get(handles.editor,'String'); + +if isempty(formulaArray) + return +else + formulaArray = strtrim(cellstr(formulaArray)); +end +nformulas = length(formulaArray); +[expspliter parts] = regexp(formulaArray, '=','match','split'); +ask4fix = 1; +wantfix = 0; +newnumbin = 1; + +for t=1:nformulas + fcomm = formulaArray{t}; + tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013) + + if isempty(tokcommentb) % skip comment symbol + pleft = regexpi(parts{t}{1}, '(\s*nb[in]*\d+)', 'tokens'); + plcom = regexpi(parts{t}{1}, '(\s*b[in]*\d+)', 'tokens'); + + if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For non recursive mode, left side of equation\nmust be define as a new bin.\n'... + 'For instance, nbin1 = ...\n\n'... + 'Do you want that ERPLAB corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for non recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix = 1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + elseif ~isempty(pleft) && strcmpi(whocall,'recu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For recursive mode, left side of equation cannot\nbe define as a new bin.\n'... + 'For instance, you must write bin1 = ...\n\n'... + 'Do you want that ERPLAB corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix =1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + %else + % wantfix = 0; + + end + if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC + fprintf('WARNING: equation %s ', formulaArray{t}) + if strcmpi(whocall,'recu') % for recursive mode delete the n in nch + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2})); + else + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*b(\D*)(\d*)',['nb$1' num2str(newnumbin)],'ignorecase')), strtrim(parts{t}{2})); + newnumbin = newnumbin+1; + end + fprintf('was changed to equation %s \n', formulaArray{t}) + end + end +end +if val==1 + set(handles.editor,'String', char(formulaArray)); +end + +%-------------------------------------------------------------------------- +function bwarning_Callback(hObject, eventdata, handles) +% if get(hObject,'Value') +% % +% % Gui memory +% % +% erpworkingmemory('wbmsgon', 1); +% else +% % +% % Gui memory +% % +% erpworkingmemory('wbmsgon', 0); +% end + +%-------------------------------------------------------------------------- +function pushbutton_contraipsi_assistant_Callback(hObject, eventdata, handles) + +chanlocs = handles.chanlocs; +bindescr = handles.bindescr; + +% +% Call GUI for assistant +% +formcell = contraipsiGUI(chanlocs, bindescr); +if isempty(formcell) + disp('User selected Cancel') + return +end +formulas = char(formcell{:}); +set(handles.editor,'String',formulas); +set(handles.button_recursive,'Value',0); +set(handles.button_no_recu,'Value',1); + + +%-------------------------------------------------------------------------- +function bwarning_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function cancel_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function RUN_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function panel1_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_example_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function eraser_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function help_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_loadlist_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_savelist_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_saveaslist_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_clearfile_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_recursive_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function button_no_recu_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function checkbox_sendfile2history_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function pushbutton_export_bin_list_Callback(hObject, eventdata, handles) +list_of_bins = get(handles.listbox_bin,'String'); +nlob = length(list_of_bins); +for i=1:nlob + fprintf('%s\n',list_of_bins{i}); +end +fprintf('\n\nEnd of list.\n\n') + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + % The GUI is still in UIWAIT, us UIRESUME + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/csd_chan_locations.fig b/studio_functions/GUIs/ERP Tab/csd_chan_locations.fig new file mode 100755 index 00000000..6c7bbb55 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/csd_chan_locations.fig differ diff --git a/studio_functions/GUIs/ERP Tab/csd_chan_locations.m b/studio_functions/GUIs/ERP Tab/csd_chan_locations.m new file mode 100755 index 00000000..b58d4c8b --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/csd_chan_locations.m @@ -0,0 +1,338 @@ +function varargout = csd_chan_locations(varargin) +% CSD_CHAN_LOCATIONS MATLAB code for csd_chan_locations.fig +% CSD_CHAN_LOCATIONS, by itself, creates a new CSD_CHAN_LOCATIONS or raises the existing +% singleton*. +% +% H = CSD_CHAN_LOCATIONS returns the handle to a new CSD_CHAN_LOCATIONS or the handle to +% the existing singleton*. +% +% CSD_CHAN_LOCATIONS('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in CSD_CHAN_LOCATIONS.M with the given input arguments. +% +% CSD_CHAN_LOCATIONS('Property','Value',...) creates a new CSD_CHAN_LOCATIONS or raises +% the existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before csd_chan_locations_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to csd_chan_locations_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help csd_chan_locations + +% Last Modified by GUIDE v2.5 10-Aug-2022 21:02:42 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @csd_chan_locations_OpeningFcn, ... + 'gui_OutputFcn', @csd_chan_locations_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +% --- Executes just before csd_chan_locations is made visible. +function csd_chan_locations_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to csd_chan_locations (see VARARGIN) + +% Choose default command line output for csd_chan_locations +handles.output = hObject; + +% +% Color GUI +% +%handles = painterplab(handles); + +% +% Set font size +% +%handles = setfonterplab(handles); + +% initialise with defaults +handles.mcont = 4; +handles.smoothl = 0.00001; +handles.headrad = 10; + +handles.csdsave = 1; + +handles.output = []; + + +axes(hObject) + +path_to_pic = which('CSD_elec_plot.png'); +if numel(path_to_pic) ~= 0 % iff a path to the pic exists, show it + imshow('CSD_elec_plot.png') +end + + +% Update handles structure +guidata(hObject, handles); + + + + + +% help +% helpbutton + +% UIWAIT makes csd_chan_locations wait for user response (see UIRESUME) +uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = csd_chan_locations_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; +% The figure can be deleted now +delete(handles.figure1); +pause(0.1) + + + + + +% --- Executes on button press in generate. +function generate_Callback(hObject, eventdata, handles) +% hObject handle to generate (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Sanity-check output +% if isa(handles.mcont,'double') ~= 1 || isnan(handles.mcont) +% ertext = 'mcont was set to 4'; +% disp(ertext) +% handles.mcont = 4; +% end +% +% % beep +% % disp('X was not a Y'); +% +% handles.output = []; + + + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.figure1); + +% --- Executes on button press in reset. +% function reset_Callback(hObject, eventdata, handles) +% % hObject handle to reset (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% web('http://psychophysiology.cpmc.columbia.edu/software/CSDtoolbox/index.html','-browser'); + + + +% -------------------------------------------------------------------- +function initialize_gui(fig_handle, handles, isreset) +% If the metricdata field is present and the reset flag is false, it means +% we are we are just re-initializing a GUI by calling it from the cmd line +% while it is up. So, bail out as we dont want to reset the data. + + + + + +% Update handles structure +guidata(handles.figure1, handles); + + + +% function mcont_Callback(hObject, eventdata, handles) +% % hObject handle to mcont (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% +% % Hints: get(hObject,'String') returns contents of mcont as text +% % str2double(get(hObject,'String')) returns contents of mcont as a double +% mcont = str2double(get(hObject,'String')); +% +% % We don't want to return the new value if the input was not a double +% if isnan(mcont) +% beep +% disp('Please ensure that the input was a number.'); +% set(hObject,'String','4'); +% else +% % input seems valid +% % Save the new value +% handles.mcont = mcont; +% guidata(hObject,handles) +% end + + + +% --- Executes during object creation, after setting all properties. +function mcont_CreateFcn(hObject, eventdata, handles) +% hObject handle to mcont (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function uipanel1_CreateFcn(hObject, eventdata, handles) +% hObject handle to uipanel1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + + +% function lambdabox_Callback(hObject, eventdata, handles) +% % hObject handle to lambdabox (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% +% % Hints: get(hObject,'String') returns contents of lambdabox as text +% % str2double(get(hObject,'String')) returns contents of lambdabox as a double +% smoothl = str2double(get(hObject,'String')); +% +% % We don't want to save the new value if the input was not a double +% if isnan(smoothl) +% beep +% disp('Please ensure that the input was a number.'); +% set(hObject,'String','0.00001'); +% else +% % input seems valid +% % Save the new value +% handles.smoothl = smoothl; +% guidata(hObject,handles) +% end + + + +% --- Executes during object creation, after setting all properties. +function lambdabox_CreateFcn(hObject, eventdata, handles) +% hObject handle to lambdabox (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +% function headradbox_Callback(hObject, eventdata, handles) +% % hObject handle to headradbox (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% +% % Hints: get(hObject,'String') returns contents of headradbox as text +% % str2double(get(hObject,'String')) returns contents of headradbox as a double +% headrad = str2double(get(hObject,'String')); +% +% % We don't want to return the new value if the input was not a double +% if isnan(headrad) +% beep +% disp('Please ensure that the input was a number.'); +% set(hObject,'String','10'); +% else +% % input seems valid +% % Save the new value +% handles.headrad = headrad; +% guidata(hObject,handles) +% end + + +% --- Executes during object creation, after setting all properties. +function headradbox_CreateFcn(hObject, eventdata, handles) +% hObject handle to headradbox (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + + + + +% --- Executes on button press in savenew. +function savenew_Callback(hObject, eventdata, handles) +% hObject handle to savenew (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of savenew +csdsave = get(hObject,'Value'); +% Save the new value +handles.csdsave = 1; +guidata(hObject,handles) + + +% --- Executes when user attempts to close figure1. +function figure1_CloseRequestFcn(hObject, eventdata, handles) +% hObject handle to figure1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +handles.output = [handles.mcont handles.smoothl handles.headrad handles.csdsave]; + + +if isequal(get(handles.figure1, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.figure1); +else + % The GUI is no longer waiting, just close it + delete(handles.figure1); +end + + +% --- Executes during object creation, after setting all properties. +function bigheadplot_CreateFcn(hObject, eventdata, handles) +% hObject handle to bigheadplot (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: place code in OpeningFcn to populate bigheadplot + +axes(hObject) + +path_to_pic = which('CSD_elec_plot.png'); +if numel(path_to_pic) ~= 0 % iff a path to the pic exists, show it + imshow('CSD_elec_plot.png') +end + + +% % --- Executes on button press in pushbutton_help. +% function pushbutton_help_Callback(hObject, eventdata, handles) +% % hObject handle to pushbutton_help (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% web https://github.com/lucklab/erplab/wiki/Current-Source-Density-(CSD)-tool -browser diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_CSD_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_CSD_GUI.m new file mode 100755 index 00000000..98d47310 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_CSD_GUI.m @@ -0,0 +1,306 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_CSD_GUI(varargin) +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +gui_erp_CSD = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global ERP_CSD_gui; +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + ERP_CSD_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'Convert Voltage to CSD', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_CSD_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Convert Voltage to CSD', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_CSD_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Convert Voltage to CSD', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_bin_operation(FonsizeDefault); +varargout{1} = ERP_CSD_gui; + + function drawui_erp_bin_operation(FonsizeDefault) + FontSize_defualt = FonsizeDefault; + + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + %%--------------------channel and bin setting---------------------- + gui_erp_CSD.DataSelBox = uiextras.VBox('Parent', ERP_CSD_gui,'BackgroundColor',ColorB_def); + + %%Display the lacations of electrodes: may use other function to + %%replace current one. + % gui_erp_CSD.erp_h_erp = uicontrol('Style','radiobutton','Parent', gui_erp_CSD.erp_history_title,'String','ERP','callback',@ERP_H_ERP,'Value',0); % 2F + gui_erp_CSD.erp_history_table = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_CSD.erp_h_erp = axes( 'Parent', gui_erp_CSD.erp_history_table, 'ActivePositionProperty', 'Position'); + set( gui_erp_CSD.erp_h_erp,'xticklabel', [], 'yticklabel', []); + + + %%Parameters + gui_erp_CSD.sif_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_CSD.sif_text = uicontrol('Style','text','Parent', gui_erp_CSD.sif_title,... + 'String','Spline interpolation flexibility m-constant value (4 is recommended)','FontSize',FontSize_defualt,'Max',10,'BackgroundColor',ColorB_def); % 2F + + gui_erp_CSD.sif_num = uicontrol('Style','edit','Parent', gui_erp_CSD.sif_title,... + 'String','4','FontSize',FontSize_defualt,'Enable',Enable_label,'callback',@csd_sif); % 2F + set(gui_erp_CSD.sif_title,'Sizes',[210,50]); + + gui_erp_CSD.scl_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_CSD.scl_text = uicontrol('Style','text','Parent', gui_erp_CSD.scl_title,... + 'String','Smoothing constant lambda (0.00001 is recommended)','FontSize',FontSize_defualt,'Max',10,'BackgroundColor',ColorB_def); % 2F + + gui_erp_CSD.scl_num = uicontrol('Style','edit','Parent', gui_erp_CSD.scl_title,... + 'String','0.00001','FontSize',FontSize_defualt,'Enable',Enable_label,'callback',@csd_scl); % 2F + set(gui_erp_CSD.scl_title,'Sizes',[210,50]); + + gui_erp_CSD.hr_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_CSD.hr_text = uicontrol('Style','text','Parent', gui_erp_CSD.hr_title,... + 'String','Head radius CSD rescaling values (10cm is recommended)','FontSize',FontSize_defualt,'Max',10,'BackgroundColor',ColorB_def); % 2F + + gui_erp_CSD.hr_num = uicontrol('Style','edit','Parent', gui_erp_CSD.hr_title,... + 'String','10','FontSize',FontSize_defualt,'Enable',Enable_label,'callback',@csd_hr); % 2F + set(gui_erp_CSD.hr_title,'Sizes',[210,50]); + + + %%-----------------Run--------------------------------------------- + gui_erp_CSD.run_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_CSD.run_title); + gui_erp_CSD.run = uicontrol('Style','pushbutton','Parent',gui_erp_CSD.run_title,... + 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + uiextras.Empty('Parent', gui_erp_CSD.run_title); + set(gui_erp_CSD.run_title,'Sizes',[85 90 85]); + + gui_erp_CSD.location_title = uiextras.HBox('Parent', gui_erp_CSD.DataSelBox,'BackgroundColor',ColorB_def); + uicontrol('Style','pushbutton','Parent',gui_erp_CSD.location_title,... + 'String','?','callback',@tool_link,'FontSize',16,'BackgroundColor',[1 1 1],'Max',10); % 2F + gui_erp_CSD.location = uicontrol('Style','pushbutton','Parent',gui_erp_CSD.location_title,... + 'String','Expand Locations','callback',@CSD_undock_loct,'FontSize',FontSize_defualt,'BackgroundColor',[1 1 1],'Enable',Enable_label); % 2F + set(gui_erp_CSD.DataSelBox,'Sizes',[230,40,40,40,30,30]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + + function CSD_undock_loct(~,~) + %%https://github.com/lucklab/erplab/wiki/Current-Source-Density-(CSD)-tool -browser + csd_chan_locations; + end +%%-------------------Setting value for Spline interpolation flexibility m-constant value---------------- + function csd_sif(source,~) + mcont = str2double(source.String); + if isnan(mcont) + gui_erp_CSD.sif_num.String=4; + beep; + msgboxText = ['Convert voltage to CSD - Please ensure that the input was a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + % input seems valid + % Save the new value + gui_erp_CSD.sif_num.String = mcont; + end + end + +%%-------------------Setting value for Smoothing constant lambda--------------------------------------- + function csd_scl(source,~) + mcont = str2double(source.String); + if isnan(mcont) + gui_erp_CSD.scl_num.String=4; + beep; + msgboxText = ['Convert voltage to CSD - Please ensure that the input was a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + % input seems valid + % Save the new value + gui_erp_CSD.scl_num.String = mcont; + end + end + +%%-------------------setting Head radius CSD rescaling values--------------------------------------- + function csd_hr(source,~) + mcont = str2double(source.String); + + if isnan(mcont) + gui_erp_CSD.hr_num.String=4; + beep; + msgboxText = ['Convert voltage to CSD - Please ensure that the input was a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + % input seems valid + % Save the new value + gui_erp_CSD.hr_num.String = mcont; + end + end + +%%---------------------CSD tool link------------------------------------- + function tool_link(~,~) + web('https://github.com/lucklab/erplab/wiki/Current-Source-Density-(CSD)-tool','-browser'); + end +%%---------------------Run------------------------------------------------- + function apply_run(~,~) + + csd_param(1) = str2double(gui_erp_CSD.sif_num.String); + csd_param(2) = str2double(gui_erp_CSD.scl_num.String); + csd_param(3) = str2double(gui_erp_CSD.hr_num.String); + csd_param(4) = 1; + erpworkingmemory('csd_param',csd_param); + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + beep; + msgboxText = ['Convert voltage to CSD - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + %%---------------------Compute CSD for each ERPset---------------- + try + erpworkingmemory('f_ERP_proces_messg','Convert Voltage to CSD'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + % Set names of slected ERPsets + Save_file_label = 0; + Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selectederp_Index,'_CSD'); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + + if ~isempty(Answer{1}) + ALLERP_out = Answer{1}; + Save_file_label = Answer{2}; + end + + %%Loop for the selcted ERPsets + for Numofselectederp = 1:numel(Selectederp_Index) + ERP = ALLERP_out(Selectederp_Index(Numofselectederp)); + [ERP, ERPCOM] = pop_currentsourcedensity(ERP); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + %%display the loctions of electrodes for each selected ERPsets. + path_to_pic = which('CSD_elec_plot.png'); + if numel(path_to_pic) ~= 0 % iff a path to the pic exists, show it + myImage = imread('CSD_elec_plot.png'); + imshow(myImage,'Parent',gui_erp_CSD.erp_h_erp); + end + + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP;%%Save the transformed ERPset + if Save_file_label==1 + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end%%Loop for ERPsets end + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('f_ERP_bin_opt',1); + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1:length(observe_ERPDAT.ALLERP)]; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + return; + catch + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + Selected_ERP_afd =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%% + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%--------Setting current ERPset/session history based on the current updated ERPset------------ + function Count_currentERPChanged(~,~) + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + + if isempty(Selectederp_Index) + beep; + msgboxText = ['Convert voltage to CSD - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + checked_curr_index = 1; + else + checked_curr_index = 0; + end + if isempty(checked_ERPset_Index) + checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index); + end + if checked_curr_index || any(checked_ERPset_Index(:)) + Enable_label = 'off'; + + else + Enable_label = 'on'; + + end + gui_erp_CSD.run.Enable = Enable_label; + gui_erp_CSD.sif_num.Enable = Enable_label; + gui_erp_CSD.scl_num.Enable = Enable_label; + gui_erp_CSD.hr_num.Enable = Enable_label; + gui_erp_CSD.location.Enable = Enable_label; + end +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_append_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_append_GUI.m new file mode 100644 index 00000000..d0fa6348 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_append_GUI.m @@ -0,0 +1,555 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_append_GUI(varargin) +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); +% addlistener(observe_ERPDAT,'Process_messg_change',@Process_messg_change); + +gui_erp_append = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erp_history; + +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end + +if nargin == 0 + fig = figure(); % Parent figure + box_erp_history = uiextras.BoxPanel('Parent', fig, 'Title', 'Append ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Append ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def); +else + box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Append ERPsets', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_append(FonsizeDefault); +varargout{1} = box_erp_history; + + function drawui_erp_append(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + %%--------------------channel and bin setting---------------------- + gui_erp_append.DataSelBox = uiextras.VBox('Parent', box_erp_history,'BackgroundColor',ColorB_def); + + gui_erp_append.erpappend_select_title = uiextras.HBox('Parent', gui_erp_append.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_append.erpappend_select_title); + + gui_erp_append.sameerpset = uicontrol('Style','radiobutton','Parent', gui_erp_append.erpappend_select_title,'String','Same as ERPset Panel',... + 'callback',@same_to_erpset,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'Value',1); % 2F + + gui_erp_append.erpset_custom = uicontrol('Style','radiobutton','Parent',gui_erp_append.erpappend_select_title,'String','Custom',... + 'callback',@erpsetcutom,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'Value',0); + set(gui_erp_append.erpappend_select_title, 'Sizes',[50 145 70]); + + gui_erp_append.erp_append_title = uiextras.HBox('Parent', gui_erp_append.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_append.erp_h_all = uicontrol('Style','text','Parent',gui_erp_append.erp_append_title,'String','ERPsets',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'HorizontalAlignment','left'); % 2F + gui_erp_append.erpset_edit = uicontrol('Style','edit','Parent', gui_erp_append.erp_append_title,'String',' ',... + 'callback',@erpset_edit,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable','off'); % 2F + set(gui_erp_append.erp_append_title, 'Sizes',[65 200]); + + + gui_erp_append.advance_help_title = uiextras.HBox('Parent',gui_erp_append.DataSelBox,'Spacing',1,'BackgroundColor',ColorB_def); + % uiextras.Empty('Parent', gui_erp_append.advance_help_title); + uicontrol('Style', 'pushbutton','Parent',gui_erp_append.advance_help_title,'String','?','callback',@erpset_append_help,'Enable','on','FontSize',16); + % uiextras.Empty('Parent', gui_erp_append.advance_help_title); + gui_erp_append.append_advance = uicontrol('Style', 'pushbutton','Parent',gui_erp_append.advance_help_title,... + 'String','Advanced','callback',@advance_erpappend,'FontSize',FonsizeDefault); + gui_erp_append.append_run = uicontrol('Style', 'pushbutton','Parent',gui_erp_append.advance_help_title,'String','Run',... + 'callback',@append_run,'FontSize',FonsizeDefault); + + set(gui_erp_append.DataSelBox,'Sizes',[30 25 30]); + + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + Enableflag = 'off'; + else + Enableflag = 'on'; + end + gui_erp_append.erpset_edit.Enable = Enableflag; + gui_erp_append.erpset_option.Enable = Enableflag; + gui_erp_append.append_advance.Enable = Enableflag; + gui_erp_append.append_run.Enable = Enableflag; + gui_erp_append.sameerpset.Enable = Enableflag; + gui_erp_append.erpset_custom.Enable = Enableflag; + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +%%-------------------------same_to_erpset---------------------------------- + function same_to_erpset(~,~) + gui_erp_append.sameerpset.Value=1; + gui_erp_append.erpset_custom.Value=0; + gui_erp_append.erpset_edit.Enable = 'off'; + ERPArray = estudioworkingmemory('selectederpstudio'); + gui_erp_append.erpset_edit.String = num2str(ERPArray); + end + + +%%-----------------erpsetcutom--------------------------------------------- + function erpsetcutom(~,~) + gui_erp_append.sameerpset.Value=0; + gui_erp_append.erpset_custom.Value=1; + gui_erp_append.erpset_edit.Enable = 'on'; + end + + +%%-------------------------Append help------------------------------------ + function erpset_append_help(~,~) + web('https://github.com/lucklab/erplab/wiki/Appending-ERPSETS','-browser'); + end + + +%%-------------------edit the ERPset to append----------------------------- + function erpset_edit(Source,~) + ERPArray = str2num(Source.String); + if isempty(ERPArray) || numel(ERPArray)==1 + messgStr = strcat('Append ERPsets > You have to specify 2 ERPsets, at least.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + if min(ERPArray) <=0 + messgStr = strcat('Append ERPsets > Index of inputs should not be larger than 0.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + + if max(ERPArray) > length(observe_ERPDAT.ALLERP) + messgStr = strcat('Append ERPsets > Index of inputs should not be larger than',32,num2str(length(observe_ERPDAT.ALLERP)),'.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + end + + +%%-----------------Advance setting for ERPset append----------------------- + function advance_erpappend(~,~) + %%Send message to Message panel + erpworkingmemory('f_ERP_proces_messg','Append ERPsets'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + + ERPArray = str2num(gui_erp_append.erpset_edit.String); + if isempty(ERPArray) || numel(ERPArray)==1 + messgStr = strcat('Append ERPsets > You have to specify 2 ERPsets, at least.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + if min(ERPArray) <=0 + messgStr = strcat('Append ERPsets > Index of inputs should not be larger than 0.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + if max(ERPArray) > length(observe_ERPDAT.ALLERP) + messgStr = strcat('Append ERPsets > Index of inputs should not be larger than',32,num2str(length(observe_ERPDAT.ALLERP)),'.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + beep; + observe_ERPDAT.Process_messg=4; + return; + end + %%check number of samples/channels, and data type + messgStr = check_ERPset(ERPArray); + if ~isempty(messgStr) + erpworkingmemory('f_ERP_proces_messg',messgStr); + beep; + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return + end + + + try + ALLERP= observe_ERPDAT.ALLERP; + nloadedset = length(observe_ERPDAT.ALLERP); + def = estudioworkingmemory('pop_appenderp'); + if isempty(def) + if isempty(observe_ERPDAT.ALLERP) + inp1 = 1; %from hard drive + erpset = []; + erpoption = 1; + else + inp1 = 0; %from erpset menu + erpset = 1:length(ALLERP); + erpoption = 1;%% 1. same as ERPset panel; 2 custom define + end + isprefix = 0; + prefixlist = ''; + def = {inp1 erpoption, erpset prefixlist}; + %def = { erpset prefixlist}; + else + if ~isempty(ALLERP) + if isnumeric(def{2}) % JavierLC 11-17-11 + [uu, mm] = unique_bc2(def{3}, 'first'); + def{3} = [def{3}(sort(mm))]; + end + end + end + + ERPsetArraydef = str2num(gui_erp_append.erpset_edit.String); + if isempty(ERPsetArraydef) || max(ERPsetArraydef)> length(observe_ERPDAT.ALLERP) + ERPsetArraydef = observe_ERPDAT.CURRENTERP; + end + def{1} = 0; + def{3} = ERPsetArraydef; + def{2} = gui_erp_append.sameerpset.Value; + ERPArrayERPpanel = estudioworkingmemory('selectederpstudio'); + def{5} = ERPArrayERPpanel; + + % + % Call GUI + % + answer = f_appenderpGUI(nloadedset, def); + if isempty(answer) + disp('User selected Cancel') + return + end + optioni = answer{1}; %1 means from hard drive, 0 means from erpsets menu + ERPsetop = answer{2}; + erpset = answer{3}; + prefixlist = answer{4}; + + + estudioworkingmemory('pop_appenderp',answer); + + if optioni==1 % from files + filelist = erpset; + ALLERP = {ALLERP, filelist}; % truco + else % from erpsets menu + %erpset = erpset; + end + if isempty(prefixlist) + prefixliststr = ''; % do not include prefix + elseif isnumeric(prefixlist) + prefixliststr = 'erpname'; % use erpname instead + else + prefixliststr = prefixlist; % include prefix from list + end + erpworkingmemory('pop_appenderp', { optioni, erpset, prefixlist }); + + ALLERPCOM = evalin('base','ALLERPCOM'); + + if optioni==0 + messgStr = check_ERPset(erpset); + if ~isempty(messgStr) + erpworkingmemory('f_ERP_proces_messg',messgStr); + beep; + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return + end + %%check prefixes + + if ~isempty(prefixliststr) && numel(erpset) ~= length(prefixliststr) + messgStr = strcat('Append ERPsets > prefixes must to be as large as ERPset indx'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + beep; + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return + end + end + % + % Somersault + % + if optioni==1 && ~isempty(erpset) + if isempty(prefixliststr) + [ERP,ERPCOM] = pop_appenderp( erpset, 'Saveas', 'off', 'History', 'gui'); + else + fid_list = fopen( erpset ); + formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', ''); + lista = formcell{:}; + + if numel(lista) ~= length(prefixliststr) + messgStr = strcat('Append ERPsets > prefixes must to be as large as ERPset indx'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + beep; + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return + end + + [ERP, ERPCOM] = pop_appenderp(erpset, 'Prefixes', prefixliststr, 'Saveas', 'off', 'History', 'gui'); + end + else + + if isempty(prefixliststr) + [ERP, ERPCOM] = pop_appenderp(ALLERP, 'Erpsets', erpset, 'Saveas', 'off', 'History', 'gui'); + else + [ERP, ERPCOM] = pop_appenderp(ALLERP, 'Erpsets', erpset, 'Prefixes', prefixliststr, 'Saveas', 'off', 'History', 'gui'); + end + end + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);%%SAVE the command + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + erpName_new = ''; + fileName_new = ''; + pathName_new = ''; + Save_file_label =0; + + Answer = f_ERP_save_single_file(strcat('append'),'',length(observe_ERPDAT.ALLERP)+1); + if isempty(Answer) + % erpName_new = strcat(num2str(length(observe_ERPDAT.ALLERP)+1),'append'); + % Save_file_label =0; + disp('User selected Cancel.'); + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + erpName_new = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + fileName_new = ''; + Save_file_label =0; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = pathName_def; + end + fileName_new = [file_name,ext]; + pathName_new = pathstr; + Save_file_label =1; + end + end + + ERP.erpname = erpName_new; + ERP.filename = fileName_new; + ERP.filepath = pathName_new; + if Save_file_label==1 + ERP_save =ERP; + ERP_save.filepath = pathName_new; + [ERP, issave, ERPCOM] = pop_savemyerp(ERP_save, 'erpname', ERP_save.erpname, 'filename', ERP_save.erpname, 'filepath',ERP_save.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + assignin('base','ERP',observe_ERPDAT.ERP); + assignin('base','CURRENTERP',observe_ERPDAT.CURRENTERP); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Process_messg =2; + estudioworkingmemory('selectederpstudio',observe_ERPDAT.CURRENTERP); + OpValue = answer{2}; + gui_erp_append.sameerpset.Value = OpValue; + gui_erp_append.erpset_custom.Value = ~OpValue; + gui_erp_append.erpset_edit.String = num2str(answer{3}); + + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + catch + observe_ERPDAT.Process_messg =3; + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + +%%--------------------------Run-------------------------------------------- + function append_run(~,~) + + %%Send message to Message panel + erpworkingmemory('f_ERP_proces_messg','Append ERPsets'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + %%-------check the inputed ERPsetArray----------------------------- + ERPArray = str2num(gui_erp_append.erpset_edit.String); + if isempty(ERPArray) || numel(ERPArray)==1 + messgStr = strcat('Append ERPsets > You have to specify 2 ERPsets, at least.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + if min(ERPArray) <=0 + messgStr = strcat('Append ERPsets > Index of inputs should not be larger than 0.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return; + end + if max(ERPArray) > length(observe_ERPDAT.ALLERP) + messgStr = strcat('Append ERPsets > Index of inputs should not be larger than',32,num2str(length(observe_ERPDAT.ALLERP)),'.'); + erpworkingmemory('f_ERP_proces_messg',messgStr); + fprintf(2,['\n Warning: ',messgStr,'.\n']); + beep; + observe_ERPDAT.Process_messg=4; + return; + end + %%check number of samples/channels, and data type + messgStr = check_ERPset(ERPArray); + if ~isempty(messgStr) + erpworkingmemory('f_ERP_proces_messg',messgStr); + beep; + fprintf(2,['\n Warning: ',messgStr,'.\n']); + observe_ERPDAT.Process_messg=4; + return + end + ALLERPCOM = evalin('base','ALLERPCOM'); + ALLERP = observe_ERPDAT.ALLERP; + prefixliststr = ''; + for Numoferpset = 1:numel(ERPArray) + prefixliststr{Numoferpset} = ALLERP(ERPArray(Numoferpset)).erpname; + + end + + try + [ERP, ERPCOM] = pop_appenderp(ALLERP, 'Erpsets', ERPArray, 'Prefixes', prefixliststr, 'Saveas', 'off', 'History', 'gui'); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1);%%SAVE the command + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + erpName_new = ''; + fileName_new = ''; + pathName_new = ''; + Save_file_label =0; + Answer = f_ERP_save_single_file(strcat('append'),'',length(observe_ERPDAT.ALLERP)+1); + if isempty(Answer) + disp('User selected Cancel.'); + return; + % erpName_new = strcat(num2str(length(observe_ERPDAT.ALLERP)+1),'append'); + % Save_file_label =0; + end + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + erpName_new = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + fileName_new = ''; + Save_file_label =0; + elseif ~isempty(fileName_full) + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = pathName_def; + end + fileName_new = [file_name,ext]; + pathName_new = pathstr; + Save_file_label =1; + end + end + ERP.erpname = erpName_new; + ERP.filename = fileName_new; + ERP.filepath = pathName_new; + if Save_file_label==1 + ERP_save =ERP; + ERP_save.filepath = pathName_new; + [ERP, issave, ERPCOM] = pop_savemyerp(ERP_save, 'erpname', ERP_save.erpname, 'filename', ERP_save.erpname, 'filepath',ERP_save.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Process_messg =2; + estudioworkingmemory('selectederpstudio',observe_ERPDAT.CURRENTERP); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + catch + observe_ERPDAT.Process_messg =3; + return; + end%% end try + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%--------Setting current ERPset/session history based on the current updated ERPset------------ + function Count_currentERPChanged(~,~) + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + Enableflag = 'off'; + else + Enableflag = 'on'; + end + gui_erp_append.erpset_edit.Enable = Enableflag; + gui_erp_append.erpset_option.Enable = Enableflag; + gui_erp_append.append_advance.Enable = Enableflag; + gui_erp_append.append_run.Enable = Enableflag; + gui_erp_append.sameerpset.Enable = Enableflag; + gui_erp_append.erpset_custom.Enable = Enableflag; + if gui_erp_append.sameerpset.Value ==1%%same to the + %%selected erpsert as the "ERPset" panel. + ERPArray = estudioworkingmemory('selectederpstudio'); + gui_erp_append.erpset_edit.String = num2str(ERPArray); + gui_erp_append.erpset_edit.Enable = 'off'; + else + gui_erp_append.erpset_edit.Enable = 'on'; + end + end + + +%%-------------Check number of bin/channel, and data type------------------ + function msgboxText = check_ERPset(ERPArray) + msgboxText = ''; + nfile = numel(ERPArray); + if nfile >1 + numpoints = zeros(1,nfile); + numchans = zeros(1,nfile); + chckdatatype = cell(1); + ALLERP= observe_ERPDAT.ALLERP; + for j=1:nfile + numpoints(j) = ALLERP(ERPArray(j)).pnts; + numchans(j) = ALLERP(ERPArray(j)).nchan; + chckdatatype{j} = ALLERP(ERPArray(j)).datatype; + clear ERP1 + end + if length(unique(numpoints))>1 + msgboxText = 'Append ERPsets > The selected ERPsets have different number of points'; + end + + if length(unique(numchans))>1 + msgboxText = 'Append ERPsets > The selected ERPsets have different number of channel'; + end + if length(unique(chckdatatype))>1 + msgboxText = 'Append ERPsets > The selected ERPsets have different data type'; + end + end + end + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_baselinecorr_detrend_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_baselinecorr_detrend_GUI.m new file mode 100755 index 00000000..e5264de1 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_baselinecorr_detrend_GUI.m @@ -0,0 +1,585 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_baselinecorr_detrend_GUI(varargin) + +% global gui_erp_blc_dt; +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange); +% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + +%%---------------------------gui------------------------------------------- +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + ERP_basecorr_detrend_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Baseline Correction & Linear Detrend', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_basecorr_detrend_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Baseline Correction & Linear Detrend', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_basecorr_detrend_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Baseline Correction & Linear Detrend', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +gui_erp_blc_dt = struct(); +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +erp_blc_dt_gui(FonsizeDefault); +varargout{1} = ERP_basecorr_detrend_box; +%%********************Draw the GUI for ERP measurement tool***************** + function erp_blc_dt_gui(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + gui_erp_blc_dt.blc_dt = uiextras.VBox('Parent',ERP_basecorr_detrend_box,'Spacing',1,'BackgroundColor',ColorB_def); + + %%Measurement type + gui_erp_blc_dt.blc_dt_type_title = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_blc_dt.blc_dt_type_title,... + 'String','Type:','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + gui_erp_blc_dt.blc_dt_option = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.blc = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_option,... + 'String','Baseline Correction','callback',@baseline_correction_erp,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.dt = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_option,... + 'String','Linear detrend','callback',@detrend_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + %%Baseline period: Pre, post whole custom + gui_erp_blc_dt.blc_dt_baseline_period_title = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_blc_dt.blc_dt_baseline_period_title,... + 'String','Baseline Period:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.blc_dt_bp_option = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.pre = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option,... + 'String','Pre','callback',@pre_erp,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.post = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option,... + 'String','Post','callback',@post_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_blc_dt.whole = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option,... + 'String','Whole','callback',@whole_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.blc_dt_bp_option_cust = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.custom = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_dt_bp_option_cust,... + 'String','Custom (ms) [start stop]','callback',@custom_erp,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.custom_edit = uicontrol('Style', 'edit','Parent', gui_erp_blc_dt.blc_dt_bp_option_cust,... + 'String','','callback',@custom_edit,'Enable',Enable_label,'FontSize',FonsizeDefault); + + if observe_ERPDAT.ERP.times(1)>=0 + CUstom_String = ''; + else + CUstom_String = num2str([observe_ERPDAT.ERP.times(1),0]); + end + gui_erp_blc_dt.custom_edit.String = CUstom_String; + set(gui_erp_blc_dt.blc_dt_bp_option_cust, 'Sizes',[160 135]); + + + %%Bin and channels selection + gui_erp_blc_dt.blc_dt_bin_chan_title = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_blc_dt.blc_dt_bin_chan_title,... + 'String','Bin and Chan Selection:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.blc_bin_chan_option = uiextras.HBox('Parent', gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.all_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_bin_chan_option,... + 'String','All(Recommended)','callback',@All_bin_chan,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_blc_dt.Selected_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_blc_dt.blc_bin_chan_option,... + 'String','Selected bin & chan','callback',@Selected_bin_chan,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_blc_dt.blc_bin_chan_option, 'Sizes',[125 175]); + + %%Cancel and advanced + gui_erp_blc_dt.other_option = uiextras.HBox('Parent',gui_erp_blc_dt.blc_dt,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_blc_dt.other_option,'BackgroundColor',ColorB_def); + gui_erp_blc_dt.reset = uicontrol('Parent',gui_erp_blc_dt.other_option,'Style','pushbutton',... + 'String','Reset','callback',@Reset_blc_dt,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uiextras.Empty('Parent', gui_erp_blc_dt.other_option); + gui_erp_blc_dt.apply = uicontrol('Style','pushbutton','Parent',gui_erp_blc_dt.other_option,... + 'String','Apply','callback',@apply_blc_dt,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uiextras.Empty('Parent', gui_erp_blc_dt.other_option); + set(gui_erp_blc_dt.other_option, 'Sizes',[15 105 30 105 15]); + + set(gui_erp_blc_dt.blc_dt,'Sizes',[18 25 15 25 25 15 25 30]); + + end +%%**************************************************************************************************************************************** +%%******************* Subfunctions *************************************************************************************************** +%%**************************************************************************************************************************************** + +%%--------------------------------setting for amplitude------------------ + function baseline_correction_erp(source,~) + gui_erp_blc_dt.blc.Value =1; + gui_erp_blc_dt.dt.Value = 0; + end + +%%--------------------------Setting for phase----------------------------- + function detrend_erp(source,~) + gui_erp_blc_dt.dt.Value = 1; + gui_erp_blc_dt.blc.Value =0; + end + +%%----------------Setting for "pre"----------------------------------------- + function pre_erp(~,~) + gui_erp_blc_dt.pre.Value=1; + gui_erp_blc_dt.post.Value=0; + gui_erp_blc_dt.whole.Value=0; + gui_erp_blc_dt.custom.Value=0; + gui_erp_blc_dt.custom_edit.Enable = 'off'; + if observe_ERPDAT.ERP.times(1)>=0 + CUstom_String = ''; + else + CUstom_String = num2str([observe_ERPDAT.ERP.times(1),0]); + end + gui_erp_blc_dt.custom_edit.String = CUstom_String; + + end + + +%%----------------Setting for "post"----------------------------------------- + function post_erp(~,~) + gui_erp_blc_dt.pre.Value=0; + gui_erp_blc_dt.post.Value=1; + gui_erp_blc_dt.whole.Value=0; + gui_erp_blc_dt.custom.Value=0; + gui_erp_blc_dt.custom_edit.Enable = 'off'; + + if observe_ERPDAT.ERP.times(end)<=0 + CUstom_String = ''; + else + CUstom_String = num2str([0 observe_ERPDAT.ERP.times(end)]); + end + gui_erp_blc_dt.custom_edit.String = CUstom_String; + + end + +%%----------------Setting for "whole"----------------------------------------- + function whole_erp(~,~) + gui_erp_blc_dt.pre.Value=0; + gui_erp_blc_dt.post.Value=0; + gui_erp_blc_dt.whole.Value=1; + gui_erp_blc_dt.custom.Value=0; + gui_erp_blc_dt.custom_edit.Enable = 'off'; + CUstom_String = num2str([observe_ERPDAT.ERP.times(1) observe_ERPDAT.ERP.times(end)]); + gui_erp_blc_dt.custom_edit.String = CUstom_String; + end + +%%----------------Setting for "custom"----------------------------------------- + function custom_erp(~,~) + gui_erp_blc_dt.pre.Value=0; + gui_erp_blc_dt.post.Value=0; + gui_erp_blc_dt.whole.Value=0; + gui_erp_blc_dt.custom.Value=1; + gui_erp_blc_dt.custom_edit.Enable = 'on'; + end + +%%----------------input baseline period defined by user---------------------- + function custom_edit(Source,~) + lat_osci = str2num(Source.String); + if isempty(lat_osci) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - Invalid input for "baseline range"']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if numel(lat_osci) ==1 + beep; + msgboxText = ['Baseline Correction & Linear Detrend - Wrong baseline range. Please, enter two values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if lat_osci(1)>= lat_osci(2) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - The first value must be smaller than the second one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if lat_osci(2) > observe_ERPDAT.ERP.times(end) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.times(end))]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if lat_osci(1) < observe_ERPDAT.ERP.times(1) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - First value must be larger than',32,num2str(observe_ERPDAT.ERP.times(1))]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + +%%---------------------Setting for all chan and bin------------------------ + function All_bin_chan(~,~) + gui_erp_blc_dt.all_bin_chan.Value = 1; + gui_erp_blc_dt.Selected_bin_chan.Value = 0; + end + +%%----------------Setting for selected bin and chan------------------------ + function Selected_bin_chan(~,~) + gui_erp_blc_dt.all_bin_chan.Value = 0; + gui_erp_blc_dt.Selected_bin_chan.Value = 1; + end +%%--------------------------Setting for plot------------------------------- + function apply_blc_dt(~,~) + + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + + + try + if gui_erp_blc_dt.pre.Value==1 + BaselineMethod = 'pre'; + elseif gui_erp_blc_dt.post.Value==1 + BaselineMethod = 'post'; + elseif gui_erp_blc_dt.whole.Value==1 + BaselineMethod = 'all'; + elseif gui_erp_blc_dt.custom.Value ==1 + BaselineMethod = str2num(gui_erp_blc_dt.custom_edit.String); + end + catch + BaselineMethod = 'pre'; + end + + %%Check the baseline period defined by the custom. + if gui_erp_blc_dt.custom.Value ==1 + if isempty(BaselineMethod) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - Invalid input for baseline range; Please reset two values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if numel(BaselineMethod) ==1 + beep; + msgboxText = ['Baseline Correction & Linear Detrend - Wrong baseline range. Please, enter two values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if BaselineMethod(1)>= BaselineMethod(2) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - The first value must be smaller than the second one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if roundn(BaselineMethod(2),-3) > roundn(observe_ERPDAT.ERP.times(end),-3) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - Second value must be smaller than',32,num2str(observe_ERPDAT.ERP.times(end))]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if roundn(BaselineMethod(1),-3) < roundn(observe_ERPDAT.ERP.times(1),-3) + beep; + msgboxText = ['Baseline Correction & Linear Detrend - First value must be larger than',32,num2str(observe_ERPDAT.ERP.times(1))]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + %%Run the function based on the defined parameters + Check_Selected_erpset = [0 0 0 0 0 0 0]; + S_ws_binchan= estudioworkingmemory('geterpbinchan'); + if numel(Selected_erpset)>1 + try + Check_Selected_erpset = S_ws_binchan.checked_ERPset_Index; + catch + Check_Selected_erpset = f_checkerpsets(observe_ERPDAT.ALLERP,Selected_erpset); + end + end + + %%--------------Loop start for removeing baseline for the selected ERPsets------------ + if gui_erp_blc_dt.dt.Value ==1 + Suffix_str = char(strcat('detrend')); + else + Suffix_str = char(strcat('baselinecorr')); + end + if numel(Selected_erpset)>1 + if gui_erp_blc_dt.dt.Value ==1 + Suffix_str = char(strcat('detrend')); + else + Suffix_str = char(strcat('baselinecorr')); + end + + Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selected_erpset,Suffix_str); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + + if ~isempty(Answer{1}) + ALLERP_advance = Answer{1}; + Save_file_label = Answer{2}; + end + + elseif numel(Selected_erpset)==1 + Save_file_label = 0; + ALLERP_advance = observe_ERPDAT.ALLERP; + end + + %%%%-------------------Loop fpor baseline correction--------------- + erpworkingmemory('f_ERP_proces_messg','Baseline correction & Linear detrend'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + + ALLERPCOM = evalin('base','ALLERPCOM'); + + try + BinArray = []; + ChanArray = []; + for Numoferp = 1:numel(Selected_erpset) + + if Selected_erpset(Numoferp)> length(observe_ERPDAT.ALLERP) + error('EStudio says: No corresponding ERP exists in ALLEERP'); + break; + end + + ERP = observe_ERPDAT.ALLERP(Selected_erpset(Numoferp)); + if (Check_Selected_erpset(1)==1 || Check_Selected_erpset(2)==2) && gui_erp_blc_dt.Selected_bin_chan.Value ==1 + if Check_Selected_erpset(1) ==1 + msgboxText = ['Number of bins across the selected ERPsets is different!']; + elseif Check_Selected_erpset(2)==2 + msgboxText = ['Number of channels across the selected ERPsets is different!']; + elseif Check_Selected_erpset(1)==1 && Check_Selected_erpset(2)==2 + msgboxText = ['Number of channels and bins vary across the selected ERPsets']; + end + question = [ '%s\n\n "All" will be active instead of "Selected bin and chan".']; + title = 'EStudio: Baseline correction & linear detrend'; + button = questdlg(sprintf(question, msgboxText), title,'OK','OK'); + BinArray = []; + ChanArray = []; + end + + if (Check_Selected_erpset(1)==0 && Check_Selected_erpset(2)==0) && gui_erp_blc_dt.Selected_bin_chan.Value ==1 + try + BinArray = S_ws_binchan.bins{1}; + ChanArray = S_ws_binchan.elecs_shown{1}; + [chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1); + if chk(1)==1 + BinArray = [1:ERP.nbin]; + end + [chk, msgboxText] = f_ERP_chckbinandchan(ERP,[], ChanArray,2); + if chk(2)==1 + ChanArray = [1:ERP.nchan]; + end + + catch + BinArray = [1:ERP.nbin]; + ChanArray = [1:ERP.nchan]; + end + end + + if gui_erp_blc_dt.all_bin_chan.Value == 1 + BinArray = [1:ERP.nbin]; + ChanArray = [1:ERP.nchan]; + end + + + if gui_erp_blc_dt.dt.Value ==1 + [ERP ERPCOM] = pop_erplindetrend( ERP, BaselineMethod , 'Saveas', 'off','History','gui'); + else + [ERP ERPCOM]= pop_blcerp( ERP , 'Baseline', BaselineMethod, 'Saveas', 'off','History','gui'); + end + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + if Numoferp ==1 + [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + end + + %%Only the slected bin and chan were selected to remove baseline and detrending and others are remiained. + if ~isempty(BinArray) + ERP_before_bl = ALLERP_advance(Selected_erpset(Numoferp)); + ERP_before_bl.bindata(ChanArray,:,BinArray) = ERP.bindata(ChanArray,:,BinArray); + ERP_before_bl.history = ERP.history; + ERP = ERP_before_bl; + end + + + if numel(Selected_erpset) ==1 + Answer = f_ERP_save_single_file(strcat(ERP.erpname,'-',Suffix_str),ERP.filename,Selected_erpset(Numoferp)); + if isempty(Answer) + beep; + disp('User selectd cancal'); + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ERP.erpname; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + %%----------save the current sdata as-------------------- + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + end + + if Save_file_label + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + + end%%Loop end for the selected ERset + + erpworkingmemory('f_ERP_BLS_Detrend',{BaselineMethod,0,1}); + %% + % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1:length(observe_ERPDAT.ALLERP)]; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + + observe_ERPDAT.Process_messg =3; + erpworkingmemory('f_ERP_BLS_Detrend',{BaselineMethod,0,1}); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%-----------------Setting for save option--------------------------------- + function Reset_blc_dt(~,~) + gui_erp_blc_dt.blc.Value =1; + gui_erp_blc_dt.dt.Value = 0; + gui_erp_blc_dt.pre.Value=1; + gui_erp_blc_dt.post.Value=0; + gui_erp_blc_dt.whole.Value=0; + gui_erp_blc_dt.custom.Value=0; + gui_erp_blc_dt.custom_edit.Enable = 'off'; + if observe_ERPDAT.ERP.times(1)>=0 + CUstom_String = ''; + else + CUstom_String = num2str([observe_ERPDAT.ERP.times(1),0]); + end + gui_erp_blc_dt.custom_edit.String = CUstom_String; + gui_erp_blc_dt.all_bin_chan.Value = 1; + gui_erp_blc_dt.Selected_bin_chan.Value = 0; + end + + +%%-------------------Setting for the whole panel of fitering based on ALLERP and CURRENTERP-------------- + function Count_currentERPChanged(~,~) + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || ~strcmp(observe_ERPDAT.ERP.datatype,'ERP') + Enable_Label = 'off'; + else + Enable_Label = 'on'; + end + + gui_erp_blc_dt.blc.Enable = Enable_Label; + gui_erp_blc_dt.dt.Enable = Enable_Label; + gui_erp_blc_dt.apply.Enable = Enable_Label; + gui_erp_blc_dt.reset.Enable = Enable_Label; + gui_erp_blc_dt.pre.Enable= Enable_Label; + gui_erp_blc_dt.post.Enable= Enable_Label; + gui_erp_blc_dt.whole.Enable= Enable_Label; + gui_erp_blc_dt.custom.Enable= Enable_Label; + gui_erp_blc_dt.custom_edit.Enable = Enable_Label; + gui_erp_blc_dt.apply.Enable = Enable_Label; + gui_erp_blc_dt.reset.Enable = Enable_Label; + gui_erp_blc_dt.all_bin_chan.Enable = Enable_Label; + gui_erp_blc_dt.Selected_bin_chan.Enable = Enable_Label; + + if gui_erp_blc_dt.custom.Value==1 + gui_erp_blc_dt.custom_edit.Enable = 'on'; + else + gui_erp_blc_dt.custom_edit.Enable = 'off'; + end + + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + + Check_Selected_erpset = [0 0 0 0 0 0 0]; + if numel(Selected_erpset)>1 + Check_Selected_erpset = S_binchan.checked_ERPset_Index; + end + if Check_Selected_erpset(1) ==1 || Check_Selected_erpset(2) == 2 + gui_erp_blc_dt.all_bin_chan.Enable = 'on'; + gui_erp_blc_dt.Selected_bin_chan.Enable = 'off'; + gui_erp_blc_dt.all_bin_chan.Value = 1; + gui_erp_blc_dt.Selected_bin_chan.Value = 0; + end + end + +end +%Progem end: ERP Measurement tool \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_bin_channel_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_bin_channel_GUI.m new file mode 100755 index 00000000..6db8737e --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_bin_channel_GUI.m @@ -0,0 +1,509 @@ +%%This function is used to get the 'Bin and Channel Selection' Panel and record the change of th selected channels and selected bins + +% *** This function is part of ERPLAB Studio Toolbox *** +% Author: Guanghui Zhang & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2022 + + +function varargout = f_ERP_bin_channel_GUI(varargin) + +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +addlistener(observe_ERPDAT,'ERP_chan_change',@ERP_chan_changed); +addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + +%---------------------------Initialize parameters------------------------------------ +try + SelectedIndex = observe_ERPDAT.CURRENTERP; +catch + disp('f_ERP_bin_channel_GUI error: No CURRENTERP is on Matlab Workspace'); + return; +end +% end +if SelectedIndex ==0 + + disp('f_ERP_bin_channel_GUI error: No ERPset is imported'); + return; +end +if SelectedIndex>length(observe_ERPDAT.ALLERP) + SelectedIndex =1; +end + +S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedIndex); +estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); +estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + +EStduio_gui_erp_bin_chan = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global EStudio_box_bin_chan; +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + EStudio_box_bin_chan = uiextras.BoxPanel('Parent', fig, 'Title', 'Bin and Channel Selection', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + EStudio_box_bin_chan = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Bin and Channel Selection', 'Padding', 5,'BackgroundColor',ColorB_def); +else + EStudio_box_bin_chan = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Bin and Channel Selection', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- + + +observe_ERPDAT.ERP_chan = S_erpbinchan.geterpbinchan.elecs_shown{1}; +observe_ERPDAT.ERP_bin = S_erpbinchan.geterpbinchan.bins{1}; +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) +FonsizeDefault = f_get_default_fontsize(); +end + +drawui_bin_chan(FonsizeDefault) +varargout{1} = EStudio_box_bin_chan; + + function drawui_bin_chan(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + %%--------------------channel and bin setting---------------------- + EStduio_gui_erp_bin_chan.DataSelBox = uiextras.VBox('Parent', EStudio_box_bin_chan,'BackgroundColor',ColorB_def); + EStduio_gui_erp_bin_chan.DataSelGrid = uiextras.Grid('Parent', EStduio_gui_erp_bin_chan.DataSelBox,'BackgroundColor',ColorB_def); + + + % Second column: + uicontrol('Style','text','Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'String','Channels','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1B + Chanlist = observe_ERPDAT.ERP.chanlocs; + Chanlist_name{1} = 'All'; + for Numofchan = 1:length(Chanlist) + Chanlist_name{Numofchan+1} = char(strcat(num2str(Numofchan),'.',32,Chanlist(Numofchan).labels)); + end + EStduio_gui_erp_bin_chan.ElecRange = uicontrol('Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'Style','listbox','min',1,'max',length(Chanlist_name),... + 'String', Chanlist_name,'Callback',@onElecRange,'FontSize',FonsizeDefault,'Enable','on'); % 2B + + if S_erpbinchan.geterpbinchan.checked_curr_index ==1 || S_erpbinchan.geterpbinchan.checked_ERPset_Index(2) ==2 + EStduio_gui_erp_bin_chan.ElecRange.Enable = 'off'; + end + + if numel(S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}) == numel(Chanlist) + EStduio_gui_erp_bin_chan.ElecRange.Value =1; + else + EStduio_gui_erp_bin_chan.ElecRange.Value = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}+1; + end + + + % Third column: + uicontrol('Style','text','Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'String','Bins','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1C + + BinNum = observe_ERPDAT.ERP.nbin; + BinName = observe_ERPDAT.ERP.bindescr; + brange = cell(BinNum+1,1); + brange(1) = {'ALL'}; + for i = 1:BinNum + brange(i+1) = {strcat(num2str(i),'.',32,BinName{i})}; + end + EStduio_gui_erp_bin_chan.BinRange = uicontrol('Parent', EStduio_gui_erp_bin_chan.DataSelGrid,'Style','listbox','Min',1,'Max',BinNum+1,... + 'String', brange,'callback',@onBinChanged,'FontSize',FonsizeDefault); % 2C + if BinNum== numel(S_erpbinchan.geterpbinchan.bins{1}) + EStduio_gui_erp_bin_chan.BinRange.Value =1; + else + EStduio_gui_erp_bin_chan.BinRange.Value = S_erpbinchan.geterpbinchan.bins{1}+1; + end + if S_erpbinchan.geterpbinchan.checked_curr_index ==1 || S_erpbinchan.geterpbinchan.checked_ERPset_Index(1) ==1 + EStduio_gui_erp_bin_chan.BinRange.Enable = 'off'; + end + + set(EStduio_gui_erp_bin_chan.DataSelGrid, 'ColumnSizes',[ -1.2 -2],'RowSizes',[20 -3]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + + +%----------------------------Get the changed channels----------------------* + function onElecRange ( src, ~) + erpworkingmemory('f_ERP_proces_messg','Bin and Channel Selection-select channel(s)'); + observe_ERPDAT.Process_messg =1; + + SelectedERP_Index= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP_Index) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan; + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_erpbinchan.geterpbinchan= estudioworkingmemory('geterpbinchan'); + if isempty(S_erpbinchan.geterpbinchan) + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan; + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + new_chans = src.Value; + if isempty(new_chans) + beep; + disp(['No channel was selected']); + return; + end + [~,y_chan_index_select] = find(new_chans==1); + if isempty(y_chan_index_select) && numel(new_chans) < numel(src.String)-1 %% 'All' is not slected + + if S_erpbinchan.geterpbinchan.checked_ERPset_Index(2) ==2%% the number of channels varied across ERPsets + S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = new_chans-1; + S_erpbinchan.geterpbinchan.elec_n(S_erpbinchan.geterpbinchan.Select_index) = numel(new_chans); + S_erpbinchan.geterpbinchan.first_elec(S_erpbinchan.geterpbinchan.Select_index) = new_chans(1)-1; + else + for Numofselecterp = 1:numel(SelectedERP_Index) + S_erpbinchan.geterpbinchan.elecs_shown{Numofselecterp} = new_chans-1; + S_erpbinchan.geterpbinchan.elec_n(Numofselecterp) = numel(new_chans); + S_erpbinchan.geterpbinchan.first_elec(Numofselecterp) = new_chans(1)-1; + end + end + EStduio_gui_erp_bin_chan.ElecRange.Value = new_chans; + else%% 'All' is selected and included or all channels are slected except 'ALL' + carray = src.String; + carray(1) = []; + if S_erpbinchan.geterpbinchan.checked_ERPset_Index(2) ==2 + S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = [1:numel(carray)]; + S_erpbinchan.geterpbinchan.elec_n(S_erpbinchan.geterpbinchan.Select_index) = numel(carray); + S_erpbinchan.geterpbinchan.first_elec(S_erpbinchan.geterpbinchan.Select_index) = 1; + else + + for Numofselecterp = 1:numel(SelectedERP_Index) + S_erpbinchan.geterpbinchan.elecs_shown{Numofselecterp} = [1:numel(carray)]; + S_erpbinchan.geterpbinchan.elec_n(Numofselecterp) = numel(carray); + S_erpbinchan.geterpbinchan.first_elec(Numofselecterp) = 1; + end + + end + + EStduio_gui_erp_bin_chan.ElecRange.Value = 1; + end + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + observe_ERPDAT.ERP_chan = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}; + observe_ERPDAT.Process_messg =2; + %%Plot waves + try + try + S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); + S_ws_viewer = S_ws_geterpvalues.Viewer; + catch + S_ws_viewer = 'off'; + end + + if strcmp(S_ws_viewer,'on') + f_redrawERP_mt_viewer(); + else + f_redrawERP(); + end + + catch + f_redrawERP(); + end + % observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + + +%---------------------------get the changed bin---------------------------- + function onBinChanged( src, ~ ) + erpworkingmemory('f_ERP_proces_messg','Bin and Channel Selection-select bin(s)'); + observe_ERPDAT.Process_messg =1; + + SelectedERP_Index= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP_Index) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan; + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + S_erpbinchan.geterpbinchan= estudioworkingmemory('geterpbinchan'); + if isempty(S_erpbinchan.geterpbinchan) + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan; + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + Bin_label_select = src.Value; + if isempty(Bin_label_select) + beep; + disp(['No bin was selected']); + return; + end + + [~,y_bin_index_select] = find(Bin_label_select==1); + if isempty(y_bin_index_select) && numel(Bin_label_select) < numel(src.String)-1 + if S_erpbinchan.geterpbinchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets + S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = Bin_label_select-1; + S_erpbinchan.geterpbinchan.bin_n(S_erpbinchan.geterpbinchan.Select_index) = numel(Bin_label_select); + else + for Numofselecterp = 1:numel(SelectedERP_Index) + S_erpbinchan.geterpbinchan.bins{Numofselecterp} = Bin_label_select-1; + S_erpbinchan.geterpbinchan.bin_n(Numofselecterp) = numel(Bin_label_select); + end + end + EStduio_gui_erp_bin_chan.BinRange.Value = Bin_label_select; + + else% 'All' is selected and inlcuded + carray = src.String; + carray(1) = []; + if S_erpbinchan.geterpbinchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets + S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = [1:numel(carray)]; + S_erpbinchan.geterpbinchan.bin_n(S_erpbinchan.geterpbinchan.Select_index) = numel(carray); + else + for Numofselecterp = 1:numel(SelectedERP_Index) + S_erpbinchan.geterpbinchan.bins{Numofselecterp} = [1:numel(carray)]; + S_erpbinchan.geterpbinchan.bin_n(Numofselecterp) = numel(carray); + end + end + EStduio_gui_erp_bin_chan.BinRange.Value = 1; + end + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + observe_ERPDAT.ERP_bin = S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}; + observe_ERPDAT.Process_messg =2; + %%Plot waves + try + try + S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); + S_ws_viewer = S_ws_geterpvalues.Viewer; + catch + S_ws_viewer = 'off'; + end + + if strcmp(S_ws_viewer,'on') + f_redrawERP_mt_viewer(); + else + f_redrawERP(); + end + + catch + f_redrawERP(); + end + % observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%----------displayed channel label will be midified after channels was selected-------- + function ERP_chan_changed(~,~) + if observe_ERPDAT.Process_messg==0 + return; + end + chanString = EStduio_gui_erp_bin_chan.ElecRange.String; + chanArray = observe_ERPDAT.ERP_chan; + if max(chanArray)> length(chanString)-1 + EStduio_gui_erp_bin_chan.ElecRange.Value =1; + observe_ERPDAT.ERP_chan = [1:length(chanString)-1]; + else + if max(chanArray)>length(chanString)-1 + EStduio_gui_erp_bin_chan.ElecRange.Value =1; + observe_ERPDAT.ERP_chan = [1:length(chanString)-1]; + else + if numel(chanArray) == length(chanString)-1 + EStduio_gui_erp_bin_chan.ElecRange.Value =1; + else + EStduio_gui_erp_bin_chan.ElecRange.Value = chanArray+1; + end + end + end + end + + + +%----------displayed bin label will be midified after different channels was selected-------- + function ERP_bin_changed(~,~) + if observe_ERPDAT.Process_messg==0 + return; + end + binArray = observe_ERPDAT.ERP_bin; + binString = EStduio_gui_erp_bin_chan.BinRange.String; + + if max(binArray)> length(binString)-1 + EStduio_gui_erp_bin_chan.BinRange.Value =1; + observe_ERPDAT.ERP_bin = [1:length(binString)-1]; + else + if max(binArray)>length(binString)-1 + EStduio_gui_erp_bin_chan.BinRange.Value =1; + observe_ERPDAT.ERP_bin = [1:length(binString)-1]; + else + if numel(binArray) == length(binString)-1 + EStduio_gui_erp_bin_chan.BinRange.Value =1; + else + EStduio_gui_erp_bin_chan.BinRange.Value = binArray+1; + end + end + end + end + + +%%--------Settting will be modified if the selected was changed------------ + function Count_currentERPChanged(~,~) + try + ERPloadIndex = estudioworkingmemory('ERPloadIndex'); + catch + ERPloadIndex =0; + end + if ERPloadIndex==1 + ALLERPIN = evalin('base','ALLERP'); + CURRENTERPIN = evalin('base','CURRENTERP'); + observe_ERPDAT.ALLERP = ALLERPIN; + observe_ERPDAT.CURRENTERP =CURRENTERPIN; + try + observe_ERPDAT.ERP = ALLERPIN(CURRENTERPIN); + catch + observe_ERPDAT.ERP = ALLERPIN(end); + observe_ERPDAT.CURRENTERP =length(ALLERPIN); + end + end + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan; + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + S_erpbinchan.geterpbinchan= estudioworkingmemory('geterpbinchan'); + if isempty(S_erpbinchan.geterpbinchan) + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + S_erpbinchan.geterpbinchan = S_erpplot.geterpbinchan; + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + if max(Selectederp_Index(:)) > length(observe_ERPDAT.ALLERP) + beep; + disp(['Max. index of selected ERPsets is greater than the length of ALLERP!!!']); + return; + end + + %The channels and bins will be modified if the ERPset is changed + Chanlist = observe_ERPDAT.ERP.chanlocs; + Chanlist_name{1} = 'All'; + for Numofchan = 1:length(Chanlist) + Chanlist_name{Numofchan+1} = strcat(num2str(Numofchan),'.',32,char(Chanlist(Numofchan).labels)); + end + EStduio_gui_erp_bin_chan.ElecRange.String=Chanlist_name; + + try + checked_ERPset_Index_bin_chan = S_erpbinchan.geterpbinchan.checked_ERPset_Index; + catch + checked_ERPset_Index_bin_chan = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index); + end + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || checked_ERPset_Index_bin_chan(2) ==2 + EStduio_gui_erp_bin_chan.ElecRange.Enable = 'off'; + else + EStduio_gui_erp_bin_chan.ElecRange.Enable = 'on'; + end + + EStduio_gui_erp_bin_chan.ElecRange.Min = 1; + EStduio_gui_erp_bin_chan.ElecRange.Max = length(Chanlist_name)+1; + + chanArray_pv = EStduio_gui_erp_bin_chan.ElecRange.Value; + if numel(chanArray_pv)==1 && chanArray_pv ==1 + EStduio_gui_erp_bin_chan.ElecRange.Value =1; + S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = 1:(length(Chanlist_name)-1); + else + if max(chanArray_pv-1)<= (length(Chanlist_name)-1) + S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}= chanArray_pv-1; + else + S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index} = 1:(length(Chanlist_name)-1); + end + end + + if numel(S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}) == numel(Chanlist) + EStduio_gui_erp_bin_chan.ElecRange.Value =1; + observe_ERPDAT.ERP_chan = [1:numel(Chanlist)]; + else + EStduio_gui_erp_bin_chan.ElecRange.Value = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}+1; + observe_ERPDAT.ERP_chan= S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}; + end + + ChanShow = S_erpbinchan.geterpbinchan.elecs_shown{S_erpbinchan.geterpbinchan.Select_index}; + S_erpbinchan.geterpbinchan.elec_n(S_erpbinchan.geterpbinchan.Select_index) = numel(ChanShow); + S_erpbinchan.geterpbinchan.first_elec(S_erpbinchan.geterpbinchan.Select_index) = ChanShow(1); + + estudioworkingmemory('ChanShow',ChanShow); + + %%Setting for display bins + BinNum = observe_ERPDAT.ERP.nbin; + BinName = observe_ERPDAT.ERP.bindescr; + brange = cell(BinNum+1,1); + brange(1) = {'ALL'}; + for i = 1:BinNum + brange(i+1) = {strcat(num2str(i),'.',32,BinName{i})}; + end + EStduio_gui_erp_bin_chan.BinRange.String=brange; + binArray_pv = EStduio_gui_erp_bin_chan.BinRange.Value; + if numel(binArray_pv)==1 && binArray_pv ==1 + EStduio_gui_erp_bin_chan.BinRange.Value =1; + S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = 1:BinNum; + else + if max(binArray_pv-1)<= BinNum + S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}= binArray_pv-1; + else + S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index} = 1:BinNum; + end + end + + if numel(S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}) == BinNum + EStduio_gui_erp_bin_chan.BinRange.Value =1; + else + EStduio_gui_erp_bin_chan.BinRange.Value =S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}; + end + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || checked_ERPset_Index_bin_chan(1) ==1 + EStduio_gui_erp_bin_chan.BinRange.Enable = 'off'; + else + EStduio_gui_erp_bin_chan.BinRange.Enable = 'on'; + end + EStduio_gui_erp_bin_chan.BinRange.Min = 1; + EStduio_gui_erp_bin_chan.BinRange.Max = length(brange)+1; + + if numel(S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}) == BinNum + EStduio_gui_erp_bin_chan.BinRange.Value =1; + observe_ERPDAT.ERP_bin = [1:BinNum]; + else + EStduio_gui_erp_bin_chan.BinRange.Value = S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}+1; + observe_ERPDAT.ERP_bin = S_erpbinchan.geterpbinchan.bins{S_erpbinchan.geterpbinchan.Select_index}; + end + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + + end + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_binoperation_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_binoperation_GUI.m new file mode 100755 index 00000000..c56fd7d8 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_binoperation_GUI.m @@ -0,0 +1,515 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_binoperation_GUI(varargin) +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +gui_erp_bin_operation = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global ERP_bin_operation_gui; +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + ERP_bin_operation_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Bin Operations', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_bin_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Bin Operations', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_bin_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Bin Operations', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_bin_operation(FonsizeDefault); +varargout{1} = ERP_bin_operation_gui; + + function drawui_erp_bin_operation(FonsizeDefault) + FontSize_defualt = FonsizeDefault; + + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + %%--------------------channel and bin setting---------------------- + gui_erp_bin_operation.DataSelBox = uiextras.VBox('Parent', ERP_bin_operation_gui,'BackgroundColor',ColorB_def); + + + for ii = 1:100 + dsnames{ii,1} = ''; + end + gui_erp_bin_operation.erp_history_table = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_bin_operation.edit_bineq = uitable( ... + 'Parent' , gui_erp_bin_operation.erp_history_table,... + 'Data' , dsnames, ... + 'ColumnWidth' , {1000}, ... + 'ColumnName' , [], ... + 'RowName' , []); + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,length(dsnames)),'FontSize',FontSize_defualt); + + gui_erp_bin_operation.equation_selection = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_bin_operation.eq_editor = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.equation_selection,... + 'String','Eq. Advanced','callback',@eq_advanced,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + gui_erp_bin_operation.eq_load = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.equation_selection,... + 'String','Load Eq.','callback',@eq_load,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + gui_erp_bin_operation.eq_clear = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.equation_selection,... + 'String','Clear Eq.','callback',@eq_clear,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + %%%----------------Mode----------------------------------- + gui_erp_bin_operation.mode_1 = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_bin_operation.mode_modify_title = uicontrol('Style','text','Parent',gui_erp_bin_operation.mode_1 ,... + 'String','Mode:','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_bin_operation.mode_modify = uicontrol('Style','radiobutton','Parent',gui_erp_bin_operation.mode_1 ,... + 'String','Modify Existing ERPset','callback',@mode_modify,'Value',1,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F + gui_erp_bin_operation.mode_modify.String = 'Modify Existing ERPset
(recursive updating)'; + set(gui_erp_bin_operation.mode_1,'Sizes',[55 -1]); + %%--------------For create a new ERPset---------------------------- + gui_erp_bin_operation.mode_2 = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_bin_operation.mode_2); + gui_erp_bin_operation.mode_create = uicontrol('Style','radiobutton','Parent',gui_erp_bin_operation.mode_2 ,... + 'String',{'', ''},'callback',@mode_create,'Value',0,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F + gui_erp_bin_operation.mode_create.String = 'Create New ERPset
(independent transformations)'; + set(gui_erp_bin_operation.mode_2,'Sizes',[55 -1]); + %%-----------------Run--------------------------------------------- + gui_erp_bin_operation.run_title = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_bin_operation.run_title); + uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.run_title,... + 'String','?','callback',@binop_help,'FontSize',16,'Enable','on'); % 2F + uiextras.Empty('Parent', gui_erp_bin_operation.run_title); + gui_erp_bin_operation.run = uicontrol('Style','pushbutton','Parent',gui_erp_bin_operation.run_title,... + 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + uiextras.Empty('Parent', gui_erp_bin_operation.run_title); + set(gui_erp_bin_operation.run_title, 'Sizes',[15 105 30 105 15]); + + gui_erp_bin_operation.note_title = uiextras.HBox('Parent', gui_erp_bin_operation.DataSelBox,'BackgroundColor',ColorB_def); + + uicontrol('Style','text','Parent',gui_erp_bin_operation.note_title,... + 'String','Note: Operates on all bins and channels','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + + set(gui_erp_bin_operation.DataSelBox,'Sizes',[130,30,35,35,30 30]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +% %%------------------help--------------------------------------------- + function binop_help(~,~)%% It seems that it can be ignored + web('https://github.com/lucklab/erplab/wiki/ERP-Bin-Operations','-browser'); + end + + +%%-------------------Equation editor--------------------------------------- + function eq_advanced(Source_editor,~) + def = erpworkingmemory('pop_binoperator'); + if isempty(def) + def = { [], 1}; + end + binopGUI = erpworkingmemory('binopGUI'); + if gui_erp_bin_operation.mode_modify.Value ==1 + binopGUI.emode =0; + else + binopGUI.emode =1; + end + erpworkingmemory('binopGUI',binopGUI); + + ERP = observe_ERPDAT.ERP; + answer = binoperGUI(ERP, def); + if isempty(answer) + disp('User selected Cancel') + return + end + + binopGUI = erpworkingmemory('binopGUI'); + ModeValue = binopGUI.emode; + if ModeValue ==0 + gui_erp_bin_operation.mode_modify.Value =1; + gui_erp_bin_operation.mode_create.Value = 0; + else + gui_erp_bin_operation.mode_modify.Value =0; + gui_erp_bin_operation.mode_create.Value = 1; + end + formulas = answer{1}; + wbmsgon = answer{2}; + + def = {formulas, wbmsgon}; + erpworkingmemory('pop_binoperator', def); + for ii = 1:100 + dsnames{ii,1} = ''; + end + if ~isempty(def{1,1}) + Eqs = def{1,1}; + for ii = 1:length(def{1,1}) + dsnames{ii,1} = Eqs{ii}; + end + gui_erp_bin_operation.edit_bineq.Data = dsnames; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + + end + +%%-------------------Equation Load--------------------------------------- + function eq_load(~,~) + [filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file'); + if isequal(filename,0) + disp('User selected Cancel') + return + else + fullname = fullfile(filepath, filename); + disp(['f_ERP_binoperation_GUI(): For formulas-file, user selected ', fullname]) + end + + fid_formula = fopen( fullname ); + try + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); + catch + beep; + msgboxText = ['ERP Bin Operations - Please, check your file:\n '... + fullname '\n']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if size(formulas,2)>256 + beep; + msgboxText = ['ERP Bin Operations - Formulas length exceed 256 characters.\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + fclose(fid_formula); + gui_erp_bin_operation.edit_bineq.Data = formcell{1,1}; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + +%%-------------------Equation Clear--------------------------------------- + function eq_clear(~,~) + for ii = 1:100 + dsnames{ii,1} = ''; + end + gui_erp_bin_operation.edit_bineq.Data = dsnames; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + + + +%%------------------Modify Existing ERPset--------------------------------------- + function mode_modify(Source_editor,~) + gui_erp_bin_operation.mode_modify.Value = 1; + gui_erp_bin_operation.mode_create.Value = 0; + + + FormulaArrayIn = char(gui_erp_bin_operation.edit_bineq.Data); + if isempty(FormulaArrayIn) + val = 0; + def = erpworkingmemory('pop_binoperator'); + FormulaArrayIn_default = def{1}; + if ~isempty(FormulaArrayIn_default) + [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn_default, 'recu'); + def{1} = formulaArray; + erpworkingmemory('pop_binoperator',def); + end + else + [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn, 'recu'); + end + if val ==1 + gui_erp_bin_operation.edit_bineq.Data =formulaArray; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + def = erpworkingmemory('pop_binoperator'); + def{1} = formulaArray; + erpworkingmemory('pop_binoperator',def); + end + + end + +%%------------------Create New ERPset--------------------------------------- + function mode_create(Source_create,~) + gui_erp_bin_operation.mode_modify.Value = 0; + gui_erp_bin_operation.mode_create.Value = 1; + + + FormulaArrayIn = char(gui_erp_bin_operation.edit_bineq.Data); + if isempty(FormulaArrayIn) + val = 0; + def = erpworkingmemory('pop_binoperator'); + try + FormulaArrayIn_default = def{1}; + catch + for ii = 1:100 + FormulaArrayIn_default{ii,1} = ''; + end + end + if ~isempty(FormulaArrayIn_default) + [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn_default, 'norecu'); + def{1} = formulaArray; + erpworkingmemory('pop_binoperator',def); + end + else + [val, formulaArray]= f_testsyntaxtype(FormulaArrayIn, 'norecu'); + end + if val ==1 + gui_erp_bin_operation.edit_bineq.Data =formulaArray; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + def = erpworkingmemory('pop_binoperator'); + def{1} = formulaArray; + erpworkingmemory('pop_binoperator',def); + end + + end + +%%---------------------Run------------------------------------------------- + function apply_run(~,~) + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + beep; + msgboxText = ['ERP Bin Operations - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + Eq_Data = gui_erp_bin_operation.edit_bineq.Data; + + Formula_str = {}; + count = 0; + for ii = 1:length(Eq_Data) + if ~isempty(Eq_Data{ii}) + count = count +1; + Formula_str{count} = Eq_Data{ii}; + end + end + + if isempty(Formula_str) + beep; + msgboxText = ['ERP Bin Operations - You have not yet written a formula']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + %%check the format of equations + if gui_erp_bin_operation.mode_modify.Value + editormode = 0; + else + editormode = 1; + end + [option, recall, goeson] = checkformulas(cellstr(Formula_str), ['pop_binoperator'], editormode); + if goeson==0 + return + end + + %%%Create a new ERPset for the bin-operated ERPsets + Save_file_label = []; + if gui_erp_bin_operation.mode_create.Value + if numel(Selectederp_Index) > 1 + Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selectederp_Index,'_binop'); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + + if ~isempty(Answer{1}) + ALLERP_out = Answer{1}; + Save_file_label = Answer{2}; + end + elseif numel(Selectederp_Index)== 1 + ALLERP_out = observe_ERPDAT.ALLERP; + ERP = observe_ERPDAT.ALLERP(Selectederp_Index); + ERP.filepath = pathName_def; + Answer = f_ERP_save_single_file(strcat(ERP.erpname,'_binop'),ERP.filename,Selectederp_Index); + if isempty(Answer) + beep; + disp('User selectd cancal'); + return; + end + Save_file_label =0; + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ERP.erpname; + Save_file_label =0; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + Save_file_label =1; + end + end + ALLERP_out(Selectederp_Index) = ERP;clear ERP; + end + elseif gui_erp_bin_operation.mode_modify.Value + ALLERP_out = observe_ERPDAT.ALLERP; + end + + if isempty(Save_file_label) + Save_file_label =0; + end + + + try + erpworkingmemory('f_ERP_proces_messg','ERP Bin Operations'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + for Numofselectederp = 1:numel(Selectederp_Index)%%Bin Operations for each selected ERPset + ERP = ALLERP_out(Selectederp_Index(Numofselectederp)); + [ERP ERPCOM]= pop_binoperator( ERP, Formula_str, 'Warning', 'on', 'ErrorMsg', 'command', 'Saveas', 'off', 'History', 'gui'); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + + if gui_erp_bin_operation.mode_modify.Value%% If select "Modify Existing ERPset (recursive updating)" + ERP.erpname = strcat(ERP.erpname,'_binop'); + observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)) = ERP; + observe_ERPDAT.ERP= observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + elseif gui_erp_bin_operation.mode_create.Value %% If select "Create New ERPset (independent transformations)" + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + if Save_file_label==1 + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ALLERP_out(Selectederp_Index(Numofselectederp)).erpname,... + 'filename', ALLERP_out(Selectederp_Index(Numofselectederp)).filename, 'filepath',ALLERP_out(Selectederp_Index(Numofselectederp)).filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + + end + + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + if gui_erp_bin_operation.mode_create.Value%%Save the labels of the selected ERPsets + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1:length(observe_ERPDAT.ALLERP)]; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + end + + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + return; + catch + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + Selected_ERP_afd =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%% + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + + +%%--------Setting current ERPset/session history based on the current updated ERPset------------ + function Count_currentERPChanged(~,~) + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + + if isempty(Selectederp_Index) + beep; + msgboxText = ['ERP Bin Operations - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + checked_curr_index = 1; + else + checked_curr_index = 0; + end + if isempty(checked_ERPset_Index) + checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index); + end + if checked_curr_index || any(checked_ERPset_Index(:)) + Enable_label = 'off'; + for ii = 1:100 + if ii==1 + dsnames{ii,1} = 'The number of bins and channles should be the same for the selected ERPset!'; + else + dsnames{ii,1} = ''; + end + end + gui_erp_bin_operation.edit_bineq.Data = dsnames; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + else + Enable_label = 'on'; + binopDataor = gui_erp_bin_operation.edit_bineq.Data; + for ii = 1:100 + binopDataorcell = char(binopDataor{ii,1}); + if isempty(binopDataorcell) + dsnames{ii,1} = ''; + else + dsnames{ii,1} = binopDataorcell; + end + end + gui_erp_bin_operation.edit_bineq.Data = dsnames; + set(gui_erp_bin_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + gui_erp_bin_operation.mode_modify.Enable=Enable_label; + gui_erp_bin_operation.mode_create.Enable=Enable_label; + gui_erp_bin_operation.eq_editor.Enable = Enable_label; + gui_erp_bin_operation.eq_load.Enable = Enable_label; + gui_erp_bin_operation.eq_clear.Enable = Enable_label; + gui_erp_bin_operation.run.Enable = Enable_label; + + end +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_chanoperation_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_chanoperation_GUI.m new file mode 100755 index 00000000..77cc5603 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_chanoperation_GUI.m @@ -0,0 +1,638 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_chanoperation_GUI(varargin) +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +gui_erp_chan_operation = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global ERP_chan_operation_gui; +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end +if nargin == 0 + fig = figure(); % Parent figure + ERP_chan_operation_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Channel Operations', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_chan_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Channel Operations', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_chan_operation_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Channel Operations', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_bin_operation(FonsizeDefault); +varargout{1} = ERP_chan_operation_gui; + + function drawui_erp_bin_operation(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + FontSize_defualt = FonsizeDefault; + if isempty(FontSize_defualt) + FontSize_defualt = 12; + end + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + %%--------------------channel and bin setting---------------------- + gui_erp_chan_operation.DataSelBox = uiextras.VBox('Parent', ERP_chan_operation_gui); + for ii = 1:100 + dsnames{ii,1} = ''; + end + gui_erp_chan_operation.erp_history_table = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_chan_operation.edit_bineq = uitable( ... + 'Parent' , gui_erp_chan_operation.erp_history_table,... + 'Data' , dsnames, ... + 'ColumnWidth' , {1000}, ... + 'ColumnName' , [], ... + 'RowName' , []); + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,length(dsnames)),'FontSize',FontSize_defualt); + + gui_erp_chan_operation.equation_selection = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_chan_operation.eq_editor = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.equation_selection,... + 'String','Eq. Advanced','callback',@eq_advanced,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + gui_erp_chan_operation.eq_load = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.equation_selection,... + 'String','Load Eq.','callback',@eq_load,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + gui_erp_chan_operation.eq_clear = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.equation_selection,... + 'String','Clear Eq.','callback',@eq_clear,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + + gui_erp_chan_operation.asst_locaInfo = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_chan_operation.ref_asst = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.asst_locaInfo,... + 'String','Reference Asst','callback',@ref_asst,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + gui_erp_chan_operation.locaInfor = uicontrol('Style','checkbox','Parent',gui_erp_chan_operation.asst_locaInfo,... + 'String','Load Eq.','callback',@loca_infor,'FontSize',FontSize_defualt,'Value',1,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F + gui_erp_chan_operation.locaInfor.String = 'Try to Preserve
Location Information'; + set(gui_erp_chan_operation.asst_locaInfo,'Sizes',[105 180]); + %%%----------------Mode----------------------------------- + gui_erp_chan_operation.mode_1 = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_chan_operation.mode_modify_title = uicontrol('Style','text','Parent',gui_erp_chan_operation.mode_1 ,... + 'String','Mode:','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_chan_operation.mode_modify = uicontrol('Style','radiobutton','Parent',gui_erp_chan_operation.mode_1 ,... + 'String','Modify Existing ERPset','callback',@mode_modify,'Value',1,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F + gui_erp_chan_operation.mode_modify.String = 'Modify Existing ERPset
(recursive updating)'; + set(gui_erp_chan_operation.mode_1,'Sizes',[55 -1]); + %%--------------For create a new ERPset---------------------------- + gui_erp_chan_operation.mode_2 = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_chan_operation.mode_2,'BackgroundColor',ColorB_def); + gui_erp_chan_operation.mode_create = uicontrol('Style','radiobutton','Parent',gui_erp_chan_operation.mode_2 ,... + 'String',{'', ''},'callback',@mode_create,'Value',0,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',ColorB_def); % 2F + gui_erp_chan_operation.mode_create.String = 'Create New ERPset
(independent transformations)'; + set(gui_erp_chan_operation.mode_2,'Sizes',[55 -1]); + %%-----------------Run--------------------------------------------- + gui_erp_chan_operation.run_title = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + + + uiextras.Empty('Parent', gui_erp_chan_operation.run_title,'BackgroundColor',ColorB_def); + uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.run_title,... + 'String','?','callback',@chanop_help,'FontSize',16,'Enable','on'); + uiextras.Empty('Parent', gui_erp_chan_operation.run_title,'BackgroundColor',ColorB_def); + gui_erp_chan_operation.run = uicontrol('Style','pushbutton','Parent',gui_erp_chan_operation.run_title,... + 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + uiextras.Empty('Parent', gui_erp_chan_operation.run_title,'BackgroundColor',ColorB_def); + set(gui_erp_chan_operation.run_title,'Sizes',[15 105 30 105 15]); + + gui_erp_chan_operation.note_title = uiextras.HBox('Parent', gui_erp_chan_operation.DataSelBox,'BackgroundColor',ColorB_def); + uicontrol('Style','text','Parent',gui_erp_chan_operation.note_title,... + 'String','Note: Operates on all bins and channels','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + + set(gui_erp_chan_operation.DataSelBox,'Sizes',[130,30,35,35,35,30 30]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +% %%------------------Edit bin--------------------------------------------- + function chanop_help(~,~)%% It seems that it can be ignored + web('https://github.com/lucklab/erplab/wiki/EEG-and-ERP-Channel-Operations','-browser'); + end + + +%%-------------------Equation editor--------------------------------------- + function eq_advanced(Source_editor,~) + def = erpworkingmemory('pop_erpchanoperator'); + if isempty(def) + def = { [], 1}; + end + chanopGUI = erpworkingmemory('chanopGUI'); + if gui_erp_chan_operation.mode_modify.Value==1 + chanopGUI.emode=0; + else + chanopGUI.emode=1; + end + localInfor = gui_erp_chan_operation.locaInfor.Value; + chanopGUI.keeplocs = localInfor; + erpworkingmemory('chanopGUI',chanopGUI); + + ERP = observe_ERPDAT.ERP; + answer = chanoperGUI(ERP, def); + if isempty(answer) + disp('User selected Cancel') + return + end + chanopGUI = erpworkingmemory('chanopGUI'); + ModeValue = chanopGUI.emode; + if ModeValue==0 + gui_erp_chan_operation.mode_modify.Value=1 ; + gui_erp_chan_operation.mode_create.Value = 0; + else + gui_erp_chan_operation.mode_modify.Value=0 ; + gui_erp_chan_operation.mode_create.Value = 1; + end + localInfor = chanopGUI.keeplocs; + if localInfor==1 + gui_erp_chan_operation.locaInfor.Value=1; + else + gui_erp_chan_operation.locaInfor.Value=0; + end + + formulas = answer{1}; + wbmsgon = answer{2}; + keeplocs = answer{3}; + if keeplocs ==1 + gui_erp_chan_operation.locaInfor.Value = 1; + else + gui_erp_chan_operation.locaInfor.Value = 0; + end + + def = {formulas, wbmsgon}; + erpworkingmemory('pop_erpchanoperator', def); + for ii = 1:1000 + dsnames{ii,1} = ''; + end + + if ~isempty(def{1,1}) + Eqs = def{1,1}; + for ii = 1:length(def{1,1}) + dsnames{ii,1} = Eqs{ii}; + end + gui_erp_chan_operation.edit_bineq.Data = dsnames; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + + end + +%%-------------------Equation Load--------------------------------------- + function eq_load(~,~) + [filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file'); + if isequal(filename,0) + disp('User selected Cancel') + return + else + fullname = fullfile(filepath, filename); + disp(['f_ERP_chanoperation_GUI(): For formulas-file, user selected ', fullname]) + end + + fid_formula = fopen( fullname ); + try + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); + catch + beep; + msgboxText = ['ERP Channel Operations - Please, check your file:\n '... + fullname '\n']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if size(formulas,2)>256 + beep; + msgboxText = ['ERP Channel Operations - Formulas length exceed 256 characters,'... + 'Be sure to press [Enter] after you have entered each formula.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + fclose(fid_formula); + gui_erp_chan_operation.edit_bineq.Data = formcell{1,1}; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + +%%-------------------Equation Clear--------------------------------------- + function eq_clear(~,~) + for ii = 1:1000 + dsnames{ii,1} = ''; + end + gui_erp_chan_operation.edit_bineq.Data = dsnames; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + +%%-------------------Reference assist-------------------------------------- + function ref_asst(~,~) + gui_erp_chan_operation.mode_modify.Value = 0; + gui_erp_chan_operation.mode_create.Value = 1; + + try + ERPLAB = observe_ERPDAT.ERP; + nchan = ERPLAB.nchan; + catch + ERPLAB.chanlocs = []; + nchan = 1; + end + listch=[]; + if isempty(ERPLAB.chanlocs) + for e=1:nchan + ERPLAB.chanlocs(e).labels = ['Ch' num2str(e)]; + end + end + listch = cell(1,nchan); + for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERPLAB.chanlocs(ch).labels ]; + end + + % open reference wizard + formulalist = f_rerefassistantGUI(nchan, listch); + if isempty(formulalist) + return; + end + formulas = char(gui_erp_chan_operation.edit_bineq.Data); + for ii = 1:1000 + dsnames{ii,1} = ''; + end + + if gui_erp_chan_operation.mode_create.Value + formulalist = cellstr([formulalist{:}]); + for t=1:length(formulalist) + [expspliter parts] = regexp(formulalist, '=','match','split'); + formulalist{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '[^n]*ch','nch','ignorecase')), strtrim(parts{t}{2})); + end + % formulalist = char(formulalist); + end + + if isempty(formulas) + for ii = 1:length(formulalist) + dsnames{ii,1} = formulalist{ii}; + end + gui_erp_chan_operation.edit_bineq.Data =dsnames; + else + formulas = cellstr(formulas); + count = 0; + for ii = 1:length(formulas) + if ~isempty(formulas{ii}) + count = count+1; + dsnames{count,1} = formulas{ii}; + end + end + + for ii = 1:length(formulalist) + dsnames{count+ii,1} = formulalist{ii}; + end + clear count; + gui_erp_chan_operation.edit_bineq.Data =dsnames; + end + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + + end + +%%--------------------Preserve location information------------------------ + function loca_infor(source,~) + Value = source.Value; + gui_erp_chan_operation.locaInfor.Value = Value; + end + + + +%%------------------Modify Existing ERPset--------------------------------------- + function mode_modify(Source_editor,~) + gui_erp_chan_operation.mode_modify.Value = 1; + gui_erp_chan_operation.mode_create.Value = 0; + + FormulaArrayIn = gui_erp_chan_operation.edit_bineq.Data; + if isempty(FormulaArrayIn) + val = 0; + def = erpworkingmemory('pop_erpchanoperator'); + FormulaArrayIn_default = def{1}; + if ~isempty(FormulaArrayIn_default) + [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn_default, 'recu'); + def{1} = formulaArray; + erpworkingmemory('pop_erpchanoperator',def); + end + else + [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn, 'recu'); + end + + if val ==1 + for ii = 1:100 + try + formulaArray{ii,1} = formulaArray{ii}; + catch + formulaArray{ii,1} = ''; + end + end + gui_erp_chan_operation.edit_bineq.Data =formulaArray; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + def = erpworkingmemory('pop_erpchanoperator'); + def{1} = formulaArray; + erpworkingmemory('pop_erpchanoperator',def); + end + + end + +%%------------------Create New ERPset--------------------------------------- + function mode_create(Source_create,~) + gui_erp_chan_operation.mode_modify.Value = 0; + gui_erp_chan_operation.mode_create.Value = 1; + FormulaArrayIn = char(gui_erp_chan_operation.edit_bineq.Data); + if isempty(FormulaArrayIn) + val = 0; + def = erpworkingmemory('pop_erpchanoperator'); + FormulaArrayIn_default = def{1}; + if ~isempty(FormulaArrayIn_default) + [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn_default, 'norecu'); + def{1} = formulaArray; + erpworkingmemory('pop_erpchanoperator',def); + else + for ii = 1:100 + formulaArray{ii,1} = ''; + end + end + else + [val, formulaArray]= f_chan_testsyntaxtype(FormulaArrayIn, 'norecu'); + end + if val ==1 + for ii = 1:100 + try + formulaArray{ii,1} = formulaArray{ii}; + catch + formulaArray{ii,1} = ''; + end + end + gui_erp_chan_operation.edit_bineq.Data =formulaArray; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + def = erpworkingmemory('pop_erpchanoperator'); + def{1} = formulaArray; + erpworkingmemory('pop_erpchanoperator',def); + end + + end + +%%---------------------Run------------------------------------------------- + function apply_run(~,~) + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + beep; + msgboxText = ['ERP Channel Operations -No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + Eq_Data = gui_erp_chan_operation.edit_bineq.Data; + + Formula_str = {}; + count = 0; + for ii = 1:length(Eq_Data) + if ~isempty(Eq_Data{ii}) + count = count +1; + Formula_str{count} = Eq_Data{ii}; + end + end + + if isempty(Formula_str) + beep; + msgboxText = ['ERP Channel Operations - You have not yet written a formula']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + %%check the format of equations + if gui_erp_chan_operation.mode_modify.Value + editormode = 0; + else + editormode = 1; + end + [option, recall, goeson] = checkformulas(cellstr(Formula_str), ['pop_erpchanoperator'], editormode); + if goeson==0 + return; + end + + %%%Create a new ERPset for the bin-operated ERPsets + Save_file_label = []; + if gui_erp_chan_operation.mode_create.Value + + if numel(Selectederp_Index) > 1 + Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selectederp_Index,'_chop'); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + if ~isempty(Answer{1}) + ALLERP_out = Answer{1}; + Save_file_label = Answer{2}; + end + + elseif numel(Selectederp_Index)== 1 + ALLERP_out = observe_ERPDAT.ALLERP; + ERP = observe_ERPDAT.ALLERP(Selectederp_Index); + ERP.filepath = pathName_def; + Answer = f_ERP_save_single_file(strcat(ERP.erpname,'_chop'),ERP.filename,Selectederp_Index); + if isempty(Answer) + beep; + disp('User selectd cancal'); + return; + end + Save_file_label =0; + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ERP.erpname; + Save_file_label =0; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + Save_file_label =1; + end + + end + ALLERP_out(Selectederp_Index) = ERP;clear ERP; + end + elseif gui_erp_chan_operation.mode_modify.Value + ALLERP_out = observe_ERPDAT.ALLERP; + end + + if isempty(Save_file_label) + Save_file_label =0; + end + + if gui_erp_chan_operation.locaInfor.Value + keeplocs =1; + else + keeplocs =0; + end + + try + erpworkingmemory('f_ERP_proces_messg','ERP Bin Operations'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + for Numofselectederp = 1:numel(Selectederp_Index)%%Bin Operations for each selected ERPset + ERP = ALLERP_out(Selectederp_Index(Numofselectederp)); + [ERP, ERPCOM] = pop_erpchanoperator(ERP, Formula_str, 'Warning', 'off', 'Saveas', 'off','ErrorMsg', 'command','KeepLocations',keeplocs, 'History', 'gui'); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + if gui_erp_chan_operation.mode_modify.Value%% If select "Modify Existing ERPset (recursive updating)" + ERP.erpname = strcat(ERP.erpname,'_chop'); + observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)) = ERP; + observe_ERPDAT.ERP= observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + elseif gui_erp_chan_operation.mode_create.Value %% If select "Create New ERPset (independent transformations)" + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + if Save_file_label==1 + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ALLERP_out(Selectederp_Index(Numofselectederp)).erpname,... + 'filename', ALLERP_out(Selectederp_Index(Numofselectederp)).filename, 'filepath',ALLERP_out(Selectederp_Index(Numofselectederp)).filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + end + + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + if gui_erp_chan_operation.mode_create.Value%%Save the labels of the selected ERPsets + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1:length(observe_ERPDAT.ALLERP)]; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selectederp_Index)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + end + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + return; + catch + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + Selected_ERP_afd =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%% + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%--------Setting current ERPset/session history based on the current updated ERPset------------ + function Count_currentERPChanged(~,~) + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + beep; + msgboxText = ['ERP Channel Operations - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + checked_curr_index = 1; + else + checked_curr_index = 0; + end + + if isempty(checked_ERPset_Index) + checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index); + end + if checked_curr_index || any(checked_ERPset_Index(:)) + Enable_label = 'off'; + for ii = 1:100 + if ii==1 + dsnames{ii,1} = 'The number of bins and channles should be the same for the selected ERPset!'; + else + dsnames{ii,1} = ''; + end + end + gui_erp_chan_operation.edit_bineq.Data = dsnames; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + else + Enable_label = 'on'; + chanopDataor = gui_erp_chan_operation.edit_bineq.Data; + for ii = 1:100 + chanopDataorcell = char(chanopDataor{ii,1}); + if isempty(chanopDataorcell) + dsnames{ii,1} = ''; + else + dsnames{ii,1} = chanopDataorcell; + end + end + gui_erp_chan_operation.edit_bineq.Data = dsnames; + set(gui_erp_chan_operation.edit_bineq,'ColumnEditable',true(1,1000),'ColumnWidth',{1000}); + end + gui_erp_chan_operation.mode_modify.Enable=Enable_label; + gui_erp_chan_operation.mode_create.Enable=Enable_label; + gui_erp_chan_operation.eq_editor.Enable = Enable_label; + gui_erp_chan_operation.eq_load.Enable = Enable_label; + gui_erp_chan_operation.eq_clear.Enable = Enable_label; + gui_erp_chan_operation.run.Enable = Enable_label; + gui_erp_chan_operation.ref_asst.Enable = Enable_label; + gui_erp_chan_operation.locaInfor.Enable = Enable_label; + + end + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_erpsetsGUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_erpsetsGUI.m new file mode 100755 index 00000000..5e3e3e3b --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_erpsetsGUI.m @@ -0,0 +1,1515 @@ +% ERPset selector panel +% +% Author: Carter Luck and Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2018 & 2022 + +% ERPLAB Toolbox +% + +% +% Initial setup +% +function varargout = f_ERP_erpsetsGUI(varargin) +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + +ERPsetops = struct(); +%---------Setting the parameter which will be used in the other panels----------- + +CurrentERPSet = evalin('base','CURRENTERP'); + +if isempty(CurrentERPSet) || (CurrentERPSet> length(observe_ERPDAT.ALLERP)) + CurrentERPSet =1; +end + + +estudioworkingmemory('selectederpstudio',CurrentERPSet); + +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end +datasets = []; % Local data structure +% global box; +if nargin == 0 + fig = figure(); % Parent figure + box_erpset_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + box_erpset_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5,'BackgroundColor',ColorB_def); +else + box_erpset_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERPsets', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + + +getDatasets() % Get datasets from ALLERP + +datasets = sortdata(datasets); +datasets = sortdata(datasets); +% global selectedData; +try + cerp = observe_ERPDAT.CURRENTERP; + i = observe_ERPDAT.ALLERP(1,cerp); + [r,~] = size(datasets); + for j = 1:r + if strcmp(i.erpname,cell2mat(datasets(j,1)))&&strcmp(i.filename,cell2mat(datasets(j,4)))&&strcmp(i.filepath,cell2mat(datasets(j,5))) + selectedData = j; + end + end +catch + selectedData = 0; +end + + +sel_path = cd; +estudioworkingmemory('ERP_save_folder',sel_path); +% datasets = {'name', 1, 0, 'Users/***/Documents/Matlab/Test_data/', 'S1.erp';'name2', 2, 1;'name3', 3, 2;'name4', 4, 1;'name5', 5, 4}; % Create datasets. {'Name', datasetNumber, parentNumber, 'filename', 'filepath'} +% Test erpname/filepath/filename against ALLERP to correlate +% No duplicate dataset numbers. If a dataset's parent number is not a valid +% dataset, the dataset will be cleared when dataset = sortdata(datasets) is +% called. erpsetname must contain at least one non-numeric character. +datasets = sortdata(datasets); + + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erpset(FonsizeDefault); + +varargout{1} = box_erpset_gui; + + +% Grab local structure from global ERP (update local structure instead of +% replacing it) + +% Draw the ui + function drawui_erpset(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + [r, ~] = size(datasets); % Get size of array of datasets. r is # of datasets + % Sort the datasets!!! + datasets = sortdata(datasets); + vBox = uiextras.VBox('Parent', box_erpset_gui, 'Spacing', 5,'BackgroundColor',ColorB_def); % VBox for everything + panelshbox = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def); + % panelshbox = uix.ScrollingPanel('Parent', vBox); + panelsv2box = uiextras.VBox('Parent',panelshbox,'Spacing',5,'BackgroundColor',ColorB_def); + + + %%-----------------------ERPset display--------------------------------------- + dsnames = {}; + if size(datasets,1)==1 + if strcmp(datasets{1},'No ERPset loaded') + dsnames = {''}; + Edit_label = 'off'; + else + dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1}); + Edit_label = 'on'; + end + else + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1})); + end + Edit_label = 'on'; + end + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + ds_length = length(datasets); + if selectedData == 0 + ERPsetops.butttons_datasets = uicontrol('Parent', panelsv2box, 'Style', 'listbox', 'min', 1,'max',... + ds_length,'String', dsnames,'Value',1,'Callback',@selectdata,'FontSize',FonsizeDefault); + else + ERPsetops.butttons_datasets = uicontrol('Parent', panelsv2box, 'Style', 'listbox', 'min', 1,'max',... + ds_length,'String', dsnames,'Value', SelectedERP,'Callback',@selectdata,'FontSize',FonsizeDefault); + end + set(vBox, 'Sizes', 150); + + %%---------------------Options for ERPsets----------------------------------------------------- + ERPsetops.buttons2 = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def); + ERPsetops.dupeselected = uicontrol('Parent', ERPsetops.buttons2, 'Style', 'pushbutton', 'String', 'Duplicate', ... + 'Callback', @duplicateSelected,'Enable',Edit_label,'FontSize',FonsizeDefault); + ERPsetops.renameselected = uicontrol('Parent', ERPsetops.buttons2, 'Style', 'pushbutton', 'String', 'Rename',... + 'Callback', @renamedata,'Enable',Edit_label,'FontSize',FonsizeDefault); + ERPsetops.suffix = uicontrol('Parent', ERPsetops.buttons2, 'Style', 'pushbutton', 'String', 'Add Suffix',... + 'Callback', @add_suffix,'Enable',Edit_label,'FontSize',FonsizeDefault); + + + buttons3 = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def); + ERPsetops.importexport = uicontrol('Parent',buttons3, 'Style', 'pushbutton', 'String', 'Import',... + 'Callback', @imp_erp,'FontSize',FonsizeDefault); + ERPsetops.export = uicontrol('Parent',buttons3, 'Style', 'pushbutton', 'String', 'Export', 'Callback', @exp_erp,'Enable',Edit_label,'FontSize',FonsizeDefault); + ERPsetops.loadbutton = uicontrol('Parent', buttons3, 'Style', 'pushbutton', 'String', 'Load', ... + 'Callback', @load,'FontSize',FonsizeDefault); + ERPsetops.clearselected = uicontrol('Parent', buttons3, 'Style', 'pushbutton', 'String', 'Clear', 'Callback', @cleardata,'Enable',Edit_label,'FontSize',FonsizeDefault); + buttons4 = uiextras.HBox('Parent', vBox, 'Spacing', 5,'BackgroundColor',ColorB_def); + ERPsetops.savebutton = uicontrol('Parent', buttons4, 'Style', 'pushbutton', 'String', 'Save', 'Callback', @savechecked,'Enable',Edit_label,'FontSize',FonsizeDefault); + ERPsetops.saveasbutton = uicontrol('Parent', buttons4, 'Style', 'pushbutton', 'String', 'Save As...', 'Callback', @savecheckedas,'Enable',Edit_label,'FontSize',FonsizeDefault); + ERPsetops.dotstoggle = uicontrol('Parent', buttons4, 'Style', 'pushbutton', 'String', 'Current Folder', 'Callback', @toggledots,'Enable',Edit_label,'FontSize',FonsizeDefault); + set(buttons4,'Sizes',[70 70 115]) + end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%---------------------------------------------- Subfunctions --------------------------------------------%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%------------------duplicate the selected ERPsets----------------------------- + function duplicateSelected(source,~)%%The defualt channels and bins that come from "bin and channel" panel but user can select bins and channels. + + erpworkingmemory('f_ERP_proces_messg','ERPsets>Duplicate'); + observe_ERPDAT.Process_messg =1; + + SelectedERP= ERPsetops.butttons_datasets.Value; + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + checked_ERPset_Index_bin_chan = [0 0 0 0 0 0 0]; + try + S_geterpbinchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan = S_geterpbinchan.checked_ERPset_Index; + catch + checked_ERPset_Index_bin_chan = f_checkerpsets(observe_ERPDAT.ALLERP,SelectedERP); + end + + BinArray = []; + ChanArray = []; + try + S_geterpbinchan = estudioworkingmemory('geterpbinchan'); + BinArray = S_geterpbinchan.bins{1}; + ChanArray = S_geterpbinchan.elecs_shown{1}; + catch + BinArray = []; + ChanArray = []; + end + + + try + for Numofselecterp = 1:numel(SelectedERP) + New_ERP = observe_ERPDAT.ALLERP(SelectedERP(Numofselecterp)); + + New_ERP.filename = ''; + New_ERP.erpname = char(strcat(New_ERP.erpname, '_Duplicated')); + if checked_ERPset_Index_bin_chan(1)==1 || checked_ERPset_Index_bin_chan(2) ==2 + BinArray = [1:New_ERP.nbin]; + ChanArray = [1:New_ERP.nchan]; + end + New_ERP = f_ERP_duplicate(New_ERP,length(observe_ERPDAT.ALLERP),BinArray,ChanArray); + if isempty(New_ERP) + beep; + disp('User selected cancal!'); + return; + end + + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = New_ERP; + + datasets = {}; + getDatasets() + datasets = sortdata(datasets); + + + dsnames = {}; + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = char(strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1})); + end + %%Reset the display in ERPset panel + ERPsetops.butttons_datasets.String = dsnames; + ERPsetops.butttons_datasets.Min = 1; + ERPsetops.butttons_datasets.Max = length(datasets); + % ERPsetops.butttons_datasets.Value = observe_ERPDAT.CURRENTERP; + end + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(SelectedERP)+1:length(observe_ERPDAT.ALLERP)]; + ERPsetops.butttons_datasets.Value = Selected_ERP_afd; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(SelectedERP)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + ERPsetops.butttons_datasets.Value = Selected_ERP_afd; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + SelectedERP =Selected_ERP_afd; + estudioworkingmemory('selectederpstudio',SelectedERP); + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP_afd); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + observe_ERPDAT.Process_messg =2; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + catch + ERPsetops.butttons_datasets.Value = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + SelectedERP =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',SelectedERP); + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP_afd); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + observe_ERPDAT.Process_messg =3; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + +%%-------------------Rename the selcted files------------------------------ + function renamedata(~,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Rename'); + observe_ERPDAT.Process_messg =1; + + SelectedERP= ERPsetops.butttons_datasets.Value; + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + for Numofselecterp = 1:length(SelectedERP) + try + ndsns = SelectedERP(Numofselecterp); + [r,~] = size(datasets); + for Numofsub = 1:r + if ismember(datasets{Numofsub,2},ndsns) + + erpName = char(datasets{Numofsub,1}); + new = f_ERP_rename_gui(erpName,SelectedERP(Numofselecterp)); + if isempty(new) + beep; + disp(['User selected cancel']); + return; + end + + datasets{Numofsub,1} = new{1,1}; + clear k + [~,cerp] = size(observe_ERPDAT.ALLERP); + for k = 1:cerp + if strcmp(observe_ERPDAT.ALLERP(1,k).filepath,datasets{Numofsub,5}) && strcmp(observe_ERPDAT.ALLERP(1,k).filename,datasets{Numofsub,4}) + observe_ERPDAT.ALLERP(1,k).erpname = cell2mat(new); + end + end + end + end + datasets = sortdata(datasets); + + dsnames = {}; + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = char(strcat(num2str(datasets{Numofsub,2}),'.',32,datasets{Numofsub,1})); + + end + ERPsetops.butttons_datasets.String = dsnames; + ERPsetops.butttons_datasets.Min = 1; + ERPsetops.butttons_datasets.Max = length(datasets); + observe_ERPDAT.Process_messg =2; + catch + datasets = sortdata(datasets); + dsnames = {}; + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = char(strcat(num2str(datasets{Numofsub,2}),'.',32,char(datasets{Numofsub,1}))); + end + ERPsetops.butttons_datasets.String = dsnames; + ERPsetops.butttons_datasets.Min = 1; + ERPsetops.butttons_datasets.Max = length(datasets); + observe_ERPDAT.Process_messg =3; + end + end + end + +%%--------------------------------Add Suffix--------------------------------- + function add_suffix(~,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Add Suffix'); + observe_ERPDAT.Process_messg =1; + + SelectedERP= ERPsetops.butttons_datasets.Value; + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + new = f_ERP_suffix_gui('Suffix'); + if ~isempty(new) + for Numofselecterp = 1:length(SelectedERP) + datasets{SelectedERP(Numofselecterp),1} = char(strcat(datasets{SelectedERP(Numofselecterp),1},'_',new{1})); + + [~,cerp] = size(observe_ERPDAT.ALLERP); + for Numoferp = 1:cerp + if strcmp(observe_ERPDAT.ALLERP(1,Numoferp).filepath,char(datasets{SelectedERP(Numofselecterp),5})) && strcmp(observe_ERPDAT.ALLERP(1,Numoferp).filename,char(datasets{SelectedERP(Numofselecterp),4})) + observe_ERPDAT.ALLERP(1,Numoferp).erpname = char(datasets{SelectedERP(Numofselecterp),1}); + end + end + end + observe_ERPDAT.Process_messg =2; + else + beep; + disp('User cancelled'); + observe_ERPDAT.Process_messg =4; + return; + end + datasets = sortdata(datasets); + dsnames = {}; + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = char(strcat(num2str((datasets{Numofsub,2})),'.',32,char(datasets{Numofsub,1}))); + end + ERPsetops.butttons_datasets.String = dsnames; + ERPsetops.butttons_datasets.Min = 1; + ERPsetops.butttons_datasets.Max = size(datasets,1); + end + + + +%----------------------- Import----------------------------------- + function imp_erp( ~, ~ ) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Import'); + observe_ERPDAT.Process_messg =1; + %-----------Setting for import------------------------------------- + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.7020 0.77 0.85]; + end + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',ColorB_def); + [ind,tf] = listdlg('ListString',{'ERPSS Text','Universal Text','Neuroscan (*.arg)'},'SelectionMode','single',... + 'PromptString','Please select a type to import from...','Name','Import','OKString','Select'); + + set(0,'DefaultUicontrolBackgroundColor',[1 1 1]); + + if isempty(ind) + beep; + disp(['User selected cancel']); + return; + + end + ALLERPCOM = evalin('base','ALLERPCOM'); + + try + if tf%Import start + %%------------------------------------------------------------------------------- + %%-----------------------Import ERPSS text--------------------------------------- + %%------------------------------------------------------------------------------- + if ind == 1 + % pop_importerpss_studio(); + answer = importERPSS_GUI; %(gui was modified) + + if isempty(answer) + disp('User selected Cancel') + return + end + + fname = answer{1}; % filename (+ whole path) + dformat = answer{2}; % data format + dtranspose = answer{3}; % transpose data (Fixed) + if dformat==0 + dformatstr = 'explicit'; % points at columns + else + dformatstr = 'implicit'; % points at rows + end + if dtranspose==0 + orienpoint = 'column'; % points at columns + else + orienpoint = 'row'; % points at rows + end + + [ERP, ALLERP, ERPCOM] = pop_importerpss('Filename', fname, 'Format', dformatstr, 'Pointat', orienpoint, 'History', 'script'); + ERP = erphistory(ERP, [], ERPCOM,1); + + try + Selected_erpset = [length(ALLERP)-length(fname)+1:length(ALLERP)]; + catch + beep; + disp('Fail to import the ERPsets, please try again or restart EStudio!'); + return + end + ALLERP = f_erp_remv_Calibrate(ALLERP, Selected_erpset); + Answer = f_ERP_save_multi_file(ALLERP,Selected_erpset,'_erpss'); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + Save_file_label = 0; + if ~isempty(Answer{1}) + ALLERP_advance = Answer{1}; + Save_file_label = Answer{2}; + end + if Save_file_label==1 + for Numoferpset = 1:length(Selected_erpset) + ERP = ALLERP_advance(Selected_erpset(Numoferpset)); + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + ERP = erphistory(ERP, [], ERPCOM,1); + end + end + observe_ERPDAT.ALLERP=ALLERP_advance; clear ALLERP_advance;clear ALLERP + + else + %%------------------------------------------------------------------------ + %%----------------------- Import Universal text----------------------- + %%------------------------------------------------------------------------ + if ind == 2 + + def = erpworkingmemory('pop_importerp'); + if isempty(def) + def = {'','','',0,1,0,0,1000,[-200 800]}; + end + % + % Call GUI + % + getlista = importerpGUI(def); + + if isempty(getlista) + disp('User selected Cancel') + return + end + + filename = getlista{1}; + filepath = getlista{2}; + ftype = getlista{3}; + includetime = getlista{4}; + timeunit = getlista{5}; + elabel = getlista{6}; + transpose = getlista{7}; + fs = getlista{8}; + xlim = getlista{9}; + + erpworkingmemory('pop_importerp', {filename, filepath, ftype,includetime,timeunit,elabel,transpose,fs,xlim}); + + filetype = {'text'}; + if includetime==0 + inctimestr = 'off'; + else + inctimestr = 'on'; + end + if elabel==0 + elabelstr = 'off'; + else + elabelstr = 'on'; + end + if transpose==0 + orienpoint = 'column'; % points at columns + else + orienpoint = 'row'; % points at rows + end + + % + % Somersault + % + [ERP, ERPCOM] = pop_importerp('Filename', filename, 'Filepath', filepath, 'Filetype', filetype, 'Time', inctimestr,... + 'Timeunit', timeunit, 'Elabel', elabelstr, 'Pointat', orienpoint, 'Srate', fs, 'Xlim', xlim, 'Saveas', 'off',... + 'History', 'gui'); + + % [ERP, ERPCOM] = pop_importerp(); + if length(observe_ERPDAT.ALLERP)==1 && strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Selected_erpset_indx = 1; + else + Selected_erpset_indx = length(observe_ERPDAT.ALLERP)+1; + end + try + filename = ERP.erpname; + catch + filename = strcat('Sub',num2str(Selected_erpset_indx),'-universal'); + end + if isempty(filename) + filename = strcat('Sub',num2str(Selected_erpset_indx),'-universal'); + end + ERP.erpname = filename; + %%------------------------------------------------------------------------ + %%------------------------Import Neuroscan (.avg)---------------- + %%------------------------------------------------------------------------ + elseif ind == 3 %% + [filename, filepath] = uigetfile({'*.avg';'Neuroscan average file (*.avg)'},'Select a file (Neuroscan)', 'MultiSelect', 'on'); + if ~iscell(filename) && ~ischar(filename) && filename==0 + disp('User selected Cancel') + return + end + + [ERP, ERPCOM]= pop_importavg(filename, filepath, 'Saveas','off','History', 'gui'); + + [pathstr, file_name, ext] = fileparts(filename{1,1}); + ERP.erpname = file_name; + if length(observe_ERPDAT.ALLERP)==1 && strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Selected_erpset_indx = 1; + else + Selected_erpset_indx = length(observe_ERPDAT.ALLERP)+1; + end + end + ERP = erphistory(ERP, [], ERPCOM,1); + + Answer = f_ERP_save_single_file(ERP.erpname,ERP.filename,Selected_erpset_indx); + if isempty(Answer) + beep; + % disp('User selectd cancal'); + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ERP.erpname; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + %%----------save the current sdata as-------------------- + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + ERP = erphistory(ERP, [], ERPCOM,1); + end + end + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) =ERP; + end + end + + [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + + ERPset_default_label = []; + count = 0; + for Numoferpset = 1:size(observe_ERPDAT.ALLERP,2) + if strcmp(observe_ERPDAT.ALLERP(Numoferpset).erpname,'No ERPset loaded') + count = count +1; + ERPset_default_label(count) = Numoferpset; + end + end + + if ~isempty(ERPset_default_label) + observe_ERPDAT.ALLERP(ERPset_default_label)=[]; + end + + datasets = {}; + getDatasets() + datasets = sortdata(datasets); + + dsnames = {}; + if size(datasets,1)==1 + if strcmp(datasets{1},'No ERPset loaded') + dsnames = {''}; + Edit_label = 'off'; + else + dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1}); + Edit_label = 'on'; + end + else + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1}); + end + Edit_label = 'on'; + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end); + observe_ERPDAT.Process_messg =2; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + catch + observe_ERPDAT.Process_messg =3; + disp(['User selected cancel']); + return; + end + ERPsetops.butttons_datasets.Value = length(observe_ERPDAT.ALLERP); + ERPsetops.butttons_datasets.String = dsnames; + if strcmp(datasets{1},'No ERPset loaded') + Edit_label = 'off'; + else + Edit_label = 'on'; + end + ERPsetops.dupeselected.Enable=Edit_label; + ERPsetops.renameselected.Enable=Edit_label; + ERPsetops.suffix.Enable= Edit_label; + ERPsetops.clearselected.Enable=Edit_label; + ERPsetops.savebutton.Enable= Edit_label; + ERPsetops.saveasbutton.Enable=Edit_label; + ERPsetops.dotstoggle.Enable=Edit_label; + ERPsetops.butttons_datasets.Enable = Edit_label; + ERPsetops.export.Enable = Edit_label; + + SelectedERP = observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',SelectedERP); + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + ERPsetops.butttons_datasets.Min=1; + if size(datasets,1)<=2 + ERPsetops.butttons_datasets.Max=size(datasets,1)+1; + else + ERPsetops.butttons_datasets.Max=size(datasets,1); + end + observe_ERPDAT.Process_messg =2; + observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + +%-----------------------Export----------------------------------- + function exp_erp( ~, ~ ) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Export'); + observe_ERPDAT.Process_messg =1; + + pathName = estudioworkingmemory('ERP_save_folder'); + if isempty(pathName) + pathName = cd; + end + Selected_erpset= ERPsetops.butttons_datasets.Value; + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + if isempty(Selected_erpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + checked_ERPset_Index_bin_chan = [0 0 0 0 0 0 0]; + try + S_geterpbinchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan = S_geterpbinchan.checked_ERPset_Index; + catch + checked_ERPset_Index_bin_chan = f_checkerpsets(observe_ERPDAT.ALLERP,Selected_erpset); + end + BinArray = []; + ChanArray = []; + try + S_geterpbinchan = estudioworkingmemory('geterpbinchan'); + BinArray = S_geterpbinchan.bins{1}; + ChanArray = S_geterpbinchan.elecs_shown{1}; + catch + BinArray = []; + ChanArray = []; + end + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.7020 0.77 0.85]; + end + + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',ColorB_def); + [ind,tf] = listdlg('ListString',{'ERPSS Text','Universal Text'},'SelectionMode','single','PromptString','Please select a type to export to...','Name','Export ERP to','OKString','Ok'); + set(0,'DefaultUicontrolBackgroundColor',[1 1 1]); + if isempty(ind) + beep; + disp(['User selected cancel']); + return; + end + + ALLERPCOM = evalin('base','ALLERPCOM'); + for Numoferpset = 1:length(Selected_erpset) + + if Selected_erpset(Numoferpset) > length(observe_ERPDAT.ALLERP) + beep; + msgboxText = ['ERPsets>Export: Index of selected ERP is lager than the length of ALLERP']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + ERP_export_erp = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)); + if checked_ERPset_Index_bin_chan(1) ==1 || checked_ERPset_Index_bin_chan(2) ==2 + BinArray = [1:ERP_export_erp.nbin]; + ChanArray = [1:ERP_export_erp.nchan]; + end + + if ind==1 + try + ERP_export_erp.filename =fullfile(pathName,ERP_export_erp.filename); + Answer_erpss = f_erp2ascGUI(ERP_export_erp,BinArray,ChanArray); + if isempty(Answer_erpss) + return; + end + ERP = Answer_erpss{1}; + FileName = Answer_erpss{2}; + + [observe_ERPDAT.ERP, ERPCOM] = pop_erp2asc(ERP,FileName,'History', 'gui'); + [observe_ERPDAT.ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + observe_ERPDAT.Process_messg =2; + catch + beep; + msgboxText = ['ERPsets>Export: cannot be saved as ERPs']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return + end + elseif ind ==2 + + try + ERP_export_erp.filename =fullfile(pathName,ERP_export_erp.filename); + ERP = ERP_export_erp; + def = estudioworkingmemory('f_export2textGUI'); + if isempty(def) + def = {1,1000, 1, 1, 4, ''}; + end + + % + % Call GUI + % + def_x = def; + def_x{6} = ERP.filename; + answer_export = f_export2textGUI(ERP,def_x,BinArray,ChanArray); + if isempty(answer_export) + beep; + disp('User selected cancel'); + return; + end + estudioworkingmemory('f_export2textGUI',answer_export); + istime = answer_export{1}; + tunit = answer_export{2}; + islabeled = answer_export{3}; + transpa = answer_export{4}; + prec = answer_export{5}; + + filename = answer_export{6}; + ERP = answer_export{7}; + binArray = [1:ERP.nbin]; + if istime + time = 'on'; + else + time = 'off'; + end + if islabeled + elabel = 'on'; + else + elabel = 'off'; + end + if transpa + tra = 'on'; + else + tra = 'off'; + end + try + [ERP, ERPCOM] = pop_export2text(ERP, filename, binArray, 'time', time, 'timeunit', tunit, 'electrodes', elabel,... + 'transpose', tra, 'precision', prec, 'History', 'gui'); + [observe_ERPDAT.ERP, ALLERPCOM] = erphistory(ERP_export_erp, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + observe_ERPDAT.Process_messg =2; + catch + beep; + msgboxText = ['ERPsets>Export: Failed to save selected ERPsets']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + catch + observe_ERPDAT.Process_messg =3; + return; + end + end + end + %%%Export data end + end + + + + +%%---------------------Load ERP-------------------------------------------- + function load(~,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Load'); + observe_ERPDAT.Process_messg =1; + + ALLERPCOM = evalin('base','ALLERPCOM'); + [~,bc] = size(observe_ERPDAT.ALLERP); + try + [filename, filepath] = uigetfile({'*.erp','ERP (*.erp)';... + '*.mat','ERP (*.mat)'}, ... + 'Load ERP', ... + 'MultiSelect', 'on'); + if isequal(filename,0) + disp('User selected Cancel'); + return; + end + + if numel(findobj('tag', 'erpsets')) > 0 + [ERP, ALLERP, ERPCOM] = pop_loaderp('filename', filename, 'filepath', filepath, 'Warning', 'on', 'UpdateMainGui', 'on', 'multiload', 'off',... + 'History', 'gui'); + else + [ERP, ALLERP, ERPCOM] = pop_loaderp('filename', filename, 'filepath', filepath, 'Warning', 'on', 'UpdateMainGui', 'off', 'multiload', 'off',... + 'History', 'gui'); %If eeglab is not open, don't update + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + catch + return; + end + + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + observe_ERPDAT.ALLERP = ALLERP; + observe_ERPDAT.ERP = ERP; + ERPset_default_label = []; + if ~isequal([1,bc], size(observe_ERPDAT.ALLERP)) + count = 0; + for Numoferpset = 1:size(observe_ERPDAT.ALLERP,2) + if strcmp(observe_ERPDAT.ALLERP(Numoferpset).erpname,'No ERPset loaded') + count = count +1; + ERPset_default_label(count) = Numoferpset; + end + end + if ~isempty(ERPset_default_label) + observe_ERPDAT.ALLERP(ERPset_default_label)=[]; + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end); + observe_ERPDAT.CURRENTERP = size(observe_ERPDAT.ALLERP,2); + end + end + datasets = {}; + getDatasets() + datasets = sortdata(datasets); + % drawui_erpset(); + + dsnames = {}; + if size(datasets,1)==1 + if strcmp(datasets{1},'No ERPset loaded') + dsnames = {''}; + Edit_label = 'off'; + else + + dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1}); + + Edit_label = 'on'; + end + else + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1}); + end + Edit_label = 'on'; + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + + ERPsetops.butttons_datasets.Value = observe_ERPDAT.CURRENTERP; + ERPsetops.butttons_datasets.String = dsnames; + + if strcmp(datasets{1},'No ERPset loaded') + Edit_label = 'off'; + else + Edit_label = 'on'; + end + + ERPsetops.dupeselected.Enable=Edit_label; + ERPsetops.renameselected.Enable=Edit_label; + ERPsetops.suffix.Enable= Edit_label; + ERPsetops.clearselected.Enable=Edit_label; + ERPsetops.savebutton.Enable= Edit_label; + ERPsetops.saveasbutton.Enable=Edit_label; + ERPsetops.dotstoggle.Enable=Edit_label; + ERPsetops.butttons_datasets.Enable = Edit_label; + ERPsetops.export.Enable = Edit_label; + + + SelectedERP = observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',SelectedERP); + + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + + ERPsetops.butttons_datasets.Min=1; + if size(datasets,1)<=2 + ERPsetops.butttons_datasets.Max=size(datasets,1)+1; + else + ERPsetops.butttons_datasets.Max=size(datasets,1); + end + + observe_ERPDAT.Process_messg =2; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + +%%----------------------Clear the selected ERPsets------------------------- + function cleardata(source,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Clear'); + observe_ERPDAT.Process_messg =1; + + % global ERPCOM; + SelectedERP = ERPsetops.butttons_datasets.Value; + ERPset_remained = setdiff(1:size(datasets,1),SelectedERP); + + if isempty(ERPset_remained) + if numel(findobj('tag', 'erpsets')) > 0 + [observe_ERPDAT.ERP, observe_ERPDAT.ALLERP, ERPCOM] = pop_loaderp('filename', 'dummy.erp', 'Warning', 'on','multiload', 'off',... + 'History', 'implicit'); + else + [observe_ERPDAT.ERP, observe_ERPDAT.ALLERP, ERPCOM] = pop_loaderp('filename', 'dummy.erp', 'Warning', 'on','multiload', 'off',... + 'History', 'implicit'); %If eeglab is not open, don't update + end + %Reset the datasets%%%%% + + datasets = {}; + datasets{1} = observe_ERPDAT.ALLERP(end).erpname; + datasets{2} = 1; + datasets{3} = 0; + datasets{4} = observe_ERPDAT.ALLERP(end).filename; + datasets{5} = observe_ERPDAT.ALLERP(end).filepath; + + observe_ERPDAT.ALLERP = observe_ERPDAT.ALLERP(end); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end); + observe_ERPDAT.CURRENTERP = 1; + assignin('base','ERP',observe_ERPDAT.ERP) + else + observe_ERPDAT.ALLERP = observe_ERPDAT.ALLERP(ERPset_remained); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(end); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + datasets = {}; + getDatasets(); + end + + datasets = sortdata(datasets); + + dsnames = {}; + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1}); + end + + if strcmp(datasets{1},'No ERPset loaded') && length(observe_ERPDAT.ALLERP)==1 + dsnames = {''}; + Edit_label = 'off'; + else + Edit_label = 'on'; + end + + ERPsetops.butttons_datasets.String = dsnames; + ERPsetops.butttons_datasets.Value = observe_ERPDAT.CURRENTERP; + ERPsetops.dupeselected.Enable=Edit_label; + ERPsetops.renameselected.Enable=Edit_label; + ERPsetops.suffix.Enable= Edit_label; + ERPsetops.clearselected.Enable=Edit_label; + ERPsetops.savebutton.Enable= Edit_label; + ERPsetops.saveasbutton.Enable=Edit_label; + ERPsetops.dotstoggle.Enable=Edit_label; + ERPsetops.butttons_datasets.Min =1; + ERPsetops.butttons_datasets.Max =length(dsnames)+1; + ERPsetops.butttons_datasets.Enable = Edit_label; + ERPsetops.export.Enable = Edit_label; + + SelectedERP = observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',SelectedERP); + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + observe_ERPDAT.Process_messg =2; + + observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%-------------------------- Save selected ERPsets------------------------------------------- + function savechecked(source,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Save'); + observe_ERPDAT.Process_messg =1; + + pathName = estudioworkingmemory('ERP_save_folder'); + if isempty(pathName) + pathName = cd; + end + + Selected_erpset= estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + if isempty(Selected_erpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + try + ALLERPCOM = evalin('base','ALLERPCOM'); + catch + ALLERPCOM = []; + assignin('base','ALLERPCOM',ALLERPCOM); + end + + try + for Numoferpset = 1:length(Selected_erpset) + + if Selected_erpset(Numoferpset) > length(observe_ERPDAT.ALLERP) + beep; + disp(['Index of selected ERP is lager than the length of ALLERP!!!']); + return; + end + ERP = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)); + FileName = ERP.filename; + + if isempty(FileName) + FileName =ERP.erpname; + end + [pathx, filename, ext] = fileparts(FileName); + filename = [filename '.erp']; + [observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', filename, 'filepath',pathName); + [~, ALLERPCOM] = erphistory(observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), ALLERPCOM, ERPCOM); + + end + + observe_ERPDAT.Process_messg =2; + catch + beep; + observe_ERPDAT.Process_messg =3; + disp(['ERPsets>Save: Cannot save the selected ERPsets.']); + return; + + end + end + + +%------------------------- Save as----------------------------------------- + function savecheckedas(~,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets>Save As'); + observe_ERPDAT.Process_messg =1; + + pathName = estudioworkingmemory('ERP_save_folder'); + if isempty(pathName) + pathName = cd; + end + + Selected_erpset= estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + if isempty(Selected_erpset) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + try + ALLERPCOM = evalin('base','ALLERPCOM'); + catch + ALLERPCOM = []; + assignin('base','ALLERPCOM',ALLERPCOM); + end + + for Numoferpset = 1:length(Selected_erpset) + if Selected_erpset(Numoferpset) > length(observe_ERPDAT.ALLERP) + beep; + disp('Index of selected ERP is lager than the length of ALLERP!!!'); + return; + end + + ERP = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)); + + [pathstr, namedef, ext] = fileparts(char(ERP.filename)); + [erpfilename, erppathname, indxs] = uiputfile({'*.erp','ERP (*.erp)';... + '*.mat','ERP (*.erp)'}, ... + ['Save "',ERP.erpname,'" as'],... + fullfile(pathName,namedef)); + + if isequal(erpfilename,0) + disp('User selected Cancel') + return + end + + [pathx, filename, ext] = fileparts(erpfilename); + [pathstr, erpfilename, ext] = fileparts(erpfilename) ; + + if indxs==1 + ext = '.erp'; + elseif indxs==2 + ext = '.mat'; + else + ext = '.erp'; + end + erpFilename = char(strcat(erpfilename,ext)); + [observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', erpFilename,... + 'filepath',erppathname); + [~, ALLERPCOM] = erphistory(observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)), ALLERPCOM, ERPCOM); + + end + observe_ERPDAT.Process_messg =2; + + end + + +%---------------- Enable/Disable dot structure----------------------------- + function toggledots(~,~) + pathName = erpworkingmemory('ERP_save_folder'); + if isempty(pathName) + pathName =cd; + end + title = 'Select one forlder for saving files in following procedures'; + sel_path = uigetdir(pathName,title); + + if isequal(sel_path,0) + sel_path = cd; + end + userpath(sel_path); + cd(sel_path); + erpworkingmemory('ERP_save_folder',sel_path); + end + + +%-----------------select the ERPset of interest-------------------------- + function selectdata(source,~) + erpworkingmemory('f_ERP_proces_messg','ERPsets-select ERPset(s)'); + observe_ERPDAT.Process_messg =1; + + Selected_ERPsetlabel = source.Value; + estudioworkingmemory('selectederpstudio',Selected_ERPsetlabel); + + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERPsetlabel); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + + Current_ERP_selected=Selected_ERPsetlabel(1); + observe_ERPDAT.CURRENTERP = Current_ERP_selected; + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_ERP_selected); + + checked_ERPset_Index_bin_chan = S_erpplot.geterpbinchan.checked_ERPset_Index; + + msgboxText = {}; + if checked_ERPset_Index_bin_chan(1) ==1 + msgboxText = ['Number of bins across ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(2)==2 + msgboxText = ['Number of channels across ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(3) ==3 + msgboxText = ['Type of data across ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(4)==4 + msgboxText = ['Number of samples across ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(5)==5 + msgboxText = ['Start time of epoch across ERPsets is different!']; + end + if ischar(msgboxText) + if checked_ERPset_Index_bin_chan(1) ==1 && checked_ERPset_Index_bin_chan(2) ==0 + question = [ '%s\n See details at command window.\n\n',... + ' (a). "Bins" will be deactive on "Bins and Channel Selection".\n\n',... + ' (b). "Plot Scalp Maps" panel will be deactive.\n\n',... + ' (c). "Selected bin and chan" will be deactive on "Baseline correction & Linear detrend".\n\n',... + ' (d). "ERP Channel Operations" panel will be deactive.\n\n',... + ' (e). "ERP Bin Operations" panel will be deactive.\n\n',... + ' (f). "Covert Voltage to CSD" panel will be deactive.\n\n',... + ' (g). "Save values" will be deactive on "ERP Measurement Tool".\n\n',... + ' (h). "Average across ERPsets" will be deactive.\n\n']; + elseif checked_ERPset_Index_bin_chan(1) ==0 && checked_ERPset_Index_bin_chan(2) ==2 + + question = [ '%s\n See details at command window.\n\n',... + ' (a). "Channels" will be deactive on "Bins and Channel Selection".\n\n',... + ' (b). "Plot Scalp Maps" panel will be deactive.\n\n',... + ' (c). "Selected bin and chan" will be deactive on "Baseline correction & Linear detrend".\n\n',... + ' (d). "ERP Channel Operations" panel will be deactive.\n\n',... + ' (e). "ERP Bin Operations" panel will be deactive.\n\n',... + ' (f). "Covert Voltage to CSD" panel will be deactive.\n\n',... + ' (g). "Save values" will be deactive on "ERP Measurement Tool".\n\n',... + ' (h). "Average across ERPsets" will be deactive.\n\n']; + elseif checked_ERPset_Index_bin_chan(1) ==1 && checked_ERPset_Index_bin_chan(2) ==2 + msgboxText = ['Both the number of channels and the number of bins vary across ERPsets!']; + question = [ '%s\n See details at command window.\n\n',... + ' (a). "Channels" and "Bins" will be deactive on "Bins and Channel Selection".\n\n',... + ' (b). "Plot Scalp Maps" panel will be deactive.\n\n',... + ' (c). "Selected bin and chan" will be deactive on "Baseline correction & Linear detrend".\n\n',... + ' (d). "ERP Channel Operations" panel will be deactive.\n\n',... + ' (e). "ERP Bin Operations" panel will be deactive.\n\n',... + ' (f). "Covert Voltage to CSD" panel will be deactive.\n\n',... + ' (g). "Save values" will be deactive on "ERP Measurement Tool".\n\n',... + ' (h). "Average across ERPsets" will be deactive.\n\n']; + else + msgboxText = []; + question = [ ]; + + end + if ~isempty(question) + BackERPLABcolor = [1 0.9 0.3]; + title = 'EStudio: ERPsets'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question, msgboxText), title,'OK','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor); + end + end + + observe_ERPDAT.Process_messg =2; + observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + if numel(source.Value)==1 + observe_ERPDAT.ERP_chan = [1:observe_ERPDAT.ERP.nchan]; + observe_ERPDAT.ERP_bin = [1:observe_ERPDAT.ERP.nbin]; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + + +% called datasets = sortdata(datasets), sorts datasets in order based on +% parents + function varargout = sortdata(data) + cinds = []; + ndata = {}; % Sorted data + it = 1; % Iterator for row + for i = data' % Iterate thru all datasets + if cell2mat(i(3)) == 0 % Find base datasets (child of 0 means it's not reliant on another dataset) + [~, ic] = size(cinds); + cinds(1, ic+1) = cell2mat(i(2)); % Append dataset number to list of current indexes + ndata(it,:) = i'; % Put it in + it = it + 1; + end + end + + cond = true; + while cond + ninds = []; % Reset new indexes + for i = data' % Iterate thru all data + for j = cinds % Iterate thru all parents + if cell2mat(i(3)) == j % Check to see if every datapoint is a child of the current layer + [~, nic] = size(ninds); + ninds(1, nic+1) = cell2mat(i(2)); % Append dataset number to the next round of parents + [ndr, ~] = size(ndata); + for v = 1:ndr + if cell2mat(ndata(v, 2)) == j + ndata(v+2:end+1,:) = ndata(v+1:end,:); + ndata(v+1,:) = i'; + end + end + end + end + end + [~, nic] = size(ninds); + if nic == 0 % If we've gone thru all of them, there should be no new indexes + cond = false; + end + clear cinds + cinds = ninds; % Start again with ninds + end + varargout{1} = ndata; + end + +% Gets [ind, erp] for input ds where ds is a dataset structure, ind is the +% index of the corresponding ERP, and ERP is the corresponding ERP +% structure. + function varargout = ds2erp(ds) + [~,cvtc] = size(observe_ERPDAT.ALLERP); + for z = 1:cvtc + fp1 = observe_ERPDAT.ALLERP(1,z).filepath; + fp2 = cell2mat(ds(5)); + fp1(regexp(fp1,'[/]')) = []; + fp2(regexp(fp2,'[/]')) = []; + if strcmp(observe_ERPDAT.ALLERP(1,z).erpname,cell2mat(ds(1)))&&strcmp(fp1,fp2) + varargout{1} = z; + varargout{2} = observe_ERPDAT.ALLERP(1,z); + end + + end + + end + + + +%%%--------------Up this panel-------------------------------------- + function Count_currentERPChanged(~,~) + + Selected_ERP= estudioworkingmemory('selectederpstudio'); + if isempty(Selected_ERP) + Selected_ERP = observe_ERPDAT.CURRENTERP; + if isempty(Selected_ERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + [chk, msgboxText] = f_ERP_chckerpindex(observe_ERPDAT.ALLERP, Selected_ERP); + if chk==1 + Selected_ERP = observe_ERPDAT.CURRENTERP; + if isempty(Selected_ERP) + msgboxText = 'No ERPset was imported!!!'; + title = 'EStudio: f_ERP_binoperation_GUI error.'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_ERP); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + return; + end + ERPfilter_label = erpworkingmemory('ERPfilter'); + def_baseline = erpworkingmemory('f_ERP_BLS_Detrend'); + ERP_bin_opertion = erpworkingmemory('f_ERP_bin_opt'); + ERP_simulation = erpworkingmemory('ERP_simulation'); + if isempty(ERPfilter_label) + ERPfilter_label =1; + end + if isempty(def_baseline) + def_baseline{3} =1; + end + if isempty(ERP_bin_opertion) + ERP_bin_opertion =1; + end + if isempty(ERP_simulation) + ERP_simulation =1; + end + if ERPfilter_label ==1 || def_baseline{3}==1 || ERP_bin_opertion==1 || ERP_simulation==1 + erpworkingmemory('ERPfilter',0); + def_baseline{3} = 0; + erpworkingmemory('f_ERP_BLS_Detrend',def_baseline); + erpworkingmemory('f_ERP_bin_opt',0); + erpworkingmemory('ERP_simulation',0); + datasets = {}; + getDatasets() + datasets = sortdata(datasets); + dsnames = {}; + if size(datasets,1)==1 + if strcmp(datasets{1},'No ERPset loaded') + dsnames = {''}; + Edit_label = 'off'; + else + dsnames{1} = strcat(num2str(cell2mat(datasets(1,2))),'.',32,datasets{1,1}); + Edit_label = 'on'; + end + else + for Numofsub = 1:size(datasets,1) + dsnames{Numofsub} = strcat(num2str(cell2mat(datasets(Numofsub,2))),'.',32,datasets{Numofsub,1}); + end + Edit_label = 'on'; + end + ERPsetops.butttons_datasets.String = dsnames; + ERPsetops.butttons_datasets.Value = Selected_ERP; + if strcmp(datasets{1},'No ERPset loaded') + Edit_label = 'off'; + else + Edit_label = 'on'; + end + ERPsetops.dupeselected.Enable=Edit_label; + ERPsetops.renameselected.Enable=Edit_label; + ERPsetops.suffix.Enable= Edit_label; + ERPsetops.clearselected.Enable=Edit_label; + ERPsetops.savebutton.Enable= Edit_label; + ERPsetops.saveasbutton.Enable=Edit_label; + ERPsetops.dotstoggle.Enable=Edit_label; + ERPsetops.butttons_datasets.Enable = Edit_label; + ERPsetops.export.Enable = Edit_label; + estudioworkingmemory('selectederpstudio',Selected_ERP); + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_ERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + ERPsetops.butttons_datasets.Min=1; + ERPsetops.butttons_datasets.Max=size(datasets,1)+1; + end + ERPsetops.butttons_datasets.Value = Selected_ERP; + observe_ERPDAT.Count_ERP = observe_ERPDAT.Count_ERP+1; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + +%----------------------Get the information of the updated ERPsets---------- + function getDatasets() + if isempty(datasets) + datasets = {}; + end + [s,~] = size(datasets); + del = []; + for i = 1:s + cond = false; + for j = observe_ERPDAT.ALLERP + if strcmp(j.filename, datasets{i,4}) && strcmp(j.filepath, datasets{i,5}) && strcmp(i.erpname, datasets{j,1}) + cond = true; + end + end + if ~cond + del(end+1) = i; + end + end + for i = del + datasets(del,:) = []; + end + for i = observe_ERPDAT.ALLERP + cond = false; + [s,~] = size(datasets); + for j = 1:s + if strcmp(i.filename, datasets{j,4}) && strcmp(i.filepath, datasets{j,5}) && strcmp(i.erpname, datasets{j,1}); + cond = true; + end + end + if ~cond + datasets{end+1,1} = i.erpname; + [r,~] = size(datasets); + datasets{end,2} = r; + datasets{end,3} = 0; + datasets{end,4} = i.filename; + datasets{end,5} = i.filepath; + end + end + end + +% function onErpChanged(~,~) +% assignin('base','ERP',observe_ERPDAT.ERP); +% end + + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_filtering_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_filtering_GUI.m new file mode 100755 index 00000000..d54847ab --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_filtering_GUI.m @@ -0,0 +1,1423 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_filtering_GUI(varargin) + +gui_erp_filtering = struct(); +% global gui_erp_filtering; +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange); +% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + +%%---------------------------gui------------------------------------------- +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end +if nargin == 0 + fig = figure(); % Parent figure + ERP_filtering_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Filtering', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Filtering', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Filtering', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + + + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +erp_filtering_gui(FonsizeDefault); + +varargout{1} = ERP_filtering_box; +%%********************Draw the GUI for ERP measurement tool***************** + function erp_filtering_gui(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + try + nchan = observe_ERPDAT.ERP.nchan; + fs = observe_ERPDAT.ERP.srate; + catch + nchan =1; + end + defx = {0 30 2 1:nchan 1 'butter' 0 []}; + def = erpworkingmemory('pop_filterp'); + if isempty(def) + def = defx; + end + if fs <=0 + fs =256; + end + locutoff = def{1}; % for high pass filter + hicutoff = def{2}; % for low pass filter + filterorder = def{3}; + chanArray = def{4}; + filterallch = def{5}; + fdesign = def{6}; + remove_dc = def{7}; + + typef = 0; + if strcmpi(fdesign,'butter') % 0 means Butterworth + if filterorder> 8 + filterorder =2; + end + else + filterorder = 2; + end + + if locutoff >= fs/2 || locutoff<=0 + locutoff = floor(fs/2)-1; + end + + + if hicutoff>=fs/2 || hicutoff<=0 + hicutoff = floor(fs/2)-1; + end + + if isempty(locutoff) + locutoff = 0; + end + + if isempty(hicutoff) + hicutoff = 0; + end + + locutoff = 0; + hicutoff = 20; + highpass_toggle_value = 1; + lowpass_toggle_value =1; + hp_halfamp_enable = 'on'; + lp_halfamp_Enable = 'on'; + hp_halfpow_string = '---'; + lp_halfpow_string = '---'; + Apply_ERP_filter_enable = 'on'; + Advance_ERP_filter_enable = 'on'; + hp_tog_enable = 'on'; + lp_tog_enable = 'on'; + + if ~strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + + %%High-pass filtering + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,locutoff,fs); + if locutoff > 0 && hicutoff ==0 + highpass_toggle_value = 1; + hp_halfamp_enable = 'on'; + lowpass_toggle_value = 0; + lp_halfamp_Enable = 'off'; + hp_halfpow_string =num2str(roundn(frec3dB(1),-2)); + lp_halfpow_string ='---'; + end + %%Low pass filtering + if hicutoff > 0 && locutoff ==0 + highpass_toggle_value = 0; + hp_halfamp_enable = 'off'; + lowpass_toggle_value = 1; + lp_halfamp_Enable = 'on'; + lp_halfpow_string =num2str(roundn(frec3dB,-2)); + hp_halfpow_string ='---'; + end + %%Band pass filtering or notch filtering + if locutoff >0 && hicutoff>0 + highpass_toggle_value = 1; + hp_halfamp_enable = 'on'; + hp_halfpow_string =num2str(roundn(frec3dB(2),-2)); + lowpass_toggle_value = 1; + lp_halfamp_Enable = 'on'; + lp_halfpow_string =num2str(roundn(frec3dB(1),-2)); + end + else + hp_halfamp_enable = 'off'; + lp_halfamp_Enable = 'off'; + Apply_ERP_filter_enable = 'off'; + Advance_ERP_filter_enable = 'off'; + + lp_tog_enable = 'off'; + hp_tog_enable = 'off'; + hp_halfpow_string ='--'; + lp_halfpow_string ='---'; + end + gui_erp_filtering.filtering = uiextras.VBox('Parent',ERP_filtering_box,'BackgroundColor',ColorB_def); + + %%-----------------------------Setting for bin and chan-------------------- + gui_erp_filtering.bin_chan_title = uiextras.HBox('Parent',gui_erp_filtering.filtering,'BackgroundColor',ColorB_def); + uicontrol('Style','text','Parent',gui_erp_filtering.bin_chan_title,'String','Bin and Chan Selection:','FontWeight','bold',... + 'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_filtering.filter_bin_chan_option = uiextras.HBox('Parent', gui_erp_filtering.filtering,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_filtering.all_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_filtering.filter_bin_chan_option,... + 'String','All (Recommended)','callback',@All_bin_chan,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_filtering.Selected_bin_chan = uicontrol('Style', 'radiobutton','Parent', gui_erp_filtering.filter_bin_chan_option,... + 'String','Selected bin & chan','callback',@Selected_bin_chan,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_filtering.filter_bin_chan_option, 'Sizes',[130 170]); + + + %%--------------------------Setting for IIR filter------------------------------ + gui_erp_filtering.IIR_title = uiextras.HBox('Parent',gui_erp_filtering.filtering,'BackgroundColor',ColorB_def); + uicontrol('Style','text','Parent',gui_erp_filtering.IIR_title,'String','Setting for IIR Butterworth:',... + 'FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + + gui_erp_filtering.filt_grid = uiextras.Grid('Parent',gui_erp_filtering.filtering,'BackgroundColor',ColorB_def); + % first column + uiextras.Empty('Parent',gui_erp_filtering.filt_grid); % 1A + gui_erp_filtering.hp_tog = uicontrol('Style','checkbox','Parent',gui_erp_filtering.filt_grid,'String','High Pass',... + 'callback',@highpass_toggle,'Value',0,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1B + gui_erp_filtering.lp_tog = uicontrol('Style','checkbox','Parent',gui_erp_filtering.filt_grid,'String','Low Pass',... + 'callback',@lowpass_toggle,'Value',1,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1C + + + % second column + uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Half Amp.','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2A + gui_erp_filtering.hp_halfamp = uicontrol('Style','edit','Parent',gui_erp_filtering.filt_grid,... + 'callback',@hp_halfamp,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 2B + if strcmp(hp_halfamp_enable,'off'); + if typef<2 + gui_erp_filtering.hp_halfamp.String = '0'; + else + gui_erp_filtering.hp_halfamp.String = '60'; + end + + else + gui_erp_filtering.hp_halfamp.String = num2str(locutoff); + end + gui_erp_filtering.lp_halfamp = uicontrol('Style','edit','Parent',gui_erp_filtering.filt_grid,... + 'callback',@lp_halfamp,'Enable',lp_halfamp_Enable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 2C + if strcmp(lp_halfamp_Enable,'off') + gui_erp_filtering.lp_halfamp.String = '20'; + else + gui_erp_filtering.lp_halfamp.String = num2str(hicutoff); + end + % third column + uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Half Power','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 3A + gui_erp_filtering.hp_halfpow = uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,... + 'String',hp_halfpow_string,'Enable','off','BackgroundColor','y','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 3B + + gui_erp_filtering.lp_halfpow = uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,... + 'String',lp_halfpow_string,'Enable','off','BackgroundColor','y','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 3C + + % fourth column + uiextras.Empty('Parent',gui_erp_filtering.filt_grid); % 4A + uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 4B + uicontrol('Style','text','Parent',gui_erp_filtering.filt_grid,'String','Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 4C + set(gui_erp_filtering.filt_grid, 'ColumnSizes',[90 70 70 40],'RowSizes',[20 -1 -1]); + + + gui_erp_filtering.rolloff_row = uiextras.HBox('Parent', gui_erp_filtering.filtering,'BackgroundColor',ColorB_def); + uicontrol('Style','text','Parent',gui_erp_filtering.rolloff_row,'String','Roll-Off','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1D + Roll_off = {'12','24','36','48'}; + gui_erp_filtering.roll_off = uicontrol('Style','popupmenu','Parent',gui_erp_filtering.rolloff_row,'String',Roll_off,... + 'callback',@ERP_filtering_rolloff,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); % 2D + if filterorder ==2 + gui_erp_filtering.roll_off.Value = 1; + elseif filterorder ==4 + gui_erp_filtering.roll_off.Value = 2; + + elseif filterorder ==6 + gui_erp_filtering.roll_off.Value = 3; + + elseif filterorder ==8 + gui_erp_filtering.roll_off.Value = 4; + end + uicontrol('Style','text','Parent',gui_erp_filtering.rolloff_row,'String','dB/Octave','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 3D + + + gui_erp_filtering.REMOVE_DC = uiextras.HBox('Parent', gui_erp_filtering.filtering,'BackgroundColor',ColorB_def); + gui_erp_filtering.DC_remove = uicontrol('Style','checkbox','Parent', gui_erp_filtering.REMOVE_DC,... + 'String','Remove DC Offset','Value',0,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def);%,'callback',@remove_dc + % uiextras.Empty('Parent',gui_erp_filtering.REMOVE_DC); + + gui_erp_filtering.filt_buttons = uiextras.HBox('Parent', gui_erp_filtering.filtering,'BackgroundColor',ColorB_def); + % uiextras.Empty('Parent', gui_erp_filtering.filt_buttons); + uicontrol('Style','pushbutton','Parent',gui_erp_filtering.filt_buttons,'String','?',... + 'callback',@ERP_filter_help,'Enable','on','FontSize',16,'BackgroundColor',[1 1 1]); + gui_erp_filtering.advanced = uicontrol('Style','pushbutton','Parent',gui_erp_filtering.filt_buttons,'String','Advanced',... + 'callback',@advanced_ERP_filter,'Enable',Advance_ERP_filter_enable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + + gui_erp_filtering.apply = uicontrol('Style','pushbutton','Parent',gui_erp_filtering.filt_buttons,'String','Run',... + 'callback',@ERP_filter_apply,'Enable',Apply_ERP_filter_enable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + set( gui_erp_filtering.filtering,'Sizes',[20 20 20 80 20 20 30]); + + end + + + +%%**************************************************************************************************************************************** +%%******************* Subfunctions *************************************************************************************************** +%%**************************************************************************************************************************************** + +%%---------------------help----------------------------- + + function ERP_filter_help(~,~) + web('https://github.com/lucklab/erplab/wiki/Filtering','-browser'); + + end +%%----------------------all bin and all chan------------------------------- + function All_bin_chan(~,~) + gui_erp_filtering.all_bin_chan.Value = 1; + gui_erp_filtering.Selected_bin_chan.Value = 0; + end + +%%----------------------selected bin and all chan------------------------------- + function Selected_bin_chan(~,~) + gui_erp_filtering.all_bin_chan.Value = 0; + gui_erp_filtering.Selected_bin_chan.Value = 1; + end + + + +%%--------------------------------High-pass filtering toggle------------------ + function highpass_toggle(source,~) + try + fs = observe_ERPDAT.ERP.srate; + catch + return; + end + locutoff = 0.1; + try + filterorder = 2*gui_erp_filtering.roll_off.Value; + catch + filterorder =2; + gui_erp_filtering.roll_off.Value=1; + end + typef = 0; + + if source.Value == 0 + gui_erp_filtering.hp_halfamp.Enable ='off'; + gui_erp_filtering.hp_halfpow.Enable ='off'; + gui_erp_filtering.hp_halfamp.String = '0'; + gui_erp_filtering.hp_halfpow.String = '---'; + if gui_erp_filtering.lp_tog.Value ==0 + gui_erp_filtering.roll_off.Enable = 'off'; + end + else + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder,0,locutoff,fs); + gui_erp_filtering.hp_tog.Value =1; + gui_erp_filtering.hp_halfamp.Enable ='on'; + gui_erp_filtering.hp_halfamp.String = num2str(locutoff); + gui_erp_filtering.hp_halfpow.String = num2str(frec3dB(1)); + gui_erp_filtering.hp_halfpow.Enable ='off'; + gui_erp_filtering.hp_halfpow.String = num2str(frec3dB); + gui_erp_filtering.roll_off.Enable = 'on'; + end + + end + + +%%--------------------------------Low-pass filtering toggle------------------ + function lowpass_toggle(source,~) + + try + fs = observe_ERPDAT.ERP.srate; + catch + return; + end + + typef = 0; + try + filterorder = 2*gui_erp_filtering.roll_off.Value; + catch + filterorder =2; + gui_erp_filtering.roll_off.Value=1; + end + + hicutoff = floor((fs/2-1)*5/10); + if source.Value == 0 + gui_erp_filtering.lp_halfamp.Enable ='off'; + gui_erp_filtering.lp_halfpow.Enable ='off'; + gui_erp_filtering.lp_halfamp.String = '0'; + gui_erp_filtering.lp_halfpow.String = '---'; + if gui_erp_filtering.hp_tog.Value ==0 + gui_erp_filtering.roll_off.Enable = 'off'; + end + else + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,0, fs); + gui_erp_filtering.lp_tog.Value =1; + gui_erp_filtering.lp_halfamp.Enable ='on'; + gui_erp_filtering.lp_halfamp.String = num2str(hicutoff); + gui_erp_filtering.lp_halfpow.String = num2str(frec3dB); + gui_erp_filtering.lp_halfpow.Enable ='off'; + gui_erp_filtering.roll_off.Enable = 'on'; + end + + end + + + +%%---------------------Half amplitude for high pass filtering-------------- + function hp_halfamp(Source,~) + try + fs = observe_ERPDAT.ERP.srate; + catch + return; + end + + typef = 0; + try + filterorder = 2*gui_erp_filtering.roll_off.Value; + catch + filterorder =2; + gui_erp_filtering.roll_off.Value=1; + end + + valueh = str2num(Source.String); + if length(valueh)~=1 + beep; + msgboxText = ['Filtring - Invalid input for high-pass filter cutoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if valueh>=fs/2 + beep; + msgboxText = ['Filtring - The high-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if valueh<0.001 + beep; + msgboxText = ['Filtring - We strongly recommend the high-pass filter cutoff is larger than 0.001Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + valuel = 0; + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, valuel, valueh, fs); + gui_erp_filtering.hp_halfamp.Enable ='on'; + gui_erp_filtering.hp_halfamp.String = num2str(valueh); + gui_erp_filtering.hp_halfpow.String = num2str(frec3dB); + gui_erp_filtering.hp_halfpow.Enable ='off'; + end + + + +%%---------------------Half amplitude for low pass filtering--------------- + function lp_halfamp(Source,~) + + try + fs = observe_ERPDAT.ERP.srate; + catch + return; + end + try + filterorder = 2*gui_erp_filtering.roll_off.Value; + catch + filterorder =2; + gui_erp_filtering.roll_off.Value=1; + end + valuel = str2num(Source.String); + if length(valuel)~=1 || isempty(valuel) + beep; + msgboxText = ['Filtring - Invalid input for low-pass filter cutoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if valuel>=fs/2 + beep; + msgboxText = ['Filtring - The low-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if valuel<0.001 + beep; + msgboxText = ['Filtring - We strongly recommend the low-pass filter cutoff is larger than 0.001Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + %if the valueh is between 0.1 and fs/2 Hz + typef = 0; + valueh = 0; + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, valuel, valueh, fs); + gui_erp_filtering.lp_halfamp.Enable ='on'; + gui_erp_filtering.lp_halfamp.String = num2str(valuel); + gui_erp_filtering.lp_halfpow.String = num2str(frec3dB(1)); + gui_erp_filtering.lp_halfpow.Enable ='off'; + + end + + +%%----------------------------Setting for roll-off------------------------- + function ERP_filtering_rolloff(Source,~) + Source_value = Source.Value; + + try + nchan = observe_ERPDAT.ERP.nchan; + fs = observe_ERPDAT.ERP.srate; + catch + return; + end + filterorder = 2*Source_value; + typef = 0; + valuel = str2num(gui_erp_filtering.lp_halfamp.String);%% for low-pass filter + valueh = str2num(gui_erp_filtering.hp_halfamp.String);%%for high-pass filter + + if gui_erp_filtering.lp_tog.Value ==1 + + if length(valuel)~=1 || isempty(valuel) + beep; + msgboxText = ['Filtring - Invalid input for low-pass filter cutoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if valuel>=fs/2 + beep; + msgboxText = ['Filtring - The low-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if gui_erp_filtering.hp_tog.Value ==0 + if valuel<0.001 + beep; + msgboxText = ['Filtring - We strongly recommend the low-pass filter cutoff is larger than 0.001Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + end + + if gui_erp_filtering.hp_tog.Value ==1 + if length(valueh)~=1 + beep; + msgboxText = ['Filtring - Invalid input for high-pass filter cutoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if valueh>=fs/2 + beep; + msgboxText = ['Filtring - The high-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if gui_erp_filtering.lp_tog.Value ==0 + if valueh<0.001 + beep; + msgboxText = ['Filtring - We strongly recommend the high-pass filter cutoff is larger than 0.001Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + end + + if gui_erp_filtering.hp_tog.Value ==1 && gui_erp_filtering.lp_tog.Value ==1 + if valueh >0 && valueh >0 && valueh >=valuel + beep; + msgboxText = ['Filtring - The lowest bandpass cuttoff is the highest bandpass cuttoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if valueh==0 && valuel==0 + beep; + msgboxText = ['Filtring - Either Lowest bandpass cuttoff or the highest bandpass cuttoff or both is larger than 0.01Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + if valuel> 0 && valueh ==0 + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, valuel, 0, fs); + gui_erp_filtering.lp_halfpow.String = num2str(frec3dB); + elseif valuel== 0 && valueh > 0 + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder,0, valueh,fs); + gui_erp_filtering.hp_halfpow.String = num2str(frec3dB); + elseif valuel> 0 && valueh > 0 + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder,valuel, valueh,fs); + gui_erp_filtering.lp_halfpow.String = num2str(frec3dB(1)); + gui_erp_filtering.hp_halfpow.String = num2str(frec3dB(2)); + end + end + +%-----------------------change for ALLERPs--------------------------------- +% function erpschange(~,~) +% +% +% end + + +%%------------------Setting for apply option-------------------------------- + function ERP_filter_apply(~,~) + try + nchan = observe_ERPDAT.ERP.nchan; + fs = observe_ERPDAT.ERP.srate; + catch + return; + end + + defx = {0 30 2 1:nchan 1 'butter' 0 []}; + def = erpworkingmemory('pop_filterp'); + if isempty(def) + def = defx; + end + + remove_dc = gui_erp_filtering.DC_remove.Value; + filterorder = 2*gui_erp_filtering.roll_off.Value; + locutoff = str2num(gui_erp_filtering.hp_halfamp.String);%% + hicutoff = str2num(gui_erp_filtering.lp_halfamp.String); + + if isempty(locutoff) + locutoff =0; + end + if isempty(hicutoff) + hicutoff =0; + end + + if gui_erp_filtering.lp_tog.Value ==1 + + if length(hicutoff)~=1 || isempty(hicutoff) + beep; + msgboxText = ['Filtring - Invalid input for low-pass filter cutoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if hicutoff>=fs/2 + beep; + msgboxText = ['Filtring - The low-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if gui_erp_filtering.hp_tog.Value ==0 + if hicutoff<0.001 + beep; + msgboxText = ['Filtring - We strongly recommend the low-pass filter cutoff is larger than 0.001Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + end + + if gui_erp_filtering.hp_tog.Value ==1 + if length(locutoff)~=1 + beep; + msgboxText = ['Filtring - Invalid input for high-pass filter cutoff']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if locutoff>=fs/2 + beep; + msgboxText = ['Filtring - The high-pass filter cutoff should be smaller than',32,num2str(fs/2),'Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if gui_erp_filtering.lp_tog.Value ==0 + if locutoff<0.001 + beep; + msgboxText = ['Filtring - We strongly recommend the high-pass filter cutoff is larger than 0.001Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + end + + if gui_erp_filtering.hp_tog.Value ==1 && gui_erp_filtering.lp_tog.Value ==1 + if locutoff==0 && hicutoff==0 + beep; + msgboxText = ['Filtring - Either Lowest bandpass cuttoff or the highest bandpass cuttoff or both is larger than 0.01Hz']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + if remove_dc==1 + rdc = 'on'; + else + rdc = 'off'; + end + filterallch = def{5}; + + if filterallch + chanArray = 1:nchan; + end + + + fdesign = 'butter'; + if ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff>0 % Butter (IIR) and FIR%% low-pass filter + ftype = 'lowpass'; + cutoff = hicutoff; + elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff==0 % Butter (IIR) and FIR + ftype = 'highpass'; + cutoff = locutoff; + elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff>0 && locutoff0 && hicutoff>0 && locutoff>hicutoff% Butter (IIR) and FIR + ftype = 'simplenotch'; + cutoff = [locutoff hicutoff]; + elseif ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff==0 % Butter (IIR) and FIR + msgboxText = 'I beg your pardon?'; + title = 'EStudio: f_ERP_filtering_GUI() !'; + errorfound(msgboxText, title); + return; + else + beep; + msgboxText = ['Filtring - Invalid type of filter']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + + end + + erpworkingmemory('pop_filterp', {locutoff,hicutoff,filterorder,chanArray,filterallch,fdesign,remove_dc}); + + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index; + + %%-------------loop start for filtering the selected ERPsets----------------------------------- + + erpworkingmemory('f_ERP_proces_messg','Filtering'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + + try + FilterMethod = 'filtered'; + if numel(Selected_erpset)>1 + + Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selected_erpset,FilterMethod); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + + if ~isempty(Answer{1}) + ALLERP_advance = Answer{1}; + Save_file_label = Answer{2}; + end + + elseif numel(Selected_erpset)==1 + Save_file_label =0; + ALLERP_advance = observe_ERPDAT.ALLERP; + end + + BinArray = []; + ChanArray = []; + for Numoferp = 1:numel(Selected_erpset) + if Selected_erpset(Numoferp)> length(observe_ERPDAT.ALLERP) + beep; + msgboxText = ['Filtring - No corresponding ERP exists in ALLEERP']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + break; + end + + if (checked_ERPset_Index_bin_chan(1)==1 || checked_ERPset_Index_bin_chan(2)==2) && gui_erp_filtering.Selected_bin_chan.Value ==1 + if checked_ERPset_Index_bin_chan(1) ==1 + msgboxText = ['Number of bins across the selected ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(2)==2 + msgboxText = ['Number of channels across the selected ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(1)==1 && checked_ERPset_Index_bin_chan(2)==2 + msgboxText = ['Number of channels and bins vary across the selected ERPsets']; + end + question = [ '%s\n\n "All" will be active instead of "Selected bin and chan".']; + title = 'EStudio: Filtering'; + button = questdlg(sprintf(question, msgboxText), title,'OK','OK'); + BinArray = []; + ChanArray = []; + end + + ERP = ALLERP_advance(Selected_erpset(Numoferp)); + if (checked_ERPset_Index_bin_chan(1)==0 && checked_ERPset_Index_bin_chan(2)==0) && gui_erp_filtering.Selected_bin_chan.Value ==1 + try + BinArray = S_binchan.bins{1}; + ChanArray = S_binchan.elecs_shown{1}; + [chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1); + if chk(1)==1 + BinArray = [1:ERP.nbin]; + end + [chk, msgboxText] = f_ERP_chckbinandchan(ERP,[], ChanArray,2); + if chk(2)==1 + ChanArray = [1:ERP.nchan]; + end + + catch + BinArray = [1:ERP.nbin]; + ChanArray = [1:ERP.nchan]; + end + end + + if gui_erp_filtering.all_bin_chan.Value == 1 + BinArray = [1:ERP.nbin]; + ChanArray = [1:ERP.nchan]; + end + ERP_AF = ERP; + %%Only the slected bin and chan were selected to remove baseline and detrending and others are remiained. + [ERP, ERPCOM] = pop_filterp(ERP, chanArray, 'Filter',ftype, 'Design', fdesign, 'Cutoff', cutoff, 'Order', filterorder, 'RemoveDC', rdc,... + 'Saveas', 'off', 'History', 'gui'); + + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + if Numoferp==1 + [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + end + if ~isempty(BinArray)&& ~isempty(ChanArray) + try + ERP_AF.bindata(ChanArray,:,BinArray) = ERP.bindata(ChanArray,:,BinArray); + ERP.bindata = ERP_AF.bindata; + catch + ERP = ERP; + end + end + + if numel(Selected_erpset) ==1 + Answer = f_ERP_save_single_file(char(strcat(ERP.erpname,'_',FilterMethod)),ERP.filename,Selected_erpset(Numoferp)); + if isempty(Answer) + disp('User selected cancel.'); + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ''; + ERP.saved = 'no'; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + ERP.saved = 'yes'; + %%----------save the current sdata as-------------------- + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + end + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + if Save_file_label + [pathstr, file_name, ext] = fileparts(ERP.filename); + ERP.filename = [file_name,'.erp']; + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + + + end + %%close the wait bar + % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('ERPfilter',1); + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1:length(observe_ERPDAT.ALLERP)]; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + + observe_ERPDAT.Process_messg =2; + catch + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + Selected_ERP_afd =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + erpworkingmemory('ERPfilter',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%%There is erros in processing procedure + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + +%%-------------------Setting for advance option--------------------------- + function advanced_ERP_filter(~,~) + + try + nchan = observe_ERPDAT.ERP.nchan; + fs = observe_ERPDAT.ERP.srate; + catch + fs = 256; + nchan = 30; + end + defx = {0 30 2 1:nchan 1 'butter' 0 []}; + def = erpworkingmemory('pop_filterp'); + + if isempty(def) + def = defx; + else + def{4} = def{4}(ismember_bc2(def{4},1:nchan)); + end + + def{1} = str2num(gui_erp_filtering.hp_halfamp.String); + def{2} = str2num(gui_erp_filtering.lp_halfamp.String); + if gui_erp_filtering.hp_tog.Value ==1 + if isempty(def{1}) || def{1} ==0 + def{1} = 0.01; + end + end + if gui_erp_filtering.lp_tog.Value ==1 + if isempty(def{2}) || def{2} ==0 + def{2} = floor((fs/2-1)*5/10); + end + end + + def{7} = gui_erp_filtering.DC_remove.Value; + def{8} = []; + fdesign = 'butter'; + def{3} = 2*gui_erp_filtering.roll_off.Value; + def{6} = fdesign; + + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index; + + BinArray = []; + ChanArray =[]; + + if checked_ERPset_Index_bin_chan(1) ==1 || checked_ERPset_Index_bin_chan(2) ==2 + BinArray = []; + ChanArray =[]; + def{5} =1; + else + try + BinArray = S_binchan.bins{1}; + ChanArray = S_binchan.elecs_shown{1}; + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, BinArray, [],1); + if chk(1)==1 + BinArray = [1:observe_ERPDAT.ERP.nbin]; + end + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP,[], ChanArray,2); + if chk(2)==1 + ChanArray = [1:observe_ERPDAT.ERP.nchan]; + end + + catch + BinArray = [1:observe_ERPDAT.ERP.nbin]; + ChanArray = [1:observe_ERPDAT.ERP.nchan]; + end + def{5} =0; + end + + + if (checked_ERPset_Index_bin_chan(1)==1 && checked_ERPset_Index_bin_chan(2)==2) + BinArray = []; + ChanArray = []; + end + + if (checked_ERPset_Index_bin_chan(1)==0 && checked_ERPset_Index_bin_chan(2)==0) && gui_erp_filtering.all_bin_chan.Value + BinArray = []; + ChanArray = []; + end + + def{9} = BinArray; + def{4} = ChanArray; + %%call the GUI for advance option + answer = f_basicfilterGUI2(observe_ERPDAT.ERP, def); + if isempty(answer) + beep; + disp('User selected Cancel') + return; + end + + defx = {answer{1},answer{2},answer{3},answer{4},answer{5},answer{6},answer{7},answer{8}}; + erpworkingmemory('pop_filterp',defx); + % erpworkingmemory('filterp_advanced', 1); + + locutoff = answer{1}; % for high pass filter + hicutoff = answer{2}; % for low pass filter + filterorder = answer{3}; + ChanArray = answer{4}; + filterallch = answer{5}; + fdesign = answer{6}; + remove_dc = answer{7}; + BinArray = answer{9}; + + if checked_ERPset_Index_bin_chan(1) ==1 || checked_ERPset_Index_bin_chan(2) ==2 + BinArray = []; + ChanArray =[]; + end + + if locutoff >= fs/2 || locutoff< 0 + locutoff = floor(fs/2)-1; + end + if hicutoff>=fs/2 || hicutoff< 0 + hicutoff = floor(fs/2)-1; + end + + if isempty(locutoff) + locutoff = 0; + end + + if isempty(hicutoff) + hicutoff = 0; + end + %%-----------setting for IIR butter---------------------- + if strcmpi(fdesign,'butter') + typef = 0; + gui_erp_filtering.roll_off.Value = filterorder/2; + gui_erp_filtering.roll_off.String = {'12','24','36','48'}'; + gui_erp_filtering.roll_off.Enable = 'on'; + gui_erp_filtering.DC_remove.Value = remove_dc; + %%High-pass filtering + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,locutoff,fs); + if locutoff > 0 && (isempty(hicutoff) || hicutoff ==0 ) + gui_erp_filtering.hp_tog.Value = 1; + gui_erp_filtering.hp_tog.Enable ='on'; + gui_erp_filtering.lp_tog.Value = 0; + gui_erp_filtering.lp_tog.Enable ='on'; + + gui_erp_filtering.hp_halfamp.String = num2str(locutoff); + gui_erp_filtering.hp_halfamp.Enable = 'on'; + + gui_erp_filtering.lp_halfamp.String = num2str(hicutoff); + gui_erp_filtering.lp_halfamp.Enable = 'off'; + gui_erp_filtering.hp_halfpow.String = num2str(roundn(frec3dB(1),-2)); + gui_erp_filtering.lp_halfpow.String = '---'; + end + %%Low pass filtering + if hicutoff > 0 && (isempty(locutoff) || locutoff ==0) + gui_erp_filtering.lp_tog.Value = 1; + gui_erp_filtering.lp_tog.Enable ='on'; + gui_erp_filtering.hp_tog.Value = 0; + gui_erp_filtering.hp_tog.Enable ='on'; + gui_erp_filtering.lp_halfamp.String = num2str(hicutoff); + gui_erp_filtering.lp_halfamp.Enable = 'on'; + gui_erp_filtering.hp_halfamp.String = num2str(locutoff); + gui_erp_filtering.hp_halfamp.Enable = 'off'; + gui_erp_filtering.lp_halfpow.String = num2str(roundn(frec3dB(1),-2)); + gui_erp_filtering.hp_halfpow.String = '---'; + + end + %%Band pass filtering or notch filtering + if locutoff >0 && hicutoff>0 + gui_erp_filtering.hp_tog.Value = 1; + gui_erp_filtering.hp_tog.Enable ='on'; + gui_erp_filtering.lp_tog.Value = 1; + gui_erp_filtering.lp_tog.Enable ='on'; + gui_erp_filtering.hp_halfamp.String = num2str(locutoff); + gui_erp_filtering.hp_halfamp.Enable = 'on'; + gui_erp_filtering.lp_halfamp.String = num2str(hicutoff); + gui_erp_filtering.lp_halfamp.Enable = 'on'; + gui_erp_filtering.hp_halfpow.String = num2str(roundn(frec3dB(2),-2)); + gui_erp_filtering.lp_halfpow.String = num2str(roundn(frec3dB(1),-2)); + end + end%%setting end for IIR butter filter + %%*************Filter the selected ERPsets*************************** + if remove_dc==1 + rdc = 'on'; + else + rdc = 'off'; + end + filterallch = def{5}; + if ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff>0 % Butter (IIR) and FIR%% low-pass filter + ftype = 'lowpass'; + cutoff = hicutoff; + elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff==0 % Butter (IIR) and FIR + ftype = 'highpass'; + cutoff = locutoff; + elseif ~strcmpi(fdesign, 'notch') && locutoff>0 && hicutoff>0 && locutoff0 && hicutoff>0 && locutoff>hicutoff% Butter (IIR) and FIR + ftype = 'simplenotch'; + cutoff = [locutoff hicutoff]; + elseif strcmpi(fdesign, 'notch') && locutoff==hicutoff % Parks-McClellan Notch + ftype = 'PMnotch'; + cutoff = hicutoff; + + elseif ~strcmpi(fdesign, 'notch') && locutoff==0 && hicutoff==0 % Butter (IIR) and FIR + msgboxText = 'I beg your pardon?'; + title = 'EStudio: f_ERP_filtering_GUI() !'; + errorfound(msgboxText, title); + return; + else + beep; + msgboxText = ['Filtring - Invalid type of filter']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + + if strcmpi(fdesign, 'notch') && locutoff==hicutoff + if 3*filterorder>=length(observe_ERPDAT.ERP.times) + beep; + msgboxText = ['Filtring -The length of the data must be more than three times the filter order']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + + %%-------------loop start for filtering the selected ERPsets----------------------------------- + erpworkingmemory('f_ERP_proces_messg','Filtering (Advanced)'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + try + Suffix_label = 1; + FilterMethod_str = char(strcat('filtered')); + if numel(Selected_erpset)>1 + Answer = f_ERP_save_multi_file(observe_ERPDAT.ALLERP,Selected_erpset,FilterMethod_str); + if isempty(Answer) + beep; + disp('User selected Cancel'); + return; + end + + if ~isempty(Answer{1}) + ALLERP_advance = Answer{1}; + Save_file_label = Answer{2}; + end + + elseif numel(Selected_erpset)==1 + Save_file_label =0; + ALLERP_advance = observe_ERPDAT.ALLERP; + end + + for Numoferp = 1:numel(Selected_erpset) + + if Selected_erpset(Numoferp)> length(observe_ERPDAT.ALLERP) + beep; + msgboxText = ['Filtring - No corresponding ERP exists in ALLEERP']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + break; + end + + if (checked_ERPset_Index_bin_chan(1)==1 || checked_ERPset_Index_bin_chan(2)==2) && gui_erp_filtering.Selected_bin_chan.Value ==1 + if checked_ERPset_Index_bin_chan(1) ==1 + msgboxText = ['Number of bins across the selected ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(2)==2 + msgboxText = ['Number of channels across the selected ERPsets is different!']; + elseif checked_ERPset_Index_bin_chan(1)==1 && checked_ERPset_Index_bin_chan(2)==2 + msgboxText = ['Number of channels and bins vary across the selected ERPsets']; + end + question = [ '%s\n\n "All" will be active instead of "Selected bin and chan".']; + title = 'EStudio: Filtering'; + button = questdlg(sprintf(question, msgboxText), title,'OK','OK'); + BinArray = []; + ChanArray = []; + end + + if (checked_ERPset_Index_bin_chan(1)==0 && checked_ERPset_Index_bin_chan(2)==0) && gui_erp_filtering.Selected_bin_chan.Value ==1 + try + BinArray = S_binchan.bins{1}; + ChanArray = S_binchan.elecs_shown{1}; + catch + BinArray = [1:ERP.nbin]; + ChanArray = [1:ERP.nchan]; + end + end + + + ERP = ALLERP_advance(Selected_erpset(Numoferp)); + ERP_before_bl = ERP; + + [ERP, ERPCOM] = pop_filterp(ERP, [1:ERP.nchan], 'Filter',ftype, 'Design', fdesign, 'Cutoff', cutoff, 'Order', filterorder, 'RemoveDC', rdc,... + 'Saveas', 'off', 'History', 'gui'); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + if Numoferp ==1 + [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + end + %%Only the slected bin and chan were selected to remove baseline and detrending and others are remiained. + if ~isempty(BinArray) && ~isempty(ChanArray) + try + ERP_before_bl.bindata(ChanArray,:,BinArray) = ERP.bindata(ChanArray,:,BinArray); + ERP.bindata = ERP_before_bl.bindata; + catch + ERP = ERP; + end + end + %%Rename single file------------------------------------ + if numel(Selected_erpset) ==1 + Answer = f_ERP_save_single_file(char(strcat(ERP.erpname,'_',FilterMethod_str)),ERP.filename,Selected_erpset(Numoferp)); + if isempty(Answer) + disp('User selected Cancel'); + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ''; + ERP.saved = 'no'; + elseif ~isempty(fileName_full) + [pathstr, file_name, ext] = fileparts(fileName_full); + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + ERP.saved = 'yes'; + %%----------save the current sdata as-------------------- + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + end + + if Save_file_label + [pathstr, file_name, ext] = fileparts(ERP.filename); + ERP.filename = [file_name,'.erp']; + ERP.saved = 'yes'; + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + else + + ERP.filename = ''; + ERP.saved = 'no'; + end + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + end + + % [~, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('ERPfilter',1); + + try + Selected_ERP_afd = [length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1:length(observe_ERPDAT.ALLERP)]; + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP)-numel(Selected_erpset)+1; + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + catch + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + Selected_ERP_afd =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + erpworkingmemory('ERPfilter',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + + observe_ERPDAT.Process_messg =3; + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%-------------------Setting for the whole panel of fitering based on ALLERP and CURRENTERP-------------- + function Count_currentERPChanged(~,~) + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') || strcmp(observe_ERPDAT.ERP.datatype,'EFFT') + gui_erp_filtering.apply.Enable = 'off'; + gui_erp_filtering.advanced.Enable = 'off'; + gui_erp_filtering.roll_off.Enable = 'off'; + gui_erp_filtering.hp_halfamp.Enable = 'off'; + gui_erp_filtering.lp_halfamp.Enable = 'off'; + gui_erp_filtering.hp_tog.Enable = 'off'; + gui_erp_filtering.lp_tog.Enable = 'off'; + gui_erp_filtering.all_bin_chan.Enable = 'off'; + gui_erp_filtering.Selected_bin_chan.Enable = 'off'; + else + + gui_erp_filtering.all_bin_chan.Enable = 'on'; + gui_erp_filtering.Selected_bin_chan.Enable = 'on'; + locutoff = str2num(gui_erp_filtering.hp_halfamp.String);%%for high pass filter + hicutoff = str2num(gui_erp_filtering.lp_halfamp.String);%% for low pass filter + + if isempty(locutoff) + locutoff =0; + gui_erp_filtering.hp_halfamp.String = '0'; + end + if isempty(hicutoff) + hicutoff = 0; + gui_erp_filtering.lp_halfamp.String = '0'; + end + fs = observe_ERPDAT.ERP.srate; + if fs <=0 + fs = 256; + end + typef = 0; + filterorder = 2*gui_erp_filtering.roll_off.Value; + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, filterorder, hicutoff,locutoff,fs); + if locutoff > 0 && hicutoff ==0 + highpass_toggle_value = 1; + hp_halfamp_enable = 'on'; + lowpass_toggle_value = 0; + lp_halfamp_Enable = 'off'; + hp_halfpow_string =num2str(roundn(frec3dB(1),-2)); + lp_halfpow_string ='---'; + end + %%Low pass filtering + if hicutoff > 0 && locutoff ==0 + highpass_toggle_value = 0; + hp_halfamp_enable = 'off'; + lowpass_toggle_value = 1; + lp_halfamp_Enable = 'on'; + lp_halfpow_string =num2str(roundn(frec3dB,-2)); + hp_halfpow_string ='---'; + end + %%Band pass filtering or notch filtering + if locutoff >0 && hicutoff>0 + highpass_toggle_value = 1; + hp_halfamp_enable = 'on'; + hp_halfpow_string =num2str(roundn(frec3dB(2),-2)); + lowpass_toggle_value = 1; + lp_halfamp_Enable = 'on'; + lp_halfpow_string =num2str(roundn(frec3dB(1),-2)); + end + + if locutoff==0 && hicutoff==0 + highpass_toggle_value = 0; + hp_halfamp_enable = 'off'; + hp_halfpow_string ='0'; + lowpass_toggle_value = 0; + lp_halfamp_Enable = 'off'; + lp_halfpow_string ='0'; + end + + gui_erp_filtering.apply.Enable = 'on'; + gui_erp_filtering.advanced.Enable = 'on'; + gui_erp_filtering.roll_off.Enable = 'on'; + gui_erp_filtering.hp_halfpow.String = hp_halfpow_string; + gui_erp_filtering.lp_halfpow.String = lp_halfpow_string; + gui_erp_filtering.hp_halfamp.Enable = hp_halfamp_enable; + gui_erp_filtering.lp_halfamp.Enable = lp_halfamp_Enable; + gui_erp_filtering.hp_tog.Value = highpass_toggle_value; + gui_erp_filtering.lp_tog.Value = lowpass_toggle_value; + + gui_erp_filtering.hp_tog.Enable = 'on'; + gui_erp_filtering.lp_tog.Enable = 'on'; + + try + S_ws = evalin('base','S'); + Selected_erpset = S_ws.geterpset.selectederp; + catch + Selected_erpset = observe_ERPDAT.CURRENTERP; + end + + Check_Selected_erpset = [0 0 0 0 0 0 0]; + if numel(Selected_erpset)>1 + try + S_ws = evalin('base','S'); + Check_Selected_erpset = S_binchan.checked_ERPset_Index; + catch + Check_Selected_erpset = f_checkerpsets(observe_ERPDAT.ALLERP,Selected_erpset); + end + end + if Check_Selected_erpset(1) ==1 || Check_Selected_erpset(2) == 2 + gui_erp_filtering.Selected_bin_chan.Value =0; + gui_erp_filtering.Selected_bin_chan.Enable = 'off'; + gui_erp_filtering.all_bin_chan.Value = 1; + gui_erp_filtering.all_bin_chan.Enable = 'on'; + end + + end + end + + +end +%Progem end: ERP Measurement tool \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_grandaverageGUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_grandaverageGUI.m new file mode 100755 index 00000000..99e0061d --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_grandaverageGUI.m @@ -0,0 +1,481 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_grandaverageGUI(varargin) +global observe_ERPDAT; +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +gui_erp_grdavg = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global ERP_grdavg_gui; +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + ERP_grdavg_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'Average across ERPsets ', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_grdavg_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Average across ERPsets ', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_grdavg_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Average across ERPsets ', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_bin_operation(FonsizeDefault) +varargout{1} = ERP_grdavg_gui; + + function drawui_erp_bin_operation(FonsizeDefault) + FontSize_defualt = FonsizeDefault; + + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + %%--------------------channel and bin setting---------------------- + gui_erp_grdavg.DataSelBox = uiextras.VBox('Parent', ERP_grdavg_gui,'BackgroundColor',ColorB_def); + + %%Parameters + gui_erp_grdavg.weigavg_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_grdavg.weigavg = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.weigavg_title,... + 'String','Use weighted average based on trial numbers','Value',0,... + 'callback',@checkbox_weigavg,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + + gui_erp_grdavg.excldnullbin_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_grdavg.excldnullbin = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.excldnullbin_title,... + 'String','','Value',0,'Enable','off','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_grdavg.excldnullbin.String = 'Exclude any null bin from non-weighted
averaing (recommended)'; + + + gui_erp_grdavg.jacknife_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_grdavg.jacknife = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.jacknife_title,... + 'String','','Value',0,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_grdavg.jacknife.String = 'Include Jackknife subaverages (creates
multiple ERPsets)'; + + + gui_erp_grdavg.warn_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_grdavg.warn = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.warn_title,... + 'String','','Value',0,'callback',@checkbox_warn,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_grdavg.warn.String = 'Warning if any subjects who exceed
the epoch rejection threshold (%) '; + gui_erp_grdavg.warn_edit = uicontrol('Style','edit','Parent', gui_erp_grdavg.warn_title,... + 'String','','callback',@warn_edit,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + % set(gui_erp_grdavg.hr_title,'Sizes',[210,50]); + set(gui_erp_grdavg.warn_title,'Sizes',[220,70]); + + + gui_erp_grdavg.cmpsd_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_grdavg.cmpsd = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.cmpsd_title,... + 'String','Compute point-by-point SEM','Value',1,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + + + gui_erp_grdavg.cbdatq_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_grdavg.cbdatq = uicontrol('Style','checkbox','Parent', gui_erp_grdavg.cbdatq_title,... + 'String','','Value',1,'callback',@checkbox_cbdatq,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_grdavg.cbdatq.String = 'Combine data
quality measures '; + + gui_erp_grdavg.cbdatq_def = uicontrol('Style','radiobutton','Parent', gui_erp_grdavg.cbdatq_title,... + 'String','defaults','Value',1,'callback',@cbdatq_def,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + + gui_erp_grdavg.cbdatq_custom = uicontrol('Style','radiobutton','Parent', gui_erp_grdavg.cbdatq_title,... + 'String','custom combo','Value',0,'callback',@cbdatq_custom,'FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + gui_erp_grdavg.cbdatq_custom.String = 'custom
combo '; + set(gui_erp_grdavg.cbdatq_title,'Sizes',[120 70 70]); + + gui_erp_grdavg.cbdatq_custom_option_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_grdavg.cbdatq_custom_option_title); + gui_erp_grdavg.cbdatq_custom_op = uicontrol('Style','pushbutton','Parent', gui_erp_grdavg.cbdatq_custom_option_title,... + 'String','set custom DQ combo','callback',@cbdatq_custom_op,'Enable','off','FontSize',FontSize_defualt,'BackgroundColor',[1 1 1]); % 2F + + gui_erp_grdavg.location_title = uiextras.HBox('Parent', gui_erp_grdavg.DataSelBox,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent',gui_erp_grdavg.location_title); + uicontrol('Style','pushbutton','Parent',gui_erp_grdavg.location_title,... + 'String','?','callback',@tool_link,'FontSize',16,'BackgroundColor',[1 1 1],'Max',10); % 2F + uiextras.Empty('Parent',gui_erp_grdavg.location_title); + gui_erp_grdavg.run = uicontrol('Style','pushbutton','Parent',gui_erp_grdavg.location_title,... + 'String','Run','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); + uiextras.Empty('Parent',gui_erp_grdavg.location_title); + set(gui_erp_grdavg.location_title,'Sizes',[20 95 30 95 20]); + + set(gui_erp_grdavg.DataSelBox,'Sizes',[25,30,30,30,25,30,25,30]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + + + +%%---------------checkbox for weighted average----------------------------- + function checkbox_weigavg(source,~) + if ~source.Value + set(gui_erp_grdavg.excldnullbin,'Enable','on','Value',0); + else + set(gui_erp_grdavg.excldnullbin,'Enable','off','Value',0); + end + end + +%%-------------------checkbox for warning---------------------------------- + function checkbox_warn(source,~) + if ~source.Value + gui_erp_grdavg.warn_edit.Enable = 'off'; + else + gui_erp_grdavg.warn_edit.Enable = 'on'; + end + end + + +%%%%----------------checkbox for combining data quality measures----------- + function checkbox_cbdatq(source,~) + checkad = source.Value; + if checkad + gui_erp_grdavg.cbdatq_custom.Value = 0; + gui_erp_grdavg.cbdatq_def.Value = 1; + gui_erp_grdavg.cbdatq_custom_op.Enable = 'off'; + gui_erp_grdavg.cbdatq_def.Enable = 'on'; + gui_erp_grdavg.cbdatq_custom.Enable = 'on'; + else + gui_erp_grdavg.cbdatq_custom.Enable = 'off'; + gui_erp_grdavg.cbdatq_def.Enable = 'off'; + gui_erp_grdavg.cbdatq_custom_op.Enable = 'off'; + end + end +%%%%----------------default setting for combining data quality measures---- + function cbdatq_def(~,~) + gui_erp_grdavg.cbdatq_custom.Value = 0; + gui_erp_grdavg.cbdatq_def.Value = 1; + gui_erp_grdavg.cbdatq_custom_op.Enable = 'off'; + end + +%%%%----------------Custom setting for combining data quality measures---- + function cbdatq_custom(~,~) + gui_erp_grdavg.cbdatq_custom.Value = 1; + gui_erp_grdavg.cbdatq_def.Value = 0; + gui_erp_grdavg.cbdatq_custom_op.Enable = 'on'; + end + +%%-----------------define the epoch rejection threshold (%) ---------------------------- + function warn_edit(source,~) + rejection_peft = str2num(source.String); + if isempty(rejection_peft) + gui_erp_grdavg.warn_edit.String = ''; + beep; + msgboxText = ['Average across ERPsets - Invalid artifact detection proportion.\n'... + 'Please, enter a number between 0 and 100.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if rejection_peft<0 || rejection_peft>100 + gui_erp_grdavg.warn_edit.String = ''; + beep; + msgboxText = ['Average across ERPsets - Invalid artifact detection proportion.\n'... + 'Please, enter a number between 0 and 100.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + +%%-----------Setting for custom DQ combo---------------------------------- + function cbdatq_custom_op(~,~) + + GAv_combo_defaults.measures = [1, 2, 3]; % Use first 3 DQ measures + GAv_combo_defaults.methods = [2, 2, 2]; % Use the 2nd combo method, Root-Mean Square, for each + GAv_combo_defaults.measure_names = {'Baseline Measure - SD';'Point-wise SEM'; 'aSME'}; + GAv_combo_defaults.method_names = {'Pool ERPSETs, GrandAvg mean','Pool ERPSETs, GrandAvg RMS'}; + GAv_combo_defaults.str = {'Baseline Measure - SD, GrandAvg RMS';'Point-wise SEM, GrandAvg RMS'; 'aSME GrandAvg RMS'}; + custom_spec = grandaverager_DQ(GAv_combo_defaults); + estudioworkingmemory('grandavg_custom_DQ',custom_spec); + end +%%---------------------CSD tool link------------------------------------- + function tool_link(~,~) + web('https://github.com/lucklab/erplab/wiki/Averaging-Across-ERPSETS-_-Creating-Grand-Averages','-browser'); + end + + +%%---------------------Run------------------------------------------------- + function apply_run(~,~) + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + beep; + msgboxText = ['Average across ERPsets - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + if numel(Selectederp_Index)<2 + beep; + msgboxText = ['Average across ERPsets - Two ERPsets,at least,were selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + optioni = 0; %1 means from a filelist, 0 means from erpsets menu + + erpset = Selectederp_Index; + if gui_erp_grdavg.warn.Value + artcrite = str2num(gui_erp_grdavg.warn_edit.String); + else + artcrite = 100; + end + + if isempty(artcrite) || artcrite<0 || artcrite>100 + beep; + msgboxText = ['Average across ERPsets - Invalid artifact detection proportion.\n'... + 'Please, enter a number between 0 and 100.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + %%Send message to Message panel + erpworkingmemory('f_ERP_proces_messg','Average across ERPsets'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + + Weightedg = gui_erp_grdavg.weigavg.Value; + wavg = gui_erp_grdavg.warn.Value; % 0;1 + excnullbin = gui_erp_grdavg.excldnullbin.Value; % 0;1 + stderror = gui_erp_grdavg.cmpsd.Value; % 0;1 + jk = gui_erp_grdavg.jacknife.Value; % 0;1 + if jk + Answer = f_ERP_save_single_file(strcat('_jackknife'),'',length(observe_ERPDAT.ALLERP)+1); + else + Answer = f_ERP_save_single_file(strcat('grand'),'',length(observe_ERPDAT.ALLERP)+1); + end + if isempty(Answer) + beep; + disp('User selectd cancal'); + return; + end + erpName_new = ''; + fileName_new = ''; + pathName_new = pathName_def; + Save_file_label =0; + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + erpName_new = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + fileName_new = ''; + Save_file_label =0; + elseif ~isempty(fileName_full) + + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = pathName_def; + end + fileName_new = [file_name,ext]; + pathName_new = pathstr; + Save_file_label =1; + end + end + + if jk + jkerpname = erpName_new; + jkfilename =fileName_new ; + else + jkerpname = ''; % erpname for JK grand averages + jkfilename = ''; % filename for JK grand averages + end + + + GAv_combo_defaults.measures = [1, 2, 3]; % Use first 3 DQ measures + GAv_combo_defaults.methods = [2, 2, 2]; % Use the 2nd combo method, Root-Mean Square, for each + GAv_combo_defaults.measure_names = {'Baseline Measure - SD';'Point-wise SEM'; 'aSME'}; + GAv_combo_defaults.method_names = {'Pool ERPSETs, GrandAvg mean','Pool ERPSETs, GrandAvg RMS'}; + GAv_combo_defaults.str = {'Baseline Measure - SD, GrandAvg RMS';'Point-wise SEM, GrandAvg RMS'; 'aSME GrandAvg RMS'}; + if ~gui_erp_grdavg.cbdatq.Value + dq_option = 0; % data quality combine option. 0 - off, 1 - on/default, 2 - on/custom + elseif gui_erp_grdavg.cbdatq.Value && gui_erp_grdavg.cbdatq_def.Value + dq_option = 1; + + dq_spec = GAv_combo_defaults; + elseif gui_erp_grdavg.cbdatq.Value && gui_erp_grdavg.cbdatq_custom.Value + dq_option = 2; + dq_spec = estudioworkingmemory('grandavg_custom_DQ'); + if isempty(dq_spec) + dq_spec = GAv_combo_defaults; + end + end + + if stderror==1 + stdsstr = 'on'; + else + stdsstr = 'off'; + end + if excnullbin==1 + excnullbinstr = 'on'; % exclude null bins. + else + excnullbinstr = 'off'; + end + if wavg==1 + wavgstr = 'on'; + else + wavgstr = 'off'; + end + if Weightedg + Weightedstr = 'on'; + else + Weightedstr = 'off'; + end + + ALLERPCOM = evalin('base','ALLERPCOM'); + try + ALLERP = observe_ERPDAT.ALLERP; + if jk==1 % Jackknife + + [ALLERP, ERPCOM] = pop_jkgaverager(ALLERP, 'Erpsets', erpset, 'Criterion', artcrite,... + 'SEM', stdsstr, 'Weighted', Weightedstr, 'Erpname', jkerpname, 'Filename', jkfilename,... + 'DQ_flag',dq_option,'DQ_spec',dq_spec,'Warning', wavgstr); + Selected_ERP_afd = setdiff([1:length(ALLERP)],[1:length(observe_ERPDAT.ALLERP)]); + observe_ERPDAT.ALLERP = ALLERP; + observe_ERPDAT.CURRENTERP = Selected_ERP_afd(1); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + + if Save_file_label==1 + for Numofselectederp =1:numel(Selected_ERP_afd) + ERP_save = observe_ERPDAT.ALLERP(Selected_ERP_afd(Numofselectederp)); + ERP_save.filepath = pathName_new; + [ERP, issave, ERPCOM] = pop_savemyerp(ERP_save, 'erpname', ERP_save.erpname, 'filename', ERP_save.erpname, 'filepath',ERP_save.filepath); + end + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + + else + [ERP, ERPCOM] = pop_gaverager(ALLERP, 'Erpsets', erpset,'Criterion', artcrite, 'SEM', stdsstr,... + 'ExcludeNullBin', excnullbinstr,'Weighted', Weightedstr, 'Saveas', 'off',... + 'DQ_flag',dq_option,'DQ_spec',dq_spec,'Warning', wavgstr, 'History', 'gui'); + ERP.erpname = erpName_new; + ERP.filename = fileName_new; + ERP.filepath = pathName_new; + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM); + % [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + if Save_file_label==1 + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + catch + msgboxText = ['Please check all the parameters are correct!!!']; + title = 'EStudio: "Average across ERPsets" panel.'; + errorfound(sprintf(msgboxText), title); + observe_ERPDAT.Process_messg =3; + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%--------Setting current ERPset/session history based on the current updated ERPset------------ + function Count_currentERPChanged(~,~) + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + + if isempty(Selectederp_Index) + beep; + msgboxText = ['Average across ERPsets - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + checked_curr_index = 1; + else + checked_curr_index = 0; + end + + if isempty(checked_ERPset_Index) + checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,Selectederp_Index); + end + if checked_curr_index || any(checked_ERPset_Index(:)) + Enable_label = 'off'; + else + Enable_label = 'on'; + end + gui_erp_grdavg.weigavg.Enable = Enable_label; + if gui_erp_grdavg.weigavg.Value + gui_erp_grdavg.excldnullbin.Enable = 'off'; + end + gui_erp_grdavg.excldnullbin.Enable = Enable_label; + gui_erp_grdavg.jacknife.Enable = Enable_label; + gui_erp_grdavg.warn.Enable = Enable_label; + gui_erp_grdavg.warn_edit.Enable = Enable_label; + if gui_erp_grdavg.warn.Value + gui_erp_grdavg.warn_edit.Enable ='on'; + else + gui_erp_grdavg.warn_edit.Enable ='off'; + end + gui_erp_grdavg.cbdatq.Enable = Enable_label; + gui_erp_grdavg.cbdatq_def.Enable = Enable_label; + gui_erp_grdavg.cbdatq_custom.Enable = Enable_label; + if gui_erp_grdavg.cbdatq.Value && gui_erp_grdavg.cbdatq_custom.Value + gui_erp_grdavg.cbdatq_custom_op.Enable = 'on'; + elseif gui_erp_grdavg.cbdatq.Value==0 + gui_erp_grdavg.cbdatq_custom_op.Enable = 'off'; + gui_erp_grdavg.cbdatq_custom.Enable = 'off'; + gui_erp_grdavg.cbdatq_def.Enable = 'off'; + end + + gui_erp_grdavg.advanced.Enable = Enable_label; + gui_erp_grdavg.run.Enable = Enable_label; + end +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_history_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_history_GUI.m new file mode 100755 index 00000000..0b6cd3d7 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_history_GUI.m @@ -0,0 +1,222 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_history_GUI(varargin) +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +gui_erp_history = struct(); + +%-----------------------------Name the title---------------------------------------------- +% global box_erp_history; + +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end + +if nargin == 0 + fig = figure(); % Parent figure + box_erp_history = uiextras.BoxPanel('Parent', fig, 'Title', 'History', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'History', 'Padding', 5,'BackgroundColor',ColorB_def); +else + box_erp_history = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'History', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_history(FonsizeDefault); +varargout{1} = box_erp_history; + + function drawui_erp_history(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + %%--------------------channel and bin setting---------------------- + gui_erp_history.DataSelBox = uiextras.VBox('Parent', box_erp_history,'BackgroundColor',ColorB_def); + gui_erp_history.erp_history_title = uiextras.HBox('Parent', gui_erp_history.DataSelBox,'BackgroundColor',ColorB_def); + + + gui_erp_history.erp_h_all = uicontrol('Style','radiobutton','Parent',gui_erp_history.erp_history_title,'String','Current ERPset',... + 'callback',@ERP_H_ALL,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F + gui_erp_history.erp_h_EEG = uicontrol('Style','radiobutton','Parent', gui_erp_history.erp_history_title,'String','Current session',... + 'callback',@ERP_H_EEG,'Value',0,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F + + % gui_erp_history.erp_h_erp = uicontrol('Style','radiobutton','Parent', gui_erp_history.erp_history_title,'String','ERP','callback',@ERP_H_ERP,'Value',0); % 2F + + try + ERP_history = observe_ERPDAT.ERP.history; + catch + ERP_history = []; + end + if isempty(ERP_history) + ERP_history = char('No history exist in the current ERPset'); + end + [~, total_len] = size(ERP_history); + if total_len <500 + total_len =1000; + end + gui_erp_history.erp_history_table = uiextras.HBox('Parent', gui_erp_history.DataSelBox); + gui_erp_history.uitable = uitable( ... + 'Parent' , gui_erp_history.erp_history_table,... + 'Data' , strsplit(ERP_history(1,:), '\n')', ... + 'ColumnWidth' , {total_len+2}, ... + 'ColumnName' , {'Function call'}, ... + 'RowName' , []); + set( gui_erp_history.DataSelBox,'Heights',[40 -1]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + + +%--------History for both EEG and ERP data processing procedure------------ + function ERP_H_ALL(~,~) + Source_value = 1; + set(gui_erp_history.erp_h_all,'Value',Source_value); + set(gui_erp_history.erp_h_EEG,'Value',~Source_value); + + %adding the relared history in dispaly panel + hiscp_empty =0; + try + ERP_history = observe_ERPDAT.ERP.history; + catch + ERP_history = []; + end + % if isempty(ERP_history) + % hiscp_empty =1; + % ERP_history = {'No history exist in the current ERPset'}; + % end + % + % if hiscp_empty + % set(gui_erp_history.uitable,'Data', ERP_history); + % else + % set(gui_erp_history.uitable,'Data', strsplit(ERP_history(1,:), '\n')'); + % end + + if isempty(ERP_history) + ERP_history = char('No history exist in the current ERPset'); + end + ERP_history_display = {}; + for Numofrow = 1:size(ERP_history,1) + ERP_history_display = [ERP_history_display,strsplit(ERP_history(Numofrow,:), '\n')]; + end + set(gui_erp_history.uitable,'Data', ERP_history_display'); + set(gui_erp_history.DataSelBox,'Heights',[40 -1]); + set(gui_erp_history.DataSelBox,'Heights',[40 -1]); + + end + + + function ERP_H_EEG(~,~) + Source_value = 1; + set(gui_erp_history.erp_h_all,'Value',~Source_value); + set(gui_erp_history.erp_h_EEG,'Value',Source_value); + %adding the relared history in dispaly panel + try + ERP_history = evalin('base','ALLERPCOM'); + ERP_history = ERP_history'; + catch + ERP_history = {'No command history was found in the current session'}; + end + if isempty(ERP_history) + ERP_history = {'No command history was found in the current session'}; + end + + set(gui_erp_history.uitable,'Data',ERP_history); + set(gui_erp_history.DataSelBox,'Heights',[40 -1]); + end + + + +%%----------------------ALLERPsets change----------------------------------------- + function allErpChanged(~,~) + + end + + +%%--------Setting current ERPset/session history based on the current updated ERPset------------ + function Count_currentERPChanged(~,~) +% try +% ERPloadIndex = estudioworkingmemory('ERPloadIndex'); +% catch +% ERPloadIndex =0; +% end +% if ERPloadIndex==1 +% ALLERPIN = evalin('base','ALLERP'); +% CURRENTERPIN = evalin('base','CURRENTERP'); +% observe_ERPDAT.ALLERP = ALLERPIN; +% observe_ERPDAT.CURRENTERP =CURRENTERPIN; +% try +% observe_ERPDAT.ERP = ALLERPIN(CURRENTERPIN); +% catch +% observe_ERPDAT.ERP = ALLERPIN(end); +% observe_ERPDAT.CURRENTERP =length(ALLERPIN); +% end +% end + + + %check which option was selected and then update the related + %information based on the current ERPset. + if gui_erp_history.erp_h_all.Value ==1 + + try + ERP_history = observe_ERPDAT.ERP.history; + catch + ERP_history = []; + end + if isempty(ERP_history) + ERP_history = char('No history exist in the current ERPset'); + end + ERP_history_display = {}; + for Numofrow = 1:size(ERP_history,1) + ERP_history_display = [ERP_history_display,strsplit(ERP_history(Numofrow,:), '\n')]; + end + set(gui_erp_history.uitable,'Data', ERP_history_display'); + set(gui_erp_history.DataSelBox,'Heights',[40 -1]); + else%% ALLERPCOM for current session + + try + ERP_history = evalin('base','ALLERPCOM'); + ERP_history = ERP_history'; + set(gui_erp_history.uitable,'Data',ERP_history); + catch + ERP_history = {'No command history was found in the current section'}; + set(gui_erp_history.uitable,'Data',ERP_history); + end + if isempty(ERP_history) + ERP_history = {'No command history was found in the current section'}; + set(gui_erp_history.uitable,'Data',ERP_history); + end + + set(gui_erp_history.DataSelBox,'Heights',[40 -1]); + end + + end + + + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.fig b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.fig new file mode 100755 index 00000000..41be9233 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.m b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.m new file mode 100755 index 00000000..ec7c1b53 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_meas_basecorr.m @@ -0,0 +1,276 @@ +function varargout = f_ERP_meas_basecorr(varargin) +% F_ERP_MEAS_BASECORR MATLAB code for f_ERP_meas_basecorr.fig +% F_ERP_MEAS_BASECORR, by itself, creates a new F_ERP_MEAS_BASECORR or raises the existing +% singleton*. +% +% H = F_ERP_MEAS_BASECORR returns the handle to a new F_ERP_MEAS_BASECORR or the handle to +% the existing singleton*. +% +% F_ERP_MEAS_BASECORR('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_MEAS_BASECORR.M with the given input arguments. +% +% F_ERP_MEAS_BASECORR('Property','Value',...) creates a new F_ERP_MEAS_BASECORR or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_meas_basecorr_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_meas_basecorr_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_meas_basecorr + +% Last Modified by GUIDE v2.5 23-Aug-2022 09:26:55 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_meas_basecorr_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_meas_basecorr_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_meas_basecorr is made visible. +function f_ERP_meas_basecorr_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_meas_basecorr + +try + Baseline_method = varargin{1}; %% 1. long; 0 wide + % latency= varargin{2}; +catch + Baseline_method = 'pre'; %% 1. long; 0 wide + % latency= ''; +end +% handles.latency = latency; +handles.output = []; +% erpmenu = findobj('tag', 'erpsets'); +% handles.pathName = pathName; +% if ~isempty(erpmenu) +% handles.menuerp = get(erpmenu); +% set(handles.menuerp.Children, 'Enable','off'); +% end + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - ERP Measurement Tool']) + + +set(handles.current_erp_label,'String', ['ERP Measurement Tool: Baseline Period in ms'],... + 'FontWeight','Bold', 'FontSize', 16); +if length(Baseline_method)==2 + set(handles.edit_custom, 'String', num2str(Baseline_method)); + +else + + if strcmpi(Baseline_method,'pre') + set(handles.radiobutton_pre, 'Value', 1); + set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole + set(handles.radiobutton_whole, 'Value', 0); + set(handles.radiobutton_custom, 'Value', 0); + set(handles.edit_custom, 'Enable', 'off'); + set(handles.radiobutton_none, 'Value', 0); + elseif strcmpi(Baseline_method,'post') + set(handles.radiobutton_pre, 'Value', 0); + set(handles.radiobutton_post, 'Value', 1);%radiobutton_whole + set(handles.radiobutton_whole, 'Value', 0); + set(handles.radiobutton_custom, 'Value', 0); + set(handles.edit_custom, 'Enable', 'off'); + set(handles.radiobutton_none, 'Value', 0); + elseif strcmpi(Baseline_method,'whole') + set(handles.radiobutton_pre, 'Value', 0); + set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole + set(handles.radiobutton_whole, 'Value', 1); + set(handles.radiobutton_custom, 'Value', 0); + set(handles.edit_custom, 'Enable', 'off'); + set(handles.radiobutton_none, 'Value', 0); + elseif strcmpi(Baseline_method,'none') + set(handles.radiobutton_pre, 'Value', 0); + set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole + set(handles.radiobutton_whole, 'Value', 0); + set(handles.radiobutton_custom, 'Value', 0); + set(handles.edit_custom, 'Enable', 'off'); + set(handles.radiobutton_none, 'Value', 1); + else + set(handles.radiobutton_pre, 'Value', 0); + set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole + set(handles.radiobutton_whole, 'Value', 0); + set(handles.radiobutton_custom, 'Value', 0); + set(handles.edit_custom, 'Enable', 'off'); + set(handles.radiobutton_none, 'Value', 1); + end +end +% set(handles.edit_custom, 'String', pathName); +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_meas_basecorr_OutputFcn(hObject, eventdata, handles) +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + +function edit_custom_Callback(hObject, eventdata, handles) + +Baseline = str2num(handles.String); +if isempty(Baseline) || length(Baseline) ==1 + msgboxText = {'Invalid Baseline range!';'Please enter two numeric values'}; + title = 'EStudio: f_ERP_meas_basecorr() error: Baseline Period setting'; + errorfound(msgboxText, title); + return; +end + + + + +% --- Executes during object creation, after setting all properties. +function edit_custom_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_pre. +function radiobutton_pre_Callback(hObject, eventdata, handles) +set(handles.radiobutton_pre, 'Value', 1); +set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole +set(handles.radiobutton_whole, 'Value', 0); +set(handles.radiobutton_custom, 'Value', 0); +set(handles.radiobutton_none, 'Value', 0); +set(handles.edit_custom, 'Enable', 'off'); + + +% --- Executes on button press in radiobutton_post. +function radiobutton_post_Callback(hObject, eventdata, handles) +set(handles.radiobutton_pre, 'Value', 0); +set(handles.radiobutton_post, 'Value', 1);%radiobutton_whole +set(handles.radiobutton_whole, 'Value', 0); +set(handles.radiobutton_custom, 'Value', 0); +set(handles.radiobutton_none, 'Value', 0); +set(handles.edit_custom, 'Enable', 'off'); + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +beep; +disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) + +if handles.radiobutton_none.Value + Baseline_corre = 'none'; +elseif handles.radiobutton_pre.Value + Baseline_corre = 'pre'; +elseif handles.radiobutton_post.Value + Baseline_corre = 'post'; +elseif handles.radiobutton_whole.Value + Baseline_corre = 'whole'; +elseif handles.radiobutton_custom.Value + + Baseline_corre = str2num(handles.edit_custom.String); + if isempty(Baseline_corre) || length(Baseline_corre) ==1 + msgboxText = {'Invalid Baseline range!';'Please enter two numeric values'}; + title = 'EStudio: f_ERP_meas_basecorr() error: Baseline Period setting'; + errorfound(msgboxText, title); + return; + elseif Baseline_corre(1)>=Baseline_corre(2) + msgboxText = ['EStudio says: The first latency should be smaller than the seocnd one.']; + title = 'EStudio: f_ERP_meas_basecorr() error: Baseline Period setting'; + errorfound(sprintf(msgboxText), title); + return; + end + Baseline_corre = handles.edit_custom.String; +else + Baseline_corre = 'none'; + +end + +handles.output = Baseline_corre; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes on button press in radiobutton_whole. +function radiobutton_whole_Callback(hObject, eventdata, handles) +set(handles.radiobutton_pre, 'Value', 0); +set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole +set(handles.radiobutton_whole, 'Value', 1); +set(handles.radiobutton_custom, 'Value', 0); +set(handles.radiobutton_none, 'Value', 0); +set(handles.edit_custom, 'Enable', 'off'); + +% --- Executes on button press in radiobutton_custom. +function radiobutton_custom_Callback(hObject, eventdata, handles) +set(handles.radiobutton_pre, 'Value', 0); +set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole +set(handles.radiobutton_whole, 'Value', 0); +set(handles.radiobutton_custom, 'Value', 1); +set(handles.radiobutton_none, 'Value', 0); +set(handles.edit_custom, 'Enable', 'on'); + + +% --- Executes on button press in radiobutton_none. +function radiobutton_none_Callback(hObject, eventdata, handles) +set(handles.radiobutton_pre, 'Value', 0); +set(handles.radiobutton_post, 'Value', 0);%radiobutton_whole +set(handles.radiobutton_whole, 'Value', 0); +set(handles.radiobutton_custom, 'Value', 0); +set(handles.radiobutton_none, 'Value', 1); +set(handles.edit_custom, 'Enable', 'off'); +% Hint: get(hObject,'Value') returns toggle state of radiobutton_none diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.fig b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.fig new file mode 100755 index 00000000..ccf145b4 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.m b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.m new file mode 100755 index 00000000..fc043572 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_meas_format_path.m @@ -0,0 +1,275 @@ +function varargout = f_ERP_meas_format_path(varargin) +% F_ERP_MEAS_FORMAT_PATH MATLAB code for f_ERP_meas_format_path.fig +% F_ERP_MEAS_FORMAT_PATH, by itself, creates a new F_ERP_MEAS_FORMAT_PATH or raises the existing +% singleton*. +% +% H = F_ERP_MEAS_FORMAT_PATH returns the handle to a new F_ERP_MEAS_FORMAT_PATH or the handle to +% the existing singleton*. +% +% F_ERP_MEAS_FORMAT_PATH('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_MEAS_FORMAT_PATH.M with the given input arguments. +% +% F_ERP_MEAS_FORMAT_PATH('Property','Value',...) creates a new F_ERP_MEAS_FORMAT_PATH or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_meas_format_path_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_meas_format_path_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_meas_format_path + +% Last Modified by GUIDE v2.5 07-Aug-2022 18:19:42 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_meas_format_path_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_meas_format_path_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_meas_format_path is made visible. +function f_ERP_meas_format_path_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_meas_format_path + +try + foutputstr = varargin{1}; %% 1. long; 0 wide + pathName= varargin{2}; + +catch + foutputstr = 1; %% 1. long; 0 wide + pathName= cd; +end + +handles.output = []; +erpmenu = findobj('tag', 'erpsets'); +handles.pathName = pathName; +if ~isempty(erpmenu) + handles.menuerp = get(erpmenu); + set(handles.menuerp.Children, 'Enable','off'); +end + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - ERP Measurement Tool']) + + +set(handles.current_erp_label,'String', ['ERP Measurement Tool: File format and path'],... + 'FontWeight','Bold', 'FontSize', 16); +if foutputstr + set(handles.radiobutton_wide, 'Value', 1); + set(handles.radiobutton5_long, 'Value', 0); +else + set(handles.radiobutton_wide, 'Value', 0); + set(handles.radiobutton5_long, 'Value', 1); +end +set(handles.edit_filename, 'String', pathName); +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_meas_format_path_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +% try +% set(handles.menuerp.Children, 'Enable','on'); +% catch +% disp('ERPset menu was not found...') +% end +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + + + +% % --- Executes on button press in radio_erpname. +% function radio_erpname_Callback(hObject, eventdata, handles) +% % hObject handle to radio_erpname (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% +% % Hint: get(hObject,'Value') returns toggle state of radio_erpname +% Value_radio_erpname = get(hObject,'Value'); +% set(handles.radio_erpname, 'Value', 1); + + + +% % --- Executes on button press in radiobutton_saveas. +% function radiobutton_saveas_Callback(hObject, eventdata, handles) +% +% if get(hObject, 'Value') +% set(handles.edit_filename, 'Enable', 'on'); +% set(handles.filename_erpname, 'Enable', 'on'); +% set(handles.pushbutton_browse, 'Enable', 'on'); +% set(handles.erpname_filename, 'Enable', 'on'); +% else +% set(handles.edit_filename, 'Enable', 'off'); +% set(handles.filename_erpname, 'Enable', 'off'); +% set(handles.pushbutton_browse, 'Enable', 'off'); +% set(handles.erpname_filename, 'Enable', 'off'); +% set(handles.edit_filename, 'String', ''); +% end + + +function edit_filename_Callback(hObject, eventdata, handles) +% hObject handle to edit_filename (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit_filename as text +% str2double(get(hObject,'String')) returns contents of edit_filename as a double + + +% --- Executes during object creation, after setting all properties. +function edit_filename_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_filename (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in radiobutton_wide. +function radiobutton_wide_Callback(hObject, eventdata, handles) +% hObject handle to radiobutton_wide (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of radiobutton_wide +set(handles.radiobutton_wide, 'Value', 1); +set(handles.radiobutton5_long, 'Value', 0); + +% --- Executes on button press in radiobutton5_long. +function radiobutton5_long_Callback(hObject, eventdata, handles) +set(handles.radiobutton_wide, 'Value', 0); +set(handles.radiobutton5_long, 'Value', 1); + + + + + + +% --- Executes on button press in pushbutton_browse. +function pushbutton_browse_Callback(hObject, eventdata, handles) + +pathName = handles.pathName; + +title = 'Save output file as'; + +[filename, filepath,filterindex] = uiputfile({'*.txt'; '*.dat'}, ... + title,pathName); + +if isequal(filterindex,0) + disp('User selected Cancel'); + return; +else + [px, fname, ext] = fileparts(filename); + if strcmp(ext,'') + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; + end + end + Filename = [fname ext]; + set(handles.edit_filename,'String',fullfile(filepath,Filename)); +end + + + + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +beep; +disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) +Filename = strtrim(get(handles.edit_filename, 'String')); + +[px, fname, ext] = fileparts(Filename); +if isempty(fname) + msgboxText = 'You must enter a name for the saved file at least!'; + title = 'EStudio: f_ERP_save_single_file empty filename'; + errorfound(msgboxText, title); + return +end + + +Wide_fromat = (get(handles.radiobutton_wide, 'Value')); + +Long_fromat = (get(handles.radiobutton5_long, 'Value')); + + +if Wide_fromat + FileFormat = 1; +elseif Long_fromat + FileFormat = 0; +end + +handles.output = {FileFormat, Filename}; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_measurement_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_measurement_GUI.m new file mode 100755 index 00000000..b1da2e07 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_measurement_GUI.m @@ -0,0 +1,1579 @@ +%%% ERPLAB Studio: ERO meansurement panel + + +%Author: Guanghui ZHANG +%Center for Mind and Brain +% University of California, Davis +%Davis, CA +% 2022 + + +function varargout = f_ERP_measurement_GUI(varargin) + +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange); +% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'ERP_chan_change',@ERP_chan_changed); +addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERP_change); + +%%Get the parameters for pop_geterpvalues used in the last time. +def_erpvalue = erpworkingmemory('pop_geterpvalues'); + +try + ALLERP = evalin('base','ALLERP'); + CurrentERPSet = evalin('base','CURRENTERP'); +catch + return; +end + +if isstruct(ALLERP) + if ~iserpstruct(ALLERP(1)) + ALLERP = []; + nbinx = 1; + nchanx = 1; + else + nbinx = ALLERP(1).nbin; + nchanx = ALLERP(1).nchan; + end +else + ALLERP = []; + nbinx = 1; + nchanx = 1; +end + + + +if isempty(def_erpvalue) + if isempty(ALLERP) + inp1 = 1; %from hard drive + CurrentERPSet = []; + else + inp1 = 0; %from erpset menu + CurrentERPSet = 1:length(ALLERP); + end + + def_erpvalue = {inp1,CurrentERPSet,'',0,1:nbinx,1:nchanx,'meanbl',... + 1,3,'pre',1,1,5,0,0.5,0,0,0,'',0,1,1}; + +else + if ~isempty(ALLERP) + if isnumeric(def_erpvalue{2}) % JavierLC 11-17-11 + [uu, mm] = unique_bc2(def_erpvalue{2}, 'first'); + erpset_list_sorted = [def_erpvalue{2}(sort(mm))]; + %def_erpvalue{2} = def_erpvalue{2}(def_erpvalue{2}<=length(ALLERP)); + % non-empty check, axs jul17 + erpset_list = erpset_list_sorted(erpset_list_sorted<=length(ALLERP)); + if isempty(erpset_list) + % if nothing in list, just go with current + def_erpvalue{2} = CurrentERPSet; + else + def_erpvalue{2} = erpset_list; + end + + end + end +end + + +if def_erpvalue{11} == 0 + def_erpvalue{11} = 'off'; +else + def_erpvalue{11} = 'on'; +end + +if def_erpvalue{12} == 0 + def_erpvalue{12} = 'negative'; +else + def_erpvalue{12} = 'positive'; +end + +if def_erpvalue{14}==0 + def_erpvalue{14} = 'NaN'; +else + def_erpvalue{14} = 'absolute'; +end + +if def_erpvalue{16}==0 % Fractional area latency replacement + def_erpvalue{16} = 'NaN'; +else + if ismember_bc2({def_erpvalue{7}}, {'fareatlat', 'fninteglat','fareaplat','fareanlat'}) + def_erpvalue{16} = 'errormsg'; + else + def_erpvalue{16} = 'absolute'; + end +end + +if def_erpvalue{17} == 0 + def_erpvalue{17} = 'off'; +else + def_erpvalue{17} = 'on'; +end + +if def_erpvalue{18} == 0 + def_erpvalue{18} = 'wide'; +else + def_erpvalue{18} = 'long'; +end + + +if def_erpvalue{20} == 0 + def_erpvalue{20} = 'no'; +else + def_erpvalue{20} = 'yes'; +end + +% +S_IN = estudioworkingmemory('geterpvalues'); +if isempty(S_IN) + erpvalues_variables = {'geterpvalues','latency',def_erpvalue{4},... + 'binArray',def_erpvalue{5},... + 'chanArray', def_erpvalue{6},... + 'Erpsets', def_erpvalue{2},... + 'Measure',def_erpvalue{7},... + 'Component',def_erpvalue{8},... + 'Resolution', def_erpvalue{9},... + 'Baseline', def_erpvalue{10},... + 'Binlabel', def_erpvalue{11},... + 'Peakpolarity',def_erpvalue{12},... + 'Neighborhood', def_erpvalue{13},... + 'Peakreplace', def_erpvalue{14},... + 'Filename', def_erpvalue{3},... + 'Warning','on',... + 'SendtoWorkspace', def_erpvalue{17},... + 'Append', '',... + 'FileFormat', def_erpvalue{18},... + 'Afraction',def_erpvalue{15},... + 'Mlabel', def_erpvalue{19},... + 'Fracreplace', def_erpvalue{16},... + 'IncludeLat', def_erpvalue{20},... + 'InterpFactor', def_erpvalue{21},... + 'Viewer', 'off',... + 'PeakOnset',def_erpvalue{22},... + 'History', 'gui'}; + S_OUT = createrplabstudioparameters(S_IN,erpvalues_variables); + estudioworkingmemory('geterpvalues',S_OUT.geterpvalues); + S_IN = S_OUT.geterpvalues; +end +% end + + +EStudio_erp_m_t_p = S_IN; + + +%%---------------------------gui------------------------------------------- +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end +if nargin == 0 + fig = figure(); % Parent figure + erp_measurement_box = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Measurement Tool', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + erp_measurement_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Measurement Tool', 'Padding', 5,'BackgroundColor',ColorB_def); +else + erp_measurement_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Measurement Tool', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +ERPMTops = struct(); + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +erp_m_t_gui(FonsizeDefault); + + + +varargout{1} = erp_measurement_box; +%%********************Draw the GUI for ERP measurement tool***************** + function erp_m_t_gui(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + ERPMTops.mt = uiextras.VBox('Parent',erp_measurement_box,'Spacing',1,'BackgroundColor',ColorB_def); + try + SelectedIndex = EStudio_erp_m_t_p.Erpsets; + catch + SelectedIndex = observe_ERPDAT.CURRENTERP; + end + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + checked_curr_index = 1; + else + checked_curr_index = 0; + end + checked_ERPset_Index = f_checkerpsets(observe_ERPDAT.ALLERP,SelectedIndex); + if checked_curr_index || any(checked_ERPset_Index) + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + %%-----------------------Measurement type setting------------------- + ERPMTops.measurement_type = uiextras.Grid('Parent',ERPMTops.mt,'Spacing',1,'BackgroundColor',ColorB_def); + + %%1A + ERPMTops.measurement_type_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Type:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.measurement_type_title,'HorizontalAlignment','left'); + %%1B + ERPMTops.erpset_select_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','ERPset:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.erpset_select_title,'HorizontalAlignment','left'); + %%1C + ERPMTops.bin_select_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Bin:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.bin_select_title,'HorizontalAlignment','left'); + %%1D + ERPMTops.channel_select_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Channel:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.channel_select_title,'HorizontalAlignment','left'); + %%1E + ERPMTops.tw_set_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','Window:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.tw_set_title,'HorizontalAlignment','left'); + %%1F + ERPMTops.out_file_title = uicontrol('Style','text','Parent', ERPMTops.measurement_type,'String','File&Path:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.out_file_title,'HorizontalAlignment','left'); + + + %%-----------------------------Setting for second column--------------- + %%2A + mesurement_type = {'Mean amplitude between two fixed latencies','Local peak amplitude (Negative)','Local peak amplitude (Positive)','Local peak latency (Negative)',... + 'Local peak latency (Positive)','Fractional peak latency (Negative)','Fractional peak latency (Positive)','Fractional area latency: Rectified area (negative values become positive)',... + 'Fractional area latency: Numrical integration (area for negatives substracted from area for positives)',... + 'Fractional area latency: Area for negative waveforms (positive values will be zeroed)','Fractional area latency: Area for positive waveforms (negative values will be zeroed)',... + 'Numerical integration/Area between two fixed latencies: Rectified area (Negative values become positive)',... + 'Numerical integration/Area between two fixed latencies: Numerical intergration (area for negative substracted from area for positive)',... + 'Numerical integration/Area between two fixed latencies: Area for negative waveforms (positive values will be zeroed)',... + 'Numerical integration/Area between two fixed latencies: Area for positive waveforms (negative values will be zeroed)',... + 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Rectified area (Negative values become positive)',... + 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Numerical intergration (area for negative substracted from area for positive)',... + 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Area for negative waveforms (positive values will be zeroed)',... + 'Numerical integration/Area between two (automatically detected)zero-crossing latencies: Area for positive waveforms (negative values will be zeroed)',... + 'Instantaneous amplitude'}; + ERPMTops.m_t_type = uicontrol('Style', 'popup','Parent',ERPMTops.measurement_type,'String',mesurement_type,'callback',@Mesurement_type,'Enable',Enable_label,'FontSize',FonsizeDefault); + if isempty(EStudio_erp_m_t_p.Measure) || ~ischar(EStudio_erp_m_t_p.Measure) + EStudio_erp_m_t_p.Measure = 'meanbl'; + end + switch EStudio_erp_m_t_p.Measure%Find the label of the selected item, the defualt one is 1 (Mean amplitude between two fixed latencies) + case 'meanbl'% Mean amplitude + set(ERPMTops.m_t_type,'Value',1); + case 'peakampbl'% Local peak amplitude (P vs. N) + if strcmp(EStudio_erp_m_t_p.Peakpolarity,'positive') + set(ERPMTops.m_t_type,'Value',3); + else + set(ERPMTops.m_t_type,'Value',2); + end + case 'peaklatbl'%Peak latency (P vs. N) + if strcmp(EStudio_erp_m_t_p.Peakpolarity,'positive') + set(ERPMTops.m_t_type,'Value',5); + elseif strcmp(EStudio_erp_m_t_p.Peakpolarity,'negative') + set(ERPMTops.m_t_type,'Value',4); + end + case 'fpeaklat'%Fractional Peak latency (P vs. N) + if strcmp(EStudio_erp_m_t_p.Peakpolarity,'positive') + set(ERPMTops.m_t_type,'Value',7); + elseif strcmp(EStudio_erp_m_t_p.Peakpolarity,'negative') + set(ERPMTops.m_t_type,'Value',6); + end + + otherwise%if the measurement type comes from Advanced option + MeasureName_other = {'fareatlat','fninteglat','fareaplat','fareanlat',... + 'areat','ninteg','areap','arean',... + 'areazt','nintegz','areazp','areazn',... + 'instabl'}; + [C,IA] = ismember_bc2({EStudio_erp_m_t_p.Measure}, MeasureName_other); + if any(IA) || isempty(IA) + set(ERPMTops.m_t_type,'Value',1); + else + set(ERPMTops.m_t_type,'Value',IA+7); + end + end + + %%2B ERPset custom + SelectedERP_Index = estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) || max(SelectedERP_Index)> length(observe_ERPDAT.ALLERP) + ERPMTops.m_t_erpset = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', '','callback',@erpset_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); % + else + ERPMTops.m_t_erpset = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', num2str(vect2colon(SelectedERP_Index,'Sort','on')),'callback',@erpset_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + + %%2C + if isempty(EStudio_erp_m_t_p.binArray) + ERP_CURRENT = evalin('base','ERP'); + if isempty(ERP_CURRENT.nbin) || any(ERP_CURRENT.nbin) + ERPMTops.m_t_bin = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', [],'callback',@binSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); % + else + ERPMTops.m_t_bin = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String', num2str(vect2colon(1:ERP_CURRENT.nbin,'Sort','on')),'callback',@binSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + else + ERPMTops.m_t_bin = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(vect2colon(EStudio_erp_m_t_p.binArray,'Sort','on')),'callback',@binSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + %%2D + if isempty(EStudio_erp_m_t_p.chanArray) || ~any(EStudio_erp_m_t_p.chanArray) + try + ERP_CURRENT = evalin('base','ERP'); + if isempty(ERP_CURRENT.chanArray) || any(ERP_CURRENT.chanArray) + ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',[],'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault);%vect2colon(observe_ERPDAT.ERP_chan,'Sort', 'on') + else + ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(vect2colon(1:ERP_CURRENT.nchan,'Sort','on')),'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + catch + ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',[],'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + else + ERPMTops.m_t_chan = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(vect2colon(EStudio_erp_m_t_p.chanArray,'Sort','on')),'callback',@chanSelect_custom,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + %%2E + if isempty(EStudio_erp_m_t_p.latency) + ERPMTops.m_t_TW = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String','0.000','callback',@t_w_set,'Enable',Enable_label,'FontSize',FonsizeDefault); + else + ERPMTops.m_t_TW = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',num2str(EStudio_erp_m_t_p.latency),'callback',@t_w_set,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + %%2F + if isempty(EStudio_erp_m_t_p.Filename) + ERPMTops.m_t_file = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String','','callback',@file_name_set,'Enable',Enable_label,'FontSize',FonsizeDefault); + else + ERPMTops.m_t_file = uicontrol('Style', 'edit','Parent',ERPMTops.measurement_type,'String',EStudio_erp_m_t_p.Filename,'callback',@file_name_set,'Enable',Enable_label,'FontSize',FonsizeDefault); + end + + + %%-----------Setting for third column-------------------------------- + %%3A + ERPMTops.m_t_type_ops = uicontrol('Style', 'pushbutton','Parent',ERPMTops.measurement_type,'String','Option','callback',@Mesurement_type_option,'Enable',Enable_label,'FontSize',FonsizeDefault); + %%3B + ERPMTops.m_t_erpset_ops = uicontrol('Style','pushbutton','Parent', ERPMTops.measurement_type,'String','Option','callback',@erpsetop,'Enable',Enable_label,'FontSize',FonsizeDefault); + %%3C + ERPMTops.m_t_bin_ops = uicontrol('Style','pushbutton','Parent', ERPMTops.measurement_type,'String','Option','callback',@binSelect_label,'Enable',Enable_label,'FontSize',FonsizeDefault); + + %%3D + ERPMTops.m_t_chan_ops = uicontrol('Style','pushbutton','Parent', ERPMTops.measurement_type,'String','Option','callback',@chanSelect_label,'Enable',Enable_label,'FontSize',FonsizeDefault); + %%3E + ERPMTops.m_t_TW_ops = uicontrol('Style', 'pushbutton','Parent',ERPMTops.measurement_type,'String','Option','callback',@baseline_set,'Enable',Enable_label,'FontSize',FonsizeDefault); + %%3F + ERPMTops.m_t_file_ops = uicontrol('Style', 'pushbutton','Parent',ERPMTops.measurement_type,'String','Option','callback',@out_file_option,'Enable',Enable_label,'FontSize',FonsizeDefault); + set(ERPMTops.measurement_type, 'ColumnSizes',[65 135 65],'RowSizes',[25 25 25 25 25 25]); + + + %%-------------------------Setting for Viewer---------------------- + ERPMTops.mt_viewer = uiextras.HBox('Parent',ERPMTops.mt,'Spacing',1,'BackgroundColor',ColorB_def); + ERPMTops.m_t_viewer_title = uicontrol('Style', 'text','Parent', ERPMTops.mt_viewer,'String','Viewer:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(ERPMTops.m_t_viewer_title,'HorizontalAlignment','left'); + ERPMTops.m_t_viewer_on = uicontrol('Style', 'radiobutton','Parent', ERPMTops.mt_viewer,'String','On',... + 'callback',@m_t_viewer_on,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + ERPMTops.m_t_viewer_off = uicontrol('Style', 'radiobutton','Parent', ERPMTops.mt_viewer,'String','Off',... + 'callback',@m_t_viewer_off,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + ERPMTops.m_t_viewer_on.Value = 1; + ERPMTops.m_t_viewer_off.Value =0; + elseif strcmp(EStudio_erp_m_t_p.Viewer,'off') + ERPMTops.m_t_viewer_on.Value = 0; + ERPMTops.m_t_viewer_off.Value =1; + + end + uiextras.Empty('Parent', ERPMTops.mt_viewer,'BackgroundColor',ColorB_def); % 1A + set(ERPMTops.mt_viewer,'Sizes',[70 60 60 70]); + + %%---------------------------Select ERPsets and Run options----------- + ERPMTops.out_file_run = uiextras.HBox('Parent',ERPMTops.mt,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', ERPMTops.out_file_run); + uicontrol('Style', 'pushbutton','Parent',ERPMTops.out_file_run,'String','?','callback',@ERPmeasr_help,'Enable','on','FontSize',16); + uiextras.Empty('Parent', ERPMTops.out_file_run); + ERPMTops.m_t_value = uicontrol('Style', 'pushbutton','Parent',ERPMTops.out_file_run,'String','Save values','callback',@apply_erp_m_t,'Enable',Enable_label,'FontSize',FonsizeDefault); + uiextras.Empty('Parent', ERPMTops.out_file_run); + set(ERPMTops.out_file_run, 'Sizes',[15 105 20 105 15]); + + %%ERPMTops end + set(ERPMTops.mt,'Sizes',[150 25 30]); + end + +%%**************************************************************************************************************************************** +%%******************* Subfunctions *************************************************************************************************** +%%**************************************************************************************************************************************** + +%%-----------------Help------------------------------ + function ERPmeasr_help(~,~) + web('https://github.com/lucklab/erplab/wiki/ERP-Measurement-Tool','-browser'); + end + +%%---------------------------Setting for the Measurement type-----------------------------%% + function Mesurement_type(source_measure_type,~) + Select_label = source_measure_type.Value; + if isempty(Select_label) + EStudio_erp_m_t_p.Measure = 'meanbl'; + elseif Select_label==1 % Mean amplitude + EStudio_erp_m_t_p.Measure = 'meanbl'; + elseif Select_label==2 %Peak amplitude + EStudio_erp_m_t_p.Measure ='peakampbl'; + EStudio_erp_m_t_p.Peakpolarity = 'negative'; + elseif Select_label==3 % Peak amplitude + EStudio_erp_m_t_p.Measure ='peakampbl'; + EStudio_erp_m_t_p.Peakpolarity = 'positive'; + elseif Select_label==4 % Peak latency + EStudio_erp_m_t_p.Measure = 'peaklatbl'; + EStudio_erp_m_t_p.Peakpolarity = 'negative'; + elseif Select_label==5 %Peak latency + EStudio_erp_m_t_p.Measure = 'peaklatbl'; + EStudio_erp_m_t_p.Peakpolarity = 'positive'; + + elseif Select_label==6 %Fractional Peak latency + EStudio_erp_m_t_p.Measure ='fpeaklat'; + EStudio_erp_m_t_p.Peakpolarity = 'negative'; + elseif Select_label==7 %Fractional Peak latency + EStudio_erp_m_t_p.Measure ='fpeaklat'; + EStudio_erp_m_t_p.Peakpolarity = 'positive'; + else + if Select_label > 7 + MeasureName_other = {'fareatlat','fninteglat','fareanlat','fareaplat',... + 'areat','ninteg','arean','areap',... + 'areazt','nintegz','areazn','areazp',... + 'instabl'}; + EStudio_erp_m_t_p.Measure = MeasureName_other{Select_label-7}; + if 15 < Select_label && Select_label<20 + mnamex = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'; + question = [ '%s\n\nThis tool is still in alpha phase.\n'... + 'Use it under your responsibility.']; + title = 'ERPLAB Studio: Overwriting Confirmation'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + end + else + EStudio_erp_m_t_p.Measure = 'meanbl'; + end + end + + S_ws = estudioworkingmemory('geterpvalues'); + S_ws.Measure = EStudio_erp_m_t_p.Measure; + S_ws.Peakpolarity = EStudio_erp_m_t_p.Peakpolarity; + estudioworkingmemory('geterpvalues',S_ws); + + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + + moption = EStudio_erp_m_t_p.Measure; + latency = EStudio_erp_m_t_p.latency; + if isempty(moption) + beep; + msgboxText = ['ERP Measurement Tool - User must specify a type of measurement']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + beep; + msgboxText = ['ERP Measurement Tool - ',32,moption ' only needs 1 latency value.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + + end + else + if length(latency)~=2 + beep; + msgboxText = ['ERP Measurement Tool - ',32,moption ' only needs 2 latency values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + if latency(1)>=latency(2) + beep; + msgboxText = ['ERP Measurement Tool - For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + end + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + end + + +%%------------Options for the measurement type----------------------------- + function Mesurement_type_option(~,~) + try + S_ws = estudioworkingmemory('geterpvalues'); + EStudio_erp_m_t_p.Measure = S_ws.Measure; + catch + beep; + msgboxText = ['ERP Measurement Tool - None of measure types was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + try + op = S_ws.Measure; + catch + op= 'meanbl'; + end% option: type of measurement ---> instabl, meanbl, peakampbl, peaklatbl, area, areaz, or errorbl. + try + dig = S_ws.Resolution; + catch + dig =3; + end%Resolution + try + Binlabel = S_ws.Binlabel; + catch + Binlabel = 'off'; + end + if strcmpi(Binlabel,'off') + binlabop = 0; % 0: bin# as bin label for table, 1 bin label + else + binlabop = 1; + end + try + Peakpolarity = S_ws.Peakpolarity; + catch + Peakpolarity = 'negative'; + end + if strcmpi(Peakpolarity,'negative') + polpeak = 0; + else + polpeak = 1; % local peak positive polarity + end + try + sampeak = S_ws.Neighborhood; % number of samples (one-side) for local peak detection criteria + catch + sampeak = 3; + end + try + Peakreplace = S_ws.Peakreplace; + catch + Peakreplace = 'absolute'; + end + if strcmpi(Peakreplace,'absolute') + locpeakrep = 1; + else + locpeakrep = 0; % 1 abs peak , 0 Nan + end + try + frac = S_ws.Afraction; + catch + frac = 0.5; + end + try + Fracreplace = S_ws.Fracreplace; + catch + Fracreplace = 'NaN'; + end + + if strcmpi(Fracreplace,'NaN') + fracmearep = 0; % def{19}; NaN + else + fracmearep = 1; % def{19}; NaN + end + try + SendtoWorkspace = S_ws.SendtoWorkspace; + catch + SendtoWorkspace = 'off'; + end + if strcmpi(SendtoWorkspace,'off') + send2ws = 0; % 1 send to ws, 0 dont do + else + send2ws = 1; + end + try + IncludeLat = S_ws.IncludeLat ; + catch + IncludeLat = 'off'; + end + if strcmpi(IncludeLat,'on') + + inclate = 1; + else + inclate = 0; + end + try + intfactor = S_ws.InterpFactor; + catch + intfactor = 10; + end + try + peakonset =S_ws.PeakOnset; + catch + peakonset = 1; + end + + %%Change the modified parameters after the subfucntion was called + def = { op ,dig,binlabop,polpeak,sampeak,locpeakrep,frac,fracmearep,send2ws,inclate,intfactor,peakonset}; + ERP= observe_ERPDAT.ERP; + Answer = geterpvaluesparasGUI2(def,ERP); + + if isempty(Answer) + beep; + disp('User selected cancel'); + return; + end + S_ws.Measure = Answer{1}; + S_ws.Resolution=Answer{2}; + binlabop = Answer{3}; + if binlabop + S_ws.Binlabel = 'on'; + else + S_ws.Binlabel = 'off'; + end + + polpeak= Answer{4}; + if polpeak==0 + S_ws.Peakpolarity = 'negative'; + else + S_ws.Peakpolarity = 'positive'; + end + + S_ws.Neighborhood = Answer{5}; + + locpeakrep = Answer{6}; + if locpeakrep==0 + S_ws.Peakreplace = 'NaN'; + else + S_ws.Peakreplace = 'absolute'; + end + + S_ws.Afraction = Answer{7}; + + fracmearep= Answer{8}; + if fracmearep==0 % Fractional area latency replacement + S_ws.Fracreplace = 'NaN'; + else + if ismember_bc2({S_ws.Measure}, {'fareatlat', 'fninteglat','fareaplat','fareanlat'}) + S_ws.Fracreplace = 'errormsg'; + else + S_ws.Fracreplace = 'absolute'; + end + end + send2ws = Answer{9}; + if send2ws + S_ws.SendtoWorkspace = 'on'; + else + S_ws.SendtoWorkspace = 'off'; + end + inclate = Answer{10}; + if inclate + S_ws.IncludeLat = 'on' ; + else + S_ws.IncludeLat = 'off' ; + end + S_ws.InterpFactor=Answer{11}; + S_ws.PeakOnset = Answer{12}; + estudioworkingmemory('geterpvalues',S_ws); + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + + moption = EStudio_erp_m_t_p.Measure; + latency = EStudio_erp_m_t_p.latency; + if isempty(moption) + beep; + msgboxText = ['ERP Measurement Tool - User must specify a type of measurement']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + beep; + msgboxText = ['ERP Measurement Tool - ',32,moption ' only needs 1 latency value']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + else + if length(latency)~=2 + beep; + msgboxText = ['ERP Measurement Tool - ',32,moption ' needs 2 latency values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + if latency(1)>=latency(2) + beep; + msgboxText = ['ERP Measurement Tool - For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + end + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + + end + +%%----------------------------ERPset custom-------------------------------- + function erpset_custom(Source,~) + ERPsetArray = str2num(Source.String); + ERPsetArraydef = estudioworkingmemory('selectederpstudio'); + if isempty(ERPsetArray) || max(ERPsetArray)> length(observe_ERPDAT.ALLERP) + if isempty(ERPsetArraydef) || max(ERPsetArraydef)> length(observe_ERPDAT.ALLERP) + Source.String = ''; + else + Source.String = num2str(vect2colon(ERPsetArraydef,'Sort','on')); + end + return; + else + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,ERPsetArray); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + Current_ERP_selected=ERPsetArray(1); + observe_ERPDAT.CURRENTERP = Current_ERP_selected; + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_ERP_selected); + + estudioworkingmemory('selectederpstudio',ERPsetArray); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + + end + +%%-------------Select bins by user custom---------------------------------- + function binSelect_custom(source,~) + binNums = str2num(source.String); + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, binNums, [],1); + + if chk(1) + binArray= observe_ERPDAT.ERP_bin; + source.String = num2str(binArray); + + beep; + msgboxText = ['ERP Measurement Tool -',32,msgboxText]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if ~isempty(binNums) + binNums = unique_bc2(binNums); + binList = 1:observe_ERPDAT.ERP.nbin; + indxlistb = binNums; + [~,y_check_bin] =find(indxlistb>observe_ERPDAT.ERP.nbin); + if any(y_check_bin) + mnamex = ['Label of one of the imported bins was higher than the number of bins (',num2str(observe_ERPDAT.ERP.nbin),').']; + question = [ '%s\n\n Please input or select bins of interst from "Bin:" on the "ERP Measurement Tool" panel again.\n']; + title = 'EStudio: ERP Measurement Tool'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + return; + end + + indxlistb = indxlistb(indxlistb<=length(binList)); + EStudio_erp_m_t_p.binArray = indxlistb; + S_ws= estudioworkingmemory('geterpvalues'); + if isempty(S_ws) + return; + end + S_ws.binArray = EStudio_erp_m_t_p.binArray; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + %Remark the selected bin in bin and Channel selection + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + SelectedERP_Index = estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',SelectedERP_Index); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + Bin_label_select = indxlistb; + if isempty(Bin_label_select) + beep; + disp(['No bin was selected']); + return; + end + if S_binchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets + S_binchan.bins{Select_index} = Bin_label_select; + S_binchan.bin_n(Select_index) = numel(Bin_label_select); + else + + for Numofselecterp = 1:numel(SelectedERP_Index) + S_binchan.bins{Numofselecterp} = Bin_label_select; + S_binchan.bin_n(Numofselecterp) = numel(Bin_label_select); + end + + end + estudioworkingmemory('geterpbinchan',S_binchan); + end + observe_ERPDAT.ERP_bin = indxlistb; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + end + + +%%----------------Option for erpset---------------------------------------- + function erpsetop(~,~) + ERPsetArraydef = estudioworkingmemory('selectederpstudio'); + if isempty(ERPsetArraydef) || max(ERPsetArraydef)> length(observe_ERPDAT.ALLERP) + ERPsetArraydef = observe_ERPDAT.CURRENTERP; + end + for Numoferpset = 1:length(observe_ERPDAT.ALLERP) + listname{Numoferpset} = char(strcat(num2str(Numoferpset),'.',observe_ERPDAT.ALLERP(Numoferpset).erpname)); + end + indxlistb =ERPsetArraydef; + + titlename = 'Select ERPset(s):'; + ERPset_select = browsechanbinGUI(listname, indxlistb, titlename); + + if ~isempty(ERPset_select) + ERPMTops.m_t_erpset.String = num2str(vect2colon(ERPset_select,'Sort','on')); + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,ERPset_select); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + Current_ERP_selected=ERPset_select(1); + observe_ERPDAT.CURRENTERP = Current_ERP_selected; + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(Current_ERP_selected); + estudioworkingmemory('selectederpstudio',ERPset_select); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + else + return; + end + + end + + + +%%---------------Bins selection from "Option"------------------------------ + function binSelect_label(Source,~) + ERP_CURRENT = evalin('base','ERP'); + for Numofbin = 1:length(ERP_CURRENT.bindescr) + listb{Numofbin} = char(strcat(num2str(Numofbin),'.',ERP_CURRENT.bindescr{Numofbin})); + end + try + indxlistb =EStudio_erp_m_t_p.binArray; + catch + indxlistb = 1:ERP_CURRENT.nbin; + end + titlename = 'Select Bin(s):'; + %----------------judge the number of latency/latencies-------- + if ~isempty(listb) + bin_label_select = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(bin_label_select) + EStudio_erp_m_t_p.binArray = bin_label_select; + ERPMTops.m_t_bin.String=num2str(vect2colon(EStudio_erp_m_t_p.binArray,'Sort', 'on')); + else + disp('User selected Cancel'); + return + end + else + beep; + msgboxText = ['ERP Measurement Tool - No bin information was found']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end%Program end: Judge the number of latency/latencies + S_ws= estudioworkingmemory('geterpvalues'); + if isempty(S_ws) + return; + end + + S_ws.binArray = EStudio_erp_m_t_p.binArray; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + %Remark the selected bin in bin and Channel selection + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + SelectedERP_Index = estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',SelectedERP_Index); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + Bin_label_select = bin_label_select; + if isempty(Bin_label_select) + beep; + disp(['No bin was selected']); + return; + end + EStudio_erp_m_t_p.binArray = bin_label_select; + if S_binchan.checked_ERPset_Index(1) ==1% The number of bins varied across the selected erpsets + S_binchan.bins{Select_index} = Bin_label_select; + S_binchan.bin_n(Select_index) = numel(Bin_label_select); + else + for Numofselecterp = 1:numel(SelectedERP_Index) + S_binchan.bins{Numofselecterp} = Bin_label_select; + S_binchan.bin_n(Numofselecterp) = numel(Bin_label_select); + end + end + estudioworkingmemory('geterpbinchan',S_binchan); + end + observe_ERPDAT.ERP_bin = bin_label_select; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + + +%%----------------Define the channels of interest---------------------- + function chanSelect_custom(Source,~) + chanNums = str2num(Source.String); + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, [], chanNums,2); + + if chk(2) + chanArray= observe_ERPDAT.ERP_chan; + Source.String = num2str(chanArray); + beep; + msgboxText = ['ERP Measurement Tool -',32,msgboxText]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if ~isempty(chanNums) + chanNums = unique_bc2(chanNums); + chanList = 1:observe_ERPDAT.ERP.nchan; + indxlist_chan = chanNums; + + [~,y_check_bin] =find(indxlist_chan>observe_ERPDAT.ERP.nchan); + if any(y_check_bin) + mnamex = ['Label of one of the imported channels was higher than the number of channels (',num2str(observe_ERPDAT.ERP.nchan),').']; + question = [ '%s\n\n Please input or select bins of interst from "Channel:" on the "ERP Measurement Tool" panel again.\n']; + title = 'ERPLAB Studio: ERP Measurement Tool'; + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + return; + end + + indxlist_chan = indxlist_chan(indxlist_chan<=length(chanList)); + EStudio_erp_m_t_p.chanArray = indxlist_chan; + S_ws= estudioworkingmemory('geterpvalues'); + if isempty(S_ws) + return; + end + S_ws.chanArray = EStudio_erp_m_t_p.chanArray; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + %When the "Viewer" is active on the measurement Tool panel--------- + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + SelectedERP_Index = estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',SelectedERP_Index); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + chan_label_select = indxlist_chan; + + if S_binchan.checked_ERPset_Index(2) ==2%% the number of channels varied across ERPsets + S_binchan.elecs_shown{S_binchan.Select_index} = chan_label_select; + S_binchan.elec_n(Select_index) = numel(chan_label_select); + S_binchan.first_elec(Select_index) = chan_label_select(1); + else + + for Numofselecterp = 1:numel(SelectedERP_Index) + S_binchan.elecs_shown{Numofselecterp} = chan_label_select; + S_binchan.elec_n(Numofselecterp) = numel(chan_label_select); + S_binchan.first_elec(Numofselecterp) = chan_label_select(1); + end + + end + estudioworkingmemory('geterpbinchan',S_binchan); + end + observe_ERPDAT.ERP_chan = indxlist_chan; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + + end + + +%%----------------Channels selection from option-------------------------------------- + function chanSelect_label(Source,~) + ERP_CURRENT = evalin('base','ERP'); + + if isempty(ERP_CURRENT.nchan) || ERP_CURRENT.nchan ==0 + beep; + msgboxText = ['ERP Measurement Tool -No channel information was found']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + for Numofchan = 1:ERP_CURRENT.nchan + listb{Numofchan}= strcat(num2str(Numofchan),'.',ERP_CURRENT.chanlocs(Numofchan).labels); + end + try + indxlistb= EStudio_erp_m_t_p.chanArray ; + catch + indxlistb = 1:ERP_CURRENT.nchan; + end + titlename = 'Select Channel(s):'; + + if ~isempty(listb) + chan_label_select = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(chan_label_select) + EStudio_erp_m_t_p.chanArray = chan_label_select; + %%%Save the changed parameters + S_ws= estudioworkingmemory('geterpvalues'); + if isempty(S_ws) + return; + end + + S_ws.chanArray = EStudio_erp_m_t_p.chanArray; + estudioworkingmemory('geterpvalues',S_ws); clear S_ws; + ERPMTops.m_t_chan.String=num2str(vect2colon(EStudio_erp_m_t_p.chanArray,'Sort', 'on')); + else + beep; + disp('User selected Cancel'); + return + end + else + beep; + msgboxText = ['ERP Measurement Tool -No channel information was found']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + %When the "Viewer" is active on the measurement Tool panel--------- + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + SelectedERP_Index = estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',SelectedERP_Index); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + if isempty(chan_label_select) + beep; + disp(['No channel was selected']); + return; + end + if S_binchan.checked_ERPset_Index(2) ==2%% the number of channels varied across ERPsets + S_binchan.elecs_shown{S_binchan.Select_index} = chan_label_select; + S_binchan.elec_n(Select_index) = numel(chan_label_select); + S_binchan.first_elec(Select_index) = chan_label_select(1); + else + + for Numofselecterp = 1:numel(SelectedERP_Index) + S_binchan.elecs_shown{Numofselecterp} = chan_label_select; + S_binchan.elec_n(Numofselecterp) = numel(chan_label_select); + S_binchan.first_elec(Numofselecterp) = chan_label_select(1); + end + end + estudioworkingmemory('geterpbinchan',S_binchan); + end + chanArray = str2num(ERPMTops.m_t_chan.String); + if ~isempty(chanArray) + observe_ERPDAT.ERP_chan = chanArray; + end + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + +%%-----------------Measurement time-window-------------------------------%% + function t_w_set(source_tw,~) + if isempty(str2num(source_tw.String)) + beep; + msgboxText = ['ERP Measurement Tool -No measurement window was set']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + lat_erp = unique_bc2(str2num(source_tw.String)); + EStudio_erp_m_t_p.latency = lat_erp; + moption = EStudio_erp_m_t_p.Measure; + latency = EStudio_erp_m_t_p.latency; + if isempty(moption) + beep; + msgboxText = ['ERP Measurement Tool - User must specify a type of measurement']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + beep; + msgboxText = ['ERP Measurement Tool -',32,moption ' only needs 1 latency value']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + else + if length(latency)~=2 + beep; + msgboxText = ['ERP Measurement Tool -',32,moption ' needs 2 latency values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + if latency(1)>=latency(2) + beep; + msgboxText = ['ERP Measurement Tool -For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + end + + + S_ws= estudioworkingmemory('geterpvalues'); + if isempty(S_ws) + return; + end + S_ws.latency = lat_erp; + estudioworkingmemory('geterpvalues',S_ws); clear S_ws; + + end + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + end + + +%-------------------------Baseline period--------------------------------- + function baseline_set(~,~) + try + S_ws=estudioworkingmemory('geterpvalues'); + Answer = f_ERP_meas_basecorr(S_ws.Baseline); + catch + Answer = f_ERP_meas_basecorr('none'); + end + + if isempty(Answer) + beep; + disp('User selected cancel'); + return; + end + ERP_times = observe_ERPDAT.ERP.times; + latency = str2num(Answer); + if ~isempty(latency) + if latency(1)>=latency(2) + beep; + msgboxText = ['ERP Measurement Tool - The first latency should be smaller than the second one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(1)< ERP_times(1) + beep; + msgboxText = ['ERP Measurement Tool - The defined first latency should be larger than',32, num2str(ERP_times(1)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(2)> ERP_times(end) + beep; + msgboxText = ['ERP Measurement Tool - The defined second latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(1)> ERP_times(end) + beep; + msgboxText = ['ERP Measurement Tool - The defined first latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + S_ws= estudioworkingmemory('geterpvalues'); + S_ws.Baseline = Answer; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + + if strcmp(EStudio_erp_m_t_p.Viewer,'on') + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + end + +%%------------------File name setting for the output file.---------------- + function file_name_set(source_file_name,~) + EStudio_erp_m_t_p.Filename = source_file_name.String; + S_ws=estudioworkingmemory('geterpvalues'); + S_ws.Filename = source_file_name.String; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + end + +%%-------------------Path setting to save the measurement results---------- + function out_file_option(~,~) + if strcmp(EStudio_erp_m_t_p.FileFormat,'wide') + FileFormat = 0; + else + FileFormat = 1; + end + pathName_folder_default = erpworkingmemory('ERP_save_folder'); + FileName = EStudio_erp_m_t_p.Filename; + [pathNamex, fname, ext] = fileparts(FileName); + Answer = f_ERP_meas_format_path(FileFormat,fullfile(pathName_folder_default,fname)); + + if isempty(Answer) + disp('User selected Cancel'); + return; + + end + if Answer{1}==1 % 1 means "long format"; 0 means "wide format" + foutputstr = 'long'; + else + foutputstr = 'wide'; + end + + S_ws=estudioworkingmemory('geterpvalues'); + S_ws.Filename = Answer{2}; + S_ws.FileFormat = foutputstr; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + + EStudio_erp_m_t_p.FileFormat = foutputstr; + EStudio_erp_m_t_p.Filename = Answer{2}; + ERPMTops.m_t_file.String = EStudio_erp_m_t_p.Filename; + + end + + +%%---------------Viewer:ON------------------------------ + function m_t_viewer_on(~,~) + Source_value = 1; + set(ERPMTops.m_t_viewer_on,'Value',Source_value); + set(ERPMTops.m_t_viewer_off,'Value',~Source_value); + EStudio_erp_m_t_p.Viewer = 'on'; + S_ws= estudioworkingmemory('geterpvalues'); + S_ws.Viewer = EStudio_erp_m_t_p.Viewer; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + +%%---------------Viewer:Off------------------------------ + function m_t_viewer_off(~,~) + Source_value = 1; + set(ERPMTops.m_t_viewer_off,'Value',Source_value); + set(ERPMTops.m_t_viewer_on,'Value',~Source_value); + EStudio_erp_m_t_p.Viewer = 'off'; + S_ws=estudioworkingmemory('geterpvalues'); + S_ws.Viewer = EStudio_erp_m_t_p.Viewer; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + + +%%--------------------Apply the set parameters to selected ERPset---------- + function apply_erp_m_t(~,~) + pathName_folder = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_folder) + pathName_folder = cd; + end + + EStudio_erp_m_t_p =estudioworkingmemory('geterpvalues'); + if isempty(EStudio_erp_m_t_p) + EStudio_erp_m_t_p =EStudio_erp_m_t_p; + return; + end + + SelectedERP_Index = estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP_Index) + SelectedERP_Index = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP_Index); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',SelectedERP_Index); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + + EStudio_erp_m_t_p.Erpsets = SelectedERP_Index; + + MeasureName = {'meanbl','peakampbl', 'peaklatbl','fareatlat','fpeaklat','fninteglat','fareaplat','fareanlat',... + 'areat','ninteg','areap','arean','areazt','nintegz','areazp','areazn','instabl'}; + [C,IA] = ismember_bc2({EStudio_erp_m_t_p.Measure}, MeasureName); + if ~any(IA) || isempty(IA) + IA =1; + end + if isempty(EStudio_erp_m_t_p.Filename) + beep; + msgboxText = ['ERP Measurement Tool - Please set a name for the output file']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if isempty(EStudio_erp_m_t_p.latency) + beep; + msgboxText = ['ERP Measurement Tool - Please set a Measurement window']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + moption = EStudio_erp_m_t_p.Measure; + latency = EStudio_erp_m_t_p.latency; + if isempty(moption) + beep; + msgboxText = ['ERP Measurement Tool - User must specify a type of measurement']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + beep; + msgboxText = ['ERP Measurement Tool - ',32, moption ' only needs 1 latency value']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + else + if length(latency)~=2 + beep; + msgboxText = ['ERP Measurement Tool - ',32,moption ' needs 2 latency values.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + if latency(1)>=latency(2) + beep; + msgboxText = ['ERP Measurement Tool - For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + end + ALLERP = evalin('base','ALLERP'); + + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, EStudio_erp_m_t_p.binArray, [],1); + + if chk(1) + beep; + msgboxText = ['ERP Measurement Tool - ',32,msgboxText]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, [], EStudio_erp_m_t_p.chanArray,2); + + if chk(2) + beep; + msgboxText = ['ERP Measurement Tool - ',32,msgboxText]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + FileName = EStudio_erp_m_t_p.Filename; + [pathNamex, fname, ext] = fileparts(FileName); + if isempty(fname) + beep; + msgboxText = ['ERP Measurement Tool - Please give a name to the output file']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if isempty(pathNamex) + EStudio_erp_m_t_p.Filename = fullfile(pathName_folder,fname); + end + + + erpworkingmemory('f_ERP_proces_messg',' ERP Measurement Tool (Save values)'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + + try + if ~isempty(EStudio_erp_m_t_p.latency) + % + [ALLERP, Amp, Lat, erpcom] = pop_geterpvalues(ALLERP, EStudio_erp_m_t_p.latency, EStudio_erp_m_t_p.binArray, EStudio_erp_m_t_p.chanArray,... + 'Erpsets', EStudio_erp_m_t_p.Erpsets, 'Measure',MeasureName{IA}, 'Component', EStudio_erp_m_t_p.Component,... + 'Resolution', EStudio_erp_m_t_p.Resolution, 'Baseline', EStudio_erp_m_t_p.Baseline, 'Binlabel', EStudio_erp_m_t_p.Binlabel,... + 'Peakpolarity',EStudio_erp_m_t_p.Peakpolarity, 'Neighborhood', EStudio_erp_m_t_p.Neighborhood, 'Peakreplace', EStudio_erp_m_t_p.Peakreplace,... + 'Filename', EStudio_erp_m_t_p.Filename, 'Warning',EStudio_erp_m_t_p.Warning,'SendtoWorkspace', EStudio_erp_m_t_p.SendtoWorkspace, 'Append', EStudio_erp_m_t_p.Append,... + 'FileFormat', EStudio_erp_m_t_p.FileFormat,'Afraction', EStudio_erp_m_t_p.Afraction, 'Mlabel', EStudio_erp_m_t_p.Mlabel,... + 'Fracreplace', EStudio_erp_m_t_p.Fracreplace,'IncludeLat', EStudio_erp_m_t_p.IncludeLat, 'InterpFactor', EStudio_erp_m_t_p.InterpFactor,... + 'PeakOnset',EStudio_erp_m_t_p.PeakOnset,'History', 'gui'); + %%%------------Save history to current session-------------- + ALLERPCOM = evalin('base','ALLERPCOM'); + [~, ALLERPCOM] = erphistory(observe_ERPDAT.ERP, ALLERPCOM, erpcom); + assignin('base','ALLERPCOM',ALLERPCOM); + + %%---------------save the applied parameters using erpworkingmemory function-------------------- + EStudio_erp_m_t_p_save = EStudio_erp_m_t_p; + if strcmp(EStudio_erp_m_t_p_save.Binlabel,'off') + EStudio_erp_m_t_p_save.Binlabel = 0; + else + EStudio_erp_m_t_p_save.Binlabel = 1; + end + + if strcmp(EStudio_erp_m_t_p_save.Peakpolarity,'negative') + EStudio_erp_m_t_p_save.Peakpolarity = 0; + else + EStudio_erp_m_t_p_save.Peakpolarity = 1; + end + + if strcmp(EStudio_erp_m_t_p_save.Peakreplace,'NaN') + EStudio_erp_m_t_p_save.Peakreplace = 0; + else + EStudio_erp_m_t_p_save.Peakreplace = 1; + end + + if strcmp(EStudio_erp_m_t_p_save.Fracreplace,'NaN') % Fractional area latency replacement + EStudio_erp_m_t_p_save.Fracreplace = 0; + else + EStudio_erp_m_t_p_save.Fracreplace = 1; + end + + if strcmp(EStudio_erp_m_t_p_save.SendtoWorkspace,'off') + EStudio_erp_m_t_p_save.SendtoWorkspace=0; + else + EStudio_erp_m_t_p_save.SendtoWorkspace=1; + end + + if strcmp(EStudio_erp_m_t_p_save.FileFormat,'wide') + EStudio_erp_m_t_p_save.FileFormat = 0; + else + EStudio_erp_m_t_p_save.FileFormat = 1; + end + + if strcmp(EStudio_erp_m_t_p_save.IncludeLat,'no') + EStudio_erp_m_t_p_save.IncludeLat = 0; + else + EStudio_erp_m_t_p_save.IncludeLat = 1; + end + + erpworkingmemory('pop_geterpvalues', {CurrentERPSet, EStudio_erp_m_t_p_save.Erpsets, EStudio_erp_m_t_p_save.Filename, EStudio_erp_m_t_p_save.latency,... + EStudio_erp_m_t_p_save.binArray, EStudio_erp_m_t_p_save.chanArray, EStudio_erp_m_t_p_save.Measure, EStudio_erp_m_t_p_save.Component, EStudio_erp_m_t_p_save.Resolution, EStudio_erp_m_t_p_save.Baseline,... + EStudio_erp_m_t_p_save.Binlabel, EStudio_erp_m_t_p_save.Peakpolarity,EStudio_erp_m_t_p_save.Neighborhood, EStudio_erp_m_t_p_save.Peakreplace,... + EStudio_erp_m_t_p_save.Afraction, EStudio_erp_m_t_p_save.Fracreplace,EStudio_erp_m_t_p_save.SendtoWorkspace, EStudio_erp_m_t_p_save.FileFormat, EStudio_erp_m_t_p_save.Mlabel,... + EStudio_erp_m_t_p_save.IncludeLat, EStudio_erp_m_t_p_save.InterpFactor, EStudio_erp_m_t_p_save.PeakOnset}); + + end + observe_ERPDAT.Process_messg =2; + catch + beep; + msgboxText = ['ERP Measurement Tool - Cannot export the values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + + + +%----------displayed channel label will be midified after vaied channels was selected-------- + function ERP_chan_changed(~,~) + ERPMTops.m_t_chan.String = num2str(vect2colon(observe_ERPDAT.ERP_chan,'Sort', 'on')); + S_ws= estudioworkingmemory('geterpvalues'); + S_ws.chanArray = observe_ERPDAT.ERP_chan; + EStudio_erp_m_t_p.chanArray = observe_ERPDAT.ERP_chan; + estudioworkingmemory('geterpvalues',S_ws); clear S_ws; + end + +%----------displayed bin label will be midified after different channels was selected-------- + function ERP_bin_changed(~,~) + ERPMTops.m_t_bin.String = num2str(vect2colon(observe_ERPDAT.ERP_bin,'Sort', 'on')); + S_ws= estudioworkingmemory('geterpvalues'); + S_ws.binArray = observe_ERPDAT.ERP_bin; + EStudio_erp_m_t_p.binArray = observe_ERPDAT.ERP_bin; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + end + + +%%--------Settting if the current panel is active or not based on the selected ERPsets------------ + function Count_currentERP_change(~,~) + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + beep; + msgboxText = ['ERP Measurement Tool - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + ERPMTops.m_t_erpset.String= num2str(vect2colon(Selectederp_Index,'Sort','on'));%%Dec 20 2022 + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + checked_curr_index = 1; + else + checked_curr_index = 0; + end + + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + if checked_curr_index || any(checked_ERPset_Index(:)) + ERPMTops.m_t_value.Enable = 'off'; + else + ERPMTops.m_t_value.Enable = 'on'; + end + Enable_label = 'on'; + ERPMTops.m_t_type.Enable = Enable_label; + ERPMTops.m_t_type_ops.Enable = Enable_label; + ERPMTops.m_t_bin.Enable = Enable_label; + ERPMTops.m_t_bin_ops.Enable = Enable_label; + ERPMTops.m_t_chan.Enable = Enable_label; + ERPMTops.m_t_chan_ops.Enable = Enable_label; + ERPMTops.m_t_TW.Enable = Enable_label; + ERPMTops.m_t_TW_ops.Enable = Enable_label; + ERPMTops.m_t_file.Enable = Enable_label; + ERPMTops.m_t_file_ops.Enable = Enable_label; + ERPMTops.m_t_viewer.Enable = Enable_label; + ERPMTops.m_t_advanced.Enable = Enable_label; + ERPMTops.m_t_viewer_on.Enable = Enable_label; + ERPMTops.m_t_viewer_off.Enable = Enable_label; + ERPMTops.m_t_erpset.Enable = Enable_label; + ERPMTops.m_t_erpset_ops.Enable = Enable_label; + if checked_ERPset_Index(1)==1 + ERPMTops.m_t_bin.Enable = 'off'; + ERPMTops.m_t_bin_ops.Enable = 'off'; + else + ERPMTops.m_t_bin.Enable = 'on'; + ERPMTops.m_t_bin_ops.Enable = 'on'; + end + if checked_ERPset_Index(2)==2 + ERPMTops.m_t_chan.Enable = 'off'; + ERPMTops.m_t_chan_ops.Enable = 'off'; + else + ERPMTops.m_t_chan.Enable = 'on'; + ERPMTops.m_t_chan_ops.Enable = 'on'; + end + end + +end%Progem end: ERP Measurement tool \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_plot_scalp_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_plot_scalp_GUI.m new file mode 100755 index 00000000..964fb78f --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_plot_scalp_GUI.m @@ -0,0 +1,1468 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_plot_scalp_GUI(varargin) +global observe_ERPDAT; +gui_erp_scalp_map = struct(); +% addlistener(observe_ERPDAT,'ALLERP_change',@allErpChanged); +% addlistener(observe_ERPDAT,'ERP_change',@onErpChanged); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'ERP_bin_change',@ERP_bin_changed); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + + +%-----------------------------Name the title---------------------------------------------- +% global ERP_plot_scalp_gui; +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + ERP_plot_scalp_gui = uiextras.BoxPanel('Parent', fig, 'Title', 'Plot Scalp Maps', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_plot_scalp_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Scalp Maps', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_plot_scalp_gui = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Scalp Maps', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_scalp_operation(FonsizeDefault); + +varargout{1} = ERP_plot_scalp_gui; + + function drawui_erp_scalp_operation(FonsizeDefault) + % FontSize_defualt = erpworkingmemory('fontsizeGUI'); + % if isempty(FontSize_defualt) + FontSize_defualt = 12; + % end + if strcmp(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + plegend.binnum = 1; + plegend.bindesc = 1; + plegend.type = 1; + plegend.latency = 1; + plegend.electrodes = 0; + plegend.elestyle = 'on'; + plegend.elec3D = 'off'; + plegend.colorbar = 1; + plegend.colormap = 0; + plegend.maximize = 0; + estudioworkingmemory('pscalp_plegend',plegend); + agif.value =0; + agif.fps =[]; + agif.fname =''; + estudioworkingmemory('pscalp_agif',agif); + + + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + %%--------------------bin and latency setting---------------------- + gui_erp_scalp_map.ERPscalpops = uiextras.VBox('Parent', ERP_plot_scalp_gui,'BackgroundColor',ColorB_def); + + %%%------------BIN TO PLOT--------------------- + gui_erp_scalp_map.bin_latency_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_scalp_map.bin_latency_title,... + 'String','Bin & Latency:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_scalp_map.bin_plot_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + gui_erp_scalp_map.bin_plot = uicontrol('Style','text','Parent',gui_erp_scalp_map.bin_plot_title,... + 'String','Bin(s)','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + set(gui_erp_scalp_map.bin_plot,'HorizontalAlignment','left'); + gui_erp_scalp_map.bin_plot_edit = uicontrol('Style','edit','Parent',gui_erp_scalp_map.bin_plot_title,... + 'String','','callback',@scalp_bin_edit,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',[1 1 1]); % 2F + gui_erp_scalp_map.bin_plot_opt = uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.bin_plot_title,... + 'String','Browse','callback',@scalp_bin_op,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',[1 1 1]); % 2F + set(gui_erp_scalp_map.bin_plot_title ,'Sizes',[60 150 60]); + + %%%------------Latency TO PLOT--------------------- + gui_erp_scalp_map.latency_plot_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + gui_erp_scalp_map.latency_plot = uicontrol('Style','text','Parent',gui_erp_scalp_map.latency_plot_title,... + 'String','Latency (ms) [min max]','FontSize',FontSize_defualt,'BackgroundColor',ColorB_def); % 2F + set(gui_erp_scalp_map.latency_plot,'HorizontalAlignment','left'); + gui_erp_scalp_map.latency_plot_edit = uicontrol('Style','edit','Parent',gui_erp_scalp_map.latency_plot_title,... + 'String','','callback',@scalp_latency_plot,'FontSize',FontSize_defualt,'Enable',Enable_label,'BackgroundColor',[1 1 1]); % 2F + + %%----------------------------------Map Type------------------------------ + gui_erp_scalp_map.map_type_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_type_title,... + 'String','Map Type:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + %%2d + gui_erp_scalp_map.map_type = uiextras.Grid('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + % + gui_erp_scalp_map.map_type_2d = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.map_type,... + 'String','2D','callback',@map_type_2d,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_scalp_map.map_type_3d = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.map_type,... + 'String','3D','callback',@map_type_3d,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_scalp_map.map_type_2d_type = uicontrol('Style', 'popupmenu','Parent',gui_erp_scalp_map.map_type,... + 'String',{'map','contour','both','fill','blank'},'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + gui_erp_scalp_map.map_type_3d_spl = uicontrol('Style', 'pushbutton','Parent',gui_erp_scalp_map.map_type,... + 'String','Spline','callback',@map_type_3d_spl,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + + gui_erp_scalp_map.map_type_2d_type_outside = uicontrol('Style', 'checkbox','Parent',gui_erp_scalp_map.map_type,... + 'String','Outside','Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_scalp_map.map_type); + + set(gui_erp_scalp_map.map_type, 'ColumnSizes',[50 130 90],'RowSizes',[25 30]); + + %%----------------------------------Bar scale------------------------------ + gui_erp_scalp_map.bar_scale_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_scalp_map.bar_scale_title,... + 'String','Color Bar Scale:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_scalp_map.bar_scale = uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + + gui_erp_scalp_map.max_min = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.bar_scale,... + 'String','Max-Min','callback',@bar_scale_max_min,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_scalp_map.custom_option = uicontrol('Style', 'radiobutton','Parent',gui_erp_scalp_map.bar_scale,... + 'String','Custom (min max:e.g.uv)','callback',@bar_scale_custom_opt,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_scalp_map.bar_scale ,'Sizes',[100 170]); + + + gui_erp_scalp_map.bar_scale_2 = uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + gui_erp_scalp_map.abs_max = uicontrol('Style', 'radiobutton','Parent', gui_erp_scalp_map.bar_scale_2,... + 'String','Abs Max','callback',@bar_scale_abs_max,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_scalp_map.bar_scale_custom_option_edit = uicontrol('Style', 'edit','Parent',gui_erp_scalp_map.bar_scale_2,... + 'String',' ','callback',@bar_scale_custom_edit,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + set(gui_erp_scalp_map.bar_scale_2 ,'Sizes',[100 170]); + + %%----------------------------------Map Extras------------------------------ + gui_erp_scalp_map.map_extras_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_extras_title,... + 'String','Map Extras:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + %%view + gui_erp_scalp_map.map_extras_view = uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + + uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_extras_view,... + 'String','View','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'HorizontalAlignment','left'); + + morimenu = {'front', 'back', 'right', 'left', 'top',... + 'frontleft', 'frontright', 'backleft', 'backright',... + 'custom'}; + gui_erp_scalp_map.map_extras_view_ops = uicontrol('Style', 'popupmenu','Parent',gui_erp_scalp_map.map_extras_view,... + 'String',morimenu,'callback',@map_extras_view_ops,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + + gui_erp_scalp_map.map_extras_view_location = uicontrol('Style', 'edit','Parent',gui_erp_scalp_map.map_extras_view,... + 'String','','callback',@map_extras_view_location,'Enable','off','FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + + set(gui_erp_scalp_map.map_extras_view,'Sizes',[70 100 100]); + + + %%Extras + gui_erp_scalp_map.map_extras_cmap_display= uiextras.HBox('Parent',gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + + gui_erp_scalp_map.map_extras_cmap = uicontrol('Style', 'text','Parent', gui_erp_scalp_map.map_extras_cmap_display,... + 'String','Colormap','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_scalp_map.map_extras_cmap,'HorizontalAlignment','left'); + cMap_par={'jet','hsv','hot','cool','gray','viridis'}; + gui_erp_scalp_map.map_extras_cmap_ops = uicontrol('Style', 'popupmenu','Parent', gui_erp_scalp_map.map_extras_cmap_display,... + 'String',cMap_par,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',[1,1,1]); + + gui_erp_scalp_map.map_extras_cmapb_disp = uicontrol('Style', 'checkbox','Parent', gui_erp_scalp_map.map_extras_cmap_display,... + 'String','Display color scale bar','Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_scalp_map.map_extras_cmapb_disp.String = 'Display Color
Scale Bar'; + set(gui_erp_scalp_map.map_extras_cmap_display ,'Sizes',[70 90 110]); + + + %%-----------------Run--------------------------------------------- + gui_erp_scalp_map.run_title = uiextras.HBox('Parent', gui_erp_scalp_map.ERPscalpops,'BackgroundColor',ColorB_def); + + uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.run_title,... + 'String','?','callback',@scap_help,'FontSize',16,'Enable','on'); % 2F + + gui_erp_scalp_map.advanced = uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.run_title,... + 'String','Advanced','callback',@apply_advanced,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + + gui_erp_scalp_map.run = uicontrol('Style','pushbutton','Parent',gui_erp_scalp_map.run_title,... + 'String','Apply','callback',@apply_run,'FontSize',FontSize_defualt,'Enable',Enable_label); % 2F + set(gui_erp_scalp_map.ERPscalpops,'Sizes',[20,25,25,25 55 20 30 25 20 25 30 30]); + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +% %%------------------help--------------------------------------------- + function scap_help(~,~)%% It seems that it can be ignored + web('https://github.com/lucklab/erplab/wiki/Topographic-Mapping','-browser'); + end + + +%%-------------------Input bin number--------------------------------------- + function scalp_bin_edit(Source,~) + binNums = str2num(Source.String); + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, binNums, [],1); + + if chk(1) + beep; + msgboxText = ['Plot Scalp Maps>Bins-',msgboxText]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + + gui_erp_scalp_map.bin_plot_edit.String = ''; + return; + end + end + +%%---------------------bin options--------------------------------- + function scalp_bin_op(~,~) + + ERP_CURRENT = evalin('base','ERP'); + for Numofbin = 1:length(ERP_CURRENT.bindescr) + listb{Numofbin} = char(strcat(num2str(Numofbin),'.',ERP_CURRENT.bindescr{Numofbin})); + end + try + indxlistb = 1:ERP_CURRENT.nbin; + catch + return; + end + + titlename = 'Select Bin(s):'; + %----------------judge the number of latency/latencies-------- + if ~isempty(listb) + bin_label_select = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(bin_label_select) + gui_erp_scalp_map.bin_plot_edit.String=num2str(vect2colon(bin_label_select,'Sort', 'on')); + else + disp('User selected Cancel'); + return + end + else + msgboxText = ['Plot Scalp Maps>Bins>Browse-No bin information was found',]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end%Program end: Judge the number of latency/latencies + S_ws= estudioworkingmemory('geterpvalues'); + if isempty(S_ws) + return; + end + + S_ws.binArray = bin_label_select; + estudioworkingmemory('geterpvalues',S_ws);clear S_ws; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + end + + +%%----------------------Define time window (two latencies)----------------- + function scalp_latency_plot(Source,~) + Latecny_scale = str2num(Source.String); + ERP_times = observe_ERPDAT.ERP.times; + if isempty(Latecny_scale) + beep; + msgboxText = ['Plot Scalp Maps>latency-No latency was defined',]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + + latency = Latecny_scale; + if length(latency)~=2 + beep; + msgboxText = ['Plot Scalp Maps>Latency-Latency needs two values',]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + elseif length(latency)==2 + if latency(1)>=latency(2) + beep; + msgboxText = ['Plot Scalp Maps>Latency-The left edge should be smaller than the seocnd one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(1)< ERP_times(1) + beep; + msgboxText = ['Plot Scalp Maps>Latency-The left edge should be larger than the seocnd one',32, num2str(ERP_times(1)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(2)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps>Latency-The right edge should be smaller than the seocnd one',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(1)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps>Latency-The left edge should be smaller than the seocnd one',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + end + + + + +%%-----------------Dispaly topography with 2D------------------------------ + function map_type_2d(~,~) + gui_erp_scalp_map.map_type_2d.Value=1; + gui_erp_scalp_map.map_type_3d.Value=0; + set(gui_erp_scalp_map.map_type_2d_type,'Enable','on','Value',1); + gui_erp_scalp_map.map_type_3d_spl.Enable = 'off'; + gui_erp_scalp_map.map_extras_view_ops.Enable = 'off'; + gui_erp_scalp_map.map_extras_view_ops.String = '+X'; + gui_erp_scalp_map.map_extras_view_ops.Value =1; + gui_erp_scalp_map.map_extras_view_location.String = num2str([-180 30]); + gui_erp_scalp_map.map_extras_view_location.Enable = 'off'; + gui_erp_scalp_map.map_type_2d_type_outside.Enable = 'on'; + end + + + +%%-----------------Dispaly topography with 3D------------------------------ + function map_type_3d(~,~) + gui_erp_scalp_map.map_type_2d.Value=0; + gui_erp_scalp_map.map_type_3d.Value=1; + gui_erp_scalp_map.map_type_3d_spl.Enable = 'on'; + morimenu = {'front', 'back', 'right', 'left', 'top',... + 'frontleft', 'frontright', 'backleft', 'backright',... + 'custom'}; + %%for 2D + set(gui_erp_scalp_map.map_type_2d_type,'Enable','off'); + set(gui_erp_scalp_map.map_type_2d_type_outside,'Enable','off','Value',0); + %%for 3D + set(gui_erp_scalp_map.map_extras_view_ops,'String', morimenu,'Enable','on','Value',1); + gui_erp_scalp_map.map_extras_view_location.String = num2str([-180 30]); + gui_erp_scalp_map.map_extras_view_location.Enable = 'off'; + end + + +%%---------------------Spline setting for 3D------------------------------- + function map_type_3d_spl(~,~) + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index)%%Check indexs of the selected ERPsets + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + msgboxText = 'No ERPset was imported!!!'; + title = 'EStudio: f_ERP_binoperation_GUI error.'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + else + [chk, msgboxText] = f_ERP_chckerpindex(observe_ERPDAT.ALLERP, Selectederp_Index); + if chk==1 + Selectederp_Index = observe_ERPDAT.CURRENTERP; + if isempty(Selectederp_Index) + msgboxText = 'No ERPset was imported!!!'; + title = 'EStudio: f_ERP_binoperation_GUI error.'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + end + + %%Send message to Message panel + erpworkingmemory('f_ERP_proces_messg','Plot Scalp Maps'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + + + Selectederp_Index_save = []; + count_scalp = 0; + try + erpworkingmemory('f_ERP_proces_messg','Plot Scalp Maps > 3D > Spline'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + for Numofselectederp = 1:length(Selectederp_Index) + ERP = observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)); + ERP.filepath = pathName_def; + + try + splnfile = ERP.splinefile; + catch + splnfile = ''; + end + if ~isempty(splnfile) + [pathstr, file_name, ext] = fileparts(splnfile); + splnfile = fullfile(pathName_def,[file_name,ext]); + end + + %% open splinefilegui + splineinfo = splinefileGUI({splnfile},ERP); + if isempty(splineinfo) + disp('User selected Cancel'); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%% + return + end + + splinefile = splineinfo.path; + + if isempty(splinefile) + msgboxText = 'You must specify a name for the spline file.'; + title = 'EStudio: Plot Scalp Maps inputs'; + errorfound(msgboxText, title); + return + end + Save_file_label =0; + if splineinfo.save + if isempty(ERP.splinefile) + ERP.splinefile = splinefile; + % ERP = pop_savemyerp(ERP, 'gui', 'erplab', 'History', 'off'); + else + question = ['This ERPset already has spline file info.\n'... + 'Would you like to replace it?']; + title_msg = 'EStudio: spline file'; + button = askquest(sprintf(question), title_msg); + + if ~strcmpi(button,'yes') + disp('User selected Cancel') + return + else + ERP.splinefile = splinefile; + end + end + + Answer = f_ERP_save_single_file(strcat(ERP.erpname,'_scalspline'),ERP.filename,Selectederp_Index(Numofselectederp)); + if isempty(Answer) + beep; + disp('User selectd cancal'); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%% + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ERP.erpname; + Save_file_label =0; + elseif ~isempty(fileName_full) + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + Save_file_label =1; + end + + end + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + count_scalp = count_scalp+1;%%Record the new data; + Selectederp_Index_save(count_scalp) = length(observe_ERPDAT.ALLERP); + splineinfo.save = 0; + observe_ERPDAT.ERP = ERP; + else + ERP.splinefile = splinefile; + observe_ERPDAT.ALLERP(Selectederp_Index(Numofselectederp)) = ERP; + observe_ERPDAT.ERP = ERP; + end + + + if Save_file_label==1 + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + assignin('base','ERPCOM',ERPCOM); + end + end%%end for ERPset loop + + if ~isempty(Selectederp_Index_save) + try + Selected_ERP_afd = Selectederp_Index_save; + observe_ERPDAT.CURRENTERP = Selectederp_Index_save(1); + catch + Selected_ERP_afd = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + end + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + end + + assignin('base','ALLERPCOM',ALLERPCOM); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + return; + catch + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + Selected_ERP_afd =observe_ERPDAT.CURRENTERP; + estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + erpworkingmemory('f_ERP_bin_opt',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =3;%% + return; + end%%end for try + + + end + +%%------------------------------Color bar scale: Max-min---------------------------- + function bar_scale_max_min(~,~) + gui_erp_scalp_map.max_min.Value = 1; + gui_erp_scalp_map.custom_option.Value = 0; + gui_erp_scalp_map.abs_max.Value = 0; + gui_erp_scalp_map.bar_scale_custom_option_edit.Enable = 'off'; + end + + +%%------------------------------Color bar scale: abs max---------------------------- + function bar_scale_abs_max(~,~) + gui_erp_scalp_map.max_min.Value = 0; + gui_erp_scalp_map.custom_option.Value = 0; + gui_erp_scalp_map.abs_max.Value = 1; + gui_erp_scalp_map.bar_scale_custom_option_edit.Enable = 'off'; + end + + +%%------------------------------Color bar scale: custom---------------------------- + function bar_scale_custom_opt(~,~) + gui_erp_scalp_map.max_min.Value = 0; + gui_erp_scalp_map.custom_option.Value = 1; + gui_erp_scalp_map.abs_max.Value = 0; + gui_erp_scalp_map.bar_scale_custom_option_edit.Enable = 'on'; + end +%%-------------------Bar scale custom edit--------------------------------- + function bar_scale_custom_edit(Source,~) + + + end + + + + +%%---------------location selection---------------------------------------- + function map_extras_view_ops(Source,~) + + if gui_erp_scalp_map.map_type_3d.Value%%%If 3D + pos = Source.Value; + lview = Source.String; + strv = lview{pos}; + if strcmpi(strv, 'custom') + set(gui_erp_scalp_map.map_extras_view_location, 'Enable', 'on') + else + switch strv + case {'front','f'} + mview = [-180,30]; + case {'back','b'} + mview = [0,30]; + case {'left','l'} + mview = [-90,30]; + case {'right','r'} + mview = [90,30]; + case {'frontright','fr'} + mview = [135,30]; + case {'backright','br'} + mview = [45,30]; + case {'frontleft','fl'} + mview = [-135,30]; + case {'backleft','bl'} + mview = [-45,30]; + case 'top' + mview = [0,90]; + otherwise + mview = []; + end + set(gui_erp_scalp_map.map_extras_view_location, 'String', vect2colon(mview, 'Delimiter', 'off')) + set(gui_erp_scalp_map.map_extras_view_location, 'Enable', 'off') + end + + end + end + +%%---------------------Setting for advanced--------------------------------- + function apply_advanced(~,~) + + is2Dmap = gui_erp_scalp_map.map_type_2d.Value; + + pscale_legend = {1,1,1,1,0,'on','off',0,is2Dmap}; + Latecny_scale = str2num(gui_erp_scalp_map.latency_plot_edit.String); + ERP_times = observe_ERPDAT.ERP.times; + if isempty(Latecny_scale) + beep; + msgboxText = ['Plot Scalp Maps - No latency was defined']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + latency = Latecny_scale; + if length(latency)~=2 + beep; + msgboxText = ['Plot Scalp Maps - Latency needs two values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + elseif length(latency)==2 + if latency(1)>=latency(2) + beep; + msgboxText = ['Plot Scalp Maps - Left edge of Latency should be smaller than the seocnd one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(1)< ERP_times(1) + beep; + msgboxText = ['Plot Scalp Maps - Left edge of Latency should be larger than',32, num2str(ERP_times(1)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(2)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps - Right edge of Latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latency(1)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps - Left edge of Latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + pagif_legend = {0,[],'',latency}; + Answer = f_scalplotadvanceGUI(pscale_legend,pagif_legend); + if isempty(Answer) + beep; + disp('User selected cancel.'); + return; + end + %%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue} + %%parameters for agif + pscale_legend = Answer{1}; + pscalp_plegend.binnum = pscale_legend{1}; + pscalp_plegend.bindesc = pscale_legend{2}; + pscalp_plegend.type = pscale_legend{3}; + pscalp_plegend.latency = pscale_legend{4}; + pscalp_plegend.electrodes = pscale_legend{5}; + pscalp_plegend.elestyle = pscale_legend{6}; + pscalp_plegend.elec3D = pscale_legend{7}; + pscalp_plegend.colorbar = gui_erp_scalp_map.map_extras_cmapb_disp.Value; + pscalp_plegend.colormap = gui_erp_scalp_map.map_extras_cmap_ops.Value; + pscalp_plegend.maximize = pscale_legend{8}; + %%parameters for agif + pagif = Answer{2}; + pscalp_agif.value = pagif{1}; + pscalp_agif.fps = pagif{2}; + pscalp_agif.fname = pagif{4}; + %%Save parameters + estudioworkingmemory('pscalp_plegend', pscalp_plegend); + estudioworkingmemory('pscalp_agif', pscalp_agif); + %%-------------------Plotting scalp mapping----------------------- + %%Send message to Message panel + erpworkingmemory('f_ERP_proces_messg','Plot Scalp Maps'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + + + pathName_def = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_def) + pathName_def =cd; + end + + Selectederp_Index= estudioworkingmemory('selectederpstudio'); + if isempty(Selectederp_Index) + Selectederp_Index = observe_ERPDAT.CURRENTERP; + + if isempty(Selectederp_Index) + beep; + msgboxText = ['Plot Scalp Maps - No ERPset was selected']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selectederp_Index); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + + plegend = estudioworkingmemory('pscalp_plegend'); + if isempty(plegend) + plegend.binnum = 1; + plegend.bindesc = 1; + plegend.type = 1; + plegend.latency = 1; + plegend.electrodes = 0; + plegend.elestyle = 'on'; + plegend.elec3D = 'off'; + plegend.colorbar = gui_erp_scalp_map.map_extras_cmapb_disp.Value; + plegend.colormap = gui_erp_scalp_map.map_extras_cmap_ops.Value; + plegend.maximize = 0; + estudioworkingmemory('pscalp_plegend',plegend); + end + + agif = estudioworkingmemory('pscalp_agif'); + + if isempty(agif) + agif.value =0; + agif.fps =[]; + agif.fname =''; + estudioworkingmemory('pscalp_agif',agif); + end + + binArray = str2num(gui_erp_scalp_map.bin_plot_edit.String); + [chk, msgboxText] = f_ERP_chckbinandchan(observe_ERPDAT.ERP, binArray, [],1); + if chk(1) + beep; + msgboxText = ['Plot Scalp Maps -',msgboxText]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + latencyArray = str2num(gui_erp_scalp_map.latency_plot_edit.String); + ERP_times = observe_ERPDAT.ERP.times; + if isempty(latencyArray) + beep; + msgboxText = ['Plot Scalp Maps - No latency was defined']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if length(latencyArray)~=2 + beep; + msgboxText = ['Plot Scalp Maps - Latency needs two values']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + elseif length(latencyArray)==2 + if latencyArray(1)>=latencyArray(2) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than the seocnd one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + + end + + if latencyArray(1)< ERP_times(1) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be larger than',32, num2str(ERP_times(1)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if latencyArray(2)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps - The right edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if latencyArray(1)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + measurestr = 'mean'; + baseline = 'none'; + if gui_erp_scalp_map.max_min.Value + maplimit = 'maxmin'; + elseif gui_erp_scalp_map.abs_max.Value + maplimit = 'absmax'; + elseif gui_erp_scalp_map.custom_option.Value + cusca = str2num(gui_erp_scalp_map.bar_scale_custom_option_edit.String); + if isempty(cusca) + beep; + msgboxText = ['Plot Scalp Maps - No value was defined for "Color Bar Scale"']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + ncusca = length(cusca); + if ncusca == 2 + if cusca(1)=latencyArray(2) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than the right one']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latencyArray(1)< ERP_times(1) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be larger than',32, num2str(ERP_times(1)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if latencyArray(2)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + + if latencyArray(1)> ERP_times(end) + beep; + msgboxText = ['Plot Scalp Maps - The left edge of latency should be smaller than',32, num2str(ERP_times(end)),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + + + measurestr = 'mean'; + baseline = 'none'; + if gui_erp_scalp_map.max_min.Value + maplimit = 'maxmin'; + elseif gui_erp_scalp_map.abs_max.Value + maplimit = 'absmax'; + elseif gui_erp_scalp_map.custom_option.Value + cusca = str2num(gui_erp_scalp_map.bar_scale_custom_option_edit.String); + if isempty(cusca) + beep; + msgboxText = ['Plot Scalp Maps - No value was defined for "Color Bar Scale"']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + else + ncusca = length(cusca); + if ncusca == 2 + if cusca(1)length(observe_ERPDAT.ALLERP) + SelectedIndex =1; + end + + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedIndex); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + S_IN = S_erpbinchan.geterpplot; + + +end + +S_erpplot = S_IN; + +plotops_erp = struct(); +gui_erp_plot = struct; + +%-----------------------------Name the title---------------------------------------------- +% global ERP_plotset_box; +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + +if nargin == 0 + fig = figure(); % Parent figure + ERP_plotset_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Plot Setting', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_plotset_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Setting', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_plotset_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Plot Setting', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +%-----------------------------Draw the panel------------------------------------- +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erpplot(FonsizeDefault); +varargout{1} = ERP_plotset_box; + + function drawui_erpplot(FonsizeDefault) + + estudioworkingmemory('erp_plot_set',0); + estudioworkingmemory('erp_xtickstep',0); + %%--------------------x and y axes setting------------------------- + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + gui_erp_plot.plotop = uiextras.VBox('Parent',ERP_plotset_box, 'Spacing',1,'BackgroundColor',ColorB_def); + + % set(gui_erp_plot.time_sel, 'Sizes', [-1 -1 -1 -1 -1]); + uicontrol('Style','text','Parent', gui_erp_plot.plotop,'String','Time Range:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def,'BackgroundColor',ColorB_def); % 1B + + gui_erp_plot.ticks = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def); + plotops_erp.timet_auto = uicontrol('Style','checkbox','Parent', gui_erp_plot.ticks,'String','Auto','callback',@timet_auto,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2B + uicontrol('Style','text','Parent', gui_erp_plot.ticks,'String','Low','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + plotops_erp.timet_low = uicontrol('Style', 'edit','Parent',gui_erp_plot.ticks,... + 'String',num2str(S_erpplot.timet_low(Select_index)),'callback',@low_ticks_change,'Enable','off','FontSize',FonsizeDefault); + uicontrol('Style','text','Parent', gui_erp_plot.ticks,'String','High','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + plotops_erp.timet_high = uicontrol('Style', 'edit','Parent',gui_erp_plot.ticks,'String',num2str(S_erpplot.timet_high(Select_index)),... + 'callback',@high_ticks_change,'Enable','off','FontSize',FonsizeDefault); + uicontrol('Style','text','Parent', gui_erp_plot.ticks,'String','Step','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + plotops_erp.timet_step = uicontrol('Style', 'edit','Parent',gui_erp_plot.ticks,'String',num2str(S_erpplot.timet_step(Select_index)),... + 'callback',@ticks_step_change,'Enable','off','FontSize',FonsizeDefault); + + set(gui_erp_plot.ticks, 'Sizes', [60 -1 -1 -1 -1 -1 -1]); + + uicontrol('Style','text','Parent', gui_erp_plot.plotop,'String','Y Scale:','FontWeight','bold','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_plot.yscale = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def); + plotops_erp.yscale_auto = uicontrol('Style','checkbox','Parent',gui_erp_plot.yscale,'String','Auto',... + 'callback',@yscale_auto,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + tooltiptext = sprintf('Tick Length:\nSize of Y Ticks'); + uicontrol('Style','text','Parent',gui_erp_plot.yscale,'String','Ticks','TooltipString',tooltiptext,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + plotops_erp.yscale_change = uicontrol('Style','edit','Parent',gui_erp_plot.yscale,... + 'String',S_erpplot.yscale(Select_index),'callback',@yscale_change,'Enable','off','FontSize',FonsizeDefault); + tooltiptext = sprintf('Minimum Vertical Spacing:\nSmallest possible distance in inches between zero lines before plots go off the page.'); + uicontrol('Style','text','Parent',gui_erp_plot.yscale,'String','Spacing','TooltipString',tooltiptext,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + plotops_erp.min_vspacing = uicontrol('Style','edit','Parent',gui_erp_plot.yscale,'String',S_erpplot.min_vspacing(Select_index),'callback',@min_vspacing,'Enable','off','FontSize',FonsizeDefault); + tooltiptext = sprintf('Fill Screen:\nDynamically expand plots to fill screen.'); + plotops_erp.fill_screen = uicontrol('Style','checkbox','Parent',gui_erp_plot.yscale,'String','Fill','callback',@fill_screen,... + 'TooltipString',tooltiptext,'Value',S_erpplot.fill(Select_index),'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + set(gui_erp_plot.yscale, 'Sizes', [50 45 35 50 35 60]); + + + gui_erp_plot.plot_column = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def,'BackgroundColor',ColorB_def); + + uicontrol('Style','text','Parent', gui_erp_plot.plot_column,'String','Number of columns:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1E + + ColumnNum = estudioworkingmemory('EStudioColumnNum'); + if isempty(ColumnNum) || numel(ColumnNum)~=1 + ColumnNum =1; + end + plotops_erp.columns = uicontrol('Style','edit','Parent', gui_erp_plot.plot_column,... + 'String',num2str(ColumnNum),'callback',@onElecNbox,'FontSize',FonsizeDefault); % 2E Plot_column + set(gui_erp_plot.plot_column, 'Sizes', [150 -1]); + + + gui_erp_plot.polarity_waveform = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def); + + uicontrol('Style','text','Parent', gui_erp_plot.polarity_waveform,'String','Polarity:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 1F + + %% second column: + plotops_erp.positive_up = uicontrol('Style','radiobutton','Parent',gui_erp_plot.polarity_waveform,'String','Positive Up','callback',@polarity_up,'Value',1,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F + plotops_erp.negative_up = uicontrol('Style','radiobutton','Parent', gui_erp_plot.polarity_waveform,'String','Negative Up','callback',@polarity_down,'Value',0,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); % 2F + + set(gui_erp_plot.polarity_waveform, 'Sizes',[60 -1 -1]); + + gui_erp_plot.bin_chan = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_plot.pagesel = uicontrol('Parent', gui_erp_plot.bin_chan, 'Style', 'popupmenu','String',... + {'CHANNELS with BINS overlay','BINS with CHANNELS overlay'},'callback',@pageviewchanged,'FontSize',FonsizeDefault); + + + gui_erp_plot.reset_apply = uiextras.HBox('Parent',gui_erp_plot.plotop,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_plot.reset_apply); % 1A + plotops_erp.plot_reset = uicontrol('Style', 'pushbutton','Parent',gui_erp_plot.reset_apply,... + 'String','Reset','callback',@plot_erp_reset,'FontSize',FonsizeDefault); + uiextras.Empty('Parent', gui_erp_plot.reset_apply); % 1A + plotops_erp.plot_apply = uicontrol('Style', 'pushbutton','Parent',gui_erp_plot.reset_apply,... + 'String','Apply','callback',@plot_erp_apply,'FontSize',FonsizeDefault); + uiextras.Empty('Parent', gui_erp_plot.reset_apply); % 1A + set(gui_erp_plot.reset_apply, 'Sizes',[10 -1 30 -1 10]); + + set(gui_erp_plot.plotop, 'Sizes', [20 25 20 25 25 25 20 30]); + + end + + + +%%**************************************************************************%% +%%--------------------------Sub function------------------------------------%% +%%**************************************************************************%% + +%---------------------------------Auto time ticks-------------------------------* + function timet_auto( src, ~ ) + estudioworkingmemory('erp_xtickstep',0); + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + if src.Value == 1 + plotops_erp.timet_low.Enable = 'off'; + plotops_erp.timet_high.Enable = 'off'; + plotops_erp.timet_step.Enable = 'off'; + else + plotops_erp.timet_low.Enable = 'on'; + plotops_erp.timet_high.Enable = 'on'; + plotops_erp.timet_step.Enable = 'on'; + end + plotops_erp.timet_low.String = num2str(floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5); + plotops_erp.timet_high.String = num2str(ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5); + + + Min_time=floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5; + Max_time = ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5; + + [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [Min_time,Max_time]); + plotops_erp.timet_step.String = num2str(xstep); + + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + + if any(checked_ERPset_Index(5)) + S_erpplot.timet_low(Select_index) = floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5; + else + S_erpplot.timet_low(1:end) = floor(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(1)/5)*5; + end + + if any(checked_ERPset_Index(6)) + S_erpplot.timet_high(Select_index) = ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5; + else + S_erpplot.timet_high(1:end) = ceil(observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).times(end)/5)*5; + end + + if any(checked_ERPset_Index(6)) || any(checked_ERPset_Index(5)) + S_erpplot.timet_step(Select_index) = xstep; + else + S_erpplot.timet_step(1:end) = xstep; + end + end + + +%%--------------------------Min. interval of time ticks--------------------- + function low_ticks_change( src, ~ ) + + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + xtixlk_min = str2num(src.String); + xtixlk_max = str2num(plotops_erp.timet_high.String); + if isempty(xtixlk_min) + src.String = num2str(S_erpplot.timet_low(Select_index)); + beep; + msgboxText = ['Plot Setting> Time range- Input of left edge must be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + + if numel(xtixlk_min)>1 + src.String = num2str(S_erpplot.timet_low(Select_index)); + msgboxText = ['Plot Setting> Time range- nput of left edge must be a single numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + + return; + end + + + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + if xtixlk_min < S_erpplot.timet_high(Select_index) + S_erpplot.timet_low(Select_index)=xtixlk_min; + if any(checked_ERPset_Index(5)) + S_erpplot.timet_low(Select_index)=xtixlk_min; + else + S_erpplot.timet_low(1:end)=xtixlk_min; + end + + [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [xtixlk_min,xtixlk_max]); + plotops_erp.timet_step.String = num2str(xstep); + S_erpplot.timet_step(1:end) = xstep; + else + src.String = S_erpplot.min(Select_index); + + msgboxText = ['Plot Setting> Time range- left range must be lower than high tick']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if S_erpplot.timet_step(Select_index) > S_erpplot.timet_high(Select_index)- S_erpplot.timet_low(Select_index) + plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index)); + + msgboxText = ['Plot Setting> Time range- Step must be within the time range']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + + + +%%----------------------high interval of time ticks--------------------------------* + function high_ticks_change( src, ~ ) + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + xtixlk_min = str2num(plotops_erp.timet_low.String); + xtixlk_max = str2num(src.String); + + if isempty(xtixlk_max) + src.String = num2str(S_erpplot.timet_high(Select_index)); + beep; + msgboxText = ['Plot Setting> Y Scale- Input of ticks edge must be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + + return; + end + + if numel(xtixlk_max)>1 + src.String = num2str(S_erpplot.timet_high(Select_index)); + beep; + msgboxText = ['Plot Setting> Y Scale- Input of ticks edge must be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + + return; + end + + + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + if xtixlk_max > xtixlk_min + + if any(checked_ERPset_Index(6)) + S_erpplot.timet_high(Select_index) = xtixlk_max; + else + S_erpplot.timet_high(1:end) = xtixlk_max; + end + [def xstep]= default_time_ticks_studio(observe_ERPDAT.ERP, [xtixlk_min,xtixlk_max]); + plotops_erp.timet_step.String = num2str(xstep); + S_erpplot.timet_step(1:end) = xstep; + + else + src.String = num2str(S_erpplot.timet_high(Select_index)); + beep; + msgboxText = ['Plot Setting> Time range- right edge must be higher than',32,num2str(xtixlk_min),'ms']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if S_erpplot.timet_step(Select_index) > S_erpplot.timet_high(Select_index) -S_erpplot.timet_low(Select_index) + beep; + plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index)); + msgboxText = ['Plot Setting> Time range- Step must be within the time range']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + + +%%----------------------Step of time ticks--------------------------------* + function ticks_step_change( src, ~ ) + + tick_step = str2num(src.String); + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + if isempty(tick_step) + src.String = num2str(S_erpplot.timet_step(Select_index)); + beep; + msgboxText = ['Plot Setting> Time range- The input of Step must be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if numel(tick_step)>1 + src.String = num2str(S_erpplot.timet_step(Select_index)); + beep; + msgboxText = ['Plot Setting> Time range- The input of Step must be one numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if tick_step<=0 %% otherwise, a bug will be displayed + src.String = num2str(S_erpplot.timet_step(Select_index)); + beep; + msgboxText = ['Plot Setting> Time range- Step must be a positive value']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + checked_ERPset_Index = S_binchan.checked_ERPset_Index; + + if tick_step < S_erpplot.timet_high(Select_index) -S_erpplot.timet_low(Select_index) + + if any(checked_ERPset_Index(5)) && any(checked_ERPset_Index(6)) + S_erpplot.timet_step(Select_index) = tick_step; + else + S_erpplot.timet_step(1:end) = tick_step; + end + estudioworkingmemory('erp_xtickstep',1); + + + else + src.String = num2str(S_erpplot.timet_step(Select_index)); + beep; + msgboxText = ['Plot Setting> Time range- Step must be within the time range']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + +%%---------------------------------Auto y scale---------------------------------* + function yscale_auto( src, ~ ) + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + if src.Value == 1 + plotops_erp.yscale_change.Enable = 'off'; + YScale =prctile((observe_ERPDAT.ALLERP(S_selectedERP(Select_index)).bindata(:)*S_erpplot.Positive_up(Select_index)),95)*2/3; + if YScale>= 0&&YScale <=0.1 + YScale = 0.1; + elseif YScale< 0&& YScale > -0.1 + YScale = -0.1; + else + YScale = round(YScale); + end + plotops_erp.yscale_change.String = YScale; + S_erpplot.yscale(1:end) = YScale; + + plotops_erp.min_vspacing.Enable = 'off'; + plotops_erp.min_vspacing.String = 1.5; + S_erpplot.min_vspacing(1:end) =1.5; + else + plotops_erp.yscale_change.Enable = 'on'; + plotops_erp.min_vspacing.Enable = 'on'; + end + + end + + +%%---------------------------------y scale change---------------------------------* + function yscale_change(src, ~ ) + + clear i + val = 1i; + try + val = str2double(src.String); + catch + beep; + msgboxText = ['Plot Setting> y scale - Input of y scale must be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if val ~= 1i + if val <= 0 + beep; + msgboxText = ['Plot Setting> y scale - Input must be greater than zero']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + else + S_erpplot.yscale(1:end) = val; + end + end + + end + + +%%-------------------------- Y scale spacing------------------------------- + function min_vspacing( src, ~ ) + clear i + val = 1i; + try + val = str2double(src.String); + catch + beep; + msgboxText = ['Plot Setting> y scale > spacing - Input of spacing must be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + src.String = 1.5; + end + if val ~= 1i + if val <= 0 + beep; + msgboxText = ['Plot Setting> y scale > spacing - Input of spacing must be greater than zero']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + src.String = 1.5; + else + S_erpplot.min_vspacing(1:end) = val; + end + end + end + +%%-----------------fill screen---------------------------------------------* + function fill_screen( src, ~ ) + S_erpplot.fill(1:end)= src.Value; + end + +%%-----------Determing the numbrt of columns------------------------------ + function onElecNbox(source,~) + Values = str2num(source.String); + if isempty(Values) || Values <=0 + source.String = num2str( S_erpplot.Plot_column(1)); + msgboxText = ['Plot Setting> Number of columns - Input for the number of columns must be greater than zero']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + S_erpplot.Plot_column(1:end) = Values; + end + +%------------------Set the polarity of waveform is up or not------------------- + function polarity_up(~,~) + source_value_up = 1; + plotops_erp.positive_up.Value =source_value_up; + plotops_erp.negative_up.Value = 0; + S_erpplot.Positive_up(1:end) = source_value_up; + end + + +%------------------Set the polarity of waveform is up or not------------------- + function polarity_down( source, ~) + source_value_down = 1; + plotops_erp.positive_up.Value =0; + plotops_erp.negative_up.Value = source_value_down; + S_erpplot.Positive_up(1:end) = -source_value_down; + end + +%%------------------------------------------------------------------------- + function Count_currentERPChanged(~,~) + erp_plot_set_label = estudioworkingmemory('erp_plot_set'); + if isempty(erp_plot_set_label) + erp_plot_set_label =1; + end + if ~erp_plot_set_label + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + S_erpplot = estudioworkingmemory('geterpplot'); + plotops_erp.timet_auto.Value = 1; % 2B + plotops_erp.timet_low.String = num2str(S_erpplot.timet_low(Select_index)); + plotops_erp.timet_low.Enable = 'off'; + plotops_erp.timet_high.String = num2str(S_erpplot.timet_high(Select_index)); + plotops_erp.timet_high.Enable = 'off'; + try + plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index)); + catch + plotops_erp.timet_step.String = num2str(floor((S_erpplot.max(Select_index)-S_erpplot.min(Select_index))/5)); + end + plotops_erp.timet_step.Enable = 'off'; + + + plotops_erp.yscale_auto.Value = 1; + + plotops_erp.yscale_change.String = num2str(S_erpplot.yscale(Select_index)); + plotops_erp.yscale_change.Enable = 'off'; + plotops_erp.min_vspacing.String = num2str(S_erpplot.min_vspacing(Select_index)); + plotops_erp.min_vspacing.Enable = 'off'; + plotops_erp.fill_screen.Value = S_erpplot.fill(Select_index); + ColumnNum = estudioworkingmemory('EStudioColumnNum'); + if isempty(ColumnNum) || numel(ColumnNum)~=1 + ColumnNum =1; + end + + plotops_erp.columns.String = num2str(ColumnNum); % 2E Plot_column + plotops_erp.columns.Enable = 'on'; + + if S_erpplot.Positive_up(Select_index) == -1 + plotops_erp.positive_up.Value =0; + plotops_erp.negative_up.Value = 1; + else + plotops_erp.positive_up.Value = 1; + plotops_erp.negative_up.Value = 0; + end + + try + Bin_chan_overlay = S_binchan.bins_chans(1); + catch + Bin_chan_overlay = 0; + end + + set(gui_erp_plot.pagesel,'Value',Bin_chan_overlay+1); + end + estudioworkingmemory('erp_plot_set',0); + + %%---------------Deative the setting for the number of columns when activing ERP viewer + try + S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); + S_ws_viewer = S_ws_geterpvalues.Viewer; + catch + S_ws_viewer = 'off'; + end + if strcmp(S_ws_viewer,'on') + plotops_erp.columns.Enable = 'off'; + end + + end + + +%%----------------------Setting for bin overlay chan--------------------- + function pageviewchanged(src,~) + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',S_selectedERP); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + + if src.Value == 1 + if S_binchan.checked_ERPset_Index(1) ==1 || S_binchan.checked_ERPset_Index(2) ==2 + S_binchan.bins_chans(Select_index) = 0; + else + S_binchan.bins_chans(1:end) = 0; + end + else + if S_binchan.checked_ERPset_Index(1) ==1 || S_binchan.checked_ERPset_Index(2) ==2 + S_binchan.bins_chans(Select_index) = 1; + else + S_binchan.bins_chans(1:end) = 1; + end + end + + estudioworkingmemory('geterpbinchan',S_binchan); + end + + + + +%%--------------Reset the parameters for plotting panel-------------------- + function plot_erp_reset(~,~) + erpworkingmemory('f_ERP_proces_messg','Plot Setting>Reset'); + observe_ERPDAT.Process_messg =1; + + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + try + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('selectederpstudio',S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + catch + return; + end + else + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + gui_erp_plot.pagesel.Value = 1; + + + erp_plot_set_label = estudioworkingmemory('erp_plot_set'); + if isempty(erp_plot_set_label) + erp_plot_set_label =1; + end + if ~erp_plot_set_label + S_selectedERP = estudioworkingmemory('selectederpstudio'); + if isempty(S_selectedERP) + S_selectedERP = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,S_selectedERP); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + Select_index = S_binchan.Select_index; + S_erpplot = estudioworkingmemory('geterpplot'); + plotops_erp.timet_auto.Value = 1; % 2B + plotops_erp.timet_low.String = num2str(S_erpplot.timet_low(Select_index)); + plotops_erp.timet_low.Enable = 'off'; + plotops_erp.timet_high.String = num2str(S_erpplot.timet_high(Select_index)); + plotops_erp.timet_high.Enable = 'off'; + try + plotops_erp.timet_step.String = num2str(S_erpplot.timet_step(Select_index)); + catch + plotops_erp.timet_step.String = num2str(floor((S_erpplot.max(Select_index)-S_erpplot.min(Select_index))/5)); + end + plotops_erp.timet_step.Enable = 'off'; + plotops_erp.yscale_auto.Value = 1; + plotops_erp.yscale_change.String = num2str(S_erpplot.yscale(Select_index)); + plotops_erp.yscale_change.Enable = 'off'; + plotops_erp.min_vspacing.String = num2str(S_erpplot.min_vspacing(Select_index)); + plotops_erp.min_vspacing.Enable = 'off'; + plotops_erp.fill_screen.Value = S_erpplot.fill(Select_index); + ColumnNum = estudioworkingmemory('EStudioColumnNum'); + if isempty(ColumnNum) || numel(ColumnNum)~=1 + ColumnNum =1; + end + + plotops_erp.columns.String = num2str(ColumnNum); % 2E Plot_column + plotops_erp.columns.Enable = 'on'; + + if S_erpplot.Positive_up(Select_index) == -1 + plotops_erp.positive_up.Value =0; + plotops_erp.negative_up.Value = 1; + else + plotops_erp.positive_up.Value = 1; + plotops_erp.negative_up.Value = 0; + end + + try + Bin_chan_overlay = S_binchan.bins_chans(1); + catch + Bin_chan_overlay = 0; + end + + set(gui_erp_plot.pagesel,'Value',Bin_chan_overlay+1); + end + estudioworkingmemory('erp_plot_set',0); + + %%---------------Deative the setting for the number of columns when activing ERP viewer + try + S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); + S_ws_viewer = S_ws_geterpvalues.Viewer; + catch + S_ws_viewer = 'off'; + end + if strcmp(S_ws_viewer,'on') + plotops_erp.columns.Enable = 'off'; + end + + observe_ERPDAT.Process_messg =2; + + %%plot the waveforms + try + S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); + S_ws_viewer = S_ws_geterpvalues.Viewer; + + moption = S_ws_geterpvalues.Measure; + latency = S_ws_geterpvalues.latency; + if strcmp(S_ws_viewer,'on') + if isempty(moption) + msgboxText = ['EStudio says: User must specify a type of measurement.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + end + if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + msgboxText = ['ERPLAB says: ' moption ' only needs 1 latency value.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + end + else + if length(latency)~=2 + msgboxText = ['EStudio says: ' moption ' needs 2 latency values.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + else + if latency(1)>=latency(2) + msgboxText = ['For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.']; + title = 'EStudio: ERP measurement tool-Measurement window'; + errorfound(sprintf(msgboxText), title); + return + end + end + end + f_redrawERP_mt_viewer(); + else + f_redrawERP(); + end + catch + f_redrawERP(); + end + + end + + +%------------Apply current parameters in plotting panel to the selected ERPset--------- + function plot_erp_apply(~,~) + erpworkingmemory('f_ERP_proces_messg','Plot Setting>Apply'); + observe_ERPDAT.Process_messg =1; + + estudioworkingmemory('geterpplot',S_erpplot); + estudioworkingmemory('erp_plot_set',1); + ColumnNum = str2num(plotops_erp.columns.String); + if isempty(ColumnNum) && numel(ColumnNum)~=1 + ColumnNum = 1; + end + estudioworkingmemory('EStudioColumnNum',ColumnNum); + % observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + + %%plot the waveforms + try + S_ws_geterpvalues = estudioworkingmemory('geterpvalues'); + S_ws_viewer = S_ws_geterpvalues.Viewer; + + moption = S_ws_geterpvalues.Measure; + latency = S_ws_geterpvalues.latency; + if strcmp(S_ws_viewer,'on') + if isempty(moption) + msgboxText = ['EStudio says: User must specify a type of measurement.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + end + if ismember_bc2({moption}, {'instabl', 'areazt','areazp','areazn', 'nintegz'}) + if length(latency)~=1 + msgboxText = ['ERPLAB says: ' moption ' only needs 1 latency value.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + end + else + if length(latency)~=2 + msgboxText = ['EStudio says: ' moption ' needs 2 latency values.']; + title = 'EStudio: ERP measurement tool- "Measurement type".'; + errorfound(msgboxText, title); + return; + else + if latency(1)>=latency(2) + msgboxText = ['For latency range, lower time limit must be on the left.\n'... + 'Additionally, lower time limit must be at least 1/samplerate seconds lesser than the higher one.']; + title = 'EStudio: ERP measurement tool-Measurement window'; + errorfound(sprintf(msgboxText), title); + return + end + end + end + f_redrawERP_mt_viewer(); + else + f_redrawERP(); + end + catch + f_redrawERP(); + end + end + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.fig b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.fig new file mode 100755 index 00000000..5dc9e8af Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.m b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.m new file mode 100755 index 00000000..ae76509a --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_rename_gui.m @@ -0,0 +1,181 @@ +function varargout = f_ERP_rename_gui(varargin) +% F_ERP_RENAME_GUI MATLAB code for f_ERP_rename_gui.fig +% F_ERP_RENAME_GUI, by itself, creates a new F_ERP_RENAME_GUI or raises the existing +% singleton*. +% +% H = F_ERP_RENAME_GUI returns the handle to a new F_ERP_RENAME_GUI or the handle to +% the existing singleton*. +% +% F_ERP_RENAME_GUI('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_RENAME_GUI.M with the given input arguments. +% +% F_ERP_RENAME_GUI('Property','Value',...) creates a new F_ERP_RENAME_GUI or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_rename_gui_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_rename_gui_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_rename_gui + +% Last Modified by GUIDE v2.5 02-Aug-2022 16:46:06 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_rename_gui_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_rename_gui_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_rename_gui is made visible. +function f_ERP_rename_gui_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_rename_gui + +try + erpname = varargin{1}; + currenterp = varargin{2}; +catch + erpname = ''; + currenterp = ''; +end + +handles.erpnameor = erpname; +handles.output = []; +erpmenu = findobj('tag', 'erpsets'); + +if ~isempty(erpmenu) + handles.menuerp = get(erpmenu); + set(handles.menuerp.Children, 'Enable','off'); +end + +erplab_studio_default_values; +version = erplabstudiover; + +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Rename current ERPset GUI']) +set(handles.edit_erpname, 'String', erpname); + +if isempty(currenterp) + set(handles.current_erp_label,'String', ['No active erpset was found'],... + 'FontWeight','Bold', 'FontSize', 16); +else + ERPNAME = char(strcat('ERPset # ', num2str(currenterp),': (',erpname,')')); + set(handles.current_erp_label,'String',ERPNAME ,... + 'FontWeight','Bold', 'FontSize', 16) +end +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_rename_gui_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +% try +% set(handles.menuerp.Children, 'Enable','on'); +% catch +% disp('ERPset menu was not found...') +% end +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + + + +% --- Executes on button press in radio_erpname. +function radio_erpname_Callback(hObject, eventdata, handles) +% hObject handle to radio_erpname (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of radio_erpname + + +function edit_erpname_Callback(hObject, eventdata, handles) + + +% --- Executes during object creation, after setting all properties. +function edit_erpname_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +beep; +disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) +erpname = strtrim(get(handles.edit_erpname, 'String')); + +if isempty(erpname) + msgboxText = 'You must enter an erpname at least!'; + title = 'EStudio: f_ERP_save_single_file empty erpname'; + errorfound(msgboxText, title); + return +end + + +handles.output = {erpname}; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.fig b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.fig new file mode 100755 index 00000000..e7351ed6 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.m b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.m new file mode 100755 index 00000000..726cf919 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_save_multi_file.m @@ -0,0 +1,391 @@ +function varargout = f_ERP_save_multi_file(varargin) +% F_ERP_SAVE_MULTI_FILE MATLAB code for f_ERP_save_multi_file.fig +% F_ERP_SAVE_MULTI_FILE, by itself, creates a new F_ERP_SAVE_MULTI_FILE or raises the existing +% singleton*. +% +% H = F_ERP_SAVE_MULTI_FILE returns the handle to a new F_ERP_SAVE_MULTI_FILE or the handle to +% the existing singleton*. +% +% F_ERP_SAVE_MULTI_FILE('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_SAVE_MULTI_FILE.M with the given input arguments. +% +% F_ERP_SAVE_MULTI_FILE('Property','Value',...) creates a new F_ERP_SAVE_MULTI_FILE or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_save_multi_file_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_save_multi_file_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_save_multi_file + +% Last Modified by GUIDE v2.5 13-Jun-2022 18:55:22 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_save_multi_file_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_save_multi_file_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_save_multi_file is made visible. +function f_ERP_save_multi_file_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_save_multi_file + +try + ALLERP = varargin{1}; + Selected_ERP_label = varargin{2}; + suffix = varargin{3}; +catch + suffix = ''; + ERPLAB = []; + ERPLAB.erpname = 'No erpset was selected'; + ERPLAB.filename ='No erpset was selected'; + ERPLAB.event = []; + ERPLAB.chanlocs = []; + ERPLAB.nbchan = 0; + ALLERP(1) = ERPLAB; + Selected_ERP_label = 1; +end + +% handles.erpnameor = erpname; +handles.output = []; +handles.suffix = suffix; + +handles.ALLERP = ALLERP; +handles.Selected_ERP_label =Selected_ERP_label; + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Save multiple Erpsets GUI']) + + +% set(handles.checkbox1_suffix,'Value',1); +set(handles.edit_suffix_name,'String',suffix); +set(handles.checkbox2_save_label,'Value',0); + +ColumnName_table = {'ERP name','File name'}; + +set(handles.uitable1_erpset_table,'ColumnName',cellstr(ColumnName_table)); +set(handles.uitable1_erpset_table,'RowName',cellstr(num2str(Selected_ERP_label'))); + + +for Numofselectederp = 1:numel(Selected_ERP_label) + DataString{Numofselectederp,1} = strcat(ALLERP(Selected_ERP_label(Numofselectederp)).erpname,suffix); + DataString{Numofselectederp,2} = ''; +end + +set(handles.uitable1_erpset_table,'Data',cellstr(DataString)); +set(handles.uitable1_erpset_table,'ColumnWidth',{248 248}); +set(handles.uitable1_erpset_table,'Enable','on'); +set(handles.checkbox3_filename_erpname,'Enable','off'); + +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_save_multi_file_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +try + varargout{1} = handles.output; +catch + varargout{1} = []; +end + +delete(handles.gui_chassis); +pause(0.1) + + + +% --- Executes on button press in checkbox1_suffix. +function checkbox1_suffix_Callback(hObject, eventdata, handles) +ALLERP = handles.ALLERP; +Selected_ERP_label = handles.Selected_ERP_label; +suffix_edit = handles.edit_suffix_name.String; + +if isempty(suffix_edit) + msgboxText = 'You must enter a suffix at least!'; + title = 'EStudio: f_ERP_save_multi_file() error'; + errorfound(msgboxText, title); + return +end + + +DataString_before = handles.uitable1_erpset_table.Data; +for Numofselectederp = 1:numel(Selected_ERP_label) + DataString{Numofselectederp,1} = strcat(ALLERP(Selected_ERP_label(Numofselectederp)).erpname,suffix_edit); + DataString{Numofselectederp,2} = DataString_before{Numofselectederp,2}; +end +set(handles.uitable1_erpset_table,'Data',cellstr(DataString)); +set(handles.uitable1_erpset_table,'ColumnWidth',{248 248}); +if handles.checkbox2_save_label.Value + set(handles.uitable1_erpset_table,'Enable','off'); +else + set(handles.uitable1_erpset_table,'Enable','on'); +end + + + + +function edit_suffix_name_Callback(hObject, eventdata, handles) + +% Suffix_string = handles.edit_suffix_name.String; +% if isempty(Suffix_string) +% msgboxText = 'You must enter a suffix at least!'; +% title = 'EStudio: f_ERP_save_multi_file() error'; +% errorfound(msgboxText, title); +% return +% end +% +% if handles.checkbox1_suffix.Value +% +% DataString_before = handles.uitable1_erpset_table.Data; +% for Numofselectederp = 1:size(DataString_before,1) +% DataString{Numofselectederp,1} = char(strcat(DataString_before{Numofselectederp,1},'-',char(Suffix_string))); +% DataString{Numofselectederp,2} = DataString_before{Numofselectederp,2}; +% end +% +% set(handles.uitable1_erpset_table,'Data',cellstr(DataString)); +% set(handles.uitable1_erpset_table,'ColumnWidth',{248 248}); +% set(handles.uitable1_erpset_table,'Enable','off'); +% handles.suffix=Suffix_string; +% end + +% --- Executes during object creation, after setting all properties. +function edit_suffix_name_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + + +% --- Executes on button press in checkbox2_save_label. +function checkbox2_save_label_Callback(hObject, eventdata, handles) + +Values = handles.checkbox2_save_label.Value; + +if Values + set(handles.checkbox3_filename_erpname,'Enable','on'); + ALLERP = handles.ALLERP; + Selected_ERP_label = handles.Selected_ERP_label; + DataString_before = handles.uitable1_erpset_table.Data; + for Numofselectederp = 1:size(DataString_before,1) + DataString{Numofselectederp,1} = DataString_before{Numofselectederp,1}; + DataString{Numofselectederp,2} = char(ALLERP(Selected_ERP_label(Numofselectederp)).filename); + end + set(handles.uitable1_erpset_table,'Data',DataString); +else + set(handles.checkbox3_filename_erpname,'Enable','off'); + DataString_before = handles.uitable1_erpset_table.Data; + for Numofselectederp = 1:size(DataString_before,1) + DataString_before{Numofselectederp,2} = ''; + end + set(handles.uitable1_erpset_table,'Data',DataString_before); + set(handles.uitable1_erpset_table,'Enable','on'); +end +if handles.checkbox2_save_label.Value + set(handles.uitable1_erpset_table,'Enable','off'); +else + set(handles.uitable1_erpset_table,'Enable','on'); +end + + + +% --- Executes on button press in checkbox3_filename_erpname. +function checkbox3_filename_erpname_Callback(hObject, eventdata, handles) +Value_filename_erpname = handles.checkbox3_filename_erpname.Value; + +set(handles.uitable1_erpset_table,'Enable','off'); +DataString_before = handles.uitable1_erpset_table.Data; + +for Numofselectederp = 1:size(DataString_before,1) + + DataString{Numofselectederp,1} = DataString_before{Numofselectederp,1}; + fileName = char(DataString_before{Numofselectederp,1}); + if isempty(fileName) + fileName = strcat(num2str(Numofselectederp),'erp'); + end + [pathstr, file_name, ext] = fileparts(fileName); + if isempty(file_name) + file_name = [num2str(Selected_ERP_label(Numofselectederp)),'_ERP.erp']; + else + file_name = [file_name,'.erp']; + end + DataString{Numofselectederp,2} = file_name; +end + +set(handles.uitable1_erpset_table,'Data',cellstr(DataString)); +set(handles.uitable1_erpset_table,'ColumnWidth',{248 248}); + + + + + +% --- Executes when entered data in editable cell(s) in uitable1_erpset_table. +function uitable1_erpset_table_CellEditCallback(hObject, eventdata, handles) + +DataString = handles.uitable1_erpset_table.Data; +Selected_ERP_label = handles.Selected_ERP_label; +if size(DataString,1) < numel(Selected_ERP_label) + msgboxText = 'Erpname and filename for one of erpsets are empty at least! Please give name to erpname and filename'; + title = 'EStudio: f_ERP_save_multi_file empty erpname'; + errorfound(msgboxText, title); + return +end + +for Numofselected = 1:numel(Selected_ERP_label) + if isempty(DataString{Numofselected,1}) + msgboxText = 'Erpname for one of erpsets is empty at least! Please give name to that erpset'; + title = 'EStudio: f_ERP_save_multi_file empty erpname'; + errorfound(msgboxText, title); + return + end + +end + + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% beep; +disp('User selected Cancel.'); +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) +% suffix = strtrim(get(handles.edit_suffix_name, 'String')); +% if handles.checkbox1_suffix.Value +% if isempty(suffix) +% msgboxText = 'You must enter suffix at least!'; +% title = 'EStudio: f_ERP_save_multi_file empty erpname'; +% errorfound(msgboxText, title); +% return +% end +% end + +Data_String =handles.uitable1_erpset_table.Data; +ALLERP = handles.ALLERP; +Selected_ERP_label = handles.Selected_ERP_label; + +if size(Data_String,1)< numel(Selected_ERP_label)% + msgboxText = 'Erpname for one of erpsets is empty at least! Please give a name'; + title = 'EStudio: f_ERP_save_multi_file empty erpname'; + errorfound(msgboxText, title); + return +end + + +if size(Data_String,1)> numel(Selected_ERP_label)% + msgboxText = 'More erpname is given. Please delect it!!!'; + title = 'EStudio: f_ERP_save_multi_file empty erpname'; + errorfound(msgboxText, title); + return +end + + + +for Numofselected = 1:numel(Selected_ERP_label) + if isempty(Data_String{Numofselected,1}) + msgboxText = 'Erpname for one of erpsets is empty at least! Please give name to that erpset'; + title = 'EStudio: f_ERP_save_multi_file empty erpname'; + errorfound(msgboxText, title); + return + end + +end + + + +for Numofselectederp = 1:numel(Selected_ERP_label) + ALLERP(Selected_ERP_label(Numofselectederp)).erpname = Data_String{Numofselectederp,1}; + fileName = char(Data_String{Numofselectederp,2}); + if isempty(fileName) + fileName = Data_String{Numofselectederp,1}; + end + + [pathstr, file_name, ext] = fileparts(fileName); + if isempty(file_name) + file_name = [num2str(Selected_ERP_label(Numofselectederp)),'_ERP.erp']; + else + file_name = [file_name,'.erp']; + end + + ALLERP(Selected_ERP_label(Numofselectederp)).filename = file_name; + if handles.checkbox2_save_label.Value + ALLERP(Selected_ERP_label(Numofselectederp)).filepath = cd; + end + + if handles.checkbox2_save_label.Value + ALLERP(Selected_ERP_label(Numofselectederp)).saved = 'yes'; + else + ALLERP(Selected_ERP_label(Numofselectederp)).saved = 'no'; + end + +end + +FilePath = handles.checkbox2_save_label.Value; + +handles.output = {ALLERP, FilePath}; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_single_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_GUI.m new file mode 100755 index 00000000..7dfaffce --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_GUI.m @@ -0,0 +1,231 @@ +%%This function is GUI that is used to save single ERP + + + + + + + +function ERP_OUT = f_ERP_save_single_GUI(ERP_In) + + +global observe_ERPDAT; + +try + % % ERP_In = evalin('base','ERP'); + ERP_In = ERP_In; + % % Suffix = varargin{2}; +catch + ERP_In = evalin('base','ERP'); +end + + +% varargout = {}; +f_ERP_save_single = figure( 'Name', 'Save ERPset GUI for single file', ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off'); +f_ERP_save_single.Position(3:4) = [600 200]; + +% global gui_erp_save_single; +ERP_OUT = []; +% varargout{1} = f_ERP_save_single; + +erp_blc_dt_adv_gui(ERP_In); +% varargout{1} = ERP_basecorr_detrend_box; +%%********************Draw the GUI for ERP measurement tool***************** + function erp_blc_dt_adv_gui(ERP_In) + gui_erp_save_single.erp_file_name = uiextras.VBox('Parent',f_ERP_save_single,'Spacing',1); + + gui_erp_save_single.erpname_title = uiextras.HBox('Parent',gui_erp_save_single.erp_file_name,'Spacing',1); + uicontrol('Style', 'text','Parent', gui_erp_save_single.erpname_title,... + 'String',['Your active erpset is #', num2str(observe_ERPDAT.CURRENTERP)],'fontsize',16); + + + gui_erp_save_single.erpname_sec = uiextras.Grid('Parent',gui_erp_save_single.erp_file_name,'Spacing',1); + gui_erp_save_single.erpname_save = uicontrol('Style', 'radiobutton','Parent', gui_erp_save_single.erpname_sec,... + 'String','ERPname','callback',@erpname_radio,'Value',1); + % uiextras.Empty('Parent', gui_erp_save_single.erpname_sec); + gui_erp_save_single.erpname_str = uicontrol('Style', 'edit','Parent', gui_erp_save_single.erpname_sec,... + 'String',ERP_In.erpname,'callback',@erpname_str); + + gui_erp_save_single.erpname_filename = uicontrol('Style', 'pushbutton','Parent', gui_erp_save_single.erpname_sec,... + 'String','save as filename','callback',@erpname_filename,'Enable','off'); + + set(gui_erp_save_single.erpname_sec, 'ColumnSizes',[80 400 115],'RowSizes',[40]); + + + + + %%Save as + gui_erp_save_single.filename_sec = uiextras.Grid('Parent',gui_erp_save_single.erp_file_name,'Spacing',1); + gui_erp_save_single.filename_save = uicontrol('Style', 'radiobutton','Parent', gui_erp_save_single.filename_sec,... + 'String','Save ERP as','callback',@filename_radio,'Value',0); + gui_erp_save_single.filename_str = uicontrol('Style', 'edit','Parent', gui_erp_save_single.filename_sec,... + 'String','','Enable','off'); + + gui_erp_save_single.filename_browse = uicontrol('Style', 'pushbutton','Parent', gui_erp_save_single.filename_sec,... + 'String','Browse','callback',@filename_browse,'Enable','off'); + + set(gui_erp_save_single.filename_sec, 'ColumnSizes',[100 410 85],'RowSizes',[40]); + + + %%Cancel and Run + + gui_erp_save_single.other_option = uiextras.HBox('Parent',gui_erp_save_single.erp_file_name,'Spacing',1); + uiextras.Empty('Parent', gui_erp_save_single.other_option); + gui_erp_save_single.cancel = uicontrol('Style','pushbutton','Parent',gui_erp_save_single.other_option,... + 'String','Cancel','callback',@cancel_blc_dt); + uiextras.Empty('Parent', gui_erp_save_single.other_option); + gui_erp_save_single.run = uicontrol('Parent',gui_erp_save_single.other_option,'Style','pushbutton',... + 'String','Ok','callback',@run_blc_dt); + uiextras.Empty('Parent', gui_erp_save_single.other_option); + set(gui_erp_save_single.other_option,'Sizes',[80 170 100 170 80]); + + set(gui_erp_save_single.erp_file_name,'Sizes',[30 60 60 40]); + end + +%%------------------------------------------------------------------------%% +%%----------------------------Subfunction---------------------------------%% +%%------------------------------------------------------------------------%% + +%%----------------Setting for 'save ERPname" Radio----------------------------------------- + function erpname_radio(~,~) + gui_erp_save_single.erpname_save.Value = 1; + end + + +%%---------------Setting for filename-------------------------------------- + function erpname_str(Source,~) + if gui_erp_save_single.filename_save.Value ==1 + gui_erp_save_single.filename_str.String = gui_erp_save_single.erpname_str.String; + else + gui_erp_save_single.filename_str.String = ''; + end + end + +%%--------------Save erpname as filename----------------------------------- + function erpname_filename(~,~) + fileName = gui_erp_save_single.filename_str.String; + [px, fname, ext] = fileparts(fileName); + gui_erp_save_single.erpname_str.String = fname; + end + + +%%--------------------Select "Save ERP as"----------------------------------- + function filename_radio(Source,~) + if Source.Value == 0 + gui_erp_save_single.filename_str.String = ''; + gui_erp_save_single.filename_str.Enable = 'off'; + gui_erp_save_single.filename_browse.Enable = 'off'; + gui_erp_save_single.erpname_filename.Enable = 'off'; + else + gui_erp_save_single.filename_str.String = gui_erp_save_single.erpname_str.String; + gui_erp_save_single.filename_str.Enable = 'on'; + gui_erp_save_single.filename_browse.Enable = 'on'; + gui_erp_save_single.erpname_filename.Enable = 'on'; + end + end + + + +%%--------------------------Path------------------------------------------- + + function filename_browse(~,~) + fileName = gui_erp_save_single.filename_str.String; + if ~isempty(fileName) + [px, fname1, ext] = fileparts(fileName); + + [filename, filepath,filterindex] = uiputfile({'*.erp'; '*.mat'}, ... + 'Save Output file as',fname1); + else + [filename, filepath] = uiputfile({'*.erp'; '*.mat'}, ... + 'Save Output file as'); + end + + if isequal(filename,0) + disp('User selected Cancel'); + return + else + [px, fname, ext] = fileparts(filename); + if strcmp(ext,'') + if filterindex==1 || filterindex==3 + ext = '.erp'; + else + ext = '.mat'; + end + end + gui_erp_save_single.filename_str.String =[filepath,fname ext]; + end + end + + + + + + +%%-----------------------Cancel section----------------------------------- + function cancel_blc_dt(Source_localp_cancel,~) + Values_localp_cancel = Source_localp_cancel.Value; + if ~isempty(Values_localp_cancel) + beep; + disp('User selected Cancel'); + ERP_OUT = ERP_In; + close(f_ERP_save_single); + + ERPName = ERP_In.erpname; + px_fn = ERP_In.filepath; + fileName_save = ERP_In.filename; + erpworkingmemory('f_ERP_save_single_file',{ERPName,fileName_save,px_fn,0}); + return; + end + end + +%%-----------------------Run selection------------------------------------- + function run_blc_dt(Source_localp_run,~) + Values_localp_run = Source_localp_run.Value; + if ~isempty(Values_localp_run) + ERPName = gui_erp_save_single.erpname_str.String; + + if isempty(ERPName) + ERP_In.erpname = ERP_In.erpname; + ERPName = ERP_In.erpname; + else + ERP_In.erpname = ERPName; + end + + if gui_erp_save_single.filename_save.Value ==1 + FileName = gui_erp_save_single.filename_str.String; + [px_fn, fname_fn, ext_fn] = fileparts(FileName); + + fileName_save = [fname_fn ext_fn]; + + if strcmp(ext_fn,'.erp') + ERP_In.filename = fileName_save; + ERP = ERP_In; + [ERP, issave, erpcom] = pop_savemyerp( ERP,'filename', fileName_save, 'filepath', px_fn); + + elseif strcmp(ext_fn,'.mat') + ERP = ERP_In; + save([px_fn,filesep,fileName_save],'ERP'); + end + fileName_save = [fname_fn '.erp']; + else + px_fn = ERP_In.filepath; + fileName_save = ERP_In.filename; + end + + + + erpworkingmemory('f_ERP_save_single_file',{ERPName,fileName_save,px_fn,1}); + ERP_OUT = ERP_In; + close(f_ERP_save_single); + + return; + end + end + + + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.fig b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.fig new file mode 100755 index 00000000..24128fe2 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.m b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.m new file mode 100755 index 00000000..1ff500a1 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_save_single_file.m @@ -0,0 +1,320 @@ +function varargout = f_ERP_save_single_file(varargin) +% F_ERP_SAVE_SINGLE_FILE MATLAB code for f_ERP_save_single_file.fig +% F_ERP_SAVE_SINGLE_FILE, by itself, creates a new F_ERP_SAVE_SINGLE_FILE or raises the existing +% singleton*. +% +% H = F_ERP_SAVE_SINGLE_FILE returns the handle to a new F_ERP_SAVE_SINGLE_FILE or the handle to +% the existing singleton*. +% +% F_ERP_SAVE_SINGLE_FILE('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_SAVE_SINGLE_FILE.M with the given input arguments. +% +% F_ERP_SAVE_SINGLE_FILE('Property','Value',...) creates a new F_ERP_SAVE_SINGLE_FILE or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_save_single_file_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_save_single_file_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_save_single_file + +% Last Modified by GUIDE v2.5 02-Aug-2022 18:34:55 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_save_single_file_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_save_single_file_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_save_single_file is made visible. +function f_ERP_save_single_file_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_save_single_file + +try + erpname = varargin{1}; + filename = varargin{2}; + currenterp = varargin{3}; + [pathstr, file_name, ext] = fileparts(erpname); + erpname =file_name; +catch + erpname = ''; + filename = ''; + currenterp = ''; +end + +handles.erpnameor = erpname; +handles.output = []; +erpmenu = findobj('tag', 'erpsets'); + +if ~isempty(erpmenu) + handles.menuerp = get(erpmenu); + set(handles.menuerp.Children, 'Enable','off'); +end + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Save single Erpset GUI']) +set(handles.edit_erpname, 'String', erpname); +set(handles.radio_erpname,'Value',1); +if isempty(currenterp) + set(handles.current_erp_label,'String', ['No active erpset was found'],... + 'FontWeight','Bold', 'FontSize', 16); +else + + set(handles.current_erp_label,'String', ['Your active erpset is # ' num2str(currenterp)],... + 'FontWeight','Bold', 'FontSize', 16) +end +if ~isempty(filename) + set(handles.edit_filename, 'Enable', 'off'); + set(handles.edit_filename, 'String', ''); + set(handles.radiobutton_saveas, 'Value', 0); + set(handles.filename_erpname, 'Enable', 'off'); + set(handles.erpname_filename, 'Enable', 'off'); + set(handles.pushbutton_browse, 'Enable', 'off'); +else + set(handles.edit_filename, 'String', ''); + set(handles.radiobutton_saveas, 'Value', 0); + set(handles.edit_filename, 'Enable', 'off'); + set(handles.filename_erpname, 'Enable', 'off'); + set(handles.erpname_filename, 'Enable', 'off'); + set(handles.pushbutton_browse, 'Enable', 'off'); +end +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); +set(handles.filename_erpname,'BackgroundColor','white') + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_save_single_file_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +% try +% set(handles.menuerp.Children, 'Enable','on'); +% catch +% disp('ERPset menu was not found...') +% end +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + + + +% --- Executes on button press in radio_erpname. +function radio_erpname_Callback(hObject, eventdata, handles) +% hObject handle to radio_erpname (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of radio_erpname +Value_radio_erpname = get(hObject,'Value'); +set(handles.radio_erpname, 'Value', 1); + + + +function edit_erpname_Callback(hObject, eventdata, handles) + + +% --- Executes during object creation, after setting all properties. +function edit_erpname_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in erpname_filename. +function erpname_filename_Callback(hObject, eventdata, handles) + +fname = get(handles.edit_filename, 'String'); +% +if strcmp(fname,'') + msgboxText = 'You must enter a filename first!'; + title = 'ERPLAB: f_ERP_save_single GUI empty filename'; + errorfound(msgboxText, title); + return +end +[pathstr, fname, ext] = fileparts(fname); +erpname = fname; +set(handles.edit_erpname, 'String', erpname); + + +% --- Executes on button press in radiobutton_saveas. +function radiobutton_saveas_Callback(hObject, eventdata, handles) + +if get(hObject, 'Value') + set(handles.edit_filename, 'Enable', 'on'); + set(handles.filename_erpname, 'Enable', 'on'); + set(handles.pushbutton_browse, 'Enable', 'on'); + set(handles.erpname_filename, 'Enable', 'on'); +else + set(handles.edit_filename, 'Enable', 'off'); + set(handles.filename_erpname, 'Enable', 'off'); + set(handles.pushbutton_browse, 'Enable', 'off'); + set(handles.erpname_filename, 'Enable', 'off'); + set(handles.edit_filename, 'String', ''); +end + + +function edit_filename_Callback(hObject, eventdata, handles) +% hObject handle to edit_filename (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit_filename as text +% str2double(get(hObject,'String')) returns contents of edit_filename as a double + + +% --- Executes during object creation, after setting all properties. +function edit_filename_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit_filename (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in filename_erpname. +function filename_erpname_Callback(hObject, eventdata, handles) +% hObject handle to filename_erpname (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +fname = get(handles.edit_erpname, 'String'); +% +if strcmp(fname,'') || isempty(fname) + msgboxText = 'You must enter a filename first!'; + title = 'ERPLAB: f_ERP_save_single GUI empty filename'; + errorfound(msgboxText, title); + return +end +[pathstr, fname, ext] = fileparts(fname); +erpname = fname; +set(handles.edit_filename, 'String', erpname); + + + + +% --- Executes on button press in pushbutton_browse. +function pushbutton_browse_Callback(hObject, eventdata, handles) +fndefault = get(handles.edit_filename,'String'); +[fname, pathname] = uiputfile({'*.erp', 'ERPset (*.erp)';... + '*.mat', 'MAT-files (*.mat)';... + '*.*' , 'All Files (*.*)'},'Save Output file as',... + fndefault); + +if isequal(fname,0) + disp('User selected Cancel') + guidata(hObject, handles); + handles.owfp = 0; % over write file permission + guidata(hObject, handles); +else + set(handles.edit_filename,'String', fullfile(pathname, fname)); + % disp(['To save ERP, user selected ', fullfile(pathname, fname)]) + handles.owfp = 1; % over write file permission + guidata(hObject, handles); +end + + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +beep; +disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) +erpname = strtrim(get(handles.edit_erpname, 'String')); + +if isempty(erpname) + msgboxText = 'You must enter an erpname at least!'; + title = 'EStudio: f_ERP_save_single_file empty erpname'; + errorfound(msgboxText, title); + return +end + +fname = strtrim(get(handles.edit_filename, 'String')); +if ~isempty(fname) && get(handles.radiobutton_saveas, 'Value') + + [pathstr, name, ext] = fileparts(fname); + + if ~strcmp(ext,'.erp') && ~strcmp(ext,'.mat') + ext = '.erp'; + end + if strcmp(pathstr,'') + pathstr = cd; + end + + fullname = fullfile(pathstr, [name ext]); +elseif isempty(fname) && get(handles.radiobutton_saveas, 'Value') + msgboxText = 'You must enter a filename!'; + title = 'EStudio: f_ERP_save_single_file empty filename'; + errorfound(msgboxText, title); + return; +else + fullname = []; +end + +handles.output = {erpname, fullname}; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_simulation_panel.m b/studio_functions/GUIs/ERP Tab/f_ERP_simulation_panel.m new file mode 100644 index 00000000..5b18461e --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_simulation_panel.m @@ -0,0 +1,2161 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Mar. 2023 + +% ERPLAB Studio + +function varargout = f_ERP_simulation_panel(varargin) + +% global gui_erp_simulation; +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange); +% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + +%%---------------------------gui------------------------------------------- +[version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +if nargin == 0 + fig = figure(); % Parent figure + ERP_simulation_box = uiextras.BoxPanel('Parent', fig, 'Title', 'Create Artificial ERP Waveform', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_simulation_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Create Artificial ERP Waveform', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_simulation_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Create Artificial ERP Waveform', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +gui_erp_simulation = struct(); +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +erp_blc_dt_gui(FonsizeDefault); +varargout{1} = ERP_simulation_box; +%%********************Draw the GUI for ERP measurement tool***************** + function erp_blc_dt_gui(FonsizeDefault) + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + def = erpworkingmemory('pop_ERP_simulation'); + if isempty(def) + def = {1,1,100,50,0,-200,799,1,1000,0,1,0,1,0,1,10}; + end + + try + BasFunLabel = def{1}; + catch + BasFunLabel =1; + end + if isempty(BasFunLabel)|| ~isnumeric(BasFunLabel) + BasFunLabel =1; + end + if numel(BasFunLabel)~=1 + BasFunLabel=BasFunLabel(1); + end + + gui_erp_simulation.bsfun_box = uiextras.VBox('Parent',ERP_simulation_box,'Spacing',1,'BackgroundColor',ColorB_def); + + + %%-----------------------Plot axis--------------------------------- + gui_erp_simulation.plotasix_op = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_simulation.plot_erp = axes( 'Parent', gui_erp_simulation.plotasix_op);%, 'ActivePositionProperty', 'Position' + % + + %%----------------------information for Real data------------------ + gui_erp_simulation.realdata_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.realdata_title,... + 'String','Basic Information for Real Data','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + + gui_erp_simulation.realdatamatch_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.realerp_check = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.realdatamatch_title,... + 'callback',@erpcheckbox,'String','Compare with Real Data','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def,'Value',0); + uiextras.Empty('Parent', gui_erp_simulation.realdatamatch_title); + set(gui_erp_simulation.realdatamatch_title, 'Sizes',[200 70]); + + %%ERPset for real data + gui_erp_simulation.erpset_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.erpset_title,... + 'String','ERPset:','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + gui_erp_simulation.erpsetedit = uicontrol('Style', 'edit','Parent', gui_erp_simulation.erpset_title,... + 'callback',@erpsetedit,'String','','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off'); + + gui_erp_simulation.erpsetpopup = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.erpset_title,... + 'callback',@erpsetpopup,'String','Browse','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off'); + + %%Channel for real data + gui_erp_simulation.erpsetchan_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.erpsetchan_title,... + 'String','Channel:','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + gui_erp_simulation.channeledit = uicontrol('Style', 'edit','Parent', gui_erp_simulation.erpsetchan_title,... + 'callback',@channeledit,'String','','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off'); + + gui_erp_simulation.channelpopup = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.erpsetchan_title,... + 'callback',@channelpopup,'String','Browse','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off'); + + + %%bin for real data + gui_erp_simulation.erpsetbin_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.erpsetbin_title,... + 'String','Bin:','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + gui_erp_simulation.binedit = uicontrol('Style', 'edit','Parent', gui_erp_simulation.erpsetbin_title,... + 'callback',@binedit,'String','','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off'); + + gui_erp_simulation.binpopup = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.erpsetbin_title,... + 'callback',@binpopup,'String','Browse','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1],'Enable','off'); + + if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + gui_erp_simulation.realerp_check.Value =0; + EnableFlag = 'off'; + gui_erp_simulation.realerp_check.Enable = EnableFlag; + end + %%--------------------Basic information---------------------------- + gui_erp_simulation.asif_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.asif_title,... + 'String','Basic Information for Simulation','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + + + gui_erp_simulation.epoch_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.epoch_title,... + 'String','Epoch: Start','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + try + epochStart = def{6}; + catch + epochStart = -200; + end + gui_erp_simulation.epoch_start = uicontrol('Style', 'edit','Parent', gui_erp_simulation.epoch_title,... + 'callback',@epochstart,'String',num2str(epochStart),'FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.epoch_title,... + 'String','Stop','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + try + epochStop = def{7}; + catch + epochStop = 799; + end + + gui_erp_simulation.epoch_stop = uicontrol('Style', 'edit','Parent', gui_erp_simulation.epoch_title,... + 'callback',@epocstop,'String',num2str(epochStop),'FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.epoch_title,... + 'String','ms','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + set(gui_erp_simulation.epoch_title, 'Sizes',[80 60 40 60 25]); + + try + srateop = def{8}; + catch + srateop = 1; + end + + gui_erp_simulation.srate_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.srate=uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.srate_title,... + 'callback',@srateop,'String','Sampling rate','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + try + srate = def{9}; + catch + srate = 1000; + end + gui_erp_simulation.srateedit =uicontrol('Style', 'edit','Parent', gui_erp_simulation.srate_title,... + 'callback',@srateedit,'String', '','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]); + if srateop==1 + gui_erp_simulation.srate.Value =1; + gui_erp_simulation.srateedit.Enable = 'on'; + gui_erp_simulation.srateedit.String = num2str(srate); + else + gui_erp_simulation.srate.Value =0; + gui_erp_simulation.srateedit.Enable = 'off'; + gui_erp_simulation.srateedit.String = num2str(1000/srate); + end + + + uicontrol('Style', 'text','Parent', gui_erp_simulation.srate_title,... + 'String','Hz','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.srate_title); + set(gui_erp_simulation.srate_title, 'Sizes',[120 80 25 40]); + + + gui_erp_simulation.speriod_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_simulation.srateperiod=uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.speriod_title,... + 'callback',@srateperiod,'String','Sampling period','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + gui_erp_simulation.srateperiodedit =uicontrol('Style', 'edit','Parent', gui_erp_simulation.speriod_title,... + 'callback',@srateperiodedit,'String', '','FontSize',FonsizeDefault ,'BackgroundColor',[1 1 1]); + if srateop==1 + gui_erp_simulation.srateperiod.Value =0; + gui_erp_simulation.srateperiodedit.Enable = 'off'; + gui_erp_simulation.srateperiodedit.String = num2str(1000/srate); + else + gui_erp_simulation.srateperiod.Value =1; + gui_erp_simulation.srateperiodedit.Enable = 'on'; + gui_erp_simulation.srateperiodedit.String = num2str(srate); + end + + uicontrol('Style', 'text','Parent', gui_erp_simulation.speriod_title,... + 'String','ms','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.speriod_title); + set(gui_erp_simulation.speriod_title, 'Sizes',[120 80 25 40]); + + + %%----------------------Basic Function title type------------------- + gui_erp_simulation.bsfun_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.bsfun_title,... + 'String','Basic Function for Simulation','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + + %%ExGaussian Function + gui_erp_simulation.exguafun_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.exgua_op = uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.exguafun_option,... + 'String','ExGaussian','callback',@exguass_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==1 + gui_erp_simulation.exgua_op.Value =1; + ExgauEnable = 'on'; + else + gui_erp_simulation.exgua_op.Value =0; + ExgauEnable = 'off'; + end + uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_option,... + 'String','Peak amplitude','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + try + Exgau_amp = def{2}; + catch + Exgau_amp =0; + end + if isempty(Exgau_amp)|| ~isnumeric(Exgau_amp) + Exgau_amp =0; + end + if numel(Exgau_amp)~=1 + Exgau_amp = Exgau_amp(1); + end + gui_erp_simulation.exgua_peakamp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_option,... + 'String',num2str(Exgau_amp),'callback',@exgau_peakamp,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_option,... + 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + uiextras.Empty('Parent', gui_erp_simulation.exguafun_option); + set(gui_erp_simulation.exguafun_option, 'Sizes',[90 90 60 30 15]); + + gui_erp_simulation.exguafun_setting = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting); + uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_setting,... + 'String','Gaussian mean','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + try + Exgau_mean = def{3}; + catch + Exgau_mean =100; + end + if isempty(Exgau_mean) || ~isnumeric(Exgau_mean) + Exgau_mean =100; + end + gui_erp_simulation.exgua_mean = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_setting,... + 'String',num2str(Exgau_mean),'callback',@exgau_mean,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_setting,... + 'String','SD','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + try + ExGauSD = def{4}; + catch + ExGauSD =50; + end + if isempty(ExGauSD) || ~isnumeric(ExGauSD) + ExGauSD =50; + end + gui_erp_simulation.exgua_sd = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_setting,... + 'String',num2str(ExGauSD),'callback',@exgau_sd,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + set(gui_erp_simulation.exguafun_setting, 'Sizes',[15 90 50 40 50]); + + + gui_erp_simulation.exguafun_setting1 = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting1); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.exguafun_setting1,... + 'String','Exponential tau','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + try + ExGauTau = def{5}; + catch + ExGauTau =0; + end + if isempty(ExGauTau) || ~isnumeric(ExGauTau) + ExGauTau =0; + end + gui_erp_simulation.exgua_tau = uicontrol('Style', 'edit','Parent', gui_erp_simulation.exguafun_setting1,... + 'String',num2str(ExGauTau),'callback',@exgau_tau,'Enable',ExgauEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting1); + uiextras.Empty('Parent', gui_erp_simulation.exguafun_setting1); + set(gui_erp_simulation.exguafun_setting1, 'Sizes',[15 90 50 40 50]); + + %%Impulse function + gui_erp_simulation.impulse_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.impulse_op = uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.impulse_option,... + 'String','Impulse','callback',@impulse_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==2 + ImpulseEnable ='on'; + gui_erp_simulation.impulse_op.Value =1; + + else + ImpulseEnable = 'off'; + gui_erp_simulation.impulse_op.Value =0; + end + + uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_option,... + 'String','Peak amplitude','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_simulation.impulse_peakamp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.impulse_option,... + 'String','','callback',@impulse_peakamp,'Enable',ImpulseEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_option,... + 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==2 + try + impulsePeakamp = def{2}; + catch + impulsePeakamp = 1; + end + if isempty(impulsePeakamp) || ~isnumeric(impulsePeakamp) + impulsePeakamp =1; + end + gui_erp_simulation.impulse_peakamp.String = num2str(impulsePeakamp); + end + uiextras.Empty('Parent', gui_erp_simulation.impulse_option); + set( gui_erp_simulation.impulse_option, 'Sizes',[80 100 60 30 15]); + + gui_erp_simulation.impulse_setting = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.impulse_setting); + uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_setting,... + 'String','Latency','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_simulation.impulse_latency = uicontrol('Style', 'edit','Parent', gui_erp_simulation.impulse_setting,... + 'String','','callback',@impulse_latency,'Enable',ImpulseEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uicontrol('Style', 'text','Parent', gui_erp_simulation.impulse_setting,... + 'String','ms','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==2 + try + impulselat = def{3}; + catch + impulselat = 100; + end + if isempty(impulselat) || ~isnumeric(impulselat) + impulselat = 100; + end + gui_erp_simulation.impulse_latency.String = num2str(impulselat); + end + + uiextras.Empty('Parent', gui_erp_simulation.impulse_setting); + set(gui_erp_simulation.impulse_setting, 'Sizes',[80 100 60 30 15]); + + %%Boxcar function + gui_erp_simulation.square_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.square_op = uicontrol('Style', 'radiobutton','Parent', gui_erp_simulation.square_option,... + 'String','Boxcar','callback',@square_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.square_option,... + 'String','Peak amplitude','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==3 + squareEnable = 'on'; + else + squareEnable = 'off'; + end + gui_erp_simulation.square_peakamp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.square_option,... + 'String','','callback',@square_peakamp,'Enable',squareEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uicontrol('Style', 'text','Parent', gui_erp_simulation.square_option,... + 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.square_option); + if BasFunLabel==3 + try + sqaurePeakamp = def{2}; + catch + sqaurePeakamp = 1; + end + if isempty(sqaurePeakamp) || ~isnumeric(sqaurePeakamp) + sqaurePeakamp =1; + end + gui_erp_simulation.square_peakamp.String = num2str(sqaurePeakamp); + gui_erp_simulation.square_op.Value =1; + else + gui_erp_simulation.square_op.Value =0; + end + set( gui_erp_simulation.square_option, 'Sizes',[80 100 60 30 15]); + + gui_erp_simulation.square_setting = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.square_setting); + uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,... + 'String','Onset','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_simulation.square_onset = uicontrol('Style', 'edit','Parent', gui_erp_simulation.square_setting,... + 'String','','callback',@square_onset,'Enable',squareEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,... + 'String','ms','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==3 + try + Onsetlat = def{3}; + catch + Onsetlat = 100; + end + if isempty(Onsetlat) || ~isnumeric(Onsetlat) + Onsetlat =100; + end + gui_erp_simulation.square_onset.String = num2str(Onsetlat); + end + + + uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,... + 'String','Offset','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + gui_erp_simulation.square_offset = uicontrol('Style', 'edit','Parent', gui_erp_simulation.square_setting,... + 'String','','callback',@square_offset,'Enable',squareEnable,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uicontrol('Style', 'text','Parent', gui_erp_simulation.square_setting,... + 'String','ms','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + if BasFunLabel==3 + try + Offsetlat = def{4}; + catch + Offsetlat = 50; + end + if isempty(Offsetlat) || ~isnumeric(Offsetlat) + Offsetlat =50; + end + gui_erp_simulation.square_offset.String = num2str(Offsetlat); + end + set( gui_erp_simulation.square_setting, 'Sizes',[15 40 60 25 40 60 25]); + + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%-----------------------noise ------------------------------------ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + gui_erp_simulation.noisefun_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uicontrol('Style', 'text','Parent', gui_erp_simulation.noisefun_title,... + 'String','Noise Function for Simulation','FontWeight','bold','FontSize',FonsizeDefault ,'BackgroundColor',ColorB_def); + + + %%sin noise + gui_erp_simulation.sin_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.sin_op = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.sin_option ,... + 'String','Sinusoidal','callback',@sinoise_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + try + sinop = def{14}; + catch + sinop =0; + end + if isempty(sinop) + sinop =0; + end + if sinop==1 + gui_erp_simulation.sin_op.Value=1; + sinEnable = 'on'; + else + gui_erp_simulation.sin_op.Value=0; + sinEnable = 'off'; + end + + gui_erp_simulation.sin_amp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.sin_option ,... + 'String',' ','callback',@sin_amp,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',sinEnable); + try + sinamp = def{15}; + catch + sinamp =0; + end + if isempty(sinamp) ||~isnumeric(sinamp) + sinamp =0; + end + gui_erp_simulation.sin_amp.String = num2str(sinamp); + uicontrol('Style', 'text','Parent', gui_erp_simulation.sin_option,... + 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_simulation.sin_fre = uicontrol('Style', 'edit','Parent', gui_erp_simulation.sin_option ,... + 'String',' ','callback',@sinoise_fre,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',sinEnable); + uicontrol('Style', 'text','Parent', gui_erp_simulation.sin_option,... + 'String','Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + + try + sinfre = def{16}; + catch + sinfre =10; + end + if isempty(sinfre) ||~isnumeric(sinfre) || sinfre<=0 + sinfre =10; + end + gui_erp_simulation.sin_fre.String = num2str(sinfre); + set(gui_erp_simulation.sin_option, 'Sizes',[90 60 30 60 30]); + + %%white noise + gui_erp_simulation.white_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.white_op = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.white_title ,... + 'String','White','callback',@whitenoise_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + try + whiteop =def{10}; + catch + whiteop=0; + end + if isempty(whiteop) || ~isnumeric(whiteop) + whiteop=0; + end + if whiteop==1 + gui_erp_simulation.white_op.Value =1; + whitEnable = 'on'; + else + gui_erp_simulation.white_op.Value =0; + whitEnable = 'off'; + end + + gui_erp_simulation.white_amp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.white_title ,... + 'String',' ','callback',@white_amp,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',whitEnable); + + uicontrol('Style', 'text','Parent', gui_erp_simulation.white_title,... + 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.white_title); + uiextras.Empty('Parent', gui_erp_simulation.white_title); + try + whiteamp =def{11}; + catch + whiteamp=0; + end + if isempty(whiteamp) + whiteamp=0; + end + gui_erp_simulation.white_amp.String = num2str(whiteamp); + set(gui_erp_simulation.white_title, 'Sizes',[90 60 30 60 30]); + + %%pink noise + gui_erp_simulation.pink_title = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_simulation.pink_op = uicontrol('Style', 'checkbox','Parent', gui_erp_simulation.pink_title ,... + 'String','Pink','callback',@pinknoise_op,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + try + pinkeop =def{12}; + catch + pinkeop=0; + end + if isempty(pinkeop) || ~isnumeric(pinkeop) + pinkeop=0; + end + if pinkeop==1 + gui_erp_simulation.pink_op.Value =1; + pinkEnable = 'on'; + else + gui_erp_simulation.pink_op.Value =0; + pinkEnable = 'off'; + end + + gui_erp_simulation.pink_amp = uicontrol('Style', 'edit','Parent', gui_erp_simulation.pink_title ,... + 'String',' ','callback',@pink_amp,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Enable',pinkEnable); + try + pinkAmp = def{13}; + catch + pinkAmp=0; + end + gui_erp_simulation.pink_amp.String = num2str(pinkAmp); + uicontrol('Style', 'text','Parent', gui_erp_simulation.pink_title,... + 'String','μV','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.pink_title); + uiextras.Empty('Parent', gui_erp_simulation.pink_title); + set(gui_erp_simulation.pink_title, 'Sizes',[90 60 30 60 30]); + + %%update noise if needed New Noise + %%seeds for white and pink noise + gui_erp_simulation.SimulationSeed = erpworkingmemory('SimulationSeed'); + rng(1,'twister'); + SimulationSeed = rng; + erpworkingmemory('SimulationSeed',SimulationSeed); + %phase for sin noise + gui_erp_simulation.SimulationPhase = erpworkingmemory('SimulationPhase'); + SimulationPhase = 0; + erpworkingmemory('SimulationPhase',SimulationPhase); + + gui_erp_simulation.newnoise_option = uiextras.HBox('Parent', gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.newnoise_option); + gui_erp_simulation.newnoise_op = uicontrol('Style', 'pushbutton','Parent', gui_erp_simulation.newnoise_option ,... + 'String','Re-randomize noise','callback',@newnoise_op,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1],'Value',0); + % uiextras.Empty('Parent', gui_erp_simulation.newnoise_option); + % uiextras.Empty('Parent', gui_erp_simulation.newnoise_option); + uiextras.Empty('Parent', gui_erp_simulation.newnoise_option); + set(gui_erp_simulation.newnoise_option, 'Sizes',[70 130 70]); + + + %%Cancel and advanced + gui_erp_simulation.other_option = uiextras.HBox('Parent',gui_erp_simulation.bsfun_box,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_simulation.other_option,'BackgroundColor',ColorB_def); + gui_erp_simulation.simulation_help = uicontrol('Parent',gui_erp_simulation.other_option,'Style','pushbutton',... + 'String','?','FontWeight','bold','callback',@simulation_help,'FontSize',14,'BackgroundColor',[1 1 1]); + uiextras.Empty('Parent', gui_erp_simulation.other_option); + gui_erp_simulation.apply = uicontrol('Style','pushbutton','Parent',gui_erp_simulation.other_option,... + 'String','Apply','callback',@simulation_apply,'FontSize',FonsizeDefault,'BackgroundColor',[1 1 1]); + uiextras.Empty('Parent', gui_erp_simulation.other_option); + set(gui_erp_simulation.other_option, 'Sizes',[15 105 30 105 15]); + set(gui_erp_simulation.bsfun_box, 'Sizes',[200 20 25 25 25 25 20 25 25 25 20 25 25 25 25 25 25 25 20 25 25 25 25 25]); + plot_erp_simulation(); + end + + + +%%**************************************************************************************************************************************** +%%******************* Subfunctions *************************************************************************************************** +%%**************************************************************************************************************************************** + + +%%---------------------Match with real ERP?-------------------------------- + function erpcheckbox(Str,~) + Value = Str.Value; + if Value ==1 + EnableFlag = 'on'; + else + EnableFlag = 'off'; + end + if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + Str.Enable = 'off'; + EnableFlag = 'off'; + + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + return; + end + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + if Value ==1 + EnableFlagn = 'off'; + else + EnableFlagn = 'on'; + end + + gui_erp_simulation.epoch_start.Enable = EnableFlagn; + gui_erp_simulation.epoch_stop.Enable = EnableFlagn; + gui_erp_simulation.srate.Enable = EnableFlagn; + gui_erp_simulation.srateedit.Enable = EnableFlagn; + gui_erp_simulation.srateperiod.Enable = EnableFlagn; + gui_erp_simulation.srateperiodedit.Enable = EnableFlagn; + if Value ==0 + if gui_erp_simulation.srate.Value ==1 + gui_erp_simulation.srate.Value = 1; + gui_erp_simulation.srateedit.Enable = 'on'; + gui_erp_simulation.srateperiod.Value = 0; + gui_erp_simulation.srateperiodedit.Enable = 'off'; + else + gui_erp_simulation.srate.Value = 0; + gui_erp_simulation.srateedit.Enable = 'off'; + gui_erp_simulation.srateperiod.Value = 1; + gui_erp_simulation.srateperiodedit.Enable = 'on'; + end + end + plot_erp_simulation(); + end + +%%------------------------ERPset edit-------------------------------------- + function erpsetedit(Str,~) + ERPArray = str2num(Str.String); + if ~isempty(observe_ERPDAT.ALLERP) + if ~isempty(ERPArray) && min(ERPArray)>0 + if numel(ERPArray) ~=1 + ERPArray = ERPArray(1); + end + if ERPArray> length(observe_ERPDAT.ALLERP) + msgboxText = 'Create Artificial ERP Waveform -Real ERP: Input should be smaller than the length of ALLERP'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = ''; + return; + end + gui_erp_simulation.erpsetedit.String = num2str(ERPArray); + ERP =observe_ERPDAT.ALLERP(ERPsetArray); + if ~strcmpi(ERP.erpname,'No ERPset loaded') + EpochStart =[]; + EpochStop = []; + srate =[]; + try + EpochStart = ERP.times(1); + EpochStop = ERP.times(end); + srate = ERP.srate; + catch + end + if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate) + gui_erp_simulation.epoch_start.String = num2str(EpochStart); + gui_erp_simulation.epoch_stop.String = num2str(EpochStop); + if srate~=0 + gui_erp_simulation.srateedit.String = num2str(srate); + gui_erp_simulation.srateperiodedit.String = num2str(1000/srate); + end + end + end + else + msgboxText = 'Create Artificial ERP Waveform -Real ERP: Index of ERPset should be a positive numeric'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = ''; + return; + end + else + gui_erp_simulation.realerp_check.Value =0; + EnableFlag = 'off'; + gui_erp_simulation.realerp_check.Enable = EnableFlag; + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = ''; + return; + end + plot_erp_simulation(); + end + + +%%-----------------------ERPset popup-------------------------------------- + function erpsetpopup(~,~) + ERPArray = str2num(gui_erp_simulation.erpsetedit.String); + if ~isempty(ERPArray) + if numel(ERPArray)~=1 + ERPArray = ERPArray(1); + end + if ERPArray< 0 || ERPArray> length(observe_ERPDAT.ALLERP) + ERPArray = length(observe_ERPDAT.ALLERP); + end + gui_erp_simulation.erpsetedit.String = num2str(ERPArray); + if ~isempty(observe_ERPDAT.ALLERP) + for Numoferpset = 1:length(observe_ERPDAT.ALLERP) + listname{Numoferpset} = char(strcat(num2str(Numoferpset),'.',observe_ERPDAT.ALLERP(Numoferpset).erpname)); + end + indxlistb =ERPArray; + + titlename = 'Select one ERPset:'; + ERPsetArray = browsechanbinGUI(listname, indxlistb, titlename); + if ~isempty(ERPsetArray) + if numel(ERPsetArray)~=1 + ERPsetArray =ERPsetArray(1); + end + CURRENTERP = ERPsetArray; + ALLERP = observe_ERPDAT.ALLERP; + handles.CURRENTERP = ERPsetArray; + ERP =observe_ERPDAT.ALLERP(ERPsetArray); + if ~strcmpi(ERP.erpname,'No ERPset loaded') + EpochStart =[]; + EpochStop = []; + srate =[]; + if ~isempty(CURRENTERP) && CURRENTERP >0 && CURRENTERP<= length(ALLERP) + ERP = ALLERP(CURRENTERP); + else + ERP = ALLERP(length(ALLERP)); + end + try + EpochStart = ERP.times(1); + EpochStop = ERP.times(end); + srate = ERP.srate; + catch + end + if ~isempty(EpochStart) && ~isempty(EpochStop) && ~isempty(srate) + gui_erp_simulation.epoch_start.String = num2str(EpochStart); + gui_erp_simulation.epoch_stop.String = num2str(EpochStop); + if srate~=0 + gui_erp_simulation.srateedit.String = num2str(srate); + gui_erp_simulation.srateperiodedit.String = num2str(1000/srate); + end + end + gui_erp_simulation.erpsetedit.String = num2str(CURRENTERP); + end + else%%the user did not select one ERPset + msgboxText = 'Create Artificial ERP Waveform -Real ERP: User selected cancel'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + end + plot_erp_simulation(); + end + + +%%------------------------channel edit------------------------------------- + function channeledit(Str,~) + channelArray = str2num(Str.String); + if ~isempty(observe_ERPDAT.ALLERP) + if isempty(channelArray) + msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Channel"'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '1'; + return; + end + if numel(channelArray)~=1 + channelArray = channelArray(1); + end + if channelArray<=0 + msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Channel"'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '1'; + return; + end + Str.String = num2str(channelArray); + else + gui_erp_simulation.realerp_check.Value =0; + EnableFlag = 'off'; + gui_erp_simulation.realerp_check.Enable = EnableFlag; + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '1'; + return; + end + plot_erp_simulation(); + end + +%%------------------------channel popup------------------------------------ + function channelpopup(~,~) + if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + return; + end + if ~isempty(observe_ERPDAT.ALLERP) + ERPsetArray = str2num(gui_erp_simulation.erpsetedit.String); + if ~isempty(ERPsetArray) + if numel(ERPsetArray)~=1 + ERPsetArray = ERPsetArray(1); + end + if ERPsetArray> length(observe_ERPDAT.ALLERP) + ERPsetArray = length(observe_ERPDAT.ALLERP); + end + gui_erp_simulation.erpsetedit.String = num2str(ERPsetArray); + channelArray = str2num(gui_erp_simulation.channeledit.String); + if isempty(channelArray) + channelArray=1; + end + if numel(channelArray)~=1 + channelArray = channelArray(1); + end + if channelArray<=0 + channelArray=1; + end + ERP = observe_ERPDAT.ALLERP(ERPsetArray); + if max(channelArray(:)) >ERP.nchan + channelArray =1; + end + + for Numofchan = 1:observe_ERPDAT.ALLERP(ERPsetArray).nchan + listb{Numofchan}= strcat(num2str(Numofchan),'.',observe_ERPDAT.ALLERP(ERPsetArray).chanlocs(Numofchan).labels); + end + titlename = 'Select One Channel:'; + channelArray = browsechanbinGUI(listb, channelArray, titlename); + + if ~isempty(channelArray) + if numel(channelArray)~=1 + channelArray = channelArray(1); + end + gui_erp_simulation.channeledit.String = num2str(channelArray); + else + msgboxText = 'Create Artificial ERP Waveform-Real ERP: User selected cancel'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + end + plot_erp_simulation(); + end + +%%------------------------bin edit----------------------------------------- + function binedit(Str,~) + binArray = str2num(Str.String); + if ~isempty(observe_ERPDAT.ALLERP) + if isempty(binArray) + msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Bin"'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + % Str.String = '1'; + return; + end + if numel(binArray)~=1 + binArray = binArray(1); + end + if binArray<=0 + msgboxText = 'Create Artificial ERP Waveform -Real ERP: Please input one positive numeric for "Bin"'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '1'; + return; + end + Str.String = num2str(binArray); + else + gui_erp_simulation.realerp_check.Value =0; + EnableFlag = 'off'; + gui_erp_simulation.realerp_check.Enable = EnableFlag; + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '1'; + return; + end + plot_erp_simulation(); + end + + +%%-----------------------bin popup----------------------------------------- + function binpopup(~,~) + if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + return; + end + if ~isempty(observe_ERPDAT.ALLERP) + ERPsetArray = str2num(gui_erp_simulation.erpsetedit.String); + if ~isempty(ERPsetArray) + if numel(ERPsetArray)~=1 + ERPsetArray = ERPsetArray(1); + end + if ERPsetArray> length(observe_ERPDAT.ALLERP) + ERPsetArray = length(observe_ERPDAT.ALLERP); + end + gui_erp_simulation.erpsetedit.String = num2str(ERPsetArray); + binArray = str2num(gui_erp_simulation.binedit.String); + if isempty(binArray) + binArray=1; + end + if numel(binArray)~=1 + binArray = binArray(1); + end + if binArray<=0 + binArray=1; + end + ERP = observe_ERPDAT.ALLERP(ERPsetArray); + if max(binArray(:)) >ERP.nchan + binArray =1; + end + + for Numofchan = 1:observe_ERPDAT.ALLERP(ERPsetArray).nbin + listb{Numofchan}= strcat(num2str(Numofchan),'.',observe_ERPDAT.ALLERP(ERPsetArray).bindescr{Numofchan}); + end + titlename = 'Select One Bin:'; + binArray = browsechanbinGUI(listb, binArray, titlename); + + if ~isempty(binArray) + if numel(binArray)~=1 + binArray = binArray(1); + end + gui_erp_simulation.binedit.String = num2str(binArray); + else + msgboxText = 'Create Artificial ERP Waveform-Real ERP: User selected cancel'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + end + else + gui_erp_simulation.realerp_check.Value =0; + EnableFlag = 'off'; + gui_erp_simulation.realerp_check.Enable = EnableFlag; + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + msgboxText = 'Create Artificial ERP Waveform -Real ERP: ALLERPset is empty and cannot match simulation with it'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '1'; + return; + end + plot_erp_simulation(); + end + + +%%----------------------------epoch start---------------------------------- + function epochstart(Str,~) + epochStart = str2num( gui_erp_simulation.epoch_start.String); + epochStop = str2num( gui_erp_simulation.epoch_stop.String); + if epochStart>=epochStop + beep; + msgboxText = ['Create Artificial ERP Waveform - The value for epoch start should be smaller than epoch stop']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = ''; + return; + end + plot_erp_simulation(); + end + +%%----------------------------epoch stop----------------------------------- + function epocstop(Str,~) + epochStart = str2num( gui_erp_simulation.epoch_start.String); + epochStop = str2num( gui_erp_simulation.epoch_stop.String); + if epochStart>=epochStop + beep; + msgboxText = ['Create Artificial ERP Waveform - The value for epoch start should be smaller than epoch stop']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = ''; + return; + end + plot_erp_simulation(); + end + +%%---------------------Sampling rate option-------------------------------- + function srateop(~,~) + gui_erp_simulation.srate.Value =1; + gui_erp_simulation.srateedit.Enable = 'on'; + gui_erp_simulation.srateperiod.Value =0; + gui_erp_simulation.srateperiodedit.Enable = 'off'; + plot_erp_simulation(); + end + + +%%--------------Edit sampling rate----------------------------------------- + function srateedit(Str,~) + srate = str2num(Str.String); + if ~isempty(srate) && numel(srate)==1 && srate>0 + gui_erp_simulation.srateperiodedit.String = num2str(1000/srate); + else + msgboxText = ['Create Artificial ERP Waveform>sampling rate- the input should be a positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateperiodedit.String = ''; + return; + end + plot_erp_simulation(); + end + +%%---------------------Sampling period------------------------------------- + function srateperiod(~,~) + gui_erp_simulation.srate.Value =0; + gui_erp_simulation.srateedit.Enable = 'off'; + gui_erp_simulation.srateperiod.Value =1; + gui_erp_simulation.srateperiodedit.Enable = 'on'; + plot_erp_simulation(); + end + +%%----------------------Edit sampling period------------------------------- + function srateperiodedit(Str,~) + srateperiod = str2num(Str.String); + if ~isempty(srateperiod) && numel(srateperiod)==1 && srateperiod>0 + gui_erp_simulation.srateedit.String = num2str(1000/srateperiod); + else + msgboxText = ['Create Artificial ERP Waveform>sampling period- the input should be a positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateedit.String = ''; + return; + end + plot_erp_simulation(); + end + +%%--------------------------------Select ex-gaussian function-------------- + function exguass_op(~,~) + gui_erp_simulation.exgua_op.Value =1; + gui_erp_simulation.exgua_peakamp.Enable = 'on'; + gui_erp_simulation.exgua_mean.Enable = 'on'; + gui_erp_simulation.exgua_sd.Enable = 'on'; + gui_erp_simulation.exgua_tau.Enable = 'on'; + + gui_erp_simulation.impulse_op.Value = 0; + gui_erp_simulation.impulse_peakamp.Enable = 'off'; + gui_erp_simulation.impulse_latency.Enable = 'off'; + + gui_erp_simulation.square_op.Value = 0; + gui_erp_simulation.square_onset.Enable = 'off'; + gui_erp_simulation.square_offset.Enable = 'off'; + gui_erp_simulation.square_peakamp.Enable = 'off'; + plot_erp_simulation(); + end + + +%%---------------Peak amplitude for ex-Gaussian function------------------- + function exgau_peakamp(Str,~) + PeakAmp = str2num(Str.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> peak amplitude for Ex-Gaussian should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%------------------Guasssian mean----------------------------------------- + function exgau_mean(Str,~) + Mean = str2num(Str.String); + if isempty(Mean) || numel(Mean)~=1 + msgboxText = ['Create Artificial ERP Waveform> Gaussian mean for Ex-Gaussian should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%-----------------SD for Ex-Gaussian function----------------------------- + function exgau_sd(Str,~) + SD = str2num(Str.String); + if isempty(SD) || numel(SD)~=1 + msgboxText = ['Create Artificial ERP Waveform> SD for Ex-Gaussian should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + + +%%----------------Tau for Ex-Gaussian function----------------------------- + function exgau_tau(Str,~) + Tau = str2num(Str.String); + if isempty(Tau) || numel(Tau)~=1 + msgboxText = ['Create Artificial ERP Waveform> Exponential tau for Ex-Gaussian should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + + +%%--------------------------------impulse function------------------------- + function impulse_op(~,~) + gui_erp_simulation.exgua_op.Value =0; + gui_erp_simulation.exgua_peakamp.Enable = 'off'; + gui_erp_simulation.exgua_mean.Enable = 'off'; + gui_erp_simulation.exgua_sd.Enable = 'off'; + gui_erp_simulation.exgua_tau.Enable = 'off'; + + gui_erp_simulation.impulse_op.Value = 1; + gui_erp_simulation.impulse_peakamp.Enable = 'on'; + gui_erp_simulation.impulse_latency.Enable = 'on'; + gui_erp_simulation.square_op.Value = 0; + gui_erp_simulation.square_onset.Enable = 'off'; + gui_erp_simulation.square_offset.Enable = 'off'; + gui_erp_simulation.square_peakamp.Enable = 'off'; + plot_erp_simulation(); + end + +%%-------------Impulse peak amplitude-------------------------------------- + function impulse_peakamp(Str,~) + peakAmp = str2num(Str.String); + if isempty(peakAmp) + msgboxText = ['Create Artificial ERP Waveform>Impulse- peak amplitude should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%-------------------Latency for impluse----------------------------------- + function impulse_latency(Str,~) + peakLat = str2num(Str.String); + if isempty(peakLat) + msgboxText = ['Create Artificial ERP Waveform>Impulse- Latency should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%--------------------------------square function-------------------------- + function square_op(~,~) + gui_erp_simulation.exgua_op.Value =0; + gui_erp_simulation.exgua_peakamp.Enable = 'off'; + gui_erp_simulation.exgua_mean.Enable = 'off'; + gui_erp_simulation.exgua_sd.Enable = 'off'; + gui_erp_simulation.exgua_tau.Enable = 'off'; + + gui_erp_simulation.impulse_op.Value = 0; + gui_erp_simulation.impulse_peakamp.Enable = 'off'; + gui_erp_simulation.impulse_latency.Enable = 'off'; + gui_erp_simulation.square_op.Value = 1; + gui_erp_simulation.square_onset.Enable = 'on'; + gui_erp_simulation.square_offset.Enable = 'on'; + gui_erp_simulation.square_peakamp.Enable = 'on'; + plot_erp_simulation(); + end + + +%%--------------Peak amplitude for square function------------------------- + function square_peakamp(Str,~) + peakAmp = str2num(Str.String); + if isempty(peakAmp) + msgboxText = ['Create Artificial ERP Waveform>Square- peak amplitude should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%------------------Square onset latency----------------------------------- + function square_onset(Str,~) + onsetlat = str2num(Str.String); + if isempty(onsetlat) + msgboxText = ['Create Artificial ERP Waveform>Boxcar- Onset latency should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + offsetLat = str2num(gui_erp_simulation.square_offset.String); + if onsetlat>offsetLat + msgboxText = ['Create Artificial ERP Waveform>Boxcar- Onset latency should be smaller than',32,num2str(offsetLat)]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%------------------Boxcar offset latency---------------------------------- + function square_offset(Str,~) + offsetlat = str2num(Str.String); + if isempty(offsetlat) + msgboxText = ['Create Artificial ERP Waveform>Boxcar- Offset latency should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + onsetlat = str2num(gui_erp_simulation.square_onset.String); + if offsetlatBoxcar- Offset latency should be larger than',32,num2str(onsetlat)]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%-----------------update new noise if needed------------------------------ + function newnoise_op(~,~) + + %%reset the phase for sin signal + SimulationPhase = rand(1); + erpworkingmemory('SimulationPhase',SimulationPhase); + + %%reset seeds for white or pink noise + SimulationSeed = erpworkingmemory('SimulationSeed'); + try + SimulationSeed.Type = 'philox'; + SimulationSeed.Seed = SimulationSeed.Seed+1; + catch + SimulationSeed.Type = 'twister'; + SimulationSeed.Seed = 1; + end + erpworkingmemory('SimulationSeed',SimulationSeed); + gui_erp_simulation.SimulationSeed = SimulationSeed; + gui_erp_simulation.SimulationPhase = SimulationPhase; + plot_erp_simulation(); + end + +%%-----------------check box of sin function------------------------------- + function sinoise_op(Str,~) + Value = Str.Value; + if Value==1 + Enable = 'on'; + else + Enable = 'off'; + end + gui_erp_simulation.sin_amp.Enable = Enable; + gui_erp_simulation.sin_fre.Enable = Enable; + plot_erp_simulation(); + end + +%%---------------Peak amplitude for sin noise------------------------------ + function sin_amp(Str,~) + peakAmp = str2num(Str.String); + if isempty(peakAmp) + msgboxText = ['Create Artificial ERP Waveform>Sinusoidal noise- peak amplitude should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%------------------Frequency for sin noise-------------------------------- + function sinoise_fre(Str,~) + Fresin = str2num(Str.String); + if isempty(Fresin) || Fresin<=0 + msgboxText = ['Create Artificial ERP Waveform>Sinusoidal noise- frequency should be a positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = ''; + return; + end + plot_erp_simulation(); + end + +%%------------checkbox for white noise------------------------------------- + function whitenoise_op(Str,~) + if Str.Value ==1 + gui_erp_simulation.white_amp.Enable ='on'; + else + gui_erp_simulation.white_amp.Enable ='off'; + end + plot_erp_simulation(); + end + +%%-------------------Peak amplitude for white noise------------------------ + function white_amp(Str,~) + peakAmp = str2num(Str.String); + if isempty(peakAmp) + msgboxText = ['Create Artificial ERP Waveform>White noise- peak amplitude should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%--------------------check box for pink noise----------------------------- + function pinknoise_op(Str,~) + if Str.Value ==1 + gui_erp_simulation.pink_amp.Enable = 'on'; + else + gui_erp_simulation.pink_amp.Enable = 'off'; + end + plot_erp_simulation(); + end + +%%------------------peak amplitude of pink noise--------------------------- + function pink_amp(Str,~) + peakAmp = str2num(Str.String); + if isempty(peakAmp) + msgboxText = ['Create Artificial ERP Waveform>Pink noise- peak amplitude should be a numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + Str.String = '0'; + return; + end + plot_erp_simulation(); + end + +%%-----------------------Help---------------------------------------------- + function simulation_help(~,~) + + end + + +%%----------------------apply---------------------------------------------- + function simulation_apply(~,~) + erpworkingmemory('f_ERP_proces_messg','Create Artificial ERP waveform'); + observe_ERPDAT.Process_messg =1; %%Marking for the procedure has been started. + ALLERPCOM = evalin('base','ALLERPCOM'); + + EpochStart = str2num(gui_erp_simulation.epoch_start.String); + EpochStop = str2num(gui_erp_simulation.epoch_stop.String); + if gui_erp_simulation.srate.Value + Srate = str2num(gui_erp_simulation.srateedit.String); + if isempty(Srate) || numel(Srate)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling rate']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateedit.String = ''; + return; + end + if Srate<=0 + msgboxText = ['Create Artificial ERP Waveform>Sampling rate must be a positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateedit.String = ''; + return; + end + else%% sampling period + Speriod = str2num(gui_erp_simulation.srateperiodedit.String); + if isempty(Speriod) || numel(Speriod)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling period']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateperiodedit.String = ''; + return; + end + if Speriod<=0 + msgboxText = ['Create Artificial ERP Waveform>Sampling period must be a positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateperiodedit.String = ''; + return; + end + Srate = 1000/Speriod; + end + if isempty(EpochStart) || numel(EpochStart)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch start']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if isempty(EpochStop) || numel(EpochStop)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch stop']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if EpochStop<=EpochStart + msgboxText = ['Create Artificial ERP Waveform> Start time of epoch must be smaller than stop time of epoch']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if 1000/Srate>= (EpochStop-EpochStart) + msgboxText = ['Create Artificial ERP Waveform> Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + %%---------------------------Simulated signal------------------------------ + ExGauTau =0; + SDOffset =50; + MeanLatOnset =0; + if gui_erp_simulation.exgua_op.Value ==1 + BasFuncName = 'ExGaussian'; + BasPeakAmp = str2num(gui_erp_simulation.exgua_peakamp.String); + if isempty(BasPeakAmp) || numel(BasPeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + MeanLatOnset = str2num(gui_erp_simulation.exgua_mean.String); + if isempty(MeanLatOnset) || numel(MeanLatOnset)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Gaussian mean" of Ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + ExGauTau = str2num(gui_erp_simulation.exgua_tau.String); + if isempty(ExGauTau) || numel(ExGauTau)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Tau" of Ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + SDOffset = str2num(gui_erp_simulation.exgua_sd.String); + if isempty(SDOffset) || numel(SDOffset)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "SD" of Ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + elseif gui_erp_simulation.impulse_op.Value ==1 + BasFuncName = 'Impulse'; + BasPeakAmp = str2num(gui_erp_simulation.impulse_peakamp.String); + if isempty(BasPeakAmp) || numel(BasPeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of impulse function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + MeanLatOnset = str2num(gui_erp_simulation.impulse_latency.String); + if isempty(MeanLatOnset) || numel(MeanLatOnset)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "latency" of impulse function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + elseif gui_erp_simulation.square_op.Value ==1 + BasFuncName = 'Boxcar'; + BasPeakAmp = str2num(gui_erp_simulation.square_peakamp.String); + if isempty(BasPeakAmp) || numel(BasPeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + MeanLatOnset = str2num(gui_erp_simulation.square_onset.String); + if isempty(MeanLatOnset) || numel(MeanLatOnset)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "onset" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + SDOffset = str2num(gui_erp_simulation.square_offset.String); + if isempty(SDOffset) || numel(SDOffset)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "offset" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if SDOffset< MeanLatOnset + msgboxText = ['Create Artificial ERP Waveform> Please "offset" should be larger than "onset" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + end + %%---------------------------Noise signal---------------------------------- + if gui_erp_simulation.sin_op.Value==1 + SinoiseAmp = str2num(gui_erp_simulation.sin_amp.String); + if isempty(SinoiseAmp) || numel(SinoiseAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of sinusoidal noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + SinoiseFre = str2num(gui_erp_simulation.sin_fre.String); + if isempty(SinoiseFre) || numel(SinoiseFre)~=1 || SinoiseFre<=0 + msgboxText = ['Create Artificial ERP Waveform> Please define one positive numeric for "frequency" of sinusoidal noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + else + SinoiseAmp =0; + SinoiseFre =10; + end + if gui_erp_simulation.white_op.Value==1 + WhiteAmp = str2num(gui_erp_simulation.white_amp.String); + if isempty(WhiteAmp) || numel(WhiteAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of white noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + else + WhiteAmp =0; + end + + if gui_erp_simulation.pink_op.Value==1 + PinkAmp = str2num(gui_erp_simulation.pink_amp.String); + if isempty(PinkAmp) || numel(PinkAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of pink noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + else + PinkAmp = 0; + end + NewnoiseFlag = gui_erp_simulation.newnoise_op.Value; + + try + ALLERP = []; + [ERP, ERPCOM] = pop_ERP_simulation(ALLERP,BasFuncName,'EpochStart',EpochStart,'EpochStop',EpochStop,'Srate',Srate,'BasPeakAmp',BasPeakAmp,'MeanLatencyOnset',MeanLatOnset,'SDOffset',SDOffset,... + 'ExGauTau',ExGauTau,'SinoiseAmp',SinoiseAmp,'SinoiseFre',SinoiseFre,'WhiteAmp',WhiteAmp,'PinkAmp',PinkAmp,'NewnoiseFlag',NewnoiseFlag,'Saveas', 'off','History', 'gui'); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + + Answer = f_ERP_save_single_file(strcat(ERP.erpname),ERP.filename,length(observe_ERPDAT.ALLERP)+1); + if isempty(Answer) + beep; + return; + end + + if ~isempty(Answer) + ERPName = Answer{1}; + if ~isempty(ERPName) + ERP.erpname = ERPName; + end + fileName_full = Answer{2}; + if isempty(fileName_full) + ERP.filename = ERP.erpname; + elseif ~isempty(fileName_full) + [pathstr, file_name, ext] = fileparts(fileName_full); + ext = '.erp'; + if strcmp(pathstr,'') + pathstr = cd; + end + ERP.filename = [file_name,ext]; + ERP.filepath = pathstr; + %%----------save the current sdata as-------------------- + [ERP, issave, ERPCOM] = pop_savemyerp(ERP, 'erpname', ERP.erpname, 'filename', ERP.filename, 'filepath',ERP.filepath); + [ERP, ALLERPCOM] = erphistory(ERP, ALLERPCOM, ERPCOM,1); + end + end + assignin('base','ALLERPCOM',ALLERPCOM); + assignin('base','ERPCOM',ERPCOM); + if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + observe_ERPDAT.ALLERP = ERP; + else + observe_ERPDAT.ALLERP(length(observe_ERPDAT.ALLERP)+1) = ERP; + end + observe_ERPDAT.CURRENTERP = length(observe_ERPDAT.ALLERP); + observe_ERPDAT.ERP = observe_ERPDAT.ALLERP(observe_ERPDAT.CURRENTERP); + estudioworkingmemory('selectederpstudio',observe_ERPDAT.CURRENTERP); + erpworkingmemory('ERP_simulation',1); + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + observe_ERPDAT.Process_messg =2; + catch + % estudioworkingmemory('selectederpstudio',Selected_ERP_afd); + observe_ERPDAT.Process_messg =3; + observe_ERPDAT.Count_currentERP = observe_ERPDAT.Count_currentERP+1; + return; + end + observe_ERPDAT.Two_GUI = observe_ERPDAT.Two_GUI+1; + end + + +%%------------------------------------------------------------------------- +%%-----------------Plot ERP for the simulation----------------------------- +%%------------------------------------------------------------------------- + function plot_erp_simulation(~,~) + + MatchFlag = gui_erp_simulation.realerp_check.Value; + ALLERP = observe_ERPDAT.ALLERP; + ERP = []; + ERPArray = []; + ChannelArray = []; + binArray = []; + if MatchFlag==1 && ~isempty(ALLERP) + %%check ERPset + ERPArray = str2num(gui_erp_simulation.erpsetedit.String); + if ~isempty(ERPArray) + if numel(ERPArray)~=1 + ERPArray = ERPArray(1); + end + if ERPArray>0 && ERPArray <=length(ALLERP) + else + ERPArray = length(ALLERP); + end + else + ERPArray = length(ALLERP); + end + gui_erp_simulation.erpsetedit.String= num2str(ERPArray); + ERP = ALLERP(ERPArray); + %%check channels + ChannelArray = str2num(gui_erp_simulation.channeledit.String); + if isempty(ChannelArray) + ChannelArray =1; + else + if numel(ChannelArray)~=1 + ChannelArray = ChannelArray(1); + end + if ChannelArray>0 && ChannelArray<= ERP.nchan + else + ChannelArray =1; + end + end + gui_erp_simulation.channeledit.String = num2str(ChannelArray); + %%check bins + binArray = str2num(gui_erp_simulation.binedit.String); + if isempty(binArray) + binArray =1; + else + if numel(binArray)~=1 + binArray = binArray(1); + end + if binArray>0 && binArray<=ERP.nbin + else + binArray =1; + end + end + gui_erp_simulation.binedit.String = num2str(binArray); + end + + EpochStart = str2num(gui_erp_simulation.epoch_start.String); + EpochStop = str2num(gui_erp_simulation.epoch_stop.String); + if gui_erp_simulation.srate.Value + srate = str2num(gui_erp_simulation.srateedit.String); + if isempty(srate) || numel(srate)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling rate']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateedit.String = ''; + return; + end + if srate<=0 + msgboxText = ['Create Artificial ERP Waveform>Sampling rate must be a positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateedit.String = ''; + return; + end + else%% sampling period + Speriod = str2num(gui_erp_simulation.srateperiodedit.String); + if isempty(Speriod) || numel(Speriod)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for sampling period']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateperiodedit.String = ''; + return; + end + if Speriod<=0 + msgboxText = ['Create Artificial ERP Waveform>Sampling period must be positive numeric']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + gui_erp_simulation.srateperiodedit.String = ''; + return; + end + srate = 1000/Speriod; + end + if isempty(EpochStart) || numel(EpochStart)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch start']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if isempty(EpochStop) || numel(EpochStop)~=1 + msgboxText = ['Create Artificial ERP Waveform>Please define one numeric for epoch stop']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + if EpochStop<=EpochStart + msgboxText = ['Create Artificial ERP Waveform> Start time of epoch must be smaller than stop time of epoch']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if 1000/srate>= (EpochStop-EpochStart) + msgboxText = ['Create Artificial ERP Waveform> Please sampling period must be much smaller than ',32,num2str(EpochStop-EpochStart)]; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + + Times = []; + if EpochStart>=0 + count =0; + tIndex(1,1) =0; + for ii = 1:10000 + count = count+1000/srate; + if count<=EpochStop + tIndex(1,ii) = count; + else + break; + end + end + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + Times = tIndex(latsamp(1):end); + if Times(1)=EpochStart + tIndex(1,ii) = count; + else + break; + end + end + tIndex = sort(tIndex); + [xxx, latsamp, latdiffms] = closest(tIndex, [EpochStart,EpochStop]); + + Times = tIndex(1:latsamp(2)); + if Times(end)> EpochStop + Times(end) = []; + end + elseif EpochStart<0 && EpochStop>0 + tIndex1(1,1) = 0; + count =0; + for ii = 1:10000 + count = count-1000/srate; + if count>=EpochStart + tIndex1(1,ii+1) = count; + else + break; + end + end + tIndex2=[]; + count1 =0; + for ii = 1:10000 + count1 = count1+1000/srate; + if count1<=EpochStop + tIndex2(1,ii) = count1; + else + break; + end + end + Times = [sort(tIndex1),tIndex2]; + end + if ~isempty(ERP) + Times= ERP.times; + end + [x1,y1] = find(roundn(Times,-3)==roundn(EpochStart,-3)); + [x2,y2] = find(roundn(Times,-3)==roundn(EpochStop,-3)); + if isempty(y1) || isempty(y2) + msgboxText = 'Create Artificial ERP Waveform> The exact time periods you have specified cannot be exactly created with the specified sampling rate. We will round to the nearest possible time values when the ERPset is created.'; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + end + Desiredsignal = zeros(1,numel(Times)); + Desirednosizesin = zeros(1,numel(Times)); + Desirednosizewhite = zeros(1,numel(Times)); + Desirednosizepink = zeros(1,numel(Times)); + RealData = nan(1,numel(Times)); + %%---------------------------Simulated signal------------------------------ + if gui_erp_simulation.exgua_op.Value ==1 + Gua_PDF = zeros(1,numel(Times)); + PeakAmp = str2num(gui_erp_simulation.exgua_peakamp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + Meanamp = str2num(gui_erp_simulation.exgua_mean.String); + if isempty(Meanamp) || numel(Meanamp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Gaussian mean" of Ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + Tau = str2num(gui_erp_simulation.exgua_tau.String); + if isempty(Tau) || numel(Tau)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "Tau" of Ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + + SD = str2num(gui_erp_simulation.exgua_sd.String); + if isempty(SD) || numel(SD)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "SD" of Ex-Gaussian function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + SD = SD/100; + if Tau~=0 + Mu = Meanamp/100-Times(1)/100; + if Mu<0 + Mu = Meanamp/100; + end + if Tau<0 + Mu = abs((Times(end)/100-Times(1)/100)-Mu); + end + LegthSig = (Times(end)-Times(1))/100; + Sig = 0: LegthSig/numel(Times):LegthSig-LegthSig/numel(Times); + Gua_PDF = f_exgauss_pdf(Sig, Mu, SD, abs(Tau)); + if Tau<0 + Gua_PDF = fliplr(Gua_PDF); + end + elseif Tau==0 %%Gaussian signal + Times_new = Times/1000; + Gua_PDF = f_gaussian(Times_new,abs(PeakAmp),Meanamp/1000,SD/10); + end + Max = max(abs( Gua_PDF(:))); + Gua_PDF = PeakAmp*Gua_PDF./Max; + if PeakAmp~=0 + Desiredsignal = Gua_PDF; + end + elseif gui_erp_simulation.impulse_op.Value ==1 + PeakAmp = str2num(gui_erp_simulation.impulse_peakamp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of impulse function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + Latency = str2num(gui_erp_simulation.impulse_latency.String); + if isempty(Latency) || numel(Latency)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "latency" of impulse function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if LatencyTimes(end) + Latency=Times(end); + end + [xxx, latsamp, latdiffms] = closest(Times, Latency); + Desiredsignal(latsamp) = PeakAmp; + + elseif gui_erp_simulation.square_op.Value ==1 + PeakAmp = str2num(gui_erp_simulation.square_peakamp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "peak amplitude" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + onsetLat = str2num(gui_erp_simulation.square_onset.String); + if isempty(onsetLat) || numel(onsetLat)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "onset" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + offsetLat = str2num(gui_erp_simulation.square_offset.String); + if isempty(offsetLat) || numel(offsetLat)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "offset" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + if offsetLat< onsetLat + msgboxText = ['Create Artificial ERP Waveform> Please "offset" should be larger than "onset" of Boxcar function']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + [xxx, latsamp, latdiffms] = closest(Times, [onsetLat,offsetLat]); + Desiredsignal(latsamp(1):latsamp(2)) = PeakAmp; + end + + %%---------------------------Noise signal---------------------------------- + % SimulationSeed = erpworkingmemory('SimulationSeed'); + SimulationSeed= gui_erp_simulation.SimulationSeed ; + try + SimulationSeed_Type = SimulationSeed.Type; + SimulationSeed_seed=SimulationSeed.Seed; + catch + SimulationSeed_Type = 'twister'; + SimulationSeed_seed = 1; + end + %phase for sin noise + % SimulationPhase = erpworkingmemory('SimulationPhase'); + SimulationPhase = gui_erp_simulation.SimulationPhase; + if isempty(SimulationPhase) || ~isnumeric(SimulationPhase) + SimulationPhase = 0; + end + if numel(SimulationPhase)~=1 + SimulationPhase = SimulationPhase(1); + end + if SimulationPhase<0 || SimulationPhase>1 + SimulationPhase = 0; + end + + + if gui_erp_simulation.sin_op.Value==1 + PeakAmp = str2num(gui_erp_simulation.sin_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of sinusoidal noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + FreHz = str2num(gui_erp_simulation.sin_fre.String); + + if isempty(FreHz) || numel(FreHz)~=1 || FreHz<=0 + msgboxText = ['Create Artificial ERP Waveform> Please define one positive numeric for "frequency" of sinusoidal noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + X = Times/1000; + Desirednosizesin = PeakAmp*sin(2*FreHz*pi*(X)+2*pi*SimulationPhase); + + end + if gui_erp_simulation.white_op.Value==1 + PeakAmp = str2num(gui_erp_simulation.white_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of white noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + try + rng(SimulationSeed_seed,SimulationSeed_Type); + catch + rng(1,'twister'); + end + Desirednosizewhite = randn(1,numel(Times));%%white noise + + Desirednosizewhite = PeakAmp*Desirednosizewhite./max(abs(Desirednosizewhite(:))); + end + + if gui_erp_simulation.pink_op.Value==1 + PeakAmp = str2num(gui_erp_simulation.pink_amp.String); + if isempty(PeakAmp) || numel(PeakAmp)~=1 + msgboxText = ['Create Artificial ERP Waveform> Please define one numeric for "amplitude" of pink noise']; + fprintf(2,['\n Warning: ',msgboxText,'.\n']); + erpworkingmemory('f_ERP_proces_messg',msgboxText); + observe_ERPDAT.Process_messg =4; + return; + end + try + rng(SimulationSeed_seed,SimulationSeed_Type); + catch + rng(1,'twister'); + end + + Desirednosizepink = f_pinknoise(numel(Times)); + + Desirednosizepink = reshape(Desirednosizepink,1,numel(Desirednosizepink)); + Desirednosizepink = PeakAmp*Desirednosizepink./max(abs(Desirednosizepink(:))); + + end + Sig = Desirednosizesin+Desiredsignal+Desirednosizepink+Desirednosizewhite; + + if ~isempty(ERP) && ~isempty(ChannelArray) && ~isempty(binArray) + try + % hold(handles.axes1,'on'); + RealData = squeeze(ERP.bindata(ChannelArray,:,binArray)); + plot(gui_erp_simulation.plot_erp,Times,[Sig;RealData],'linewidth',1.5); + % legend(gui_erp_simulation.plot_erp,{'Simulated data',['Real data at',32,ERP.chanlocs(ChannelArray).labels]},'FontSize',FonsizeDefault); + % legend(gui_erp_simulation.plot_erp,'boxoff'); + + catch + end + else + plot(gui_erp_simulation.plot_erp,Times,Sig,'k','linewidth',1.5); + % legend(gui_erp_simulation.plot_erp,{'Simulated data'},'FontSize',FonsizeDefault); + % legend(gui_erp_simulation.plot_erp,'boxoff'); + end + gui_erp_simulation.plot_erp.FontSize =12; + xlim(gui_erp_simulation.plot_erp,[Times(1),Times(end)]); + end + + +%%-------enable the panel for real data------------------------------------ + function Count_currentERPChanged(~,~) + if length(observe_ERPDAT.ALLERP)==1 && strcmpi(observe_ERPDAT.ALLERP(1).erpname,'No ERPset loaded') + gui_erp_simulation.realerp_check.Value =0; + EnableFlag = 'off'; + gui_erp_simulation.realerp_check.Enable = EnableFlag; + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + else + gui_erp_simulation.realerp_check.Enable = 'on'; + if gui_erp_simulation.realerp_check.Value==1 + EnableFlag = 'on'; + else + EnableFlag = 'off'; + end + gui_erp_simulation.erpsetedit.Enable = EnableFlag; + gui_erp_simulation.erpsetpopup.Enable = EnableFlag; + gui_erp_simulation.channeledit.Enable = EnableFlag; + gui_erp_simulation.channelpopup.Enable = EnableFlag; + gui_erp_simulation.binedit.Enable = EnableFlag; + gui_erp_simulation.binpopup.Enable = EnableFlag; + if gui_erp_simulation.realerp_check.Value==1 + EnableFlags = 'off'; + else + EnableFlags = 'on'; + end + gui_erp_simulation.epoch_start.Enable = EnableFlags; + gui_erp_simulation.epoch_stop.Enable = EnableFlags; + gui_erp_simulation.srateedit.Enable = EnableFlags; + gui_erp_simulation.srateperiodedit.Enable = EnableFlags; + gui_erp_simulation.srate.Enable = EnableFlags; + gui_erp_simulation.srateperiod.Enable = EnableFlags; + if strcmpi(EnableFlags,'on') + if gui_erp_simulation.srate.Value ==1 + gui_erp_simulation.srateedit.Enable = 'on'; + gui_erp_simulation.srateperiod.Value =0; + gui_erp_simulation.srateperiodedit.Enable = 'off'; + else + gui_erp_simulation.srate.Value=0; + gui_erp_simulation.srateedit.Enable = 'off'; + gui_erp_simulation.srateperiod.Value =1; + gui_erp_simulation.srateperiodedit.Enable = 'on'; + end + end + end + plot_erp_simulation(); + end + +end +%Progem end: ERP simulation \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_spectral_GUI.m b/studio_functions/GUIs/ERP Tab/f_ERP_spectral_GUI.m new file mode 100755 index 00000000..db63c73b --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_spectral_GUI.m @@ -0,0 +1,892 @@ +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + +% ERPLAB Studio + +function varargout = f_ERP_spectral_GUI(varargin) + +% global gui_erp_spectral; +global observe_ERPDAT; +% addlistener(observe_ERPDAT,'ALLERP_change',@erpschange); +% addlistener(observe_ERPDAT,'ERP_change',@drawui_CB); +% addlistener(observe_ERPDAT,'CURRENTERP_change',@cerpchange); +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + +% erp_m_t_p = S_OUT.geterpvalues; + +defaulpar = erpworkingmemory('f_ERP_spectral'); +defaulpar{1} = 0;defaulpar{2} = [];defaulpar{3} = [];defaulpar{4} = [];defaulpar{5} = []; +defaulpar{6} = [];defaulpar{7} = []; +erpworkingmemory('f_ERP_spectral',defaulpar); +%%---------------------------gui------------------------------------------- +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end +if nargin == 0 + fig_title = figure(); % Parent figure + ERP_filtering_box = uiextras.BoxPanel('Parent', fig_title, 'Title', 'Spectral Analysis', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Spectral Analysis', 'Padding', 5,'BackgroundColor',ColorB_def); +else + ERP_filtering_box = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Spectral Analysis', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + + +gui_erp_spectral = struct(); + +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +erp_spectral_gui(FonsizeDefault); + +varargout{1} = ERP_filtering_box; +%%********************Draw the GUI for ERP measurement tool***************** + function erp_spectral_gui(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + + gui_erp_spectral.spectral = uiextras.VBox('Parent',ERP_filtering_box,'Spacing',1,'BackgroundColor',ColorB_def); + + gui_erp_spectral.amplitude_option = uiextras.HBox('Parent', gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def); + + %%amplitude and phase + gui_erp_spectral.dispaly_title = uicontrol('Style','text','Parent', gui_erp_spectral.amplitude_option,... + 'String','Display in:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_spectral.dispaly_title,'HorizontalAlignment','left'); + gui_erp_spectral.amplitude = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.amplitude_option,'String','Amplitude',... + 'callback',@spectral_amplitude,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_spectral.phase = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.amplitude_option,... + 'String','Phase','callback',@spectral_phase,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set( gui_erp_spectral.amplitude_option, 'Sizes', [80 100 100]); + %%%power and dB + gui_erp_spectral.pow_db = uiextras.HBox('Parent', gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_spectral.pow_db); + gui_erp_spectral.power = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.pow_db ,... + 'String','Power','callback',@spectral_power,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_spectral.db = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.pow_db ,... + 'String','dB','callback',@spectral_db,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set( gui_erp_spectral.pow_db , 'Sizes', [80 100 100]); + %%% + + gui_erp_spectral.hamwin_title_option = uiextras.HBox('Parent', gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_spectral.hamwin_title = uicontrol('Style','text','Parent', gui_erp_spectral.hamwin_title_option,'String','Hamming window:','FontSize',FonsizeDefault); + set( gui_erp_spectral.hamwin_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + gui_erp_spectral.hamwin_on = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.hamwin_title_option,... + 'String','On','callback',@spectral_hamwin_on,'Value',1,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + gui_erp_spectral.hamwin_off = uicontrol('Style', 'radiobutton','Parent', gui_erp_spectral.hamwin_title_option,... + 'String','Off','callback',@spectral_hamwin_off,'Value',0,'Enable',Enable_label,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + uiextras.Empty('Parent', gui_erp_spectral.hamwin_title_option,'BackgroundColor',ColorB_def); + set( gui_erp_spectral.hamwin_title_option, 'Sizes', [120 60 60 40]); + + + gui_erp_spectral.other_option = uiextras.HBox('Parent',gui_erp_spectral.spectral,'Spacing',1,'BackgroundColor',ColorB_def); + gui_erp_spectral.plot = uicontrol('Style','pushbutton','Parent',gui_erp_spectral.other_option,... + 'String','Plot','callback',@spectral_plot,'Enable',Enable_label,'FontSize',FonsizeDefault); + gui_erp_spectral.save = uicontrol('Style','pushbutton','Parent',gui_erp_spectral.other_option,... + 'String','Save','callback',@spectral_save,'Enable',Enable_label,'FontSize',FonsizeDefault); + gui_erp_spectral.advanced = uicontrol('Parent',gui_erp_spectral.other_option,'Style','pushbutton',... + 'String','Advanced','callback',@spectral_advanced,'Enable',Enable_label,'FontSize',FonsizeDefault); + + set(gui_erp_spectral.spectral, 'Sizes', [20 20 20 30]); + + end +%%**************************************************************************************************************************************** +%%******************* Subfunctions *************************************************************************************************** +%%**************************************************************************************************************************************** + +%%--------------------------------setting for amplitude------------------ + function spectral_amplitude(source,~) + gui_erp_spectral.amplitude.Value =1; + gui_erp_spectral.phase.Value = 0; + gui_erp_spectral.power.Value = 0; + gui_erp_spectral.db.Value =0; + end + +%%--------------------------Setting for phase----------------------------- + function spectral_phase(source,~) + gui_erp_spectral.phase.Value = 1; + gui_erp_spectral.amplitude.Value =0; + gui_erp_spectral.power.Value = 0; + gui_erp_spectral.db.Value =0; + end + +%%--------------------Setting for power------------------------------------ + function spectral_power(~,~) + gui_erp_spectral.phase.Value = 0; + gui_erp_spectral.amplitude.Value =0; + gui_erp_spectral.power.Value =1; + gui_erp_spectral.db.Value =0; + end + +%%--------------------Setting for dB------------------------------------ + function spectral_db(~,~) + gui_erp_spectral.phase.Value = 0; + gui_erp_spectral.amplitude.Value =0; + gui_erp_spectral.power.Value =0; + gui_erp_spectral.db.Value =1; + end + + +%%-------------------------Setting for hamming window:on------------------- + function spectral_hamwin_on(~,~) + gui_erp_spectral.hamwin_on.Value = 1; + gui_erp_spectral.hamwin_off.Value = 0; + end + +%%-------------------------Setting for hamming window:off------------------- + function spectral_hamwin_off(~,~) + gui_erp_spectral.hamwin_on.Value = 0; + gui_erp_spectral.hamwin_off.Value = 1; + end + + + +%%--------------------------Setting for plot------------------------------- + function spectral_plot(~,~) + if gui_erp_spectral.hamwin_on.Value + iswindowed =1; + else + iswindowed = 0; + end + + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index; + + + defaulpar1 = erpworkingmemory('f_ERP_spectral'); + BinArray = []; + ChanArray = []; + FreqRange = []; + + if checked_ERPset_Index_bin_chan(1) ==1 + BinArray = []; + elseif checked_ERPset_Index_bin_chan(2) ==2 + ChanArray = []; + end + + try + + BinArray = S_binchan.bins{1}; + ChanArray = S_binchan.elecs_shown{1}; + catch + BinArray = []; + ChanArray = []; + end + + + %%Plot the spectrum for the selected ERPset + % try + for Numoferpset = 1:numel(Selected_erpset) + %%% + ERP_curret_s = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)); + if strcmp(ERP_curret_s.datatype,'ERP') + ERP_FFT = f_getFFTfromERP(ERP_curret_s,iswindowed); + elseif strcmp(ERP_curret_s.datatype,'EFFT') + ERP_FFT = ERP_curret_s; + end + + ColumnNum = 1; + if isempty(BinArray) + BinArray = [1:ERP_curret_s.nbin]; + end + + if isempty(ChanArray) + ChanArray = [1:ERP_curret_s.nchan]; + end + + if max(BinArray(:))> ERP_FFT.nbin + BinArray = [1:ERP_FFT.nbin]; + end + + if max(ChanArray(:))> ERP_FFT.nchan + ChanArray = [1:ERP_FFT.nchan]; + end + RowNum = ceil(numel(ChanArray)/ColumnNum); + + if gui_erp_spectral.amplitude.Value + ERP_FFT.bindata = abs(ERP_FFT.bindata); + figure_name = ['Spectral analysis: Amplitude for ',32,ERP_FFT.erpname]; + elseif gui_erp_spectral.phase.Value + ERP_FFT.bindata = angle(ERP_FFT.bindata); + figure_name = ['Spectral analysis: Phase for ',32,ERP_FFT.erpname]; + elseif gui_erp_spectral.power.Value + ERP_FFT.bindata = abs(ERP_FFT.bindata).^2; + figure_name = ['Spectral analysis: Power for ',32,ERP_FFT.erpname]; + elseif gui_erp_spectral.db.Value + ERP_FFT.bindata = 20*log10(abs(ERP_FFT.bindata)); + figure_name = ['Spectral analysis: dB for ',32,ERP_FFT.erpname]; + end + + fig = figure('Name',figure_name); + set(fig,'outerposition',get(0,'screensize')); + + line_colors = erpworkingmemory('PWColor'); + if size(line_colors,1)~= ERP_FFT.nbin + if ERP_FFT.nbin> size(line_colors,1) + line_colors = get_colors(ERP_FFT.nbin); + else + line_colors = line_colors(1:ERP_FFT.nbin,:,:); + end + end + + if isempty(line_colors) + line_colors = get_colors(ERP_FFT.nbin); + end + FreqRange=[ERP_FFT.times(1), ERP_FFT.times(end)]; + FreqTick = default_time_ticks(ERP_FFT, FreqRange); + FreqTick = str2num(FreqTick{1}); + ERP_FFT.bindata = ERP_FFT.bindata(ChanArray,:,BinArray); + ERP_FFT.nbin = numel(BinArray); + ERP_FFT.nchan = numel(ChanArray); + ERP_FFT.chanlocs = ERP_FFT.chanlocs(ChanArray); + ERP_FFT.bindescr = ERP_FFT.bindescr(BinArray); + + pbox = f_getrow_columnautowaveplot(ChanArray); + try + RowNum = pbox(1); + ColumnNum = pbox(2); + catch + RowNum = numel(ChanArray); + ColumnNum = 1; + end + + count = 0; + for Numofcolumn = 1:ColumnNum + for Numofrow = 1: RowNum + count = count+1; + if ColumnNum*RowNum<5 + pause(1); + end + if count>ERP_FFT.nchan + break; + end + p_ax = subplot(RowNum,ColumnNum,count); + set(gca,'fontsize',14); + hold on; + temp = squeeze(ERP_FFT.bindata); + for Numofplot = 1:ERP_FFT.nbin + h_p(Numofplot) = plot(p_ax,ERP_FFT.times,squeeze(ERP_FFT.bindata(count,:,Numofplot)),'LineWidth',1,'Color',line_colors(Numofplot,:,:)); + end + axis(p_ax,[floor(ERP_FFT.times(1)),ceil(ERP_FFT.times(end)), 1.1*min(temp(:)) 1.1*max(temp(:))]); + xticks(p_ax,FreqTick); + if count == 1 + title(p_ax,[ERP_FFT.chanlocs(count).labels],'FontSize',14); %#ok<*NODEF> + legend(p_ax,ERP_FFT.bindescr,'FontSize',14); + legend(p_ax,'boxoff'); + else + title(p_ax,ERP_FFT.chanlocs(count).labels,'FontSize',14); + end + xlabel(p_ax,'Frequency/Hz','FontSize',14); + if gui_erp_spectral.phase.Value + ylabel(p_ax,'Angle/degree','FontSize',14); + elseif gui_erp_spectral.amplitude.Value + ylabel(p_ax,'Amplitude/\muV','FontSize',14); + elseif gui_erp_spectral.power.Value + ylabel(p_ax,'Power/\muV^2','FontSize',14); + elseif gui_erp_spectral.db.Value + ylabel(p_ax,'Decibels/dB','FontSize',14); + end + for NUmoflabel = 1:length(ERP_FFT.times) + X_label{NUmoflabel} = []; + end + set(gca,'TickDir','out'); + set(gca,'LineWidth',2); + end + end + + end%%end loop for ERPSET + + end + + +%%-----------------Setting for save option--------------------------------- + function spectral_save(~,~) + pathName = erpworkingmemory('ERP_save_folder'); + if isempty(pathName) + pathName = cd; + end + + if gui_erp_spectral.hamwin_on.Value + iswindowed =1; + else + iswindowed = 0; + end + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index; + + + BinArray = []; + ChanArray = []; + FreqRange = []; + + if checked_ERPset_Index_bin_chan(1) ==1 + BinArray = []; + elseif checked_ERPset_Index_bin_chan(2) ==2 + ChanArray = []; + end + + try + BinArray = S_binchan.bins{1}; + ChanArray = S_binchan.elecs_shown{1}; + catch + BinArray = []; + ChanArray = []; + end + try + ALLERPCOM = evalin('base','ALLERPCOM'); + catch + ALLERPCOM = []; + assignin('base','ALLERPCOM',ALLERPCOM); + end + %%Plot the spectrum for the selected ERPset + %-----------Setting for import------------------------------------- + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.7020 0.77 0.85]; + end + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',ColorB_def); + [ind,tf] = listdlg('ListString',{'".mat"','".csv"'},'SelectionMode','single','PromptString','Please select a type to export to...','Name','Export Spectrum for Selected ERPset to','OKString','Ok'); + set(0,'DefaultUicontrolBackgroundColor',[1 1 1]); + if isempty(ind) + beep; + disp(['User selected cancel']); + return; + end + for Numoferpset = 1:numel(Selected_erpset) + %%% + ERP_curret_s = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)); + if strcmp(ERP_curret_s.datatype,'ERP') + ERP_FFT = f_getFFTfromERP(ERP_curret_s,iswindowed); + else + ERP_FFT = ERP_curret_s; + end + if isempty(BinArray) + BinArray = [1:ERP_curret_s.nbin]; + end + + if isempty(ChanArray) + ChanArray = [1:ERP_curret_s.nchan]; + end + + if max(BinArray(:))> ERP_FFT.nbin + BinArray = [1:ERP_FFT.nbin]; + end + + if max(ChanArray(:))> ERP_FFT.nchan + ChanArray = [1:ERP_FFT.nchan]; + end + + if isempty(FreqRange) || FreqRange(2)>ERP_FFT.times(end) + FreqRange=[ERP_FFT.times(1), ERP_FFT.times(end)]; + end + [xxx, latsamp, latdiffms] = closest(ERP_FFT.times, FreqRange); + tmin = latsamp(1); + tmax = latsamp(2); + ERP_FFT.bindata = ERP_FFT.bindata(ChanArray,tmin:tmax,BinArray); + ERP_FFT.nbin = numel(BinArray); + ERP_FFT.nchan = numel(ChanArray); + ERP_FFT.chanlocs = ERP_FFT.chanlocs(ChanArray); + ERP_FFT.bindescr = ERP_FFT.bindescr(BinArray); + ERP_FFT.times = ERP_FFT.times(tmin:tmax); + + if strcmp(ERP_curret_s.datatype,'ERP') + if gui_erp_spectral.amplitude.Value + ERP_FFT.bindata = abs(ERP_FFT.bindata); + figure_name = [ERP_FFT.erpname,'_Spectrum_Amplitude']; + elseif gui_erp_spectral.phase.Value + ERP_FFT.bindata = angle(ERP_FFT.bindata); + figure_name = [ERP_FFT.erpname,'_Spectrum_Phase']; + elseif gui_erp_spectral.power.Value + ERP_FFT.bindata = abs(ERP_FFT.bindata).^2; + figure_name = [ERP_FFT.erpname,'_Spectrum_Power']; + elseif gui_erp_spectral.db.Value + ERP_FFT.bindata = 20*log10(abs(ERP_FFT.bindata)); + figure_name = [ERP_FFT.erpname,'_Spectrum_ dB']; + end + else + if gui_erp_spectral.amplitude.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_amplitude']; + elseif gui_erp_spectral.phase.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_phase']; + elseif gui_erp_spectral.power.Value + figure_name = strcat(ERP_FFT.erpname,'Spectrum_Power'); + + elseif gui_erp_spectral.db.Value + figure_name = strcat(ERP_FFT.erpname,'_Spectrum_dB'); + end + end + + if ind==1 + + [filenamei, pathname] = uiputfile({'*.mat';'*.*'},['Save',32,'"',ERP_FFT.erpname,'"', 32,'as'],fullfile(pathName,figure_name)); + if isequal(filenamei,0) + disp('User selected Cancel') + return + else + [pathx, filename, ext] = fileparts(filenamei); + ext = '.mat'; + filename = [filename ext]; + end + + if strcmpi(ext,'.mat') + [ERP_FFT, issave, ERPCOM] = pop_savemyerp(ERP_FFT, 'erpname', ERP_FFT.erpname, 'filename', filename, 'filepath',pathname); + [~, ALLERPCOM] = erphistory(ERP_FFT, ALLERPCOM, ERPCOM); + end + + %%save as '.csv' + elseif ind==2 + def = erpworkingmemory('f_export2csvGUI'); + if isempty(def) + def = {1, 1, 1, 3, ''}; + end + def{5} = fullfile(pathName,ERP_FFT.filename); + answer_export = f_export2csvGUI(ERP_FFT,def); + erpworkingmemory('f_export2csvGUI',answer_export); + if isempty(answer_export) + beep; + disp('User selected cancel!!!'); + return; + end + binArray = [1:ERP_FFT.nbin]; + decimal_num = answer_export{4}; + istime =answer_export{1} ; + electrodes=answer_export{2} ; + transpose=answer_export{3}; + filenamei = answer_export{5}; + [pathx, filename, ext] = fileparts(filenamei); + ext = '.csv'; + if isempty(pathx) + pathx =cd; + end + filename = [filename ext]; + mkdir([pathx,filesep]); + try + export2csv_spectranl_analysis(ERP_FFT,fullfile(pathx,filename), binArray,istime, electrodes,transpose, decimal_num); + catch + beep; + disp('Fail to save selected ERPset as ".csv"!!!'); + return; + end + end + + end + end + + +%%-------------------Setting for advance option--------------------------- + function spectral_advanced(~,~) + pathName_folder = erpworkingmemory('ERP_save_folder'); + if isempty(pathName_folder) + pathName_folder = cd; + end + + if gui_erp_spectral.hamwin_on.Value + iswindowed =1; + else + iswindowed = 0; + end + + try + def = erpworkingmemory('f_spectral_analysis_adavance'); + catch + def = {1,[], [], [1 16], 1, 1,1,0}; + end + if isempty(def) + def = {1,[], [], [1 16], 1, 1,1,0}; + + end + try + ALLERPCOM = evalin('base','ALLERPCOM'); + catch + ALLERPCOM = []; + assignin('base','ALLERPCOM',ALLERPCOM); + end + + Selected_erpset = estudioworkingmemory('selectederpstudio'); + if isempty(Selected_erpset) + Selected_erpset = observe_ERPDAT.CURRENTERP; + S_erpbinchan = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,Selected_erpset); + estudioworkingmemory('geterpbinchan',S_erpbinchan.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpbinchan.geterpplot); + estudioworkingmemory('selectederpstudio',Selected_erpset); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + checked_ERPset_Index_bin_chan =S_binchan.checked_ERPset_Index; + + try + BinArray = S_binchan.bins{1}; + ChanArray = S_binchan.elecs_shown{1}; + catch + BinArray = []; + ChanArray = []; + end + + def{2} = BinArray; + def{3} = ChanArray; + + ERP_d =f_getFFTfromERP(observe_ERPDAT.ERP,iswindowed); + + + defaulpar1 = f_spectral_analysis_advance(ERP_d,def); + if isempty(defaulpar1) + beep; + disp('User selected cancel!!!'); + return; + end + erpworkingmemory('f_spectral_analysis_adavance',defaulpar1); + + + BinArray = defaulpar1{2}; + ChanArray = defaulpar1{3}; + if checked_ERPset_Index_bin_chan(1)==1 + BinArray = []; + end + + if checked_ERPset_Index_bin_chan(2) ==2 + ChanArray = []; + end + + FreqRange = defaulpar1{4}; + FreqTick = defaulpar1{5}; + RowNum = defaulpar1{6}; + ColumnNum = defaulpar1{7}; + Save_label = defaulpar1{8}; + + if Save_label + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.7020 0.77 0.85]; + end + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',ColorB_def); + [ind,tf] = listdlg('ListString',{'".mat"','".csv"'},'SelectionMode','single','PromptString','Please select a type to export to...','Name','Export Spctrum for Selected ERPset to','OKString','Ok'); + set(0,'DefaultUicontrolBackgroundColor',[1 1 1]); + + if isempty(ind) + beep; + disp(['User selected cancel']); + return; + end + end + + %%Plot the spectrum for the selected ERPset + % Loop start for the selected ERPsets try + for Numoferpset = 1:numel(Selected_erpset) + %%% + ERP_curret_s = observe_ERPDAT.ALLERP(Selected_erpset(Numoferpset)); + if strcmp(ERP_curret_s.datatype,'ERP') + ERP_FFT = f_getFFTfromERP(ERP_curret_s,iswindowed); + elseif strcmp(ERP_curret_s.datatype,'EFFT') + ERP_FFT = ERP_curret_s; + else + disp(['Please selected ERPsets']); + return; + end + if isempty(ColumnNum) + ColumnNum = 1; + end + + if isempty(ChanArray) + ChanArray = [1:ERP_curret_s.nchan]; + end + + if isempty(RowNum) + RowNum = ceil(numel(ChanArray)/ColumnNum); + end + if isempty(BinArray) + BinArray = [1:ERP_curret_s.nbin]; + end + + if max(BinArray(:))> ERP_FFT.nbin + BinArray = [1:ERP_FFT.nbin]; + end + + if max(ChanArray(:))> ERP_FFT.nchan + ChanArray = [1:ERP_FFT.nchan]; + end + + if isempty(FreqRange) || FreqRange(2)>ERP_FFT.times(end) + FreqRange=[ERP_FFT.times(1), ERP_FFT.times(end)]; + FreqTick = default_time_ticks(ERP_FFT, FreqRange); + FreqTick = str2num(FreqTick{1}); + end + if isempty(FreqTick) + FreqTick = default_time_ticks(ERP_FFT, FreqRange); + FreqTick = str2num(FreqTick{1}); + end + + [xxx, latsamp, latdiffms] = closest(ERP_FFT.times, FreqRange); + tmin = latsamp(1); + tmax = latsamp(2); + ERP_FFT.bindata = ERP_FFT.bindata(ChanArray,tmin:tmax,BinArray); + ERP_FFT.nbin = numel(BinArray); + ERP_FFT.nchan = numel(ChanArray); + ERP_FFT.chanlocs = ERP_FFT.chanlocs(ChanArray); + ERP_FFT.bindescr = ERP_FFT.bindescr(BinArray); + ERP_FFT.times = ERP_FFT.times(tmin:tmax); + ERP_FFT.xmin = ERP_FFT.times(1); + ERP_FFT.xmax = ERP_FFT.times(end); + ERP_FFT.pnts = numel(ERP_FFT.times); + if strcmp(ERP_curret_s.datatype,'ERP') + if gui_erp_spectral.amplitude.Value + ERP_FFT.bindata = abs(ERP_FFT.bindata); + figure_name = ['Spectral analysis: Amplitude for ',32,ERP_FFT.erpname]; + elseif gui_erp_spectral.phase.Value + ERP_FFT.bindata = angle(ERP_FFT.bindata); + figure_name = ['Spectral analysis: Phase for ',32,ERP_FFT.erpname]; + elseif gui_erp_spectral.power.Value + ERP_FFT.bindata = abs(ERP_FFT.bindata).^2; + figure_name = ['Spectral analysis: Power for ',32,ERP_FFT.erpname]; + elseif gui_erp_spectral.db.Value + ERP_FFT.bindata = 20*log10(abs(ERP_FFT.bindata)); + figure_name = ['Spectral analysis: dB for ',32,ERP_FFT.erpname]; + end + else + if gui_erp_spectral.amplitude.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_amplitude']; + elseif gui_erp_spectral.phase.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_phase']; + elseif gui_erp_spectral.power.Value + figure_name = ['Spectral analysis: Power for ',32,ERP_FFT.erpname]; + + elseif gui_erp_spectral.db.Value + figure_name = ['Spectral analysis: dB for ',32,ERP_FFT.erpname]; + end + end + + if ~Save_label + fig = figure('Name',figure_name); + set(fig,'outerposition',get(0,'screensize')); + + line_colors = erpworkingmemory('PWColor'); + if size(line_colors,1)~= ERP_FFT.nbin + if ERP_FFT.nbin> size(line_colors,1) + line_colors = get_colors(ERP_FFT.nbin); + else + line_colors = line_colors(1:ERP_FFT.nbin,:,:); + end + end + + if isempty(line_colors) + line_colors = get_colors(ERP_FFT.nbin); + end + + count = 0; + for Numofcolumn = 1:ColumnNum + for Numofrow = 1: RowNum + count = count+1; + % waitbar(count/(ColumnNum*RowNum),Hw); + if ColumnNum*RowNum<5 + pause(1); + end + if count>ERP_FFT.nchan + break; + end + p_ax = subplot(RowNum,ColumnNum,count); + set(gca,'fontsize',14); + hold on; + temp = squeeze(ERP_FFT.bindata(:,:,:)); + for Numofplot = 1:ERP_FFT.nbin + h_p(Numofplot) = plot(p_ax,ERP_FFT.times,squeeze(ERP_FFT.bindata(count,:,Numofplot)),'LineWidth',1.5,'Color',line_colors(Numofplot,:,:)); + end + axis(p_ax,[floor(ERP_FFT.times(1)),ceil(ERP_FFT.times(end)), 1.1*min(temp(:)) 1.1*max(temp(:))]); + xticks(p_ax,FreqTick); + xlim([floor(ERP_FFT.times(1)),ceil(ERP_FFT.times(end))]); + if count == 1 + title(p_ax,[ERP_FFT.chanlocs(count).labels],'FontSize',14); + legend(p_ax,ERP_FFT.bindescr,'FontSize',14); + legend(p_ax,'boxoff'); + else + title(p_ax,ERP_FFT.chanlocs(count).labels,'FontSize',14); + end + xlabel(p_ax,'Frequency/Hz','FontSize',14); + if gui_erp_spectral.phase.Value + ylabel(p_ax,'Angle/degree','FontSize',14); + elseif gui_erp_spectral.amplitude.Value + ylabel(p_ax,'Amplitude/\muV','FontSize',14); + elseif gui_erp_spectral.power.Value + ylabel(p_ax,'Power/\muV^2','FontSize',14); + elseif gui_erp_spectral.db.Value + ylabel(p_ax,'Decibels/dB','FontSize',14); + end + for Numoflabel = 1:length(ERP_FFT.times) + X_label{Numoflabel} = []; + end + set(gca,'TickDir','out'); + set(gca,'LineWidth',2); + end + end + hold off; + clear h_p + end + %%Save the transformed data for the selected ERPsets as + if Save_label + if strcmp(ERP_FFT.datatype,'EFFT') + if gui_erp_spectral.amplitude.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_Amplitude']; + elseif gui_erp_spectral.phase.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_Phase']; + elseif gui_erp_spectral.power.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_Power']; + elseif gui_erp_spectral.db.Value + figure_name = [ERP_FFT.erpname,'_Spectrum_ dB']; + end + + end + + if ind==1 + [filenamei, pathname] = uiputfile({'*.mat';'*.*'},['Save',32,'"',ERP_FFT.erpname,'"', 32,'as'],fullfile(pathName_folder,figure_name)); + + if isequal(filenamei,0) + disp('User selected Cancel') + return + else + [pathx, filename, ext] = fileparts(filenamei); + if ~strcmpi(ext,'.mat') + ext = '.mat'; + end + filename = [filename ext]; + end + + if strcmpi(ext,'.mat') + [ERP_FFT, issave, ERPCOM] = pop_savemyerp(ERP_FFT, 'erpname', ERP_FFT.erpname, 'filename', filename, 'filepath',pathname); + [~, ALLERPCOM] = erphistory(ERP_FFT, ALLERPCOM, ERPCOM); + end + + %%save as '.csv' + elseif ind==2 + def = erpworkingmemory('f_export2csvGUI'); + if isempty(def) + def = {1, 1, 1, 3, ''}; + end + + def{5} = fullfile(pathName_folder,ERP_FFT.filename); + answer_export = f_export2csvGUI(ERP_FFT,def); + erpworkingmemory('f_export2csvGUI',answer_export); + if isempty(answer_export) + beep; + disp('User selected cancel!!!'); + return; + end + binArray = [1:ERP_FFT.nbin]; + decimal_num = answer_export{4}; + istime =answer_export{1} ; + electrodes=answer_export{2} ; + transpose=answer_export{3}; + filenamei = answer_export{5}; + [pathx, filename, ext] = fileparts(filenamei); + if ~strcmpi(ext,'.csv') + ext = '.csv'; + end + if isempty(pathx) + pathx =cd; + end + filename = [filename ext]; + mkdir([pathx,filesep]); + try + export2csv_spectranl_analysis(ERP_FFT,fullfile(pathx,filename), binArray,istime, electrodes,transpose, decimal_num); + catch + beep; + disp('Fail to save selected ERPset as ".csv"!!!'); + return; + end + end + end + + end%%end loop for ERPSET + + end + + +%%-------------------Setting for the whole panel of fitering based on ALLERP and CURRENTERP-------------- + function Count_currentERPChanged(~,~) + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + gui_erp_spectral.advanced.Enable = 'off'; + gui_erp_spectral.save.Enable = 'off'; + gui_erp_spectral.plot.Enable = 'off'; + gui_erp_spectral.phase.Enable = 'off'; + gui_erp_spectral.amplitude.Enable = 'off'; + gui_erp_spectral.hamwin_on.Enable = 'off'; + gui_erp_spectral.hamwin_off.Enable = 'off'; + gui_erp_spectral.power.Enable = 'off'; + gui_erp_spectral.db.Enable = 'off'; + else + gui_erp_spectral.advanced.Enable = 'on'; + gui_erp_spectral.save.Enable = 'on'; + gui_erp_spectral.plot.Enable = 'on'; + gui_erp_spectral.phase.Enable = 'on'; + gui_erp_spectral.amplitude.Enable = 'on'; + gui_erp_spectral.power.Enable = 'on'; + gui_erp_spectral.db.Enable = 'on'; + gui_erp_spectral.hamwin_on.Enable = 'on'; + gui_erp_spectral.hamwin_off.Enable = 'on'; + end + end + +%%----Get the color for lines-------------------------------------- + function colors = get_colors(ncolors) + % Each color gets 1 point divided into up to 2 of 3 groups (RGB). + degree_step = 6/ncolors; + angles = (0:ncolors-1)*degree_step; + colors = nan(numel(angles),3); + for i = 1:numel(angles) + if angles(i) < 1 + colors(i,:) = [1 (angles(i)-floor(angles(i))) 0]*0.75; + elseif angles(i) < 2 + colors(i,:) = [(1-(angles(i)-floor(angles(i)))) 1 0]*0.75; + elseif angles(i) < 3 + colors(i,:) = [0 1 (angles(i)-floor(angles(i)))]*0.75; + elseif angles(i) < 4 + colors(i,:) = [0 (1-(angles(i)-floor(angles(i)))) 1]*0.75; + elseif angles(i) < 5 + colors(i,:) = [(angles(i)-floor(angles(i))) 0 1]*0.75; + else + colors(i,:) = [1 0 (1-(angles(i)-floor(angles(i))))]*0.75; + end + end + end + +end +%Progem end: ERP Measurement tool \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.fig b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.fig new file mode 100755 index 00000000..3cdf437e Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.m b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.m new file mode 100755 index 00000000..a013df32 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_ERP_suffix_gui.m @@ -0,0 +1,176 @@ +function varargout = f_ERP_suffix_gui(varargin) +% F_ERP_SUFFIX_GUI MATLAB code for f_ERP_suffix_gui.fig +% F_ERP_SUFFIX_GUI, by itself, creates a new F_ERP_SUFFIX_GUI or raises the existing +% singleton*. +% +% H = F_ERP_SUFFIX_GUI returns the handle to a new F_ERP_SUFFIX_GUI or the handle to +% the existing singleton*. +% +% F_ERP_SUFFIX_GUI('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in F_ERP_SUFFIX_GUI.M with the given input arguments. +% +% F_ERP_SUFFIX_GUI('Property','Value',...) creates a new F_ERP_SUFFIX_GUI or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before f_ERP_suffix_gui_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to f_ERP_suffix_gui_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help f_ERP_suffix_gui + +% Last Modified by GUIDE v2.5 02-Aug-2022 18:45:52 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_ERP_suffix_gui_OpeningFcn, ... + 'gui_OutputFcn', @f_ERP_suffix_gui_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before f_ERP_suffix_gui is made visible. +function f_ERP_suffix_gui_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_ERP_suffix_gui + +try + erpname = varargin{1}; + +catch + erpname = ''; + +end + +handles.erpnameor = erpname; +handles.output = []; +erpmenu = findobj('tag', 'erpsets'); + +if ~isempty(erpmenu) + handles.menuerp = get(erpmenu); + set(handles.menuerp.Children, 'Enable','off'); +end + +erplab_studio_default_values; +version = erplabstudiover; + +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Add Suffix GUI']) +set(handles.edit_erpname, 'String', '_processed'); + +set(handles.current_erp_label,'String', ['Enter suffix, which will be added onto the name of each selected ERPset'],... + 'FontWeight','Bold', 'FontSize', 16); + +% +% % Color GUI +% % +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + + +% UIWAIT makes savemyerpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + + + + +% --- Outputs from this function are returned to the command line. +function varargout = f_ERP_suffix_gui_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +% try +% set(handles.menuerp.Children, 'Enable','on'); +% catch +% disp('ERPset menu was not found...') +% end +varargout{1} = handles.output; +delete(handles.gui_chassis); +pause(0.1) + + + + +% --- Executes on button press in radio_erpname. +function radio_erpname_Callback(hObject, eventdata, handles) +% hObject handle to radio_erpname (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of radio_erpname + + +function edit_erpname_Callback(hObject, eventdata, handles) + + +% --- Executes during object creation, after setting all properties. +function edit_erpname_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_Cancel. +function pushbutton_Cancel_Callback(hObject, eventdata, handles) +handles.output = []; +beep; +disp('User selected Cancel') +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +% --- Executes on button press in pushbutton4_okay. +function pushbutton4_okay_Callback(hObject, eventdata, handles) +erpname = strtrim(get(handles.edit_erpname, 'String')); + +if isempty(erpname) + msgboxText = 'You must enter a suffix at least!'; + title = 'EStudio: f_ERP_suffix_gui empty suffix.'; + errorfound(msgboxText, title); + return +end + + +handles.output = {erpname}; +% Update handles structure +guidata(hObject, handles); + +uiresume(handles.gui_chassis); + + + + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_appenderpGUI.fig b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.fig new file mode 100644 index 00000000..9bd183d9 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_appenderpGUI.m b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.m new file mode 100644 index 00000000..f33a5af0 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_appenderpGUI.m @@ -0,0 +1,1157 @@ +% +% Author: Javier Lopez-Calderon & Steven Luck & Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 && 2023 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = f_appenderpGUI(varargin) + +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_appenderpGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_appenderpGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end + +% ----------------------------------------------------------------------- +function f_appenderpGUI_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_appenderpGUI +% def = {inp1 erpset isprefix prefixl/ist}; + +handles.output = []; +handles.totline = 1; + +try + totalerpset = varargin{1}; +catch + totalerpset = 0; +end +try + % def = {inp1 erpset prefixlist}; + def = varargin{2}; + +catch + def = {1 1 [] '', []}; +end + +optioni = def{1}; +ERPsetOp = def{2}; +erpset = def{3}; +prefixlist = def{4}; +erpsetPanel = def{5}; + +handles.optioni = optioni; +handles.erpset = erpset; +handles.erpsetop = ERPsetOp; +handles.prefixlist = prefixlist; +handles.totalerpset = totalerpset; +handles.full_list = []; +handles.listname = []; +handles.erpsetPanel = erpsetPanel; +% set GUI +handles = setbuttonsgui(hObject, eventdata, handles); + +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - APPEND ERPs GUI']) + +handles = painterplabstudio(handles); +% +% Set font size +% +handles = setfonterplabestudio(handles); + +% help button +% helpbutton + +% Update handles structure +guidata(hObject, handles); + +% UIWAIT makes f_appenderpGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +% ----------------------------------------------------------------------- +function varargout = f_appenderpGUI_OutputFcn(hObject, eventdata, handles) +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +% ----------------------------------------------------------------------- +function edit_erpset_Callback(hObject, eventdata, handles) +[chkerp] = checkERPs(hObject, eventdata, handles); +if chkerp + return % problem was found +else + set(handles.radiobutton_includep, 'Enable', 'on'); +end + +% ----------------------------------------------------------------------- +function edit_erpset_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% ----------------------------------------------------------------------- +function pushbutton_RUN_Callback(hObject, eventdata, handles) +% nsets = handles.totalerpset; +if handles.radiobutton_folders.Value==0 + + erpset = str2num(char(get(handles.edit_erpset, 'String'))); + + % if isempty(erpset) + % msgboxText = ['No ERPset indices were specified!\n\n'... + % 'You must use any integer value(s) between 1 and ' num2str(nsets)]; + % title = 'ERPLAB: geterpvaluesGUI inputs'; + % errorfound(sprintf(msgboxText), title); + % return + % end + % if max(erpset)>nsets + % msgboxText = ['ERPset indexing out of range!\n\n'... + % 'You only have ' num2str(nsets) ' ERPsets loaded on your ERPset Menu.']; + % title = 'ERPLAB: geterpvaluesGUI inputs'; + % errorfound(sprintf(msgboxText), title); + % return + % end + % if min(erpset)<1 + % msgboxText = ['Invalid ERPset indexing!\n\n'... + % 'You may use any integer value between 1 and ' num2str(nsets)]; + % title = 'ERPLAB: geterpvaluesGUI inputs'; + % errorfound(sprintf(msgboxText), title); + % return + % end + % + % chkerp = checkERPs(hObject, eventdata, handles); + foption = 0; %from erpsets +else + erpset = get(handles.listbox_erpnames, 'String'); + nline = length(erpset); + + if nline==1 + msgboxText = 'You have to specify at least one erpset!'; + etitle = 'ERPLAB: geterpvaluesGUI() -> missing input'; + errorfound(msgboxText, etitle); + return + end + + listname = handles.listname; % file conteining the list of erpsets + + if isempty(listname) && nline>1 + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['You have not yet saved your list.\n'... + 'What would you like to do?']; + etitle = 'Save List of ERPsets'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), etitle,'Save and Continue','Save As', 'Cancel','Save and Continue'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Save As') + fullname = savelist(hObject, eventdata, handles); + listname = fullname; + set(handles.edit_filelist,'String', listname); + handles.listname = listname; + + % Update handles structure + guidata(hObject, handles); + return + elseif strcmpi(button,'Save and Continue') + fulltext = char(get(handles.listbox_erpnames,'String')); + listname = char(strtrim(get(handles.edit_filelist,'String'))); + + if isempty(listname) + % save as + fullname = savelist(hObject, eventdata, handles); + listname = fullname; + set(handles.edit_filelist,'String', listname); + else + % just save + fid_list = fopen( listname , 'w'); + for i=1:size(fulltext,1)-1 + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + fclose(fid_list); + end + elseif strcmpi(button,'Cancel') || strcmpi(button,'') + handles.output = []; + handles.listname = []; + + % Update handles structure + guidata(hObject, handles); + return + end + end + erpset = listname; + foption = 1; % from list +end +[chkerp ] = checkERPs(hObject, eventdata, handles); +if chkerp + return +else + if get(handles.checkbox_useerpname, 'Value') + prefixArray = 0; % use filenames instead. + else + prefixArray = get(handles.listbox_prefix, 'String')'; + %totline = length(prefixArray)-1; + % if totline>0 && totline~=length(erpset) + % msgboxText = 'You must enter as many prefixes as erpsets you want to append.'; + % title = 'ERPLAB: f_appenderpGUI few inputs'; + % errorfound(msgboxText, title); + % return + % end + prefixArray = prefixArray(1:end-1); + end + ERPsetOp = handles.radiobutton_erpset.Value; + handles.output = {foption,ERPsetOp, erpset, prefixArray}; + + % Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +end + +% ----------------------------------------------------------------------- +function radiobutton_includep_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.edit_prefix, 'Enable', 'on'); + set(handles.pushbutton_addp, 'Enable', 'on'); + set(handles.pushbutton_deletep, 'Enable', 'on'); + %set(handles.togglebutton_autonumber, 'Enable', 'on'); + set(handles.listbox_prefix, 'Enable', 'on'); + set(handles.pushbutton_cleara, 'Enable', 'on'); + set(handles.pushbutton_doit4me, 'Enable', 'on'); + set(handles.checkbox_useerpname, 'Enable', 'on'); +else + set(handles.edit_prefix, 'Enable', 'off'); + set(handles.pushbutton_addp, 'Enable', 'off'); + set(handles.pushbutton_deletep, 'Enable', 'off'); + set(handles.pushbutton_cleara, 'Enable', 'off'); + set(handles.togglebutton_autonumber, 'Enable', 'off'); + set(handles.listbox_prefix, 'Enable', 'off'); + set(handles.pushbutton_doit4me, 'Enable', 'off'); + set(handles.checkbox_useerpname, 'Value', 0); + set(handles.checkbox_useerpname, 'Enable', 'off'); +end + +% ----------------------------------------------------------------------- +function pushbutton_addp_Callback(hObject, eventdata, handles) +newline = get(handles.edit_prefix,'String'); +if isempty(strtrim(newline)) + return +end +set(handles.togglebutton_autonumber, 'Value', 0); +set(handles.togglebutton_autonumber, 'Enable', 'on'); +currline = get(handles.listbox_prefix, 'Value'); +full_list = get(handles.listbox_prefix, 'String'); +totline = length(full_list); + +if currline==totline + % extra line forward + full_list = cat(1, full_list, {'new prefix'}); + set(handles.listbox_prefix, 'Value', currline+1) +else + set(handles.listbox_prefix, 'Value', currline) + resto = full_list(currline:totline); + + full_list = cat(1, full_list, {'new prefix'}); + set(handles.listbox_prefix, 'Value', currline+1) + [full_list{currline+1:totline+1}] = resto{:}; +end + +full_list{currline} = newline; +totline = length(full_list); +set(handles.listbox_prefix, 'String', full_list); +handles.totline = totline; +handles.full_list = full_list; + +% Update handles structure +guidata(hObject, handles); + +% ----------------------------------------------------------------------- +function pushbutton_deletep_Callback(hObject, eventdata, handles) +full_list = get(handles.listbox_prefix, 'String'); +totline = length(full_list) ; +full_list = char(full_list); % string matrix +currline = get(handles.listbox_prefix, 'Value'); +set(handles.togglebutton_autonumber, 'Enable', 'off'); + +if currline>=1 && currline0 && (totline==nerpset || totline==1) + for i=1:nerpset + if totline==1 + j = 1; + else + j = i; + end + full_list_new{i} = [full_list{j} ' ' num2str(i)]; + end + full_list = cat(1, full_list_new', {'new prefix'}); + set(handles.listbox_prefix, 'String', full_list); + elseif nerpset==0 + set(handles.togglebutton_autonumber, 'Value', 0); + set(handles.togglebutton_autonumber,'Enable','off') + msgboxText = 'You must enter at least two datasets to use this button.'; + etitle = 'ERPLAB: Append ERP GUI automatic prefix numbering'; + errorfound(msgboxText, etitle); + set(handles.togglebutton_autonumber,'Enable','on') + set(handles.togglebutton_autonumber,'Enable','on') + return + else + set(handles.togglebutton_autonumber,'Value',0) + set(handles.togglebutton_autonumber,'Enable','off') + msgboxText = ['You have to enter 1 or ' num2str(nerpset) ' to use this button!']; + etitle = 'ERPLAB: Append ERP GUI automatic prefix numbering'; + errorfound(msgboxText, etitle); + set(handles.togglebutton_autonumber,'Enable','on') + return + end + handles.backup_list = backup_list; + % Update handles structure + guidata(hObject, handles); +else + set(handles.listbox_prefix, 'String', handles.backup_list); +end + +% ----------------------------------------------------------------------- +function edit_prefix_Callback(hObject, eventdata, handles) + +% ----------------------------------------------------------------------- +function edit_prefix_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% ----------------------------------------------------------------------- +function listbox_prefix_Callback(hObject, eventdata, handles) +full_list = get(handles.listbox_prefix, 'String'); +totline = length(full_list) ; +currline = get(handles.listbox_prefix, 'Value'); + +if currline>=1 && currline' fullname '']) +end +try + fid_list = fopen( fullname ); +catch + fprintf('WARNING: %s was not found or is corrupted\n', fullname) + return +end +formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', ''); +lista = formcell{:}; + +% extra line forward +lista = cat(1, lista, {'new erpset'}); +lentext = length(lista); +fclose(fid_list); + +if lentext>1 + % try + filereadin = strtrim(lista{1}); + ERP1 = load(filereadin, '-mat'); + ERP = ERP1.ERP; + + if ~iserpstruct(ERP) + error('') + end + + set(handles.listbox_erpnames,'String',lista); + set(handles.edit_filelist,'String',fullname); + listname = fullname; + handles.listname = listname; + set(handles.button_savelistas, 'Enable','on') + + set(handles.radiobutton_includep, 'Enable', 'on'); + + + % Update handles structure + guidata(hObject, handles); + % catch + % msgboxText = 'This list is anything but an ERPset list!'; + % title = 'ERPLAB: geterpvaluesGUI inputs'; + % errorfound(msgboxText, title) + % handles.listname = []; + % set(handles.button_savelist, 'Enable','off') + % + % % Update handles structure + % guidata(hObject, handles); + % end +else + msgboxText = 'This list is empty!'; + etitle = 'ERPLAB: geterpvaluesGUI inputs'; + errorfound(msgboxText, etitle); + handles.listname = []; + set(handles.button_savelist, 'Enable','off') + + % Update handles structure + guidata(hObject, handles); +end + +% ----------------------------------------------------------------------- +function button_savelist_Callback(hObject, eventdata, handles) +fulltext = char(strtrim(get(handles.listbox_erpnames,'String'))); + +if length(fulltext)>1 + fullname = get(handles.edit_filelist, 'String'); + + if ~strcmp(fullname,'') + fid_list = fopen( fullname , 'w'); + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); + handles.listname = fullname; + + % Update handles structure + guidata(hObject, handles); + disp(['Saving equation list at ' fullname '']) + else + button_savelistas_Callback(hObject, eventdata, handles) + return + end +else + set(handles.button_savelistas,'Enable','off') + msgboxText = 'You have not written any formula yet!'; + etitle = 'ERPLAB: chanoperGUI few inputs'; + errorfound(msgboxText, etitle); + set(handles.button_savelistas,'Enable','on') + return +end + +% ----------------------------------------------------------------------- +function button_adderpset_Callback(hObject, eventdata, handles) +[erpfname, erppathname] = uigetfile({ '*.erp','ERPLAB-files (*.erp)'; ... + '*.mat','Matlab (*.mat)'; ... + '*.*', 'All Files (*.*)'}, ... + 'Select an edited file', ... + 'MultiSelect', 'on'); + +if isequal(erpfname,0) + disp('User selected Cancel') + return +else + % try + % + % test current directory + % + % changecd(erppathname) + + if ~iscell(erpfname) + erpfname = {erpfname}; + end + + nerpn = length(erpfname); + + for i=1:nerpn + newline = fullfile(erppathname, erpfname{i}); + currline = get(handles.listbox_erpnames, 'Value'); + fulltext = get(handles.listbox_erpnames, 'String'); + indxline = length(fulltext); + + if currline==indxline + % extra line forward + fulltext = cat(1, fulltext, {'new erpset'}); + set(handles.listbox_erpnames, 'Value', currline+1) + else + set(handles.listbox_erpnames, 'Value', currline) + resto = fulltext(currline:indxline); + fulltext = cat(1, fulltext, {'new erpset'}); + set(handles.listbox_erpnames, 'Value', currline+1) + [fulltext{currline+1:indxline+1}] = resto{:}; + end + + fulltext{currline} = newline; + set(handles.listbox_erpnames, 'String', fulltext) + end + + handles.listname = []; + indxline = length(fulltext); + handles.indxline = indxline; + handles.fulltext = fulltext; + set(handles.button_savelistas, 'Enable','on') + set(handles.edit_filelist,'String',''); + set(handles.radiobutton_includep, 'Enable', 'on'); + + + % Update handles structure + guidata(hObject, handles); + % catch + % set(handles.listbox_erpnames, 'String', ''); + % msgboxText = 'A file you are attempting to load is not an ERPset!'; + % title = 'ERPLAB: geterpvaluesGUI2 inputs'; + % errorfound(msgboxText, title); + % handles.listname = []; + % set(handles.button_savelist, 'Enable','off') + % + % % Update handles structure + % guidata(hObject, handles); + % end +end + +% ----------------------------------------------------------------------- +function button_clearfile_Callback(hObject, eventdata, handles) +set(handles.edit_filelist,'String',''); +set(handles.button_savelist, 'Enable', 'off') +set(handles.radiobutton_includep, 'Enable', 'off'); + +handles.listname = []; +% Update handles structure +guidata(hObject, handles); + +% ----------------------------------------------------------------------- +function button_savelistas_Callback(hObject, eventdata, handles) +fulltext = char(get(handles.listbox_erpnames,'String')); +if length(fulltext)>1 + fullname = savelist(hObject, eventdata, handles); + + if isempty(fullname) + return + end + + set(handles.edit_filelist, 'String', fullname ) + set(handles.button_savelist, 'Enable', 'on') + handles.listname = fullname; + + % Update handles structure + guidata(hObject, handles); +else + set(handles.button_savelistas,'Enable','off') + msgboxText = 'You have not specified any ERPset!'; + etitle = 'ERPLAB: averager GUI few inputs'; + errorfound(msgboxText, etitle); + set(handles.button_savelistas,'Enable','on') + return +end + +% ----------------------------------------------------------------------- +function button_delerpset_Callback(hObject, eventdata, handles) +fulltext = get(handles.listbox_erpnames, 'String'); +indxline = length(fulltext); +fulltext = char(fulltext); % string matrix +currline = get(handles.listbox_erpnames, 'Value'); + +if currline>=1 && currline1 % put this one first on the list + newline = fulltext{1}; + ERP1 = load(newline, '-mat'); + ERP = ERP1.ERP; + end + + set(handles.listbox_erpnames, 'String', fulltext); + listbox_erpnames_Callback(hObject, eventdata, handles) + handles.fulltext = fulltext; + indxline = length(fulltext); + handles.listname = []; + set(handles.edit_filelist,'String',''); + + % Update handles structure + guidata(hObject, handles); +else + set(handles.button_savelistas, 'Enable','off') +end + +% ----------------------------------------------------------------------- +function togglebutton_edit_list_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + %list = get(handles.listbox_erpnames, 'String') + set(handles.listbox_erpnames, 'Value',1) + set(handles.listbox_erpnames, 'Style','edit') + set(handles.listbox_erpnames, 'Max',2) + set(handles.listbox_erpnames, 'HorizontalAlignment','left') + set(handles.listbox_erpnames, 'Foregroundcolor',[0 0 0.72]) + + set(handles.button_delerpset,'Enable','off') + set(handles.button_adderpset,'Enable','off') + set(handles.button_savelistas,'Enable','off') + set(handles.button_savelist,'Enable','off') + set(handles.button_clearfile,'Enable','off') + set(handles.button_loadlist,'Enable','off') +else + %list = get(handles.listbox_erpnames, 'String') + set(handles.listbox_erpnames, 'Style','listbox') + set(handles.listbox_erpnames, 'Value',1) + set(handles.listbox_erpnames, 'Foregroundcolor',[0 0 0]) + set(handles.button_delerpset,'Enable','on') + set(handles.button_adderpset,'Enable','on') + set(handles.button_savelistas,'Enable','on') + set(handles.button_savelist,'Enable','on') + set(handles.button_clearfile,'Enable','on') + set(handles.button_loadlist,'Enable','on') +end + +% ----------------------------------------------------------------------- +function radiobutton_erpset_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + + set(hObject,'Value',1); + set(handles.edit_erpset,'Enable','off'); + set(handles.radiobutton_ERPsetcustom,'Value',0); + set(handles.radiobutton_ERPsetcustom,'Enable','on'); +% if handles.erpsetop ==1 + set(handles.edit_erpset, 'String',num2str(handles.erpsetPanel)); +% end + + set(handles.radiobutton_folders,'Value',0) + set(handles.listbox_erpnames,'Enable','off') + set(handles.button_adderpset,'Enable','off') + set(handles.button_delerpset,'Enable','off') + set(handles.button_savelist,'Enable','off') + set(handles.button_clearfile,'Enable','off') + set(handles.button_savelistas,'Enable','off') + set(handles.button_loadlist,'Enable','off') + set(handles.edit_filelist,'Enable','off') + set(handles.pushbutton_flush,'Enable','off') +else + set(hObject,'Value',1) +end + +%-------------------------------------------------------------------------- +function [chkerp ]= checkERPs(hObject, eventdata, handles) +chkerp = 0; % no problem +errorerp = 0; +nerp = handles.totalerpset; + +% +% Read first ERPset +% +if get(handles.radiobutton_folders, 'Value')==0; + indexerp = unique_bc2(str2num(get(handles.edit_erpset, 'String'))); + + if isempty(indexerp) + msgboxText = ['Invalid ERPset indexing!\n\n'... + 'You must use any integer value between 1 and %g.']; + etitle = 'ERPLAB: appenderpGUI inputs'; + errorfound(sprintf(msgboxText, num2str(nerp)), etitle); + chkerp = 1; + return + end + if max(indexerp)>nerp + msgboxText = ['ERPset indexing out of range!\n\n'... + 'You only have %g ERPsets loaded on your ERPset Menu.']; + etitle = 'ERPLAB: appenderpGUI inputs'; + errorfound(sprintf(msgboxText, num2str(nerp)), etitle); + chkerp = 1; + return + end + if min(indexerp)<1 + msgboxText = ['Invalid ERPset indexing!\n\n'... + 'You must use any integer value between 1 and %g' ]; + etitle = 'ERPLAB: appenderpGUI inputs'; + errorfound(sprintf(msgboxText, num2str(nerp)), etitle); + chkerp = 1; + return + end + if length(indexerp)<2 + msgboxText = 'You have to specify 2 erpsets, at least!'; + title = 'ERPLAB: appenderpGUI() -> few inputs'; + errorfound(msgboxText, title); + chkerp = 1; + return + end + + ALLERP = evalin('base', 'ALLERP'); + + if ~isempty(ALLERP) + nerp2 = length(indexerp); + numpoints = zeros(1,nerp2); + numchans = zeros(1,nerp2); + nameerp = {''}; + for k=1:nerp2 + numpoints(k) = ALLERP(indexerp(k)).pnts; + numchans(k) = ALLERP(indexerp(k)).nchan; + nameerp{k} = ALLERP(indexerp(k)).filename; + end + else + chkerp = 1; + return + end + clear ALLERP +else + listname = strtrim(char(get(handles.edit_filelist,'String'))); + + % + % open file containing the erp list + % + fid_list = fopen( listname ); + formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', ''); + lista = formcell{:}; + + % extra line forward + lista = cat(1, lista, {'new erpset'}); + lentext = length(lista); + fclose(fid_list); + + if lentext>1 + numpoints = zeros(1,lentext-1); + numchans = zeros(1,lentext-1); + nameerp = {''}; + for j=1:lentext-1 + ERP1 = load(strtrim(lista{j}), '-mat'); + ERP = ERP1.ERP; + if ~iserpstruct(ERP) + %set(handles.listbox_erpnames, 'String', ''); + msgboxText = 'A file you are attempting to load is not an ERPset!'; + etitle = 'ERPLAB: appenderpGUI inputs'; + errorfound(msgboxText, etitle); + handles.listname = []; + + % Update handles structure + guidata(hObject, handles); + errorerp = 1; + set(handles.button_savelist, 'Enable','off') + break + else + numpoints(j) = ERP.pnts; + numchans(j) = ERP.nchan; + nameerp{j} = ERP.filename; + end + + clear ERP1 ERP + end + if errorerp + chkerp = 1; + return + end + end + nerp2 = lentext-1; + handles.listname = listname; + % Update handles structure + guidata(hObject, handles); +end +if length(unique_bc2(numpoints))>1 + fprintf('Detail:\n') + fprintf('-------\n') + for j=1:nerp2 + fprintf('Erpset %s has %g points per bin\n', nameerp{j}, numpoints(j)); + end + msgboxText = 'ERPsets have different number of points\n'; + etitle = 'ERPLAB: appenderpGUI inputs'; + errorfound(sprintf(msgboxText), etitle); + chkerp = 1; + return +end +if length(unique_bc2(numchans))>1 + fprintf('Detail:\n') + fprintf('-------\n') + for j=1:nerp2 + fprintf('Erpset %s has %g channels\n', nameerp{j}, numchans(j)); + end + msgboxText = 'ERPsets have different number of channel\n'; + etitle = 'ERPLAB: appenderpGUI inputs'; + errorfound(sprintf(msgboxText), etitle); + chkerp = 1; + return +end + +% ----------------------------------------------------------------------- +function handles = setbuttonsgui(hObject, eventdata, handles) +optioni = handles.optioni; +erpset = handles.erpset; +prefixlist = handles.prefixlist; +nsets = handles.totalerpset; +ERPsetOp = handles.erpsetop; + +if nsets>0 && optioni==0 %&& isnumeric(erpset) % from erpset menu + set(handles.radiobutton_erpset, 'Value', ERPsetOp); + set(handles.radiobutton_erpset, 'Enable', 'on'); + set( handles.radiobutton_ERPsetcustom, 'Value', ~ERPsetOp); + set( handles.radiobutton_ERPsetcustom, 'Enable', 'on'); + if ERPsetOp==1 + set( handles.edit_erpset, 'Enable', 'off'); + else + set( handles.edit_erpset, 'Enable', 'on'); + end + + set(handles.radiobutton_folders, 'Value', 0); + set(handles.listbox_erpnames, 'Enable', 'off'); + set(handles.button_adderpset, 'Enable', 'off'); + set(handles.button_delerpset, 'Enable', 'off'); + set(handles.button_savelistas, 'Enable', 'off'); + set(handles.button_savelist, 'Enable', 'off'); + set(handles.button_clearfile, 'Enable', 'off'); + set(handles.button_loadlist, 'Enable', 'off'); + set(handles.edit_erpset, 'String', vect2colon(erpset, 'Delimiter','off', 'Repeat', 'off')); + set(handles.listbox_erpnames, 'String', {'new erpset'}); + set(handles.edit_filelist,'String', '') + set(handles.pushbutton_flush,'Enable','off') + set(handles.radiobutton_includep, 'Enable', 'on'); +else % from hard drive + set(handles.radiobutton_folders, 'Value', 1); + set( handles.edit_erpset, 'Enable', 'off'); + set(handles.radiobutton_erpset, 'Value', ERPsetOp); + set(handles.radiobutton_erpset, 'Enable', 'off'); + set( handles.radiobutton_ERPsetcustom, 'Value', ~ERPsetOp); +% if ERPsetOp==1 +% set( handles.radiobutton_ERPsetcustom, 'Enable', 'off'); +% else + set( handles.radiobutton_ERPsetcustom, 'Enable', 'off'); +% end + + + set(handles.pushbutton_flush,'Enable','on') + set(handles.radiobutton_includep, 'Value', 0); + + if nsets==0 + set(handles.radiobutton_erpset, 'Enable', 'off'); + set(handles.edit_erpset, 'String', 'no erpset'); + else + set(handles.edit_erpset, 'String', vect2colon(1:nsets, 'Delimiter','off', 'Repeat', 'off')); + end + if ~isempty(erpset) && ischar(erpset) + + % + % open file containing the erp list + % + try + fid_list = fopen( erpset ); + catch + fprintf('WARNING: %s was not found or is corrupted\n', fullname) + return + end + formcell = textscan(fid_list, '%[^\n]','CommentStyle','#', 'whitespace', ''); + fclose(fid_list); + + lista = formcell{:}; + listname = erpset; + set(handles.radiobutton_includep, 'Enable', 'on'); + set(handles.edit_filelist,'String', erpset) + else + lista = {}; + listname = []; + set(handles.radiobutton_includep, 'Enable', 'off'); + end + + % extra line forward + lista = cat(1, lista, {'new erpset'}); + %lentext = length(lista); + + handles.listname = listname; + set(handles.button_savelistas, 'Enable','on') + set(handles.listbox_erpnames,'String',lista); +end +if isempty(prefixlist) + set(handles.radiobutton_includep, 'Value', 0); + set(handles.edit_prefix, 'Enable', 'off'); + set(handles.pushbutton_addp, 'Enable', 'off'); + set(handles.pushbutton_deletep, 'Enable', 'off'); + set(handles.pushbutton_cleara, 'Enable', 'off'); + set(handles.togglebutton_autonumber, 'Enable', 'off'); + set(handles.listbox_prefix, 'Enable', 'off'); + set(handles.listbox_prefix, 'String', {'new prefix'}); + set(handles.pushbutton_doit4me, 'Enable', 'off'); + set(handles.checkbox_useerpname, 'Enable', 'off'); +elseif iscell(prefixlist) + set(handles.radiobutton_includep, 'Value', 1); + set(handles.edit_prefix, 'Enable', 'on'); + set(handles.pushbutton_addp, 'Enable', 'on'); + set(handles.pushbutton_deletep, 'Enable', 'on'); + set(handles.pushbutton_cleara, 'Enable', 'on'); + set(handles.togglebutton_autonumber, 'Enable', 'on'); + set(handles.listbox_prefix, 'Enable', 'on'); + set(handles.listbox_prefix, 'String', {prefixlist{:} 'new prefix'}); + set(handles.pushbutton_doit4me, 'Enable', 'on'); + set(handles.checkbox_useerpname, 'Enable', 'on'); +else + set(handles.radiobutton_includep, 'Value', 1); + set(handles.edit_prefix, 'Enable', 'off'); + set(handles.pushbutton_addp, 'Enable', 'off'); + set(handles.pushbutton_deletep, 'Enable', 'off'); + set(handles.pushbutton_cleara, 'Enable', 'off'); + set(handles.togglebutton_autonumber, 'Enable', 'off'); + set(handles.listbox_prefix, 'Enable', 'off'); + set(handles.listbox_prefix, 'String', {'new prefix'}); + set(handles.pushbutton_doit4me, 'Enable', 'off'); + set(handles.checkbox_useerpname, 'Enable', 'on'); + set(handles.checkbox_useerpname, 'Value', 1); +end + +% set(handles.radiobutton_erpset, 'Value', 1); + +%-------------------------------------------------------------------------- +function fullname = savelist(hObject, eventdata, handles) +fullname = ''; +fulltext = char(get(handles.listbox_erpnames,'String')); + +% +% Save OUTPUT file +% +[filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save erpset list as'); + +if isequal(filename,0) + disp('User selected Cancel') + return +else + [px, fname, ext] = fileparts(filename); + + if strcmp(ext,'') + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; + end + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + disp(['To Save erpset list, user selected ', fullname]) + + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1)-1 + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + fclose(fid_list); +end + +% ----------------------------------------------------------------------- +function checkbox_useerpname_Callback(hObject, eventdata, handles) +if ~get(hObject,'Value') + set(handles.edit_prefix, 'Enable', 'on'); + set(handles.pushbutton_addp, 'Enable', 'on'); + set(handles.pushbutton_deletep, 'Enable', 'on'); + %set(handles.togglebutton_autonumber, 'Enable', 'on'); + set(handles.listbox_prefix, 'Enable', 'on'); + set(handles.pushbutton_cleara, 'Enable', 'on'); + set(handles.pushbutton_doit4me, 'Enable', 'on'); +else + set(handles.edit_prefix, 'Enable', 'off'); + set(handles.pushbutton_addp, 'Enable', 'off'); + set(handles.pushbutton_deletep, 'Enable', 'off'); + set(handles.pushbutton_cleara, 'Enable', 'off'); + set(handles.togglebutton_autonumber, 'Enable', 'off'); + set(handles.listbox_prefix, 'Enable', 'off'); + set(handles.pushbutton_doit4me, 'Enable', 'off'); +end + +% if get(hObject, 'Value') +% set(handles.radiobutton_includep, 'Value', 1) +% else +% set(handles.radiobutton_includep, 'Value', 0) +% end + + +% ----------------------------------------------------------------------- +function pushbutton_help_Callback(hObject, eventdata, handles) +web https://github.com/lucklab/erplab/wiki/Appending-ERPSETS -browser + +% ----------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +% ----------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes on button press in radiobutton_ERPsetcustom. +function radiobutton_ERPsetcustom_Callback(hObject, eventdata, handles) +% hObject handle to radiobutton_ERPsetcustom (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +if get(hObject,'Value') + set(handles.edit_erpset,'Enable','on'); + set(handles.radiobutton_erpset,'Value',0); + set(handles.radiobutton_ERPsetcustom,'Value',1); + + set(handles.radiobutton_folders,'Value',0); + set(handles.listbox_erpnames,'Enable','off'); + set(handles.button_adderpset,'Enable','off'); + set(handles.button_delerpset,'Enable','off'); + set(handles.button_savelist,'Enable','off'); + set(handles.button_clearfile,'Enable','off'); + set(handles.button_savelistas,'Enable','off'); + set(handles.button_loadlist,'Enable','off'); + set(handles.edit_filelist,'Enable','off'); + set(handles.pushbutton_flush,'Enable','off'); +else + set(hObject,'Value',1); + set(handles.radiobutton_erpset,'Value',0); +end diff --git a/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.fig b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.fig new file mode 100755 index 00000000..01643e2b Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.m b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.m new file mode 100755 index 00000000..479eaec8 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_basicfilterGUI2.m @@ -0,0 +1,3054 @@ +% +% Author: Javier Lopez-Calderon & Steven Luck & Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 %2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = f_basicfilterGUI2(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_basicfilterGUI2_OpeningFcn, ... + 'gui_OutputFcn', @f_basicfilterGUI2_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_basicfilterGUI2_OpeningFcn(hObject, eventdata, handles, varargin) +global outstr +warning('off','MATLAB:dispatcher:InexactMatch') +warning('off','MATLAB:dispatcher:InexactCaseMatch') +handles.output = []; +outstr = []; % I know, I failed...This is just cause it eliminates some issues using handles.output... +try + ERPLAB = varargin{1}; +catch + ERPLAB = []; + ERPLAB.srate = 500; + ERPLAB.epoch = []; + ERPLAB.event = []; + ERPLAB.chanlocs = []; + ERPLAB.nbchan = 1; + ERPLAB.nbbin = 1; +end +try + def = varargin{2}; +catch + % locutoff = answer{1}; % for high pass filter + % hicutoff = answer{2}; % for low pass filter + % filterorder = answer{3}; + % chanArray = answer{4}; + % filterallch = answer{5}; + % fdesign = answer{6}; + % remove_dc = answer{7}; + % boundary = def{8}; + + % binArray = def{9}; + def = {0 30 2 1 1 0 0 [] 1}; +end +handles.ERPLAB = ERPLAB; +if isfield(ERPLAB, 'nbchan') + nchan = ERPLAB.nbchan; +elseif isfield(ERPLAB, 'nchan') + nchan = ERPLAB.nchan; +else + nchan = 0; +end + +if isfield(ERPLAB, 'nbbin')% By Guanghui 2022 + nbin = ERPLAB.nbbin; +elseif isfield(ERPLAB, 'nchan') + nbin = ERPLAB.nbin; +else + nbin = 0; +end + +handles.fs = ERPLAB.srate; +handles.nchan = nchan; +handles.nbin = nbin; +fnyq = ERPLAB.srate/2; +handles.maxsliders = fnyq-1; +handles.def = def; +handles.minboundarysamdist = inf; +handles.xmaxfreqr = [0 round(ERPLAB.srate/4)]; %100 +handles.xmaxpimpz = [0 100]; +handles.valhp = '0'; +handles.vallp = '0'; +handles.iswarngain = 0; +handles.iswarnroff = 0; +handles.ishopermission = 0; % high order permission (butterworth) +handles.autorder = 0; +handles.datafr.chan = []; +handles.datafr.ym = []; +handles.datafr.yf = []; +handles.datafr.f = []; +handles.colorband = []; +handles.memvaluel = 30; +handles.memvalueh = 0; +handles.mvaluel = 30; +handles.mvalueh = 0; +handles.morder = 2; +handles.mem6dbl = '---'; +handles.mem6dbh = '---'; +handles.mem3dbl = '---'; +handles.mem3dbh = '---'; +handles.mvalueh = 0; % memory value highpass +handles.freqdef = 60; % default NOTCH frec +% set(handles. checkbox_filterallchannels, 'Enable', 'off'); + +% +% Prepare List of current Channels +% +if isempty(ERPLAB.chanlocs) + for e = 1:nchan + ERPLAB.chanlocs(e).labels = ['Ch' num2str(e)]; + end +end +listch = {''}; +for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERPLAB.chanlocs(ch).labels ]; +end + +handles.listch = listch; +handles.indxlistch = def{4}; % channel array + +listb = {''}; +for bin =1:nbin + listb{bin} = strcat('BIN',num2str(bin),' = ', ERPLAB.bindescr{bin}); +end + +handles.listb = listb; +handles.indxlistb = def{9}; % channel array + + + + + +% Update handles structure +guidata(hObject, handles); + +% +% Color GUI +% +% handles = painterplab(handles); + +% +% pre-plot +% +plot(1,1) +axis([0 ERPLAB.srate/2 -0.75 1.25]) +drawnow + +% +% Set font size +handles = painterplabstudio(handles); + +% +% Set font size +% +handles = setfonterplabestudio(handles); +% Update handles structure +guidata(hObject, handles); + +% help +helpbutton + +setall(hObject, eventdata, handles) + +% Update handles structure +guidata(hObject, handles); +drawnow +% UIWAIT makes str2codeGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_basicfilterGUI2_OutputFcn(hObject, eventdata, handles) +global outstr +% Get default command line output from handles structure +varargout{1} = outstr; + +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +%-------------------------------------------------------------------------- +function [order orderindx ]= getorder(handles) +% +% FILTER order +% +orderindx = get(handles.popupmenu_order, 'Value'); +orderlist = cellstr(get(handles.popupmenu_order, 'String')); +order = str2num(strrep(orderlist{orderindx},'automin:','')); % get rid of auto (in case of) + +%-------------------------------------------------------------------------- +function slider_highpass_Callback(hObject, eventdata, handles) + +valueh = get(handles.slider_highpass, 'Value'); +valueh = round(valueh*10)/10; + +if valueh<0.1; + valueh = 0; + set(handles.slider_highpass, 'Value', 0); +end +if get(handles.radiobutton_butter, 'Value'); + typef = 0; % 0 means Butterworth +elseif get(handles.radiobutton_fir, 'Value'); + typef = 1;% 1 means FIR +elseif get(handles.radiobutton_PM_notch, 'Value'); + typef = 2; % 2 means PM Notch +end + +posh = get(handles.popupmenu_order,'Value'); % order pop menu current position +autorder = handles.autorder; + +% +% FILTER order +% +order = getorder(handles); + +if isempty(order) + return +end + +tonhp = get(handles.togglebutton_highpass, 'Value'); + +if typef==2 + if valueh>=5 && valueh<=handles.maxsliders-5 + set(handles.slider_lowpass, 'Value', valueh); + valuehstr = sprintf('%.1f', valueh); + set(handles.edit_highpass, 'String', valuehstr); + else + if valueh<5 + nvaln = 5; + elseif valueh>handles.maxsliders-5 + nvaln = handles.maxsliders-5; + end + + nvalstr = sprintf('%.1f',nvaln); + set(handles.edit_highpass, 'String', nvalstr); + set(handles.slider_highpass, 'Value', nvaln); + end +else + if tonhp + if valueh==0 + set(handles.edit_highpass, 'String', '0'); + set(handles.edit_highpass, 'Enable', 'off'); + set(handles.togglebutton_highpass, 'Value', 0); + set(handles.slider_highpass, 'Enable','off'); + set(handles.checkbox_removedc, 'Enable', 'off') + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]); + else + valuehstr = sprintf('%.1f', valueh); + set(handles.edit_highpass, 'String', valuehstr); + set(handles.edit_highpass, 'Enable', 'on'); + set(handles.checkbox_removedc, 'Enable', 'on') + %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]); + end + else + set(handles.edit_highpass, 'String', '0'); + set(handles.edit_highpass, 'Enable', 'off'); + set(handles.togglebutton_highpass, 'Value', 0); + set(handles.slider_highpass, 'Enable','off'); + set(handles.checkbox_removedc, 'Enable', 'off') + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); + end +end +if typef==0 && autorder==1 + % order starts again for auto butter + orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list + orderlist{1} = 'automin:2'; + set(handles.popupmenu_order, 'String', orderlist); + set(handles.popupmenu_order, 'Value',1); + set(handles.popupmenu_dboct, 'Value',1); + set(handles.popupmenu_dbdec, 'Value',1); +end + +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +% ------------------------------------------------------------------------- +function slider_highpass_CreateFcn(hObject, eventdata, handles) + +if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor',[.9 .9 .9]); +end + +%-------------------------------------------------------------------------- +function slider_lowpass_Callback(hObject, eventdata, handles) + +valuel = get(handles.slider_lowpass, 'Value'); +valuel = round(valuel*10)/10; +fs = handles.fs; + +if valuel<0.1; + valuel = 0; + set(handles.slider_lowpass, 'Value', 0); +end +if valuel>round(fs/10) && (get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_fdatafr,'Value')) + handles.xmaxfreqr = [0 round(fs/2)]; %100 + set(handles.edit_xmaxplot, 'String', sprintf('%d %d', handles.xmaxfreqr)); + % Update handles structure + guidata(hObject, handles); +elseif valuel<=round(fs/10) && (get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_fdatafr,'Value')) + handles.xmaxfreqr = [0 round(fs/10)]; %100 + set(handles.edit_xmaxplot, 'String', sprintf('%d %d', handles.xmaxfreqr)); + % Update handles structure + guidata(hObject, handles); +end +if get(handles.radiobutton_butter, 'Value'); + typef = 0; % 0 means Butterworth +elseif get(handles.radiobutton_fir, 'Value'); + typef = 1;% 1 means FIR +elseif get(handles.radiobutton_PM_notch, 'Value'); + typef = 2; % 2 means PM Notch +end + +autorder = handles.autorder; + +% +% FILTER order +% +order = getorder(handles); + +if isempty(order) + return +end +tonlp = get(handles.togglebutton_lowpass, 'Value'); +if tonlp + if valuel==0 + set(handles.edit_lowpass, 'String', '0'); + set(handles.edit_lowpass, 'Enable', 'off'); + set(handles.togglebutton_lowpass, 'Value', 0); + set(handles.slider_lowpass, 'Enable','off'); + %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]); + else + valuelstr = sprintf('%.1f', valuel); + set(handles.edit_lowpass, 'String', valuelstr); + set(handles.edit_lowpass, 'Enable', 'on'); + %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]); + end +else + set(handles.edit_lowpass, 'String', '0'); + set(handles.edit_lowpass, 'Enable', 'off'); + set(handles.togglebutton_lowpass, 'Value', 0); + set(handles.slider_lowpass, 'Enable','off'); + %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]); +end +if typef==0 && autorder==1 + % order starts again for auto butter + orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list + orderlist{1} = 'automin:2'; + set(handles.popupmenu_order, 'String', orderlist); + set(handles.popupmenu_order, 'Value',1); + set(handles.popupmenu_dboct, 'Value',1); + set(handles.popupmenu_dbdec, 'Value',1); +end + +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function slider_lowpass_CreateFcn(hObject, eventdata, handles) + +if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor',[.9 .9 .9]); +end + +%-------------------------------------------------------------------------- +function popupmenu_order_Callback(hObject, eventdata, handles) + +orderindx = get(handles.popupmenu_order, 'Value'); +orderlist = cellstr(get(handles.popupmenu_order, 'String')); + +if orderindx==1 + orderlist = regexprep(orderlist,'automin:','','ignorecase'); %get rid of auto: (if any) + newlaborder = ['automin:' orderlist{2}]; + orderlist{1} = newlaborder; + set(handles.popupmenu_order,'String', orderlist); + handles.autorder = 1; + + if get(handles.radiobutton_butter,'Value') + order = str2num(strrep(orderlist{1},'automin:','')); % get rid of auto (in case of) + set(handles.popupmenu_dboct,'Value', 1); + set(handles.popupmenu_dbdec,'Value', 1); + end +else + orderlist{1} = 'automin'; + set(handles.popupmenu_order,'String', orderlist); + handles.autorder = 0; + + if get(handles.radiobutton_butter,'Value') + set(handles.popupmenu_dboct,'Value', orderindx-1); + set(handles.popupmenu_dbdec,'Value', orderindx-1); + end +end + +% Update handles structure +guidata(hObject, handles); +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function popupmenu_order_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function edit_highpass_Callback(hObject, eventdata, handles) + +valueh = str2num(get(handles.edit_highpass, 'String')); + +if length(valueh)~=1 + msgboxText = 'Invalid input for high pass cutoff'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + return +end +if valueh<0.001; + set(handles.edit_highpass, 'String', num2str(handles.maxsliders)) + set(handles.slider_highpass, 'Value', handles.maxsliders); + set(handles.slider_highpass, 'Enable', 'on'); + set(handles.togglebutton_highpass, 'Value', 1); + set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]); + plotresponsefilter(hObject, eventdata, handles); + return +end +if valueh<0 + msgboxText = 'Invalid input for high pass cutoff'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + set(handles.edit_highpass, 'String', '0') + set(handles.edit_highpass, 'Enable', 'off') + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_highpass, 'Enable', 'off'); + set(handles.togglebutton_highpass, 'Value', 0); + set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]); + plotresponsefilter(hObject, eventdata, handles); + return +end +if valueh>handles.maxsliders + msgboxText = 'Too high!!!'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + set(handles.edit_highpass, 'String', num2str(handles.maxsliders)) + set(handles.slider_highpass, 'Value', handles.maxsliders); + set(handles.slider_highpass, 'Enable', 'on'); + set(handles.togglebutton_highpass, 'Value', 1); + set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]); + plotresponsefilter(hObject, eventdata, handles); + return +end + +set(handles.edit_highpass, 'String', num2str(valueh)); +autorder = handles.autorder; + +if get(handles.radiobutton_butter, 'Value'); + typef = 0; % 0 means Butterworth +elseif get(handles.radiobutton_fir, 'Value'); + typef = 1;% 1 means FIR +elseif get(handles.radiobutton_PM_notch, 'Value'); + typef = 2; % 2 means PM Notch +end + +notchpm = get(handles.radiobutton_PM_notch,'Value'); + +if notchpm + if valueh>=5 && valueh<=handles.maxsliders-5 + set(handles.slider_highpass, 'Value', valueh); + else + if valueh<5 + nvaln = 5; + elseif valueh>handles.maxsliders-5 + nvaln = handles.maxsliders-5; + end + + nvalstr = sprintf('%.1f',nvaln); + set(handles.edit_highpass, 'String', nvalstr); + set(handles.slider_highpass, 'Value', nvaln); + end + + % + % Plot corresponding response + % + + if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) + elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); + end +else + set(handles.slider_highpass, 'Value', valueh); + + if typef==0 && autorder==1 + % order starts again for auto butter + orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list + orderlist{1} = 'automin:2'; + set(handles.popupmenu_order, 'String', orderlist); + set(handles.popupmenu_order, 'Value',1); + end + + % + % Plot corresponding response + % + if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) + elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); + end +end + +%-------------------------------------------------------------------------- +function edit_highpass_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function edit_lowpass_Callback(hObject, eventdata, handles) + +valuel = str2num(get(handles.edit_lowpass, 'String')); + +if length(valuel)~=1 + msgboxText = 'Invalid input for low pass cutoff'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + return +end +if valuel<0.001; + set(handles.edit_lowpass, 'String', num2str(handles.maxsliders)) + set(handles.slider_lowpass, 'Value', handles.maxsliders); + set(handles.slider_lowpass, 'Enable', 'on'); + set(handles.togglebutton_lowpass, 'Value', 1); + set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]); + plotresponsefilter(hObject, eventdata, handles); + return +end +if valuel<0 + msgboxText = 'Invalid input for low pass cutoff'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + set(handles.edit_lowpass, 'String', '0') + set(handles.edit_lowpass, 'Enable', 'off') + %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.slider_lowpass, 'Value', 0); + set(handles.slider_lowpass, 'Enable', 'off'); + set(handles.togglebutton_lowpass, 'Value', 0); + set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]); + plotresponsefilter(hObject, eventdata, handles); + return +end +if valuel>handles.maxsliders + msgboxText = 'Too high!!!'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + set(handles.edit_lowpass, 'String', num2str(handles.maxsliders)) + set(handles.slider_lowpass, 'Value', handles.maxsliders); + set(handles.slider_lowpass, 'Enable', 'on'); + set(handles.togglebutton_lowpass, 'Value', 1); + set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]); + plotresponsefilter(hObject, eventdata, handles); + return +end + +set(handles.edit_lowpass, 'String', num2str(valuel)); +autorder = handles.autorder; +set(handles.slider_lowpass, 'Value', valuel); + +if get(handles.radiobutton_butter, 'Value'); + typef = 0; % 0 means Butterworth +elseif get(handles.radiobutton_fir, 'Value'); + typef = 1;% 1 means FIR +elseif get(handles.radiobutton_PM_notch, 'Value'); + typef = 2; % 2 means PM Notch +end +if typef==0 && autorder==1 + % order starts again for auto butter + orderlist = cellstr(get(handles.popupmenu_order, 'String')); % whole list + orderlist{1} = 'automin:2'; + set(handles.popupmenu_order, 'String', orderlist); + set(handles.popupmenu_order, 'Value',1); +end + +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function edit_lowpass_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +% % % function popupmenu_channels_Callback(hObject, eventdata, handles) +% % % +% % % numch = get(hObject, 'Value'); +% % % nums = str2num(get(handles.edit_channels, 'String')); +% % % nums = [nums numch]; +% % % if isempty(nums) +% % % msgboxText{1} = 'Invalid channel indexing.'; +% % % title = 'EStudio: f_basicfilter GUI error:'; +% % % errorfound(msgboxText, title); +% % % return +% % % end +% % % chxstr = vect2colon(nums,'Delimiter','off', 'Repeat', 'off'); +% % % set(handles.edit_channels,'String', chxstr) +% % % if get(handles.radiobutton_ufdatafr,'Value'); +% % % plotresponse_uf_data(hObject, eventdata, handles); +% % % end + +%-------------------------------------------------------------------------- +% % function popupmenu_channels_CreateFcn(hObject, eventdata, handles) +% % +% % if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) +% % set(hObject,'BackgroundColor','white'); +% % end + +%-------------------------------------------------------------------------- +function edit_channels_Callback(hObject, eventdata, handles) + +nchan = handles.nchan; +chx = str2num(get(handles.edit_channels,'String')); +tf = checkchannels(chx, nchan); +if tf + return +end +ERPLAB = handles.ERPLAB; +[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, [], chx,2); +if chk(2) + title = 'EStudio: f_basicfilterGUI2'; + errorfound(msgboxText, title); + return; +end +handles.indxlistch = chx; % channel array +% if length(chx)==nchan +% % set(handles.checkbox_filterallchannels, 'Value', 1) +% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off')); +% set(handles.edit_channels, 'Enable', 'off'); +% set(handles.pushbutton_browsechan, 'Enable', 'off'); +% else +chxstr = vect2colon(chx,'Delimiter','off', 'Repeat', 'off'); +set(handles.edit_channels,'String', chxstr) +% end +if get(handles.radiobutton_ufdatafr,'Value'); + plotresponse_uf_data(hObject, eventdata, handles); +elseif get(handles.radiobutton_fdatafr,'Value'); + plotresponse_fd_data(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function tf = checkchannels(chx, nchan, showmsg) + +if nargin<3 + showmsg = 1; +end +tf = 0; % no problem by default +if isempty(chx) + if showmsg + msgboxText = 'Invalid channel indexing.'; + title = 'EStudio: f_basicfilterGUI2 error:'; + errorfound(msgboxText, title); + end + tf = 1; % + return +end +if ~isempty(find(chx>nchan)) + if showmsg + msgboxText = ['You only have %g channels,\n'... + 'so you cannot specify indices greater than this.']; + title = 'EStudio: f_basicfilterGUI2 error:'; + errorfound(sprintf(msgboxText, nchan), title); + end + tf = 1; % + return +end +if ~isempty(find(chx<1)) + if showmsg + msgboxText = 'You cannot use zero or a negative number as a channel indexing'; + title = 'EStudio: f_basicfilterGUI2 error:'; + errorfound(msgboxText, title); + end + tf = 1; % + return +end +if length(chx)>length(unique_bc2(chx)) + if showmsg + msgboxText = ['Repeated channels are not allowed.\n'... + 'Therefore, ERPLAB will get rid of them.']; + title = 'EStudio: f_basicfilterGUI2 error:'; + errorfound(sprintf(msgboxText), title, [1 1 0], [0 0 0], 0) + end + tf = 0; % + return +end +return + +%-------------------------------------------------------------------------- +function edit_channels_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) + +handles.output= []; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +%-------------------------------------------------------------------------- +function pushbutton_help_Callback(hObject, eventdata, handles) +% doc pop_basicfilter +web https://github.com/lucklab/erplab/wiki/Filtering -browser +%-------------------------------------------------------------------------- +function pushbutton_apply_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function pushbutton_apply_Callback(hObject, eventdata, handles) +global outstr +outstr=[]; + +[readobjects v] = read_GUI(hObject, eventdata, handles); % v=1 means everythink is ok. + +if v~=1 % means something was wrong + return +end + +channelArray = readobjects{1}; +filterallch = readobjects{2}; +highpasscutoff = readobjects{3}; +lowpasscutoff = readobjects{4}; +order = readobjects{5}; +typefilter = readobjects{6}; +remove_dc = readobjects{7}; +boundarycheck = readobjects{8}; +boundarystr = readobjects{9}; + +binArray = str2num(get(handles.edit_bins,'String')); +% tf = checkchannels(chx, nchan); +def = handles.def; + +ERPLAB = handles.ERPLAB; +if def{5} + binArray = [1:ERPLAB.nbin]; + channelArray = [1:ERPLAB.nchan]; +end + + +[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, binArray,[],1); +if chk(1) + title = 'EStudio: f_basicfilterGUI2'; + errorfound(msgboxText, title); + return; +end + +iswarngain = handles.iswarngain; +iswarnroff = handles.iswarnroff; + +if (iswarngain==1 || iswarngain==2) && ~strcmpi(typefilter,'notch') + + BackERPLABcolor = [1 0.9 0.3]; % yellow + + if iswarngain==1 + question = ['With this filter setting, there will be significant \n'... + 'attenuation at passband. This is almost always a \n'... + 'bad thing. This problem can usually be eliminated by \n'... + 'selecting a lower high-pass cuttoff, higher low-pass \n'... + 'cuttoff, and/or a higher filter order. ']; + elseif iswarngain==2 + question = ['With this filter setting, there will be some \n'... + 'amplification at the passband frequencies. \n'... + 'This problem can be eliminated by selecting \n'... + 'a higher filter order. ']; + end + + title = 'WARNING!'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Proceed anyway', 'Cancel','Proceed anyway'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if ~strcmpi(button,'Proceed anyway') + disp('User selected Cancel') + return + end +end +if highpasscutoff==0 && lowpasscutoff==0 + msgboxText = ['I beg your pardon?\n\n'... + 'You must define one frequency cutoff at least.']; + title = 'EStudio: f_basicfilter GUI error:'; + errorfound(sprintf(msgboxText), title); + return +end +if strcmp(typefilter, 'fir') || strcmp(typefilter, 'notch') + + minboundarysamdist = handles.minboundarysamdist; + if boundarycheck==1 + if minboundarysamdist<3*order + BackERPLABcolor = [ 1 1 0]; + question = ['You have set the checkbox for filtering between boundary events.\n'... + 'Event codes ''boundary'' or -99 were found in you dataset.\n\n'... + 'However, at least one of the segments among boundaries \n'... + 'has less samples than 3 times the filter order you are currently setting.\n\n'... + 'You may either decrese the order of the filter - if it is possible - (recommended),\n'... + 'or uncheck the option for filtering between boundary events (not recommended).']; + + questionstr = sprintf(question); + titlex = 'EStudio: Filter order vs number of samples'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(questionstr, titlex,'OK','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + return + end + end +end +if boundarycheck==1 + if strcmpi(boundarystr,'boundary')||strcmpi(boundarystr,'''boundary''') + boundary = 'boundary'; + else + if ~strcmp(boundarystr,'') + boundary = str2num(boundarystr); + if isempty(boundary); + boundary = boundarystr; + end + else + %boundary = []; + msgboxText = ['You have set the checkbox for filtering between boundary events.\n'... + 'So, you must define a boundary event code.']; + title = 'EStudio: f_basicfilter GUI error:'; + errorfound(sprintf(msgboxText), title); + return + end + end +else + boundary = []; +end + +nchan = handles.nchan; +tf = checkchannels(channelArray, nchan, 0); % 0 means no problems + +if tf + return +end +if ~isempty(highpasscutoff) && ~isempty(lowpasscutoff) && ~isempty(order) && ~isempty(channelArray) && ~isempty(binArray) + %v=1; + outstr = {highpasscutoff, lowpasscutoff, order, channelArray, filterallch, typefilter, remove_dc, boundary,binArray}; + %handles.output = outstr; + %guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + msgboxText = 'Something went wrong...Please try again'; + title = 'EStudio: f_basicfilter GUI error:'; + errorfound(msgboxText, title); + return +end + +%-------------------------------------------------------------------------- +function [readobjects v] = read_GUI(hObject, eventdata, handles) +% global readobjects +v = 1; % everything ok by default +readobjects = {}; +channelArray = str2num(get(handles.edit_channels, 'string')); +channelArray = unique_bc2(channelArray); +len1 = length(channelArray); +% filterallch = get(handles.checkbox_filterallchannels, 'Value'); +% if filterallch +% nchan = handles.nchan; +% channelArray = 1:nchan; % all channels +% len2 = length(channelArray); +% if len1~=len2 +% fprintf('Index of channels to be filtered was adjusted since current %s has %g channels.\n', typedata, nchan); +% end +% if len2==nchan +% set(handles.checkbox_filterallchannels, 'Value', 1) +% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off')); +% set(handles.edit_channels, 'Enable', 'off'); +% set(handles.pushbutton_browsechan, 'Enable', 'off'); +% end +% end +filterallch = 1; +highpasscutoff = str2num(get(handles.edit_highpass, 'string')); +if length(highpasscutoff)~=1 + msgboxText = 'Invalid input for high pass cutoff'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + v=0; + return +end +remove_dc = get(handles.checkbox_removedc, 'Value'); +boundarystr = get(handles.edit_boundary, 'String'); +boundarycheck = get(handles.checkbox_boundary,'Value'); +if get(handles.radiobutton_butter, 'Value'); % 0 means Butterworth + typefilter = 'butter'; +elseif get(handles.radiobutton_fir, 'Value'); % 1 means FIR + typefilter = 'fir'; +elseif get(handles.radiobutton_PM_notch, 'Value'); % 2 means PM Notch + typefilter = 'notch'; +end +if strcmp(typefilter, 'notch') + lowpasscutoff = highpasscutoff; + order = 180; +else + lowpasscutoff = str2num(get(handles.edit_lowpass, 'string')); + + if length(lowpasscutoff)~=1 + msgboxText = 'Invalid input for low pass cutoff'; + title = 'EStudio: basicfilterGUI2() error'; + errorfound(msgboxText, title); + v=0; + return + end + order = getorder(handles); +end +readobjects = {channelArray, filterallch, highpasscutoff, lowpasscutoff, order, typefilter, remove_dc, boundarycheck, boundarystr}; + +%-------------------------------------------------------------------------- +function checkbox_removedc_Callback(hObject, eventdata, handles) + +% ------------------------------------------------------------------------- +function togglebutton_highpass_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.edit_highpass, 'Enable', 'on'); + set(handles.edit2_highpass, 'Enable', 'on'); + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_highpass, 'Enable', 'inactive'); + set(handles.togglebutton_highpass, 'Value', 1); + set(handles.slider_highpass, 'Enable','on'); + mvalueh = round(handles.mvalueh*10)/10; + + if mvalueh<0.1 + handles.mvalueh = 0.1; + end + + set(handles.slider_highpass, 'Value', handles.mvalueh); + set(handles.edit_highpass, 'String', num2str(handles.mvalueh)); + set(handles.checkbox_removedc, 'Enable', 'on') + set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]); + + % + % Roll off + % + set(handles.popupmenu_dboct, 'Enable', 'on'); + set(handles.popupmenu_dbdec, 'Enable', 'on'); + set(handles.popupmenu_order, 'Enable', 'on'); + + % + % Plot filter related responses + % + set(handles.radiobutton_freqr, 'Enable', 'on'); + set(handles.radiobutton_impr, 'Enable', 'on'); + set(handles.radiobutton_fdatafr, 'Enable', 'on'); + + % Update handles structure + guidata(hObject, handles); +else + set(handles.togglebutton_highpass, 'Value', 0); + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_highpass, 'Enable','off'); + set(handles.edit_highpass, 'String', '0'); + set(handles.edit_highpass, 'Enable', 'off'); + set(handles.edit2_highpass, 'String', '---'); + set(handles.edit2_highpass, 'Enable', 'off'); + set(handles.checkbox_removedc, 'Enable', 'off') + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]); +end +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +else + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function togglebutton_lowpass_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.edit_lowpass, 'Enable', 'on'); + set(handles.edit2_lowpass, 'Enable', 'on'); + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_lowpass, 'Enable', 'inactive'); + set(handles.slider_lowpass, 'Enable','on'); + fc = round(handles.mvaluel*10)/10; + + if fc==0 + fc = round(handles.maxsliders*5)/10; + end + + set(handles.slider_lowpass, 'Value', fc); + set(handles.edit_lowpass, 'String', num2str(fc)); + %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]); + set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]); + + % + % Roll off + % + set(handles.popupmenu_dboct, 'Enable', 'on'); + set(handles.popupmenu_dbdec, 'Enable', 'on'); + set(handles.popupmenu_order, 'Enable', 'on'); + + % + % Plot filter related responses + % + set(handles.radiobutton_freqr, 'Enable', 'on'); + set(handles.radiobutton_impr, 'Enable', 'on'); + set(handles.radiobutton_fdatafr, 'Enable', 'on'); +else + set(handles.edit_lowpass, 'String', '0'); + set(handles.edit_lowpass, 'Enable', 'off'); + set(handles.edit2_lowpass, 'String', '---'); + set(handles.edit2_lowpass, 'Enable', 'off'); + set(handles.slider_lowpass, 'Enable','off'); + set(handles.slider_lowpass, 'Value', 0); + %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]); +end +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +else + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function radiobutton_freqr_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_impr,'Value', 0); + set(handles.radiobutton_ufdatafr,'Value', 0); + set(handles.radiobutton_fdatafr,'Value', 0); + %set(handles.popupmenu_FRscale,'Value', 1); + set(handles.popupmenu_FRscale,'Enable', 'on'); + set(handles.radiobutton_butter, 'Enable', 'on') + set(handles.radiobutton_fir, 'Enable', 'on') + set(handles.radiobutton_PM_notch,'Enable','on') + set(handles.radiobutton_ideal, 'Enable','on') + plotresponsefilter(hObject, eventdata, handles); +else + set(handles.radiobutton_freqr,'Value', 1); +end + +%-------------------------------------------------------------------------- +function radiobutton_impr_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_freqr,'Value', 0); + set(handles.radiobutton_ufdatafr,'Value', 0); + set(handles.radiobutton_fdatafr,'Value', 0); + %set(handles.popupmenu_FRscale,'Value', 1); + set(handles.popupmenu_FRscale,'Enable', 'off'); + set(handles.radiobutton_butter, 'Enable', 'on') + set(handles.radiobutton_fir, 'Enable', 'on') + set(handles.radiobutton_PM_notch,'Enable','on') + set(handles.radiobutton_ideal, 'Enable','off') + plotresponsefilter(hObject, eventdata, handles); +else + set(handles.radiobutton_impr,'Value', 1); +end + +%-------------------------------------------------------------------------- +function radiobutton_ufdatafr_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_freqr,'Value', 0); + set(handles.radiobutton_impr,'Value', 0); + set(handles.radiobutton_fdatafr,'Value', 0); + % set(handles.popupmenu_FRscale,'Value', 1); + set(handles.popupmenu_FRscale,'Enable', 'on'); + set(handles.radiobutton_butter, 'Enable', 'off') + set(handles.radiobutton_fir, 'Enable', 'off') + set(handles.radiobutton_PM_notch,'Enable','off') + set(handles.radiobutton_ideal, 'Enable','off') + drawnow + plotresponse_uf_data(hObject, eventdata, handles); +else + set(handles.radiobutton_ufdatafr,'Value', 1); +end + +%-------------------------------------------------------------------------- +function radiobutton_fdatafr_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_freqr,'Value', 0); + set(handles.radiobutton_impr,'Value', 0); + set(handles.radiobutton_ufdatafr,'Value', 0); + % set(handles.popupmenu_FRscale,'Value', 1); + set(handles.popupmenu_FRscale,'Enable', 'on'); + set(handles.radiobutton_butter, 'Enable', 'on') + set(handles.radiobutton_fir, 'Enable', 'on') + set(handles.radiobutton_PM_notch,'Enable','on') + set(handles.radiobutton_ideal, 'Enable','on') + drawnow + plotresponse_fd_data(hObject, eventdata, handles); +else + set(handles.radiobutton_fdatafr,'Value', 1); +end + +%-------------------------------------------------------------------------- +function checkbox_boundary_Callback(hObject, eventdata, handles) +if get(hObject, 'Value') + + set(handles.edit_boundary,'Enable', 'on'); + %set(handles.edit_boundary,'BackgroundColor', [1 1 1]); + + if get(handles.radiobutton_butter, 'Value'); % 0 means Butterworth + typef = 0; + elseif get(handles.radiobutton_fir, 'Value'); % 1 means FIR + typef = 1; + elseif get(handles.radiobutton_PM_notch, 'Value'); % 2 means PM Notch + typef = 2; + end + if typef==1 || typef==2 + + % + % FILTER order + % + order = getorder(handles); + + minboundarysamdist = handles.minboundarysamdist; + + if get(handles.checkbox_boundary,'Value') + if minboundarysamdist<3*order + BackERPLABcolor = [ 1 1 0]; + question = ['You have set the checkbox for filtering between boundary events.\n'... + 'Event codes ''boundary'' or -99 were found in you dataset.\n\n'... + 'However, at least one of the segments among boundaries \n'... + 'has less samples than 3 times the filter order you are currently setting.\n\n'... + 'You may either decrese the order of the filter - if it is possible - (recommended),\n'... + 'or uncheck the option for filtering between boundary events (not recommended).']; + questionstr = sprintf(question); + titlex = 'EStudio: Filter order vs number of samples'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(questionstr, titlex,'OK','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + return + end + end + end +else + set(handles.edit_boundary,'Enable', 'off'); + set(handles.edit_boundary,'BackgroundColor', [0.75 0.75 0.75]); +end + +%-------------------------------------------------------------------------- +function checkbox_notch_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function no_filter(hObject,handles, msgtx) +plot(1, 1, 'w'); +text(0.32,0.5, msgtx,'FontSize',18, 'color', [1 0 0]) +axis([0 1 0 1]) +set(handles.slider_highpass, 'Value', 0); +set(handles.slider_lowpass, 'Value', 0); +set(handles.slider_highpass, 'Enable', 'off') +set(handles.slider_lowpass, 'Enable', 'off') +set(handles.togglebutton_highpass, 'Value', 0) +set(handles.togglebutton_lowpass, 'Value', 0) +set(handles.edit_highpass,'String','0') +set(handles.edit_highpass,'Enable','off') +set(handles.edit2_highpass,'String','---') +set(handles.edit2_highpass,'Enable','off') +set(handles.edit_lowpass,'String','0') +set(handles.edit_lowpass,'Enable','off') +set(handles.edit2_lowpass,'String','---') +set(handles.edit2_lowpass,'Enable','off') +set(handles.checkbox_removedc, 'Enable','off') +handles.memvalueh = 0.1; +handles.mvalueh = 0.1; % memory value highpass +fc = round(handles.maxsliders*5)/10; +handles.memvaluel = fc; +handles.mvaluel = fc; % memory value lowpass + +% Update handles structure +guidata(hObject, handles); +return + +%########################################################################## +%########################################################################## +%########################################################################## +%########################################################################## + +function [hfr labelf] = plotresponsefilter(hObject, eventdata, handles) + +% +% IMPORTANT: This function plot the filter response of FILTFILT function only. +% +hfr = []; +valueh = get(handles.slider_highpass, 'Value'); +valuel = get(handles.slider_lowpass, 'Value'); +axes(handles.axes1); + +if valueh==0 && valuel==0 + if get(handles.radiobutton_freqr, 'Value') ||... + get(handles.radiobutton_impr, 'Value') ||... + get(handles.radiobutton_fdatafr, 'Value') + msgtx = '--NO FILTERING--'; + no_filter(hObject, handles, msgtx) + end + return +else + xmaxp = handles.xmaxfreqr; + if nargout==0 + %if ~isempty(xmaxp) + if get(handles.radiobutton_freqr, 'Value') || get(handles.radiobutton_impr, 'Value') + % posaxes1 = get(gca,'YLim'); + msgtx = 'Working, please wait...'; + text(mean(xmaxp)/3, 1.12, msgtx,'FontSize',14, 'color', 'k') + drawnow + end + %end + end +end + +fs = handles.fs; +fnyq = fs/2; + +% +% FILTER order +% +order = getorder(handles); + +if isempty(order) + disp('Still busy...') + return +end +if get(handles.radiobutton_butter, 'Value'); % 0 means Butterworth + typef = 0; +elseif get(handles.radiobutton_fir, 'Value'); % 1 means FIR + typef = 1; +elseif get(handles.radiobutton_PM_notch, 'Value'); % 2 means PM Notch + typef = 2; +end + +n = round(fnyq); % number of points for frequency response. +hpzoom = diff(str2num(char(get(handles.edit_xmaxplot,'String')))); + +% +% Augmented number of points for frequency response. +% +if hpzoom<=5 + n = n*50; +elseif hpzoom<=0.5 + n = n*1000; +end +if typef==2 % PM Notch + valuel = valueh; +end + +bt = []; +at = []; + +[bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, order, valuel, valueh, fs); + +if ~v % something is wrong or turned off + disp('Filter coefficient calculation failed...') + if get(handles.radiobutton_freqr, 'Value') ||... + get(handles.radiobutton_impr, 'Value') ||... + get(handles.radiobutton_fdatafr, 'Value') + msgtx = '--NO FILTERING--'; + no_filter(hObject, handles, msgtx) + end + + handles.autorder = 0; + % Update handles structure + guidata(hObject, handles); + return +else + autorder = handles.autorder; +end +if ~isempty(orderx) + if orderx~=order + order = orderx; + str = ['\nWARNING: Odd order symmetric FIR filters must have a gain of zero \n'... + 'at the Nyquist frequency. The order has been increased to %g.\n']; + fprintf(str, order); + end +end + +% +% Automin for FIR +% +if autorder == 1 && typef==1 + slidersoff(hObject, eventdata, handles) + orderlist = cellstr(get(handles.popupmenu_order,'String')); + orderlist{1} = 'automin...'; + set(handles.popupmenu_order, 'String', orderlist) + set(handles.popupmenu_order, 'Value', 1) + set(handles.text_halfamp, 'String','updating...'); + set(handles.text_halfpow, 'String','updating...'); + drawnow + xdB_at_fx = 0; + order = 4; + j=1; + + while mean(xdB_at_fx)~=-6 && order<=4096-2 && j<=2000% && get(handles.popupmenu_order,'Value')==1 + + if mean(xdB_at_fx)==0 + order = order + 32; + elseif mean(xdB_at_fx)>-3 && mean(xdB_at_fx)<0 + order = order + 8; + else + order = order + 4; + end + + [bt, at, labelf, v, frec3dB, xdB_at_fx, orderx] = filter_tf(typef, order, valuel, valueh, fs); + + if isempty(xdB_at_fx) + xdB_at_fx = 0; + end + if v + if orderx~=order + if mod(orderx,4)==0 + order = orderx; + else + order = orderx + 2; + end + str = ['\nWARNING: Odd order symmetric FIR filters must have a gain of zero \n'... + 'at the Nyquist frequency. The order has been increased to %g.\n']; + fprintf(str, order); + end + end + end + if mean(xdB_at_fx)==-6 + orderlist{1} = ['automin:' num2str(order)]; + set(handles.popupmenu_order, 'String', orderlist) + set(handles.popupmenu_order, 'Value', 1) + disp('min order was found.') + iswarnroff = 0; + else + orderlist{1} = 'automin'; + set(handles.popupmenu_order, 'String', orderlist) + set(handles.popupmenu_order, 'Value', length(orderlist)) + handles.autorder = 0; + iswarnroff = 1; % atenuation at frquency cutoff was impposible... + + % Update handles structure + guidata(hObject, handles); + disp('min order was not found...') + end + + sliderson(hObject, eventdata, handles) + drawnow +else + if mean(xdB_at_fx)==-6 + iswarnroff =0; + else + iswarnroff =1; + end +end +if ~v % something is wrong or turned off (1 means everything is ok) + if get(handles.radiobutton_freqr, 'Value') ||... + get(handles.radiobutton_impr, 'Value') ||... + get(handles.radiobutton_fdatafr, 'Value') + + msgtx = '--NO FILTERING--'; + no_filter(hObject, handles, msgtx) + end + disp('Filter coefficient calculation failed....') + handles.autorder = 0; + % Update handles structure + guidata(hObject, handles); + return +end + +% +% Final filter coefficients +% +if size(bt,1)==2 + if strcmpi(labelf,'Band-Pass') + % cascade filter transfer function + b = conv(bt(1,:),bt(2,:)); + a = conv(at(1,:),at(2,:)); + else + % parallel filter transfer function + b = conv(bt(1,:),at(2,:)) + conv(bt(2,:),at(1,:)); + a = conv(at(1,:),at(2,:)); + end +else + b = bt; + a = at; +end + +% +% Half power cuttoff (-3 dB) (ONLY FOR FILTFILT!) +% +if ~isempty(frec3dB) + if strcmpi(labelf, 'Low-pass') + f3str = sprintf('%7.2f', frec3dB); + set(handles.edit2_highpass,'String','---') + set(handles.edit2_highpass,'Enable','off') + set(handles.edit2_lowpass,'String', f3str) + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + elseif strcmpi(labelf, 'High-pass') + f3str = sprintf('%7.2f', frec3dB); + set(handles.edit2_highpass,'String',f3str) + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_lowpass,'String', '---') + set(handles.edit2_lowpass,'Enable','off') + else + try + f3str1 = sprintf('%7.2f', frec3dB(1)); + f3str2 = sprintf('%7.2f', frec3dB(2)); + set(handles.edit2_highpass,'String', f3str2) + set(handles.edit2_lowpass,'String', f3str1) + %set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + catch + set(handles.edit2_highpass,'String','---') + set(handles.edit2_lowpass,'String', '---') + set(handles.edit2_highpass,'Enable','off') + set(handles.edit2_lowpass,'Enable','off') + end + end +else + set(handles.edit2_highpass,'String','---') + set(handles.edit2_lowpass,'String','---') + set(handles.edit2_highpass,'Enable','off') + set(handles.edit2_lowpass,'Enable','off') +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Filter responses. Thanks to Sean Little from MathWorks Technical Support Department. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% +% filtfilt frequency response +% +[hfr,f1] = freqz(b,a,n,fs); +hfr = abs(hfr).^2; % Filter responses is squared in order to fit with FILTFILT + +% filtfilt impulse response +[hira,f3] = freqz(b,a,n,'whole',fs); +hir2 = abs(hira).^2; +hir = ifft(hir2); + +% +% Gain constraint. Gain should be close to 1 at the passband region. +% +gain_postL = 1-0.05; % 5% criteria +gain_postU = 1+0.05; % 5% criteria + +if max(abs(hfr))>=gain_postL && max(abs(hfr))<=gain_postU && (max(abs(hfr))-min(abs(hfr)))>0.95 + + iswarngain = 0; % gain is fine + + % + % Slider memory + % + handles.memvaluel = round(valuel); + handles.memvalueh = round(valueh); + handles.mem6dbl = num2str(ceil(str2num(get(handles.edit_lowpass,'String')))); + handles.mem6dbh = num2str(floor(str2num(get(handles.edit_highpass,'String')))); + handles.mem3dbl = num2str(ceil(str2num(get(handles.edit2_lowpass,'String')))); + handles.mem3dbh = num2str(floor(str2num(get(handles.edit2_highpass,'String')))); + +elseif max(abs(hfr))>=gain_postL && max(abs(hfr))<=gain_postU && (max(abs(hfr))-min(abs(hfr)))<=0.75 + iswarngain = 3; + xdB_at_fx = []; +else + if max(abs(hfr))=4096 + BackERPLABcolor = [ 1 1 0]; + + question = ['Unable to achieve specified cutoff (-6dB). Higher filter order is needed,\n'... + 'but order greater than 4096 is not allowed for this ERPLAB version.\n'... + 'You may either select a wider passband with automin (recommended),\n'... + 'or turn off automin and leave with the reduced attenuation (not recommended)']; + + questionstr = sprintf(question); + titlex = 'EStudio: Filter order'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(questionstr, titlex,'OK','Reset filters','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + % + % reset order + % + orderlist = cellstr(get(handles.popupmenu_order, 'String')); + orderindx = get(handles.popupmenu_order, 'Value'); + order = str2num(strrep(orderlist{orderindx},'automin:','')); + orderlist{1} = 'automin'; + [tfx, posord] = ismember_bc2(order,[-1 4:4:4096]); + + set(handles.popupmenu_order, 'String',orderlist) + set(handles.popupmenu_order, 'Value',posord) + set(handles.popupmenu_dboct, 'String','---') + set(handles.popupmenu_dbdec, 'String','---') + set(handles.popupmenu_dboct, 'Value',1) + set(handles.popupmenu_dbdec, 'Value',1) + handles.autorder = 0; + + if strcmpi(button,'OK') + set(handles.slider_highpass, 'Value', handles.memvalueh); + set(handles.slider_lowpass, 'Value', handles.memvaluel); + chksliders(hObject, eventdata, handles) + set(handles.edit_highpass, 'String', handles.mem6dbh); + set(handles.edit_lowpass, 'String', handles.mem6dbl); + set(handles.edit2_highpass, 'String', handles.mem3dbh); + set(handles.edit2_lowpass, 'String', handles.mem3dbl); + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + sliderson(hObject, eventdata, handles) + + % Update handles structure + guidata(hObject, handles); + plotresponsefilter(hObject, eventdata, handles); + return + else + sliderson(hObject, eventdata, handles) + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_lowpass, 'Value', fnyq/2); + chksliders(hObject, eventdata, handles) + handles.memvalueh = 0.1; + handles.mvalueh = 0.1; % memory value highpass + + % Update handles structure + guidata(hObject, handles); + plotresponsefilter(hObject, eventdata, handles); + return + end + end +elseif iswarngain~=0 && iswarnroff==0 + if autorder == 1 && typef==0 + slidersoff(hObject, eventdata, handles) + + % + % Filter order + % + order = getorder(handles); + + if isempty(order) + disp('Ops, I could not read the filter order...') + sliderson(hObject, eventdata, handles) + return + end + + order = order + 2; % increase the order + ishopermission = handles.ishopermission; % permission for higher order when high-pass filter cutoff is <=0.5 + + if order>2 && order<=8 && valueh>0 && valueh<=0.5 && ~ishopermission + question = ['We do not recommend a filter order greater than 2 for a Butterworth filter\n '... + 'when the high-pass cutoff is <= 0.5 Hz\n'... + 'Continue anyway?']; + titlex = 'EStudio: Filter order'; + button = askquest(sprintf(question), titlex); + + if ~strcmpi(button,'yes') + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_lowpass, 'Value', handles.memvaluel); + + if handles.memvaluel==0 + set(handles.slider_lowpass, 'Enable', 'off'); + set(handles.togglebutton_lowpass,'Value',0) + set(handles.edit_lowpass, 'String', '0'); + set(handles.edit_lowpass, 'Enable', 'off'); + set(handles.edit2_lowpass, 'String', '---'); + set(handles.edit2_lowpass, 'Enable', 'off'); + else + set(handles.edit_lowpass, 'String', handles.mem6dbl); + set(handles.edit2_lowpass, 'String', handles.mem3dbl); + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + end + + set(handles.edit_highpass, 'String', handles.mem6dbh); + set(handles.edit2_highpass, 'String', handles.mem3dbh); + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.popupmenu_order, 'Value', 2); + handles.autorder = 0; + handles.ishopermission =0; + chksliders(hObject, eventdata, handles) + + % Update handles structure + guidata(hObject, handles); + plotresponsefilter(hObject, eventdata, handles); + sliderson(hObject, eventdata, handles) + return + else + chksliders(hObject, eventdata, handles) + handles.ishopermission = 1; + % Update handles structure + guidata(hObject, handles); + end + + sliderson(hObject, eventdata, handles) + return + end + if order>8 + + BackERPLABcolor = [ 1 1 0]; + + if iswarngain==3 + line01 = 'You are losing stopband attenuation!'; + else + line01 = 'You are losing passband gain!'; + end + + question = ['WARNING: %s \n\n'... + 'In order to use the automin feature, a higher Butterworth filter order is needed, '... + 'but an order greater than 8 is not allowed for this ERPLAB version. '... + 'You may select a wider passband with automin (recommended), '... + 'or turn off automin and leave with the reduced gain (not recommended).']; + + titlex = 'EStudio: Filter order'; + + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question, line01), titlex,'OK','Reset filters','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + % + % reset order + % + orderlist = cellstr(get(handles.popupmenu_order, 'String')); + orderindx = get(handles.popupmenu_order, 'Value'); + order = str2num(strrep(orderlist{orderindx},'automin:','')); + orderlist{1} = 'automin'; + [tfx, posord] = ismember_bc2(order,[-1 2 4 6 8]); + + set(handles.popupmenu_order, 'String',orderlist) + set(handles.popupmenu_order, 'Value',posord) + set(handles.popupmenu_dboct, 'Value',posord-1) + set(handles.popupmenu_dbdec, 'Value',posord-1) + handles.autorder = 0; + + if strcmpi(button,'OK') + set(handles.slider_highpass, 'Value', handles.memvalueh); + set(handles.slider_lowpass, 'Value', handles.memvaluel); + chksliders(hObject, eventdata, handles) + set(handles.edit_highpass, 'String', handles.mem6dbh); + set(handles.edit_lowpass, 'String', handles.mem6dbl); + set(handles.edit2_highpass, 'String', handles.mem3dbh); + set(handles.edit2_lowpass, 'String', handles.mem3dbl); + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); + % Update handles structure + guidata(hObject, handles); + + sliderson(hObject, eventdata, handles) + plotresponsefilter(hObject, eventdata, handles); + return + else + sliderson(hObject, eventdata, handles) + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_lowpass, 'Value', fnyq/2); + chksliders(hObject, eventdata, handles) + handles.memvalueh = 0.1; + handles.mvalueh = 0.1; % memory value highpass + + ordervector = 2:2:8; + set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list + set(handles.popupmenu_order,'Value', 2); + + % Update handles structure + guidata(hObject, handles); + + plotresponsefilter(hObject, eventdata, handles); + return + end + else + rolloffindx = get(handles.popupmenu_dboct,'Value'); + rolloffindx = rolloffindx + 1; + set(handles.popupmenu_dboct,'Value', rolloffindx); + set(handles.popupmenu_dbdec,'Value', rolloffindx); + end + + orderlist = cellstr(get(handles.popupmenu_order, 'String')); + orderlist{1} = ['automin:' num2str(order)]; + set(handles.popupmenu_order, 'String', orderlist) + set(handles.popupmenu_order, 'Value', 1) + sliderson(hObject, eventdata, handles) + + plotresponsefilter(hObject, eventdata, handles); + return + end +end + +% hfig = axes(handles.axes1); + +if get(handles.radiobutton_freqr,'Value') + h = hfr; + f = f1; + color = [0 0 0.75]; + FRscale = get(handles.popupmenu_FRscale, 'Value'); + + if FRscale==1 + ymax = 1.25; + ymin = -0.075; %6.25% of ymax - + ymaxb = 1; + yminb = 0; + plot(f, h, 'linewidth', 2, 'LineSmoothing','on','Color', color) + ylabel('passband gain') + else + ymax = 10; + ymin = -65; + ymaxb = 0; + yminb = -90; + plot(f, 20*log10(h), 'linewidth', 2, 'LineSmoothing','on','Color', color) + ylabel('passband gain in dB') + end + + xlabel('frequency (Hz)') + + if get(handles.radiobutton_ideal, 'Value') + drawidealresp(handles, labelf, fnyq, valuel, valueh, yminb, ymaxb) + end + if typef~=2 + if iswarngain==1 + yym = max(hfr); + + if yym>1 + yym=0.3; + end + + xxm = hpzoom/5; + text(xxm, yym+0.2,' Losing passband gain!','FontSize',10) + text(xxm, yym+0.1,' Increase the order of the filter or select automin.','FontSize',10) + set(gca,'Color', 'y') + + elseif iswarngain==2 + + yym = max(hfr); + + if yym>1 + yym=0.3; + end + + xxm = hpzoom/5; + text(xxm, yym+0.2,' Passband gain of 1 was overpassed!','FontSize',10) + text(xxm, yym+0.1,' Increase the order of the filter or select automin.','FontSize',10) + set(gca,'Color', 'y') + + elseif iswarngain==3 + + yym = max(hfr); + + if yym>1 + yym=0.3; + end + + xxm = hpzoom/5; + text(xxm, yym+0.2,' Losing stopband attenuation','FontSize',10) + text(xxm, yym+0.1,' Increase the order of the filter or select automin.','FontSize',10) + set(gca,'Color', 'y') + + elseif iswarnroff==0 && iswarngain==0 + set(gca,'Color', 'w') + end + else + set(gca,'Color', 'w') + end + +elseif get(handles.radiobutton_impr,'Value') + h = hir; % impulse + f = f3; %1:length(h); + ymax = max(h)*1.2; + ymin = min(h)*1.2; + color = [0.78 0 0.1]; + stem(f, h, 'linewidth', 2, 'Color', color); + xlabel('time (msec)') + ylabel('amplitude') +else + return +end + +% +% True attenuation value at specified cutoff frequency (it must be -6db, otherwise...) +% +if ~isempty(xdB_at_fx) + + attvaldB = round(mean(xdB_at_fx)); + + if attvaldB==-6 && typef==0 + string4HA = ['Half-Amp(' num2str(attvaldB) 'dB)']; + coloratt = 'k'; + else + if typef~=2 + attvalgain = 10^(attvaldB/20); + string4HA = [sprintf('%.2f',attvalgain) '-Amp(' num2str(attvaldB) 'dB)']; + + if attvaldB==-6 && typef==1 + coloratt = 'k'; + else + coloratt = 'r'; + end + else + string4HA = 'Center frequency'; + coloratt = 'k'; + end + end + set(handles.text_halfamp,'String', string4HA, 'ForegroundColor', coloratt) + set(handles.text_halfpow,'String', 'Half-Power(-3dB)', 'ForegroundColor', 'k') +else + set(handles.text_halfamp,'String', '--- ???dB ---', 'ForegroundColor', 'r') + set(handles.text_halfpow,'String', '--- ???dB ---', 'ForegroundColor', 'r') +end + +% +% Axis limits for frequency response +% +xmaxp = str2num(char(get(handles.edit_xmaxplot, 'String'))); + +if isempty(xmaxp) + xmaxp = [0 max(f)]; + if get(handles.radiobutton_fdatafr,'Value') || get(handles.radiobutton_freqr,'Value') + handles.xmaxfreqr = xmaxp; + else + handles.xmaxpimpz = xmaxp; + end +else + if get(handles.radiobutton_fdatafr,'Value') || get(handles.radiobutton_freqr,'Value') + xmaxp = handles.xmaxfreqr; + else + xmaxp = handles.xmaxpimpz; + end +end + +set(handles.edit_xmaxplot, 'String', num2str(xmaxp)); + +% +% Axis limits +% +axis([xmaxp ymin ymax]) +hle = legend(labelf); +set(hle, 'Color', 'none', 'Box', 'off') +handles.memvalueh = valueh; +handles.mvaluel = valuel; +handles.morder = order; +handles.iswarngain = iswarngain; +handles.iswarnroff = iswarnroff; +sliderson(hObject, eventdata, handles) +handles.datafr.yf = hfr; + +if typef==1 || typef==2 + + minboundarysamdist = handles.minboundarysamdist; + + if get(handles.checkbox_boundary,'Value') + if minboundarysamdist<3*order + BackERPLABcolor = [ 1 1 0]; + question = ['You have set the checkbox for filtering between boundary events.\n'... + 'Event codes ''boundary'' or -99 were found in your dataset.\n\n'... + 'However, at least one of the segments among boundaries \n'... + 'has fewer samples than 3 times the filter order you are currently setting.\n\n'... + 'You may either decrese the order of the filter - if it is possible - (recommended),\n'... + 'or uncheck the option for filtering between boundary events.']; + questionstr = sprintf(question); + titlex = 'EStudio: Filter order vs number of samples'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(questionstr, titlex,'OK','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + return + end + end +end + +% Update handles structure +guidata(hObject, handles); + +% ------------------------------------------------------------------------- +function drawidealresp(handles, labelf, fnyq, valuel, valueh, yminb, ymaxb) + +axes(handles.axes1) + +% draw ideal filter response +% +colorband = [0.9922 0.9176 0.7961]; +alphaval = 0.7; + +if ismember_bc2(labelf, {'Low-pass','High-pass','Band-pass'}) + + if strcmpi(labelf,'High-pass') + valuelx = fnyq; + else + valuelx = valuel; + end + + patch([valueh valueh valuelx valuelx],[yminb ymaxb ymaxb yminb],'r',... + 'facecolor',colorband,... + 'edgecolor',colorband,... + 'facealpha',alphaval) +elseif ismember_bc2(labelf,'Stop-band (Parks-McClellan Notch)') + patch([0 0 valuel-1.5 valuel-1.5],[yminb ymaxb ymaxb yminb],'r',... + 'facecolor',colorband,... + 'edgecolor',colorband,... + 'facealpha',alphaval) + patch([valueh+1.5 valueh+1.5 fnyq fnyq],[yminb ymaxb ymaxb yminb],'r',... + 'facecolor',colorband,... + 'edgecolor',colorband,... + 'facealpha',alphaval) +else + patch([0 0 valuel valuel],[yminb ymaxb ymaxb yminb],'r',... + 'facecolor',colorband,... + 'edgecolor',colorband,... + 'facealpha',alphaval) + patch([valueh valueh fnyq fnyq],[yminb ymaxb ymaxb yminb],'r',... + 'facecolor',colorband,... + 'edgecolor',colorband,... + 'facealpha',alphaval) +end +return + +% ------------------------------------------------------------------------- +function popupmenu_dboct_Callback(hObject, eventdata, handles) + +dboct = get(handles.popupmenu_dboct,'Value'); + +if get(handles.radiobutton_butter,'Value') + set(handles.popupmenu_order,'Value', dboct+1) + set(handles.popupmenu_dbdec,'Value', dboct) +end + +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function popupmenu_dboct_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_dbdec_Callback(hObject, eventdata, handles) + +dbdec = get(handles.popupmenu_dbdec,'Value'); + +if get(handles.radiobutton_butter,'Value') + set(handles.popupmenu_order,'Value', dbdec+1); + set(handles.popupmenu_dboct,'Value', dbdec); +end + +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function popupmenu_dbdec_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function radiobutton_butter_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + + unsetnotchpm(hObject, eventdata, handles) + + if get(handles.togglebutton_lowpass,'Value')==1 && get(handles.togglebutton_highpass,'Value')==0 + set(handles.checkbox_removedc, 'Value', 0); + set(handles.checkbox_removedc, 'Enable', 'off'); + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_highpass, 'Enable', 'off') + set(handles.togglebutton_highpass, 'Value', 0) + set(handles.edit_highpass,'String','0') + set(handles.edit_highpass,'Enable','off') + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]); + + elseif get(handles.togglebutton_lowpass,'Value')==0 && get(handles.togglebutton_highpass,'Value')==1 + colorband = [0.9922 0.9176 0.7961]; + set(handles.checkbox_removedc, 'Value', 1); + set(handles.checkbox_removedc, 'Enable', 'on'); + set(handles.slider_highpass, 'Enable', 'on') + set(handles.togglebutton_highpass, 'Value', 1) + %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]); + end + + set(handles.radiobutton_fir,'Value',0) + ordervector = 2:2:8; + set(handles.popupmenu_order,'Enable','on') + set(handles.popupmenu_dboct,'Enable','on') + set(handles.popupmenu_dbdec,'Enable','on') + set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list + set(handles.popupmenu_dboct,'String', num2str(6*ordervector')) % set db/oct list + set(handles.popupmenu_dbdec,'String', num2str(20*ordervector')) % set db/dec list + set(handles.popupmenu_order,'Value',2) + set(handles.popupmenu_dboct,'Value',1) + set(handles.popupmenu_dbdec,'Value',1) + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end +else + set(handles.radiobutton_butter,'Value',1) +end + +%-------------------------------------------------------------------------- +function radiobutton_fir_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + + unsetnotchpm(hObject, eventdata, handles) + + if get(handles.togglebutton_lowpass,'Value')==1 && get(handles.togglebutton_highpass,'Value')==0 + set(handles.checkbox_removedc, 'Value', 0); + set(handles.checkbox_removedc, 'Enable', 'off'); + set(handles.slider_highpass, 'Value', 0); + set(handles.slider_highpass, 'Enable', 'off') + set(handles.togglebutton_highpass, 'Value', 0) + set(handles.edit_highpass,'String','0') + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); + set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]); + elseif get(handles.togglebutton_lowpass,'Value')==0 && get(handles.togglebutton_highpass,'Value')==1 + colorband = [0.9922 0.9176 0.7961]; + set(handles.checkbox_removedc, 'Value', 1); + set(handles.checkbox_removedc, 'Enable', 'on'); + set(handles.slider_highpass, 'Enable', 'on') + set(handles.togglebutton_highpass, 'Value', 1) + %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]) + else + %... + end + + highpasscutoff = str2num(get(handles.edit_highpass, 'string')); + %lowpasscutoff = str2num(get(handles.edit_lowpass, 'string')); + + if highpasscutoff>0 && highpasscutoff<0.2 + set(handles.edit_highpass, 'string','0.4') + set(handles.slider_highpass, 'Value', 0.4) + end + + set(handles.radiobutton_butter,'Value',0) + ordervector = 4:4:4096; + set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list + set(handles.popupmenu_dboct,'String', '---') % set db/oct list + set(handles.popupmenu_dbdec,'String', '---') % set db/dec list + set(handles.popupmenu_order,'Value',10) + set(handles.popupmenu_dboct,'Value',1) + set(handles.popupmenu_dbdec,'Value',1) + + handles.ishopermission = 0; + % Update handles structure + guidata(hObject, handles); + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end +else + set(handles.radiobutton_fir,'Value',1) +end + +%-------------------------------------------------------------------------- +function radiobutton_PM_notch_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + valhp = get(handles.edit_highpass,'String'); + vallp = get(handles.edit_lowpass,'String'); + handles.valhp = valhp; + handles.vallp = vallp; + + % Update handles structure + guidata(hObject, handles); + setnotchpm(handles) + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end +else + set(handles.radiobutton_PM_notch,'Value',1) +end + +%-------------------------------------------------------------------------- +function radiobutton_gaussian_Callback(hObject, eventdata, handles) + +%------------------------------------------------------------------------ +function setnotchpm(handles) + +freqdef = handles.freqdef; +set(handles.radiobutton_butter,'Value',0) +set(handles.radiobutton_fir,'Value',0) +set(handles.slider_highpass, 'Enable', 'on') +set(handles.slider_highpass, 'Value', freqdef); +set(handles.slider_lowpass, 'Value', freqdef); +set(handles.slider_lowpass, 'Visible', 'off') +set(handles.togglebutton_highpass, 'Value', 0) +set(handles.togglebutton_lowpass, 'Value', 0) +set(handles.togglebutton_lowpass, 'Visible', 'off') +set(handles.togglebutton_highpass, 'Visible', 'off') +set(handles.edit_highpass,'Enable','on') +set(handles.edit_highpass,'String',num2str(freqdef)) +set(handles.edit_lowpass,'Visible','off') +set(handles.edit_lowpass,'String',num2str(freqdef)) +set(handles.edit2_lowpass,'Visible','off') +set(handles.edit2_highpass,'Visible','off') +set(handles.checkbox_removedc, 'Enable', 'on'); +set(handles.text_hzlp,'Visible','off') +%set(handles.edit_highpass, 'BackgroundColor', [1 1 1]); +set(handles.popupmenu_order,'String', '180') % set db/oct list +set(handles.popupmenu_dbdec,'String', '---') % set db/dec list +set(handles.popupmenu_dboct,'String', '---') % set db/oct list +set(handles.popupmenu_order,'Value',1) +set(handles.popupmenu_dboct,'Value',1) +set(handles.popupmenu_dbdec,'Value',1) +set(handles.popupmenu_dboct,'Enable','off') +set(handles.popupmenu_dbdec,'Enable','off') +set(handles.text_halfpow,'Visible','off') +set(handles.text_halfamp,'Visible','off') +set(handles.text_cutoff_1,'Visible','off') +return + +%------------------------------------------------------------------------ +function unsetnotchpm(hObject, eventdata, handles) +if strcmp(get(handles.slider_lowpass,'Visible'),'off') + set(handles.togglebutton_highpass, 'Visible', 'on') + set(handles.togglebutton_highpass,'Value',1) + set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.checkbox_removedc, 'Enable', 'on'); + set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]); + vals = get(handles.slider_highpass, 'Value'); + set(handles.edit_highpass,'String',sprintf('%.1f',vals)); + set(handles.slider_lowpass, 'Visible', 'on') + set(handles.slider_lowpass, 'Value', 0) + set(handles.slider_lowpass, 'Enable', 'off') + set(handles.togglebutton_lowpass, 'Visible', 'on') + set(handles.togglebutton_lowpass,'Value',0) + set(handles.edit_lowpass,'String','0'); + set(handles.edit_lowpass,'Enable','off'); + %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]); + set(handles.text_hzlp,'Visible','on') +else + set(handles.togglebutton_highpass, 'Visible', 'on') + set(handles.togglebutton_lowpass, 'Visible', 'on') + %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]); + set(handles.text_hzlp,'Visible','on') +end + +set(handles.edit_lowpass,'Visible','on'); +set(handles.edit2_lowpass,'Visible','on'); +set(handles.edit2_highpass,'Visible','on'); +set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); +set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); +set(handles.text_halfpow,'Visible','on') +set(handles.text_halfamp,'Visible','on') +set(handles.text_cutoff_1,'Visible','on') + +%-------------------------------------------------------------------------- +function edit_boundary_Callback(hObject, eventdata, handles) + +% ------------------------------------------------------------------------- +function edit_boundary_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function a_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_xmaxplot_Callback(hObject, eventdata, handles) +xmaxpstr = strtrim(get(handles.edit_xmaxplot, 'String')); +xmaxp = str2num(xmaxpstr); + +if isempty(xmaxp) + msgboxText{1} = 'Your must enter a positive number greater than 0.1!'; + title = 'EStudio: Basic Filter Error'; + errorfound(msgboxText, title); + set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr)) + + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end + return +elseif length(xmaxp)==1 + if xmaxp<0.1 + msgboxText{1} = 'Your must enter a positive number greater than 0.1!'; + title = 'EStudio: Basic Filter Error'; + errorfound(msgboxText, title); + set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr)) + + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end + return + end + xmaxp = [0 xmaxp]; +elseif length(xmaxp)==2 + if xmaxp(1)>=xmaxp(2) + msgboxText{1} = 'Frenquency range must be sorted [minf maxf].'; + title = 'EStudio: Basic Filter Error'; + errorfound(msgboxText, title); + set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr)) + + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end + return + end + if xmaxp(1)<0 || xmaxp(2)<0 + msgboxText{1} = 'Your must enter 1 or 2 positive numbers.'; + title = 'EStudio: Basic Filter Error'; + errorfound(msgboxText, title); + set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr)) + + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end + return + end + if abs(xmaxp(2)-xmaxp(1))<0.1 + msgboxText{1} = 'Bandwidth for plotting must be greater than 0.1 Hz.'; + title = 'EStudio: Basic Filter Error'; + errorfound(msgboxText, title); + set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr)) + + if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); + elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); + else + plotresponsefilter(hObject, eventdata, handles); + end + return + end +else + msgboxText = 'Wrong frenquency range!'; + title = 'EStudio: Basic Filter Error'; + errorfound(msgboxText, title); + set(handles.edit_xmaxplot, 'String', num2str(handles.xmaxfreqr)) + return +end +if get(handles.radiobutton_impr,'Value') + handles.xmaxpimpz = xmaxp; +else + handles.xmaxfreqr = xmaxp; +end + +% Update handles structure +guidata(hObject, handles); + + +if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); +elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); +else + plotresponsefilter(hObject, eventdata, handles); +end +return + +%-------------------------------------------------------------------------- +function edit_xmaxplot_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function noncausal_Callback(hObject, eventdata, handles) +if ~get(hObject,'Value') + set(hObject,'Value',1) +end + +%-------------------------------------------------------------------------- +function causal_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_FRscale_Callback(hObject, eventdata, handles) +if get(handles.radiobutton_ufdatafr,'Value') + plotresponse_uf_data(hObject, eventdata, handles); +elseif get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles); +else + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function chksliders(hObject, eventdata, handles) +sH = get(handles.slider_highpass,'Value'); +sL = get(handles.slider_lowpass,'Value'); +if sH<0.001 + set(handles.slider_highpass,'Value', 0) + set(handles.edit_highpass,'String', '0') + set(handles.edit2_highpass,'String', '---') + set(handles.slider_highpass,'Enable', 'off') + set(handles.edit_highpass,'Enable', 'off') + set(handles.edit2_highpass,'Enable', 'off') + set(handles.togglebutton_highpass,'Value', 0) + set(handles.checkbox_removedc,'Value', 0) +else + set(handles.edit_highpass, 'String', sprintf('%.1f',sH)); + set(handles.edit2_highpass, 'BackgroundColor', [1 1 0.5]); +end +if sL<0.001 + set(handles.slider_lowpass,'Value', 0) + set(handles.edit_lowpass,'String', '0') + set(handles.edit2_lowpass,'String', '---') + set(handles.slider_lowpass,'Enable', 'off') + set(handles.edit_lowpass,'Enable', 'off') + set(handles.edit2_lowpass,'Enable', 'off') + set(handles.togglebutton_lowpass,'Value', 0) +else + set(handles.edit_lowpass, 'String', sprintf('%.1f',sL)); + set(handles.edit2_lowpass, 'BackgroundColor', [1 1 0.5]); +end +if sL<0.001 && sH<0.001 + set(handles.popupmenu_order,'Value', 2) +end +drawnow +return + +%-------------------------------------------------------------------------- +function pushbutton_refresh_Callback(hObject, eventdata, handles) +sHstr = sprintf('%.1f',get(handles.slider_highpass,'Value')); +sLstr = sprintf('%.1f',get(handles.slider_lowpass,'Value')); +set(handles.edit_lowpass,'String', sLstr) +set(handles.edit_highpass,'String', sHstr) +drawnow + +plotresponsefilter(hObject, eventdata, handles); + +%-------------------------------------------------------------------------- +function sliderson(hObject, eventdata, handles) +if get(handles.togglebutton_highpass,'value') + set(handles.slider_highpass,'Enable','on') +end + +if get(handles.togglebutton_lowpass,'value') + set(handles.slider_lowpass,'Enable','on') +end +drawnow + +%-------------------------------------------------------------------------- +function slidersoff(hObject, eventdata, handles) +if get(handles.togglebutton_highpass,'value') + set(handles.slider_highpass,'Enable','off') +end + +if get(handles.togglebutton_lowpass,'value') + set(handles.slider_lowpass,'Enable','off') +end +drawnow + +%-------------------------------------------------------------------------- +function uipanel8_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_tip_cutoff_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function [ym f ylim] = plotresponse_uf_data(hObject, eventdata, handles) + +[ym f ylim] = deal([]); +frecp = str2num(get(handles.edit_xmaxplot,'String')); + +if isempty(frecp) + return +end + +ch = str2num(get(handles.edit_channels,'String')); + +if isempty(ch) + return +end + +axes(handles.axes1); +posaxes1 = get(gca,'YLim'); +msgtx = 'Working, please wait...'; +text(mean(frecp)/3, posaxes1(2)/2, msgtx,'FontSize',14, 'color', 'k') +drawnow + +if isempty(setxor(ch, [handles.datafr.chan])) % are equal? + ym = handles.datafr.ym; + f = handles.datafr.f; +else + ERPLAB = handles.ERPLAB; + np = round(ERPLAB.srate/2); + + if iserpstruct(ERPLAB) % for erpset + % [ym f] = fourierp(ERPLAB,ch,frecp(1),np,np); + [ym f] = fourierp(ERPLAB,ch,[], 0,np,np); + elseif iseegstruct(ERPLAB) % for erpset + % [ym f] = fourieeg(ERPLAB,ch,frecp(1),np,np); + [ym f] = fourieeg(ERPLAB,ch,[],0,np,np); + else + return + end +end + +[frecpxx frecpsam2] = min(abs(f-frecp(2))); +[frecpxx frecpsam1] = min(abs(f-frecp(1))); + +FRscale = get(handles.popupmenu_FRscale, 'Value'); +color = [0 0.2 0]; + +if FRscale==1 + ymax = max(ym)+0.2; + ymin = -0.0625*ymax; %6.25% of ymax - + plot(f(frecpsam1:frecpsam2), ym(frecpsam1:frecpsam2), 'linewidth', 2, 'LineSmoothing','on','Color', color) + ylabel('Data amplitude') +else + ymax = 20*log(max(ym))+0.2; + ymin = -65; + plot(f(frecpsam1:frecpsam2), 20*log10(ym(frecpsam1:frecpsam2)), 'linewidth', 2, 'LineSmoothing','on','Color', color) + ylabel('Data amplitude in dB') +end + +ylim = [ymin ymax]; +xlabel('frequency (Hz)') +axis([frecp ymin ymax]) +hle = legend('Unfiltered data'); +set(hle, 'Color', 'none', 'Box', 'off') +drawnow +handles.datafr.chan = ch; +handles.datafr.ym = ym; +handles.datafr.f = f; + +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function plotresponse_fd_data(hObject, eventdata, handles) + +valueh = get(handles.slider_highpass, 'Value'); +valuel = get(handles.slider_lowpass, 'Value'); + +if valueh==0 && valuel==0 + msgtx = '--NO FILTERING--'; + no_filter(hObject, handles, msgtx) + return +end +frecp = str2num(get(handles.edit_xmaxplot,'String')); +if isempty(frecp) + return +end +ch = str2num(get(handles.edit_channels,'String')); +if isempty(ch) + return +end + +axes(handles.axes1); + +[ydata f ylim] = plotresponse_uf_data(hObject, eventdata, handles); +[yfilter labelf] = plotresponsefilter(hObject, eventdata, handles); +yfildata = ydata.*yfilter'; + +FRscale = get(handles.popupmenu_FRscale, 'Value'); +color = [0.2 0 0]; +ymin = ylim(1); +ymax = ylim(2); + +if FRscale==1 + %ymax = max(yfildata)+0.2; + %ymin = -0.075; + ymaxb = 1; + yminb = 0; + plot(f, yfildata, 'linewidth', 2, 'LineSmoothing','on','Color', color) + ylabel('Data amplitude') +else + %ymax = 20*log(ymax)+0.2; + %ymin = -65; + ymaxb = 0; + yminb = -90; + plot(f, 20*log10(yfildata), 'linewidth', 2, 'LineSmoothing','on','Color', color) + ylabel('Data amplitude in dB') +end +fnyq = round(handles.fs/2); +if get(handles.radiobutton_ideal, 'Value') + drawidealresp(handles, labelf, fnyq, valuel, valueh, yminb, ymaxb) +end + +% text(mean(frecp), posaxes1(2)/2, msgtx,'FontSize',14, 'color', 'w') % erase text...temporary... +xlabel('frequency (Hz)') +axis([frecp ymin ymax]) +hle = legend('Filtered data'); +set(hle, 'Color', 'none', 'Box', 'off') +drawnow + +%-------------------------------------------------------------------------- +function minboundarysamdist = boundarydistance(EVENTSTRUCT) + +% +% Minimum number of sample among boundaries +% +if isempty(EVENTSTRUCT) + minboundarysamdist = inf; + return +end +if ischar(EVENTSTRUCT(1).type) + ecpos = strmatch('boundary', {EVENTSTRUCT.type}); +else + ecpos = find([EVENTSTRUCT.type]==-99); +end +if isempty(ecpos) + minboundarysamdist = inf; +else + minboundarysamdist = min(diff([EVENTSTRUCT(ecpos).latency])); +end + +%-------------------------------------------------------------------------- +function setall(hObject, eventdata, handles, ERPLAB, def) + +if nargin<5 + def = handles.def; +end +if nargin<4 + ERPLAB = handles.ERPLAB; +end +if isempty(ERPLAB) + try + ERPLAB = handles.ERPLAB; + catch + ERPLAB = buildERPstruct([]); + end +end +fs = ERPLAB.srate; +if isempty(fs) + fs=1000; +end + +% def = {highpasscutoff, lowpasscutoff, order, channelArray, typefilter, remove_dc, boundary}; +% setall(hObject, eventdata, handles, [], def) + +locutoff = def{1}; % for high pass filter +hicutoff = def{2}; % for low pass filter +filterorder = def{3}; +chanArray = def{4}; +filterallch = def{5}; +typefilter = def{6}; +remove_dc = def{7}; +boundary = def{8}; +binArray = def{9}; +colorband = [0.9922 0.9176 0.7961]; + +if iserpstruct(ERPLAB) % for erpset + typedata = 'ERP'; + set(handles.checkbox_removedc, 'Visible', 'on') + set(handles.checkbox_removedc, 'Value', remove_dc) + set(handles.checkbox_removedc, 'String', 'Remove mean value (DC bias) before filtering (not usually appropriate for baseline-corrected data)') + %set(handles.checkbox_removedc, 'Enable', 'off') + set(handles.checkbox_boundary, 'Visible', 'off') + set(handles.edit_boundary,'Visible', 'off'); + set(handles.text_boundary,'Visible', 'off'); + minboundarysamdist = inf; + %nchan = ERPLAB.nchan; +else + if isempty(ERPLAB.epoch) % for continuous dataset + set(handles.checkbox_boundary, 'Enable', 'on') + + if isempty(boundary) + set(handles.checkbox_boundary, 'Value', 0) + set(handles.edit_boundary, 'string', 'boundary'); % default + set(handles.edit_boundary,'Enable', 'off'); + %set(handles.edit_boundary,'BackgroundColor', [0.75 0.75 0.75]); + else + set(handles.checkbox_boundary, 'Value', 1) + set(handles.edit_boundary,'Enable', 'on'); + %set(handles.edit_boundary,'BackgroundColor', [1 1 1]); + set(handles.edit_boundary, 'string', boundary); + end + + label1 = 'Apply filter to segments defined'; + label2 = 'by boundary events (Strongly Recommended)'; + set(handles.checkbox_boundary, 'string',[label1 '
' label2]); + set(handles.checkbox_removedc, 'Value', remove_dc) + typedata = 'continuous EEG'; + minboundarysamdist = boundarydistance(ERPLAB.event); + else % for epoched dataset + set(handles.checkbox_boundary, 'Value', 0) + set(handles.checkbox_boundary, 'Enable', 'off') + set(handles.edit_boundary, 'string', ''); + set(handles.edit_boundary,'Enable', 'off'); + %set(handles.edit_boundary,'BackgroundColor', [0.75 0.75 0.75]); + label1 = 'Apply filter to segments defined'; + label2 = 'by boundary events (Strongly Recommended)'; + set(handles.checkbox_boundary, 'string',[label1 '
' label2]); + set(handles.text_boundary,'Enable', 'off'); + set(handles.checkbox_removedc, 'String', 'Remove mean value (DC bias) before filtering (not usually appropriate for baseline-corrected data)') + set(handles.checkbox_removedc, 'Value', remove_dc) + %set(handles.checkbox_removedc, 'Enable', 'off') + typedata = 'epoched EEG'; + minboundarysamdist = inf; + end + %nchan = ERPLAB.nbchan; +end + +% +% Name & version +% +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio V.', version ' - ERP Filtering > Advanced' ]) +highpasscutoff = locutoff; +lowpasscutoff = hicutoff; +maxsliders = handles.maxsliders; +handles.minboundarysamdist = minboundarysamdist; +handles.memvaluel = lowpasscutoff; +handles.memvalueh = highpasscutoff; +handles.morder = filterorder; +handles.mvalueh = highpasscutoff; % memory value highpass + +slider_step(1) = 0.1/maxsliders; +slider_step(2) = 0.5/maxsliders; + +switch typefilter + case 'butter' + set(handles.radiobutton_butter, 'Value', 1); % 0 means Butterworth + ordervector = 2:2:8; + [tf, ordenp] = ismember_bc2(filterorder, ordervector); + set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list + set(handles.popupmenu_order,'Value', ordenp+1); + set(handles.popupmenu_dboct,'String', num2str(6*ordervector')) % set db/oct list + set(handles.popupmenu_dbdec,'String', num2str(20*ordervector')) % set db/dec list + set(handles.popupmenu_dboct,'Value', ordenp) % set db/oct list + set(handles.popupmenu_dbdec,'Value', ordenp) % set db/dec list + case 'fir' + set(handles.radiobutton_fir, 'Value', 1); % 1 means FIR + ordervector = 4:4:4096; + [tf, ordenp] = ismember_bc2(filterorder, ordervector); + set(handles.popupmenu_order,'String', char([{'automin'}; cellstr(num2str(ordervector'))])) % set order list + set(handles.popupmenu_order,'Value', ordenp+1); + set(handles.popupmenu_dboct,'String', '---') % set db/oct list + set(handles.popupmenu_dbdec,'String', '---') % set db/dec list + case 'notch' + set(handles.radiobutton_PM_notch, 'Value', 1); + setnotchpm(handles) + handles.freqdef = highpasscutoff; +end + +set(handles.slider_highpass, 'Value', highpasscutoff, 'Max', maxsliders, 'Min', 0, 'SliderStep', slider_step) +set(handles.slider_lowpass, 'Value', lowpasscutoff, 'Max', maxsliders, 'Min', 0, 'SliderStep', slider_step) +%set(handles.edit_channels,'String', vect2colon(chanArray, 'Delimiter','off', 'Repeat', 'off')) +% % % set(handles.popupmenu_channels,'String', listch) +set(handles.radiobutton_freqr,'Value', 1); +set(handles.radiobutton_impr,'Value', 0); +set(handles.radiobutton_ufdatafr,'Value', 0); +set(handles.radiobutton_fdatafr,'Value', 0); +set(handles.radiobutton_ideal, 'Enable','on') +nchan = handles.nchan; +% if filterallch +% % set(handles.checkbox_filterallchannels, 'Value', 1) +% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off')); +% set(handles.edit_channels, 'Enable', 'off'); +% set(handles.pushbutton_browsechan, 'Enable', 'off'); +% else +ERPLAB = handles.ERPLAB; +len1 = length(chanArray); +chanArray = chanArray(chanArray<=nchan); +% len2 = length(chanArray); +% if len1~=len2 +% fprintf('Index of channels to be filtered was adjusted since current %s has only %g channels.\n', typedata, nchan); +% end +[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, [],chanArray,2); +if chk(2) + chanArray = [1:ERPLAB.nchan]; + handles.indxlistch = chanArray; +end +% if len2==nchan +% set(handles.checkbox_filterallchannels, 'Value', 1) +if filterallch + set(handles.edit_channels, 'String','All'); +else +set(handles.edit_channels, 'String', vect2colon(chanArray, 'Delimiter', 'off')); +end +set(handles.edit_channels, 'Enable', 'off'); +set(handles.pushbutton_browsechan, 'Enable', 'off'); +% else +% chanArraystr = vect2colon(chanArray, 'Delimiter','off', 'Repeat', 'off'); +% set(handles.edit_channels, 'String', chanArraystr) +% end +% end + + +[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, binArray,[],1); +if chk(1) + binArray = [1:ERPLAB.nbin]; + handles.indxlistb = binArray; +end +if filterallch + set(handles.edit_bins,'String','All'); +else +set(handles.edit_bins,'String',vect2colon(binArray, 'Delimiter','off', 'Repeat', 'off')); +end +set(handles.edit_bins, 'Enable', 'off'); +set(handles.pushbutton_broswe_bin, 'Enable', 'off'); +% +% Causality (pending) +% +set(handles.noncausal,'Value',1); % only noncausal, for now. +set(handles.causal,'Value',0); +set(handles.causal,'Enable','off'); + +tooltip1 = 'Cutoff frequency = frequency where the magnitude
response of the filter is either 0.5 (-6dB) or 0.707 (-3dB)'; +tooltip2 = ['The filter does not attenuate all frequencies outside the desired frequency range completely;
'... + 'in particular, there is a region just outside the intended passband where frequencies are attenuated,
'... + 'but not rejected. This is known as the filter roll-off, and it is usually expressed in dB of attenuation
'... + 'per octave or decade of frequency. In general, the roll-off for an order-n filter is 6n dB per octave or
'... + '20n dB per decade.']; + +set(handles.edit_tip_cutoff, 'tooltip',tooltip1); +set(handles.edit_tip_rolloff, 'tooltip',tooltip2); + +if highpasscutoff== 0 + set(handles.togglebutton_highpass, 'Value',0); + set(handles.togglebutton_highpass, 'BackgroundColor', [0.8 0.8 0.75]); + set(handles.slider_highpass, 'Enable', 'off'); + set(handles.edit_highpass, 'String', '0'); + + set(handles.edit_highpass, 'Enable', 'off'); + %set(handles.edit_highpass, 'BackgroundColor', [0.75 0.75 0.75]); +else + set(handles.togglebutton_highpass, 'Value',1); + set(handles.togglebutton_highpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit_highpass, 'Enable', 'on'); + + set(handles.edit_highpass, 'String', sprintf('%.1f',highpasscutoff)); + %set(handles.edit_highpass, 'BackgroundColor', [1 1 1]); +end +if lowpasscutoff== 0 + set(handles.togglebutton_lowpass, 'Value',0); + set(handles.togglebutton_lowpass, 'BackgroundColor', [0.8 0.8 0.75]); + set(handles.slider_lowpass, 'Enable', 'off'); + set(handles.edit_lowpass, 'String', '0'); + set(handles.edit_lowpass, 'Enable', 'off'); + %set(handles.edit_lowpass, 'BackgroundColor', [0.75 0.75 0.75]); +else + set(handles.togglebutton_lowpass, 'Value',1); + set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]); + set(handles.edit_lowpass, 'Enable', 'on'); + + set(handles.edit_lowpass, 'String', sprintf('%.1f',lowpasscutoff)); + %set(handles.edit_lowpass, 'BackgroundColor', [1 1 1]); +end + +set(handles.radiobutton_gaussian,'Enable','off') +% set(handles.togglebutton_lowpass, 'Value',1); +% set(handles.togglebutton_lowpass, 'BackgroundColor', [1 1 0.5]); +set(handles.popupmenu_FRscale, 'String', {'Linear' 'Decibels'}); +set(handles.popupmenu_FRscale,'Value', 1); +set(handles.popupmenu_FRscale,'Enable', 'on'); +set(handles.edit_xmaxplot, 'String', num2str([0 fs])) +drawnow + +% Update handles structure +guidata(hObject, handles); +plotresponsefilter(hObject, eventdata, handles); + +%-------------------------------------------------------------------------- +% --- Executes on button press in radiobutton_ideal. +function radiobutton_ideal_Callback(hObject, eventdata, handles) +% +% Plot corresponding response +% +if get(handles.radiobutton_fdatafr,'Value') + plotresponse_fd_data(hObject, eventdata, handles) +elseif get(handles.radiobutton_freqr,'Value') || get(handles.radiobutton_impr,'Value') + plotresponsefilter(hObject, eventdata, handles); +end + +%-------------------------------------------------------------------------- +function pushbutton_import_settings_Callback(hObject, eventdata, handles) +[filename, pathname] = uigetfile({'*.bfil','Basic Filter seetings (*.bfil)'}, 'Load settings'); +if isequal(filename,0) + disp('User selected Cancel') + return +end +L = load(fullfile(pathname, filename), '-mat'); +readobjects = L.outstr; + +% outstr = {highpasscutoff, lowpasscutoff, order, channelArray, typefilter, remove_dc, boundary}; +highpasscutoff = readobjects{1}; +lowpasscutoff = readobjects{2}; +order = readobjects{3}; +channelArray = readobjects{4}; +filterallch = readobjects{5}; +typefilter = readobjects{6}; +remove_dc = readobjects{7}; +boundary = readobjects{8}; +def = {highpasscutoff, lowpasscutoff, order, channelArray, filterallch, typefilter, remove_dc, boundary}; +setall(hObject, eventdata, handles, [], def) + +%-------------------------------------------------------------------------- +function pushbutton_save_settings_Callback(hObject, eventdata, handles) + +% readobjects = {channelArray, highpasscutoff, lowpasscutoff, order, typefilter, remove_dc, boundarycheck, boundarystr}; + +% global readobjects +[readobjects v] = read_GUI(hObject, eventdata, handles); +if v~=1 % means something was going wrong + msgboxText = 'Setting is not ready to be saved. Please check it out.'; + title = 'EStudio: f_basicfilter GUI error:'; + errorfound(sprintf(msgboxText), title); + return +end + +channelArray = readobjects{1}; +filterallch = readobjects{2}; +if filterallch + nchan = handles.nchan; + channelArray = 1:nchan; +end +highpasscutoff = readobjects{3}; +lowpasscutoff = readobjects{4}; +order = readobjects{5}; +typefilter = readobjects{6}; +remove_dc = readobjects{7}; +boundarycheck = readobjects{8}; +boundarystr = readobjects{9}; + +if boundarycheck==1 + if strcmpi(boundarystr,'boundary')||strcmpi(boundarystr,'''boundary''') + boundary = 'boundary'; + else + if ~strcmp(boundarystr,'') + boundary = str2num(boundarystr); + if isempty(boundary); + boundary = boundarystr; + end + else + %boundary = []; + msgboxText = ['You have set the checkbox for filtering between boundary events.\n'... + 'So, you must define a boundary event code.']; + title = 'EStudio: f_basicfilter GUI error:'; + errorfound(sprintf(msgboxText), title); + return + end + end +else + boundary = []; +end + +% +% Save OUTPUT file +% +[filename, filepath, filterindex] = uiputfile({'*.bfil','Basic Filter settings (*.bfil)'},'Save filter settings as'); + +if isequal(filename,0) + disp('User selected Cancel') + return +else + outstr = {highpasscutoff, lowpasscutoff, order, channelArray, filterallch, typefilter, remove_dc, boundary}; + + [px, fname, ext] = fileparts(filename); + if strcmp(ext,'') + if filterindex==1 + ext = '.bfil'; + end + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + save(fullname, 'outstr'); + + % fid_list = fopen( fullname , 'w'); + % + % for i=1:size(fulltext,1) + % fprintf(fid_list,'%s\n', fulltext(i,:)); + % end + % + % fclose(fid_list); + % set(handles.button_savelist, 'Enable','on') +end + +%-------------------------------------------------------------------------- +function edit2_highpass_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit2_lowpass_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function togglebutton_lowpass_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function togglebutton_highpass_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + % The GUI is still in UIWAIT, us UIRESUME + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +function pushbutton_browsechan_Callback(hObject, eventdata, handles) + +listch = handles.listch; +indxlistch = handles.indxlistch; +indxlistch = indxlistch(indxlistch<=length(listch)); +titlename = 'Select Channel(s)'; + +if get(hObject, 'Value') + if ~isempty(listch) + ch = browsechanbinGUI(listch, indxlistch, titlename); + if ~isempty(ch) + set(handles.edit_channels, 'String', vect2colon(ch, 'Delimiter', 'off')); + handles.indxlistch = ch; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No channel information was found'; + title = 'EStudio: f_basicfilter GUI input'; + errorfound(msgboxText, title); + return + end +end + +% +% function checkbox_filterallchannels_Callback(hObject, eventdata, handles) +% if get(hObject, 'Value') +% nchan = handles.nchan; +% set(handles.edit_channels, 'String', vect2colon([1:nchan], 'Delimiter', 'off')); +% set(handles.edit_channels, 'Enable', 'off'); +% set(handles.pushbutton_browsechan, 'Enable', 'off'); +% else +% set(handles.edit_channels, 'Enable', 'on'); +% set(handles.pushbutton_browsechan, 'Enable', 'on'); +% end + + + +function edit_bins_Callback(hObject, eventdata, handles) +% nbin = handles.nbin; +binx = str2num(get(handles.edit_bins,'String')); +% tf = checkchannels(chx, nchan); + +ERPLAB = handles.ERPLAB; +[chk, msgboxText] = f_ERP_chckbinandchan(ERPLAB, binx,[],1); +if chk(2) + title = 'EStudio: f_basicfilterGUI2'; + errorfound(msgboxText, title); + return; +end +handles.indxlistb = binx; % bin array + + + +% --- Executes during object creation, after setting all properties. +function edit_bins_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton_broswe_bin. +function pushbutton_broswe_bin_Callback(hObject, eventdata, handles) +listch = handles.listb; +indxlistch = handles.indxlistb; +indxlistch = indxlistch(indxlistch<=length(listch)); +titlename = 'Select Bin(s)'; + +if get(hObject, 'Value') + if ~isempty(listch) + bin = browsechanbinGUI(listch, indxlistch, titlename); + if ~isempty(ch) + set(handles.edit_bins, 'String', vect2colon(bin, 'Delimiter', 'off')); + handles.indxlistb = bin; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No bin information was found'; + title = 'EStudio: f_basicfilter GUI input'; + errorfound(msgboxText, title); + return + end +end diff --git a/studio_functions/GUIs/ERP Tab/f_chan_testsyntaxtype.m b/studio_functions/GUIs/ERP Tab/f_chan_testsyntaxtype.m new file mode 100755 index 00000000..91e6ece5 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_chan_testsyntaxtype.m @@ -0,0 +1,92 @@ +function [val, formulaArray] = f_chan_testsyntaxtype(FormulaArrayIn, whocall) +val = 1; +formulaArray = FormulaArrayIn; + +if isempty(formulaArray) + return +else + formulaArray = strtrim(cellstr(formulaArray)); +end +nformulas = length(formulaArray); + +[expspliter parts] = regexp(formulaArray, '=','match','split'); +ask4fix = 1; +wantfix = 0; +newnumchan = 1; + +for t=1:nformulas + fcomm = formulaArray{t}; + tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013) + + if isempty(tokcommentb) % skip comment symbol + pleft = regexpi(parts{t}{1}, '(\s*nch[an]*\d+)', 'tokens'); + plcom = regexpi(parts{t}{1}, '(\s*ch[an]*\d+)', 'tokens'); + + if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For non recursive mode, left side of equation\nmust be define as a new channel.\n'... + 'For instance, nchan1 = ...\n\n'... + 'Do you want that EStudio corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for non recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix = 1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + elseif ~isempty(pleft) && strcmpi(whocall,'recu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For recursive mode, left side of equation cannot\nbe define as a new channel.\n'... + 'For instance, you must write chan1 = ...\n\n'... + 'Do you want that EStudio corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix =1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + %else + % wantfix = 0; + end + if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC + fprintf('WARNING: equation %s ', formulaArray{t}) + if strcmpi(whocall,'recu') % for recursive mode delete the n in nch + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2})); + else + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*ch(\D*)(\d*)',['nch$1' num2str(newnumchan)],'ignorecase')), strtrim(parts{t}{2})); + newnumchan = newnumchan+1; + end + fprintf('was changed to equation %s \n', formulaArray{t}) + end + end +end +% if val==1 +% set(handles.editor,'String', char(formulaArray)); +% end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_chanoperGUI.fig b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.fig new file mode 100755 index 00000000..f3ea7ae0 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_chanoperGUI.m b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.m new file mode 100755 index 00000000..20cec6c7 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_chanoperGUI.m @@ -0,0 +1,1021 @@ + +% Begin initialization code - DO NOT EDIT +function varargout = f_chanoperGUI(varargin) +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_chanoperGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_chanoperGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_chanoperGUI_OpeningFcn(hObject, eventdata, handles, varargin) + +handles.output = []; +example{1} = 'ch@ = ch6 - ch5 label HEOG'; +example{2} = 'chan@ = ch6 - ch5 label = HEOG'; +example{3} = 'ch@ = 0.5*chan7 + 0.5*chan9 label LINKM'; +example{4} = 'ch@ = mahaleeg(ch1,ch2) label MAHAL01'; +example{5} = 'CH@ = mahaleeg(ch40) label SELFMAHAL'; +example{6} = 'ch@ = (ch11+ch12+ch13)/3 label = ROI temporal'; +example{7} = 'CHAN@ = (ch11 + ch12 + ch13)/3 label ROI temporal'; +example{8} = 'ch@ = abs(ch110) label E110 rectified '; + + +try + ERPLAB = varargin{1}; + + if iserpstruct(ERPLAB) + nchan = ERPLAB.nchan; % Total number of channels + typedata = 'ERP'; + datastr = 'ERPset'; + formtype = 'erpchanformulas'; + example{5} = 'ch@ = mgfperp(ERP) label MGFPower'; + else + example{3} = 'ch@ = chinterpol'; + nchan = ERPLAB.nbchan; % Total number of channels + typedata = 'EEG'; + datastr = 'dataset'; + formtype = 'eegchanformulas'; + end +catch + ERPLAB.chanlocs = []; + listch = ''; + nchan = 1; + formtype = []; + typedata = 'unspecific data'; + datastr = 'who-knows-what'; +end +try + def = varargin{2}; + formulas = def{1}; + wchmsgon = def{2}; +catch + formulas = []; + wchmsgon = 1; +end + +handles.nchan = nchan; +% handles.listname = []; +handles.example = example; +handles.exacounter = 0; +handles.typedata = typedata; +handles.formtype = formtype; + +% +% Name & version +% +version = geterplabstudioversion; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Channel Operation GUI for ' typedata]) + +% formulas = erpworkingmemory(formtype); + +if isempty(formulas) + set(handles.editor,'String',''); +else + set(handles.editor, 'String', formulas) +end + +% For undo & redo +% handles.formulas{1} = get(handles.editor, 'String'); +% handles.undocount = 1; +% set(handles.pushbutton_undo,'Enable','off') +% set(handles.pushbutton_redo,'Enable','off') + +% +% Prepare List of current Channels +% +listch=[]; +if isempty(ERPLAB.chanlocs) + for e=1:nchan + ERPLAB.chanlocs(e).labels = ['Ch' num2str(e)]; + end +end +listch = cell(1,nchan); +for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERPLAB.chanlocs(ch).labels ]; +end + +set(handles.listboxchan1,'String', listch) +label1 = 'Send file rather than individual equations'; +label2 = '(creates compact history)'; +set(handles.checkbox_sendfile2history, 'string',[label1 '
' label2]) +handles.listch = listch; + +% +% Mode buttons +% +set(handles.button_recursive, 'String', sprintf('Modify existing %s (recursive updating)', datastr)); +set(handles.button_no_recu, 'String', sprintf('Create new %s (independent transformations)',datastr)); + +% +% Gui memory +% +chanopGUI = erpworkingmemory('chanopGUI'); + +if isempty(chanopGUI) + set(handles.button_recursive,'Value', 1); % default is Modify existing ERPset (recursive updating) + set(handles.button_savelist, 'Enable','off') + set(handles.chkeeplocs,'Value', 1) %default is Preserve Channel locations + + % + % File List + % + set(handles.edit_filelist,'String',''); + set(handles.checkbox_sendfile2history,'Value',0) + handles.listname = []; +else + if chanopGUI.emode==0 + set(handles.button_recursive,'Value', 1); + set(handles.button_no_recu,'Value', 0); + else + set(handles.button_recursive,'Value', 0); + set(handles.button_no_recu,'Value', 1); + end + if chanopGUI.hmode==0 + set(handles.checkbox_sendfile2history,'Value', 0); + else + set(handles.checkbox_sendfile2history,'Value', 1); + end + if chanopGUI.keeplocs ==1 + set(handles.chkeeplocs,'Value',1); + else + set(handles.chkeeplocs,'Value',0); + end + listname = chanopGUI.listname; + set(handles.edit_filelist,'String', listname ); + handles.listname = listname; % JLC Sept 1, 2012 +end + +% wchmsgon = erpworkingmemory('wchmsgon'); + +if isempty(wchmsgon) || wchmsgon==0 + set(handles.chwarning,'Value', 0) +elseif wchmsgon==1 + set(handles.chwarning,'Value', 1) +else + error('Oops...checkbox_warning memory failed') +end + +handles.locs = ERPLAB.chanlocs; + +% +% Color GUI +% +handles = painterplabstudio(handles); + +% +% Set font size +% +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +helpbutton + +drawnow +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_chanoperGUI_OutputFcn(hObject, eventdata, handles) +% Get default command line output from handles structure + +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +%-------------------------------------------------------------------------- +function editor_Callback(hObject, eventdata, handles) + +set(handles.edit_filelist, 'String',''); +compacteditor(hObject, eventdata, handles); + +% handles = editorbackup(hObject, eventdata, handles); +% formulas = get(handles.editor, 'String'); +% undocount = handles.undocount; +% undocount = undocount + 1; +% handles.formulas{undocount} = formulas; +% handles.undocount = undocount; + +handles.listname = []; + +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function editor_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_help_Callback(hObject, eventdata, handles) +% doc pop_eegchanoperator +web https://github.com/lucklab/erplab/wiki/EEG-and-ERP-Channel-Operations -browser + +%-------------------------------------------------------------------------- +function pushbutton_RUN_Callback(hObject, eventdata, handles) +listname = handles.listname; +compacteditor(hObject, eventdata, handles); +formulalist = get(handles.editor,'String'); +wchmsgon = get(handles.chwarning,'Value'); +keeplocs = get(handles.chkeeplocs,'Value'); + + +if strcmp(formulalist,'') + msgboxText = 'You have not written any formula!'; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(msgboxText, title); + return +end +if size(formulalist,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end + +% +% Check formulas +% +if get(handles.button_recursive,'Value') + editormode = 0; +else + editormode = 1; +end + +typedata = lower(handles.typedata); +[option, recall, goeson] = checkformulas(cellstr(formulalist), [typedata 'chanoperGUI'], editormode); + +if goeson==0 + return +end +if isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1 + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['Equations at editor window have not been saved yet.\n\n'... + 'What would you like to do?']; + title = 'WARNING: Save List of edited chans'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Save and run','Run without saving', 'Cancel','Run without saving'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Save and run') + fullname = savelist(hObject, eventdata, handles); + listname = fullname; + handles.output = {listname, wchmsgon}; % sent filenam string) + elseif strcmpi(button,'Run without saving') + handles.output = {cellstr(formulalist), wchmsgon}; % sent like a cell string (with formulas) + elseif strcmpi(button,'Cancel') || strcmpi(button,'') + handles.output = []; + handles.listname = []; + % Update handles structure + guidata(hObject, handles); + return + end +elseif isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 + handles.output = {cellstr(formulalist), wchmsgon}; % sent like a cell string (with formulas) + +elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==1 + handles.output = {listname, wchmsgon}; % sent filename string + +elseif ~isempty(listname) && get(handles.checkbox_sendfile2history,'Value')==0 + handles.output = {cellstr(formulalist), wchmsgon}; % sent like a cell string (with formulas) +end + +% handles.output +% formtype = handles.formtype; +% erpworkingmemory(formtype, formulalist); + +% +% memory for Gui +% +chanopGUI.emode = editormode; +chanopGUI.hmode = get(handles.checkbox_sendfile2history,'Value'); +chanopGUI.listname = listname; +chanopGUI.keeplocs = keeplocs; +chanopGUI.chanlocs = handles.locs; +disp(chanopGUI.chanlocs) +erpworkingmemory('chanopGUI', chanopGUI); + +try + handles.output{3} = keeplocs; +catch + disp('Problem setting location preference') +end + + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function cancel_Callback(hObject, eventdata, handles) + +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function eraser_Callback(hObject, eventdata, handles) +% % +% % for undo +% % +% formulas = get(handles.editor, 'String'); +% undocount = handles.undocount; +% handles.formulas{undocount} = formulas; +% undocount = undocount + 1; +% handles.undocount = undocount; +formulas = get(handles.editor, 'String'); +if isempty(formulas) + return +end + +% handles = editorbackup(hObject, eventdata, handles); +set(handles.editor, 'String','') +handles.output = []; +disp('Formulas were erased.') +set(handles.button_savelist, 'Enable','off') +handles.listname = []; +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function help_Callback(hObject, eventdata, handles) + +fprintf('\n\n\n\n\n') +help pop_chanoperator + +%-------------------------------------------------------------------------- +function button_saveaslist_Callback(hObject, eventdata, handles) + +compacteditor(hObject, eventdata, handles); +fulltext = strtrim(get(handles.editor,'String')); + +if size(fulltext,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end +if ~strcmp(fulltext,'') + fullname = savelist(hObject, eventdata, handles); + if isempty(fullname) + return + end + set(handles.edit_filelist, 'String', fullname ) + set(handles.button_savelist, 'Enable', 'on') + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); +else + set(handles.button_saveaslist,'Enable','off') + msgboxText = 'You have not written any formula yet!'; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_saveaslist,'Enable','on') + return +end + +%-------------------------------------------------------------------------- +function button_loadlist_Callback(hObject, eventdata, handles) +[filename, filepath] = uigetfile({'*.txt';'*.*'},'Select a formulas-file'); + +if isequal(filename,0) + disp('User selected Cancel') + return +else + fullname = fullfile(filepath, filename); + disp(['pop_chanoperation(): For formulas-file, user selected ', fullname]) +end + +set(handles.edit_filelist,'String',fullname); +fid_formula = fopen( fullname ); + +try + formcell = textscan(fid_formula, '%s','delimiter', '\r'); + formulas = char(formcell{:}); +catch + serr = lasterror; + msgboxText = ['Please, check your file: \n'; + fullname '\n'... + serr.message]; + title = 'ERPLAB: pop_chanoperation() error:'; + errorfound(sprintf(msgboxText), title); + return +end +if size(formulas,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end + +compacteditor(hObject, eventdata, handles); +set(handles.editor,'String',formulas); +fclose(fid_formula); +set(handles.button_savelist, 'Enable','on') +handles.listname = fullname; + +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function listboxchan1_Callback(hObject, eventdata, handles) + +numchan = get(hObject, 'Value'); +if isempty(numchan) + return +end + +linet = get(handles.editor, 'Value'); + +if nnz(linet) == 0 + linet = 1; +end + +formulas = cellstr(get(handles.editor, 'String')); +formulas{linet} = [formulas{linet} 'ch' num2str(numchan)]; +set(handles.editor, 'String', char(formulas)); + +%-------------------------------------------------------------------------- +function listboxchan1_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function button_example_Callback(hObject, eventdata, handles) + +% % +% % for undo +% % +% formulas = get(handles.editor, 'String'); +% undocount = handles.undocount; +% handles.formulas{undocount} = formulas; +% undocount = undocount + 1; +% handles.undocount = undocount; + +nchan = handles.nchan; +example = handles.example; +exacounter = handles.exacounter; +exacounter = exacounter + 1; +text = cellstr(get(handles.editor, 'String')); + +if get(handles.button_no_recu,'Value') + prechar = 'n'; +else + prechar = ''; +end +if isempty([text{:}]) || exacounter>length(example) + exacounter = 1; +end +if length(text)==1 && strcmp(text{1}, '') + exacurr = char(regexprep(example{exacounter},'@',num2str(nchan+exacounter))); + text{1} = [prechar exacurr]; +else + exacurr = char(regexprep(example{exacounter},'@',num2str(nchan+exacounter))); + text{end+1} = [prechar exacurr]; +end + +set(handles.editor, 'String', char(text)); +% handles = editorbackup(hObject, eventdata, handles); +handles.exacounter = exacounter; +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function fullname = savelist(hObject, eventdata, handles) +fulltext = char(get(handles.editor,'String')); + +if isempty(fulltext) + return +end + +fullnamepre = get(handles.edit_filelist,'String'); + +% +% Save OUTPUT file +% +[filename, filepath, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},'Save formulas-file as', fullnamepre); + +if isequal(filename,0) + disp('User selected Cancel') + fullname = []; + return +else + [px, fname, ext] = fileparts(filename); + + if strcmp(ext,'') + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; + end + end + + fname = [ fname ext]; + fullname = fullfile(filepath, fname); + + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); + set(handles.button_savelist, 'Enable','on') +end + +%-------------------------------------------------------------------------- +function compacteditor(hObject, eventdata, handles) +texteditor = strtrim(get(handles.editor,'String')); + +if isempty(texteditor) + return +end + +formul = cellstr(texteditor); +nfl = length(formul); +k = 1; +formulalist = cell(1); + +% removes blank lines +for i=1:nfl + if ~strcmp(formul{i},'') + % removes blank lines + formulalist{k} = regexprep(formul{i},'[^\s](label)[^\s]',' $1 ', 'ignorecase'); + k = k+1; + end +end + +formulalist = strtrimx(formulalist); % special white space removing +set(handles.editor,'String', char(formulalist)); +drawnow + +%-------------------------------------------------------------------------- +function check_aoperations(hObject, eventdata, handles) +texteditor = strtrim(get(handles.editor,'String')); +if isempty(texteditor) + return +end + +formul = cellstr(texteditor); +nfl = length(formul); +k = 1; +formulalist = cell(1); + +for i=1:nfl + if ~strcmp(formul{i},'') + formulalist{k} = formul{i}; + k = k+1; + end +end + +formulalist = strtrimx(formulalist); +set(handles.editor,'String', char(formulalist)); + +%-------------------------------------------------------------------------- +function button_savelist_Callback(hObject, eventdata, handles) +compacteditor(hObject, eventdata, handles); +fulltext = strtrim(get(handles.editor,'String')); + +if size(fulltext,2)>256 + msgboxText = ['Formulas length exceed 256 characters.\n\n'... + 'Be sure to press [Enter] after you have entered each formula.']; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(sprintf(msgboxText), title); + return +end +if ~isempty(fulltext) + + fullname = get(handles.edit_filelist, 'String'); + + if ~strcmp(fullname,'') + fid_list = fopen( fullname , 'w'); + + for i=1:size(fulltext,1) + fprintf(fid_list,'%s\n', fulltext(i,:)); + end + + fclose(fid_list); + handles.listname = fullname; + % Update handles structure + guidata(hObject, handles); + disp(['Saving equation list at ' fullname '']) + else + button_saveaslist_Callback(hObject, eventdata, handles) + return + end +else + set(handles.button_saveaslist,'Enable','off') + msgboxText = 'You have not written any formula yet!'; + title = 'ERPLAB: chanoperGUI few inputs'; + errorfound(msgboxText, title); + set(handles.button_saveaslist,'Enable','on') + return +end + +%-------------------------------------------------------------------------- +function checkbox_sendfile2history_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_filelist_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_filelist_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function button_clearfile_Callback(hObject, eventdata, handles) +set(handles.edit_filelist,'String',''); +set(handles.button_savelist, 'Enable', 'off') + +%-------------------------------------------------------------------------- +function button_recursive_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.button_no_recu,'Value',0) + val = testsyntaxtype(hObject, eventdata, handles, 'recu'); + + if val==0; + set(handles.button_recursive, 'Value', 0) + set(handles.button_no_recu, 'Value', 1) + end + + %%% handles = editorbackup(hObject, eventdata, handles); + %%% Update handles structure + %%guidata(hObject, handles); +else + set(hObject,'Value',1) +end + +%-------------------------------------------------------------------------- +function button_no_recu_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.button_recursive,'Value',0) + val = testsyntaxtype(hObject, eventdata, handles, 'norecu'); + if val==0 + set(handles.button_recursive, 'Value', 1) + set(handles.button_no_recu, 'Value', 0) + end + %%% handles = editorbackup(hObject, eventdata, handles); + %%% Update handles structure + %%%guidata(hObject, handles); +else + set(hObject,'Value',1) +end + +%-------------------------------------------------------------------------- +function val = testsyntaxtype(hObject, eventdata, handles, whocall) +val = 1; +formulaArray = get(handles.editor,'String'); + +if isempty(formulaArray) + return +else + formulaArray = strtrim(cellstr(formulaArray)); +end +nformulas = length(formulaArray); + +[expspliter parts] = regexp(formulaArray, '=','match','split'); +ask4fix = 1; +wantfix = 0; +newnumchan = 1; + +for t=1:nformulas + fcomm = formulaArray{t}; + tokcommentb = regexpi(fcomm, '^#', 'match'); % comment symbol (June 3, 2013) + + if isempty(tokcommentb) % skip comment symbol + pleft = regexpi(parts{t}{1}, '(\s*nch[an]*\d+)', 'tokens'); + plcom = regexpi(parts{t}{1}, '(\s*ch[an]*\d+)', 'tokens'); + + if isempty(pleft) && ~isempty(plcom) && strcmpi(whocall,'norecu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For non recursive mode, left side of equation\nmust be define as a new channel.\n'... + 'For instance, nchan1 = ...\n\n'... + 'Do you want that ERPLAB corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for non recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix = 1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + elseif ~isempty(pleft) && strcmpi(whocall,'recu') + if ask4fix + BackERPLABcolor = [1 0.9 0.3]; % yellow + question = ['For recursive mode, left side of equation cannot\nbe define as a new channel.\n'... + 'For instance, you must write chan1 = ...\n\n'... + 'Do you want that ERPLAB corrects the syntax for you?']; + title = 'WARNING: Syntax is not proper for recursive mode'; + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question), title,'Cancel','No', 'Yes','Yes'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) + + if strcmpi(button,'Yes') + ask4fix = 0; + wantfix =1; + elseif strcmpi(button,'Cancel') + val = 0; % cancel + break + else + ask4fix = 0; + wantfix = 0; + end + %else + % wantfix =1; + end + %else + % wantfix = 0; + end + if wantfix && (~isempty(pleft) || ~isempty(plcom))% fixed (June 3, 2013): JLC + fprintf('WARNING: equation %s ', formulaArray{t}) + if strcmpi(whocall,'recu') % for recursive mode delete the n in nch + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*','','ignorecase')), strtrim(parts{t}{2})); + else + formulaArray{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '^n*ch(\D*)(\d*)',['nch$1' num2str(newnumchan)],'ignorecase')), strtrim(parts{t}{2})); + newnumchan = newnumchan+1; + end + fprintf('was changed to equation %s \n', formulaArray{t}) + end + end +end +if val==1 + set(handles.editor,'String', char(formulaArray)); +end + +%-------------------------------------------------------------------------- +function chwarning_Callback(hObject, eventdata, handles) +% +% if get(hObject,'Value') +% % +% % Gui memory +% % +% erpworkingmemory('wchmsgon', 1); +% else +% % +% % Gui memory +% % +% erpworkingmemory('wchmsgon', 0); +% end + +%-------------------------------------------------------------------------- +function pushbutton_export_chan_list_Callback(hObject, eventdata, handles) +list_of_chans = get(handles.listboxchan1,'String'); +nloch = length(list_of_chans); + +for i=1:nloch + fprintf('%s\n',list_of_chans{i}); +end + +fprintf('\n\nEnd of list.\n\n') + +%-------------------------------------------------------------------------- +function pushbutton_removechan_Callback(hObject, eventdata, handles) +typedata = handles.typedata; +chan2del = deletechanGUI(typedata); +nchan = handles.nchan; +keeplocs = get(handles.chkeeplocs,'Value'); + +if ~isempty(chan2del) + chan2del = unique_bc2(cell2mat(chan2del)); + if max(chan2del)>nchan && nnz(isinf(chan2del))==0 + msgboxText = 'You are specifying non-existing channels!'; + title = 'ERPLAB: chanoperGUI remove channels'; + errorfound(sprintf(msgboxText), title); + return + end + if min(chan2del)<1 && nnz(isinf(chan2del))==0 + msgboxText = 'You are specifying freaky non-existing channels!'; + title = 'ERPLAB: chanoperGUI remove channels'; + errorfound(sprintf(msgboxText), title); + return + end + if nnz(isnan(chan2del))>0 || nnz(isinf(chan2del))>0 + msgboxText = ['Channel problem\n'... + 'You are specifying freaky non-existing channels!']; + title = 'ERPLAB: chanoperGUI remove channels'; + errorfound(sprintf(msgboxText), title); + return + end + if strcmpi(typedata, 'EEG') + eqtn = sprintf('deletechan(%s)', vect2colon(chan2del, 'Delimiter','off')); + else + eqtn = sprintf('delerpchan(%s)', vect2colon(chan2del, 'Delimiter','off')); + end + + wchmsgon = get(handles.chwarning,'Value'); + handles.output = {{eqtn}, wchmsgon}; % sent like a cell string (with formulas) + try + handles.output{3} = keeplocs; + catch + disp('Problem setting location preference') + end + % Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + return +end + +%-------------------------------------------------------------------------- +function pushbutton_rerefwizard_Callback(hObject, eventdata, handles) +% set to non-recursive mode +set(handles.button_recursive, 'Value', 0) +set(handles.button_no_recu, 'Value', 1) + +% open reference wizard +formulalist = rerefassistantGUI(handles.nchan, handles.listch); +if isempty(formulalist) + return +end + +compacteditor(hObject, eventdata, handles); +formulas = get(handles.editor, 'String'); + +if get(handles.button_no_recu,'Value') + formulalist = cellstr([formulalist{:}]); + for t=1:length(formulalist) + [expspliter parts] = regexp(formulalist, '=','match','split'); + formulalist{t} = sprintf('%s = %s', strtrim(regexprep(parts{t}{1}, '[^n]*ch','nch','ignorecase')), strtrim(parts{t}{2})); + end + formulalist = char(formulalist); +end + +if isempty(formulas) + set(handles.editor,'String',formulalist); +else + formulalist = cellstr(formulalist); + formulas = cellstr(formulas); + formt = [formulas ;formulalist]; + formt = char(formt); + set(handles.editor,'String',formt); +end + +% %-------------------------------------------------------------------------- +% function pushbutton_undo_Callback(hObject, eventdata, handles) +% +% undocount = handles.undocount; +% if undocount>1 +% undocount = undocount - 1; +% formulas = handles.formulas{undocount}; +% handles.undocount = undocount; +% set(handles.editor, 'String',char(formulas)); +% set(handles.pushbutton_redo,'Enable','on') +% +% % formulas = get(handles.edit_filelist, 'String'); +% % Update handles structure +% guidata(hObject, handles); +% end +% if undocount==1 +% set(handles.pushbutton_undo,'Enable','off') +% set(handles.pushbutton_redo,'Enable','on') +% end + +%-------------------------------------------------------------------------- +% function pushbutton_redo_Callback(hObject, eventdata, handles) +% +% nformu = length(handles.formulas); +% undocount = handles.undocount; +% if undocount. + +function varargout = f_erp2ascGUI(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_erp2ascGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_erp2ascGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_erp2ascGUI_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for f_erp2ascGUI +handles.output = []; +try + ERP = varargin{1}; +catch + ERP.erpname = 'No erp was imported'; + ERP.filename = 'No erp was imported'; + ERP.nbin =1; + ERP.nchan = 1; + ERP.chanlocs(1).labels = 'None'; + ERP.bindescr{1} = 'None'; + ERP.bindata = zeros(1,10,1); +end + +try + binArray = varargin{2}; + chanArray = varargin{3}; +catch + binArray = 1; + chanArray = 1; +end + +% +% Name & version +% +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', strcat('EStudio',version,' - Save "',ERP.erpname, '" as ERPSS')) +[pathx, erpfilename, ext] = fileparts(ERP.filename); +ERPFileName = char(strcat(erpfilename,'.txt')); + +set(handles.edit_saveas, 'String',fullfile(pathx,ERPFileName) ); + + +%%----------------------Setting for bin and channels----------------------- +listb = {''}; +nbin = ERP.nbin; % Total number of bins +try + for b=1:nbin + listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; + end +catch + listb = ''; +end +handles.listb = listb; +handles.indxlistb = binArray; + +nchan = ERP.nchan; % Total number of channels +if ~isfield(ERP.chanlocs,'labels') + for e=1:nchan + ERP.chanlocs(e).labels = ['Ch' num2str(e)]; + end +end +listch = {''}; +try + for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ]; + end +catch + listch = ''; +end +handles.listch = listch; +handles.indxlistch = chanArray; + +set(handles.edit3_custom_bin,'String', vect2colon(binArray, 'Delimiter', 'off')); +set(handles.edit_custom_chan,'String', vect2colon(chanArray, 'Delimiter', 'off')); +handles.ERP = ERP; + + +% helpbutton + +% +% Color GUI +% +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +% helpbutton + +% UIWAIT makes f_erp2ascGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_erp2ascGUI_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); + + +function edit3_custom_bin_Callback(hObject, eventdata, handles) + +BinString = str2num(handles.edit3_custom_bin.String); +ERP = handles.ERP; +% [chk, msgboxText] = chckbinandchan(ERP, BinString, []); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1); + +if chk(1) + title = 'EStudio: f_export2text GUI for bin input!'; + errorfound(msgboxText, title); + return; +end +% --- Executes during object creation, after setting all properties. +function edit3_custom_bin_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton7_browse_bin. +function pushbutton7_browse_bin_Callback(hObject, eventdata, handles) +listb = handles.listb; +indxlistb = handles.indxlistb; +indxlistb = indxlistb(indxlistb<=length(listb)); +titlename = 'Select Bin(s)'; + +if get(hObject, 'Value') + %set(handles.pushbutton_browsechan, 'Enable', 'off') + if ~isempty(listb) + bin = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(bin) + set(handles.edit3_custom_bin, 'String', vect2colon(bin, 'Delimiter', 'off')); + handles.indxlistb = bin; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No bin information was found'; + title = 'EStudio: f_export2text GUI for bin input'; + errorfound(msgboxText, title); + return + end + +end + + +function edit_custom_chan_Callback(hObject, eventdata, handles) +chanString = str2num(handles.edit_custom_chan.String); +ERP = handles.ERP; + +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],chanString, 2); + +if chk(2) + title = 'EStudio: f_export2text GUI for channel input!'; + errorfound(msgboxText, title); + return; +end + + +% --- Executes during object creation, after setting all properties. +function edit_custom_chan_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton8_browse_chan. +function pushbutton8_browse_chan_Callback(hObject, eventdata, handles) + +listch = handles.listch; +indxlistch = handles.indxlistch; +indxlistch = indxlistch(indxlistch<=length(listch)); +titlename = 'Select Channel(s)'; + +if get(hObject, 'Value') + if ~isempty(listch) + ch = browsechanbinGUI(listch, indxlistch, titlename); + if ~isempty(ch) + set(handles.edit_custom_chan, 'String', vect2colon(ch, 'Delimiter', 'off')); + handles.indxlistch = ch; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No channel information was found'; + title = 'EStudio: f_export2text GUI for channel input'; + errorfound(msgboxText, title); + return + end +end + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +disp('User selected cancel'); +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +% function pushbutton_help_Callback(hObject, eventdata, handles) +% % doc pop_export2text +% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser +%-------------------------------------------------------------------------- +function pushbutton_export_Callback(hObject, eventdata, handles) + +filename = get(handles.edit_saveas, 'string'); +% bins = str2num(get(handles.edit_bins, 'string')); + +if isempty(filename) + msgboxText = 'You must enter a filename!'; + title = 'EStudio: f_erp2asc GUI empty filename'; + errorfound(msgboxText, title); + return +end + + +BinArray = str2num(handles.edit3_custom_bin.String); +ERP = handles.ERP; +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1); + +if chk(1) + title = 'EStudio: f_erp2asc GUI for bin input!'; + errorfound(msgboxText, title); + return; +end + + +ChanArray = str2num(handles.edit_custom_chan.String); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],ChanArray, 2); + +if chk(2) + title = 'EStudio: f_erp2asc GUI for channel input!'; + errorfound(msgboxText, title); + return; +end + +ERP.bindata = ERP.bindata(ChanArray,:,BinArray); +ERP.nbin = numel(BinArray); +ERP.nchan = numel(ChanArray); +ERP.chanlocs = ERP.chanlocs(ChanArray); +for Numofbin = 1:numel(BinArray) + ERP.bindescr{Numofbin} = ERP.bindescr{BinArray(Numofbin)}; +end + +answer = {ERP,filename}; +handles.output = answer; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +% ------------------------------------------------------------------------- +function edit_saveas_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_saveas_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_browse_Callback(hObject, eventdata, handles) + +% +% Save OUTPUT file +% +ERP = handles.ERP; +prename = get(handles.edit_saveas,'String'); +[fname, pathname, filterindex] = uiputfile({'*.txt';'*.*'},['Save "',ERP.erpname,'"as'], prename); + +if isequal(fname,0) + disp('User selected Cancel') + return +else + + [px, fname2, ext] = fileparts(fname); + + if strcmp(ext,'') + + if filterindex==1 || filterindex==2 + ext = '.txt'; + else + ext = '.txt'; + end + + fname = [ fname2 ext]; + end + + set(handles.edit_saveas,'String', fullfile(pathname, fname)); +% disp(['To save ERP, user selected ', fullfile(pathname, fname)]) +end + + + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + handles.output = []; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_erp_dataquality_SME_GUI.m b/studio_functions/GUIs/ERP Tab/f_erp_dataquality_SME_GUI.m new file mode 100755 index 00000000..d755cf36 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_erp_dataquality_SME_GUI.m @@ -0,0 +1,342 @@ + +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + + + + +function varargout = f_erp_dataquality_SME_GUI(varargin) + +global observe_ERPDAT; +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +if nargin < 1 + beep; + help f_erp_dataquality_SME_GUI; + return; +end + + +try + ERP = evalin('base','ERP'); +catch + beep; + disp('f_erp_dataquality_SME_GUI: No ERP was found in workspace'); + return; +end + +if isempty(ERP) + msgboxText = 'No ERPset was found!'; + title_msg = 'ERPLAB: f_erp_dataquality_SME_GUI() error:'; + errorfound(msgboxText, title_msg); + return +end +if ~isfield(ERP, 'bindata') + msgboxText = 'f_erp_dataquality_SME_GUI cannot handle an empty ERP dataset'; + title = 'ERPLAB: f_erp_dataquality_SME_GUI() error:'; + errorfound(msgboxText, title); + return +end +if isempty(ERP.bindata) + msgboxText = 'f_erp_dataquality_SME_GUI cannot handle an empty ERP dataset'; + title = 'ERPLAB: f_erp_dataquality_SME_GUI() error:'; + errorfound(msgboxText, title); + return +end + +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end + +if nargin == 0 + fig = figure(); % Parent figure + Erp_information = uiextras.BoxPanel('Parent', fig, 'Title', 'Data Quality (aSME)', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Data Quality (aSME)', 'Padding', 5,'BackgroundColor',ColorB_def); +else + Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'Data Quality (aSME)', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +varargout{1} = Erp_information; +gui_erp_DQSME = struct; +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_information(FonsizeDefault); + + + function drawui_erp_information(FonsizeDefault) + + + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + SelectedERP_current_index = S_binchan.Select_index; + + + + if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP) + SelectedERP(1) = observe_ERPDAT.CURRENTERP; + SelectedERP_current_index = 1; + end + + if strcmp(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + ERP_SME_summary = f_dq_summary(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index))); + + gui_erp_DQSME.DataSelBox = uiextras.VBox('Parent', Erp_information, 'Spacing',1,'BackgroundColor',ColorB_def); + + %%----------------------------Setting midian SME--------------------- + gui_erp_DQSME.Median_sme = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_DQSME.Median_sme_title = uicontrol('Style','text','Parent', gui_erp_DQSME.Median_sme,'String','Median:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_DQSME.Median_sme_title,'HorizontalAlignment','left'); + Median_tw =ERP_SME_summary{3,1}; + Median_name = strcat(num2str(roundn(ERP_SME_summary{1,1},-2)),', chan.',num2str(ERP_SME_summary{2,1}),',',32,num2str(Median_tw(1)),'-',num2str(Median_tw(2)),'ms, bin:',32,num2str(ERP_SME_summary{4,1})); + gui_erp_DQSME.Median_sme_name = uicontrol('Style','text','Parent', gui_erp_DQSME.Median_sme,'String',Median_name,'FontSize',FonsizeDefault); + set(gui_erp_DQSME.Median_sme_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_DQSME.Median_sme,'Sizes',[60 400]); + + %%----------------------------Setting min. SME--------------------- + gui_erp_DQSME.min_sme = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_DQSME.min_sme_title = uicontrol('Style','text','Parent', gui_erp_DQSME.min_sme,'String','Min:','FontSize',FonsizeDefault); + set(gui_erp_DQSME.min_sme_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + Min_tw =ERP_SME_summary{3,2}; + Min_name = strcat(num2str(roundn(ERP_SME_summary{1,2},-2)),', chan.',num2str(ERP_SME_summary{2,2}),',',32,num2str(Min_tw(1)),'-',num2str(Min_tw(2)),'ms, bin:',32,num2str(ERP_SME_summary{4,2})); + gui_erp_DQSME.min_sme_name = uicontrol('Style','text','Parent', gui_erp_DQSME.min_sme,'String',Min_name,'FontSize',FonsizeDefault); + set(gui_erp_DQSME.min_sme_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_DQSME.min_sme,'Sizes',[40 400]); + + %%----------------------------Setting max. SME--------------------- + gui_erp_DQSME.max_sme = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_DQSME.max_sme_title = uicontrol('Style','text','Parent', gui_erp_DQSME.max_sme,'String','Max:','FontSize',FonsizeDefault); + set(gui_erp_DQSME.max_sme_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + Max_tw =ERP_SME_summary{3,3}; + Max_name = strcat(num2str(roundn(ERP_SME_summary{1,3},-2)),', chan.',num2str(ERP_SME_summary{2,3}),',',32,num2str(Max_tw(1)),'-',num2str(Max_tw(2)),'ms, bin:',32,num2str(ERP_SME_summary{4,3})); + gui_erp_DQSME.max_sme_name = uicontrol('Style','text','Parent', gui_erp_DQSME.max_sme,'String',Max_name,'FontSize',FonsizeDefault); + set(gui_erp_DQSME.max_sme_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_DQSME.max_sme,'Sizes',[40 400]); + + gui_erp_DQSME.DQSME_option = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_DQSME.DQSME_option_table = uicontrol('Style','pushbutton','Parent', gui_erp_DQSME.DQSME_option,'String','Show in a table',... + 'callback',@DQSME_table,'Enable',Enable_label,'FontSize',FonsizeDefault); + + gui_erp_DQSME.DQSME_option_file = uicontrol('Style','pushbutton','Parent', gui_erp_DQSME.DQSME_option,'String','Save to file',... + 'callback',@DQSME_file,'Enable',Enable_label,'FontSize',FonsizeDefault); + set(gui_erp_DQSME.DQSME_option,'Sizes',[120 120]); + try + ERP_data_quality = observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).dataquality.data; + catch + ERP_data_quality =[]; + end + if isempty(ERP_data_quality) + set(gui_erp_DQSME.DQSME_option_table,'Enable','off'); + set(gui_erp_DQSME.DQSME_option_file,'Enable','off'); + end + gui_erp_DQSME.DQSME_option1 = uiextras.HBox('Parent',gui_erp_DQSME.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_DQSME.DQSME_option_measure = uicontrol('Style','pushbutton','Parent', gui_erp_DQSME.DQSME_option1,'String','Show measures on Command Window',... + 'callback',@DQSME_measures,'Enable',Enable_label,'FontSize',FonsizeDefault); + uiextras.Empty('Parent', gui_erp_DQSME.DQSME_option1); + set(gui_erp_DQSME.DQSME_option1,'Sizes',[240 10]); + set(gui_erp_DQSME.DataSelBox,'Sizes',[20 20 20 30 30]); + end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%-----------------------------Subfunction---------------------------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +%%--------Settting will be modified if the selected was changed------------ + function Count_currentERPChanged(~,~) + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + S_binchan = estudioworkingmemory('geterpbinchan'); + SelectedERP_current_index = S_binchan.Select_index; + if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP) + SelectedERP(1) = observe_ERPDAT.CURRENTERP; + SelectedERP_current_index = 1; + end + + if strcmp(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + ERP_SME_summary = f_dq_summary(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index))); + Median_tw =ERP_SME_summary{3,1}; + Median_name = strcat(num2str(roundn(ERP_SME_summary{1,1},-2)),', chan.',num2str(ERP_SME_summary{2,1}),',',32,num2str(Median_tw(1)),'-',num2str(Median_tw(2)),'ms, bin',32,num2str(ERP_SME_summary{4,1})); + gui_erp_DQSME.Median_sme_name.String = Median_name; + Min_tw =ERP_SME_summary{3,2}; + Min_name = strcat(num2str(roundn(ERP_SME_summary{1,2},-2)),', chan.',num2str(ERP_SME_summary{2,2}),',',32,num2str(Min_tw(1)),'-',num2str(Min_tw(2)),'ms, bin',32,num2str(ERP_SME_summary{4,2})); + gui_erp_DQSME.min_sme_name.String = Min_name; + Max_tw =ERP_SME_summary{3,3}; + Max_name = strcat(num2str(roundn(ERP_SME_summary{1,3},-2)),', chan.',num2str(ERP_SME_summary{2,3}),',',32,num2str(Max_tw(1)),'-',num2str(Max_tw(2)),'ms, bin',32,num2str(ERP_SME_summary{4,3})); + gui_erp_DQSME.max_sme_name.String=Max_name; + gui_erp_DQSME.DQSME_option_measure.Enable = Enable_label; + + try% check if the data for SMEs exsists or not + data_quality = observe_ERPDAT.ERP.dataquality.data; + if isempty(data_quality) + Enable_label = 'off'; + end + catch + Enable_label = 'off'; + beep; + disp('There no SME exist in current ERPset'); + end + gui_erp_DQSME.DQSME_option_table.Enable = Enable_label; + gui_erp_DQSME.DQSME_option_file.Enable = Enable_label; + + + end + + + +%%---------------------Save SME to a table--------------------------------- + function DQSME_table(~,~) + + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + SelectedERP_current_index = S_binchan.Select_index; + + if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP) + SelectedERP_current_index = 1; + end + DQ_Table_GUI(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)),observe_ERPDAT.ALLERP,SelectedERP(SelectedERP_current_index),1); + end + + + +%-----------------Save the SME to a file----------------------------------- + function DQSME_file(~,~) + + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + SelectedERP_current_index = S_binchan.Select_index; + + + if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP) + SelectedERP_current_index = 1; + end + + %-----------Setting for import------------------------------------- + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.7020 0.77 0.85]; + end + + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',ColorB_def); + + for Numoferp = 1:numel(SelectedERP) + ERP =observe_ERPDAT.ALLERP(SelectedERP(Numoferp)); + try + Datquality = ERP.dataquality; + if isempty(Datquality(1).data)&& isempty(Datquality(2).data) && isempty(Datquality(3).data) + msgboxText = ['No information for data quality is found!']; + question = [ 'No information for data quality is found!']; + title = 'ERPLAB Studio: ERPsets'; + button = questdlg(sprintf(question, msgboxText), title,'OK','OK'); + else + save_data_quality(observe_ERPDAT.ALLERP(SelectedERP(Numoferp))); + end + catch + msgboxText = ['No information for data quality is found!']; + question = [ 'No information for data quality is found!']; + title = 'ERPLAB Studio: "Save to file" on "Data quality (aSME)".'; + button = questdlg(sprintf(question, msgboxText), title,'OK','OK'); + end + + end + set(0,'DefaultUicontrolBackgroundColor',[1 1 1]); + end + + + +%-------------------Show which Data Quality measures are in each loaded ERPSET--------------------------- + function DQSME_measures(~,~) + if isempty(observe_ERPDAT.ALLERP) + beep; + disp('f_erp_dataquality_SME_GUI: No ERP was found!!!'); + return; + end + erpset_summary(observe_ERPDAT.ALLERP); + + end + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_erp_informtion_GUI.m b/studio_functions/GUIs/ERP Tab/f_erp_informtion_GUI.m new file mode 100755 index 00000000..03a9f2ae --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_erp_informtion_GUI.m @@ -0,0 +1,344 @@ + +%Author: Guanghui ZHANG--zhang.guanghui@foxmail.com +%Center for Mind and Brain +%University of California, Davis +%Davis, CA, USA +%Feb. 2022 + + + + +function varargout = f_erp_informtion_GUI(varargin) + +global observe_ERPDAT; +addlistener(observe_ERPDAT,'Count_currentERP_change',@Count_currentERPChanged); + + +if nargin < 1 + beep; + help f_erp_informtion_GUI; + return; +end + + +try + ERP = evalin('base','ERP'); +catch + beep; + disp('f_erp_informtion_GUI: No ERP was found in workspace'); + return; + +end + +if isempty(ERP) + msgboxText = 'No ERPset was found!'; + title_msg = 'EStudio: f_erp_informtion_GUI() error:'; + errorfound(msgboxText, title_msg); + return +end +if ~isfield(ERP, 'bindata') + msgboxText = 'f_erp_informtion_GUI cannot handle an empty ERP dataset'; + title = 'EStudio: f_erp_informtion_GUI() error:'; + errorfound(msgboxText, title); + return +end +if isempty(ERP.bindata) + msgboxText = 'f_erp_informtion_GUI cannot handle an empty ERP dataset'; + title = 'EStudio: f_erp_informtion_GUI() error:'; + errorfound(msgboxText, title); + return +end + + +try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; +catch + ColorB_def = [0.95 0.95 0.95]; +end +if nargin == 0 + fig = figure(); % Parent figure + Erp_information = uiextras.BoxPanel('Parent', fig, 'Title', 'ERP Information', 'Padding', 5,'BackgroundColor',ColorB_def); % Create boxpanel +elseif nargin == 1 + Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Information', 'Padding', 5,'BackgroundColor',ColorB_def); +else + Erp_information = uiextras.BoxPanel('Parent', varargin{1}, 'Title', 'ERP Information', 'Padding', 5, 'FontSize', varargin{2},'BackgroundColor',ColorB_def); +end + +varargout{1} = Erp_information; +gui_erp_information = struct; +try + FonsizeDefault = varargin{2}; +catch + FonsizeDefault = []; +end +if isempty(FonsizeDefault) + FonsizeDefault = f_get_default_fontsize(); +end +drawui_erp_information(FonsizeDefault); + + + function drawui_erp_information(FonsizeDefault) + try + [version reldate,ColorB_def,ColorF_def,errorColorF_def] = geterplabstudiodef; + catch + ColorB_def = [0.95 0.95 0.95]; + end + gui_erp_information.DataSelBox = uiextras.VBox('Parent', Erp_information, 'Spacing',1,'BackgroundColor',ColorB_def); + + %%----------------------------Setting sampling rate--------------------- + gui_erp_information.samplingrate = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_information.samplingrate_title = uicontrol('Style','text','Parent', gui_erp_information.samplingrate,'String','Sampling:','FontSize',FonsizeDefault); + if ERP.srate> 0 + ERP_time_resolution = strcat(32,num2str(roundn(1000/ERP.srate,-2)),32,'ms (resolution);',32,num2str(ERP.srate),32,'Hz','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + else + ERP_time_resolution = strcat(32,num2str(0),32,'ms (time resolution);',32,num2str(ERP.srate),32,'Hz (rate)','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + end + set(gui_erp_information.samplingrate_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + + gui_erp_information.samplingrate_resolution = uicontrol('Style','text','Parent', gui_erp_information.samplingrate,'String',ERP_time_resolution,'FontSize',FonsizeDefault); + set(gui_erp_information.samplingrate_resolution,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_information.samplingrate ,'Sizes',[70 430]); + + %%----------------------------Setting epoch--------------------- + gui_erp_information.epoch = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_information.epoch_title = uicontrol('Style','text','Parent', gui_erp_information.epoch,'String','Epoch:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_information.epoch_title,'HorizontalAlignment','left'); + gui_erp_information.epoch_name = uicontrol('Style','text','Parent', gui_erp_information.epoch,'String',[32,num2str(roundn(ERP.times(1),-2)),32,'to',32,num2str(roundn(ERP.times(end),-2)),32,'ms (',num2str(numel(ERP.times)),32,'pts)'],'FontSize',FonsizeDefault); + set(gui_erp_information.epoch_name,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_information.epoch ,'Sizes',[50 450]); + + %%----------------------------Number of Channels--------------------- + gui_erp_information.chan_num = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_information.numofchan_title = uicontrol('Style','text','Parent', gui_erp_information.chan_num,'String','Number of channels:','FontSize',FonsizeDefault); + set(gui_erp_information.numofchan_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + gui_erp_information.numofchan = uicontrol('Style','text','Parent', gui_erp_information.chan_num,'String',[32,num2str(ERP.nchan)],'FontSize',FonsizeDefault); + set(gui_erp_information.numofchan,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_information.chan_num ,'Sizes',[125 375]); + % set(gui_erp_information.filename_gui,'Sizes',[100 -1]); + + + %%----------------------------Number of bins--------------------- + gui_erp_information.bin_num = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_information.bin_num_title = uicontrol('Style','text','Parent', gui_erp_information.bin_num,'String','Number of bins:','FontSize',FonsizeDefault); + set(gui_erp_information.bin_num_title,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + gui_erp_information.numofbin = uicontrol('Style','text','Parent', gui_erp_information.bin_num,'String',[num2str(ERP.nbin)],'FontSize',FonsizeDefault); + % set(gui_erp_information.filename_gui,'Sizes',[100 -1]); + set(gui_erp_information.numofbin,'HorizontalAlignment','left','BackgroundColor',ColorB_def); + set(gui_erp_information.bin_num ,'Sizes',[110 390]); + + + %%----------------------------Total accepted--------------------- + N_trials = ERP.ntrials; + N_trial_total = sum(N_trials.accepted(:))+sum(N_trials.rejected(:))+sum(N_trials.invalid(:)); + N_trial_rejected = sum(N_trials.rejected(:)); + + if N_trial_total ==0 + Total_rejected_trials = strcat('0'); + else + Total_rejected_trials = strcat(num2str(roundn(N_trial_rejected/N_trial_total,-3)*100),'%'); + end + + gui_erp_information.total_rejected = uiextras.HBox('Parent',gui_erp_information.DataSelBox); + gui_erp_information.total_rejected_title = uicontrol('Style','text','Parent', gui_erp_information.total_rejected,'String','Total rejected trials:','FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_information.total_rejected_title,'HorizontalAlignment','left'); + + gui_erp_information.total_rejected_percentage = uicontrol('Style','text','Parent', gui_erp_information.total_rejected,'String',Total_rejected_trials,'FontSize',FonsizeDefault,'BackgroundColor',ColorB_def); + set(gui_erp_information.total_rejected_percentage,'HorizontalAlignment','left'); + set(gui_erp_information.total_rejected,'Sizes',[125 375]); + + %%------------totla rejected---------- + gui_erp_information.total_rejected_show = uiextras.HBox('Parent',gui_erp_information.DataSelBox,'BackgroundColor',ColorB_def); + gui_erp_information.total_rejected_option = uicontrol('Style','pushbutton','Parent', gui_erp_information.total_rejected_show,'String','Artifact rejection details',... + 'callback',@total_reject_ops,'FontSize',FonsizeDefault); + + if strcmp(observe_ERPDAT.ERP.erpname,'No ERPset loaded') + gui_erp_information.total_rejected_option.Enable = 'off'; + end + uiextras.Empty('Parent', gui_erp_information.total_rejected_show); + set(gui_erp_information.total_rejected_show,'Sizes',[150 250]); + + set(gui_erp_information.DataSelBox,'Sizes',[20 20 20 20 20 30]) + end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%-----------------------------Subfunction---------------------------------- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +%%--------Settting will be modified if the selected was changed------------ + function Count_currentERPChanged(~,~) +% try +% ERPloadIndex = estudioworkingmemory('ERPloadIndex'); +% catch +% ERPloadIndex =0; +% end +% if ERPloadIndex==1 +% ALLERPIN = evalin('base','ALLERP'); +% CURRENTERPIN = evalin('base','CURRENTERP'); +% observe_ERPDAT.ALLERP = ALLERPIN; +% observe_ERPDAT.CURRENTERP =CURRENTERPIN; +% try +% observe_ERPDAT.ERP = ALLERPIN(CURRENTERPIN); +% catch +% observe_ERPDAT.ERP = ALLERPIN(end); +% observe_ERPDAT.CURRENTERP =length(ALLERPIN); +% end +% end + + + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + S_binchan = estudioworkingmemory('geterpbinchan'); + SelectedERP_current_index = S_binchan.Select_index; + + if ~isempty(SelectedERP)&& SelectedERP_current_index> numel(SelectedERP) + SelectedERP(1) = observe_ERPDAT.CURRENTERP; + SelectedERP_current_index = 1; + end + + if strcmp(observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)).erpname,'No ERPset loaded') + Enable_label = 'off'; + else + Enable_label = 'on'; + end + + ERP_current_index = observe_ERPDAT.ALLERP(SelectedERP(SelectedERP_current_index)); + if numel(SelectedERP)==1 + if ERP_current_index.srate> 0 + ERP_time_resolution = strcat(32,num2str(roundn(1000/ERP_current_index.srate,-2)),32,'ms(resolution);',32,num2str(ERP_current_index.srate),32,'Hz'); + else + ERP_time_resolution = strcat(32,num2str(0),32,'ms(time resolution);',32,num2str(ERP_current_index.srate),32,'Hz (rate)'); + end + gui_erp_information.samplingrate_resolution.String = ERP_time_resolution; + try + gui_erp_information.epoch_name.String=char(strcat(num2str(roundn(ERP_current_index.times(1),-2)),32,'to',32,num2str(roundn(ERP_current_index.times(end),-2)),32,... + 'ms(',num2str(numel(ERP_current_index.times)),32,'pts)')); + catch + gui_erp_information.epoch_name.String=char(strcat('0 to 0ms(0 pts)')); + end + + gui_erp_information.numofchan.String=num2str(ERP_current_index.nchan); + gui_erp_information.numofbin.String=num2str(ERP_current_index.nbin); + N_trials = ERP_current_index.ntrials; + N_trial_total = sum(N_trials.accepted(:))+sum(N_trials.rejected(:))+sum(N_trials.invalid(:)); + N_trial_rejected = sum(N_trials.rejected(:)); + if N_trial_total ==0 + Total_rejected_trials = strcat('0'); + else + Total_rejected_trials = strcat(num2str(roundn(N_trial_rejected/N_trial_total,-3)*100),'%'); + end + gui_erp_information.total_rejected_percentage.Enable = Enable_label; + gui_erp_information.total_rejected_percentage.String = Total_rejected_trials; + gui_erp_information.total_rejected_option.Enable = Enable_label; + end + + if numel(SelectedERP)>1 + Check_Selected_erpset = [0 0 0 0 0 0 0]; + if numel(SelectedERP)>1 + + Check_Selected_erpset = S_binchan.checked_ERPset_Index; + + end + %%bin + if Check_Selected_erpset(1) ==1 + gui_erp_information.numofbin.String = 'Varied across ERPsets'; + else + try + BinNum = observe_ERPDAT.ERP.nbin; + catch + BinNum = 0; + end + gui_erp_information.numofbin.String = num2str(BinNum); + end + + %%chan + if Check_Selected_erpset(2) ==2 + gui_erp_information.numofchan.String = 'Varied across ERPsets'; + else + try + chanNum = observe_ERPDAT.ERP.nchan; + catch + chanNum = 0; + end + gui_erp_information.numofchan.String = num2str(chanNum); + end + %%Total rejected artifacts + gui_erp_information.total_rejected_percentage.String = 'Varied across ERPsets'; + + %%sampling rate + if Check_Selected_erpset(7) ==7 + gui_erp_information.samplingrate_resolution.String = 'Varied across ERPsets'; + else + try + if observe_ERPDAT.ERP.srate + ERP_time_resolution = strcat(32,num2str(roundn(1000/ERP_current_index.srate,-2)),32,'ms(resolution);',32,num2str(ERP_current_index.srate),32,'Hz'); + end + catch + ERP_time_resolution = strcat(32,num2str(0),32,'ms(time resolution);',32,num2str(ERP_current_index.srate),32,'Hz (rate)'); + end + gui_erp_information.samplingrate_resolution.String = ERP_time_resolution; + end + + if any(Check_Selected_erpset(4:6)) + gui_erp_information.epoch_name.String=char(strcat('Varied across ERPsets')); + else + try + gui_erp_information.epoch_name.String=char(strcat(num2str(roundn(ERP_current_index.times(1),-2)),32,'to',32,num2str(roundn(ERP_current_index.times(end),-2)),32,... + 'ms(',num2str(numel(ERP_current_index.times)),32,'pts)')); + catch + gui_erp_information.epoch_name.String=char(strcat('0 to 0ms(0 pts)')); + end + end + + + end + + + end + + + +%%----------------Rejection option---------------------------------------- + function total_reject_ops(~,~) + + SelectedERP= estudioworkingmemory('selectederpstudio'); + if isempty(SelectedERP) + SelectedERP = observe_ERPDAT.CURRENTERP; + + if isempty(SelectedERP) + msgboxText = 'No ERPset was selected!!!'; + title = 'EStudio: ERPsets'; + errorfound(msgboxText, title); + return; + end + S_erpplot = f_ERPplot_Parameter(observe_ERPDAT.ALLERP,SelectedERP); + estudioworkingmemory('geterpbinchan',S_erpplot.geterpbinchan); + estudioworkingmemory('geterpplot',S_erpplot.geterpplot); + end + + try + for Numoferp = 1:numel(SelectedERP) + ERP = observe_ERPDAT.ALLERP(SelectedERP(Numoferp)); + [ERP, acce, rej, histoflags, erpcom] = pop_summary_AR_erp_detection(ERP); + end + catch + return; + end + end + +end \ No newline at end of file diff --git a/studio_functions/GUIs/ERP Tab/f_export2csvGUI.fig b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.fig new file mode 100755 index 00000000..47afcceb Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_export2csvGUI.m b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.m new file mode 100755 index 00000000..48438e6d --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_export2csvGUI.m @@ -0,0 +1,352 @@ +% +% Author: Javier Lopez-Calderon & Steven Luck & Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 & 2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% Copyright (C) 2008 Javier Lopez-Calderon & Steven Luck, +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = f_export2csvGUI(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_export2csvGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_export2csvGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_export2csvGUI_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for f_export2csvGUI +handles.output = []; +try + ERP = varargin{1}; +catch + ERP.nbin =1; + ERP.nchan = 1; + ERP.chanlocs(1).labels = 'None'; + ERP.bindescr{1} = 'None'; + ERP.bindata = zeros(1,10,1); +end +handles.ERP = ERP; + +try + def = varargin{2}; +catch + def = {1, 1, 1, 3, ''}; +end + + +% try +% binArray = varargin{3}; +% chanArray = varargin{4}; +% +% catch +% binArray = 1; +% chanArray = 1; +% end + +istime = def{1}; +islabeled = def{2}; +transpa = def{3}; +prec = def{4}; +filename = def{5}; + +% version = geterplabversion; +set(handles.gui_chassis,'Name', ['EStudio ' '2022.1' ' - Export spectrum for selected ERPset as ".csv"']) + +[pathx, erpfilename, ext] = fileparts(filename); +ERPFileName = char(strcat(erpfilename,'.csv')); +set(handles.edit_saveas, 'String', fullfile(pathx,ERPFileName) ) +% set(handles.edit_bins, 'String', vect2colon(binArray, 'Delimiter', 'off')) +% set(handles.popupmenu_tunits,'String',{'seconds';'milliseconds'}) +% set(handles.popupmenu_tunits,'Value', tunitx) +set(handles.popupmenu_precision,'String', num2str([1:10]')) +set(handles.popupmenu_precision,'Value', prec) +set(handles.checkbox_time,'Value', istime) +set(handles.checkbox_elabels,'Value', islabeled) +set(handles.radiobutton_pr_ec,'Value', prec) + +if transpa==0 + set(handles.radiobutton_pr_ec,'Value', 1) + set(handles.radiobutton_er_pc,'Value', 0) +else + set(handles.radiobutton_pr_ec,'Value', 0) + set(handles.radiobutton_er_pc,'Value', 1) +end + + +% listb = {''}; +% nbin = ERP.nbin; % Total number of bins +% try +% for b=1:nbin +% listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; +% end +% catch +% listb = ''; +% end +% +% handles.listb = listb; +% handles.indxlistb = binArray; + + + + +% nchan = ERP.nchan; % Total number of channels +% if ~isfield(ERP.chanlocs,'labels') +% for e=1:nchan +% ERP.chanlocs(e).labels = ['Ch' num2str(e)]; +% end +% end +% listch = {''}; +% try +% for ch =1:nchan +% listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ]; +% end +% catch +% listch = ''; +% end +% handles.listch = listch; +% handles.indxlistch = chanArray; +% +% set(handles.edit_custom_bin,'String', vect2colon(binArray, 'Delimiter', 'off')); +% set(handles.edit_custom_chan,'String', vect2colon(chanArray, 'Delimiter', 'off')); + + +% helpbutton + +% +% Color GUI +% +% handles = painterplab(handles); + +% +% Set font size +% +% handles = setfonterplab(handles); + +handles = painterplabstudio(handles); +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +% helpbutton + +% UIWAIT makes f_export2csvGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_export2csvGUI_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function checkbox_time_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function checkbox_elabels_Callback(hObject, eventdata, handles) +values = handles.checkbox_elabels.Value; + +if values==1 + handles.checkbox_elabels.Value=values; +else + handles.checkbox_elabels.Value=values; +end + + +%-------------------------------------------------------------------------- +% function popupmenu_tunits_Callback(hObject, eventdata, handles) +% +% %-------------------------------------------------------------------------- +% function popupmenu_tunits_CreateFcn(hObject, eventdata, handles) +% +% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) +% set(hObject,'BackgroundColor','white'); +% end + +%-------------------------------------------------------------------------- +function popupmenu_precision_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_precision_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) + +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +% function pushbutton_help_Callback(hObject, eventdata, handles) +% % doc pop_export2text +% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser + + +%-------------------------------------------------------------------------- +function pushbutton_export_Callback(hObject, eventdata, handles) + +istime = get(handles.checkbox_time, 'Value'); +% timeu = get(handles.popupmenu_tunits, 'value'); + +islabeled = get(handles.checkbox_elabels, 'Value'); +transpa = get(handles.radiobutton_er_pc, 'Value'); +precision = get(handles.popupmenu_precision, 'Value'); +filename = get(handles.edit_saveas, 'String'); +% bins = str2num(get(handles.edit_bins, 'string')); + +if isempty(filename) + msgboxText = 'You must enter a filename!'; + title = 'EStudio: export2csv empty filename'; + errorfound(msgboxText, title); + return +end + +answer = {istime, islabeled, transpa, precision,filename}; +handles.output = answer; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +% ------------------------------------------------------------------------- +function edit_saveas_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_saveas_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_browse_Callback(hObject, eventdata, handles) + +% +% Save OUTPUT file +% +prename = get(handles.edit_saveas,'String'); +[fname, pathname, filterindex] = uiputfile({'*.csv';'*.*'},'Save Output file as', prename); + +if isequal(fname,0) + disp('User selected Cancel') + return +else + + [px, fname2, ext] = fileparts(fname); + + if strcmp(ext,'') + + if filterindex==1 || filterindex==2 + ext = '.csv'; + else + ext = '.csv'; + end + + fname = [ fname2 ext]; + end + + set(handles.edit_saveas,'String', fullfile(pathname, fname)); + % disp(['To save ERP, user selected ', fullfile(pathname, fname)]) +end + + + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + handles.output = []; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes when uipanel1 is resized. +function uipanel1_SizeChangedFcn(hObject, eventdata, handles) +% hObject handle to uipanel1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + + +% function edit_custom_bin_Callback(hObject, eventdata, handles) +% +% +% +% % --- Executes during object creation, after setting all properties. +% function edit_custom_bin_CreateFcn(hObject, eventdata, handles) +% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) +% set(hObject,'BackgroundColor','white'); +% end + + +% % --- Executes on button press in pushbutton_browse_bin. +% function pushbutton_browse_bin_Callback(hObject, eventdata, handles) +% % hObject handle to pushbutton_browse_bin (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) +% +% +% +% function edit_custom_chan_Callback(hObject, eventdata, handles) +% +% +% +% % --- Executes during object creation, after setting all properties. +% function edit_custom_chan_CreateFcn(hObject, eventdata, handles) +% if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) +% set(hObject,'BackgroundColor','white'); +% end +% +% +% % --- Executes on button press in pushbutton_browse_chan. +% function pushbutton_browse_chan_Callback(hObject, eventdata, handles) +% % hObject handle to pushbutton_browse_chan (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles structure with handles and user data (see GUIDATA) diff --git a/studio_functions/GUIs/ERP Tab/f_export2textGUI.fig b/studio_functions/GUIs/ERP Tab/f_export2textGUI.fig new file mode 100755 index 00000000..41604a53 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_export2textGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_export2textGUI.m b/studio_functions/GUIs/ERP Tab/f_export2textGUI.m new file mode 100755 index 00000000..9b87e99e --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_export2textGUI.m @@ -0,0 +1,438 @@ +% +% Author: Javier Lopez-Calderon & Steven Luck & Guanghui ZHANG +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 & 2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% Copyright (C) 2008 Javier Lopez-Calderon & Steven Luck, +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = f_export2textGUI(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_export2textGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_export2textGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_export2textGUI_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for f_export2textGUI +handles.output = []; +try + ERP = varargin{1}; +catch + ERP.erpname = 'No erp was imported'; + ERP.nbin =1; + ERP.nchan = 1; + ERP.chanlocs(1).labels = 'None'; + ERP.bindescr{1} = 'None'; + ERP.bindata = zeros(1,10,1); +end + +try + + binArray = varargin{3}; + chanArray = varargin{4}; +catch + binArray = 1; + chanArray = 1; +end + +try + def = varargin{2}; +catch + def = {1,1000, 1, 1, 4, 1, ''}; +end + +istime = def{1}; +tunit = def{2}; +islabeled = def{3}; +transpa = def{4}; +prec = def{5}; +filename = def{6}; + +if tunit == 1 + tunitx = 1; +else + tunitx = 2; +end + +% +% Name & version +% +erplab_studio_default_values; +version = erplabstudiover; + +set(handles.gui_chassis,'Name', ['EStudio ', version, ' - Export ERP GUI']) + +[pathx, erpfilename, ext] = fileparts(filename); +ERPFileName = char(strcat(erpfilename,'.txt')); + + +set(handles.edit_saveas, 'String', fullfile(pathx,ERPFileName)) +% set(handles.edit_bins, 'String', vect2colon(binArray, 'Delimiter', 'off')) +set(handles.popupmenu_tunits,'String',{'seconds';'milliseconds'}) +set(handles.popupmenu_tunits,'Value', tunitx) +set(handles.popupmenu_precision,'String', num2str([1:10]')) +set(handles.popupmenu_precision,'Value', prec) +set(handles.checkbox_time,'Value', istime) +set(handles.checkbox_elabels,'Value', islabeled) +set(handles.radiobutton_pr_ec,'Value', prec) + +if transpa==0 + set(handles.radiobutton_pr_ec,'Value', 1) + set(handles.radiobutton_er_pc,'Value', 0) +else + set(handles.radiobutton_pr_ec,'Value', 0) + set(handles.radiobutton_er_pc,'Value', 1) +end + +%%----------------------Setting for bin and channels----------------------- +listb = {''}; +nbin = ERP.nbin; % Total number of bins +try + for b=1:nbin + listb{b}= ['BIN' num2str(b) ' = ' ERP.bindescr{b} ]; + end +catch + listb = ''; +end +handles.listb = listb; +handles.indxlistb = binArray; + +nchan = ERP.nchan; % Total number of channels +if ~isfield(ERP.chanlocs,'labels') + for e=1:nchan + ERP.chanlocs(e).labels = ['Ch' num2str(e)]; + end +end +listch = {''}; +try + for ch =1:nchan + listch{ch} = [num2str(ch) ' = ' ERP.chanlocs(ch).labels ]; + end +catch + listch = ''; +end +handles.listch = listch; +handles.indxlistch = chanArray; + +set(handles.edit3_custom_bin,'String', vect2colon(binArray, 'Delimiter', 'off')); +set(handles.edit_custom_chan,'String', vect2colon(chanArray, 'Delimiter', 'off')); +handles.ERP = ERP; + + +% helpbutton + +% +% Color GUI +% +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +% helpbutton + +% UIWAIT makes f_export2textGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_export2textGUI_OutputFcn(hObject, eventdata, handles) + +% Get default command line output from handles structure +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); + + +function edit3_custom_bin_Callback(hObject, eventdata, handles) + +BinString = str2num(handles.edit3_custom_bin.String); +ERP = handles.ERP; +% [chk, msgboxText] = chckbinandchan(ERP, BinString, []); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinString, [],1); + +if chk(1) + title = 'EStudio: f_export2text GUI for bin input!'; + errorfound(msgboxText, title); + return; +end +% --- Executes during object creation, after setting all properties. +function edit3_custom_bin_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton7_browse_bin. +function pushbutton7_browse_bin_Callback(hObject, eventdata, handles) +listb = handles.listb; +indxlistb = handles.indxlistb; +indxlistb = indxlistb(indxlistb<=length(listb)); +titlename = 'Select Bin(s)'; + +if get(hObject, 'Value') + %set(handles.pushbutton_browsechan, 'Enable', 'off') + if ~isempty(listb) + bin = browsechanbinGUI(listb, indxlistb, titlename); + if ~isempty(bin) + set(handles.edit3_custom_bin, 'String', vect2colon(bin, 'Delimiter', 'off')); + handles.indxlistb = bin; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No bin information was found'; + title = 'EStudio: f_export2text GUI for bin input'; + errorfound(msgboxText, title); + return + end + +end + + +function edit_custom_chan_Callback(hObject, eventdata, handles) +chanString = str2num(handles.edit_custom_chan.String); +ERP = handles.ERP; + +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],chanString, 2); + +if chk(2) + title = 'EStudio: f_export2text GUI for channel input!'; + errorfound(msgboxText, title); + return; +end + + +% --- Executes during object creation, after setting all properties. +function edit_custom_chan_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in pushbutton8_browse_chan. +function pushbutton8_browse_chan_Callback(hObject, eventdata, handles) + +listch = handles.listch; +indxlistch = handles.indxlistch; +indxlistch = indxlistch(indxlistch<=length(listch)); +titlename = 'Select Channel(s)'; + +if get(hObject, 'Value') + if ~isempty(listch) + ch = browsechanbinGUI(listch, indxlistch, titlename); + if ~isempty(ch) + set(handles.edit_custom_chan, 'String', vect2colon(ch, 'Delimiter', 'off')); + handles.indxlistch = ch; + % Update handles structure + guidata(hObject, handles); + else + disp('User selected Cancel') + return + end + else + msgboxText = 'No channel information was found'; + title = 'EStudio: f_export2text GUI for channel input'; + errorfound(msgboxText, title); + return + end +end +%-------------------------------------------------------------------------- +function checkbox_time_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function checkbox_elabels_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_tunits_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_tunits_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_precision_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_precision_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) + +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +% function pushbutton_help_Callback(hObject, eventdata, handles) +% % doc pop_export2text +% web 'https://github.com/lucklab/erplab/wiki/Exporting,-Editing,-and-Importing-EVENTLISTS' -browser +%-------------------------------------------------------------------------- +function pushbutton_export_Callback(hObject, eventdata, handles) + +istime = get(handles.checkbox_time, 'value'); +timeu = get(handles.popupmenu_tunits, 'value'); + +if timeu == 1 + timeunit = 1E0; +else + timeunit = 1E-3; +end + +islabeled = get(handles.checkbox_elabels, 'value'); +transpa = get(handles.radiobutton_er_pc, 'value'); +precision = get(handles.popupmenu_precision, 'value'); +filename = get(handles.edit_saveas, 'string'); +% bins = str2num(get(handles.edit_bins, 'string')); + +if isempty(filename) + msgboxText = 'You must enter a filename!'; + title = 'EStudio: f_export2text GUI empty filename'; + errorfound(msgboxText, title); + return +end + + +BinArray = str2num(handles.edit3_custom_bin.String); +ERP = handles.ERP; +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, BinArray, [],1); + +if chk(1) + title = 'EStudio: f_export2text GUI for bin input!'; + errorfound(msgboxText, title); + return; +end + + +ChanArray = str2num(handles.edit_custom_chan.String); +[chk, msgboxText] = f_ERP_chckbinandchan(ERP, [],ChanArray, 2); + +if chk(2) + title = 'EStudio: f_export2text GUI for channel input!'; + errorfound(msgboxText, title); + return; +end + +ERP.bindata = ERP.bindata(ChanArray,:,BinArray); +ERP.nbin = numel(BinArray); +ERP.nchan = numel(ChanArray); +ERP.chanlocs = ERP.chanlocs(ChanArray); +for Numofbin = 1:numel(BinArray) + ERP.bindescr{Numofbin} = ERP.bindescr{BinArray(Numofbin)}; +end + +answer = {istime, timeunit, islabeled, transpa, precision,filename,ERP}; +handles.output = answer; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +% ------------------------------------------------------------------------- +function edit_saveas_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_saveas_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_browse_Callback(hObject, eventdata, handles) + +% +% Save OUTPUT file +% +ERP = handles.ERP; +prename = get(handles.edit_saveas,'String'); +[fname, pathname, filterindex] = uiputfile({'*.txt';'*.dat';'*.*'},['Save "', ERP.erpname,'" as'], prename); + +if isequal(fname,0) + disp('User selected Cancel') + return +else + + [px, fname2, ext] = fileparts(fname); + + if strcmp(ext,'') + + if filterindex==1 || filterindex==3 + ext = '.txt'; + else + ext = '.dat'; + end + + fname = [ fname2 ext]; + end + + set(handles.edit_saveas,'String', fullfile(pathname, fname)); + disp(['To save ERP, user selected ', fullfile(pathname, fname)]) +end + + + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + handles.output = []; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.fig b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.fig new file mode 100755 index 00000000..88ebabfb Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.m b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.m new file mode 100755 index 00000000..ea236564 --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_rerefassistantGUI.m @@ -0,0 +1,383 @@ +function varargout = f_rerefassistantGUI(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_rerefassistantGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_rerefassistantGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +%-------------------------------------------------------------------------- +function f_rerefassistantGUI_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for f_rerefassistantGUI +handles.output = hObject; +try + handles.norichan = varargin{1}; + listch = varargin{2}; + listch = regexprep(listch, '.*=','','ignorecase'); + listch = strtrim(listch); + handles.listch = listch; +catch + handles.norichan = 1; + handles.listch = {}; +end + +% +% Gui memory +% +rerefwizardGUI = erpworkingmemory('rerefwizardGUI'); + +if isempty(rerefwizardGUI) + set(handles.edit_includechan,'String',''); + set(handles.radiobutton_allchan,'Value',1) + set(handles.radiobutton_chan2inclu,'Value',0) + set(handles.radiobutton_chan2exclu,'Value',0) + set(handles.edit_excludechan,'String',''); + set(handles.checkbox_addrefchan2mydata,'Value', 0); % 1 means yes + set(handles.checkbox_copynewlabel,'Value', 1); + set(handles.edit_equation,'String', ''); + set(handles.checkbox_addunrefequ,'Value', 0); + set(handles.edit_includechan,'Enable','off') + set(handles.edit_excludechan,'Enable','off') + chArray = 1:handles.norichan; +else + incexc = rerefwizardGUI.incexc ; + chArray = rerefwizardGUI.chArray; + addref = rerefwizardGUI.addref; + addlab = rerefwizardGUI.addlab; + equation = rerefwizardGUI.equation; + addunrefequ = rerefwizardGUI.addunrefequ; + + if incexc + set(handles.radiobutton_chan2inclu,'Value',1) + set(handles.radiobutton_chan2exclu,'Value',0) + set(handles.edit_includechan,'String',vect2colon(chArray,'Delimiter','off')); + set(handles.edit_excludechan,'String',''); + %set(handles.edit_includechan,'Enable','off') + set(handles.edit_excludechan,'Enable','off') + else + set(handles.radiobutton_chan2inclu,'Value',0) + set(handles.radiobutton_chan2exclu,'Value',1) + set(handles.edit_includechan,'String', ''); + set(handles.edit_excludechan,'String', vect2colon(chArray,'Delimiter','off')); + set(handles.edit_includechan,'Enable','off') + %set(handles.edit_excludechan,'Enable','off') + end + set(handles.checkbox_addrefchan2mydata,'Value', addref); % 1 means yes + set(handles.checkbox_copynewlabel,'Value', addlab); + set(handles.edit_equation,'String', equation); + set(handles.checkbox_addunrefequ,'Value', addunrefequ); +end + +handles.chArray = chArray; + +% +% Name & version +% +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - Rereference GUI']) + +% +% Color GUI +% +handles = painterplabstudio(handles); + +% +% Set font size +% +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +% helpbutton + +drawnow +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_rerefassistantGUI_OutputFcn(hObject, eventdata, handles) + +varargout{1} = handles.output; + +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +%-------------------------------------------------------------------------- +function edit_equation_Callback(hObject, eventdata, handles) + +% +% In case user writes "Ch_REF =", this will be erased. +% +formula = get(hObject,'String'); +formula = regexprep(formula, '.*s*=','','ignorecase'); +formula = lower(formula); +set(hObject,'String', formula); + +%-------------------------------------------------------------------------- +function edit_equation_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function radiobutton_allchan_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_chan2inclu,'Value',0) + set(handles.radiobutton_chan2exclu,'Value',0) + set(handles.edit_includechan,'Enable','off') + set(handles.edit_excludechan,'Enable','off') +else + set(handles.radiobutton_allchan,'Value',1) +end + +%-------------------------------------------------------------------------- +function radiobutton_chan2inclu_Callback(hObject, eventdata, handles) + +if get(hObject,'Value') + set(handles.radiobutton_allchan,'Value',0) + set(handles.radiobutton_chan2exclu,'Value',0) + set(handles.edit_includechan,'Enable','on') + set(handles.edit_excludechan,'Enable','off') +else + set(handles.radiobutton_chan2inclu,'Value',1) +end + +%-------------------------------------------------------------------------- +function radiobutton_chan2exclu_Callback(hObject, eventdata, handles) + +if get(hObject,'Value') + set(handles.radiobutton_allchan,'Value',0) + set(handles.radiobutton_chan2inclu,'Value',0) + set(handles.edit_includechan,'Enable','off') + set(handles.edit_excludechan,'Enable','on') +else + set(handles.radiobutton_chan2exclu,'Value',1) +end + +%-------------------------------------------------------------------------- +function edit_includechan_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_includechan_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function edit_excludechan_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_excludechan_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function pushbutton2_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function pushbutton_OK_Callback(hObject, eventdata, handles) + +addref = get(handles.checkbox_addrefchan2mydata,'Value'); % 1 means yes +addlabel = get(handles.checkbox_copynewlabel,'Value'); +equation = get(handles.edit_equation,'String'); +addunrefequ = get(handles.checkbox_addunrefequ,'Value'); % 1 means yes + +if isempty(equation) + msgboxText = 'You have not written any expression yet!'; + title = 'ERPLAB: rerefwizardGUI empty input'; + errorfound(msgboxText, title); + return +end + +abut = get(handles.radiobutton_allchan,'Value'); % all +bbut = get(handles.radiobutton_chan2inclu,'Value'); % include +cbut = get(handles.radiobutton_chan2exclu,'Value'); % exclude +norichan = handles.norichan; + +if abut && ~bbut && ~cbut + incexc = 1; % include + chArray = 1:norichan; +elseif ~abut && bbut && ~cbut + incexc = 1; % include + chArray = str2num(get(handles.edit_includechan,'String')); + if isempty(chArray) + msgboxText = 'You have not specified any channel yet!'; + title = 'ERPLAB: rerefwizardGUI empty input'; + errorfound(msgboxText, title); + return + end +elseif ~abut && ~bbut && cbut + incexc = 0; % exclude + chArray = str2num(get(handles.edit_excludechan,'String')); +else + fprintf('\nOops! something went wrong with this gui.\n') + return +end +% if get(handles.radiobutton_chan2inclu,'Value') && ~get(handles.radiobutton_chan2exclu,'Value') +% incexc = 1; % include +% chArray = str2num(get(handles.edit_includechan,'String')); +% elseif ~get(handles.radiobutton_chan2inclu,'Value') && get(handles.radiobutton_chan2exclu,'Value') +% incexc = 0; % exclude +% chArray = str2num(get(handles.edit_excludechan,'String')); +% else +% return +% end + +formulalist = createformulas(handles, incexc, chArray, addref, equation, addunrefequ); +handles.output = {formulalist}; + +% +% memory for Gui +% +rerefwizardGUI.incexc = incexc; +rerefwizardGUI.chArray = chArray; +rerefwizardGUI.addref = addref; +rerefwizardGUI.addlab = addlabel; +rerefwizardGUI.equation = equation; +rerefwizardGUI.addunrefequ = addunrefequ; + +erpworkingmemory('rerefwizardGUI', rerefwizardGUI); + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function checkbox_addrefchan2mydata_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function formulalist = createformulas(handles, incexc, chArray, addref, equation, addunrefequ) + +% +% Creates list of formulas for referencing +% +norichan = handles.norichan; % number of original channels +listch = handles.listch; + +if incexc + chanArray = chArray; +else + orichanArray = 1:norichan; + chanArray = orichanArray(~ismember_bc2(orichanArray, chArray)); +end +% nchan = length(chanArray); % number of chs to reref + +unrefchanArray = 1:norichan; +unrefchanArray = unrefchanArray(~ismember_bc2(unrefchanArray, chanArray)); + +for i=1:norichan + if get(handles.checkbox_copynewlabel,'Value') + try + newlabel = listch{i}; + catch + newlabel = 'undefined'; + end + if ismember_bc2(i, unrefchanArray) && addunrefequ + flist{i} = sprintf('ch%g = ch%g Label %s', i, i, newlabel); + elseif ismember_bc2(i, chanArray) + flist{i} = sprintf('ch%g = ch%g - ( %s ) Label %s', i, i, equation, newlabel) ; + end + else + if ismember_bc2(i, unrefchanArray) && addunrefequ + flist{i} = sprintf('ch%g = ch%g', i, i) ; + elseif ismember_bc2(i, chanArray) + flist{i} = sprintf('ch%g = ch%g - ( %s )', i, i, equation) ; + end + end +end +flist = flist(~cellfun(@isempty, flist)); + +% for i=1:nchan +% if get(handles.checkbox_copynewlabel,'Value') +% try +% newlabel = listch{chanArray(i)}; +% catch +% newlabel = 'undefined'; +% end +% flist{i} = sprintf('ch%g = ch%g - ( %s ) Label %s', chanArray(i), chanArray(i), equation, newlabel) ; +% else +% flist{i} = sprintf('ch%g = ch%g - ( %s )', chanArray(i), chanArray(i), equation) ; +% end +% end +% +% +% +% +% if addunrefequ +% unrefchanArray = 1:norichan; +% unrefchanArray = unrefchanArray(~ismember_bc2(unrefchanArray, chanArray)); +% unchan = length(unrefchanArray); +% for i=1:unchan +% if get(handles.checkbox_copynewlabel,'Value') +% try +% newlabel = listch{unrefchanArray(i)}; +% catch +% newlabel = 'undefined'; +% end +% flist{i+nchan} = sprintf('ch%g = ch%g Label %s', unrefchanArray(i), unrefchanArray(i), newlabel) ; +% else +% flist{i+nchan} = sprintf('ch%g = ch%g', unrefchanArray(i), unrefchanArray(i)) ; +% end +% end +% end + +if addref + flist{end+1} = sprintf('ch%g = %s Label New Ref', norichan+1, equation) ; +end +formulalist = char(flist); +return + +%-------------------------------------------------------------------------- +function pushbutton_avgref_Callback(hObject, eventdata, handles) +chArray = handles.chArray; +set(handles.edit_equation, 'String','') +avgformula = sprintf('avgchan(%s)', vect2colon(chArray, 'Delimiter', 'off')); +set(handles.edit_equation, 'String', avgformula) + +%-------------------------------------------------------------------------- +function checkbox_copynewlabel_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function checkbox_addunrefequ_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) + +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME + handles.output = ''; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end diff --git a/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.fig b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.fig new file mode 100755 index 00000000..035469a4 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.fig differ diff --git a/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.m b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.m new file mode 100755 index 00000000..ce7a4c5f --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/f_scalplotadvanceGUI.m @@ -0,0 +1,738 @@ +% Author: Javier Lopez-Calderon % Sam London +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% EStudio Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = f_scalplotadvanceGUI(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @f_scalplotadvanceGUI_OpeningFcn, ... + 'gui_OutputFcn', @f_scalplotadvanceGUI_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function f_scalplotadvanceGUI_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for f_scalplotadvanceGU +try + pscale_legend = varargin{1}; +catch + %%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue} + pscale_legend = {1,1,1,1,0,'on','off',0,1}; +end + +binnum = pscale_legend{1}; +bindesc = pscale_legend{2}; +type = pscale_legend{3}; +latency = pscale_legend{4}; +electrodes = pscale_legend{5}; +elestyle = pscale_legend{6}; +elec3D = pscale_legend{7}; +% colorbar = val(6); +ismaxim = pscale_legend{8}; +is2Dmap = pscale_legend{9}; + +handles.is2Dmap = is2Dmap; +% Name & version +% +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - SCALP MAPPING ADVANCED GUI']) + + + +set(handles.checkbox_binnumber,'Value', binnum) +set(handles.checkbox_bindescription,'Value', bindesc) +set(handles.checkbox_tvalue,'Value', type) +set(handles.checkbox_latency,'Value', latency) + +if electrodes && ~strcmpi(elec3D, 'on') + switch elestyle + case 'on' + set(handles.checkbox_electrodes,'Value', 1) + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 0) + set(handles.radiobutton_excludepoints,'Enable', 'off') + case 'off' + set(handles.checkbox_electrodes,'Value', 0) + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 0) + + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'off') + set(handles.radiobutton_showelabel,'Enable', 'off') + case 'numbers' + set(handles.checkbox_electrodes,'Value', 1) + set(handles.radiobutton_excludepoints,'Value', 1) + set(handles.radiobutton_showenumber,'Value', 1) + set(handles.radiobutton_showelabel,'Value', 0) + case 'labels' + set(handles.checkbox_electrodes,'Value', 1) + set(handles.radiobutton_excludepoints,'Value', 1) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 1) + case 'ptsnumbers' + set(handles.checkbox_electrodes,'Value', 1) + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 1) + set(handles.radiobutton_showelabel,'Value', 0) + case 'ptslabels' + set(handles.checkbox_electrodes,'Value', 1) + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 1) + otherwise + set(handles.checkbox_electrodes,'Value', 0) + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 0) + + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'off') + set(handles.radiobutton_showelabel,'Enable', 'off') + end + + % if ~elecexcpnts && ~elecshownum && ~elecshowlab + % %'on','off','labels','numbers','ptslabels','ptsnumbers' + % elestyle = 'on'; + % elseif ~elecexcpnts && elecshownum && ~elecshowlab + % %'on','off','labels','numbers','ptslabels','ptsnumbers' + % elestyle = 'numbers'; + % elseif ~elecexcpnts && ~elecshownum && elecshowlab + % %'on','off','labels','numbers','ptslabels','ptsnumbers' + % elestyle = 'labels'; + % elseif elecexcpnts && elecshownum && ~elecshowlab + % %'on','off','labels','numbers','ptslabels','ptsnumbers' + % elestyle = 'ptsnumbers'; + % elseif elecexcpnts && ~elecshownum && elecshowlab + % %'on','off','labels','numbers','ptslabels','ptsnumbers' + % elestyle = 'ptslabels'; + % else + % return + % end +else + %elestyle = 'off'; + set(handles.checkbox_electrodes,'Value', 0); + set(handles.radiobutton_excludepoints,'Enable', 'off','Value',0) + set(handles.radiobutton_showenumber,'Enable', 'off','Value',0); + set(handles.radiobutton_showelabel,'Enable', 'off','Value',0); + set(handles.checkbox_3Delec,'Value', 0,'Enable', 'off'); +end +if is2Dmap + set(handles.checkbox_3Delec,'Value', 0) + set(handles.checkbox_3Delec,'Enable', 'off') +else + if strcmpi(elec3D, 'on') + set(handles.checkbox_3Delec,'Value', 1) + set(handles.checkbox_electrodes,'Value', 1) + + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 0) + + %set(handles.checkbox_electrodes,'Enable', 'off') + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'off') + set(handles.radiobutton_showelabel,'Enable', 'off') + end +end + +set(handles.checkbox_maximize,'Value', ismaxim) +% + +try + pagif_legend = varargin{2}; +catch + %%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue} + pagif_legend = {0,[],'',[]}; +end + +agif = pagif_legend{1}; +FPS = pagif_legend{2}; +fnameagif = pagif_legend{3}; +latency =pagif_legend{4}; +handles.latency = latency; + + +if agif>0 + set(handles.checkbox_animation,'Value', 1) + set(handles.checkbox_adjust1frame,'Enable', 'on') + set(handles.edit_fps,'Enable', 'on') + set(handles.edit_fps,'String', num2str(FPS)) + set(handles.edit_fname_animation,'Enable', 'on') + set(handles.edit_fname_animation,'String', fnameagif) + set(handles.pushbutton_browse_animation,'Enable', 'on') + + if agif==2 + set(handles.checkbox_adjust1frame,'Value', 1) + else + set(handles.checkbox_adjust1frame,'Value', 0) + end + set(handles.checkbox_adjust1frame,'Enable', 'on') +else + set(handles.checkbox_animation,'Value', 0) + set(handles.checkbox_animation,'Value', 0) + set(handles.checkbox_adjust1frame,'Value', 0) + set(handles.checkbox_adjust1frame,'Enable', 'off') + set(handles.edit_fps,'Enable', 'off') + set(handles.edit_fname_animation,'Enable', 'off') + set(handles.pushbutton_browse_animation,'Enable', 'off') + set(handles.checkbox_adjust1frame,'Value', 0) + set(handles.checkbox_adjust1frame,'Enable', 'off') +end + + +% Color GUI +% +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +% help +% helpbutton + +% PDF button +% pdfbutton + +% set all objects +% setall(hObject, eventdata, handles) + +% UIWAIT makes geterpvaluesGUI wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = f_scalplotadvanceGUI_OutputFcn(hObject, eventdata, handles) +varargout{1} = handles.output; +% varargout{2} = handles.ERP; + +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + + +%-------------------------------------------------------------------------- +function pushbutton_OK_Callback(hObject, eventdata, handles) +% Animation +% +if get(handles.checkbox_animation, 'Value') + if get(handles.checkbox_adjust1frame, 'Value') + isagif = 2; % adjust first frame + else + isagif = 1; + end + + FPS = str2num(get(handles.edit_fps, 'String')); + fnameagif = get(handles.edit_fname_animation, 'String'); + + if isempty(FPS) || FPS<1 || FPS>1000 + msgboxText = 'Error: You must specify a scalar value between 1 and 1000 inclusive'; + title = 'EStudio: f_scalplotadvanceGUI() error:'; + errorfound(msgboxText, title); + return + end + if isempty(strtrim(fnameagif)) + msgboxText = 'Error: You must specify a valid file name for your animated GIF'; + title = 'EStudio: f_scalplotadvanceGUI() error:'; + errorfound(msgboxText, title); + return + else + [pthxz, fnamez, ext] = fileparts(fnameagif); + if strcmp(ext,'') + ext = '.gif'; + end + fnameagif = fullfile(pthxz,[ fnamez ext]); + end +else + isagif = 0; + FPS = []; + fnameagif = ''; +end + + + +binnum = get(handles.checkbox_binnumber,'Value'); +bindesc = get(handles.checkbox_bindescription,'Value'); +type = get(handles.checkbox_tvalue,'Value'); +latency = get(handles.checkbox_latency,'Value'); +electrodes = get(handles.checkbox_electrodes,'Value'); + +elecexcpnts = get(handles.radiobutton_excludepoints,'Value'); +elecshownum = get(handles.radiobutton_showenumber,'Value'); +elecshowlab = get(handles.radiobutton_showelabel,'Value'); + +if electrodes + if ~elecexcpnts && ~elecshownum && ~elecshowlab + %'on','off','labels','numbers','ptslabels','ptsnumbers' + elestyle = 'on'; + elseif ~elecexcpnts && elecshownum && ~elecshowlab + %'on','off','labels','numbers','ptslabels','ptsnumbers' + elestyle = 'ptsnumbers'; + elseif ~elecexcpnts && ~elecshownum && elecshowlab + %'on','off','labels','numbers','ptslabels','ptsnumbers' + elestyle = 'ptslabels'; + elseif elecexcpnts && elecshownum && ~elecshowlab + %'on','off','labels','numbers','ptslabels','ptsnumbers' + elestyle = 'numbers'; + elseif elecexcpnts && ~elecshownum && elecshowlab + %'on','off','labels','numbers','ptslabels','ptsnumbers' + elestyle = 'labels'; + else + return + end +else + elestyle = 'off'; +end + +el3D = get(handles.checkbox_3Delec,'Value'); +if el3D + elec3D = 'on'; +else + elec3D = 'off'; +end + +% colorbar = get(handles.checkbox_cbar,'Value'); +ismaxim = get(handles.checkbox_maximize,'Value'); + +is2Dmap=handles.is2Dmap; +%%{binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim, 2Dvalue} +pscale_legend = {binnum, bindesc, type, latency, electrodes, elestyle, elec3D, ismaxim,is2Dmap}; + +%%isagif; FPS;fnameagif +pagif_legend = {isagif,FPS,'',fnameagif}; + + +handles.output = {pscale_legend,pagif_legend}; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); +% end +% end + + + + + + +%-------------------------------------------------------------------------- +function edit_customblc_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + + + + +%-------------------------------------------------------------------------- +function edit_exchan_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_exchan_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_exchan_Callback(hObject, eventdata, handles) +numch = get(hObject, 'Value'); +nums = get(handles.edit_exchan, 'String'); +nums = [nums ' ' num2str(numch)]; +set(handles.edit_exchan, 'String', nums); + +%-------------------------------------------------------------------------- +function popupmenu_exchan_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function checkbox_animation_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.edit_fps,'Enable', 'on') + set(handles.edit_fname_animation,'Enable', 'on') + set(handles.pushbutton_browse_animation,'Enable', 'on') + set(handles.checkbox_adjust1frame,'Enable', 'on') +else + set(handles.edit_fps,'Enable', 'off') + set(handles.edit_fname_animation,'Enable', 'off') + set(handles.pushbutton_browse_animation,'Enable', 'off') + set(handles.checkbox_adjust1frame,'Enable', 'off') +end + +%-------------------------------------------------------------------------- +function edit_fname_animation_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_fname_animation_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function pushbutton_browse_animation_Callback(hObject, eventdata, handles) + +% +% Save GIF, mov, or mpg +% +prename = get(handles.edit_fname_animation,'String'); +%[blfilename, blpathname, filterindex] = uiputfile({'*.gif';'*.*'},'Save animation as',prename); + +[blfilename, blpathname, filterindex] = uiputfile( ... + {'*.gif','Animated GIF (*.gif)'; + '*.mat', 'Matlab movie (*.mat)';... + '*.avi','AVI file (*.avi)'},... + 'Save animation as', prename); + +if isequal(blfilename,0) + disp('User selected Cancel') + return +else + [px, fname, ext] = fileparts(blfilename); + if filterindex==1 + ext = '.gif'; + elseif filterindex==2 + ext = '.mat'; + elseif filterindex==3 + ext = '.avi'; + else + ext = '.gif'; + end + + fname = [ fname ext]; + + fullgifname = fullfile(blpathname, fname); + set(handles.edit_fname_animation,'String', fullgifname); + disp(['Animatation will be saved at ' fullgifname]) +end + +%-------------------------------------------------------------------------- +function edit_fps_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit_fps_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +% function checkbox_colorbar_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function pushbutton_ploterp_Callback(hObject, eventdata, handles) +plotset = getplotset(hObject, eventdata, handles); +if isempty(plotset.ptime) + return +else + plotset.ptime.binArray = plotset.pscalp.binArray ; + plotset.ptime.blcorr = plotset.pscalp.baseline; + assignin('base','plotset', plotset); + handles.eplot = 1; + + %Update handles structure + guidata(hObject, handles); + uiresume(handles.figure1); +end + + + + +%-------------------------------------------------------------------------- +function checkbox_adjust1frame_Callback(hObject, eventdata, handles) + + + +%-------------------------------------------------------------------------- +function popupmenu_orientation_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +%-------------------------------------------------------------------------- +function edit_customview_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +%-------------------------------------------------------------------------- +function popupmenu_measurement_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + +%-------------------------------------------------------------------------- +function popupmenu_mapstyle_CreateFcn(hObject, eventdata, handles) + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +%-------------------------------------------------------------------------- +function checkbox_realtime_Callback(hObject, eventdata, handles) +if get(hObject, 'Value') + lat = handles.latency; + if isempty(lat) + msgboxText = 'You must specify a latency vector first.'; + title = 'EStudio: f_scalplotadvancedGUI input'; + errorfound(msgboxText, title); + return + end +% lat = str2num(lat); + T = unique_bc2(diff(lat)); + if isempty(T) + msgboxText = 'You must specify a latency vector first.'; + title = 'EStudio: f_scalplotadvancedGUI input'; + errorfound(msgboxText, title); + return + end + if length(T)>1 + msgboxText = ['The latency vector does not have a fixed step to determine its periodicity.\n\n'... + 'You may use colon notation, e.g. start:step:end, to specify your latency vector.\n'... + 'This may work better to generate the time of each frame.']; + title = 'EStudio: f_scalplotadvancedGUI input'; + errorfound(sprintf(msgboxText), title); + return + end + f = round(1/(T/1000)); + set(handles.edit_fps, 'String', num2str(f)); + set(handles.edit_fps,'Enable', 'off') +else + set(handles.edit_fps,'Enable', 'on') +end + + + + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +% plotset = evalin('base', 'plotset'); +% plotset.pscalp = []; +handles.output = {}; + +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + %The GUI is still in UIWAIT, us UIRESUME +% plotset = evalin('base', 'plotset'); +% plotset.pscalp = []; + handles.output = {}; + %Update handles structure + guidata(hObject, handles); + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes on button press in checkbox_binnumber. +function checkbox_binnumber_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_binnumber (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_binnumber + + +% --- Executes on button press in checkbox_bindescription. +function checkbox_bindescription_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_bindescription (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_bindescription + + +% --- Executes on button press in checkbox_latency. +function checkbox_latency_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_latency (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_latency + + +% --- Executes on button press in checkbox_tvalue. +function checkbox_tvalue_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_tvalue (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_tvalue + + +% --- Executes on button press in checkbox_maximize. +function checkbox_maximize_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_maximize (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_maximize + + +% --- Executes on button press in checkbox_electrodes. +function checkbox_electrodes_Callback(hObject, eventdata, handles) + +is2Dmap = handles.is2Dmap; + +if get(hObject, 'value') + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'on') + set(handles.radiobutton_showelabel,'Enable', 'on') + + set(handles.checkbox_3Delec,'Enable', 'on') +else + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 0) + set(handles.checkbox_3Delec,'Value', 0) + + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'off') + set(handles.radiobutton_showelabel,'Enable', 'off') + set(handles.checkbox_3Delec,'Enable', 'off') +end + + + + +% --- Executes on button press in radiobutton_excludepoints. +function radiobutton_excludepoints_Callback(hObject, eventdata, handles) +% if get(hObject, 'value') +% +% else +% +% end + + +% --- Executes on button press in checkbox_3Delec. +function checkbox_3Delec_Callback(hObject, eventdata, handles) +if get(hObject, 'Value') + %set(handles.checkbox_electrodes,'Value', 0) + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_showelabel,'Value', 0) + + %set(handles.checkbox_electrodes,'Enable', 'off') + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'off') + set(handles.radiobutton_showelabel,'Enable', 'off') +else + %set(handles.radiobutton_excludepoints,'Value', 0) + %set(handles.radiobutton_showenumber,'Value', 0) + %set(handles.radiobutton_showelabel,'Value', 0) + + %set(handles.checkbox_electrodes,'Enable', 'off') + set(handles.radiobutton_excludepoints,'Enable', 'off') + set(handles.radiobutton_showenumber,'Enable', 'on') + set(handles.radiobutton_showelabel,'Enable', 'on') +end + + +% --- Executes on button press in radiobutton_showelabel. +function radiobutton_showelabel_Callback(hObject, eventdata, handles) + +if get(hObject, 'value') + set(handles.radiobutton_showenumber,'Value', 0) + set(handles.radiobutton_excludepoints,'Enable', 'on') +else + %set(handles.radiobutton_showelabel,'Value', 1) + if ~get(handles.radiobutton_showelabel,'Value') + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_excludepoints,'Enable', 'off') + end +end + + +% --- Executes on button press in radiobutton_showenumber. +function radiobutton_showenumber_Callback(hObject, eventdata, handles) +if get(hObject, 'value') + set(handles.radiobutton_showelabel,'Value', 0) + set(handles.radiobutton_excludepoints,'Enable', 'on') +else + %set(handles.radiobutton_showenumber,'Value', 1 + if ~get(handles.radiobutton_showenumber,'Value') + set(handles.radiobutton_excludepoints,'Value', 0) + set(handles.radiobutton_excludepoints,'Enable', 'off') + end +end + + + +% --- Executes during object creation, after setting all properties. +function checkbox_maximize_CreateFcn(hObject, eventdata, handles) +% hObject handle to checkbox_maximize (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + + +% --- Executes during object creation, after setting all properties. +function checkbox_electrodes_CreateFcn(hObject, eventdata, handles) +% hObject handle to checkbox_maximize (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called diff --git a/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.fig b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.fig new file mode 100755 index 00000000..cde446d6 Binary files /dev/null and b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.fig differ diff --git a/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.m b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.m new file mode 100755 index 00000000..894b172c --- /dev/null +++ b/studio_functions/GUIs/ERP Tab/geterpvaluesparasGUI2.m @@ -0,0 +1,1212 @@ +% +% Author: Javier Lopez-Calderon & Steven Luck +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function varargout = geterpvaluesparasGUI2(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @geterpvaluesparasGUI2_OpeningFcn, ... + 'gui_OutputFcn', @geterpvaluesparasGUI2_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +%-------------------------------------------------------------------------- +function geterpvaluesparasGUI2_OpeningFcn(hObject, eventdata, handles, varargin) +% Choose default command line output for geterpvaluesparasGUI2 +handles.output = []; +handles.indxline = 1; +handles.listname = []; +handles.listb = ''; +handles.indxlistb = []; +handles.listch = ''; +handles.indxlistch = []; +handles.owfp = 0; % over write file permission. 1:allowed; 0:do not overwrite w/o asking. +handles.rise = 1; + +try + def = varargin{1}; + handles.def = def; +catch + def = {'fpeaklat', 3, 0, 1, 3, 0, 0.5, 0, 0, 1, 1, 1}; + handles.def = def; +end + + +try + ERP = varargin{2}; + if isstruct(ERP) + handles.xmin = ERP.xmin; + handles.xmax = ERP.xmax; + handles.srate = ERP.srate; + + else + handles.xmin = []; + handles.xmax = []; + handles.srate = []; + + end + datatype =ERP.datatype; +catch + ERP = []; + handles.xmin = []; + handles.xmax = []; + handles.srate = []; + handles.nsets = []; + datatype = 'ERP'; +end + +handles.datatype = datatype; +if strcmpi(datatype, 'ERP') + kktime = 1000; +else + return; +end +handles.kktime = kktime; + + +handles.frac = []; +handles.intfactor = []; + +% +% Color GUI +handles = painterplabstudio(handles); +% +% % +% % Set font size +% % +handles = setfonterplabestudio(handles); + +% Update handles structure +guidata(hObject, handles); + +setall(hObject, eventdata, handles) + +% help +% helpbutton + +% viewer +% viewerbutton + +% +% Set Measurement menu +% +% set(handles.listbox_erpnames, 'Value',1) +% set(handles.popupmenu_measurement, 'Backgroundcolor',[1 1 0.8]) +% set(handles.popupmenu_pol_amp, 'Backgroundcolor',[1 1 0.8]) +% set(handles.popupmenu_samp_amp, 'Backgroundcolor',[1 1 0.8]) +% set(handles.popupmenu_locpeakreplacement, 'Backgroundcolor',[1 1 0.8]) +% set(handles.popupmenu_fracreplacement, 'Backgroundcolor',[1 1 0.8]) +% set(handles.popupmenu_precision, 'Backgroundcolor',[1 1 0.8]) +%set(handles.text_fraca,'String', {''}); +%set(handles.text_fa3,'String',{''}); +drawnow + +% UIWAIT makes geterpvaluesparasGUI2 wait for user response (see UIRESUME) +uiwait(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function varargout = geterpvaluesparasGUI2_OutputFcn(hObject, eventdata, handles) +varargout{1} = handles.output; +% The figure can be deleted now +delete(handles.gui_chassis); +pause(0.1) + +%-------------------------------------------------------------------------- +function menupeakoff(hObject, eventdata, handles) +set(handles.popupmenu_pol_amp, 'Enable', 'off') +set(handles.text_fa1, 'Enable', 'off') +set(handles.popupmenu_samp_amp, 'Enable', 'off') +set(handles.text_samp, 'Enable', 'off') +set(handles.text12, 'Enable', 'off') +set(handles.popupmenu_locpeakreplacement, 'Enable', 'off') +set(handles.text_fa1, 'Enable', 'off') +set(handles.text_fa2, 'Enable', 'off') +set(handles.text_fa3, 'Enable', 'off') +set(handles.text_fa4, 'Enable', 'off') + +%-------------------------------------------------------------------------- +function menupeakon(hObject, eventdata, handles) +set(handles.popupmenu_pol_amp, 'Enable', 'off') +set(handles.text_fa1, 'Enable', 'on') +set(handles.popupmenu_samp_amp, 'Enable', 'on') +set(handles.text_samp, 'Enable', 'on') +set(handles.text12, 'Enable', 'on') +set(handles.popupmenu_locpeakreplacement, 'Enable', 'on') +set(handles.text_fa1, 'Enable', 'on') +set(handles.text_fa2, 'Enable', 'on') + + + +%-------------------------------------------------------------------------- +function menufareaoff(hObject, eventdata, handles) +set(handles.text_fraca,'Enable','off') +set(handles.popupmenu_fraca,'String', {''}) +set(handles.popupmenu_fraca,'Enable','off') +set(handles.text_punit,'Enable','off') +set(handles.popupmenu_fracreplacement,'Enable','off') +set(handles.text19, 'Enable', 'off') +set(handles.text_fa3, 'Enable', 'off') +set(handles.text_fa3,'String',{''}); +set(handles.text_fa4, 'Enable', 'off') +set(handles.popupmenu_fraca, 'Enable', 'off') +set(handles.popupmenu_rise, 'Enable', 'off') +set(handles.text_fraca,'String', {''}); + +%-------------------------------------------------------------------------- +function menufareaon(hObject, eventdata, handles) +set(handles.text_fraca,'Enable','on') +set(handles.text_punit,'Enable','on') +set(handles.popupmenu_fraca,'Enable','on') +set(handles.popupmenu_fracreplacement,'Enable','on') +set(handles.text19, 'Enable', 'on') +set(handles.text_fa3, 'Enable', 'on') +set(handles.text_fa3,'String',{'Measure'}); +set(handles.text_fa4, 'Enable', 'on') +set(handles.popupmenu_fraca, 'Enable', 'on') +set(handles.popupmenu_rise, 'Enable', 'on') + +fracarray = 0:100; +set(handles.popupmenu_fraca,'String', cellstr(num2str(fracarray'))) +frac = handles.frac; +if isempty(frac) + frac = 0.50; +end +fracpos = round(frac*100)+1; +set(handles.popupmenu_fraca,'Value', fracpos) + +set(handles.text19, 'Enable', 'on') + +%-------------------------------------------------------------------------- +function pushbutton_cancel_Callback(hObject, eventdata, handles) +handles.output = []; +% Update handles structure +guidata(hObject, handles); +uiresume(handles.gui_chassis); + +%-------------------------------------------------------------------------- +function pushbutton_run_Callback(hObject, eventdata, handles) +datatype = handles.datatype; +kktime = handles.kktime; +if kktime==1 % sec or Hz + TimeOp = 0; +else % ms + TimeOp = 1; +end + +xmin = handles.xmin; +xmax = handles.xmax; + +srate = handles.srate; + + +% Send to workspace +% +send2ws = get(handles.checkbox_send2ws, 'Value'); % 0:no; 1:yes +owfp = handles.owfp; % over write file permission +appendfile = 0; + + +% if ~strcmp(chanArraystr, '') && ~isempty(chanArraystr) && ~strcmp(latestr, '') && ~isempty(latestr) && ~strcmp(binArraystr, '') && ~isempty(binArraystr) +% binArray = str2num(binArraystr); +% chanArray = str2num(chanArraystr); +% late = str2num(latestr); +% nlate = length(late); +% + + +polpeak = []; +sampeak = []; +% coi = 0; % ignore overlapped components +locpeakrep = 0; +frac = []; +fracmearep = 0; +measure_option = get(handles.popupmenu_measurement, 'Value'); +areatype = get(handles.popupmenu_areatype,'Value'); % 1=total ; 2=pos; 3=neg + + + +switch measure_option + case 1 % instabl + % if nlate~=1 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define only one frequency'; + % else + % msgboxText = 'You must define only one latency'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + moption = 'instabl'; + fprintf('\nInstantaneous amplitude measurement in progress...\n'); + case 2 % meanbl + % if nlate~=2 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define two frequencies'; + % else + % msgboxText = 'You must define two latencies'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + moption = 'meanbl'; + fprintf('\nMean amplitude measurement in progress...\n'); + case 3 % peakampbl + % if nlate~=2 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define two frequencies'; + % else + % msgboxText = 'You must define two latencies'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + moption = 'peakampbl'; + polpeak = 2-get(handles.popupmenu_pol_amp,'Value'); + sampeak = get(handles.popupmenu_samp_amp,'Value') - 1; + locpeakrep = 2-get(handles.popupmenu_locpeakreplacement,'Value'); + + % cc1 = late(1)-sample2time(TimeOp, sampeak, srate) < xmin*kktime; + % ccdiff = abs((late(1)-sample2time(TimeOp, sampeak, srate)) - xmin*kktime); + % cc2 = time2sample(TimeOp, ccdiff, srate)>2; + % cc3 = late(2)+sample2time(TimeOp, sampeak, srate)>xmax*kktime; + % ccdiff = abs((late(2)+sample2time(TimeOp, sampeak, srate)) - xmax*kktime); + % cc4 = time2sample(TimeOp, ccdiff, srate)>2; + + % if (cc1 && cc2) || (cc3 && cc4) + % msgboxText = msgboxText4peak; + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText,sampeak, sampeak, sampeak, xmin*kktime, xmax*kktime, xmin*kktime+sample2time(TimeOp, sampeak,srate), xmax*kktime-sample2time(TimeOp, sampeak,srate)), title); + % return + % end + fprintf('\nLocal peak measurement in progress...\n'); + case 4 % peaklatbl + % if nlate~=2 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define two frequencies'; + % else + % msgboxText = 'You must define two latencies'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + moption = 'peaklatbl'; + polpeak = 2-get(handles.popupmenu_pol_amp,'Value'); + sampeak = get(handles.popupmenu_samp_amp,'Value') - 1; + locpeakrep = 2-get(handles.popupmenu_locpeakreplacement,'Value'); + + % cc1 = late(1)-sample2time(TimeOp, sampeak, srate) < xmin*kktime; + % ccdiff = abs((late(1)-sample2time(TimeOp, sampeak, srate)) - xmin*kktime); + % cc2 = time2sample(TimeOp, ccdiff, srate)>2; + % cc3 = late(2)+sample2time(TimeOp, sampeak, srate)>xmax*kktime; + % ccdiff = abs((late(2)+sample2time(TimeOp, sampeak, srate)) - xmax*kktime); + % cc4 = time2sample(TimeOp, ccdiff, srate)>2; + + % if (cc1 && cc2) || (cc3 && cc4) + % msgboxText = msgboxText4peak; + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText,sampeak, sampeak, sampeak, xmin*kktime, xmax*kktime, xmin*kktime+sample2time(TimeOp, sampeak,srate), xmax*kktime-sample2time(TimeOp, sampeak,srate)), kktime); + % return + % end + if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + fprintf('\nLocal peak frequency measurement in progress...\n'); + else + fprintf('\nLocal peak latency measurement in progress...\n'); + end + case 5 % fpeaklat + % if nlate~=2 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define two frequencies'; + % else + % msgboxText = 'You must define two latencies'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + set(handles.text_fraca,'String', 'Fractional Peak') + moption = 'fpeaklat'; + frac = (get(handles.popupmenu_fraca,'Value') - 1)/100; % 0 to 1 + polpeak = 2-get(handles.popupmenu_pol_amp,'Value'); + sampeak = get(handles.popupmenu_samp_amp,'Value') - 1; + locpeakrep = 2-get(handles.popupmenu_locpeakreplacement,'Value'); + fracmearep = 2-get(handles.popupmenu_fracreplacement,'Value'); + + % cc1 = late(1)-sample2time(TimeOp, sampeak, srate) < xmin*kktime; + % ccdiff = abs((late(1)-sample2time(TimeOp, sampeak, srate)) - xmin*kktime); + % cc2 = time2sample(TimeOp, ccdiff, srate)>2; + % cc3 = late(2)+sample2time(TimeOp, sampeak, srate)>xmax*kktime; + % ccdiff = abs((late(2)+sample2time(TimeOp, sampeak, srate)) - xmax*kktime); + % cc4 = time2sample(TimeOp, ccdiff, srate)>2; + + % if (cc1 && cc2) || (cc3 && cc4) + % msgboxText = msgboxText4peak; + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText,sampeak, sampeak, sampeak, xmin*kktime, xmax*kktime, xmin*kktime+sample2time(TimeOp, sampeak,srate), xmax*kktime-sample2time(TimeOp, sampeak,srate)), title); + % return + % end + if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + fprintf('\nFractional Peak Frequency measurement in progress...\n'); + else + fprintf('\nFractional Peak Latency measurement in progress...\n'); + end + case 6 % inte/area value (fixed latencies) + % if nlate~=2 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define two frequencies'; + % else + % msgboxText = 'You must define two latencies'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + switch areatype + case 1 + moption = 'areat'; + fprintf('\nTotal area measurement in progress...\n'); + case 2 + moption = 'ninteg'; + fprintf('\nNumerical integration in progress...\n'); + case 3 + moption = 'areap'; + fprintf('\nPositive area measurement in progress...\n'); + case 4 + moption = 'arean'; + fprintf('\nNegative area measurement in progress...\n'); + end + + case 7 % inte/area value (auto latencies) + if ~strcmpi(datatype, 'ERP') + msgboxText = 'Sorry. This type of measurement is not allowed for Power Spectrum data'; + title = 'ERPLAB: geterpvaluesGUI() -> invalid input'; + errorfound(sprintf(msgboxText), title); + return + end + % if nlate~=1 + % %if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % % msgboxText = 'You must define only one frequency'; + % %else + % msgboxText = 'You must define only one latency'; + % %end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + switch areatype + case 1 + moption = 'areazt'; + fprintf('\nTotal area measurement in progress...\n'); + case 2 + moption = 'nintegz'; + fprintf('\nNumerical integration (automatic limits) in progress...\n'); + case 3 + moption = 'areazp'; + fprintf('\nPositive area measurement (automatic limits) in progress...\n'); + case 4 + moption = 'areazn'; + fprintf('\nNegative area measurement (automatic limits) in progress...\n'); + end + + case 8 % fractional inte/area latency + % if nlate~=2 + % if strcmpi(datatype, 'TFFT') || strcmpi(datatype, 'EFFT') % Hz + % msgboxText = 'You must define two frequencies'; + % else + % msgboxText = 'You must define two latencies'; + % end + % title = 'ERPLAB: measurement window'; + % errorfound(sprintf(msgboxText), title); + % return + % end + + set(handles.text_fraca,'String', 'Fractional Area') + frac = (get(handles.popupmenu_fraca,'Value') - 1)/100; % 0 to 1 + if strcmpi(datatype, 'ERP') + meawordx = 'Latency'; + else + meawordx = 'Frequency'; + end + switch areatype + case 1 + moption = 'fareatlat'; + fprintf('\nFractional Total Area %s measurement in progress...\n', meawordx); + case 2 + moption = 'fninteglat'; + fprintf('\nFractional Total Area %s measurement in progress...\n', meawordx); + case 3 + moption = 'fareaplat'; + fprintf('\nFractional Positive Area %s measurement in progress...\n', meawordx); + + case 4 + moption = 'fareanlat'; + fprintf('\nFractional Negative Area %s measurement in progress...\n', meawordx); + otherwise + error('wrong area type.') + end + fracmearep = 1+ (-1)^(get(handles.popupmenu_fracreplacement,'Value')); % when 1 means 0, when 2 means 2 +end + +% + + +dig = get(handles.popupmenu_precision, 'Value'); +binlabop = get(handles.checkbox_binlabel,'Value'); % bin label option for table +inclate = get(handles.checkbox_include_used_latencies, 'Value'); +intfactor = get(handles.popupmenu_interpofactor, 'Value'); + +peakonset = get(handles.popupmenu_rise, 'Value'); % axs - get onset from menu value + +% +% Output +% +outstr = {moption, dig, binlabop, polpeak, sampeak, locpeakrep, frac, fracmearep,... + send2ws, inclate, intfactor, peakonset}; +handles.output = outstr; + +guidata(hObject, handles); +uiresume(handles.gui_chassis); + + +%-------------------------------------------------------------------------- +function popupmenu_precision_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_precision_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +% ------------------------------------------------------------------------- +function pushbutton_run_CreateFcn(hObject, eventdata, handles) + + + +%-------------------------------------------------------------------------- +function popupmenu_pol_amp_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_pol_amp_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_samp_amp_Callback(hObject, eventdata, handles) +kktime = handles.kktime; +srate = handles.srate; +pnts = get(handles.popupmenu_samp_amp,'Value')-1; +intfactor = get(handles.popupmenu_interpofactor,'Value'); +if isempty(srate) + msecstr = sprintf('pnts ( ? ms)'); +else + msecstr = sprintf('pnts (%4.1f ms)', (pnts/srate*intfactor)*kktime); +end +set(handles.text_samp,'String',msecstr) + +%-------------------------------------------------------------------------- +function popupmenu_samp_amp_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_measurement_Callback(hObject, eventdata, handles) +meamenu = get(handles.popupmenu_measurement, 'String'); +currentm = get(handles.popupmenu_measurement, 'Value'); +if currentm==7 + mnamex = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'; + question = [ '%s\n\nThis tool is still in alpha phase.\n'... + 'Use it under your responsibility.']; + title = 'ERPLAB: Overwriting Confirmation'; + BackERPLABcolor = [1 0.9 0.3]; % yellow + oldcolor = get(0,'DefaultUicontrolBackgroundColor'); + set(0,'DefaultUicontrolBackgroundColor',BackERPLABcolor) + button = questdlg(sprintf(question, mnamex), title,'OK','OK'); + set(0,'DefaultUicontrolBackgroundColor',oldcolor) +end + +areatype = get(handles.popupmenu_areatype,'Value'); +% formatout = get(handles.popupmenu_formatout,'Value'); +version = geterplabversion; +set(handles.gui_chassis,'Name', ['ERPLAB ' version ' - ERP Measurements GUI - ' meamenu{currentm}]) + +datatype = handles.datatype; +if strcmpi(datatype, 'ERP') + meawordx = 'latenc'; +else + meawordx = 'frequenc'; +end + +% +% NEW MENU +% + +% 1 = 'Instantaneous amplitude', +% 2 = 'Mean amplitude between two fixed latencies',... +% 3 = 'Peak amplitude' +% 4 = 'Peak latency' +% 5 = 'Fractional Peak latency',... +% 6 = 'Numerical integration/Area between two fixed latencies' +% 7 = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'... +% 8 = 'Fractional Area latency' + +switch currentm + case 1 % 'Instantaneous amplitude' + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + set(handles.text_punit,'String','% of peak') + set(handles.text_tip_inputlat, 'String',['(use one ' meawordx 'y)']); + set(handles.popupmenu_areatype,'Enable','off') + case {2,6} % mean, area, integral between fixed latencies + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + set(handles.text_punit,'String','% of peak') + set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']); + if currentm==6 + set(handles.popupmenu_areatype,'Enable','on') + else + set(handles.popupmenu_areatype,'Enable','off') + end + case {3,4} % 'Peak amplitude', 'Peak latency' + menupeakon(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + set(handles.text_punit,'String','% of peak') + % set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']); + set(handles.popupmenu_areatype,'Enable','off') + set(handles.popupmenu_fracreplacement, 'String', {'fractional absolute peak','"not a number" (NaN)'}); + case 5 % 'Fractional Peak latency' + menupeakon(hObject, eventdata, handles) + menufareaon(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + fracpos = round(frac*100)+1; + set(handles.popupmenu_fraca,'Value', fracpos) + set(handles.text_punit,'String','% of peak') + % set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']); + set(handles.text_fraca,'String', 'Fractional Peak'); + set(handles.popupmenu_areatype,'Enable','off'); + set(handles.popupmenu_fracreplacement, 'String', {'"not a number" (NaN)','show error message'}); + case {7} % area, integral automatic limits + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', '--------') + set(handles.popupmenu_rise, 'Value', 1) + set(handles.popupmenu_rise, 'Enable', 'off') + set(handles.text_punit,'String','% of area') + % set(handles.text_tip_inputlat, 'String',['(use one "seed" ' meawordx 'y)']); + if currentm==7 + set(handles.popupmenu_areatype,'Enable','on') + else + set(handles.popupmenu_areatype,'Enable','off') + end + case 8 % 'Fractional Area latency' + menupeakoff(hObject, eventdata, handles) + menufareaon(hObject, eventdata, handles) + %punit_str = get(handles.text_punit, 'String'); + set(handles.popupmenu_rise, 'String', '--------') + set(handles.popupmenu_rise, 'Value', 1) + set(handles.popupmenu_rise, 'Enable', 'off') + set(handles.text_punit,'String','% of area') + set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']); + set(handles.text_fraca,'String', 'Fractional Area') + set(handles.popupmenu_areatype,'Enable','on') + set(handles.popupmenu_fracreplacement, 'String', {'show error message','"not a number" (NaN)'}); + otherwise % 'test' + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.text_tip_inputlat, 'String',['(use two ' meawordx 'ies)']); +end + +%-------------------------------------------------------------------------- +function popupmenu_measurement_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_locpeakreplacement_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_locpeakreplacement_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function uipanel9_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel1_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel2_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function pushbutton_cancel_CreateFcn(hObject, eventdata, handles) + +% %-------------------------------------------------------------------------- +function text_tip_inputlat_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel4_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel6_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel8_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel12_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function uipanel13_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +% function radiobutton_erpset_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +% function radiobutton_folders_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function setall(hObject, eventdata, handles) + +% ALLERP = handles.ALLERP; +% if isstruct(ALLERP) +% nsets = length(ALLERP); +% nbin = ALLERP(1).nbin; +% nchan = ALLERP(1).nchan; +% else +% nsets = 0; +% nbin = 1; +% nchan = 1; +% end +datatype = handles.datatype; +set(handles.popupmenu_samp_amp,'String',cellstr(num2str([0:40]'))) +set(handles.popupmenu_precision,'String', num2str([1:6]')) +kktime = handles.kktime; + + + +set(handles.popupmenu_rise,'BackgroundColor',[1 1 1]) +set(handles.popupmenu_fraca,'BackgroundColor',[1 1 1]) +set(handles.popupmenu_fracreplacement,'BackgroundColor',[1 1 1]) +set(handles.popupmenu_locpeakreplacement,'BackgroundColor',[1 1 1]) +set(handles.popupmenu_areatype,'BackgroundColor',[1 1 1]) + +set(handles.popupmenu_interpofactor,'BackgroundColor',[1 1 1]) +set(handles.popupmenu_precision,'BackgroundColor',[1 1 1]) + + +% +% NEW MENU +% + +% 1 = 'Instantaneous amplitude', +% 2 = 'Mean amplitude between two fixed latencies',... +% 3 = 'Peak amplitude' +% 4 = 'Peak latency' +% 5 = 'Fractional Peak latency',... +% 6 = 'Numerical integration/Area between two fixed latencies' +% 7 = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'... +% 8 = 'Fractional Area latency' + +% +% New Are type menu +% +% 1 = 'Rectified area (negative values become positive)' +% 2 = 'Numerical integration (negative substracted from positive)' +% 3 = 'Only positive area' +% 4 = 'Only negative area' +% + +if strcmpi(datatype, 'ERP') + measurearray = {'Instantaneous amplitude',... + 'Mean amplitude between two fixed latencies',... + 'Peak amplitude',... + 'Peak latency',... + 'Fractional Peak latency',... + 'Numerical integration/Area between two fixed latencies',... + 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'... + 'Fractional Area latency'}; +else + measurearray = {'Instantaneous power',... + 'Mean power between two fixed frequencies',... + 'Peak power',... + 'Peak frequency',... + 'Fractional Peak frequency',... + 'Numerical integration/Area between two fixed frequencies',... + '------------------------------------------------------'... + 'Fractional Area frequency'}; +end +set(handles.popupmenu_measurement, 'String', measurearray,'Enable','off'); +set(handles.popupmenu_locpeakreplacement, 'String', {'absolute peak','"not a number" (NaN)','show error message'}); +set(handles.popupmenu_fracreplacement, 'String', {'closest value','"not a number" (NaN)','show error message'}); + + +% +% Type of Area +% +% areatype = {'Total area', 'Only positive area', 'Only negative area'}; +areatype = {'Rectified area (negative values become positive)', 'Numerical integration (area for negatives substracted from area for positives)',... + 'Area for positive waveforms (negative values will be zeroed)', 'Area for negative waveforms (positive values will be zeroed)'}; +set(handles.popupmenu_areatype, 'String', areatype); + +% Interpolation factor +set(handles.popupmenu_interpofactor, 'String', cellstr(num2str([1:10]'))') + +% +% GUI's working memory +% +def = handles.def; +% def{:} + +if ~isempty(def) + op = def{1}; % option: type of measurement ---> instabl, meanbl, peakampbl, peaklatbl, area, areaz, or errorbl. + dig = def{2}; %Resolution + binlabop = def{3}; % 0: bin# as bin label for table, 1 bin label + polpeak = def{4}; % local peak polarity + sampeak = def{5}; % number of samples (one-side) for local peak detection criteria + locpeakrep = def{6}; % 1 abs peak , 0 Nan + frac = def{7}; + fracmearep = def{8}; % def{19}; NaN + send2ws = def{9}; % 1 send to ws, 0 dont do + inclate = def{10}; + intfactor = def{11}; + if isempty(sampeak) + sampeak = 3; + end + +else + + %%def = {'fareaplat', 3, 0, 1, 3, 0, 0.5, NaN, 0, 0, 1, 1}; + op = 'meanbl'; % option: type of measurement ---> instabl, meanbl, peakampbl, peaklatbl, area, areaz, or errorbl. + dig = 3; %Resolution + binlabop = 0; % 0: bin# as bin label for table, 1 bin label + polpeak = 1; % local peak polarity + sampeak = 3; % number of samples (one-side) for local peak detection criteria + locpeakrep = 0; % 1 abs peak , 0 Nan + frac = 0.5; + fracmearep = 0; % def{19}; NaN + send2ws = 0; % 1 send to ws, 0 dont do + inclate = 1; + intfactor = 1; +end +if isempty(frac) + frac = 0.50; +end + +% +% New menu +% +[tfm, indxmeaX] = ismember_bc2({op}, {'instabl', 'meanbl', 'peakampbl', 'peaklatbl', 'fpeaklat',... + 'areat', 'areap', 'arean','areazt','areazp','areazn','fareatlat', 'fninteglat',... + 'fareaplat','fareanlat', 'ninteg','nintegz' } ); + +% +% fix index for menu +% +areatype=1; % 1=total; 2=integral; 3=pos; 4= neg +fracmenuindex = 2-fracmearep; + +if ismember(indxmeaX,[6 7 8 16]) + indxmea = 6; + areatype = find(indxmeaX==[6 16 7 8]); % 1,2,3,4 +elseif ismember(indxmeaX,[9 10 11 17]) + areatype = find(indxmeaX==[9 17 10 11]); % 1,2,3,4 + + if strcmpi(datatype, 'ERP') + indxmea = 7; + else + indxmea = 1; + end +elseif ismember(indxmeaX,[12 13 14 15]) + areatype = find(indxmeaX==[12 13 14 15]); % 1,2,3,4 + indxmea = 8; + fracmenuindex = round(2^(fracmearep/2)); % when 0 means 1, when 2 means 2; +else + indxmea = indxmeaX; +end + +% +% Type of output +% +% 1 = one measurement per line; 0 = one erpset per line +% +set(handles.checkbox_include_used_latencies, 'Value', inclate); + +set(handles.checkbox_send2ws, 'Value', send2ws); +set(handles.checkbox_binlabel, 'Value', binlabop); %0: use bin number as binlabel; 1:use bin descr as binlabel + +% interpolation +set(handles.popupmenu_interpofactor, 'Value', intfactor); + +% +% Measurements +% +set(handles.popupmenu_measurement,'value', indxmea); +set(handles.popupmenu_fracreplacement,'value', fracmenuindex); + +% +% NEW MENU (indxmea) +% +% 1 = 'Instantaneous amplitude', +% 2 = 'Mean amplitude between two fixed latencies',... +% 3 = 'Peak amplitude' +% 4 = 'Peak latency' +% 5 = 'Fractional Peak latency',... +% 6 = 'Numerical integration/Area between two fixed latencies' +% 7 = 'Numerical integration/Area between two (automatically detected) zero-crossing latencies'... +% 8 = 'Fractional Area latency' + +set(handles.popupmenu_samp_amp,'value',sampeak+1); + +switch indxmea + case 1 % 'Instantaneous amplitude' + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + set(handles.text_punit,'String','% of peak') + set(handles.popupmenu_areatype,'Enable','off') + % set(handles.text_tip_inputlat, 'String',['(use one ' mwordx 'y)']); + case {2,6} % mean, area, integral between fixed latencies + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + set(handles.text_punit,'String','% of peak') + if indxmea==6 + set(handles.popupmenu_areatype,'Value',areatype) + end + set(handles.popupmenu_areatype,'Enable','off') + + case {3,4} % 'Peak amplitude', 'Peak latency' + menupeakon(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + set(handles.text_punit,'String','% of peak') + % set(handles.text_tip_inputlat, 'String',['(use two ' mwordx 'ies)']); + set(handles.popupmenu_pol_amp,'Value',2-polpeak,'Enable','off') + %set(handles.popupmenu_samp_amp,'value',sampeak+1); + set(handles.popupmenu_locpeakreplacement,'value',2-locpeakrep); + set(handles.popupmenu_areatype,'Enable','off'); + % set(handles.popupmenu_fracreplacement, 'String', {'fractional absolute peak','"not a number" (NaN)'}); + case 5 % 'Fractional Peak latency' + menupeakon(hObject, eventdata, handles) + menufareaon(hObject, eventdata, handles) + set(handles.popupmenu_rise, 'String', {'(pre-peak) onset','(post-peak) offset'}) + set(handles.popupmenu_rise, 'Value', 1) + fracpos = round(frac*100)+1; + set(handles.popupmenu_fraca,'Value', fracpos) + set(handles.text_punit,'String','% of peak') + % set(handles.text_tip_inputlat, 'String',['(use two ' mwordx 'ies)']); + set(handles.text_fraca,'String', 'Fractional Peak') + set(handles.popupmenu_pol_amp,'Value',2-polpeak,'Enable','off') + %set(handles.popupmenu_samp_amp,'value',sampeak+1); + set(handles.popupmenu_locpeakreplacement,'value',2-locpeakrep); + set(handles.popupmenu_fracreplacement,'value',2-fracmearep); + set(handles.popupmenu_areatype,'Enable','off'); + % set(handles.popupmenu_fracreplacement, 'String', {'"not a number" (NaN)','show error message'}); + + if strcmpi(fracmearep,'NaN') + set(handles.popupmenu_fracreplacement, 'Value', 1); + else + set(handles.popupmenu_fracreplacement, 'Value', 2); + end + case 7 % area and integral with auto limits + menupeakoff(hObject, eventdata, handles); + menufareaoff(hObject, eventdata, handles); + set(handles.popupmenu_rise, 'String', '--------'); + set(handles.popupmenu_rise, 'Value', 1); + set(handles.popupmenu_rise, 'Enable', 'off'); + set(handles.popupmenu_areatype,'Enable','on'); + set(handles.popupmenu_areatype,'Value',areatype); + + case 8 % fractional area + menupeakoff(hObject, eventdata, handles) + menufareaon(hObject, eventdata, handles) + fracpos = round(frac*100)+1; + set(handles.popupmenu_rise, 'String', '--------') + set(handles.popupmenu_rise, 'Value', 1) + set(handles.popupmenu_rise, 'Enable', 'off') + set(handles.text_punit,'String','% of area') + set(handles.popupmenu_fraca,'Value', fracpos); + + + set(handles.text_fa3,'Enable', 'on') + set(handles.text_fraca,'String', 'Fractional Area') + set(handles.popupmenu_areatype,'Enable','on') + set(handles.popupmenu_areatype,'Value',areatype) + set(handles.popupmenu_fracreplacement, 'String', {'show error message','"not a number" (NaN)'}); + if strcmpi(fracmearep,'NaN') + set(handles.popupmenu_fracreplacement, 'Value', 2); + else + set(handles.popupmenu_fracreplacement, 'Value', 1); + end + + otherwise + menupeakoff(hObject, eventdata, handles) + menufareaoff(hObject, eventdata, handles) +end + +set(handles.popupmenu_precision, 'Value', dig) +set(handles.checkbox_send2ws, 'Value', send2ws); + +srate = handles.srate; +try + msecstr = sprintf('pnts (%4.1f ms)', (sampeak/srate*intfactor)*kktime); +catch + msecstr = 'pnts (... ms)'; +end + +set(handles.text_samp,'String',msecstr) + +% +% Name & version +% +meamenu = get(handles.popupmenu_measurement, 'String'); +currentm = get(handles.popupmenu_measurement, 'Value'); +erplab_studio_default_values; +version = erplabstudiover; +set(handles.gui_chassis,'Name', ['EStudio ' version ' - ERP Measurement Tool > Type > Option']) +handles.frac = frac; + + +% Update handles structure +guidata(hObject, handles); + +%-------------------------------------------------------------------------- +function gui_chassis_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function checkbox_send2ws_Callback(hObject, eventdata, handles) + + + +%-------------------------------------------------------------------------- +function radiobutton_f0_1erp_per_line_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_f1_1mea_per_line,'Value',0) + %set(handles.edit_label_mea,'Enable', 'off') +else + set(hObject,'Value',1) +end + +%-------------------------------------------------------------------------- +function radiobutton_f1_1mea_per_line_Callback(hObject, eventdata, handles) +if get(hObject,'Value') + set(handles.radiobutton_f0_1erp_per_line,'Value',0) + % set(handles.edit_label_mea,'Enable', 'on') +else + set(hObject,'Value',1) +end + + +%-------------------------------------------------------------------------- +function popupmenu_interpofactor_Callback(hObject, eventdata, handles) +kktime = handles.kktime; +srate = handles.srate; +pnts = get(handles.popupmenu_samp_amp,'Value')-1; +intfactor = get(handles.popupmenu_interpofactor,'Value'); +if isempty(srate) + msecstr = sprintf('pnts ( ? ms)'); +else + msecstr = sprintf('pnts (%4.1f ms)', (pnts/srate*intfactor)*kktime); +end +set(handles.text_samp,'String',msecstr) + +%-------------------------------------------------------------------------- +function popupmenu_interpofactor_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function edit10_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function edit10_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_fraca_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_fraca_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_fracreplacement_Callback(hObject, eventdata, handles) +% if get(hObject,'Value')==1 +% set(handles. popupmenu_fracreplacement,'Value',2) +% end + +%-------------------------------------------------------------------------- +function popupmenu_fracreplacement_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +%-------------------------------------------------------------------------- +function popupmenu_areatype_Callback(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function popupmenu_areatype_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +%-------------------------------------------------------------------------- +% function togglebutton_viewer_Callback(hObject, eventdata, handles) +% if get(hObject, 'Value') +% pushbutton_run_Callback(hObject, eventdata, handles) +% end + +%-------------------------------------------------------------------------- +function uipanel_inputlat_CreateFcn(hObject, eventdata, handles) + +%-------------------------------------------------------------------------- +function gui_chassis_CloseRequestFcn(hObject, eventdata, handles) +if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting') + % The GUI is still in UIWAIT, us UIRESUME + uiresume(handles.gui_chassis); +else + % The GUI is no longer waiting, just close it + delete(handles.gui_chassis); +end + + +% --- Executes on selection change in popupmenu_rise. +function popupmenu_rise_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu_rise (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_rise contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu_rise + + +% --- Executes during object creation, after setting all properties. +function popupmenu_rise_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu_rise (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes during object creation, after setting all properties. +function text_punit_CreateFcn(hObject, eventdata, handles) +% hObject handle to text_punit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + +% --- Executes during object creation, after setting all properties. +function text_fa1_CreateFcn(hObject, eventdata, handles) +% hObject handle to text_fa1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% --- Executes during object creation, after setting all properties. +function text_fraca_CreateFcn(hObject, eventdata, handles) +% hObject handle to text_fa1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + +% --- Executes during object creation, after setting all properties. +function checkbox_include_used_latencies_CreateFcn(hObject, eventdata, handles) +% hObject handle to checkbox_include_used_latencies (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + +% --- Executes during object deletion, before destroying properties. +function checkbox_include_used_latencies_DeleteFcn(hObject, eventdata, handles) +% hObject handle to checkbox_include_used_latencies (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in checkbox_include_used_latencies. +function checkbox_include_used_latencies_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_include_used_latencies (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_include_used_latencies + + +% --- Executes on button press in checkbox_binlabel. +function checkbox_binlabel_Callback(hObject, eventdata, handles) +% hObject handle to checkbox_binlabel (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of checkbox_binlabel diff --git a/studio_functions/displayEquiComERP.m b/studio_functions/displayEquiComERP.m new file mode 100755 index 00000000..9e7f5dff --- /dev/null +++ b/studio_functions/displayEquiComERP.m @@ -0,0 +1,74 @@ +function displayEquiComERP(xcom, nline2end) +if nargin<2 + nline2end = 140; % max line length + nd = nline2end; % number of dashed lines +end + +%%changed by Guanghui Mar 2023 +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + else + Toolabel = 0; + end +else + Toolabel = 1; +end + + +fprintf([repmat('-', 1,nd) '\n']); +if Toolabel==0 + try + cprintf([0.1333 0.5451 0.1333], '%%Equivalent command:\n'); + catch + fprintf('%%Equivalent command:\n'); + end +elseif Toolabel==1 + + try + cprintf([0.1333 0.5451 0.1333], '%%EStudio:Equivalent command:\n'); + catch + fprintf('%%EStudio:Equivalent command:\n'); + end +end +if length(xcom)nline2end) + if isempty(indxcomx) + fprintf('%s\n', xcom); % as it is... + else + N = round((length(xcom)/nline2end)); + Npos = nline2end:nline2end:N*nline2end; + Apos = unique_bc2(closest(indxcomx,Npos)); + if length(Apos)>1 && (length(xcom)-Apos(end-1))<=nline2end + Apos = Apos(1:end-1); + elseif length(Apos)==1 && (length(xcom)-Apos)< 0.1*length(xcom) + fprintf('%s\n', xcom); % as it is... + fprintf([repmat('-', 1,nd) '\n']); + return + end + for kk=1:length(xcom) + if ~ismember_bc2(kk, Apos) + fprintf('%s', xcom(kk)); + elseif ismember_bc2(kk, Apos) && kkGo back to ERPLAB menu'); +end +fprintf('\n'); \ No newline at end of file diff --git a/studio_functions/erpgettoolversion.m b/studio_functions/erpgettoolversion.m new file mode 100755 index 00000000..b7734cbe --- /dev/null +++ b/studio_functions/erpgettoolversion.m @@ -0,0 +1,43 @@ + + +function output = erpgettoolversion(field) +output = []; +if nargin<1 + help erpgettoolversion; + return +end + +if nargin==1 % read + try + p = which('EStudio'); + p = p(1:findstr(p,'EStudio.m')-1); + v = load(fullfile(p,'erplab_running_version.erpm'), '-mat'); + catch + + msgboxText = ['EStudio (erpgettoolversion.m) could not find "erplab_running_version.erpm" or does not have permission for reading it.\n'... + 'Please, run EStudio once again.\n']; + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + output = []; + return + end + if isfield(v, field) + output = v.(field); + else + output = []; + end + return + +else % invalid inputs + msgboxText = 'Wrong number of inputs for erpworkingmemory.m\n'; + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + output = []; + return +end \ No newline at end of file diff --git a/studio_functions/erplab_running_version.m b/studio_functions/erplab_running_version.m new file mode 100755 index 00000000..aca135a2 --- /dev/null +++ b/studio_functions/erplab_running_version.m @@ -0,0 +1,108 @@ +% PURPOSE : + + + + +function erplab_running_version(varargin) +erpcom = ''; +if nargin < 1 + help erplab_running_version + return +end + +% if isempty(tooltype) +% +% +% end + + + +% +% CHECK EEGLAB Version +% +if exist('erplab_running_version.erpm','file')==2 + iserpmem = 1; % file for memory exists +else + iserpmem = 0; % does not exist file for memory +end + +% +% Parsing inputs +% +p = inputParser; +p.FunctionName = mfilename; +p.CaseSensitive = false; + +p.addParamValue('version', @isnumeric); % erpset index or input file +p.addParamValue('tooltype', @ischar); % 'on', 'off' + +p.parse(varargin{:}); + + + + +% if ~iserpmem + +p_location = which('EStudio'); +p_location = p_location(1:findstr(p_location,'EStudio.m')-1); +try + tooltype = p.Results.tooltype; +catch + tooltype = 'erplab'; +end + +try + version = p.Results.version; +catch + version = 1; +end + +save(fullfile(p_location,'erplab_running_version.erpm'),'tooltype','version'); + + + +% end +% erpcom = char(strcat()); + +fn = fieldnames(p.Results); +erpcom = sprintf( '%s erplab_running_version( %s ', inputname(1), inputname(1) ); + +for q=1:length(fn) + + fn2com = fn{q}; + fn2res = p.Results.(fn2com); + if ~isempty(fn2res) + if ischar(fn2res) + + erpcom = sprintf( '%s ''%s'', ''%s''', erpcom, fn2com, fn2res); + else + if isnumeric(fn2res) + fn2resstr = char(num2str(fn2res)); + fnformat = '%s'; + erpcom = sprintf( ['%s, ''%s'', ' fnformat], erpcom, fn2com, fn2resstr); + end + + end + end + +end + +erpcom = sprintf( '%s );', erpcom); +ALLERPCOM = []; +if isempty(ALLERPCOM) + ALLERPCOM{1} = erpcom; +else + ALLERPCOM{length(ALLERPCOM)+1} = erpcom; +end + +assignin('base','ALLERPCOM',ALLERPCOM); + +assignin('base','ERPCOM',erpcom);%Send the history to Matlab workspace +% get history from script. ERP + +displayEquiComERP(erpcom); + + + + +return diff --git a/studio_functions/erplab_studio_default_values.m b/studio_functions/erplab_studio_default_values.m new file mode 100755 index 00000000..9c796e1e --- /dev/null +++ b/studio_functions/erplab_studio_default_values.m @@ -0,0 +1,23 @@ +erplabstudiover = '1.00'; % current erplab studio version +erplabstudiorel = '26-April-2022'; % DOB +erplabstudiodeveloper = 'Simmons&Zhang'; +% erplabstudiolabel = 1;%0: using ERPLAB; 1:using ERPLAB Studio +%ColorB = [170 180 195]/255; % old background color (until version 3) +%ColorB = [0.9216 0.8353 0.6078]; % background color for version 4 +%ColorB = [0.7020 0.7647 0.8392]; % background color since version 4.0.0.3 +%ColorB = [0.9804 0.8118 0.5529]; % background color since version 4.0.0.11 +ColorB = [0.7020 0.77 0.85]; % background color since version 4.0.0.12 +ColorBviewer = [0.8 0.8 0.9];%[0.7765,0.7294,0.8627]; +% ColorB = [0.95 0.95 0.95]; +ColorF = [0.02 0.02 0.02]; % foreground color since version 4.0.2.0 +errorColorF = [0 0 0]; % foreground color for error window +errorColorB = [0.6824 1 0.6353]; % background color for error window +fontunitsGUI = 'pixels'; + +set(0,'Units','pixels') +thisscreen = get(0, 'ScreenSize'); +if thisscreen(4)>=1440 + fontsizeGUI = 12; % high resolution display (eg Retina) +else + fontsizeGUI = 11; +end diff --git a/studio_functions/erpworkingmemory.m b/studio_functions/erpworkingmemory.m new file mode 100755 index 00000000..a4d75751 --- /dev/null +++ b/studio_functions/erpworkingmemory.m @@ -0,0 +1,189 @@ +% PURPOSE : encodes and retrieves ERPLAB's working memory +% +% FORMAT : +% +% output = erpworkingmemory(field, input2store) +% +% INPUTS : +% +% field - function name. e.g. 'pop_appenderp' +% input2store - values to store (cell array) +% +% +% OUTPUTS : +% +% output - stored values (cell array) +% +% +% EXAMPLE 1: encode pop_appenderp's memory (values currently being used) +% +% erpworkingmemory('pop_appenderp', { optioni, erpset, prefixlist }); +% +% +% EXAMPLE 2: retrieve pop_appenderp's memory (values last used) +% +% def = erpworkingmemory('pop_appenderp'); +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon &Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 & 2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function output = erpworkingmemory(field, input2store) +output = []; +if nargin<1 + help erpworkingmemory + return +end +try + vmemoryerp = evalin('base', 'vmemoryerp'); +catch + vmemoryerp = []; +end + +ERPtooltype = erpgettoolversion('tooltype'); +if ~isempty(ERPtooltype) + if strcmpi(ERPtooltype,'EStudio') + Toolabel = 1;%%Get label from work space to confirm whether EStudio was executed. + + else + Toolabel = 0; + end +else + Toolabel = 1; +end + + +if nargin==1 % read + if ~isempty(vmemoryerp) % variable at the workspace for storing/reading memory + % try + % v = memoryerp; + % catch + % msgboxText = 'ERPLAB could not load the variable, at workspace, called "memoryerp"'; + % try + % cprintf([0.45 0.45 0.45], sprintf(msgboxText', erplabmemoryfile)); + % catch + % fprintf(msgboxText); + % end + % output = []; + % return + % end + if isfield(vmemoryerp, field) + output = vmemoryerp.(field); + else + output = []; + end + else % file for storing/reading memory + try + if Toolabel==1%%When using EStudio + p = which('EStudio'); + p = p(1:findstr(p,'EStudio.m')-1); + v = load(fullfile(p,'memoryerpstudio.erpm'), '-mat'); + else%%When using ERPLAB + p = which('eegplugin_erplab'); + p = p(1:findstr(p,'eegplugin_erplab.m')-1); + v = load(fullfile(p,'memoryerp.erpm'), '-mat'); + end + catch + if Toolabel==1%%When using EStudio + msgboxText = ['ERPLAB Studio (erpworkingmemory.m) could not find "memoryerpstudio.erpm" or does not have permission for reading it.\n'... + 'Please, run EEGLAB once again or go to ERPLAB''s Setting menu and specify/create a new memory file.\n']; + else + msgboxText = ['ERPLAB Studio (erpworkingmemory.m) could not find "memoryerpstudio.erpm" or does not have permission for reading it.\n'... + 'Please, run EEGLAB Studio once again or go to EStudio''s Setting menu and specify/create a new memory file.\n']; + + end + + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + output = []; + return + end + if isfield(v, field) + output = v.(field); + else + output = []; + end + end + return +elseif nargin==2 % write + if ~isempty(vmemoryerp) % variable at the workspace for storing/reading memory + try + vmemoryerp.(field) = input2store; + assignin('base','vmemoryerp', vmemoryerp); + catch + msgboxText = 'ERPLAB (erpworkingmemory.m) could not write to the variable called vmemoryerp, at workspace.'; + try + cprintf([0.45 0.45 0.45], sprintf(msgboxText', erplabmemoryfile)); + catch + fprintf(msgboxText); + end + return + end + else % file for storing/reading memory + try + if Toolabel==1%%When using EStudio + eval([field '=input2store;']) + p = which('EStudio'); + p = p(1:findstr(p,'EStudio.m')-1); + save(fullfile(p,'memoryerpstudio.erpm'), field,'-append'); + + else%%When using ERPLAB + eval([field '=input2store;']) + p = which('eegplugin_erplab'); + p = p(1:findstr(p,'eegplugin_erplab.m')-1); + save(fullfile(p,'memoryerp.erpm'), field,'-append'); + end + catch + if Toolabel==1%%When using EStudio + msgboxText = ['ERPLAB Studio could not find "memoryerpstudio.erpm" or does not have permission for writting on it.\n'... + 'Please, run EEGLAB Studio once again or go to EStudio''s Setting menu and specify/create a new memory file.\n']; + else + msgboxText = ['ERPLAB could not find "memoryerp.erpm" or does not have permission for writting on it.\n'... + 'Please, run EEGLAB once again or go to ERPLAB''s Setting menu and specify/create a new memory file.\n']; + end + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + return + end + end +else % invalid inputs + msgboxText = 'Wrong number of inputs for erpworkingmemory.m\n'; + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + output = []; + return +end \ No newline at end of file diff --git a/studio_functions/estudioworkingmemory.m b/studio_functions/estudioworkingmemory.m new file mode 100755 index 00000000..270aec06 --- /dev/null +++ b/studio_functions/estudioworkingmemory.m @@ -0,0 +1,144 @@ +% PURPOSE : encodes and retrieves ERPLAB's working memory +% +% FORMAT : +% +% output = erpworkingmemory(field, input2store) +% +% INPUTS : +% +% field - function name. e.g. 'pop_appenderp' +% input2store - values to store (cell array) +% +% +% OUTPUTS : +% +% output - stored values (cell array) +% +% +% EXAMPLE 1: encode pop_appenderp's memory (values currently being used) +% +% erpworkingmemory('pop_appenderp', { optioni, erpset, prefixlist }); +% +% +% EXAMPLE 2: retrieve pop_appenderp's memory (values last used) +% +% def = erpworkingmemory('pop_appenderp'); +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon &Guanghui Zhang +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 & 2022 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function output = estudioworkingmemory(field, input2store); +output = []; +if nargin<1 + help estudioworkingmemory + return +end +try + vmemoryestudio = evalin('base', 'vmemoryestudio'); +catch + vmemoryestudio = []; +end + + + +if nargin==1 % read + if ~isempty(vmemoryestudio) % variable at the workspace for storing/reading memory + if isfield(vmemoryestudio, field) + output = vmemoryestudio.(field); + else + output = []; + end + else % file for storing/reading memory + try + p = which('EStudio'); + p = p(1:findstr(p,'EStudio.m')-1); + v = load(fullfile(p,'memoryerpstudiopanels.erpm'), '-mat'); + + catch + + msgboxText = ['EStudio (memoryerpstudiopanels.m) could not find "memoryerpstudiopanels.erpm" or does not have permission for reading it.\n'... + 'Please, run EStudio again or go to EStudio''s Setting menu and specify/create a new memory file.\n']; + + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + output = []; + return + end + if isfield(v, field) + output = v.(field); + else + output = []; + end + end + return +elseif nargin==2 % write + if ~isempty(vmemoryestudio) % variable at the workspace for storing/reading memory + try + vmemoryestudio.(field) = input2store; + assignin('base','vmemoryestudio', vmemoryestudio); + catch + msgboxText = 'EStudio (estudioworkingmemory.m) could not write to the variable called vmemoryestudio, at workspace.'; + try + cprintf([0.45 0.45 0.45], sprintf(msgboxText', erplabmemoryfile)); + catch + fprintf(msgboxText); + end + return + end + else % file for storing/reading memory + try + eval([field '=input2store;']) + p = which('EStudio'); + p = p(1:findstr(p,'EStudio.m')-1); + save(fullfile(p,'memoryerpstudiopanels.erpm'), field,'-append'); + catch + msgboxText = ['EStudio could not find "memoryerpstudiopanels.erpm" or does not have permission for writting on it.\n'... + 'Please, run EStudio again or go to EStudio''s Setting menu and specify/create a new memory file.\n']; + + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + return + end + end +else % invalid inputs + msgboxText = 'Wrong number of inputs for estudioworkingmemory.m\n'; + try + cprintf([0.45 0.45 0.45], msgboxText'); + catch + fprintf(msgboxText); + end + output = []; + return +end \ No newline at end of file diff --git a/studio_functions/geterplabstudioversion.m b/studio_functions/geterplabstudioversion.m new file mode 100755 index 00000000..40fff9a4 --- /dev/null +++ b/studio_functions/geterplabstudioversion.m @@ -0,0 +1,45 @@ +% PURPOSE: gets current ERPLAB's version +% +% FORMAT: +% +% version = geterplabversion; +% +% or +% +% +% [version reldate] = geterplabversion; % reldate=release date +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function [version reldate] = geterplabstudioversion + +erplab_studio_default_values +version = erplabstudiover; +reldate = erplabstudiorel; \ No newline at end of file diff --git a/studio_functions/memoryerpstudio.erpm b/studio_functions/memoryerpstudio.erpm new file mode 100644 index 00000000..9aaa7a95 Binary files /dev/null and b/studio_functions/memoryerpstudio.erpm differ diff --git a/studio_functions/memoryerpstudiopanels.erpm b/studio_functions/memoryerpstudiopanels.erpm new file mode 100644 index 00000000..0068b260 Binary files /dev/null and b/studio_functions/memoryerpstudiopanels.erpm differ diff --git a/studio_functions/o_ERPDAT.m b/studio_functions/o_ERPDAT.m new file mode 100755 index 00000000..ea07e70a --- /dev/null +++ b/studio_functions/o_ERPDAT.m @@ -0,0 +1,79 @@ +classdef o_ERPDAT < handle + properties + ALLERP + ERP + CURRENTERP + Count_ERP + ERP_chan + ERP_bin + Count_currentERP + Process_messg + Two_GUI + end + + + events + erpschange + drawui_CB + cerpchange + Count_ERP_change + ERP_chan_change + ERP_bin_change + Count_currentERP_change + Messg_change + Two_GUI_change + end + + + methods + function set.ALLERP(obj,value) + obj.ALLERP = value; + notify(obj,'erpschange'); + end + function set.ERP(obj,value) + obj.ERP = value; + notify(obj,'drawui_CB'); + end + %%Modified CurrentERP + function set.CURRENTERP(obj,value) + obj.CURRENTERP = value; + notify(obj,'cerpchange'); + end + %%ERP Plotting panel + function set.Count_ERP(obj,value) + obj.Count_ERP = value; + notify(obj,'Count_ERP_change'); + end + %Modified channels of the selected ERP + function set.ERP_chan(obj,value) + obj.ERP_chan = value; + notify(obj,'ERP_chan_change'); + end + %Modified bins of the selected ERP + function set.ERP_bin(obj,value) + obj.ERP_bin = value; + notify(obj,'ERP_bin_change'); + end + + %Modified bins of the selected ERP + function set.Count_currentERP(obj,value) + obj.Count_currentERP = value; + notify(obj,'Count_currentERP_change'); + end + + + %Modified bins of the selected ERP + function set.Process_messg(obj,value) + obj.Process_messg = value; + notify(obj,'Messg_change'); + end + + %capture the change from main EStudio + function set.Two_GUI(obj,value) + obj.Two_GUI = value; + notify(obj,'Two_GUI_change'); + end + + + end +end \ No newline at end of file diff --git a/studio_functions/painterplabstudio.m b/studio_functions/painterplabstudio.m new file mode 100755 index 00000000..bdfbac85 --- /dev/null +++ b/studio_functions/painterplabstudio.m @@ -0,0 +1,89 @@ +% PURPOSE : sets background and foreground color of the current ERPLAB's GUI +% +% FORMAT : +% +% handles = painterplab(handles, type); +% +% handles - GUI's handles structure +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2009 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function handles = painterplabstudio(handles, type) +if nargin<2 + type = 0; +end +if type==0 + % + % Color GUI + % + ColorB = erpworkingmemory('ColorB'); + ColorF = erpworkingmemory('ColorF'); +elseif type==1 + ColorB = [0.95 0.95 0.95]; + ColorF = [0 0 0]; +end +if isempty(ColorB) + ColorB = [0.95 0.95 0.95]; + %ColorB = [0.83 0.82 0.79]; +end +if isempty(ColorF) + ColorF = [0 0 0]; +end + +filedsn = fieldnames(handles); + +% GUI's objects' color background +for kk=1:length(filedsn) + mstr = regexpi(filedsn{kk},'^figure|^axes1|^nbin|^edit|^listbox|^EEG|^ERP|togglebutton_summary|^pushbutton|totline|indxline|ERP_figure|Scalp_figure|counterchanwin|counterbinwin','match'); + if isempty(mstr) + num = handles.(filedsn{kk}); + if ~iscell(num) && ~isstruct(num) + if num~=1 + try + set(num, 'BackgroundColor', ColorB) + catch + end + try + set(num, 'ForegroundColor', ColorF) + catch + + end + end + end + end +end +% GUI's color background +try + set(handles.gui_chassis, 'Color', ColorB) + %disp('Mira:') + %num + %filedsn{kk} +catch +end \ No newline at end of file diff --git a/studio_functions/setfonterplabestudio.m b/studio_functions/setfonterplabestudio.m new file mode 100755 index 00000000..961868c7 --- /dev/null +++ b/studio_functions/setfonterplabestudio.m @@ -0,0 +1,87 @@ +% PURPOSE: sets ERPLAB's GUIs' font +% +% FORMAT: +% +% handles = setfonterplab(handles, fontsize, fontunits); +% +% INPUT +% +% handles - GUI's handles stucture +% fontsize - font size +% fontunits - font units ('pixels', 'points') +% +% +% *** This function is part of ERPLAB Toolbox *** +% Author: Javier Lopez-Calderon & Johanna Kreither +% Center for Mind and Brain +% University of California, Davis, +% Davis, CA +% 2012 + +%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b +% +% ERPLAB Toolbox +% Copyright © 2007 The Regents of the University of California +% Created by Javier Lopez-Calderon and Steven Luck +% Center for Mind and Brain, University of California, Davis, +% javlopez@ucdavis.edu, sjluck@ucdavis.edu +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +function handles = setfonterplabestudio(handles, fontsize, fontunits) + +if nargin<3 + fontunits = []; +end +if nargin<2 + fontsize = []; +end +if isempty(fontsize) + % + % GUI's fontsize + % + fontsize = f_get_default_fontsize(); +end +if isempty(fontsize) + fontsize = 10; +end +if isempty(fontunits) + % + % GUI's fontsize + % + fontunits = erpworkingmemory('fontunitsGUI'); +end +if isempty(fontunits) + fontunits = 'points'; +end + +filedsn = fieldnames(handles); + +for j=1:length(filedsn) + %mstr = regexp(filedsn{j},'^nbin|^edit|^listbox|^EEG|^ERP|togglebutton_summary|^pushbutton|totline|indxline|Plotting_ERP|Scalp|counterchanwin|counterbinwin|text_erpset','match'); + mstr = regexp(filedsn{j},'^EEG|^ERP|totline|Plotting_ERP|Scalp|text_erpset','match'); + if isempty(mstr) + num = handles.(filedsn{j}); + if ~iscell(num) && ~isstruct(num) + if num~=1 + try + set(num, 'FontUnits', fontunits) + set(num, 'FontSize' , fontsize) + catch + + end + end + end + end +end \ No newline at end of file