function varargout = BrainNetClass(varargin)

%BrainNet construction and classification toolbox (BrainNetClass) GUI by Zhen Zhou
%  Copyright(c) 2019; GNU GENERAL PUBLIC LICENSE
%  Image Display, Enhancement, and Analysis (IDEA) Group
%  Department of Radiology and Biomedical Research Imaging Center,
%  University of North Carolina, Chapel Hill, NC 27599, USA
%  Written by Zhen Zhou, Han Zhang
%  zzstefan@email.unc.edu, hanzhang@med.unc.edu

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

% Choose default command line output for BrainNetClass

Release='V1.1';
%handles.Release = Release; % Will be used in mat file version checking (e.g., in function SetLoadedData)

if ispc
    UserName =getenv('USERNAME');
else
    UserName =getenv('USER');
end
Datetime=fix(clock);
fprintf('Welcome: %s, %.4d-%.2d-%.2d %.2d:%.2d \n', UserName,Datetime(1),Datetime(2),Datetime(3),Datetime(4),Datetime(5));
fprintf('BrainNet construction and classification toolbox (BrainNetClass) GUI. \nRelease = %s\n',Release);
fprintf('Copyright(c) 2019; GNU GENERAL PUBLIC LICENSE\n');
fprintf('Image Display, Enhancement, and Analysis (IDEA) Group, Department of Radiology and Biomedical Research Imaging Center, University of North Carolina, Chapel Hill, NC 27599, USA;\n');
fprintf('Mail to Author:  Zhen Zhou Han Zhang');
fprintf('\n-----------------------------------------------------------\n');
fprintf('Citing Information:\nIf you think BrainNetClass is useful for your work, citing it in your paper would be greatly appreciated!\nReference: Zhou, Z., Chen, X., Zhang, Y., Qiao, L., Yu, R., Pan, G., Zhang, H., Shen, D., 2019. Brain network construction and classification toolbox (BrainNetClass). arXiv:1906.09908.\n');

BrainNetClassPath=fileparts(which('BrainNetClass.m'));

axes(handles.axes_logo);
axis image;
[A, map, alpha] = imread(fullfile(BrainNetClassPath,'./Pics/logo.png'));
h = imshow(A, map);
set(h, 'AlphaData', alpha);

axes(handles.axes_arrow2);
axis image;
[A, map, alpha] = imread(fullfile(BrainNetClassPath,'/Pics/arrow_down.png'));
h = imshow(A, map);
set(h, 'AlphaData', alpha);

axes(handles.axes6);
axis image;
[A, map, alpha] = imread(fullfile(BrainNetClassPath,'/Pics/arrow_left.png'));
h = imshow(A, map);
set(h, 'AlphaData', alpha);

axes(handles.axes7);
axis image;
[A, map, alpha] = imread(fullfile(BrainNetClassPath,'/Pics/arrow_down.png'));
h = imshow(A, map);
set(h, 'AlphaData', alpha);

axes(handles.axes8);
axis image;
[A, map, alpha] = imread(fullfile(BrainNetClassPath,'/Pics/arrow_down2.png'));
h = imshow(A, map);
set(h, 'AlphaData', alpha);

axes(handles.axes9);
axis image;
[A, map, alpha] = imread(fullfile(BrainNetClassPath,'/Pics/arrow_down2.png'));
h = imshow(A, map);
set(h, 'AlphaData', alpha);

set(handles.lambda1,'Enable','off');
set(handles.lambda2,'Enable','off');
set(handles.clusters,'Enable','off');
%set(handles.step,'Enable','off');
set(handles.window_length,'Enable','off');
%set(handles.lasso_lambda,'Enable','off');
set(handles.sensitivity_test,'Enable','off');

% handles.default.lambda_1=[0.01:0.01:0.05];
% handles.default.lambda_2=[0.01:0.01:0.05];
% handles.default.clusters=[100:100:300];
% handles.default.window_length=[20:10:40];

handles.default.lambda_1=[0.01:0.01:0.1];
handles.default.lambda_2=[0.01:0.01:0.1];
handles.default.clusters=[100:100:800];
handles.default.window_length=[50:10:120];
handles.default.k_times=10;

% User can change the value of lasso_lambda and step
handles.default.lasso_lambda=0.05;
handles.default.step=1;

handles.cross_val='loocv';
set(handles.k_times,'Enable','off');
set(handles.k_times,'String',mat2str(handles.default.k_times));

No_parameter={'PC','tHOFC','aHOFC'};
Parameter_needed={'SR','WSR','SGR','WSGR','GSR','SSGSR','SLR','dHOFC'};
%set(handles.net_method,'String','Network Type I:  No Parameter Required');
set(handles.method_choice,'String',No_parameter);
handles.meth_Type='Network Type I:  No Parameter Required';
handles.meth_Net='PC';
% set(handles.pop_choice_fe,'value','Connection coefficients';
% set(handles.pop_choice_fs,'value','')
%set the initial radiobutton being selected

% axes(handles.axes_arrow1);
% arrow_p1=[0.5 1];
% arrow_p2=[0 -1];
% h=annotation('textarrow');
% set(h,'parent','postition',[arrow_p1 arrow_p2]);

% axes(handles.axes_arrow1);
% h_arrow_axis=annotation('textarrow');
% set(h_arrow_axis,'parent',gca,'position',[0.5 1],[0 -1]);

%uicontrol('Style','text','String',sprintf('Set \x3a9'),'units','characters','Position',[62.142857142857140,25.588235294117645,9.714285714285708,1.058823529411765]);

% handles.laxis = axes('parent',hObject,'units','normalized','position',[0 0 1 1],'visible','off');
% Find all static text UICONTROLS whose 'Tag' starts with latex_
%lbls = findobj(hObject,'-regexp','tag','latex_*');
% for i=1:length(lbls)
%       l = lbls(i);
%       % Get current text, position and tag
%       set(l,'units','normalized');
%       s = get(l,'string');
%       p = get(l,'position');
%       t = get(l,'tag');
%       % Remove the UICONTROL
%       delete(l);
%       % Replace it with a TEXT object
%       %handles.(t) = text(p(1),p(2),s,'interpreter','latex');
%       handles.(t) = text('position',p,'interpreter','latex','string','$\lambda$');
% end

% lbls=findobj(hObject,'-regexp','tag','lambda_1');
% p=get(lbls,'position');
% uicontrol('Style','text','Fontname','Calibri','FontSize',10,'String',sprintf('\x3bb_1'),'units','characters','Position',p);
%
% lbls=findobj(hObject,'-regexp','tag','lambda_2');
% p=get(lbls,'position');
% uicontrol('Style','text','Fontname','Calibri','FontSize',10,'String',sprintf('\x3bb_2'),'units','characters','Position',p);

% lbls=findobj(hObject,'-regexp','tag','lambda_lasso');
% p=get(lbls,'position');
% uicontrol('Style','text','Fontname','Calibri','String',sprintf('    \x3bb lasso for \n feature selection'),'units','characters','Position',p);

% Update handles structure
if ~ispc
    if ismac
        ZoomFactor=0.95;  %For Mac
    else
        ZoomFactor=0.8;  %For Linux
    end
    ObjectNames = fieldnames(handles);
    for i=1:length(ObjectNames);
        eval(['IsFontSizeProp=isprop(handles.',ObjectNames{i},',''FontSize'');']);
        if IsFontSizeProp
            eval(['PCFontSize=get(handles.',ObjectNames{i},',''FontSize'');']);
            FontSize=PCFontSize*ZoomFactor;
            eval(['set(handles.',ObjectNames{i},',''FontSize'',',num2str(FontSize),');']);
        end
    end
end

handles.output = hObject;
guidata(hObject, handles);

% UIWAIT makes test wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = BrainNetClass_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;

% p=[62.142857142857140,25.588235294117645,9.714285714285708,1.058823529411765];
% uicontrol('Style','text','String',sprintf('Set '),'Units','norm','Position',p);
% --- Executes on selection change in net_method.
function net_method_Callback(hObject, eventdata, handles)
% hObject    handle to net_method (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 net_method contents as cell array
%        contents{get(hObject,'Value')} returns selected item from net_method
% contents_net=cellstr(get(hObject,'String'));
% pop_choice_net=contents_net{get(hObject,'Value')};

% if isfield(handles,'meth_Net')
%     set(handles.net_method,'Enable','off');
%     handles=rmfield(handles,'meth_Net');
% end
popStrings_net = cellstr(get(hObject,'String'));
meth_Type=popStrings_net{get(hObject,'Value')};
No_parameter={'PC','tHOFC','aHOFC'};
Parameter_needed={'SR','WSR','SGR','WSGR','GSR','SSGSR','SLR','dHOFC'};
if strcmpi(meth_Type,'Network Type I:  No Parameter Required')

    set(handles.method_choice,'String',No_parameter);
    set(handles.method_choice, 'value', 1);
    set(handles.lambda1,'Enable','off');
    set(handles.lambda2,'Enable','off');
    %set(handles.lasso_lambda,'Enable','off');
    set(handles.clusters,'Enable','off');
    set(handles.window_length,'Enable','off');
    %set(handles.step,'Enable','off');
    set(handles.sensitivity_test,'Enable','off');
    set(handles.fe_method,'Enable','on');
    set(handles.fs_method,'Enable','on');
    set(handles.fe_method,'Value',1);
    set(handles.fs_method,'Value',1);
    meth_Net='PC';
    handles.meth_Net=meth_Net;
    set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf(''));
    set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf(''));
    set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf(''));
elseif strcmpi(meth_Type,'Network Type II: Parameter Required')
    if isfield(handles,'pop_choice_fe')
        handles=rmfield(handles,'pop_choice_fe');
    end
    if isfield(handles,'pop_choice_fs')
        handles=rmfield(handles,'pop_choice_fs');
    end
    set(handles.fs_method,'Value',4);
    set(handles.fe_method,'Value',2);
    set(handles.fe_method,'Enable','off');
    set(handles.fs_method,'Enable','off');
    set(handles.lambda1,'Enable','on','String',mat2str(handles.default.lambda_1));
    set(handles.sensitivity_test,'Value',1);
    %set(handles.method_choice, 'value', 1);
    set(handles.method_choice,'String',Parameter_needed);
    set(handles.sensitivity_test,'Enable','on');
    meth_Net='SR';
    handles.meth_Net=meth_Net;
    set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Lambda controls sparsity'));
    set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Connection coefficients as features'));
    set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('t-test (p<0.05) + LASSO for feature selection'));
    %guidata(hObject,handles);
    if isfield(handles,'meth_Net')
        switch meth_Net
            case{'SR','WSR','GSR','SLR','SSGSR','WSGR','SGR'}
                set(handles.fs_method,'Value',4);
                set(handles.fe_method,'Value',2);
                set(handles.fe_method,'Enable','off');
                set(handles.fs_method,'Enable','off');
            case 'dHOFC'
                set(handles.fs_method,'Value',3);
                set(handles.fe_method,'Value',3);
                set(handles.fe_method,'Enable','off');
                set(handles.fs_method,'Enable','off');
        end
    end
end

handles.meth_Type=meth_Type;
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function net_method_CreateFcn(hObject, eventdata, handles)
% hObject    handle to net_method (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 fs_method.
function fe_method_Callback(hObject, eventdata, handles)
% hObject    handle to fs_method (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 fs_method contents as cell array
%        contents{get(hObject,'Value')} returns selected item from fs_method
contents_fe=cellstr(get(hObject,'String'));
pop_choice_fe=contents_fe{get(hObject,'Value')};
switch pop_choice_fe
    case 'Feature Extraction Method'
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','string',sprintf(''));
        if isfield(handles,'pop_choice_fe')
        handles=rmfield(handles,'pop_choice_fe');
        end
    case 'Connection coefficients'
        tmp='coef';
        %handles.fe_method=tmp;
        handles.fe_display=pop_choice_fe;
        handles.pop_choice_fe=tmp;
        guidata(hObject,handles);
    case 'Local clustering coefficients'
        tmp='clus';
        %handles.fe_method=tmp;
        handles.fe_display=pop_choice_fe;
        handles.pop_choice_fe=tmp;
        guidata(hObject,handles);
end

if isfield(handles,'fe_method')&&~strcmpi(pop_choice_fe,'Feature Extraction Method')
    set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('%s as features',handles.fe_display));
end

% --- Executes during object creation, after setting all properties.
function fe_method_CreateFcn(hObject, eventdata, handles)
% hObject    handle to fs_method (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 fs_method.
function fs_method_Callback(hObject, eventdata, handles)
% hObject    handle to fs_method (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 fs_method contents as cell array
%        contents{get(hObject,'Value')} returns selected item from fs_method
contents_fs=cellstr(get(hObject,'String'));
pop_choice_fs=contents_fs{get(hObject,'Value')};
handles.pop_choice_fs=pop_choice_fs;
guidata(hObject,handles);
if strcmpi(pop_choice_fs,'Feature Selection Method')
    set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','string',sprintf(''));
    if isfield(handles,'pop_choice_fe')
        handles=rmfield(handles,'pop_choice_fe');
    end
elseif isfield(handles,'fs_method')
    set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',...
        sprintf('%s for feature selection',pop_choice_fs));
end

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

% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (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 method_choice.
function method_choice_Callback(hObject, eventdata, handles)
% hObject    handle to method_choice (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 method_choice contents as cell array
%        contents{get(hObject,'Value')} returns selected item from method_choice
% popStrings_net_2 = handles.method_choice.String;
% selectedIndex_net_2 = handles.method_choice.Value;
% meth_Net = popStrings_net_2{selectedIndex_net_2};
contents=cellstr(get(hObject,'String'));
meth_Net=contents{get(hObject,'Value')};
handles.meth_Net=meth_Net;
guidata(hObject,handles);

switch meth_Net
    case {'SR','WSR'}
        set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Lambda controls sparsity'));
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Connection coefficients as features'));
        set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('t-test (p<0.05) + LASSO for feature selection'));
    case 'GSR'
        set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Lambda controls group sparsity'));
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Connection coefficients as features'));
        set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('t-test (p<0.05) + LASSO for feature selection'));
    case 'SLR'
        set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Lambda 1 controls low_rank \nLambda 2 controls sparsity'));
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Connection coefficients as features'));
        set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('t-test (p<0.05) + LASSO for feature selection'));
    case {'SGR','WSGR'}
        set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',...
            sprintf('Lambda 1 controls sparsity \nLambda 2 controls group sparsity'));
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Connection coefficients as features'));
        set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('t-test (p<0.05) + LASSO for feature selection'));
    case 'SSGSR'
        set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',...
            sprintf('Lambda 1 controls group sparsity \nLambda 2 controls inter-subject LOFC-pattern similarity'));
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Connection coefficients as features'));
        set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('t-test (p<0.05) + LASSO for feature selection'));
    case 'dHOFC'
        set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Step normally set to 1'));
        set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('Local clustering coefficients as features'));
        set(handles.fs_details,'HorizontalAlignment','left','Fontname','Calibri','ForegroundColor',[0.3 0.75 0.93],'string',sprintf('LASSO for feature selection'));
end

if strcmp(meth_Net,'SR')||strcmp(meth_Net,'WSR')||strcmp(meth_Net,'GSR')
    set(handles.lambda2,'Enable','off');
    set(handles.window_length,'Enable','off');
    %set(handles.step,'Enable','off');
    set(handles.clusters,'Enable','off');
    set(handles.lambda1,'Enable','on','String',mat2str(handles.default.lambda_1));
    %set(handles.lasso_lambda,'Enable','on','String',num2str(handles.default.lasso_lambda));
    set(handles.sensitivity_test,'Enable','on');
    %set(handles.sensitivity_test,'ForegroundColor','k');
elseif strcmp(meth_Net,'SLR')||strcmp(meth_Net,'SGR')||strcmp(meth_Net,'WSGR')||strcmp(meth_Net,'SSGSR')
    set(handles.window_length,'Enable','off');
    %set(handles.step,'Enable','off');
    set(handles.clusters,'Enable','off');
    set(handles.lambda1,'Enable','on','String',mat2str(handles.default.lambda_1));
    %set(handles.lasso_lambda,'Enable','on','String',num2str(handles.default.lasso_lambda));
    set(handles.lambda2,'Enable','on','String',mat2str(handles.default.lambda_1));
    set(handles.sensitivity_test,'Enable','on');
    %set(handles.sensitivity_test,'ForegroundColor','k');
elseif strcmp(meth_Net,'dHOFC')
    set(handles.lambda1,'Enable','off');
    set(handles.lambda2,'Enable','off');
    %set(handles.lasso_lambda,'Enable','on','String',num2str(handles.default.lasso_lambda));
    set(handles.clusters,'Enable','on','String',mat2str(handles.default.clusters));
    set(handles.window_length,'Enable','on','String',mat2str(handles.default.window_length));
    %set(handles.step,'Enable','on','String',num2str(handles.default.step));
    set(handles.sensitivity_test,'Enable','on');
    %set(handles.sensitivity_test,'ForegroundColor','k');
end

switch meth_Net
    case{'SR','WSR','SLR','SGR','WSGR','GSR','SSGSR'}
        set(handles.fs_method,'Value',4);
        set(handles.fe_method,'Value',2);
        set(handles.fe_method,'Enable','off');
        set(handles.fs_method,'Enable','off');
    case 'dHOFC'
        set(handles.fs_method,'Value',3);
        set(handles.fe_method,'Value',3);
        set(handles.fe_method,'Enable','off');
        set(handles.fs_method,'Enable','off');
end

% --- Executes during object creation, after setting all properties.
function method_choice_CreateFcn(hObject, eventdata, handles)
% hObject    handle to method_choice (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 button press in run_withparam.
function run_withparam_Callback(hObject, eventdata, handles)
% hObject    handle to run_withparam (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
sign_input=isfield(handles,'BOLD');
sign_output=isfield(handles,'result_dir');
sign_label=isfield(handles,'label');
sign_FEX=isfield(handles,'pop_choice_fe');
sign_FS=isfield(handles,'pop_choice_fs');

switch handles.meth_Type
    case 'Network Type I:  No Parameter Required'
       sign_all_char={'input data','output directory','label','feature extraction method','feature selection method'};
       sign_all_char=string(sign_all_char);

        sign_all=[sign_input,sign_output,sign_label,sign_FEX,sign_FS];
        if sum(sign_all)<5
            index=find(sign_all==0);
            temp='You need to specify: ';
            missing_inputs=length(index);
            i=1;
            while missing_inputs>=i
                if i==missing_inputs
                    temp=strcat(temp,sign_all_char(index(i)),'.');
                else
                    temp=strcat(temp,sign_all_char(index(i)),',',{' '});
                end
                i=i+1;
            end
            uiwait(msgbox(temp,'Warning','modal'));
            return;
        end
    case 'Network Type II: Parameter Required'
        sign_all_char={'input data','output directory','label'};
        sign_all_char=string(sign_all_char);
        sign_all=[sign_input,sign_output,sign_label];
        if sum(sign_all)<3
            index=find(sign_all==0);
            temp='You need to specify: ';
            missing_inputs=length(index);
            i=1;
            while missing_inputs>=i
                if i==missing_inputs
                    temp=strcat(temp,sign_all_char(index(i)),'.');
                else
                    temp=strcat(temp,sign_all_char(index(i)),',',{' '});
                end
                i=i+1;
            end
            uiwait(msgbox(temp,'Warning','modal'));
            return;
        end
end

BOLD=handles.BOLD;
[~,nROI]=size(BOLD{1});
label=handles.label;
nSubj=length(label);

result_dir=handles.result_dir;
if handles.sensitivity_test.Value==1
    para_test_flag=1;
else
    para_test_flag=0;
end

if strcmpi(handles.meth_Type,'Network Type I:  No Parameter Required')
    meth_Net=handles.meth_Net;
    meth_FEX=handles.pop_choice_fe;
    meth_FS=handles.pop_choice_fs;

%     memory_needed=nSubj*nROI*nROI*4/(1024*1024*1024);
%     msg=sprintf('The whole program needs at least %3.4f GB memory to run.',memory_needed);
%     uiwait(msgbox({msg,'If your the RAM of your computer is not enough,','you may change to another computer with larger RAM','or switch to the no-parameter required construction method!'},'modal','warn'));
%
    if strcmpi(handles.cross_val,'loocv')
        switch meth_FS
            case 't-test'
                [AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest]=no_param_select(result_dir,meth_Net,meth_FEX,meth_FS,BOLD,label,handles.default.lasso_lambda);
                if AUC==0
                    uiwait(msgbox('AUC=0,you may need to add more samples or change a different feature extraction method.','Warning','modal'));
                    return;
                end
                [result_features]=back_find_low_node_Nopara(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,meth_FEX,meth_FS,feature_index_ttest);
            case 'LASSO'
                [AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_lasso]=no_param_select(result_dir,meth_Net,meth_FEX,meth_FS,BOLD,label,handles.default.lasso_lambda);
                 if AUC==0
                    uiwait(msgbox('AUC=0,you may need to add more samples or change a different feature extraction method.','Warning','modal'));
                    return;
                end
                [result_features]=back_find_low_node_Nopara(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,meth_FEX,meth_FS,feature_index_lasso);
            case 't-test + LASSO'
                [AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest,feature_index_lasso]=no_param_select(result_dir,meth_Net,meth_FEX,meth_FS,BOLD,label,handles.default.lasso_lambda);
                 if AUC==0
                    uiwait(msgbox('AUC=0,you may need to add more samples or change a different feature extraction method.','Warning','modal'));
                    return;
                end
                [result_features]=back_find_low_node_Nopara(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,meth_FEX,meth_FS,feature_index_ttest,feature_index_lasso);
        end
    elseif strcmpi(handles.cross_val,'10-fold')
        switch meth_FS
            case 't-test'
                [AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest]=no_param_select_kfold(handles.default.k_times,result_dir,meth_Net,meth_FEX,meth_FS,BOLD,label,handles.default.lasso_lambda);
                 if AUC==0
                    uiwait(msgbox('AUC=0,you may need to add more samples or change a different feature extraction method.','Warning','modal'));
                    return;
                end
                [result_features]=back_find_low_node_Nopara(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,meth_FEX,meth_FS,feature_index_ttest);
            case 'LASSO'
                [AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_lasso]=no_param_select_kfold(handles.default.k_times,result_dir,meth_Net,meth_FEX,meth_FS,BOLD,label,handles.default.lasso_lambda);
                 if AUC==0
                    uiwait(msgbox('AUC=0,you may need to add more samples or change a different feature extraction method.','Warning','modal'));
                    return;
                end
                [result_features]=back_find_low_node_Nopara(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,meth_FEX,meth_FS,feature_index_lasso);
            case 't-test + LASSO'
                [AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest,feature_index_lasso]=no_param_select_kfold(handles.default.k_times,result_dir,meth_Net,meth_FEX,meth_FS,BOLD,label,handles.default.lasso_lambda);
                 if AUC==0
                    uiwait(msgbox('AUC=0,you may need to add more samples or change a different feature extraction method.','Warning','modal'));
                    return;
                end
                [result_features]=back_find_low_node_Nopara(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,meth_FEX,meth_FS,feature_index_ttest,feature_index_lasso);
        end
    end
        write_log(result_dir,meth_Net,handles.cross_val,AUC,SEN,SPE,F1,Acc,Youden,BalanceAccuracy,meth_FEX,meth_FS,handles.default.k_times,handles.default.lasso_lambda);
else

    meth_Net=handles.meth_Net;
    switch meth_Net
        case {'SR','WSR','GSR'}
            memory_needed=nSubj*nROI*nROI*4*length(handles.default.lambda_1)/(1024*1024*1024);
        case {'SLR','SGR','WSGR','SSGSR'}
            memory_needed=nSubj*nROI*nROI*4*length(handles.default.lambda_1)*length(handles.default.lambda_2)/(1024*1024*1024);
        case 'dHOFC'
            memory_needed=sum(nSubj*4*length(handles.default.window_length)*(handles.default.clusters.*handles.default.clusters))/(1024*1024*1024);
    end
    msg=sprintf('The whole program needs at least %3.4f GB memory to run.',memory_needed);
    answer=questdlg({msg,'If the physical memory of your computer is not enough,','you may change to another PC or server/cluster with larger RAM','or switch to a method that does not need parameter tuning.'},...
        'Warning','Continue','Stop','Continue');
    switch answer
        case 'Continue'

        case 'Stop'
            error('Stop by user.');
    end

    if strcmpi(handles.cross_val,'loocv')
        switch meth_Net
            case {'SR','WSR','GSR'}
                [opt_paramt,opt_t,AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest,feature_index_lasso]=param_select(result_dir,meth_Net,BOLD,label,para_test_flag,handles.default.lambda_1,handles.default.lasso_lambda);
            case {'SLR','SGR','WSGR','SSGSR'}
                [opt_paramt,opt_t,AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest,feature_index_lasso]=param_select(result_dir,meth_Net,BOLD,label,para_test_flag,handles.default.lambda_1,handles.default.lambda_2,handles.default.lasso_lambda);
            case 'dHOFC'
                [opt_paramt,opt_t,AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_lasso,IDX]=param_select(result_dir,meth_Net,BOLD,label,para_test_flag,handles.default.window_length,handles.default.step,handles.default.clusters,handles.default.lasso_lambda);
        end
    elseif strcmpi(handles.cross_val,'10-fold')
        switch meth_Net
            case {'SR','WSR','GSR'}
                [opt_paramt,opt_t,AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest,feature_index_lasso]=param_select_kfold(handles.default.k_times,result_dir,meth_Net,BOLD,label,para_test_flag,handles.default.lambda_1,handles.default.lasso_lambda);
            case {'SLR','SGR','WSGR','SSGSR'}
                [opt_paramt,opt_t,AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_ttest,feature_index_lasso]=param_select_kfold(handles.default.k_times,result_dir,meth_Net,BOLD,label,para_test_flag,handles.default.lambda_1,handles.default.lambda_2,handles.default.lasso_lambda);
            case 'dHOFC'
                [opt_paramt,opt_t,AUC,SEN,SPE,F1,Acc,w,Youden,BalanceAccuracy,feature_index_lasso,IDX]=param_select_kfold(handles.default.k_times,result_dir,meth_Net,BOLD,label,para_test_flag,handles.default.window_length,handles.default.step,handles.default.clusters,handles.default.lasso_lambda);
        end
    end

    switch meth_Net
        case {'SR','WSR','GSR'}
            [result_features]=back_find_low_node_para(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,feature_index_ttest,feature_index_lasso);
            write_log(result_dir,meth_Net,handles.cross_val,AUC,SEN,SPE,F1,Acc,Youden,BalanceAccuracy,handles.default.lambda_1,handles.default.lasso_lambda,opt_paramt,handles.default.k_times,opt_t);
        case {'SGR','WSGR','SSGSR','SLR'}
            [result_features]=back_find_low_node_para(result_dir,nSubj,handles.default.k_times,nROI,w,handles.cross_val,feature_index_ttest,feature_index_lasso);
            write_log(result_dir,meth_Net,handles.cross_val,AUC,SEN,SPE,F1,Acc,Youden,BalanceAccuracy,handles.default.lambda_1,handles.default.lambda_2,handles.default.lasso_lambda,opt_paramt,handles.default.k_times,opt_t);
        case 'dHOFC'
            [result_features]=back_find_high_node(handles.default.window_length,handles.default.clusters,nROI,w,feature_index_lasso,IDX,opt_t);
            write_log(result_dir,meth_Net,handles.cross_val,AUC,SEN,SPE,F1,Acc,Youden,BalanceAccuracy,handles.default.window_length,handles.default.step,handles.default.clusters,handles.default.lasso_lambda,opt_paramt,handles.default.k_times,opt_t);
    end
    set(handles.parameter,'string',opt_paramt);
end

save (char(strcat(result_dir,'/result_features.mat')),'result_features');
set(handles.Result_details,'HorizontalAlignment','left','Fontname','Calibri','FontSize',10,...
    'string',sprintf('AUC: %0.4g\nACC: %3.2f%%\nSEN: %3.2f%%\nSPE: %3.2f%%\nF-score: %3.2f%%',AUC,Acc,SEN,SPE,F1));

uiwait(msgbox('All Jobs Completed.','modal'));
% --- Executes on button press in select_dir.

function select_dir_Callback(hObject, eventdata, handles)
% hObject    handle to select_dir (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

folderName = uigetdir();
set(handles.data_dir,'string',folderName);
%
% file_extension=any(size(dir([folderName '/*.mat']),1));
% if file_extension==1
%     dirOutput=dir(fullfile(folderName,'*.mat'));
% else
%     dirOutput=dir(fullfile(folderName,'*.txt'));
% end
% fileName={dirOutput.name}';
% folder={dirOutput.folder}';
% [cs,index]=sort_nat(fileName);
% for i=1:length(fileName)
%     load([folder{i},'/',fileName{index(i)}]);
%     BOLD{i}=ROISignals;
% end
% handles.file_extension=file_extension;

file_extension=any(size(dir([folderName '/*.csv']),1));
if file_extension==1
    dirOutput=dir(fullfile(folderName,'*.csv'));
else
    dirOutput=dir(fullfile(folderName,'*.txt'));
end
fileName={dirOutput.name}';
%folder={dirOutput.folder}';
for i=1:length(fileName)
    BOLD{i,1}=load([folderName,'/',fileName{i}]);
end
handles.file_extension=file_extension;

handles.BOLD=BOLD;
guidata(hObject,handles);

% --- If Enable == 'on', executes on mouse press in 5 pixel border.
% --- Otherwise, executes on mouse press in 5 pixel border or over parameter.
function parameter_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to parameter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

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

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

% --- Executes during object creation, after setting all properties.
function label_file_CreateFcn(hObject, eventdata, handles)
% hObject    handle to label_file (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 select_label.
function select_label_Callback(hObject, eventdata, handles)
% hObject    handle to select_label (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% if handles.file_extension ==1
%     [label_fileName,path]=uigetfile('.mat','please select the label file');
% else
%     [label_fileName,path]=uigetfile('.txt','please select the label file');
% end

[label_fileName,path]=uigetfile('.txt','please select the label file');

label=importdata(fullfile(path,label_fileName));

set(handles.label_file,'string',label_fileName);

handles.label=label;
guidata(hObject,handles);

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

% lambda_1=get(hObject,'String');
% temp=strsplit(lambda_1,' ');
% lambda_1=str2double(temp);
% handles.lambda_1=lambda_1;
% guidata(hObject,handles);
lambda_1=get(hObject,'String');
handles.default.lambda_1=eval(['[',lambda_1,']']);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function lambda1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to lambda1 (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 lambda2_Callback(hObject, eventdata, handles)
% hObject    handle to lambda2 (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 lambda2 as text
%        str2double(get(hObject,'String')) returns contents of lambda2 as a double
% lambda_2=get(hObject,'String');
% temp=strsplit(lambda_2,' ');
% lambda_2=str2double(temp);
% handles.lambda_2=lambda_2;
% guidata(hObject,handles);

lambda_2=get(hObject,'String');
handles.default.lambda_2=eval(['[',lambda_2,']']);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function lambda2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to lambda2 (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 window_length_Callback(hObject, eventdata, handles)
% hObject    handle to window_length (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 window_length as text
%        str2double(get(hObject,'String')) returns contents of window_length as a double
% window_length=get(hObject,'String');
% temp=strsplit(window_length,' ');
% window_length=str2double(temp);
% handles.window_length=window_length;
% guidata(hObject,handles);

window_length=get(hObject,'String');
handles.default.window_length=eval(['[',window_length,']']);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function window_length_CreateFcn(hObject, eventdata, handles)
% hObject    handle to window_length (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 clusters_Callback(hObject, eventdata, handles)
% hObject    handle to clusters (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 clusters as text
%        str2double(get(hObject,'String')) returns contents of clusters as a double
% clusters=get(hObject,'String');
% temp=strsplit(clusters,' ');
% clusters=str2double(temp);
% handles.clusters=clusters;
% guidata(hObject,handles);

clusters=get(hObject,'String');
handles.default.clusters=eval(['[',clusters,']']);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function clusters_CreateFcn(hObject, eventdata, handles)
% hObject    handle to clusters (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 lasso_lambda_CreateFcn(hObject, eventdata, handles)
% hObject    handle to lasso_lambda (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 axes1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (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 axes1

% --- Executes during object creation, after setting all properties.
function run_withparam_CreateFcn(hObject, eventdata, handles)
% hObject    handle to run_withparam (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 select_label_CreateFcn(hObject, eventdata, handles)
% hObject    handle to select_label (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 lambda_1_CreateFcn(hObject, eventdata, handles)
% % hObject    handle to lambda_1 (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 loocv.
function loocv_Callback(hObject, eventdata, handles)
% hObject    handle to loocv (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 loocv

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

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

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

% --- Executes during object creation, after setting all properties.
function output_dir_CreateFcn(hObject, eventdata, handles)
% hObject    handle to output_dir (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 select_outdir.
function select_outdir_Callback(hObject, eventdata, handles)
% hObject    handle to select_outdir (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
folderName = uigetdir();
handles.result_dir=folderName;
set(handles.output_dir,'string',folderName);
guidata(hObject,handles);

% --- Executes when selected object is changed in uibuttongroup1.
function uibuttongroup1_SelectionChangedFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in uibuttongroup1
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
switch(get(eventdata.NewValue,'Tag'))
    case 'loocv'
        handles.cross_val=get(handles.loocv,'string');
        set(handles.k_times,'Enable','off');
    case 'k_fold'
        handles.cross_val=get(handles.k_fold,'string');
        set(handles.k_times,'Enable','on');
end
guidata(hObject,handles);

function k_times_Callback(hObject, eventdata, handles)
% hObject    handle to k_times (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 k_times as text
%        str2double(get(hObject,'String')) returns contents of k_times as a double
k=get(hObject,'String');
handles.default.k_times=eval(['[',k,']']);
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function k_times_CreateFcn(hObject, eventdata, handles)
% hObject    handle to k_times (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 reset_para(handles)
%     set(handles.window_length,'Enable','off');
%     %set(handles.step,'Enable','off');
%     set(handles.clusters,'Enable','off');
%     set(handles.lambda1,'Enable','off');
%     %set(handles.lasso_lambda,'Enable','off');
%     set(handles.lambda2,'Enable','off');
%     set(handles.sensitivity_test,'Enable','off');
%     set(handles.lambda_details,'HorizontalAlignment','left','Fontname','Calibri','string',sprintf(''));
%     set(handles.fe_details,'HorizontalAlignment','left','Fontname','Calibri','string',sprintf(''));
%     set(handles.fe_method,'Enable','on');
%     set(handles.fs_method,'Enable','on');
%     set(handles.fe_method,'Value',1);
%     set(handles.fs_method,'Value',1);


function [s] = fslHwrite(P,DIM,VOX,SCALE,TYPE,OFFSET,ORIGIN,DESCRIP)
% writes a header
% FORMAT [s] = spm_hwrite(P,DIM,VOX,SCALE,TYPE,OFFSET,ORIGIN,DESCRIP);
%
% P       - filename 	     (e.g 'spm' or 'spm.img')
% DIM     - image size       [i j k [l]] (voxels)
% VOX     - voxel size       [x y z [t]] (mm [sec])
% SCALE   - scale factor
% TYPE    - datatype (integer - see spm_type)
% OFFSET  - offset (bytes)
% ORIGIN  - [i j k] of origin  (default = [0 0 0])
% DESCRIP - description string (default = 'spm compatible')
%
% s       - number of elements successfully written (should be 348)
%___________________________________________________________________________
%
% spm_hwrite writes variables from working memory into a SPM/ANALYZE
% compatible header file.  The 'originator' field of the ANALYZE format has
% been changed to ORIGIN in the SPM version of the header. funused1
% of the ANALYZE format is used for SCALE
%
% see also dbh.h (ANALYZE) spm_hread.m and spm_type.m
%
%__________________________________________________________________________
% @(#)spm_hwrite.m	2.2 99/10/29

% ensure correct suffix {.hdr} and open header file
%---------------------------------------------------------------------------
P               = P(P ~= ' ');
q    		= length(P);
if q>=4 & P(q - 3) == '.', P = P(1:(q - 4)); end;
P     		= [P '.hdr'];

% For byte swapped data-types, also swap the bytes around in the headers.
mach = 'native';
%if spm_type(TYPE,'swapped'),
%	if spm_platform('bigend'),
		mach = 'ieee-le';
%	else,
%		mach = 'ieee-be';
%	end;
%	TYPE = spm_type(spm_type(TYPE));
%end;
fid             = fopen(P,'w',mach);

if (fid == -1),
	error(['Error opening ' P '. Check that you have write permission.']);
end;
%---------------------------------------------------------------------------
data_type 	= ['dsr      ' 0];

P     		= [P '                  '];
db_name		= [P(1:17) 0];

% set header variables
%---------------------------------------------------------------------------
DIM		= DIM(:)'; if size(DIM,2) < 4; DIM = [DIM 1]; end
VOX		= VOX(:)'; if size(VOX,2) < 4; VOX = [VOX 0]; end
dim		= [4 DIM(1:4) 0 0 0];
pixdim		= [0 VOX(1:4) 0 0 0];
vox_offset      = OFFSET;
funused1	= SCALE;
glmax		= 1;
glmin		= 0;
bitpix 		= 0;
descrip         = zeros(1,80);
aux_file        = ['none                   ' 0];
origin          = [0 0 0 0 0];

%---------------------------------------------------------------------------
if TYPE == 1;   bitpix = 1;  glmax = 1;        glmin = 0;	end
if TYPE == 2;   bitpix = 8;  glmax = 255;      glmin = 0;	end
if TYPE == 4;   bitpix = 16; glmax = 32767;    glmin = 0;  	end
if TYPE == 8;   bitpix = 32; glmax = (2^31-1); glmin = 0;	end
if TYPE == 16;  bitpix = 32; glmax = 1;        glmin = 0;	end
if TYPE == 64;  bitpix = 64; glmax = 1;        glmin = 0;	end

%---------------------------------------------------------------------------
if nargin >= 7; origin = [ORIGIN(:)' 0 0];  end
if nargin <  8; DESCRIP = 'spm compatible'; end

d          	= 1:min([length(DESCRIP) 79]);
descrip(d) 	= DESCRIP(d);

fseek(fid,0,'bof');

% write (struct) header_key
%---------------------------------------------------------------------------
fwrite(fid,348,		'int32');
fwrite(fid,data_type,	'char' );
fwrite(fid,db_name,	'char' );
fwrite(fid,0,		'int32');
fwrite(fid,0,		'int16');
fwrite(fid,'r',		'char' );
fwrite(fid,'0',		'char' );

% write (struct) image_dimension
%---------------------------------------------------------------------------
fseek(fid,40,'bof');

fwrite(fid,dim,		'int16');
fwrite(fid,'mm',	'char' );
fwrite(fid,0,		'char' );
fwrite(fid,0,		'char' );

fwrite(fid,zeros(1,8),	'char' );
fwrite(fid,0,		'int16');
fwrite(fid,TYPE,	'int16');
fwrite(fid,bitpix,	'int16');
fwrite(fid,0,		'int16');
fwrite(fid,pixdim,	'float');
fwrite(fid,vox_offset,	'float');
fwrite(fid,funused1,	'float');
fwrite(fid,0,		'float');
fwrite(fid,0,		'float');
fwrite(fid,0,		'float');
fwrite(fid,0,		'float');
fwrite(fid,0,		'int32');
fwrite(fid,0,		'int32');
fwrite(fid,glmax,	'int32');
fwrite(fid,glmin,	'int32');

% write (struct) image_dimension
%---------------------------------------------------------------------------
fwrite(fid,descrip,	'char');
fwrite(fid,aux_file,    'char');
fwrite(fid,0,           'char');
fwrite(fid,origin,      'int16');
if fwrite(fid,zeros(1,85), 'char')~=85
	fclose(fid);
%	spm_unlink(P);
	error(['Error writing ' P '. Check your disk space.']);
end

s   = ftell(fid);
fclose(fid);


classdef PTKAirways < PTKPlugin
    % PTKAirways. Plugin for segmenting the pulmonary airways from CT data
    %
    %     This is a plugin for the Pulmonary Toolkit. Plugins can be run using
    %     the gui, or through the interfaces provided by the Pulmonary Toolkit.
    %     See PTKPlugin.m for more information on how to run plugins.
    %
    %     Plugins should not be run directly from your code.
    %
    %     PTKAirways calls the PTKTopOfTrachea plugin to find the trachea
    %     location, and then runs the library routine
    %     PTKAirwayRegionGrowingWithExplosionControl to obtain the
    %     airway segmentation. The results are stored in a heirarchical tree
    %     structure.
    %
    %     The output image generated by GenerateImageFromResults creates a
    %     colour-coded segmentation image with true airway points shown as blue
    %     and explosion points shown in red.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD Pulmonary Toolkit. https://github.com/tomdoel/pulmonarytoolkit
    %     Author: Tom Doel, 2012.  www.tomdoel.com
    %     Distributed under the GNU GPL v3 licence. Please see website for details.
    %

    properties
        ButtonText = 'Airways'
        ToolTip = 'Shows a segmentation of the airways illustrating deleted points'
        Category = 'Airways'

        AllowResultsToBeCached = true
        AlwaysRunPlugin = false
        PluginType = 'ReplaceOverlay'
        HidePluginInDisplay = false
        FlattenPreviewImage = true
        PTKVersion = '1'
        ButtonWidth = 6
        ButtonHeight = 2
        GeneratePreview = true
        Version = 2
    end

    methods (Static)
        function results = RunPlugin(dataset, reporting)
            trachea_results = dataset.GetResult('PTKTopOfTrachea');

            if dataset.IsGasMRI
                threshold = dataset.GetResult('PTKThresholdGasMRIAirways');
                coronal_mode = false;
            elseif strcmp(dataset.GetImageInfo.Modality, 'MR')
                lung_threshold = dataset.GetResult('PTKMRILungThreshold');
                threshold = lung_threshold.LungMask;
                threshold_raw = threshold.RawImage;
                se = ones(1, 3, 10);
                threshold_raw_c = imopen(threshold_raw, se);
                threshold.ChangeRawImage(threshold_raw_c);
                coronal_mode = true;

            else
                threshold = dataset.GetResult('PTKThresholdLungInterior');
                coronal_mode = false;
            end

            % We use results from the trachea finding to remove holes in the
            % trachea, which can otherwise cause early branching of the airway
            % algorithm
            threshold.SetIndexedVoxelsToThis(trachea_results.trachea_voxels, true);

            start_point = trachea_results.top_of_trachea;

            if PTKSoftwareInfo.FastMode
                maximum_number_of_generations = 10;
            else
                maximum_number_of_generations = 15;
            end

            explosion_multiplier = 4;

            debug_mode = PTKSoftwareInfo.GraphicalDebugMode;
            results = PTKAirwayRegionGrowingWithExplosionControl(threshold, start_point, maximum_number_of_generations, explosion_multiplier, coronal_mode, reporting, debug_mode);
        end

        function results = GenerateImageFromResults(airway_results, image_templates, reporting)
            template_image = image_templates.GetTemplateImage(PTKContext.LungROI);
            results = PTKGetImageFromAirwayResults(airway_results.AirwayTree, template_image, false, reporting);
            results_raw = results.RawImage;
            explosion_points = template_image.GlobalToLocalIndices(airway_results.ExplosionPoints);
            results_raw(explosion_points) = 3;
            results.ChangeRawImage(results_raw);
       end
    end
end


function [candidates, priority] = run_rantalankila(im, num_candidates, varargin)
  if ~isdeployed
    old_path = path;
    addpath(fullfile('..', 'Rantalankila'));
    addpath(fullfile('..', 'Rantalankila', 'GCMex'));
    addpath(fullfile('..', 'Rantalankila', 'features'));
    addpath(fullfile('..', 'Rantalankila', 'vlfeat-0.9.18', 'toolbox', 'mex', 'mexa64'));

  end

  opts = get_opts();

  interp_data = load('/path/to/all/rantalankila_num_candidates_interpolation_data.mat');
  if num_candidates <= min(interp_data.num_candidates)
    opts.gc_branches = 0;
  elseif num_candidates >= max(interp_data.num_candidates)
    opts.gc_branches = 500;
  else
    opts.gc_branches = interp1(interp_data.num_candidates, interp_data.gc_branches, num_candidates);
    assert(~isnan(opts.gc_branches));
  end

  argl = length(varargin);
  if mod(argl,2) ~= 0 % string-value pairs
      error('Give pairs of extra arguments.');
  end
  for argi = 0:((argl/2) - 1)
      arg_str = varargin(2*argi + 1);
      arg_val = varargin(2*argi + 2);
      assert(isfield(opts, arg_str{1}));
      opts.(arg_str{1}) = arg_val{1};
  end

  opts.seg_method = 'felz';
  try
    [region_parts{1}, orig_sp{1}] = spagglom(im, opts);
  catch
    fprintf('rantalankila run on felsenzwalb segmentation failed\n');
  end
  opts.seg_method = 'slic';
  [region_parts{2}, orig_sp{2}] = spagglom(im, opts);

  candidates = sp_to_candidates(im, region_parts, orig_sp);
  priority = [];

  if ~isdeployed
    path(old_path);
  end
end

function bboxes = sp_to_candidates(im, region_parts, orig_sp)
%   candidates = [];
%   for sus = 1:length(orig_sp)
%     ys = double(orig_sp{sus}.pixels(:,1));
%     xs = double(orig_sp{sus}.pixels(:,2));
%     candidates = cat(1, candidates, [min(xs), min(ys), max(xs), max(ys)]);
%   end

  [h, w, ~] = size(im);

    % For each sp of orig_sp, find its bounding box
    for region_set = 1:length(region_parts)
        sp_edges{region_set} = zeros(length(orig_sp{region_set}), 4);
        bboxes{region_set} = zeros(length(region_parts{region_set}), 4);

        % find edges of Ri
        for ses = 1:length(orig_sp{region_set})
            Ri = false(h, w); % note ',', not '*' as below
            Ri(orig_sp{region_set}{ses}.spind) = 1;
            Xi = sum(Ri,1);
            Yi = sum(Ri,2);
            sp_edges{region_set}(ses,:) = [find(Xi,1,'first'), find(Yi,1,'first'), find(Xi,1,'last'), find(Yi,1,'last')];
        end

        % Using the above bounding boxes, solve bounding box of each region
        % proposal
        for j = 1:length(region_parts{region_set})
            sus = region_parts{region_set}{j};
            if ~isempty(sus)
                tg = sp_edges{region_set}(sus,:);
                bboxes{region_set}(j,:) = [min(tg(:,1)), min(tg(:,2)), max(tg(:,3)), max(tg(:,4))]; % bounding box is the most extreme values of individual bounding boxes
            else
              error('what is this?');
                bboxes = [];
            end
        end
    end % for each region set

    bboxes = cat(1, bboxes{:});
end

function [opts] = get_opts()
% Sets options for spagglom.m that are propagated through the functions. Many of the
% options are zero/one flags. The default settings were used to produce the
% results presented in the paper.

%% Superpixelation stage
opts.seg_method = 'slic'; % 'felz', 'slic' or 'qshift'. Two first recommended

% Felzenswalb superpixelation parameters
opts.felz_k = 50; % default 50
opts.felz_sigma = 0.8; % default 0.8
opts.felz_min_area = 150; % default 150

% SLIC superpixelation parameters
opts.slic_regularizer = 800; % default 800 (uses different definition than SLIC authors)
opts.slic_region_size = 20; % default 20

%% Features
opts.diagonal_connections = 0; % default 0. Whether only diagonally connected pixels are considered connected.
opts.dsift_step = 2; % default 2. calculate dsfit only every n step (quadratic speedup in n).

% Histogram features to use
opts.feature_dsift_bow = 1;    % 1 % denseSIFT bag-of-words
opts.feature_color_bow = 1;    % 2 % color bag-of-words in various color spaces
opts.feature_rgb_raw = 0;      % 3 % raw rgb histograms
opts.feature_grad_texture = 0; % 4 % feature used by van de Sande. Has two implementations, see code
opts.feature_lbp = 0;          % 6 % Local binary patterns
opts.feature_size = 1;         % 8 % size of combined superpixel
opts.features = 1:6; % This will be used in similarity.m to change histogram distances feature-wise
opts.features = opts.features(logical([opts.feature_dsift_bow, opts.feature_color_bow, opts.feature_rgb_raw, opts.feature_grad_texture, opts.feature_lbp ,opts.feature_size]));

opts.feature_weights = [1,1,2]; % default [1,1,2] with above dsift_bow, color_bow, size enabled and rest disabled

opts.collect_merged_regions = 1; % default 1. Every time a pair is merged during the greedy pairing algorithm, the new pair is saved as a region

opts.gc_branches = 15; % default 15. Number of graphcut branches.

opts.start_phase2 = 0.8; % 0.8 default. Score at which to change features and/or start branching

% Load precalculated data
opts.load_color_dict = 1; % default 1. 0 means dictionary will be created from the image (very slow). This option is used for both, rgb and lab features.
opts.load_dsift_dict = 1; % default 1. same as above but for dsift
opts.load_dsift_words = 0; % default 0. load precalculated dsift words using precalculated dict. This option overrides opts.load_dsift_dict.
opts.load_init_segs = 0; % default 0. Load initial felz or slic rgb segmentations with "default" parameters (see conditionals in code at spagglom.m)

if opts.load_dsift_dict
    load('/path/to/Rantalankila/dicts/dsift_dict_k500');
    opts.dsift_dict = dsift_dict;
    clear dsift_dict;
end
end


function type = tt_assignment_type(x,subs,rhs)
%TT_ASSIGNMENT_TYPE What type of subsasgn is this?
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

if isequal(class(x),class(rhs))
    type = 'subtensor';
    return;
end

if (numel(subs) >= 2)
    type = 'subtensor';
    return;
end

type = 'subscripts';


%Run one participant: normalize full brain tractography set (not just mori).
%Two-stage procedure: first, generate a mori set and initialize the solution. Second, throw in the rest of the fibers and normalize them, too.

%Assumes each dti folder already contains safe brain mask, bvals/bvecs averages & contrack parameter files.
%See dti_Longitude_NormalizeMoriFibersDensity.m for an example how to set up a batch process to generate those.
%In face, use dtiRawAverage instead of dtiAverageRawAligned function (the fist one is a more general version).

%ER 07/2009
warning('off'); clear;
addpath(genpath('~/vistasoft'));
addpath(genpath('/usr/local/matlab/toolbox/mri/spm5_r2008/'));

project_folder='/biac3/wandell4/data/reading_longitude/dti_y1234/';
load('/biac3/wandell4/users/elenary/longitudinal/subjectCodesAll4Years');
subjectID=subjectCodes;
numProcessorsAvail=16; %Courtesy max number of processors to be used on Azure without annoying everyone else.
allfibers_prefix='all';
moriFile=fullfile('dti06trilinrt', 'fibers',  [allfibers_prefix 'ConnectingGM_MoriGroups.mat']);
wholebrainGM=fullfile('dti06trilinrt', 'fibers',  [allfibers_prefix 'ConnectingGM.mat']);
wholebrainFibers=fullfile('dti06trilinrt', 'fibers', [allfibers_prefix '.mat']); %Usually we do not save all.mat since blue
%matter only work with fibers that connect gm

compute_allConnectingGM=false; %We already computed allConnectingGM before; only recompute if does not exist
saveAllFibers=false;

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

for s=1:size(subjectID, 2)

    cd([project_folder subjectID{s}]);
    if exist(moriFile, 'file')
    fprintf('Subject %s already has morifile created \n', num2str(s));
    continue;
    end

    fprintf(1, 'Working on %s\n', subjectID{s});
    dt6File=fullfile(pwd, 'dti06trilinrt', 'dt6.mat');
    dt = dtiLoadDt6(dt6File);

    if  compute_allConnectingGM || ~exist(wholebrainGM, 'file')
    %Perform full brain tractography and save results
        faThresh = 0.30;
        opts.stepSizeMm = 1;
        opts.faThresh = 0.15;
        opts.lengthThreshMm = [50 250];
        opts.angleThresh = 50;
        opts.wPuncture = 0.2;
        opts.whichAlgorithm = 1;
        opts.whichInterp = 1;
        opts.seedVoxelOffsets = [0.25 0.75];
        opts.offsetJitter = 0.1;
        fa = dtiComputeFA(dt.dt6);
        fa(fa>1) = 1; fa(fa<0) = 0;
        roiAll = dtiNewRoi(allfibers_prefix);
        mask = dtiCleanImageMask(fa>=faThresh);
        [x,y,z] = ind2sub(size(mask), find(mask));
        clear mask fa;
        roiAll.coords = mrAnatXformCoords(dt.xformToAcpc, [x,y,z]);
        clear x y z;
        fg = dtiFiberTrack(dt.dt6, roiAll.coords, dt.mmPerVoxel, dt.xformToAcpc, allfibers_prefix, opts);
        clear roiAll
    if saveAllFibers
        dtiWriteFiberGroup(fg, wholebrainFibers);
    end
    fprintf('Get fibers connecting GM\n');
    fg=dtiGetFibersConnectingGM(fg, dt);
    dtiWriteFiberGroup(fg, wholebrainGM); %Need to save it once b/c it is fed to dtiFindMoriTracts; overwritten later by a sequence of Mori and Non-Mori (unclassified) fibers.
    end

    fprintf('Find Mori Tracts\n');

    [fgMoriWithCST, fg_unclassifiedMoriWithCST]=dtiFindMoriTracts(dt6File, moriFile, wholebrainGM);%Note: here we went with default values which included useRoiBasedApproach=[.89 1]. This is a very conservative threshold for minDist (fiber-to-roi). But since we are simply using this moriClassification to generate an initial solution for blue Matter, we'll leave it at that.
    mergedFG = dtiMergeFiberGroups(fgMoriWithCST, fg_unclassifiedMoriWithCST, allfibers_prefix);
    %Save "Mori-plus-the-rest" file (overwrites/reorders wholebrainGM)
    dtiWriteFiberGroup(mergedFG, wholebrainGM);
    %Save Mori only file
    dtiWriteFiberGroup(fgMoriWithCST, moriFile);
    %Save both of them as PDB
    dtiWriteFibersPdb(mergedFG, dt.xformToAcpc, [wholebrainGM(1:(end-4)) '.pdb']);
    dtiWriteFibersPdb(fgMoriWithCST, dt.xformToAcpc, [moriFile(1:(end-4)) '.pdb']);

    %Create initial solution
    [status, result]=system(['ps -U elenary |grep ''trueSA'' |wc|awk ''{print $1}''']); %result=2 if no trueSA by me are running
    if str2num(result)<=(numProcessorsAvail+2)
    display(['starting a trueSA for' subjectID{s}]);
    SAlogfile=['/azure/scr1/bluematterscratch' filesep subjectID{s} 'dti06trilinrt_' allfibers_prefix 'ConnectingGM_MoriGroups_DN' filesep 'runSAmpi.log'];
    system(['/biac3/wandell4/users/elenary/density_normalization/scripts/runSAmpi.sh ' project_folder filesep subjectID{s} filesep 'dti06trilinrt  ' [allfibers_prefix 'ConnectingGM_MoriGroups.pdb'] ' ' [allfibers_prefix 'ConnectingGM_MoriGroups_DN.pdb'] ' &>' SAlogfile  '&']);
    else continue
    end
end
return
%Since we could not launch all trueSAs, launch'em here
a=1;
while a
try
    a=(size(findstr('allConnectingGM_MoriGroups_DN.ind', ls([project_folder filesep '*' filesep 'dti06trilinrt' filesep 'fibers' filesep allfibers_prefix  'ConnectingGM_MoriGroups_DN.ind'])), 2)<108);
catch
    %in no *.ind yet
    a=1;
end
for s=1:size(subjectID, 2)
    s
     cd([project_folder subjectID{s}]);
        [status, result]=system('ps -U elenary -u elenary |grep ''trueSA'' |wc|awk ''{print $1}''');
    if (~exist([moriFile(1:(end-4)) '_DN.TMP'], 'file')) && str2num(result)<=(numProcessorsAvail+2) && (~exist([moriFile(1:(end-4)) '_DN.ind'], 'file')) && (exist(moriFile, 'file'))
        display(['starting a trueSA for ' subjectID{s}]);
        SAlogfile=['/azure/scr1/bluematterscratch' filesep subjectID{s} 'dti06trilinrt_' allfibers_prefix 'ConnectingGM_MoriGroups_DN' filesep 'runSAmpi.log'];
    mkdir(fileparts(SAlogfile));
        system(['/biac3/wandell4/users/elenary/density_normalization/scripts/runSAmpi.sh ' project_folder filesep subjectID{s} filesep 'dti06trilinrt  ' [allfibers_prefix 'ConnectingGM_MoriGroups.pdb'] ' ' [allfibers_prefix 'ConnectingGM_MoriGroups_DN.pdb'] ' &>' SAlogfile '&']);
        else

    end
pause(10);
end

end

return
%%%%%%%%%%% RUN AFTER ALL TRUESA and VALIDATION JOBS DONE -- this step
%%%%%%%%%%% is not required to continue on with full  brain BM
%%%%%%%%%%% normalization. This step is required for quality checks though.
%%%%%%%%%%%
%Tranform ind to mat
for s=1:size(subjectID, 2)
    cd([project_folder subjectID{s}]);
    dt6File=fullfile('dti06trilinrt', 'dt6.mat');

    %Get the pdb back to mat, incorporating the indices
    fg=dtiLoadFiberGroup(moriFile);
    try
    fid=fopen(fullfile(fileparts(dt6File), 'fibers', [allfibers_prefix  'ConnectingGM_MoriGroups_DN.ind']));
    fprintf( subjectID{s});
    %TrueSA solution are indices of fibers to keep--in the space of allConnectingGM_MoriGroups. PLUS1!!! (those indices count from 0)
    DN_ind=textscan(fid, '%d');DN_ind=DN_ind{1}; fclose(fid);
    dtiWriteFibersSubset(moriFile, DN_ind+1, fullfile(fileparts(dt6File), 'fibers', [allfibers_prefix  'ConnectingGM_MoriGroups_DN.mat']), 'allConnectingGM_MoriGroups_DN', fg.subgroup(DN_ind+1), fg.subgroupNames);

    catch
        fprintf('Not converged yet');
    end
end

return

%After the initial solution has been obtained, use its model.pid to run
%blue matter on the full set arranged as MoriTracts-then-otherTracts.
a=1;
while a
try
    a=(size(findstr('allConnectingGM_DN.ind', ls([project_folder filesep '*' filesep 'dti06trilinrt' filesep 'fibers' filesep allfibers_prefix  'ConnectingGM_DN.ind'])), 2)<112);
catch
    %in no *.ind yet
    a=1;
end
for s=1:size(subjectID, 2)
    %check that the initial guess job at least finished. system(grep) returns "0" if
    %there is a match found---oukey. (system error codes of 1 or 2 otherwise).. And also see if maybe this job is
    %already running...
        display([subjectID{s}]);

    [status, result]=system('ps -U elenary -u elenary |grep ''trueSA'' |wc|awk ''{print $1}''');
    if(str2num(result)<=(numProcessorsAvail+2)&&~system(['grep "converged" /azure/scr1/bluematterscratch/' subjectID{s} 'dti06trilinrt_' allfibers_prefix 'ConnectingGM_MoriGroups_DN' filesep '*true*']) && ~exist(['/azure/scr1/bluematterscratch/' subjectID{s} 'dti06trilinrt_' allfibers_prefix 'ConnectingGM_DN' filesep 'data_0.SBfloat'], 'file') && (system(['grep "converged" /azure/scr1/bluematterscratch/' subjectID{s} 'dti06trilinrt_' allfibers_prefix 'ConnectingGM_DN' filesep '*true*'])~=0))

        display(['Submitting all fibers Blue Matter for ' subjectID{s}]);
        cd([project_folder subjectID{s}]);
        initialGuess=['/azure/scr1/bluematterscratch/' subjectID{s} 'dti06trilinrt_' allfibers_prefix 'ConnectingGM_MoriGroups_DN' filesep 'pids' filesep 'model.pid'];
        system(['/biac3/wandell4/users/elenary/density_normalization/scripts/runSAmpi.sh ' project_folder filesep subjectID{s} filesep 'dti06trilinrt  ' [allfibers_prefix 'ConnectingGM.pdb'] ' ' [allfibers_prefix 'ConnectingGM_DN.pdb '] initialGuess ' &']);
    end
pause(50)
end

end

return

%Final solution -- Tranform ind to mat.  allConnectingGM_DN.mat: Mori Labels for the indices correspoinding to
%first N fibers can be obtained from allConnectingGM_MoriGroups, the rest
%should be "0";
for s=1:size(subjectID, 2)
    cd([project_folder subjectID{s}]);
    dt6File=fullfile('dti06trilinrt', 'dt6.mat');

    %Get the pdb back to mat, incorporating the indices
    fgWholeBrain=dtiLoadFibergroup(wholebrainGM);
    try
    fid=fopen(fullfile(fileparts(dt6File), 'fibers', [allfibers_prefix  'ConnectingGM_DN.ind']));
    fprintf( subjectID{s});
    %TrueSA solution are indices of fibers to keep--in the space of allConnectingGM. PLUS1!!! (those indices count from 0)
    DN_ind=textscan(fid, '%d');DN_ind=DN_ind{1}; fclose(fid);
    dtiWriteFibersSubset(wholebrainGM, DN_ind+1, fullfile(fileparts(dt6File), 'fibers', [allfibers_prefix  'ConnectingGM_DN.mat']), 'allConnectingGM_DN', fgWholeBrain.subgroup(DN_ind+1), fgWholeBrain.subgroupNames);

    catch
        fprintf('Not converged yet');
    end
end


files = {
    fullfile('VPibv_10_11_02','calibration_CenterSpellerMVEP_VPibv')
    fullfile('VPibq_10_09_24','calibration_CenterSpellerMVEP_VPibq')
    fullfile('VPiac_10_10_13','calibration_CenterSpellerMVEP_VPiac')
    };

%% Define some settings
disp_ival= [-200 1000];
ref_ival= [-200 0];
crit_maxmin= 70;
crit_ival= [100 800];
crit_clab= {'F9,z,10','AF3,4'};
clab= {'Cz','PO7'};
colOrder= [1 0 1; 0.4 0.4 0.4];

%% load all data sets
nsub = length(files);
for isub = 1:nsub
    file = files{isub};
    file= fullfile(BTB.DataDir, 'demoMat', file);

    %% Load data
    fprintf('loading %s \n', file)

    [cnt, mrk, mnt] = file_loadMatlab(file);

    %% Apply highpass filter to reduce drifts
    b= procutil_firlsFilter(0.5, cnt.fs);
    cnt= proc_filtfilt(cnt, b);

    %% Artifact rejection based on variance criterion
    mrk= reject_varEventsAndChannels(cnt, mrk, disp_ival, 'verbose', 1);

    %% Segmentation
    epo= proc_segmentation(cnt, mrk, disp_ival);

    %% Artifact rejection based on maxmin difference criterion on frontal chans
    [epo iArte] = proc_rejectArtifactsMaxMin(epo, crit_maxmin, 'Clab',crit_clab, ...
        'Ival',crit_ival, 'Verbose',1);

    %% Baseline subtraction, and calculation of a measure of discriminability
    epo= proc_baseline(epo, ref_ival);

    epos_av{isub} = proc_average(epo, 'Stats', 1);

    % three different but almost equivalent ways to make statistics about class differences
    epos_diff{isub} = proc_classmeanDiff(epo, 'Stats', 1);
    epos_r{isub} = proc_rSquareSigned(epo, 'Stats', 1);
    epos_auc{isub} = proc_aucValues(epo, 'Stats', 1);

end

%% grand average
epo_av = proc_grandAverage(epos_av, 'Average', 'INVVARweighted', 'Stats', 1, 'Bonferroni', 1, 'Alphalevel', 0.01);
epo_r = proc_grandAverage(epos_r, 'Average', 'INVVARweighted', 'Stats', 1, 'Bonferroni', 1, 'Alphalevel', 0.01);
epo_diff = proc_grandAverage(epos_diff, 'Average', 'INVVARweighted', 'Stats', 1, 'Bonferroni', 1, 'Alphalevel', 0.01);
epo_auc = proc_grandAverage(epos_auc, 'Average', 'INVVARweighted', 'Stats', 1, 'Bonferroni', 1, 'Alphalevel', 0.01);

%% Select some discriminative intervals, with constraints to find N2, P2, P3 like components.
constraint= ...
    {{-1, [100 300], {'I#','O#','PO7,8','P9,10'}, [50 300]}, ...
    {1, [200 350], {'P3-4','CP3-4','C3-4'}, [200 400]}, ...
    {1, [400 500], {'P3-4','CP3-4','C3-4'}, [350 600]}};
[ival_scalps, nfo]= ...
    procutil_selectTimeIntervals(epo_r, 'Visualize', 0, 'VisuScalps', 1, ...
    'Title', util_untex(file), ...
    'Clab',{'not','E*'}, ...
    'Constraint', constraint);
%printFigure('r_matrix', [18 13]);
ival_scalps= visutil_correctIvalsForDisplay(ival_scalps, 'fs',epo.fs);

%% plot classwise grand-average ERPs
fig_set(1);
H= plot_scalpEvolutionPlusChannel(epo_av, mnt, clab, ival_scalps, defopt_scalp_erp, ...
    'ColorOrder',colOrder);
grid_addBars(epo_r);
%printFigure(['erp_topo'], [20  4+5*size(epo.y,1)]);

%% plot difference of the class means
fig_set(2, 'Resize',[1 2/3]);
plot_scalpEvolutionPlusChannel(epo_diff, mnt, clab, ival_scalps, defopt_scalp_r);
%printFigure(['erp_topo_r'], [20 9]);

% plot signed log10 p-values of the null hypothesis
% that the difference of the class means is zero
% interpretation: abs(sgnlogp) > 1   <-->  p < 0.1
%                 abs(sgnlogp) > 2   <-->  p < 0.01
%                 abs(sgnlogp) > 3   <-->  p < 0.001 , and so on
fig_set(3, 'Resize',[1 2/3]);
epo_diff_sgnlogp = epo_diff;
epo_diff_sgnlogp.x = epo_diff_sgnlogp.sgnlogp;
epo_diff_sgnlogp.yUnit = 'sgnlogp';
plot_scalpEvolutionPlusChannel(epo_diff_sgnlogp, mnt, clab, ival_scalps, defopt_scalp_r);
%printFigure(['erp_topo_r'], [20 9]);

%% now plot differences again, with all insignificant results set to zero
epo_diff.x = epo_diff.x.*epo_diff.sigmask;
fig_set(4, 'Resize',[1 2/3]);
plot_scalpEvolutionPlusChannel(epo_diff, mnt, clab, ival_scalps, defopt_scalp_r);


function C = cat(dim, varargin)
%CAT   Concatenation of CHEBMATRIX objects.
%   C = CAT(dim, A, B,...) concatenates chebmatrices along the indicated
%   dimension following Matlab conventions.
%
% See also CHEBMATRIX.HORZCAT, CHEBMATRIX.VERTCAT.

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

% Any singleton operator blocks must be encased in cells to match up with
% CHEBMATRIX blocks.

if ( dim == 1 )
    C = vertcat(varargin{:});
elseif ( dim == 2 )
    C = horzcat(varargin{:});
else
    error('CHEBFUN:CHEBMATRIX:cat:dim', ...
        'Must concatenate along dimension 1 or 2.')
end

end


function ft_realtime_packettimer(cfg)

% FT_REALTIME_PACKETTIMER can be used to time the rate at which data can be processed
%
% Use as
%   ft_realtime_packettimer(cfg)
% with the following configuration options
%   cfg.bcifun    = processing of the data (default = @bcifun_timer)
%   cfg.npackets  = the number of packets shown in one plot (default=1000)
%                     after reaching the end
%   cfg.saveplot  = if path is specified, first plot is saved (default=[]);
%   cfg.rellim = y limits of subplot 1 (default = [-100 100])
%
% SEE ALSO:
%   FT_REALTIME_PROCESS

% TO DO:
%   jitter in het binnenhalen van de data; scatterplot!
%   triggers sturen en herhalen (loop closen)
%   tijd schatten waarin matlab nog kan processen

% Copyright (C) 2009, Marcel van Gerven
%
% $Id$

if ~isfield(cfg,'bcifun'),    cfg.bcifun = @bcifun_timer; end
if ~isfield(cfg,'npackets'),  cfg.npackets = 10^2; end
if ~isfield(cfg,'rellim'),    cfg.rellim = [-1 1]; end
if ~isfield(cfg,'saveplot'),  cfg.saveplot= []; end

close all;
f1 = figure();
set(f1,'units','normalized','outerposition',[0 0 1 1]);

% reset persistent variables
cfg.bcifun();

try
  ft_realtime_process(cfg);
catch
  fprintf('%s\n',lasterr);
  close;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% BCIFUN_TIMER plots real time versus packet time
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bcifun_timer(cfg,data)

persistent startsample;
persistent olddf;

persistent idx;

if nargin == 0
  idx = []; % reset persistent
  return;
end

if isempty(idx)

  tic;

  startsample = data.endsample;

  idx       = 1;
  olddf     = 0;

  return;

end

if mod(idx,cfg.npackets) == 1

  xl = [floor(idx/cfg.npackets)*cfg.npackets+1 (floor(idx/cfg.npackets)+1)*cfg.npackets];

  hold off
  plot(xl,[0 0],'k--');
  xlim(xl);
  ylim(cfg.rellim);
  xlabel('packet number');
  ylabel('delay (sample time - real time)');
  hold on;

end

cursample = data.endsample;
curtime   = toc;

smptime = (cursample - startsample)/data.fsample;
df = smptime - curtime;
if df < 0
  plot([idx-1 idx],[olddf df],'r');
else
  plot([idx-1 idx],[olddf df],'g');
end
olddf = df;
title(sprintf('packet timing for %g s blocks in %d channels at sample frequency %d; sample time = %g, real time = %g, delay = %g',...
  data.blocksize/data.fsample,length(data.label),data.fsample,smptime,curtime,smptime - curtime));

idx = idx + 1;

drawnow;

if idx==cfg.npackets && strcmp(cfg.saveplot,'yes')
  saveas(gcf,cfg.saveplot,'jpg');
end


function test_withinScansMotionComp
%Test test_withinScansMotionComp as well as the creation of a new data type
%
%   test_withinScansMotionComp()
%
%
% Tests: intiHiddenInplane, test_withinScansMotionComp, dtGet, motionCompSelScan
%
% INPUTS
%  No inputs
%
% RETURNS
%  No returns
%
% Example: test_withinScansMotionComp()
%
% See also MRVTEST
%
% Copyright Stanford team, mrVista, 2014
%
%

% Initialize the key variables and data path
% Data directory (where the mrSession file is located)
dataDir = mrtInstallSampleData('functional','prfInplane');

% This is the validation file
stored = mrtGetValididationData('withinScansMotionComp');

%
% dtNum = 2;
% stored.name = dtGet(dataTYPES(dtNum),'Name');
% stored.annotation = dtGet(dataTYPES(dtNum),'Annotation', 1);
% stored.nFrames = dtGet(dataTYPES(dtNum),'nFrames', 1);
% stored.framePeriod = dtGet(dataTYPES(dtNum),'Frame Period', 1);
% stored.numSlices = length(dtGet(dataTYPES(dtNum),'slices', 1));
% stored.numScans = dtGet(dataTYPES(dtNum),'N Scans');
% stored.motionEstimates = motionEstimates;
% save(vFile, '-struct',  'stored')

% Relative tolerance of assertAlmostEqual
relTol = 1e-10;

% Retain original directory, change to data directory
curDir = pwd;
cd(dataDir);

% Get data structure:
vw = initHiddenInplane;
mrGlobals;

typeName        = 'WitinScansMotionComp';
baseScan        = 1;
baseFrame       = 1;
scansToCorrect  = 1;
nSmooth         = 1;

% compute the within scan motion, and return the view structure
vw = motionCompSelScan(vw, typeName, scansToCorrect, baseFrame, nSmooth, baseScan);

% close the graph window created by motionCompSelScan
close(gcf)

%Now that we have created the necessary data, we can do the actual tests.
dtNum  = length(dataTYPES);
vw     = viewSet(vw, 'current dt', dtNum);
nScans = viewGet(vw, 'num scans');

% get the within scan motion
motionEstimates = dtGet(dataTYPES(dtNum), 'within scan motion', scansToCorrect);

% Now check that the motion estimates agree with stored estimates
assertVectorsAlmostEqual(motionEstimates, stored.motionEstimates, 'relative', relTol);

% Check that the new dataTYPE got the proper name
assertEqual(typeName, dtGet(dataTYPES(dtNum),'Name'));

% Check that the new dataTYPE got the proper annoation
assertEqual(stored.annotation, dtGet(dataTYPES(dtNum),'Annotation', nScans));

% Check that the new dataTYPE got the proper numbr of frames
assertEqual(stored.nFrames, dtGet(dataTYPES(dtNum),'nFrames', nScans));

% Check that the new dataTYPE got the proper TR
assertEqual(stored.framePeriod, dtGet(dataTYPES(dtNum),'Frame Period', nScans));

% Check that the new dataTYPE got the proper number of slices
assertEqual(stored.numSlices, length(dtGet(dataTYPES(dtNum),'slices', nScans)));

% Check that the new dataTYPE got the proper number of scans
assertEqual(stored.numScans, dtGet(dataTYPES(dtNum),'N Scans'));

% clean up vistadata repository because this test script wrote new data
% test_CleanUpSVN
mrvCleanWorkspace;

cd(curDir);


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

%%
clear; close all; clc;

%% Syntax
% |opt=fmin_fvalfind_ppform(pp,x,y);|

%% 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/>.


classdef tflowmex < matlab.unittest.TestCase

  properties
    numLabs
  end

  properties (TestParameter)
    device = {'cpu', 'gpu'}
  end

  methods (TestClassSetup)
    function openParpool(test)
      test.numLabs = 4 ;
      if ~isempty(gcp('nocreate'))
        delete(gcp) ;
      end
      cl = parcluster('local');
      cl.NumWorkers = test.numLabs ;
      parpool(cl,test.numLabs) ;
    end
  end

  methods (TestClassTeardown)
    function closeParpool(test)
      if ~isempty(gcp('nocreate'))
        delete(gcp) ;
      end
    end
  end

  methods (TestMethodTeardown)
    function reset(test)
      if ~isempty(gcp('nocreate'))
        spmd
          vl_tflow('reset') ;
        end
      end
    end
  end

  methods (Test)
    function test_basic(test, device)
      haveGpu = strcmp(device,'gpu') ;
      T = 10 ;
      finalValue = (test.numLabs * (test.numLabs + 1)) / 2 * ...
          test.numLabs^(T-1) ;
      format = {'single', [10 10],     'x0', 'cpu', ;
                'single', [10 15 3 2], 'x1', 'cpu'  ;
                'double', [3 4 5 6],   'x2', 'cpu' } ;
      if haveGpu
        format = vertcat(format, ...
                         {'single', [10 10],     'x0g', 'gpu', ;
                          'single', [10 15 3 2], 'x1g', 'gpu'  ;
                          'double', [3 4 5 6],   'x2g', 'gpu' }) ;
      end
      spmd
        if haveGpu
          gpuDevice(1) ;
        end
        for i = 1:size(format,1)
          x{i} = tflowmex.makeArray(format(i,:)) + labindex ;
        end
        labBarrier() ;
        vl_tflow('init',format,labindex,numlabs) ;
        for t = 1:T
          for i = 1:size(format,1),
            vl_tflow('push',format{i,3},x{i}) ;
          end
          for i = 1:size(format,1),
            x{i} = vl_tflow('pull',format{i,3}) ;
          end
        end
        for i = 1:size(format,1)
          assert(x{i}(1) == finalValue) ;
        end
      end
    end

    function test_inplace(test, device)
      haveGpu = strcmp(device,'gpu') ;
      if ~haveGpu, return ; end
      T = 10 ;
      finalValue = (test.numLabs * (test.numLabs + 1)) / 2 * ...
          test.numLabs^(T-1) ;
      format = {'single', [10 10],     'x0', 'gpu', ;
                'single', [10 15 3 2], 'x1', 'gpu'  ;
                'double', [3 4 5 6],   'x2', 'gpu' } ;
      gpuDevice(1) ;
      spmd
        for i = 1:size(format,1)
          x{i} = tflowmex.makeArray(format(i,:)) + labindex ;
        end
        vl_tflow('init',format,labindex,numlabs) ;
        for t = 1:T
          for i = 1:size(format,1),
            vl_tflow('push',format{i,3},x{i},'inplace') ;
          end
          for i = 1:size(format,1),
            vl_tflow('pull',format{i,3},'inplace') ;
          end
        end
        for i = 1:size(format,1)
          assert(x{i}(1) == finalValue) ;
        end
      end
    end

  end

  methods (Static)
    function x = makeArray(format)
      x = zeros(format{1,2},format{1,1}) ;
      if numel(format) > 3 && strcmp(format{4},'gpu')
        x = gpuArray(x) ;
      end
    end
  end

end