function varargout = avg_data_quality(varargin)
% AVG_DATA_QUALITY MATLAB code for avg_data_quality.fig
%      AVG_DATA_QUALITY, by itself, creates a new AVG_DATA_QUALITY or raises the existing
%      singleton*.
%
%      H = AVG_DATA_QUALITY returns the handle to a new AVG_DATA_QUALITY or the handle to
%      the existing singleton*.
%
%      AVG_DATA_QUALITY('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in AVG_DATA_QUALITY.M with the given input arguments.
%
%      AVG_DATA_QUALITY('Property','Value',...) creates a new AVG_DATA_QUALITY or raises
%      the existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before avg_data_quality_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to avg_data_quality_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 avg_data_quality

% Last Modified by GUIDE v2.5 17-Jan-2023 13:20:16

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @avg_data_quality_OpeningFcn, ...
    'gui_OutputFcn',  @avg_data_quality_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 avg_data_quality is made visible.
function avg_data_quality_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 avg_data_quality (see VARARGIN)

handles.output = hObject;

disp('Awaiting Data Quality settings...');

% Parse input
handles.DQ_spec = varargin{1};
handles.timelimits = varargin{2};

if isempty(varargin{1})

    preAvg_info = make_DQ_spec(handles.timelimits);
    sme_tw_labels = preAvg_info(3).time_window_labels;
    sme_tw = num2cell(preAvg_info(3).times);
    preAvg_labels = strrep(sme_tw_labels,'aSME','(Metric)');
    sme_tw3= [preAvg_labels' sme_tw];

else
    preAvg_info = varargin{1};

    nDQ = length(preAvg_info);
    times_ind = zeros(1, nDQ);

    %search "times" struct
    %time_present = 0;
    for ti = 1:nDQ

        if ~isempty(preAvg_info(ti).times)
            times_ind(ti) = 1;
        end

    end

    if ~any(times_ind) %no valid times
        sme_tw3 = [];
%         preAvg_labels_old = preAvg_info(3).time_window_labels';
%         preAvg_info_times = num2cell(preAvg_info(3).times);
    else
         try %in case there is only one time-window metric
             preAvg_info_times = num2cell(preAvg_info.times);
             %             preAvg_info_times = num2cell(preAvg_info.times);
             %

%              sme_tw2 = cellstr(strcat({'(Metric) at '}, ...
%                 string(preAvg_info_times(:,1)),{' to '},string(preAvg_info_times(:,2))));
            sme_tw2 = preAvg_info.time_window_labels;

            sme_tw2 = strrep(sme_tw2,'aSME','');
            sme_tw2 = strrep(sme_tw2,'(Corrected)','');
            sme_tw2 = strrep(sme_tw2,'aSD','');
            sme_tw2 = strcat('(Metric)',sme_tw2);

            try
                sme_tw3 = [sme_tw2 preAvg_info_times];
            catch
                sme_tw3 = [sme_tw2' preAvg_info_times];
            end

         catch
             %find usable inddex
             use_row = find(times_ind ==1);
             preAvg_info_times = num2cell(preAvg_info(use_row(1)).times);

             %retain time_window_labels if previously set

%             sme_tw2 = cellstr(strcat({'(Metric) at '}, ...
%                 string(preAvg_info_times(:,1)),{' to '},string(preAvg_info_times(:,2))));

            sme_tw2 = preAvg_info(use_row(1)).time_window_labels;
            sme_tw2 = strrep(sme_tw2,'aSME','');
            sme_tw2 = strrep(sme_tw2,'(Corrected)','');
            sme_tw2 = strrep(sme_tw2,'aSD','');
          %  sme_tw2 = strrep(sme_tw2,'aSD (Corrected)','(');

            sme_tw2 = strcat('(Metric)',sme_tw2);

            try
                sme_tw3 = [sme_tw2 preAvg_info_times];
            catch
                sme_tw3 = [sme_tw2' preAvg_info_times];
            end
         end

    end

%     try
%
%     catch ME
%         switch ME.identifier
%             case 'MATLAB:nonExistentField'
%                 preAvg_labels_old = 'EMPTY';
%                 preAvg_info_times = 'NAN';
%             otherwise
%                 preAvg_labels_old = preAvg_info.time_window_labels';
%                 preAvg_info_times = num2cell(preAvg_info.times);
%         end
%
%     end
%     preAvg_labels = strrep(preAvg_labels_old,'aSME','(Metric)');
%
%
%     try
%         sme_tw2= [preAvg_labels' preAvg_info_times];
%     catch
%         sme_tw2= [preAvg_labels preAvg_info_times];
%     end

end

% Choose default command line output for avg_data_quality

handles.DQout = zeros(2,4);
handles.tupdate = 0;
handles.num_tests = 1;

handles.paraSME = 1;
handles.tdata = handles.SME_table.Data;
handles.SME_table.Data = sme_tw3;

handles.Tout = sme_tw3;
disp(handles.Tout);

handles.sel_row = size(handles.Tout,1); % set to max on load

%read from default/working memory values
type_struct = {preAvg_info.type};

for curtype = type_struct
    switch char(curtype)

        case 'Baseline Measure - SD'
            set(handles.checkbox_baseline_noise,'Value',1);
            set(handles.radiobutton_basel_sd,'Value',1);

        case 'Baseline Measure - SD (Corrected)'
            set(handles.checkbox_baseline_noise,'Value',1);
            set(handles.radiobutton_basel_sdcorr,'Value',1);

        case 'Baseline Measure - RMS'
            set(handles.checkbox_baseline_noise,'Value',1);
            set(handles.radiobutton_basel_rms,'Value',1);

        case 'Point-wise SEM'
            set(handles.checkbox_SEM,'Value',1);
            set(handles.radiobutton12, 'Value',1);

        case 'Point-wise SEM (Corrected)'
            set(handles.checkbox_SEM,'Value',1);
            set(handles.radiobutton_sem_corr,'Value',1);

        case 'aSME'
            set(handles.checkbox1_paraSME,'Value',1);
            set(handles.radiobutton_SD,'Value',1);

        case 'aSME (Corrected)'
            set(handles.checkbox1_paraSME,'Value',1);
            set(handles.radiobutton_SD_corr,'Value',1);

        case 'aSD'
            set(handles.checkbox6_paraSD,'Value',1);
            set(handles.radiobutton_SD,'Value',1);

        case 'aSD (Corrected)'
            set(handles.checkbox6_paraSD,'Value',1);
            set(handles.radiobutton_SD_corr,'Value',1);
    end

end

% Update handles structure
guidata(hObject, handles);

%helpbutton
initialize_gui(hObject, handles, false);

% UIWAIT makes avg_data_quality wait for user response (see UIRESUME)
uiwait(handles.avg_dq);

% --- Outputs from this function are returned to the command line.
function varargout = avg_data_quality_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
pause(0.1)
% Update handles structure
guidata(hObject, handles);

% Get default command line output from handles structure
varargout{1} = handles.output;
% The figure can be deleted now
pause(0.1)
delete(handles.avg_dq);
pause(0.1)

% --- Executes on button press in cancel.
function cancel_Callback(hObject, eventdata, handles)
% hObject    handle to cancel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

if isequal(get(handles.avg_dq, 'waitstatus'), 'waiting')
    %The GUI is still in UIWAIT, us UIRESUME
    handles.output = '';
    %Update handles structure
    guidata(hObject, handles);
    uiresume(handles.avg_dq);
else
    % The GUI is no longer waiting, just close it
    delete(handles.avg_dq);
end

% --- Executes on button press in save.
function save_Callback(hObject, eventdata, handles)
% hObject    handle to save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% First, check time windows are valid
try
    times_here = cell2mat(handles.Tout(:,2:3));
    if any(times_here(:) < min(handles.timelimits)) || any(times_here(:) > max(handles.timelimits))
        beep
        time_off_str = ['It appears that some of the listed times are out of bounds of the epoch time of this EEG set'];
        disp(time_off_str)
        time_off2 = ['Time limits here are: ' num2str(handles.timelimits)];
        disp(time_off2)
        pause(0.1)
        return
    end
catch
    times_here = [];

end

disp('Saving Data Quality settings...');

if handles.paraSME == 1
    num_tests = 1;
    type = 'SME';
end

baseline_on = get(handles.checkbox_baseline_noise,'Value');
sem_on = get(handles.checkbox_SEM,'Value');
asme_on = get(handles.checkbox1_paraSME,'Value');
aSD_on = get(handles.checkbox6_paraSD,'Value');

%num_tests = baseline_on + sem_on + asme_on;

% Make DQout
DQout = [];
dq_slot = 0;
if baseline_on
    dq_slot = dq_slot + 1;

    basel_sd = get(handles.radiobutton_basel_sd,'Value');
    basel_rms = get(handles.radiobutton_basel_rms,'Value');
    %basel_sdcorr = get(handles.radiobutton_basel_sdcorr,(
    if basel_sd
        DQout(dq_slot).type = 'Baseline Measure - SD';
    elseif basel_rms
        DQout(dq_slot).type = 'Baseline Measure - RMS';
    else
        DQout(dq_slot).type = 'Baseline Measure - SD (Corrected)';
    end

    default_t = get(handles.checkbox_basel_default_times,'Value');
    if default_t
        DQout(dq_slot).times = [];
    else
        custom_t = [1 str2double(get(handles.baseline_start,'String')) str2double(get(handles.baseline_end,'String'))];
        DQout(dq_slot).times = custom_t;
    end
end

if sem_on
    dq_slot = dq_slot + 1;
    sem_corr = get(handles.radiobutton_sem_corr,'Value');

    if sem_corr
        DQout(dq_slot).type = 'Point-wise SEM (Corrected)';
    else
        DQout(dq_slot).type = 'Point-wise SEM';
    end
end

if asme_on
    dq_slot = dq_slot + 1;

    dq_sd = get(handles.radiobutton_SD,'Value');
    if dq_sd
        DQout(dq_slot).type = 'aSME';
        DQout(dq_slot).times = times_here;
        DQout(dq_slot).time_window_labels = strrep(handles.Tout(:,1),'(Metric)','aSME');
    else
        DQout(dq_slot).type = 'aSME (Corrected)';
        DQout(dq_slot).times = times_here;
        DQout(dq_slot).time_window_labels = strrep(handles.Tout(:,1),'(Metric)','aSME (Corrected)');
    end

   % DQout(dq_slot).time_window_labels = strrep(handles.Tout(:,1),'(Metric)','aSME');

end

if aSD_on
    dq_slot = dq_slot + 1;

    dq_sd = get(handles.radiobutton_SD,'Value');
    if dq_sd
        DQout(dq_slot).type = 'aSD';
        DQout(dq_slot).times = times_here;
        DQout(dq_slot).time_window_labels = strrep(handles.Tout(:,1),'(Metric)','aSD');
    else
        DQout(dq_slot).type = 'aSD (Corrected)';
        DQout(dq_slot).times = times_here;
        DQout(dq_slot).time_window_labels = strrep(handles.Tout(:,1),'(Metric)','aSD (Corrected)');
    end

   % DQout(dq_slot).time_window_labels = strrep(handles.Tout(:,1),'(Metric)','aSD');

end

%DQout.num_tests = num_tests;

handles.output = DQout;

% Update handles structure
guidata(hObject, handles);
uiresume(handles.avg_dq);
%avg_dq_CloseRequestFcn(hObject, eventdata, handles);

% --- Executes when selected object changed in unitgroup.
function unitgroup_SelectionChangedFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in unitgroup
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------
function initialize_gui(fig_handle, handles, isreset)
% If the metricdata field is present and the save 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 save the data.
if isfield(handles, 'metricdata') && ~isreset
    return;
end

% Update handles structure
guidata(handles.avg_dq, handles);

% --- Executes on button press in checkbox1_paraSME.
function checkbox1_paraSME_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox1_paraSME (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 checkbox1_paraSME
SME_here = get(hObject,'Value');
%disp(SME_here);

temp_times = handles.Tout;

if SME_here
    set(handles.SME_table,'Enable','on');
    set(handles.radiobutton_SD,'Enable','on');
    set(handles.radiobutton_SD_corr,'Enable','on');

    if isempty(temp_times)
        temp_DQ_spec = make_DQ_spec(handles.timelimits);
        sme_tw_labels_old = temp_DQ_spec(3).time_window_labels;
        sme_tw_labels = strrep(sme_tw_labels_old,'aSME','(Metric)');
        sme_tw = num2cell(temp_DQ_spec(3).times);
        sme_tw2 = [sme_tw_labels' sme_tw];

        handles.Tout = sme_tw2;
        set(handles.SME_table, 'Data', sme_tw2);
        pause(0.3)
    end

else

    SD_check = get(handles.checkbox6_paraSD,'Value');
    if SD_check == 0
        set(handles.SME_table,'Enable','off');
        set(handles.radiobutton_SD,'Enable','off');
        set(handles.radiobutton_SD_corr,'Enable','off');

    end
end

guidata(hObject, handles);

function pushbutton_help_Callback(hObject, eventdata, handles)
% doc pop_averager
web('https://github.com/lucklab/erplab/wiki/Computing-Averaged-ERPs#data-quality-measures', '-browser');

% --- Executes when user attempts to close avg_dq.
function avg_dq_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to avg_dq (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

if isequal(get(handles.avg_dq, 'waitstatus'), 'waiting')
    %The GUI is still in UIWAIT, us UIRESUME
    handles.output = '';
    %Update handles structure
    guidata(hObject, handles);
    uiresume(handles.avg_dq);
else
    % The GUI is no longer waiting, just close it
    delete(handles.avg_dq);
end
% Hint: delete(hObject) closes the figure
%delete(hObject);

% --- Executes during object creation, after setting all properties.
function SME_table_CreateFcn(hObject, eventdata, handles)
% hObject    handle to SME_table (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

Tout = hObject.Data;
handles.Tout = Tout;
guidata(hObject, handles);

% --- Executes when entered data in editable cell(s) in SME_table.
function SME_table_CellEditCallback(hObject, eventdata, handles)
% hObject    handle to SME_table (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
%	Indices: row and column indices of the cell(s) edited
%	PreviousData: previous data for the cell(s) edited
%	EditData: string(s) entered by the user
%	NewData: EditData or its converted form set on the Data property. Empty if Data was not changed
%	Error: error string when failed to convert EditData to appropriate value for Data
% handles    structure with handles and user data (see GUIDATA)
% handles.tdata = eventdata.NewData;
% handles.SME_table.Data = handles.tdata;

Tout = hObject.Data;
handles.Tout = Tout;
guidata(hObject, handles);

% --- Executes on button press in SME_row_minus.
function SME_row_minus_Callback(hObject, eventdata, handles)
% hObject    handle to SME_row_minus (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

curr_rows = size(handles.Tout,1);

row_del = handles.sel_row;

if curr_rows <= 1
    beep
    disp('Already at 1 rows')
else

    % notify
    row_del_text = ['Now removing row ' num2str(row_del)];
    disp(row_del_text)

    new_rows = curr_rows - 1;

    new_Tout = handles.Tout;
    new_Tout(row_del,:) = []; % pop the selected row out
    handles.Tout = new_Tout;

    %     row_drop_txt = ['The number of rows was ' num2str(curr_rows) '. Now dropping to ' num2str(new_rows)];
    % disp(row_drop_txt)
    set(handles.SME_table,'Data',new_Tout)
    pause(0.3)
    handles.sel_row = new_rows;

    %

end

guidata(hObject, handles);

% --- Executes on button press in SME_row_plus.
function SME_row_plus_Callback(hObject, eventdata, handles)
% hObject    handle to SME_row_plus (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

curr_rows = size(handles.Tout,1);
new_rows = curr_rows + 1;

old_Tout = handles.Tout;
win_size = old_Tout{end,3} - old_Tout{end,2};

new_row_str = ['(Metric) Time Window custom ' num2str(new_rows)];
new_row_cell = {new_row_str,old_Tout{end,3},old_Tout{end,3}+win_size};
new_Tout = [old_Tout;new_row_cell];

handles.Tout = new_Tout;

set(handles.SME_table,'Data',new_Tout);

guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function text_time_range_CreateFcn(hObject, eventdata, handles)
% hObject    handle to text_time_range (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% --- Executes on button press in checkbox_baseline_noise.
function checkbox_baseline_noise_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox_baseline_noise (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_baseline_noise
inc_baseline = get(hObject,'Value');
if inc_baseline == 1
    set(handles.checkbox_basel_default_times,'Value',1);
    set(handles.radiobutton_basel_custom_times,'Value',1);
    set(handles.radiobutton_basel_sd,'Value',1);
    set(handles.radiobutton_basel_sdcorr,'Value',1);
    set(handles.radiobutton_basel_rms,'Value',1);
else
    set(handles.checkbox_basel_default_times,'Value',0);
    set(handles.radiobutton_basel_custom_times,'Value',0);
    set(handles.radiobutton_basel_sd,'Value',0);
    set(handles.radiobutton_basel_sdcorr,'Value',0);
    set(handles.radiobutton_basel_rms,'Value',0);
end
guidata(hObject, handles);

% --- Executes on button press in checkbox_SEM.
function checkbox_SEM_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox_SEM (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_SEM
inc_SEM = get(hObject,'Value');
if inc_SEM == 1
    set(handles.radiobutton12,'Value',1);
    set(handles.radiobutton_sem_corr,'Value',1);
else
    set(handles.radiobutton12,'Value',0);
    set(handles.radiobutton_sem_corr,'Value',0);
end
guidata(hObject, handles);

function baseline_start_Callback(hObject, eventdata, handles)
% hObject    handle to baseline_start (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 baseline_start as text
%        str2double(get(hObject,'String')) returns contents of baseline_start as a double

% --- Executes during object creation, after setting all properties.
function baseline_start_CreateFcn(hObject, eventdata, handles)
% hObject    handle to baseline_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 baseline_end_Callback(hObject, eventdata, handles)
% hObject    handle to baseline_end (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 baseline_end as text
%        str2double(get(hObject,'String')) returns contents of baseline_end as a double

% --- Executes during object creation, after setting all properties.
function baseline_end_CreateFcn(hObject, eventdata, handles)
% hObject    handle to baseline_end (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 checkbox_baseline_subtract.
function checkbox_baseline_subtract_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox_baseline_subtract (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_baseline_subtract

% --- Executes on button press in radiobutton_basel_sd.
function radiobutton_basel_sd_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton_basel_sd (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_basel_sd
basel_sd = get(hObject,'Value');

if basel_sd
    set(handles.radiobutton_basel_rms,'Value',0);
end

% --- Executes on button press in radiobutton_basel_rms.
function radiobutton_basel_rms_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton_basel_rms (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_basel_rms
basel_rms = get(hObject,'Value');

if basel_rms
    set(handles.radiobutton_basel_sd,'Value',0);
end

% --- Executes on button press in checkbox_basel_default_times.
function checkbox_basel_default_times_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox_basel_default_times (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_basel_default_times
default_times = get(hObject,'Value');

if default_times
    set(handles.baseline_start,'Enable','off');
    set(handles.baseline_end,'Enable','off');
    %set(handles.radiobutton_basel_custom_times,'Enable','off');
    set(handles.text_basel2,'Enable','off');
    set(handles.text_basel3,'Enable','off');

else
    set(handles.baseline_start,'Enable','on');
    set(handles.baseline_end,'Enable','on');
    %set(handles.radiobutton_basel_custom_times,'Enable','on');
    set(handles.text_basel2,'Enable','on');
    set(handles.text_basel3,'Enable','on');
end

% --- Executes on button press in radiobutton_basel_custom_times.
function radiobutton_basel_custom_times_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton_basel_custom_times (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_basel_custom_times
custom_times = get(hObject,'Value');

if custom_times
    set(handles.baseline_start,'Enable','on');
    set(handles.baseline_end,'Enable','on');
    %set(handles.radiobutton_basel_custom_times,'Enable','on');
    set(handles.text_basel2,'Enable','on');
    set(handles.text_basel3,'Enable','on');
else
    set(handles.baseline_start,'Enable','off');
    set(handles.baseline_end,'Enable','off');
    %set(handles.radiobutton_basel_custom_times,'Enable','off');
    set(handles.text_basel2,'Enable','off');
    set(handles.text_basel3,'Enable','off');
end

% --- Executes when selected cell(s) is changed in SME_table.
function SME_table_CellSelectionCallback(hObject, eventdata, handles)
% hObject    handle to SME_table (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
%	Indices: row and column indices of the cell(s) currently selecteds
% handles    structure with handles and user data (see GUIDATA)

%disp(eventdata)
% if the selected cell info exists, save it to handles
if numel(eventdata.Indices)
    row_here = eventdata.Indices(1);
    old_row = handles.sel_row;
    handles.sel_row = row_here;
    if isequal(row_here,old_row) == 0
        row_text = ['Row number ' num2str(row_here) ' now selected'];
        disp(row_text)
    end
    guidata(hObject, handles);
end

% --- Executes on button press in restbutton.
function restbutton_Callback(hObject, eventdata, handles)
% hObject    handle to restbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% get default timewindows
temp_DQ_spec = make_DQ_spec(handles.timelimits);
sme_tw_labels_old = temp_DQ_spec(3).time_window_labels;
sme_tw_labels = strrep(sme_tw_labels_old,'aSME','(Metric)');
sme_tw = num2cell(temp_DQ_spec(3).times);
sme_tw2 = [sme_tw_labels' sme_tw];

handles.Tout = sme_tw2;
set(handles.SME_table, 'Data', sme_tw2);
pause(0.3)

guidata(hObject, handles);

% --- Executes on button press in checkbox7.
function checkbox7_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox7 (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 checkbox7

% --- Executes on button press in pushbutton9.
function pushbutton9_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton9 (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 pushbutton10.
function pushbutton10_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton10 (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 pushbutton11.
function pushbutton11_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton11 (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 checkbox6_paraSD.
function checkbox6_paraSD_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox6_paraSD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
SD_check = get(hObject,'Value');
%disp(SME_here);
temp_times = handles.Tout;

if SD_check
    set(handles.SME_table,'Enable','on');
    set(handles.radiobutton_SD,'Enable','on');
    set(handles.radiobutton_SD_corr,'Enable','on');

    if isempty(temp_times)
        temp_DQ_spec = make_DQ_spec(handles.timelimits);
        sme_tw_labels_old = temp_DQ_spec(3).time_window_labels;
        sme_tw_labels = strrep(sme_tw_labels_old,'aSME','(Metric)');
        sme_tw = num2cell(temp_DQ_spec(3).times);
        sme_tw2 = [sme_tw_labels' sme_tw];

        handles.Tout = sme_tw2;
        set(handles.SME_table, 'Data', sme_tw2);
        pause(0.3)
    end

else
    SME_check = get(handles.checkbox1_paraSME,'Value');
    if SME_check == 0
    set(handles.SME_table,'Enable','off');
    set(handles.radiobutton_SD,'Enable','off');
    set(handles.radiobutton_SD_corr,'Enable','off');
    end
end

guidata(hObject, handles);

% Hint: get(hObject,'Value') returns toggle state of checkbox6_paraSD

% --- Executes on button press in radiobutton_SD_corr.
function radiobutton_SD_corr_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton_SD_corr (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_SD_corr


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% a script that runs the motion compensation algorithm and
% computes the MSE and the MI error for all the dataSets in the workDir
% directory (can be manually changed).
%gb 05/15/05
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%% temp file storage is on biac2 - change this below too!!!
% if isunix
%     networkPath = '/biac2/wandell';
% else
%     networkPath = '\\White\biac2-wandell\';
% end
% workDir = fullfile(networkPath,'data','reading_longitudinal_study','To_correct');
%%%% temp file storage is on teal - change this below too!!!
if isunix
    networkPath = '/teal/scr1';
else
    networkPath = '\\teal\scr1\';
end
workDir = fullfile(networkPath,'fmri','mcToCorrect');

cd(workDir);
[fileNum dirName] = countDirs(pwd);
for count = 3:fileNum
    currentDir = dirName{count};
    cd(fullfile(workDir,currentDir));
    transformAll;
	close all
	clear all
	mrVista
	vw = getSelectedInplane;
	computeError

    % Redefining variables because they are cleared in transform
    if isunix
        networkPath = '/teal/scr1';
    else
        networkPath = '\\teal\scr1\';
    end
    workDir = fullfile(networkPath,'fmri','mcToCorrect');
    cd(workDir);
    [fileNum dirName] = countDirs(pwd);
    pause(0.001);
end


function gui_cb(action)
%
% This file is used by FASTICAG

% This file holds the callbacks to the main window

% @(#)$Id: gui_cb.m,v 1.5 2003/09/10 10:33:41 jarmo Exp $

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Global variables

% Handle to the main figure
global hf_FastICA_MAIN;

% Handles for needed controls in main figure;
global ht_FastICA_mixedStatus;
global ht_FastICA_dim;
global ht_FastICA_numOfSamp;
global ht_FastICA_newDim;
global ht_FastICA_whiteStatus;
global ht_FastICA_icaStatus;
global hpm_FastICA_approach;
global he_FastICA_numOfIC;
global hpm_FastICA_g;
global hpm_FastICA_stabilization;

% Main values are stored here
global g_FastICA_mixedsig;
global g_FastICA_mixedmean;
global g_FastICA_pca_D;
global g_FastICA_pca_E;
global g_FastICA_white_sig;
global g_FastICA_white_wm;
global g_FastICA_white_dwm;
global g_FastICA_ica_sig;
global g_FastICA_ica_A;
global g_FastICA_ica_W;
global g_FastICA_initGuess;
global g_FastICA_approach;
global g_FastICA_numOfIC;
global g_FastICA_g;
global g_FastICA_finetune;
global g_FastICA_a1;
global g_FastICA_a2;
global g_FastICA_myy;
global g_FastICA_stabilization;
global g_FastICA_epsilon;
global g_FastICA_maxNumIte;
global g_FastICA_maxFinetune;
global g_FastICA_sampleSize;
global g_FastICA_initState;
global g_FastICA_displayMo;
global g_FastICA_displayIn;
global g_FastICA_verbose;

% String values are here
global c_FastICA_appr_strV;
global c_FastICA_g1_strD;
global c_FastICA_g1_strV;
global c_FastICA_g2_strD;
global c_FastICA_g2_strV;
global c_FastICA_finetune_strD;
global c_FastICA_finetune_strV;
global c_FastICA_stabili_strV;
global c_FastICA_iSta_strV;
global c_FastICA_dMod_strV;
global c_FastICA_verb_strV;

% What is the load type of load dialog
global g_FastICA_loadType;

% Global variable for stopping the ICA calculations
global g_FastICA_interrupt;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% What ever we do, it will take some time... not much, but some :-)
watchonInFigure = watchon;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
switch action
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'InitAll'

 % If the data is already loaded, then get the information from data
 % and show to the user (also set g_FastICA_numOfIC)
 if ~isempty(g_FastICA_mixedsig)
   set(ht_FastICA_mixedStatus, 'String', '');
   [dim, numofsamp] = size(g_FastICA_mixedsig);
   set(ht_FastICA_dim, 'String', int2str(dim));
   set(ht_FastICA_numOfSamp, 'String', int2str(numofsamp));
   set(ht_FastICA_newDim, 'String', int2str(dim));
   set(he_FastICA_numOfIC, 'String', int2str(dim));
   g_FastICA_numOfIC = dim;
   g_FastICA_mixedmean = [];
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'LoadData'

 handle = findobj('Tag','f_FastICALoad');  % Check if the window is already
 if isempty(handle)                        % open. If not then open it.
   pos = get(hf_FastICA_MAIN, 'Position');
   % Based on the feedback obtained from some users, it seems
   % that at least in some systems, pos can sometimes be empty. A
   % similar check is done a few lines below.
   if ~isempty (pos),
     gui_l(pos(1), pos(2));
   else
     gui_l (0, 0);
   end
 else
   if strcmp(g_FastICA_loadType, 'data')   % Check if it was the same load
     figure(handle);                       % window. If it wasn't then
   else                                    % close the other window first
     close(handle);                        % and then open the load window
     fprintf('''Load initial guess'' -dialog closed!\n');
     pos = get(hf_FastICA_MAIN, 'Position');
     if ~isempty (pos),
       gui_l(pos(1), pos(2));
     else
       gui_l (0, 0);
     end
   end
 end

 % gui_cb NewData; - is called from the load function if not canceled...

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'NewData'

 % New data is loaded or the old data changed. We need to find out
 % somethings about the new data... and do some other stuff also...
 [dim, numofsamp] = size(g_FastICA_mixedsig);
 set(ht_FastICA_dim, 'String', dim);
 set(ht_FastICA_newDim, 'String', dim);
 set(ht_FastICA_numOfSamp, 'String', numofsamp);
 set(he_FastICA_numOfIC, 'String', int2str(dim));

 g_FastICA_numOfIC = dim;    % Default for numOfIC = the new dimension
			     % PCA needs to be calculated again.
 g_FastICA_pca_E = [];       % We use this to check if PCA is calculated
 gui_cb NullWhite;           % Whitening needs to be done again also

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'NullWhite'

 % Whitening needs to done again next time it's needed
 g_FastICA_white_sig = [];   % We use this to check if whitening is calculated
 gui_cb NullICA;             % The FPICA must be calculated again

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'NullICA'

 % If IC's are needed they have to bee calculated again
 g_FastICA_ica_sig = [];     % We use this to check if FPICA is calculated
 set(ht_FastICA_icaStatus,'String','Not yet done');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'Transpose'

 if isempty(g_FastICA_mixedmean)
   g_FastICA_mixedsig = g_FastICA_mixedsig';
 else
   g_FastICA_mixedsig = (g_FastICA_mixedsig + ...
			 g_FastICA_mixedmean * ...
			 ones(1,size(g_FastICA_mixedsig, 2)))';
   g_FastICA_mixedmean = [];
 end
 gui_cb NewData;             % Data has been changed

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'DoPCA'

 if ~isempty(g_FastICA_mixedsig)
   % We'll remove mean of the data here also just in case...
   if isempty(g_FastICA_mixedmean)
     [g_FastICA_mixedsig, g_FastICA_mixedmean] = remmean(g_FastICA_mixedsig);
   end

   % Do PCA interactively: ask the user for eigenvalues
   [g_FastICA_pca_E, g_FastICA_pca_D] = pcamat(g_FastICA_mixedsig, ...
					       0, 0, 'gui', ...
					       deblank(c_FastICA_verb_strV(g_FastICA_verbose,:)));

   newdim = size(g_FastICA_pca_D, 1);
   set(ht_FastICA_newDim, 'String', int2str(newdim));
   set(he_FastICA_numOfIC, 'String', int2str(newdim));
   g_FastICA_numOfIC = newdim;
   gui_cb NullWhite;           % Whitening needs to be done again also
			       % but we'll do it when it's needed.
 else
   fprintf('Data not loaded yet!\n\n');
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'OrigDim'

 gui_cb NewData;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ShowMixed'

 if ~isempty(g_FastICA_mixedsig)
   handle = findobj('Tag','f_FastICA_mix');  % Check if the window is already
   if isempty(handle)                        % open. If not then open it.
     figure('Tag', 'f_FastICA_mix', ...
	    'Name', 'FastICA: Plot data', ...
	    'NumberTitle', 'off');
   else
     figure(handle);
     clf;		% clear the figure for next plots
   end
   if isempty(g_FastICA_mixedmean)
     icaplot('dispsig',g_FastICA_mixedsig, 0, 0, 0, 'Mixed signals');
   else
     icaplot('dispsig',g_FastICA_mixedsig + g_FastICA_mixedmean * ...
	     ones(1, size(g_FastICA_mixedsig, 2)), 0, 0, 0, 'Mixed signals');
   end
 else
   fprintf('Data not loaded yet!\n\n');
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ShowWhite'

 if ~isempty(g_FastICA_mixedsig)
   if isempty(g_FastICA_white_sig)     % if whitening is not done, we need to
     gui_cb Whiten;                    % do it before we can display the
   end                                 % whitened signals

   handle = findobj('Tag','f_FastICA_white');  % Check if the window is already
   if isempty(handle)                          % open. If not then open it.
     figure('Tag', 'f_FastICA_white', ...
	    'Name', 'FastICA: Plot whitened', ...
	    'NumberTitle', 'off');
   else
     figure(handle);
     clf;		% clear the figure for next plots
   end
   icaplot('dispsig',g_FastICA_white_sig,0,0,0,'Whitened signals');
 else
   fprintf('Data not loaded yet!\n\n');
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'Whiten'

 set(ht_FastICA_whiteStatus,'String','Computing...');

 % If PCA is not calculated, we'll have to calculate it now,
 % we'll do it without guestions - we don't reduce the dimension
 % here - but PCAMAT might reduce the dimension automatically.
 if isempty(g_FastICA_pca_E)
   % We'll remove mean of the data here also just in case...
   if isempty(g_FastICA_mixedmean)
     [g_FastICA_mixedsig, g_FastICA_mixedmean] = remmean(g_FastICA_mixedsig);
   end

   [g_FastICA_pca_E, g_FastICA_pca_D] = pcamat(g_FastICA_mixedsig, 1, ...
					       size(g_FastICA_mixedsig, ...
						    1), 'off', ...
					       deblank(c_FastICA_verb_strV(g_FastICA_verbose,:)));

   % Check if the dimension was reduced automatically
   newdim = size(g_FastICA_pca_D, 1);
   set(ht_FastICA_newDim, 'String', int2str(newdim));
   % Check if the numOfIC now has illegal value entered
   % We do that by telling the program that there is new value
   % entered for NumOfIC.
   gui_cb ChangeNumOfIC;
 end

 % And now we can calculate whitening...
 [g_FastICA_white_sig, g_FastICA_white_wm, g_FastICA_white_dwm] = ...
								  whitenv(g_FastICA_mixedsig, g_FastICA_pca_E, g_FastICA_pca_D, deblank(c_FastICA_verb_strV(g_FastICA_verbose,:)));

 set (ht_FastICA_whiteStatus,'String','');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ChangeApproach'

 % Get the old value for g
 eval(['g_str = c_FastICA_g' int2str(g_FastICA_approach) '_strV;']);
 old_g = deblank(g_str(g_FastICA_g,:));

 % Get and set the new value for approach
 g_FastICA_approach = get(hpm_FastICA_approach, 'Value');

 % The possible values for g depend on the value of approach...
 eval(['g_str = c_FastICA_g' int2str(g_FastICA_approach) '_strD;']);
 set(hpm_FastICA_g, 'String', g_str);

 % Match the old g value from the new g values so that if the
 % old_g can be found from the new values (anywhere), then set new g
 % to that value, and if it's not found then set the new value to 1.
 match = 0;
 eval(['g_str = c_FastICA_g' int2str(g_FastICA_approach) '_strV;']);
 for i=1:size(g_str,1)
   if strcmp(old_g, deblank(g_str(i,:)))
     match = i;
   end
 end
 if match == 0
   match = 1;   % the old g is not availabe anymore, set g = 1.
 end
 g_FastICA_g = match;
 set(hpm_FastICA_g, 'Value', match);

 gui_cb NullICA;      % The options are changed so we must calculate ICA again

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ChangeNumOfIC'

 % Get the new value... and store it later on after some checks
 numofic = str2num(get(he_FastICA_numOfIC, 'String'));

 % The number of IC can't be less than 1 or more than the reduced dimension.
 numoficmax = str2num(get(ht_FastICA_newDim, 'String'));
 if numofic < 1
   set(he_FastICA_numOfIC, 'String', '1');
   g_FastICA_numOfIC = 1;
 elseif numofic > numoficmax
   set(he_FastICA_numOfIC, 'String', int2str (numoficmax));
   g_FastICA_numOfIC = numoficmax;
 else
   g_FastICA_numOfIC = numofic;
 end

 gui_cb NullICA;      % The options are changed so we must calculate ICA again

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ChangeG'

 % Get the new value for g.
 g_FastICA_g = get(hpm_FastICA_g, 'Value');

 gui_cb NullICA;      % The options are changed so we must calculate ICA again

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ChangeStab'

 % Get the new value for g.
 g_FastICA_stabilization = get(hpm_FastICA_stabilization, 'Value');

 gui_cb NullICA;      % The options are changed so we must calculate ICA again

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'AdvOpt'

 handle = findobj('Tag','f_FastICAAdvOpt');
 if isempty(handle)                        % Check to see if the window is
   pos = get(hf_FastICA_MAIN, 'Position');     % already open...
   if ~isempty (pos),
     gui_adv(pos(1), pos(2));
   else
     gui_adv(0, 0);
   end
 else
   figure(handle)
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'ShowICASig'

 if ~isempty(g_FastICA_mixedsig)
   % If the IC's are not already calculated, we'll do it now
   if isempty(g_FastICA_ica_sig)
     gui_cb DoFPICA;
   end

   % The signals may have been already displaued by the FPICA function
   % BUT the FPICA may also have shown either the basis of the filters
   % so the signals still need to be shown - besides the mean was added
   % in only later after FPICA

   % Also notice that in this version if there was something wrong in FPICA
   % Then the results are []. - We don't try to plot them!
   if ~isempty(g_FastICA_ica_sig')
     handle = findobj('Tag','f_FastICA_ica');  % Check if the window is already
     if isempty(handle)                        % open. If not then open it.
       figure('Tag', 'f_FastICA_ica', ...
	      'Name', 'FastICA: Plot ICs', ...
	      'NumberTitle', 'off');
     else
       figure(handle);
       clf;		% clear the figure for next plots
     end

     icaplot('dispsig', g_FastICA_ica_sig, 0, ...
	     0, 0, 'Independent components');
   end
 else
   fprintf('Data not loaded yet!\n\n');
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'DoFPICA'

 gui_cb DisableButtons;
 g_FastICA_interrupt = 0;

 if ~isempty(g_FastICA_mixedsig)
   if isempty(g_FastICA_white_sig)     % We need the whitened signal here
     gui_cb Whiten;
   end

   set(ht_FastICA_icaStatus,'String','Computing...');

   % The possible values for g depend on approach
   eval(['g_str = c_FastICA_g' int2str(g_FastICA_approach) '_strV;']);

   % We'll contruct a command string which we'll later on evaluate...
   % This is where the Fixed point algorithm is used.
   command_str = ['[g_FastICA_ica_A,g_FastICA_ica_W]=' ...
		  'fpica(g_FastICA_white_sig,' ...
		  'g_FastICA_white_wm,' ...
		  'g_FastICA_white_dwm,' ...
		  '''' deblank(c_FastICA_appr_strV(g_FastICA_approach,:)) ...
		  ''',' ...
		  'g_FastICA_numOfIC,' ...
		  '''' deblank(g_str(g_FastICA_g,:)) ''',' ...
		  '''' ...
		  deblank(c_FastICA_finetune_strV(g_FastICA_finetune,:)) ...
		  ''',' ...
		  'g_FastICA_a1,' ...
		  'g_FastICA_a2,' ...
		  'g_FastICA_myy,' ...
		  '''' ...
		  deblank(c_FastICA_stabili_strV(g_FastICA_stabilization,:)) ...
		  ''',' ...
		  'g_FastICA_epsilon,' ...
		  'g_FastICA_maxNumIte,' ...
		  'g_FastICA_maxFinetune,' ...
		  '''' deblank(c_FastICA_iSta_strV(g_FastICA_initState,:)) ...
		  ''',' ...
		  'g_FastICA_initGuess,' ...
		  'g_FastICA_sampleSize,' ...
		  '''' deblank(c_FastICA_dMod_strV(g_FastICA_displayMo,:)) ...
		  ''',' ...
		  'g_FastICA_displayIn,' ...
		  '''' deblank(c_FastICA_verb_strV(g_FastICA_verbose,:)) ...
		  ''');'];

   % If the user wants to plot while computing...
   % let's at least plot it to the right figure then
   if ~strcmp(deblank(c_FastICA_dMod_strV(g_FastICA_displayMo,:)),'off')
     handle = findobj('Tag','f_FastICA_ica');  % Check if the window is already
     if isempty(handle)                        % open. If not then open it.
       figure('Tag', 'f_FastICA_ica', ...
	      'Name', 'FastICA: Plot ICs', ...
	      'NumberTitle', 'off');
     else
       figure(handle);
       clf;		% clear the figure for next plots
     end
   end

   % ... and so let's do it...
   eval(command_str);

   % Also notice that in this version if there was something wrong in FPICA
   % Then the results are [].
   if ~isempty(g_FastICA_ica_W)
     % Add the mean back in.
     g_FastICA_ica_sig = g_FastICA_ica_W * g_FastICA_mixedsig ...
			 + (g_FastICA_ica_W * g_FastICA_mixedmean) ...
			 * ones(1,size(g_FastICA_mixedsig, 2));
     set (ht_FastICA_icaStatus,'String','Done');
   else
     gui_cb NullICA;  % set icasig=[] and do what ever needs to be done then
   end

   if ~(g_FastICA_interrupt)
     gui_cb EnableButtons;
   end
 else
   fprintf('Data not loaded yet!\n\n');
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'Interrupt'
 g_FastICA_interrupt = 1;
 set(ht_FastICA_icaStatus,'String','Interrupted');
 gui_cb EnableButtons;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'DisableButtons'
 set(findobj('Tag','b_Transpose'),'Enable','off');
 set(findobj('Tag','b_ShowMixed'),'Enable','off');
 set(findobj('Tag','b_DoPCA'),'Enable','off');
 set(findobj('Tag','b_OrigDim'),'Enable','off');
 set(findobj('Tag','b_ShowWhite'),'Enable','off');
 set(findobj('Tag','b_advOpt'),'Enable','off');
 set(findobj('Tag','b_ShowICASig'),'Enable','off');
 set(findobj('Tag','b_LoadData'),'Enable','off');
 set(findobj('Tag','b_DoFPICA'),'Enable','off');
 set(findobj('Tag','b_SaveData'),'Enable','off');
 set(findobj('Tag','b_Quit'),'Enable','off');
 set(findobj('Tag','b_Interrupt'),'Visible','on');
 drawnow;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'EnableButtons'
 set(findobj('Tag','b_Transpose'),'Enable','on');
 set(findobj('Tag','b_ShowMixed'),'Enable','on');
 set(findobj('Tag','b_DoPCA'),'Enable','on');
 set(findobj('Tag','b_OrigDim'),'Enable','on');
 set(findobj('Tag','b_ShowWhite'),'Enable','on');
 set(findobj('Tag','b_advOpt'),'Enable','on');
 set(findobj('Tag','b_ShowICASig'),'Enable','on');
 set(findobj('Tag','b_LoadData'),'Enable','on');
 set(findobj('Tag','b_DoFPICA'),'Enable','on');
 set(findobj('Tag','b_SaveData'),'Enable','on');
 set(findobj('Tag','b_Quit'),'Enable','on');
 set(findobj('Tag','b_Interrupt'),'Visible','off');
 drawnow;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'SaveData'

 handle = findobj('Tag','f_FastICASave');  % Check if the window is already
 if isempty(handle)                        % open. If not then open it.
   pos = get(hf_FastICA_MAIN, 'Position');
   if ~isempty (pos),
     gui_s(pos(1), pos(2));
   else
     gui_s(0, 0);
   end
 else
   figure(handle);                       % window. If it wasn't then
 end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'Quit'

 % We'll close the other dialogs if they are open.
 Tags = ['f_FastICALoad  '
	 'f_FastICAAdvOpt'
	 'f_FastICASave  '
	 'f_FastICA_mix  '
	 'f_FastICA_white'
	 'f_FastICA_ica  '];
 for i=1:size(Tags,1)
   handle = findobj('Tag', deblank(Tags(i,:)));
   if ~isempty(handle)
     close(handle);
   end
 end

 % Close this window
 close(hf_FastICA_MAIN);

 % Clear the used global variables.
 gui_cg;

 % Use return to avoid reaching the watchoff statement at the end
 % (There used to be a 'break' statement here, but it resulted in
 % errors in more recent version of Matlab -- jarmo)
 return;
 % ... and we're done.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'About'

 gui_help('gui_cb_about');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case 'Help'

 gui_help('gui_cb_help');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

end    % switch

watchoff (watchonInFigure);


%% patchCentre
% Below is a demonstration of the features of the |patchCentre| function

%%
clear; close all; clc;

%% Syntax
% |[Vm]=patchCentre(F,V);|

%% Description
% UNDOCUMENTED
%% Examples
%
%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% 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 <http://www.gnu.org/licenses/>.


function [cfg, M] = ft_sourcemovie(cfg, source, source2)

% FT_SOURCEMOVIE displays the source reconstruction on a cortical mesh
% and allows the user to scroll through time with a movie.
%
% Use as
%   ft_sourcemovie(cfg, source)
% where the input source data is obtained from FT_SOURCEANALYSIS, or a
% a parcellated source structure (i.e. contains a brainordinate field) and
% cfg is a configuration structure that should contain
%
%  cfg.funparameter    = string, functional parameter that is color coded (default = 'avg.pow')
%  cfg.maskparameter   = string, functional parameter that is used for opacity (default = [])
%
% To facilitate data-handling and distributed computing you can use
%   cfg.inputfile   =  ...
% If you specify this option the input data will be read from a *.mat
% file on disk. This mat files should contain only a single variable named 'data',
% corresponding to the input structure.
%
% See also FT_SOURCEPLOT, FT_SOURCEINTERPOLATE, FT_SOURCEPARCELLATE

% Copyright (C) 2011-2015, Robert Oostenveld
% Copyright (C) 2012-2014, Jorn Horschig
% Copyright (C) 2018, Jan-Mathijs Schoffelen
%
% $Id$

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the initial part deals with parsing the input options and data
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
if ft_abort
  return
end
ft_preamble debug
ft_preamble loadvar source
ft_preamble provenance source
ft_preamble trackconfig

% ensure that the input data is valid for this function, this will also do
% backward-compatibility conversions of old data that for example was
% read from an old *.mat file
source = ft_checkdata(source, 'datatype', 'source', 'feedback', 'yes');

% get the options
xlim          = ft_getopt(cfg, 'time');
ylim          = ft_getopt(cfg, 'frequency');
zlim          = ft_getopt(cfg, 'funcolorlim');
olim          = ft_getopt(cfg, 'opacitylim');                     % don't use alim as variable name
cfg.xparam    = ft_getopt(cfg, 'xparam', 'time');                 % use time as default
cfg.yparam    = ft_getopt(cfg, 'yparam');                         % default is dealt with below
cfg.funparameter  = ft_getopt(cfg, 'funparameter', 'avg.pow');        % use power as default
cfg.funcolormap   = ft_getopt(cfg, 'funcolormap',  'jet');
cfg.maskparameter = ft_getopt(cfg, 'maskparameter');

if isempty(cfg.yparam) && isfield(source, 'freq')
  % the default is freq (if present)
  cfg.yparam = 'freq';
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the actual computation is done in the middle part
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargin==2
  fun = getsubfield(source, cfg.funparameter); % might be avg.pow
elseif nargin>2 && isfield(source2, 'pos')
  % in this case two conditions of data seem to have been inputted
  fun  = getsubfield(source, cfg.funparameter); % might be avg.pow
  fun2 = getsubfield(source2, cfg.funparameter);
elseif nargin>2
  % assume the first data argument to be a parcellation, and the second a
  % parcellated structure

  % THIS DOES NOT EXIST ANYMORE: IF PARCELLATED DATA IS IN THE INPUT, IT
  % WILL BE UNPARCELLATED AUTOMATICALLY BY FT_CHECKDATA
  ft_error('bogus');
end
if size(source.pos)~=size(fun,1)
  ft_error('inconsistent number of vertices in the cortical mesh');
end

if ~isfield(source, 'tri')
  ft_error('source.tri missing, this function requires a triangulated cortical sheet as source model');
end

if ~isempty(cfg.maskparameter) && ischar(cfg.maskparameter)
  mask = double(getsubfield(source, cfg.maskparameter));
else
  mask = 0.5*ones(size(fun));
end

xparam = source.(cfg.xparam);
if length(xparam)~=size(fun,2)
  error('inconsistent size of "%s" compared to "%s"', cfg.funparameter, cfg.xparam);
end

if ~isempty(cfg.yparam)
  yparam = source.(cfg.yparam);
  if length(cfg.yparam)~=size(fun,3)
    error('inconsistent size of "%s" compared to "%s"', cfg.funparameter, cfg.yparam);
  end
end

if isempty(xlim)
  xlim(1) = min(xparam);
  xlim(2) = max(xparam);
end

xbeg = nearest(xparam, xlim(1));
xend = nearest(xparam, xlim(2));
% update the configuration
cfg.xlim = xparam([xbeg xend]);

if ~isempty(cfg.yparam)
  if isempty(ylim)
    ylim(1) = min(yparam);
    ylim(2) = max(yparam);
  end
  ybeg = nearest(yparam, ylim(1));
  yend = nearest(yparam, ylim(2));
  % update the configuration
  cfg.ylim = yparam([ybeg yend]);
  hasyparam = true;
else
  % this allows us not to worry about the yparam any more
  yparam = nan;
  ybeg = 1;
  yend = 1;
  cfg.ylim = [];
  hasyparam = false;
end

% make a subselection of the data
xparam  = xparam(xbeg:xend);
yparam  = yparam(ybeg:yend);
fun     = fun(:,xbeg:xend,ybeg:yend);
if exist('fun2', 'var')
  fun2 = fun2(:,xbeg:xend,ybeg:yend);
end
mask    = mask(:,xbeg:xend,ybeg:yend);
clear xbeg xend ybeg yend

if isempty(zlim)
  zlim(1) = min(fun(:));
  zlim(2) = max(fun(:));
  % update the configuration
  cfg.funcolorlim = zlim;
end

if isempty(olim)
  olim(1) = min(mask(:));
  olim(2) = max(mask(:));
  if olim(1)==olim(2)
    olim(1) = 0;
    olim(2) = 1;
  end
  % update the configuration
  cfg.opacitylim = olim;
end

% collect the data and the options to be used in the figure
opt.cfg     = cfg;
opt.xparam  = xparam;
opt.yparam  = yparam;
opt.xval    = 0;
opt.yval    = 0;
opt.dat     = fun;
opt.mask    = mask;
opt.pos     = source.pos;
opt.tri     = source.tri;
opt.vindx   = source.inside(:);
opt.speed   = 1;
opt.record  = 0;
opt.threshold = 0;
opt.frame   = 0;
opt.cleanup = false;
if isfield(source, 'parcellation')
  opt.parcellation = source.parcellation;
  opt.parcellationlabel = source.parcellationlabel;
end

% add functional data of optional third input to the opt structure
% FIXME here we should first check whether the meshes correspond!
if nargin>2 && isfield(source2, 'pos')
  opt.dat2 = fun2;
end

% get a handle to a figure
h  = figure;
set(h, 'color', [1 1 1]);
set(h, 'toolbar', 'figure');
set(h, 'visible', 'on');
set(h, 'CloseRequestFcn', @cb_quitbutton);
set(h, 'position', [100 50 1000 600]);
set(h, 'windowbuttondownfcn', @cb_getposition);

% get timer object
t = timer;
set(t, 'timerfcn', {@cb_timer, h}, 'period', 0.1, 'executionmode', 'fixedSpacing');

% make the user interface elements
cambutton    = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'light', 'userdata', 'C');
playbutton   = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'play',   'userdata', 'p');
recordbutton = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'record', 'userdata', 'r');
quitbutton   = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'quit',   'userdata', 'q');

thrminmin    = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '-', 'userdata', 'downarrow');
thrminplus   = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '+', 'userdata', 'shift+downarrow');
thr          = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'threshold', 'userdata', 't');
thrplusmin   = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '-', 'userdata', 'shift+uparrow');
thrplusplus  = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '+', 'userdata', 'uparrow');

spdmin       = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '<', 'userdata', 'shift+downarrow');
spd          = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'speed','userdata', 's');
spdplus      = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '>', 'userdata', 'shift+uparrow');
climminmin   = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '-', 'userdata', 'leftarrow');
climminplus  = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '+', 'userdata', 'shift+leftarrow');
clim         = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', 'colorlim', 'userdata', 'z');
climplusmin  = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '-', 'userdata', 'shift+rightarrow');
climplusplus = uicontrol('parent', h, 'units', 'normalized', 'style', 'pushbutton', 'string', '+', 'userdata', 'rightarrow');
sliderx      = uicontrol('parent', h, 'units', 'normalized', 'style', 'slider',     'string', sprintf('%s = ', cfg.xparam));
stringx      = uicontrol('parent', h, 'units', 'normalized', 'style', 'text');
slidery      = uicontrol('parent', h, 'units', 'normalized', 'style', 'slider',     'string', sprintf('%s = ', cfg.yparam));
stringy      = uicontrol('parent', h, 'units', 'normalized', 'style', 'text');
stringz      = uicontrol('parent', h, 'units', 'normalized', 'style', 'text');

set(cambutton,    'position', [0.095 0.28  0.09 0.05 ], 'callback', @cb_keyboard);
set(quitbutton,   'position', [0.005 0.28  0.09 0.05 ], 'callback', @cb_keyboard);
set(playbutton,   'position', [0.005 0.22  0.09 0.05 ], 'callback', @cb_keyboard);
set(recordbutton, 'position', [0.095 0.22  0.09 0.05 ], 'callback', @cb_keyboard);
set(thrminmin,    'position', [0.005 0.16  0.03 0.025], 'callback', @cb_keyboard);
set(thrminplus,   'position', [0.005 0.185 0.03 0.025], 'callback', @cb_keyboard);
set(thr,          'position', [0.035 0.16  0.12 0.05 ], 'callback', @cb_keyboard);
set(thrplusmin,   'position', [0.155 0.16  0.03 0.025], 'callback', @cb_keyboard);
set(thrplusplus,  'position', [0.155 0.185 0.03 0.025], 'callback', @cb_keyboard);
set(climminmin,   'position', [0.005 0.10  0.03 0.025], 'callback', @cb_keyboard);
set(climminplus,  'position', [0.005 0.125 0.03 0.025], 'callback', @cb_keyboard);
set(clim,         'position', [0.035 0.10  0.12 0.05 ], 'callback', @cb_keyboard);
set(climplusmin,  'position', [0.155 0.10  0.03 0.025], 'callback', @cb_keyboard);
set(climplusplus, 'position', [0.155 0.125 0.03 0.025], 'callback', @cb_keyboard);
set(spdmin,       'position', [0.005 0.04  0.03 0.05 ], 'callback', @cb_keyboard);
set(spd,          'position', [0.035 0.04  0.12 0.05 ], 'callback', @cb_keyboard);
set(spdplus,      'position', [0.155 0.04  0.03 0.05 ], 'callback', @cb_keyboard);
set(sliderx,      'position', [0.02  0.35  0.38 0.03 ], 'callback', @cb_slider);
set(slidery,      'position', [0.200 0.005 0.78 0.03 ], 'callback', @cb_slider);
set(stringx,      'position', [0.750 0.90  0.18 0.03 ]);
set(stringy,      'position', [0.750 0.85  0.18 0.03 ]);
set(stringz,      'position', [0.60  0.95  0.33 0.03 ]);

set(stringx, 'string', sprintf('%s = ', cfg.xparam));
set(stringy, 'string', sprintf('%s = ', cfg.yparam));
set(stringz, 'string', sprintf('location = '));
set(stringx, 'horizontalalignment', 'right', 'backgroundcolor', [1 1 1]);
set(stringy, 'horizontalalignment', 'right', 'backgroundcolor', [1 1 1]);
set(stringz, 'horizontalalignment', 'right', 'backgroundcolor', [1 1 1]);

% create axes object to contain the mesh
hx = axes;
set(hx, 'position', [0.4 0.08 0.6 0.8]);
set(hx, 'tag', 'mesh');
hs = ft_plot_mesh(source, 'edgecolor', 'none', 'facecolor', [0.5 0.5 0.5], 'vertexcolor', 0.*opt.dat(:,1,1), 'facealpha', 0.*opt.mask(:,1,1), 'clim', [0 1], 'alphalim', [0 1], 'alphamap', 'rampup', 'colormap', cfg.funcolormap, 'maskstyle', 'colormix');

lighting gouraud
material dull
cam1 = camlight('left');
cam2 = camlight('right');
caxis(cfg.funcolorlim);

% create axis object to contain a time course
hy = axes;
set(hy, 'position', [0.02 0.45 0.38 0.5]);
set(hy, 'yaxislocation', 'right');

if ~hasyparam
  tline = plot(opt.xparam, mean(opt.dat(opt.vindx,:))); hold on;
  abc = axis;
  axis([opt.xparam(1) opt.xparam(end) abc(3:4)]);
  vline = plot(opt.xparam(1)*[1 1], abc(3:4), 'r');
  hline1 = plot(opt.xparam([1 end]), [0 0], 'k');
  hline2 = plot(opt.xparam([1 end]), [0 0], 'k');

  if nargin>2 && isfield(source2, 'pos')
    tline2 = plot(opt.xparam, mean(opt.dat2(opt.vindx,:)), 'r'); hold on;
  end

else
  error('not yet implemented');
end
set(hy, 'tag', 'timecourse');

% remember the various handles
opt.h   = h;  % handle to the figure
opt.hs  = hs; % handle to the mesh
opt.hx  = hx; % handle to the axes containing the mesh
opt.hy  = hy; % handle to the axes containing the timecourse
opt.cam = [cam1 cam2]; % handles to the light objects
opt.vline = vline; % handle to the vertical line in the ERF plot
opt.tline = tline; % handle to the ERF
if nargin>2 && isfield(source2, 'pos')
  opt.tline2 = tline2;
end
opt.hline1 = hline1; % handle for the horizontal line for upper threshold
opt.hline2 = hline2; % handle for hte horizontal line for lower threshold
opt.playbutton   = playbutton; % handle to the playbutton
opt.recordbutton = recordbutton; % handle to the recordbutton
opt.quitbutton   = quitbutton; % handle to the quitbutton
opt.threshold    = [0 0];

opt.t   = t;
opt.sliderx  = sliderx;
opt.slidery  = slidery;
opt.stringx  = stringx;
opt.stringy  = stringy;
opt.stringz  = stringz;

if ~hasyparam
  set(opt.slidery, 'visible', 'off');
  set(opt.stringy, 'visible', 'off');
end

setappdata(h, 'opt', opt);

while opt.cleanup==0
  uiwait(h);
  opt = getappdata(h, 'opt');
end
stop(opt.t);

if nargout
  M = opt.movie;
end

delete(h);

% do the general cleanup and bookkeeping at the end of the function
% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble trackconfig
ft_postamble previous source
ft_postamble provenance

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_slider(h, eventdata)

persistent previous_valx previous_valy previous_vindx previous_clim previous_thr

if isempty(previous_valx)
  previous_valx = 0;
end
if isempty(previous_valy)
  previous_valy = 0;
end
if isempty(previous_clim)
  previous_clim = [0 1];
end
if isempty(previous_thr)
  previous_thr = [0 0];
end

h    = getparent(h);
opt  = getappdata(h, 'opt');
valx = get(opt.sliderx, 'value');
valx = round(valx*(size(opt.dat,2)-1))+1;
valx = min(valx, size(opt.dat,2));
valx = max(valx, 1);

valy = get(opt.slidery, 'value');
valy = round(valy*(size(opt.dat,3)-1))+1;
valy = min(valy, size(opt.dat,3));
valy = max(valy, 1);

mask = squeeze(opt.mask(:,valx,valy));

% update stuff
if previous_valx~=valx || previous_valy~=valy || ~isequal(previous_clim, opt.cfg.funcolorlim) || ~isequal(previous_thr, opt.threshold)
  % update strings
  set(opt.stringx, 'string', sprintf('%s = %3.3f\n', opt.cfg.xparam, opt.xparam(valx)));
  set(opt.stringy, 'string', sprintf('%s = %3.3f\n', opt.cfg.yparam, opt.yparam(valy)));

  dat = opt.dat(:,valx,valy);
  mask(dat>opt.threshold(1)&dat<opt.threshold(2)) = 0;

  % convert the color-data + opacity into rgb for robust rendering
  bgcolor = repmat([0.5 0.5 0.5], [numel(mask) 1]);
  rgb     = bg_rgba2rgb(bgcolor, dat, opt.cfg.funcolormap, opt.cfg.funcolorlim, mask, 'rampup', opt.cfg.opacitylim);

  % update data in mesh
  set(opt.hs, 'FaceVertexCData', rgb, 'facecolor', 'interp');

  set(opt.vline, 'xdata', [1 1]*opt.xparam(valx));
end

% update ERF-plot
set(opt.hy,    'ylim',   opt.cfg.funcolorlim);
set(opt.vline, 'ydata',  opt.cfg.funcolorlim);
if ~(numel(previous_vindx)==numel(opt.vindx) && all(previous_vindx==opt.vindx))
  tmp = mean(opt.dat(opt.vindx,:,valy),1);
  set(opt.tline, 'ydata', tmp);
  %set(opt.hy,    'ylim',  [min(tmp(:)) max(tmp(:))]);
  %set(opt.vline, 'ydata', [min(tmp(:)) max(tmp(:))]);

  if isfield(opt, 'dat2')
    tmp = mean(opt.dat2(opt.vindx,:,valy),1);
    set(opt.tline2, 'ydata', tmp);
  end

  set(opt.hy,    'yaxislocation', 'right');
  if isfield(opt, 'parcellation')
    set(opt.stringz, 'string', sprintf('location = %s', opt.parcellationlabel{opt.parcellation(opt.vindx)}));
  else
    set(opt.stringz, 'string', sprintf('location = [%2.1f, %2.1f, %2.1f]', opt.pos(opt.vindx,:)));
  end
end

if opt.record
  tmp = get(opt.h, 'position');
  opt.frame = opt.frame + 1;
  opt.movie(opt.frame) = getframe(opt.h,[1 1 tmp(3:4)-1]);
end
setappdata(h, 'opt', opt);

previous_valx = valx;
previous_valy = valy;
previous_vindx = opt.vindx;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_playbutton(h, eventdata)

opt = getappdata(h, 'opt');
if strcmp(get(opt.playbutton, 'string'), 'pause')
  stop(opt.t);
  set(opt.playbutton, 'string', 'play');
else
  start(opt.t);
  set(opt.playbutton, 'string', 'pause');
end
setappdata(h, 'opt', opt);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_quitbutton(h, eventdata)

opt = getappdata(h, 'opt');
opt.cleanup = 1;
setappdata(h, 'opt', opt);
uiresume(h);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_recordbutton(h, eventdata)

opt = getappdata(h, 'opt');
if strcmp(get(opt.recordbutton, 'string'), 'stop')
  opt.record = 0;
  set(opt.recordbutton, 'string', 'record');
else
  opt.record = 1;
  set(opt.recordbutton, 'string', 'stop');
end
setappdata(h, 'opt', opt);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_timer(obj, info, h)

opt   = getappdata(h, 'opt');
delta = opt.speed/size(opt.dat,2);
val = get(opt.sliderx, 'value');
val = val + delta;
if val>1
  val = val-1;
end
set(opt.sliderx, 'value', val);
setappdata(h, 'opt', opt);
cb_slider(h);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_alim(h, eventdata)
if ~ishandle(h)
  return
end
opt = guidata(h);
switch get(h, 'String')
  case '+'
    alim(alim*sqrt(2));
  case '-'
    alim(alim/sqrt(2));
end % switch
guidata(h, opt);
uiresume;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_getposition(h, eventdata)

h   = getparent(h);
opt = getappdata(h, 'opt');
if strcmp(get(get(h, 'currentaxes'), 'tag'), 'timecourse')
  % get the current point
  %pos = get(opt.hy, 'currentpoint');
  %set(opt.sliderx, 'value', nearest(opt.xparam, pos(1)));
elseif strcmp(get(get(h, 'currentaxes'), 'tag'), 'mesh')
  % get the current point, which is defined as the intersection through the
  % axis-box (in 3D)
  pos       = get(opt.hx, 'currentpoint');

  % get the intersection with the mesh
  [ipos, d] = intersect_line(opt.pos, opt.tri, pos(1,:), pos(2,:));
  [md, ix]  = min(abs(d));

  if ~isempty(ix)
    dpos      = opt.pos - ipos(ix*ones(size(opt.pos,1),1),:);
    opt.vindx = nearest(sum(dpos.^2,2),0);
  end
end
setappdata(h, 'opt', opt);
cb_slider(h);
uiresume;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cb_keyboard(h, eventdata)

if (isempty(eventdata) && ft_platform_supports('matlabversion', -Inf, '2014a')) || isa(eventdata, 'matlab.ui.eventdata.ActionData')
  % determine the key that corresponds to the uicontrol element that was activated
  key = get(h, 'userdata');
else
  % determine the key that was pressed on the keyboard
  key = parsekeyboardevent(eventdata);
end
% get focus back to figure
if ~strcmp(get(h, 'type'), 'figure')
  set(h, 'enable', 'off');
  drawnow;
  set(h, 'enable', 'on');
end

h = getparent(h);
opt = getappdata(h, 'opt');

switch key
  case 'leftarrow' % change colorlim
    cval = opt.cfg.funcolorlim(1);
    if cval<0
      cval = cval.*1.1;
    else
      cval = cval./1.1;
    end
    opt.cfg.funcolorlim(1) = cval;
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hx, 'Clim', opt.cfg.funcolorlim);
  case 'rightarrow' % change colorlim
    cval = opt.cfg.funcolorlim(2);
    if cval<0
      cval = cval.*1.1;
    else
      cval = cval./1.1;
    end
    opt.cfg.funcolorlim(2) = cval;
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hx, 'Clim', opt.cfg.funcolorlim);
  case 'shift+leftarrow'
    cval = opt.cfg.funcolorlim(1);
    if cval<0
      cval = cval./1.1;
    else
      cval = cval.*1.1;
    end
    opt.cfg.funcolorlim(1) = cval;
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hx, 'Clim', opt.cfg.funcolorlim);
  case 'shift+rightarrow'
    cval = opt.cfg.funcolorlim(2);
    if cval<0
      cval = cval./1.1;
    else
      cval = cval.*1.1;
    end
    opt.cfg.funcolorlim(2) = cval;
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hx, 'Clim', opt.cfg.funcolorlim);
  case 'uparrow' % enhance threshold
    thrval = opt.threshold(2);
    if thrval==0 && opt.cfg.funcolorlim(2)>0
      opt.threshold(2) = opt.cfg.funcolorlim(2).*0.1;
    elseif thrval==0
      opt.threshold(2) = max(opt.dat(:)).*0.1;
    else
      opt.threshold(2) = thrval.*1.1;
    end
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hline1, 'YData', [1 1].*opt.threshold(2));
  case 'shift+uparrow' % enhance threshold
    thrval = opt.threshold(2);
    if thrval>0
      opt.threshold(2) = thrval.*0.9;
    end
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hline1, 'YData', [1 1].*opt.threshold(2));
  case 'downarrow' % lower threshold
    thrval = opt.threshold(1);
    if thrval==0 && opt.cfg.funcolorlim(1)<0
      opt.threshold(1) = opt.cfg.funcolorlim(1).*0.1;
    elseif thrval==0
      opt.threshold(1) = min(opt.dat(:)).*0.1;
    else
      opt.threshold(1) = thrval.*1.1;
    end
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hline2, 'YData', [1 1].*opt.threshold(1));
  case 'shift+downarrow' % lower threshold
    thrval = opt.threshold(1);
    if thrval<0
      opt.threshold(1) = thrval.*0.9;
    end
    setappdata(h, 'opt', opt);
    cb_slider(h);
    set(opt.hline2, 'YData', [1 1].*opt.threshold(1));
  case 'ctrl+uparrow' % change speed
    opt.speed = opt.speed*sqrt(2);
    setappdata(h, 'opt', opt);
  case 'ctrl+downarrow'
    opt.speed = opt.speed/sqrt(2);
    opt.speed = max(opt.speed, 1); % should not be smaller than 1
    setappdata(h, 'opt', opt);
  case 'ctrl+rightarrow' % change channel
  case 'C' % update camera position1.373e-14
    camlight(opt.cam(1), 'left');
    camlight(opt.cam(2), 'right');
  case 'p'
    cb_playbutton(h);
  case 'q'
    cb_quitbutton(h);
  case 'r'
    cb_recordbutton(h);
  case 's'
    % select the speed
    response = inputdlg('speed', 'specify', 1, {num2str(opt.speed)});
    if ~isempty(response)
      opt.speed = str2double(response);
      setappdata(h, 'opt', opt);
    end
  case 't'
    % select the threshold
    response = inputdlg('threshold', 'specify', 1, {num2str(opt.threshold)});
    if ~isempty(response)
      tok = tokenize(response{1}, ' ');
      tok(cellfun(@isempty,tok)) = [];
      for k = 1:numel(tok)
        opt.threshold(1,k) = str2double(tok{k});
      end
      setappdata(h, 'opt', opt);
    end
    set(opt.hline1, 'YData', [1 1].*opt.threshold(2));
    set(opt.hline2, 'YData', [1 1].*opt.threshold(1));
  case 'z'
    % select the colorlim
    response = inputdlg('colorlim', 'specify', 1, {num2str(opt.cfg.funcolorlim)});
    if ~isempty(response)
      tok = tokenize(response{1}, ' ');
      tok(cellfun(@isempty,tok)) = [];
      for k = 1:2
        opt.cfg.funcolorlim(1,k) = str2double(tok{k});
      end
      setappdata(h, 'opt', opt);
      cb_slider(h);
    end
  case 'control+control'
    % do nothing
  case 'shift+shift'
    % do nothing
  case 'alt+alt'
    % do nothing
  otherwise
    setappdata(h, 'opt', opt);
    %cb_help(h);
end
cb_slider(h);
uiresume(h);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function h = getparent(h)
p = h;
while p~=0
  h = p;
  p = get(h, 'parent');
end


%% EMGSignal.m
% This code is about the EMG signal amplitude in each session for all subjects.
% Please set the download directory of your computer for visualization.
% Please add the bbci toolbox in the 'Reference_toolbox' folder

edit EMGSignal_Session1
edit EMGSignal_Session2
edit EMGSignal_Session3


% PutSegyTrace(segyid,tracedata,SegyTraceHeader,SegyHeader)
% Write a SegyTrace to a filehandle 'segyid'
%
% (C) 2001-2012, Thomas Mejer Hansen, thomas.mejer.hansen@gmail.com
%

%
%    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 PutSegyTrace(segyid,tracedata,SegyTraceHeader,SegyHeader);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% WRITE SegyTraceHeader

  if ~exist('TraceStart')==1, TraceStart=ftell(segyid);end

  WRITETRACEHEADER=1;
  if WRITETRACEHEADER==1,
    fseek(segyid,0,'bof');
    fseek(segyid,TraceStart,'bof');
    fwrite(segyid,SegyTraceHeader.TraceSequenceLine,'int32');    % 0
    fwrite(segyid,SegyTraceHeader.TraceSequenceFile,'int32');    % 4
    fwrite(segyid,SegyTraceHeader.FieldRecord,'int32');          % 8
    fwrite(segyid,SegyTraceHeader.TraceNumber,'int32');          % 12
    fwrite(segyid,SegyTraceHeader.EnergySourcePoint,'int32');    % 16
    fwrite(segyid,SegyTraceHeader.cdp,'int32');                  % 20
    fwrite(segyid,SegyTraceHeader.cdpTrace,'int32');             % 24
    fwrite(segyid,SegyTraceHeader.TraceIdentifactionCode,'int16'); % 28
    fwrite(segyid,SegyTraceHeader.NSummedTraces,'int16'); % 30
    fwrite(segyid,SegyTraceHeader.NStackedTraces,'int16'); % 32
    fwrite(segyid,SegyTraceHeader.DataUse,'int16'); % 34
    fwrite(segyid,SegyTraceHeader.offset,'int32');             %36
    fwrite(segyid,SegyTraceHeader.ReceiverGroupElevation,'int32');             %40
    fwrite(segyid,SegyTraceHeader.SourceSurfaceElevation,'int32');             %44
    fwrite(segyid,SegyTraceHeader.SourceDepth,'int32');             %48
    fwrite(segyid,SegyTraceHeader.ReceiverDatumElevation,'int32');             %52
    fwrite(segyid,SegyTraceHeader.SourceDatumElevation,'int32');             %56
    fwrite(segyid,SegyTraceHeader.SourceWaterDepth,'int32');  %60
    fwrite(segyid,SegyTraceHeader.GroupWaterDepth,'int32');  %64
    fwrite(segyid,SegyTraceHeader.ElevationScalar,'int16');  %68
                                                             % Multiply/divide next number for following 4 values
    fwrite(segyid,SegyTraceHeader.SourceGroupScalar,'int16');  %70
    fwrite(segyid,SegyTraceHeader.SourceX,'int32');  %72
    fwrite(segyid,SegyTraceHeader.SourceY,'int32');  %76
    fwrite(segyid,SegyTraceHeader.GroupX,'int32');  %80
    fwrite(segyid,SegyTraceHeader.GroupY,'int32');  %84
    fwrite(segyid,SegyTraceHeader.CoordinateUnits,'int16');  %88
    fwrite(segyid,SegyTraceHeader.WeatheringVelocity,'int16');  %90
    fwrite(segyid,SegyTraceHeader.SubWeatheringVelocity,'int16');  %92
    fwrite(segyid,SegyTraceHeader.SourceUpholeTime,'int16');  %94
    fwrite(segyid,SegyTraceHeader.GroupUpholeTime,'int16');  %96
    fwrite(segyid,SegyTraceHeader.SourceStaticCorrection,'int16');  %98
    fwrite(segyid,SegyTraceHeader.GroupStaticCorrection,'int16');  %100
    fwrite(segyid,SegyTraceHeader.TotalStaticApplied,'int16');  %102
    fwrite(segyid,SegyTraceHeader.LagTimeA,'int16');  %104
    fwrite(segyid,SegyTraceHeader.LagTimeB,'int16');  %106
    fwrite(segyid,SegyTraceHeader.DelayRecordingTime,'int16');  %108
    fwrite(segyid,SegyTraceHeader.MuteTimeStart,'int16');  %110
    fwrite(segyid,SegyTraceHeader.MuteTimeEND,'int16');  %112
    fwrite(segyid,SegyTraceHeader.ns,'uint16');  %114
    fwrite(segyid,SegyTraceHeader.dt,'uint16');  %116
    fwrite(segyid,SegyTraceHeader.GainType,'int16');  %118
    fwrite(segyid,SegyTraceHeader.InstrumentGainConstant,'int16');  %120
    fwrite(segyid,SegyTraceHeader.InstrumentInitialGain,'int16');  %%122
    fwrite(segyid,SegyTraceHeader.Correlated,'int16');  %124
    fwrite(segyid,SegyTraceHeader.SweepFrequenceStart,'int16');  %126
    fwrite(segyid,SegyTraceHeader.SweepFrequenceEnd,'int16');  %128
    fwrite(segyid,SegyTraceHeader.SweepLength,'int16');  %130
    fwrite(segyid,SegyTraceHeader.SweepType,'int16');  %132
    fwrite(segyid,SegyTraceHeader.SweepTraceTaperLengthStart,'int16');  %134
    fwrite(segyid,SegyTraceHeader.SweepTraceTaperLengthEnd,'int16');  %136
    fwrite(segyid,SegyTraceHeader.TaperType,'int16');  %138
    fwrite(segyid,SegyTraceHeader.AliasFilterFrequency,'int16');  %140
    fwrite(segyid,SegyTraceHeader.AliasFilterSlope,'int16');  %142
    fwrite(segyid,SegyTraceHeader.NotchFilterFrequency,'int16');  %144
    fwrite(segyid,SegyTraceHeader.NotchFilterSlope,'int16');  %146
    fwrite(segyid,SegyTraceHeader.LowCutFrequency,'int16');  %148
    fwrite(segyid,SegyTraceHeader.HighCutFrequency,'int16');  %150
    fwrite(segyid,SegyTraceHeader.LowCutSlope,'int16');  %152
    fwrite(segyid,SegyTraceHeader.HighCutSlope,'int16');  %154
    fwrite(segyid,SegyTraceHeader.YearDataRecorded,'int16');  %156
    fwrite(segyid,SegyTraceHeader.DayOfYear,'int16');  %158
    fwrite(segyid,SegyTraceHeader.HourOfDay,'int16');  %160
    fwrite(segyid,SegyTraceHeader.MinuteOfHour,'int16');  %162
    fwrite(segyid,SegyTraceHeader.SecondOfMinute,'int16');  %164
    fwrite(segyid,SegyTraceHeader.TimeBaseCode,'int16');  %166
    fwrite(segyid,SegyTraceHeader.TraceWeightningFactor,'int16');  %170
    fwrite(segyid,SegyTraceHeader.GeophoneGroupNumberRoll1,'int16');  %172
    fwrite(segyid,SegyTraceHeader.GeophoneGroupNumberFirstTraceOrigField,'int16');  %174
    fwrite(segyid,SegyTraceHeader.GeophoneGroupNumberLastTraceOrigField,'int16');  %176
    fwrite(segyid,SegyTraceHeader.GapSize,'int16');  %178
    fwrite(segyid,SegyTraceHeader.OverTravel,'int16');  %178
    fwrite(segyid,SegyTraceHeader.cdpX,'int32');  %180
    fwrite(segyid,SegyTraceHeader.cdpY,'int32');  %184
    fwrite(segyid,SegyTraceHeader.Inline3D,'int32');  %188
    fwrite(segyid,SegyTraceHeader.Crossline3D,'int32');  %192
    fwrite(segyid,SegyTraceHeader.ShotPoint,'int32');  %196
    fwrite(segyid,SegyTraceHeader.ShotPointScalar,'int16');  %200
    fwrite(segyid,SegyTraceHeader.TraceValueMeasurementUnit,'int16');  %202
    fwrite(segyid,SegyTraceHeader.TransductionConstantMantissa,'int32');  %204
    fwrite(segyid,SegyTraceHeader.TransductionConstantPower,'int16'); %208
    fwrite(segyid,SegyTraceHeader.TransductionUnit,'int16');  %210
    fwrite(segyid,SegyTraceHeader.TraceIdentifier,'int16');  %212
    fwrite(segyid,SegyTraceHeader.ScalarTraceHeader,'int16');  %214
    fwrite(segyid,SegyTraceHeader.SourceType,'int16');  %216
    fwrite(segyid,SegyTraceHeader.SourceEnergyDirectionMantissa,'int32');  %218
    fwrite(segyid,SegyTraceHeader.SourceEnergyDirectionExponent,'int16');  %222
    fwrite(segyid,SegyTraceHeader.SourceMeasurementMantissa,'int32');  %224
    fwrite(segyid,SegyTraceHeader.SourceMeasurementExponent,'int16');  %228
    fwrite(segyid,SegyTraceHeader.SourceMeasurementUnit,'int16');  %230
                                                                   % WRITE UNASSIGNED CHARACTERS FOR THE REST
    fwrite(segyid,SegyTraceHeader.UnassignedInt1,'int32');  %232
    fwrite(segyid,SegyTraceHeader.UnassignedInt2,'int32');  %236

  end

  Revision=SegyHeader.SegyFormatRevisionNumber;
  if Revision>0, Revision=1; end
  Format=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).format;
  BPS=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).bps;

  SegymatVerbose([mfilename,' SegyRevision ',sprintf('%0.4g',Revision),', ',Format],3);
  %% WRITE TRACE DATA;
  if (strcmp(Format,'uint32')==1)|(strcmp(Format,'uint16')==1), % IBM FLOATING POINT
                                                                % CONVERT FROM FLOATING POINT
    SegymatVerbose([mfilename,'Converting from IBM, DataFormat :',SegyHeader.DataSampleFormat],2);
    tracedata=double(num2ibm(tracedata));
  end;
  if SegyHeader.FixedLengthTraceFlag
      fwrite(segyid,tracedata,Format);
  else
      fwrite(segyid,tracedata(1:SegyTraceHeader.ns),Format);
  end


% The COBRAToolbox: testConvertCobraToSBML.m
%
% Purpose:
%     - test the convertCobraToSBML function
%
% Authors:
%     - Jacek Wachowiak
global CBTDIR
% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testConvertCobraToSBML'));
cd(fileDir);

% test variables
sbmlLevel = 0;
sbmlVersion = 0;
compSymbolList = '';
compNameList = '';
model = getDistributedModel('ecoli_core_model.mat');

% function outputs
warning('off', 'all')
  sbmlModel = convertCobraToSBML(model, sbmlLevel, sbmlVersion, compSymbolList, compNameList);
  sbmlModel_2 = convertCobraToSBML(model, sbmlLevel, sbmlVersion);
  assert(length(lastwarn()) > 0)
warning('on', 'all')
% test
assert(isequaln(sbmlModel, sbmlModel_2));

% change to old directory
cd(currentDir);


% eegplugin_iirfilt() - EEGLAB plugin for importing data using IIRFILT Matlab toolbox
%
% Usage:
%   >> eegplugin_iirfilt(fig, trystrs, catchstrs);
%
% Inputs:
%   fig        - [integer]  EEGLAB figure
%   trystrs    - [struct] "try" strings for menu callbacks.
%   catchstrs  - [struct] "catch" strings for menu callbacks.
%
% Create a plugin:
%   For more information on how to create an EEGLAB plugin see the
%   help message of eegplugin_besa() or visit http://www.sccn.ucsd.edu/eeglab/contrib.html
%
% Authors: Maksym Pozdin (mpozdin.ece04@gtalumni.org, IOL/ONRC,2004),
%          with Arnaud Delorme and Scott Makeig (SCCN/INC/UCSD, La Jolla CA)

% Copyright (C) 2003 Arnaud Delorme, Salk Institute, arno@salk.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 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 vers = eegplugin_iirfilt(fig, trystrs, catchstrs)

    vers = 'iirfilt1.01';
  if nargin < 3
      error('eegplugin_iirfilt requires 3 arguments');
  end;

  % add besa folder to path
  % -----------------------
  if ~exist('pop_iirfilt')
      p = which('eegplugin_iirfilt');
      p = p(1:findstr(p,'eegplugin_iirfilt.m')-1);
      if ~isdeployed
        addpath([ p vers ] ); end
  end;

  % find import data menu
  % ---------------------
  menu = findobj(fig, 'tag', 'filter');

  % menu callbacks
  % --------------
  combio = [ trystrs.no_check '[EEG LASTCOM] = pop_iirfilt(EEG);' catchstrs.new_and_hist ];

  % create menus if necessary
  % -------------------------
  uimenu( menu, 'Label', 'Short IIR filter',  'CallBack', combio, 'Separator', 'on');


function msns_l_d
%
%  Deletes the global data that has been generated by 'msns_l_i'.
%
%  Calling sequence:
%
%    msns_l_d
%
%
%  LYAPACK 1.0 (Thilo Penzl, May 1999)

global LP_NU

clear global LP_NU


function varargout = horzcat(varargin)
%HORZCAT   Horizontal concatenation of SPHEREFUNV objects.
%   This is not allowed and returns an error.  This function exists so that the
%   error message is meaningful to a SPHEREFUN user.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

error('SPHEREFUN:SPHEREFUNV:horzcat:notSupported', ...
    'Horizontal concatenation of SPHEREFUNV objects is not supported.')

end


function cellarray = remove_str_from_cell(cellarray,str)

    wh = cellfun(@isempty, strfind(cellarray, str));
    cellarray = cellarray(wh);

end