if(exist('D:\Datasets\fera/au_training', 'file'))
    FERA2011_dir = 'D:\Datasets\fera/au_training/';
elseif(exist('/multicomp/datasets/fera2011/', 'file'))
    FERA2011_dir = '/multicomp/datasets/fera2011/au_training/';
elseif(exist('E:\Datasets\fera/au_training', 'file'))
    FERA2011_dir = 'E:\Datasets\fera/au_training/';
elseif(exist('/media/tadas/2EBEA130BEA0F20F/datasets/fera/au_training/', 'file'))
    FERA2011_dir = '/media/tadas/2EBEA130BEA0F20F/datasets/fera/au_training/';
else
    fprintf('FERA2011 location not found (or not defined)\n');
end

all_recs = {'train_001', 'train_002', 'train_003', 'train_004', 'train_005',...
            'train_006', 'train_007', 'train_008', 'train_009', 'train_010',...
            'train_011', 'train_012', 'train_013', 'train_014', 'train_015',...
            'train_016', 'train_017', 'train_018', 'train_019', 'train_020',...
            'train_021', 'train_022', 'train_023', 'train_024', 'train_025',...
            'train_026', 'train_027', 'train_028', 'train_029', 'train_030',...
            'train_031', 'train_032', 'train_033', 'train_034', 'train_035',...
            'train_036', 'train_037', 'train_038', 'train_039', 'train_040',...
            'train_041', 'train_042', 'train_043', 'train_044', 'train_045',...
            'train_046', 'train_047', 'train_048', 'train_049', 'train_050',...
            'train_051', 'train_052', 'train_053', 'train_054', 'train_055',...
            'train_056', 'train_057', 'train_058', 'train_059', 'train_060',...
            'train_061', 'train_062', 'train_063', 'train_064', 'train_065',...
            'train_066', 'train_067', 'train_068', 'train_069', 'train_070',...
            'train_071', 'train_072', 'train_073', 'train_074', 'train_075',...
            'train_076', 'train_077', 'train_078', 'train_079', 'train_080',...
            'train_081', 'train_082', 'train_083', 'train_084', 'train_085',...
            'train_086', 'train_087'};

% Making them person independent
train_recs = all_recs(1:56);
devel_recs = setdiff(all_recs, train_recs);

all_aus = [1, 2, 4, 6, 7, 10, 12, 15, 17, 18, 25, 26];


function y = lt( x, y )

if isa(x,'cvxin')||~isa(y,'cvxin')||y.active,
    error( 'CVX error: improper use of the <in> pseudo-operator.' );
end
y.active = true;
y.value  = x;

% Copyright 2005-2016 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function spectrumButtonCallback(blockHandle)
% Callback function for SpecButton
% Allows user to specify what .mat file to use for spectrumImport wave type

    [filename,filepath] = uigetfile('.mat');               % Return filename, filepath of user-chosen file
    % Don't set value if no file is chosen, or prompt canceled.
    if ~isequal(filename,0) && ~isequal(filepath,0)
        mask = Simulink.Mask.get(blockHandle);
        fileParam = mask.getParameter('spectrumFile');
        fileParam.Value = [filepath,filename];             % Update spectrumFile with new filename
    end
end


function data = loadubjson(fname,varargin)
%
% data=loadubjson(fname,opt)
%    or
% data=loadubjson(fname,'param1',value1,'param2',value2,...)
%
% parse a JSON (JavaScript Object Notation) file or string
%
% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
% created on 2013/08/01
%
% $Id: loadubjson.m 460 2015-01-03 00:30:45Z fangq $
%
% input:
%      fname: input file name, if fname contains "{}" or "[]", fname
%             will be interpreted as a UBJSON string
%      opt: a struct to store parsing options, opt can be replaced by
%           a list of ('param',value) pairs - the param string is equivallent
%           to a field in opt. opt can have the following
%           fields (first in [.|.] is the default)
%
%           opt.SimplifyCell [0|1]: if set to 1, loadubjson will call cell2mat
%                         for each element of the JSON data, and group
%                         arrays based on the cell2mat rules.
%           opt.IntEndian [B|L]: specify the endianness of the integer fields
%                         in the UBJSON input data. B - Big-Endian format for
%                         integers (as required in the UBJSON specification);
%                         L - input integer fields are in Little-Endian order.
%
% output:
%      dat: a cell array, where {...} blocks are converted into cell arrays,
%           and [...] are converted to arrays
%
% examples:
%      obj=struct('string','value','array',[1 2 3]);
%      ubjdata=saveubjson('obj',obj);
%      dat=loadubjson(ubjdata)
%      dat=loadubjson(['examples' filesep 'example1.ubj'])
%      dat=loadubjson(['examples' filesep 'example1.ubj'],'SimplifyCell',1)
%
% license:
%     BSD, see LICENSE_BSD.txt files for details
%
% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%

global pos inStr len  esc index_esc len_esc isoct arraytoken fileendian systemendian

if(regexp(fname,'[\{\}\]\[]','once'))
   string=fname;
elseif(exist(fname,'file'))
   fid = fopen(fname,'rb');
   string = fread(fid,inf,'uint8=>char')';
   fclose(fid);
else
   error('input file does not exist');
end

pos = 1; len = length(string); inStr = string;
isoct=exist('OCTAVE_VERSION','builtin');
arraytoken=find(inStr=='[' | inStr==']' | inStr=='"');
jstr=regexprep(inStr,'\\\\','  ');
escquote=regexp(jstr,'\\"');
arraytoken=sort([arraytoken escquote]);

% String delimiters and escape chars identified to improve speed:
esc = find(inStr=='"' | inStr=='\' ); % comparable to: regexp(inStr, '["\\]');
index_esc = 1; len_esc = length(esc);

opt=varargin2struct(varargin{:});
fileendian=upper(jsonopt('IntEndian','B',opt));
[os,maxelem,systemendian]=computer;

jsoncount=1;
while pos <= len
    switch(next_char)
        case '{'
            data{jsoncount} = parse_object(opt);
        case '['
            data{jsoncount} = parse_array(opt);
        otherwise
            error_pos('Outer level structure must be an object or an array');
    end
    jsoncount=jsoncount+1;
end % while

jsoncount=length(data);
if(jsoncount==1 && iscell(data))
    data=data{1};
end

if(~isempty(data))
      if(isstruct(data)) % data can be a struct array
          data=jstruct2array(data);
      elseif(iscell(data))
          data=jcell2array(data);
      end
end

%%
function newdata=parse_collection(id,data,obj)

if(jsoncount>0 && exist('data','var'))
    if(~iscell(data))
       newdata=cell(1);
       newdata{1}=data;
       data=newdata;
    end
end

%%
function newdata=jcell2array(data)
len=length(data);
newdata=data;
for i=1:len
      if(isstruct(data{i}))
          newdata{i}=jstruct2array(data{i});
      elseif(iscell(data{i}))
          newdata{i}=jcell2array(data{i});
      end
end

%%-------------------------------------------------------------------------
function newdata=jstruct2array(data)
fn=fieldnames(data);
newdata=data;
len=length(data);
for i=1:length(fn) % depth-first
    for j=1:len
        if(isstruct(getfield(data(j),fn{i})))
            newdata(j)=setfield(newdata(j),fn{i},jstruct2array(getfield(data(j),fn{i})));
        end
    end
end
if(~isempty(strmatch('x0x5F_ArrayType_',fn)) && ~isempty(strmatch('x0x5F_ArrayData_',fn)))
  newdata=cell(len,1);
  for j=1:len
    ndata=cast(data(j).x0x5F_ArrayData_,data(j).x0x5F_ArrayType_);
    iscpx=0;
    if(~isempty(strmatch('x0x5F_ArrayIsComplex_',fn)))
        if(data(j).x0x5F_ArrayIsComplex_)
           iscpx=1;
        end
    end
    if(~isempty(strmatch('x0x5F_ArrayIsSparse_',fn)))
        if(data(j).x0x5F_ArrayIsSparse_)
            if(~isempty(strmatch('x0x5F_ArraySize_',fn)))
                dim=double(data(j).x0x5F_ArraySize_);
                if(iscpx && size(ndata,2)==4-any(dim==1))
                    ndata(:,end-1)=complex(ndata(:,end-1),ndata(:,end));
                end
                if isempty(ndata)
                    % All-zeros sparse
                    ndata=sparse(dim(1),prod(dim(2:end)));
                elseif dim(1)==1
                    % Sparse row vector
                    ndata=sparse(1,ndata(:,1),ndata(:,2),dim(1),prod(dim(2:end)));
                elseif dim(2)==1
                    % Sparse column vector
                    ndata=sparse(ndata(:,1),1,ndata(:,2),dim(1),prod(dim(2:end)));
                else
                    % Generic sparse array.
                    ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3),dim(1),prod(dim(2:end)));
                end
            else
                if(iscpx && size(ndata,2)==4)
                    ndata(:,3)=complex(ndata(:,3),ndata(:,4));
                end
                ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3));
            end
        end
    elseif(~isempty(strmatch('x0x5F_ArraySize_',fn)))
        if(iscpx && size(ndata,2)==2)
             ndata=complex(ndata(:,1),ndata(:,2));
        end
        ndata=reshape(ndata(:),data(j).x0x5F_ArraySize_);
    end
    newdata{j}=ndata;
  end
  if(len==1)
      newdata=newdata{1};
  end
end

%%-------------------------------------------------------------------------
function object = parse_object(varargin)
    parse_char('{');
    object = [];
    type='';
    count=-1;
    if(next_char == '$')
        type=inStr(pos+1); % TODO
        pos=pos+2;
    end
    if(next_char == '#')
        pos=pos+1;
        count=double(parse_number());
    end
    if next_char ~= '}'
        num=0;
        while 1
            str = parseStr(varargin{:});
            if isempty(str)
                error_pos('Name of value at position %d cannot be empty');
            end
            %parse_char(':');
            val = parse_value(varargin{:});
            num=num+1;
            eval( sprintf( 'object.%s  = val;', valid_field(str) ) );
            if next_char == '}' || (count>=0 && num>=count)
                break;
            end
            %parse_char(',');
        end
    end
    if(count==-1)
        parse_char('}');
    end

%%-------------------------------------------------------------------------
function [cid,len]=elem_info(type)
id=strfind('iUIlLdD',type);
dataclass={'int8','uint8','int16','int32','int64','single','double'};
bytelen=[1,1,2,4,8,4,8];
if(id>0)
    cid=dataclass{id};
    len=bytelen(id);
else
    error_pos('unsupported type at position %d');
end
%%-------------------------------------------------------------------------

function [data adv]=parse_block(type,count,varargin)
global pos inStr isoct fileendian systemendian
[cid,len]=elem_info(type);
datastr=inStr(pos:pos+len*count-1);
if(isoct)
    newdata=int8(datastr);
else
    newdata=uint8(datastr);
end
id=strfind('iUIlLdD',type);
if(id<=5 && fileendian~=systemendian)
    newdata=swapbytes(typecast(newdata,cid));
end
data=typecast(newdata,cid);
adv=double(len*count);

%%-------------------------------------------------------------------------

function object = parse_array(varargin) % JSON array is written in row-major order
global pos inStr isoct
    parse_char('[');
    object = cell(0, 1);
    dim=[];
    type='';
    count=-1;
    if(next_char == '$')
        type=inStr(pos+1);
        pos=pos+2;
    end
    if(next_char == '#')
        pos=pos+1;
        if(next_char=='[')
            dim=parse_array(varargin{:});
            count=prod(double(dim));
        else
            count=double(parse_number());
        end
    end
    if(~isempty(type))
        if(count>=0)
            [object adv]=parse_block(type,count,varargin{:});
            if(~isempty(dim))
                object=reshape(object,dim);
            end
            pos=pos+adv;
            return;
        else
            endpos=matching_bracket(inStr,pos);
            [cid,len]=elem_info(type);
            count=(endpos-pos)/len;
            [object adv]=parse_block(type,count,varargin{:});
            pos=pos+adv;
            parse_char(']');
            return;
        end
    end
    if next_char ~= ']'
         while 1
            val = parse_value(varargin{:});
            object{end+1} = val;
            if next_char == ']'
                break;
            end
            %parse_char(',');
         end
    end
    if(jsonopt('SimplifyCell',0,varargin{:})==1)
      try
        oldobj=object;
        object=cell2mat(object')';
        if(iscell(oldobj) && isstruct(object) && numel(object)>1 && jsonopt('SimplifyCellArray',1,varargin{:})==0)
            object=oldobj;
        elseif(size(object,1)>1 && ndims(object)==2)
            object=object';
        end
      catch
      end
    end
    if(count==-1)
        parse_char(']');
    end

%%-------------------------------------------------------------------------

function parse_char(c)
    global pos inStr len
    skip_whitespace;
    if pos > len || inStr(pos) ~= c
        error_pos(sprintf('Expected %c at position %%d', c));
    else
        pos = pos + 1;
        skip_whitespace;
    end

%%-------------------------------------------------------------------------

function c = next_char
    global pos inStr len
    skip_whitespace;
    if pos > len
        c = [];
    else
        c = inStr(pos);
    end

%%-------------------------------------------------------------------------

function skip_whitespace
    global pos inStr len
    while pos <= len && isspace(inStr(pos))
        pos = pos + 1;
    end

%%-------------------------------------------------------------------------
function str = parseStr(varargin)
    global pos inStr esc index_esc len_esc
 % len, ns = length(inStr), keyboard
    type=inStr(pos);
    if type ~= 'S' && type ~= 'C' && type ~= 'H'
        error_pos('String starting with S expected at position %d');
    else
        pos = pos + 1;
    end
    if(type == 'C')
        str=inStr(pos);
        pos=pos+1;
        return;
    end
    bytelen=double(parse_number());
    if(length(inStr)>=pos+bytelen-1)
        str=inStr(pos:pos+bytelen-1);
        pos=pos+bytelen;
    else
        error_pos('End of file while expecting end of inStr');
    end

%%-------------------------------------------------------------------------

function num = parse_number(varargin)
    global pos inStr len isoct fileendian systemendian
    id=strfind('iUIlLdD',inStr(pos));
    if(isempty(id))
        error_pos('expecting a number at position %d');
    end
    type={'int8','uint8','int16','int32','int64','single','double'};
    bytelen=[1,1,2,4,8,4,8];
    datastr=inStr(pos+1:pos+bytelen(id));
    if(isoct)
        newdata=int8(datastr);
    else
        newdata=uint8(datastr);
    end
    if(id<=5 && fileendian~=systemendian)
        newdata=swapbytes(typecast(newdata,type{id}));
    end
    num=typecast(newdata,type{id});
    pos = pos + bytelen(id)+1;

%%-------------------------------------------------------------------------

function val = parse_value(varargin)
    global pos inStr len
    true = 1; false = 0;

    switch(inStr(pos))
        case {'S','C','H'}
            val = parseStr(varargin{:});
            return;
        case '['
            val = parse_array(varargin{:});
            return;
        case '{'
            val = parse_object(varargin{:});
            if isstruct(val)
                if(~isempty(strmatch('x0x5F_ArrayType_',fieldnames(val), 'exact')))
                    val=jstruct2array(val);
                end
            elseif isempty(val)
                val = struct;
            end
            return;
        case {'i','U','I','l','L','d','D'}
            val = parse_number(varargin{:});
            return;
        case 'T'
            val = true;
            pos = pos + 1;
            return;
        case 'F'
            val = false;
            pos = pos + 1;
            return;
        case {'Z','N'}
            val = [];
            pos = pos + 1;
            return;
    end
    error_pos('Value expected at position %d');
%%-------------------------------------------------------------------------

function error_pos(msg)
    global pos inStr len
    poShow = max(min([pos-15 pos-1 pos pos+20],len),1);
    if poShow(3) == poShow(2)
        poShow(3:4) = poShow(2)+[0 -1];  % display nothing after
    end
    msg = [sprintf(msg, pos) ': ' ...
    inStr(poShow(1):poShow(2)) '<error>' inStr(poShow(3):poShow(4)) ];
    error( ['JSONparser:invalidFormat: ' msg] );

%%-------------------------------------------------------------------------

function str = valid_field(str)
global isoct
% From MATLAB doc: field names must begin with a letter, which may be
% followed by any combination of letters, digits, and underscores.
% Invalid characters will be converted to underscores, and the prefix
% "x0x[Hex code]_" will be added if the first character is not a letter.
    pos=regexp(str,'^[^A-Za-z]','once');
    if(~isempty(pos))
        if(~isoct)
            str=regexprep(str,'^([^A-Za-z])','x0x${sprintf(''%X'',unicode2native($1))}_','once');
        else
            str=sprintf('x0x%X_%s',char(str(1)),str(2:end));
        end
    end
    if(isempty(regexp(str,'[^0-9A-Za-z_]', 'once' ))) return;  end
    if(~isoct)
        str=regexprep(str,'([^0-9A-Za-z_])','_0x${sprintf(''%X'',unicode2native($1))}_');
    else
        pos=regexp(str,'[^0-9A-Za-z_]');
        if(isempty(pos)) return; end
        str0=str;
        pos0=[0 pos(:)' length(str)];
        str='';
        for i=1:length(pos)
            str=[str str0(pos0(i)+1:pos(i)-1) sprintf('_0x%X_',str0(pos(i)))];
        end
        if(pos(end)~=length(str))
            str=[str str0(pos0(end-1)+1:pos0(end))];
        end
    end
    %str(~isletter(str) & ~('0' <= str & str <= '9')) = '_';

%%-------------------------------------------------------------------------
function endpos = matching_quote(str,pos)
len=length(str);
while(pos<len)
    if(str(pos)=='"')
        if(~(pos>1 && str(pos-1)=='\'))
            endpos=pos;
            return;
        end
    end
    pos=pos+1;
end
error('unmatched quotation mark');
%%-------------------------------------------------------------------------
function [endpos e1l e1r maxlevel] = matching_bracket(str,pos)
global arraytoken
level=1;
maxlevel=level;
endpos=0;
bpos=arraytoken(arraytoken>=pos);
tokens=str(bpos);
len=length(tokens);
pos=1;
e1l=[];
e1r=[];
while(pos<=len)
    c=tokens(pos);
    if(c==']')
        level=level-1;
        if(isempty(e1r)) e1r=bpos(pos); end
        if(level==0)
            endpos=bpos(pos);
            return
        end
    end
    if(c=='[')
        if(isempty(e1l)) e1l=bpos(pos); end
        level=level+1;
        maxlevel=max(maxlevel,level);
    end
    if(c=='"')
        pos=matching_quote(tokens,pos+1);
    end
    pos=pos+1;
end
if(endpos==0)
    error('unmatched "]"');
end


function  sParams = rmCreateStim(vw,curStim)
%Create default the retinotopy model stimulus parameter structure
%
%  sParams = rmCreateStim([vw],[curStim]);
%
% This is the modern one.  The older form is rmStimCreate - which is used
% by the older GUI (rmEditStimulusParameters).  When that goes away
% rmStimCreate can also go away. This one works with rmEditStimParams).
%
%Example:
%    sParams = rmCreateStim;   % Create an array with the default
%    sParams = rmCreateStim(vw,myStimParams); % Overlay myStimParams values
%
% JW Jan, 2008
% SD: getCurView is order dependent (gets inplanes first and since we
% typically use the volume/gray view it gets the incorrect one if you have
% an inplane open. Safer to propogate the view structure.
% JW: added argin curStim so that a stim template can be made from just a
% single scan if requested. and not necessarily all the scans in the view's
% current dataTYPE

if ~exist('vw','var') || isempty(vw)
    vw = getCurView; % careful getCurView is unreliable (order dependent)
end

if ~exist('curStim', 'var') || isempty(curStim)
    sParams = rmStimTemplate(vw);
    curStim = length(sParams);
else
    sParams = rmStimTemplate(vw, length(curStim));
end

% Loop through each of the curStim fields and copy the values into the
% sParams fields.
s = fieldnames(sParams(1));
for ii=1:length(curStim)
    for jj=1:length(s)
        if isfield(curStim(ii),s{jj})
            sParams(ii).(s{jj}) = curStim(ii).(s{jj});
        end
    end
end

return;


function Plugin_ReverseK
global VVar

VVar.Kz=-VVar.Kz;
VVar.Ky=-VVar.Ky;
VVar.Kx=-VVar.Kx;

end


% plugin_installstartup() - install popular toolboxes when EEGLAB starts
%
% Usage:
%   >> restartEeglabFlag = plugin_installstartup; % pop up window
%
% Outputs:
%   restartEeglabFlag - [0|1] restart EEGLAB
%
% Author: Arnaud Delorme, SCCN, INC, UCSD, Oct. 29, 2013-

% Copyright (C) 2013 Arnaud Delorme, SCCN, INC, UCSD, 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 restartEeglabFlag = plugin_installstartup

%                 { 'style' 'checkbox' 'string' 'Neuroelectromagnetic Forward Head Modeling Toolbox (NFT): Advanced source localization tools - beta (Zeynep Akalin Acar, 100 Mb)' 'value' 1 'enable' 'on' } ...

    uilist = { { 'style' 'text' 'String' 'Download and install some popular third party EEGLAB plug-ins' 'fontweight', 'bold','tag', 'title'} ...
                 { } ...
                 { 'style' 'checkbox' 'string' 'Brain Vision Analyser data import plugin (40 Kb)' 'value' 1 'enable' 'on' } ...
                 { 'style' 'checkbox' 'string' 'ANT data import plugin (800 Kb)' 'value' 1 'enable' 'on' } ...
                 { 'style' 'checkbox' 'string' 'Measure Projection Toolbox (MPT) for ulti-subject ICA analysis (415 Mb)' 'value' 1 'enable' 'on' } ...
                 { 'style' 'checkbox' 'string' 'Source Information Flow Toolbox (SIFT) for causal analysis of EEG sources (600 Mb)' 'value' 1 'enable' 'on' } ...
                 { 'style' 'checkbox' 'string' 'BCILAB for real-time and offline BCI platform (200 Mb)' 'value' 1 'enable' 'on' } ...
                 { 'style' 'checkbox' 'string' 'LIMO for linear analysis of MEEG data using single trials (2.5 Mb)' 'value' 1 'enable' 'on' } ...
                 { } ...
                 { 'style' 'radiobutton' 'string' 'Do not show this query again' 'value' 0 } ...
                 {} ...
                 { 'style' 'text' 'String' 'Note: manage plug-in tools using EEGLAB menu item, "File > Plug-ins > Manage plug-ins"' } ...
                 {} ...
                 { 'Style', 'pushbutton', 'string', 'Do not install now', 'tag' 'cancel' 'callback', 'set(gcbf, ''userdata'', ''cancel'');' } { } ...
                 { 'Style', 'pushbutton', 'string', 'Install plugins now', 'tag', 'ok', 'callback', 'set(gcbf, ''userdata'', ''ok'');' } ...
                 };

    geomline = [1];
    geom     = { [1] [1] geomline geomline geomline geomline geomline geomline [1] geomline [1] [1] [1] [1 1 1]};
    geomvert = [ 1   0.5 1        1        1        1        1        1        0.3 1        0.3 1   1   1];

    %result = inputgui( 'geometry', geom, 'uilist', uilist, 'helpcom', 'pophelp(''plugin_installstartup'')', 'title', 'Install popular plugins', 'geomvert', geomvert, 'eval', evalstr);
    fig = figure('visible', 'off');
    [tmp1 tmp2 handles] = supergui( 'geomhoriz', geom, 'uilist', uilist, 'title', 'Install popular plugins', 'geomvert', geomvert, 'fig', fig); %, 'eval', evalstr);
    set(findobj(fig, 'tag', 'title'), 'fontsize', 16);
    waitfor( fig, 'userdata');

    % decode inputs
    handles
    results = cellfun(@(x)(get
    get(handles, 'value')


function [merged unused] = propval(propvals, defaults, varargin)

% Create a structure combining property-value pairs with default values.
%
% [MERGED UNUSED] = PROPVAL(PROPVALS, DEFAULTS, ...)
%
% Given a cell array or structure of property-value pairs
% (i.e. from VARARGIN or a structure of parameters), PROPVAL will
% merge the user specified values with those specified in the
% DEFAULTS structure and return the result in the structure
% MERGED.  Any user specified values that were not listed in
% DEFAULTS are output as property-value arguments in the cell array
% UNUSED.  STRICT is disabled in this mode.
%
% ALTERNATIVE USAGE:
%
% [ ARGS ] = PROPVAL(PROPVALS, DEFAULTS, ...)
%
% In this case, propval will assume that no user specified
% properties are meant to be "picked up" and STRICT mode will be enforced.
%
% ARGUMENTS:
%
% PROPVALS - Either a cell array of property-value pairs
%   (i.e. {'Property', Value, ...}) or a structure of equivalent form
%   (i.e. struct.Property = Value), to be merged with the values in
%   DEFAULTS.
%
% DEFAULTS - A structure where field names correspond to the
%   default value for any properties in PROPVALS.
%
% OPTIONAL ARGUMENTS:
%
% STRICT (default = true) - Use strict guidelines when processing
%   the property value pairs.  This will warn the user if an empty
%   DEFAULTS structure is passed in or if there are properties in
%   PROPVALS for which no default was provided.
%
% EXAMPLES:
%
% Simple function with two optional numerical parameters:
%
% function [result] = myfunc(data, varargin)
%
%   defaults.X = 5;
%   defaults.Y = 10;
%
%   args = propvals(varargin, defaults)
%
%   data = data * Y / X;
%
% >> myfunc(data)
%    This will run myfunc with X=5, Y=10 on the variable 'data'.
%
% >> myfunc(data, 'X', 0)
%    This will run myfunc with X=0, Y=10 (thus giving a
%    divide-by-zero error)
%
% >> myfunc(data, 'foo', 'bar') will run myfunc with X=5, Y=10, and
%    PROPVAL will give a warning that 'foo' has no default value,
%    since STRICT is true by default.
%

% License:
%=====================================================================
%
% This is part of the Princeton MVPA toolbox, released under
% the GPL. See http://www.csbmb.princeton.edu/mvpa for more
% information.
%
% The Princeton MVPA toolbox is available free and
% unsupported to those who might find it useful. We do not
% take any responsibility whatsoever for any problems that
% you have related to the use of the MVPA toolbox.
%
% ======================================================================

% Backwards compatibility
pvdef.ignore_missing_default = false;
pvdef.ignore_empty_defaults = false;

% check for the number of outputs
if nargout == 2
  pvdef.strict = false;
else
  pvdef.strict = true;
end

pvargs = pvdef;

% Recursively process the propval optional arguments (possible
% because we only recurse if optional parameters are given)
if ~isempty(varargin)
  pvargs = propval(varargin, pvdef);
end

% NOTE: Backwards compatibility with previous version of propval
if pvargs.ignore_missing_default | pvargs.ignore_empty_defaults
  pvargs.strict = false;
end

% check for a single cell argument; assume propvals is that argument
if iscell(propvals) && numel(propvals) == 1
  propvals = propvals{1};
end

% check for valid inputs
if ~iscell(propvals) & ~isstruct(propvals)
  error('Property-value pairs must be a cell array or a structure.');
end

if ~isstruct(defaults) & ~isempty(defaults)
  error('Defaults struct must be a structure.');
end

% check for empty defaults structure
if isempty(defaults)
  if pvargs.strict & ~pvargs.ignore_missing_default
   error('Empty defaults structure passed to propval.');
  end
  defaults = struct();
end

defaultnames = fieldnames(defaults);
defaultvalues = struct2cell(defaults);

% prepare the defaults structure, but also prepare casechecking
% structure with all case stripped
defaults = struct();
casecheck = struct();

for i = 1:numel(defaultnames)
  defaults.(defaultnames{i}) = defaultvalues{i};
  casecheck.(lower(defaultnames{i})) = defaultvalues{i};
end

% merged starts with the default values
merged = defaults;
unused = {};
used = struct();

properties = [];
values = [];

% To extract property value pairs, we use different methods
% depending on how they were passed in
if isstruct(propvals)
  properties = fieldnames(propvals);
  values = struct2cell(propvals);
else
  properties = { propvals{1:2:end} };
  values = { propvals{2:2:end} };
end

if numel(properties) ~= numel(values)
  error(sprintf('Found %g properties but only %g values.', numel(properties), ...
                numel(values)));
end

% merge new properties with defaults
for i = 1:numel(properties)

  if ~ischar(properties{i})
    error(sprintf('Property %g is not a string.', i));
  end

  % convert property names to lower case
  properties{i} = properties{i};

  % check for multiple usage
  if isfield(used, properties{i})
    error(sprintf('Property %s is defined more than once.\n', ...
                  properties{i}));
  end

  % Check for case errors
  if isfield(casecheck, lower(properties{i})) & ...
    ~isfield(merged, properties{i})
    error(['Property ''%s'' is equal to a default property except ' ...
           'for case.'], properties{i});
  end

  % Merge with defaults
  if isfield(merged, properties{i})
    merged.(properties{i}) = values{i};
  else
    % add to unused property value pairs
    unused{end+1} = properties{i};
    unused{end+1} = values{i};

    % add to defaults, just in case, if the user isn't picking up "unused"
    if (nargout == 1 & ~pvargs.strict)
      merged.(properties{i}) = values{i};
    end

    if pvargs.strict
      error('Property ''%s'' has no default value.', properties{i});
    end

  end

  % mark as used
  used.(properties{i}) = true;
end


function [tf, bool,ind] = isvar(T,varName)
%checks if varName is a column of table T

if isstruct(T)
    tf = isfield(T,varName);
    bool = tf;
    ind = 1;
else
    bool = ismember(T.Properties.VariableNames,varName);
    tf = any(bool);
    ind = find(bool);
end

end


% EEG_REJMACRO - Internal EEGLAB macro for all pop_ functions that
%                  perform data rejection.
%
% Author: Arnaud Delorme, CNL / Salk Institute, 2001
%
% See also: EEGLAB

% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

% 01-25-02 reformated help & license -ad
% 03-08-02 include past rejections in eegplot -ad

% this macro is used by pop_eegplot, pop_eegthresh, pop_const, pop_jointprob, pop_eegthreshfreq, pop_kurtosis

% inputs:
%   rej - input rejection in this workspace (string)
%   rejE - electrode rejection in this workspace (string)
%   elecrange - range of selected electrodes
%   reject - superpose with previous rejections
% optional : nbpnts = number of points per trial

% outputs:
%   rejection arrays ('oldrej', 'oldrejE'), 'command' for eeglot

if ~exist('elecrange')
	help eeg_rejmacro;
	error('Error: eeg_rejmacro cannot be called from the command line');
end;

if ~exist('nbpnts') nbpnts = EEG.pnts; end

% mix all type of rejections
% --------------------------
if icacomp
    nChan = EEG.nbchan;
else
    nChan = size(EEG.icaweights,1);
end
if superpose == 2
    com2 = ['if ~isempty(TMPREJ), ' ...
            '  icaprefix = ' fastif(icacomp, '''''', '''ica''') ';' ...
            '  for indextmp = 1:length(EEG.reject.disprej),' ...
            '     eval([ ''colortmp = EEG.reject.rej'' EEG.reject.disprej{indextmp} ''col;'' ]);' ...
            '     [tmprej tmprejE] = eegplot2trial(TMPREJ,' int2str(nbpnts) ', EEG.trials, colortmp, []);' ...
            '     if ~isempty(tmprejE),' ...
            '          tmprejE2 = zeros(' int2str(nChan) ', length(tmprej));' ...
            '          tmprejE2([' int2str(elecrange) '],:) = tmprejE;' ...
            '     else,' ...
            '          tmprejE2 = [];' ...
            '     end;' ...
            '     eval([ ''EEG.reject.'' icaprefix ''rej'' EEG.reject.disprej{indextmp} ''= tmprej;'' ]);' ...
            '     eval([ ''EEG.reject.'' icaprefix ''rej'' EEG.reject.disprej{indextmp} ''E = tmprejE2;'' ]);' ...
            '  end;' ];
%           '     colortmp, tmpstr = [ ''EEG.reject.'' icaprefix ''rej'' EEG.reject.disprej{indextmp} ], sum(tmprej),' ...
else
    com2 = [ 'if ~isempty(TMPREJ),' ...
             '  icaprefix = ' fastif(icacomp, '''''', '''ica''') ';' ...
             '  [tmprej tmprejE] = eegplot2trial(TMPREJ,' int2str(nbpnts) ', EEG.trials, [' num2str(colrej) '], []);' ...
             '  if ~isempty(tmprejE),' ...
             '     tmprejE2 = zeros(' int2str(nChan) ', length(tmprej));' ...
             '     tmprejE2([' int2str(elecrange) '],:) = tmprejE;' ...
             '  else,' ...
             '     tmprejE2 = [];' ...
             '  end;' ...
             macrorej '= tmprej;' macrorejE '= tmprejE2;' ...
             ... % below are manual rejections
             '  tmpstr = [ ''EEG.reject.'' icaprefix ''rejmanual'' ];' ...
             '  if ~isempty(tmprej) eval([ ''if ~isempty('' tmpstr ''),'' tmpstr ''='' tmpstr ''| tmprej; else, '' tmpstr ''=tmprej; end;'' ]); end;' ...
             '  if ~isempty(tmprejE2) eval([ ''if ~isempty('' tmpstr ''E),'' tmpstr ''E='' tmpstr ''E| tmprejE2; else, '' tmpstr ''E=tmprejE2; end;'' ]); end;' ];
%             '  size(tmprejE2), eval([''disp(size('' tmpstr ''E))'']),' ...
end
% text commented below to fix BUG 478
%             '  [tmprej tmprejE] = eegplot2trial(TMPREJ,' int2str(nbpnts) ', EEG.trials, [' num2str(EEG.reject.rejmanualcol) '], []);' ...
%             '  if ~isempty(tmprejE),' ...
%             '     tmprejE2 = zeros(EEG.nbchan, length(tmprej));' ...
%             '     tmprejE2([' int2str(elecrange) '],:) = tmprejE;' ...
%             '  else,' ...
%             '     tmprejE2 = [];' ...
%             '  end;' ...
if reject
    com2 = [ com2 ...
           '[EEGTMP LASTCOM] = pop_rejepoch(EEG, tmprej, 1);' ...
		   'if ~isempty(LASTCOM),'...
           '   EEG = eegh(LASTCOM, EEG);' ...
           '   [ALLEEG EEG CURRENTSET tmpcom] = pop_newset(ALLEEG, EEGTMP, CURRENTSET);' ...
           '   if ~isempty(tmpcom),' ...
           '     eegh(tmpcom);' ...
           '     eeglab(''redraw'');' ...
            '  end;' ...
	       'end; clear EEGTMP tmpcom; end;' ] ;
else
	com2 = [com2 ...
			' warndlg2(strvcat(''Epochs (=trials) marked for rejection have been noted.'',' ...
			'''To actually reject these epochs, use the same menu item to'',' ...
            '''inspect/reject data and select "Reject marked trials" checkbox''), ''Warning'');' ...
			'[ALLEEG EEG] = eeg_store(ALLEEG, EEG, CURRENTSET); eeglab(''redraw''); end;' ];
end;
if ~exist('topcommand')
	topcommand = [];
end

% the first part is used to convert the eegplot output
command = [  com2 topcommand 'clear indextmp colortmp icaprefix tmpcom tmprej tmprejE tmprejE2 TMPREJ;' ];

if all(colrej == EEG.reject.rejmanualcol)
	oldrej = [];  % for manual rejection, old rejection are
	oldrejE = []; % the current rejection
else
	oldrej  = eval(macrorej);
	oldrejE = eval(macrorejE);
end

switch superpose
 case 0, rejeegplot = trial2eegplot(  rej, rejE, nbpnts, colrej);
 case 1, rejeegplottmp = trial2eegplot(  oldrej, oldrejE, nbpnts, min(colrej+0.15, [1 1 1]));
         if ~isempty(rejeegplottmp), rejeegplot = [ rejeegplottmp ];
		 else rejeegplot = []; end
         rejeegplottmp = trial2eegplot(  rej, rejE, nbpnts, colrej);
         if ~isempty(rejeegplottmp), rejeegplot = [ rejeegplot; rejeegplottmp ]; end
 case 2,
  rejeegplot = [];
  for index = 1:length(EEG.reject.disprej)
	  if ~isempty(EEG.reject.disprej{index})
		  eval([ 'colortmp = EEG.reject.rej' EEG.reject.disprej{index} 'col;']);
		  if any(colortmp ~= colrej) % test if current rejection (if color different)
			  if icacomp == 0 % ica
				  currentname = [ 'EEG.reject.icarej' EEG.reject.disprej{index} ];
			  else
				  currentname = [ 'EEG.reject.rej' EEG.reject.disprej{index} ];
			  end
			  currentcolor =  [ 'EEG.reject.rej' EEG.reject.disprej{index} 'col' ];
			  %if strcmp(EEG.reject.disprej{index}, 'manual')
			  %	  currentcolor = [ 'min(' currentcolor '+0.15, [1 1 1])' ];
			  %end; % using this test, manual rejections won't be added to current rej
			  eval( [ 'rejeegplottmp = trial2eegplot( ' currentname ',' currentname ...
					  'E, nbpnts,' currentcolor ');' ]);
			  if ~isempty(rejeegplottmp), rejeegplot = [ rejeegplot; rejeegplottmp ]; end
		  end
	  end
  end
  rejeegplottmp = trial2eegplot(  rej, rejE, nbpnts, colrej);
  if ~isempty(rejeegplottmp), rejeegplot = [ rejeegplot; rejeegplottmp ]; end
end
if ~isempty(rejeegplot)
	rejeegplot = rejeegplot(:,[1:5,elecrange+5]);
else
	rejeegplot = [];
end
eegplotoptions = { 'events', EEG.event, 'winlength', 5, 'winrej', ...
				   rejeegplot, 'xgrid', 'off', 'wincolor', EEG.reject.rejmanualcol, ...
				   'colmodif', { { EEG.reject.rejmanualcol EEG.reject.rejthreshcol EEG.reject.rejconstcol ...
                                   EEG.reject.rejjpcol     EEG.reject.rejkurtcol   EEG.reject.rejfreqcol } } };

if ~isempty(EEG.chanlocs) && icacomp == 1
    if exist('elecrange')
        eegplotoptions = { eegplotoptions{:}  'eloc_file', EEG.chanlocs(elecrange) };
    else
        eegplotoptions = { eegplotoptions{:}  'eloc_file', EEG.chanlocs };
    end
else
    if exist('elecrange')
        for index = 1:length(elecrange)
            tmpstruct(index).labels = int2str(elecrange(index));
        end
        eegplotoptions = { eegplotoptions{:}  'eloc_file' tmpstruct };
    end
end
if ~reject
	eegplotoptions = { eegplotoptions{:}  'butlabel', 'UPDATE MARKS' };
end


% EEGLAB Toolbox to process EEG data
% Version - see eeg_getversion()
%
% eeglab() - Matlab graphic user interface environment for
%   electrophysiological data analysis incorporating the ICA/EEG toolbox
%   (Makeig et al.) developed at CNL / The Salk Institute, 1997-2001.
%   Released 11/2002- as EEGLAB (Delorme, Makeig, et al.) at the Swartz Center
%   for Computational Neuroscience, Institute for Neural Computation,
%   University of California San Diego (http://sccn.ucsd.edu/).
%   User feedback welcome: email eeglab@sccn.ucsd.edu
%
% Authors: Arnaud Delorme, Scott Makeig, with substantial contributions
%   from Colin Humphries, Sigurd Enghoff, Tzyy-Ping Jung, plus contributions
%   from Tony Bell, Te-Won Lee, Luca Finelli and other contributors.
%
% Description:
%   EEGLAB is Matlab software for processing continuous or event-related
%   EEG or other physiological data. It is designed for use by both novice and
%   expert Matlab users. In normal use, the EEGLAB graphic interface calls
%   graphic functions via pop-up function windows. The EEGLAB history mechanism
%   can save the resulting Matlab calls to disk for later incorporation into
%   Matlab scripts.  A single data structure ('EEG') containing all dataset
%   parameters may be accessed and modified directly from the Matlab commandline.
%   EEGLAB now recognizes "plugins," sets of EEGLAB functions linked to the EEGLAB
%   main menu through an "eegplugin_[name].m" function (Ex. >> help eeplugin_besa.m).
%


function pth = voxDataDir(view);
%
% pth = voxDataDir(view);
%
% Return the directory in which voxel-wise
% data is kept for the current view type/
% data type. Makes it if necessary.
%
% See: er_voxelData.m
%
% ras, 04/05.
pth = fullfile(dataDir(view),'VoxelData');

if ~exist(pth)
    % make it
    [p f] = fileparts(pth);
    try
        [success, msg] = mkdir(p,f);
    catch
        errmsg = sprintf('Couldn''t create voxel data dir: %s',msg)
        error(errmsg);
    end
    fprintf('Made directory %s for voxel data.\n',pth);
end

return


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

% Last Modified by GUIDE v2.5 14-Aug-2017 19:12:30

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

% Choose default command line output for online_ssvep_gui_analysis
% save('InitData.mat','handles');
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);
initialize_gui(hObject, handles, false);

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

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

function initialize_gui(fig_handle, handles, isreset)
% If the metricdata field is present and the reset flag is false, it means
% we are we are just re-initializing a GUI by calling it from the cmd line
% while it is up. So, bail out as we dont want to reset the data.
RESET(handles, true);
% Update handles structure
guidata(handles.figure1, handles);

function freq_Callback(hObject, eventdata, handles)
% hObject    handle to freq (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 freq as text
%        str2double(get(hObject,'String')) returns contents of freq as a double
input = get(handles.freq,'string');
if regexp(input, '[^0-9., ;]')
    set(handles.noti_text, 'String', sprintf('[%s] is not acceptable', input))
    set(handles.freq,'string','6.67, 7.5, 8.57,10, 12');
end

% --- Executes during object creation, after setting all properties.
function freq_CreateFcn(hObject, eventdata, handles)
% hObject    handle to freq (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 time_stimulus_Callback(hObject, eventdata, handles)
% hObject    handle to time_stimulus (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 time_stimulus as text
%        str2double(get(hObject,'String')) returns contents of time_stimulus as a double
input = get(handles.time_stimulus,'string');
if regexp(input, '[^0-9]')
    set(handles.noti_text, 'String', sprintf('[%s] is not acceptable', input))
    set(handles.timeSti,'string','5');
end

% --- Executes during object creation, after setting all properties.
function time_stimulus_CreateFcn(hObject, eventdata, handles)
% hObject    handle to time_stimulus (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 freq_range_min_Callback(hObject, eventdata, handles)
% hObject    handle to freq_range_min (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 freq_range_min as text
%        str2double(get(hObject,'String')) returns contents of freq_range_min as a double
input = get(handles.freq_range_min,'string');
if regexp(input, '[^0-9.]')
    set(handles.noti_text, 'String', sprintf('[%s] is not acceptable', input))
    set(handles.freq_range_min,'string','0.1');
end

% --- Executes during object creation, after setting all properties.
function freq_range_min_CreateFcn(hObject, eventdata, handles)
% hObject    handle to freq_range_min (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 btnReset.
function btnReset_Callback(hObject, eventdata, handles)
% hObject    handle to btnReset (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% disp(get(handles.btwBox,'String'));
% load('InitData.mat');
% handles.output = hObject;
% disp(get(handles.btwBox,'String'));
% guidata(handles.figure1, handles);
RESET(handles,false);

% --- Executes on button press in btnStart.
function btnStart_Callback(hObject, eventdata, handles)
% hObject    handle to btnStart (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global sock state
try
    chan = get(handles.chan,'String');
    if isequal(chan,'all')
        chan = filt_EEG_CHANNEL(state.clab);
        chan = cell2mat(chan(1,:));
    else
        chan = str2double(strsplit(chan, ' ,'));
    end
    time_stimulus = str2double(get(handles.time_stimulus, 'String'));
    freq = str2double(strsplit(get(handles.freq, 'String'),','));
    fRange = [str2double(get(handles.freq_range_min, 'String')), ...
        str2double(get(handles.freq_range_max,'String'))];
    freq_class = strsplit(get(handles.freq_class,'String'),',');
    axes_fft = handles.axes_FFT;
    axes_cca = handles.axes_CCA;
    results_text = handles.results_text;
catch
    set(handles.noti_text, 'String', 'Somethings wrong...');
    return;
end
if ~isequal(sock.status,'closed')
    s = online_ssvep_Analysis(axes_fft, axes_cca, results_text, {'chan', chan;...
        'time_stimulus', time_stimulus; 'freq', freq;...
        'fRange', fRange; 'class', freq_class});
else
    set(handles.noti_text, 'String', 'check your socket');
    return;
end
bbci_acquire_bv('close');
set(handles.noti_text, 'String', s);

function chan_Callback(hObject, eventdata, handles)
% hObject    handle to chan (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 chan as text
%        str2double(get(hObject,'String')) returns contents of chan as a double
input = get(handles.chan,'string');
if ~isequal(input,'all')
    if regexp(input, '[^0-9., ;]')
        set(handles.noti_text, 'String', sprintf('[%s] is not acceptable', input))
        set(handles.freq,'string','all');
    end
end

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

try
    bbci_acquire_bv('close');
    params = struct;
    state = bbci_acquire_bv('init', params);
catch
    set(handles.noti_text,'String', 'Please open the BrainVisino Recorder');
    return;
end

if isempty(sock) || isequal(sock.status,'closed')
    port = str2double(get(handles.tcpip_port,'String'));
    sock = tcpip('localhost', port,'timeout',2);
    try
        fopen(sock);
    catch
        set(handles.noti_text, 'String', 'First open the server');
        return;
    end
    while true
        fwrite(sock,19);
        [~, ~, markerdescr, ~] = bbci_acquire_bv(state);
        if ~isempty(markerdescr)&&(markerdescr == 19)
            flushoutput(sock);
            break;
        end
    end
    set(handles.closebtn,'Visible', 'On');
    set(handles.trig_button, 'String', 'OK!');
    set(handles.noti_text, 'String', 'Connect!');
end

% --- Executes on button press in selChan.
function selChan_Callback(hObject, eventdata, handles)
% hObject    handle to selChan (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global state
filt_EEG_CHANNEL(state.clab);
select_channel_v2({'chan', state.clab});
% figure;
% uitable('Data',handles.initialization.bv.clab);

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

% --- Executes during object creation, after setting all properties.
function freq_class_CreateFcn(hObject, eventdata, handles)
% hObject    handle to freq_class (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 tcpip_port_Callback(hObject, eventdata, handles)
% hObject    handle to tcpip_port (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 tcpip_port as text
%        str2double(get(hObject,'String')) returns contents of tcpip_port as a double
input = get(handles.tcpip_port,'string');
if regexp(input, '[^0-9]')
    set(handles.noti_text, 'String', sprintf('[%s] is not acceptable', input))
    set(handles.timeSti,'string','12300');
end

% --- Executes during object creation, after setting all properties.
function tcpip_port_CreateFcn(hObject, eventdata, handles)
% hObject    handle to tcpip_port (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(handles, init)
% handles    empty - handles not created until after all CreateFcns called
% init        initialization
set(handles.chan,'String','all');
set(handles.time_stimulus, 'String','5');
set(handles.freq, 'String','6.67, 7.5, 8.57,10, 12');
set(handles.freq_range_min, 'String', '0.1');
set(handles.freq_range_max, 'String', '50');
set(handles.freq_class,'String','up, left, center, right, down');
set(handles.trig_button,'String', 'Check');
set(handles.closebtn,'Visible', 'Off');
set(handles.results_text, 'String', '');
set(handles.noti_text, 'String', 'Welcome');
set(handles.axes_FFT, 'XTickLabel','');
set(handles.axes_CCA, 'XTickLabel', '');
set(handles.axes_FFT, 'YTickLabel', '');
set(handles.axes_CCA, 'YTickLabel', '');
delete(get(handles.axes_FFT,'Children'));
delete(get(handles.axes_CCA,'Children'));
global sock
try
    bbci_acquire_bv('close');
catch
    set(handles.noti_text,'String', 'Please open the BV');
end
try
    fclose(sock);
catch
end

function freq_range_max_Callback(hObject, eventdata, handles)
% hObject    handle to freq_range_max (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 freq_range_max as text
%        str2double(get(hObject,'String')) returns contents of freq_range_max as a double
input = get(handles.freq_range_max,'string');
if regexp(input, '[^0-9.]')
    set(handles.noti_text, 'String',  sprintf('[%s] is not acceptable', input))
    set(handles.timeSti,'string','50');
end

% --- Executes during object creation, after setting all properties.
function freq_range_max_CreateFcn(hObject, eventdata, handles)
% hObject    handle to freq_range_max (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 closebtn.
function closebtn_Callback(hObject, eventdata, handles)
% hObject    handle to closebtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global sock;
fclose(sock);
set(handles.noti_text, 'String', 'Close the socket');
set(handles.trig_button,'String', 'Check');
set(handles.closebtn,'Visible', 'Off');


function x = clearconicinfo(x)
x.conicinfo = [0 0];


function MRSIStruct = setAffineMatrix(MRSIStruct, newAffineMatrix)
    MRSIStruct.affineMatrix = newAffineMatrix;
end


function cache_dir = resolve_cache_dir(model, model_dir, opts)
%
% This file is part of the code that implements the following ICCV2015 accepted paper:
% title: "Object detection via a multi-region & semantic segmentation-aware CNN model"
% authors: Spyros Gidaris, Nikos Komodakis
% institution: Universite Paris Est, Ecole des Ponts ParisTech
% Technical report: http://arxiv.org/abs/1505.01749
% code: https://github.com/gidariss/mrcnn-object-detection
%
%
% AUTORIGHTS
% --------------------------------------------------------
% Copyright (c) 2015 Spyros Gidaris
%
% "Object detection via a multi-region & semantic segmentation-aware CNN model"
% Technical report: http://arxiv.org/abs/1505.01749
% Licensed under The MIT License [see LICENSE for details]
% ---------------------------------------------------------

cache_dir_base = fullfile(model_dir, 'cache_dir');
mkdir_if_missing(cache_dir_base);
if ~isempty(opts.cache_dir)
    assert(isempty(opts.cache_dir_name));
    cache_dir = opts.cache_dir;
elseif ~isempty(opts.cache_dir_name)
    assert(isempty(opts.cache_dir));
    cache_dir = fullfile(cache_dir_base, opts.cache_dir_name);
else
    if opts.use_detection_svms
        cache_dir = fullfile(model_dir, model.svm_cache_dir(2:end));
    else
        cache_dir = fullfile(model_dir, 'softmax');
    end
end
mkdir_if_missing(cache_dir);
end


function [doseArray, isCompress, isRemote] = getDoseArray(doseIndex, planC)
%"getDoseArray"
%   Returns the doseArray stored in a planC, in slot doseIndex.  The last
%   returned doseArray is cached in a persistent variable to avoid delays
%   in loading remotely stored or compressed doses.
%
%   If a dose array is compressed it is decompressed before being returned.
%
%   If planC is not passed in, the global planC is used.
%
%   If doseIndex is not valid, or if no valid planC can be found an error is
%   returned.
%
%   isCompress and isRemote are booleans to let the calling function know
%   if the doseArray was compressed and/or remote.
%
%   JRA 10/14/04
%
%Usage:
%   function doseArray = getDoseArray(doseIndex, planC)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

persistent lastDoseStruct;
persistent lastDoseArray;
persistent isLastDoseCompressed;
persistent isLastDoseRemote;

%Check if a doseStruct, not a doseIndex was passed.
if isstruct(doseIndex) && isfield(doseIndex, 'doseArray')

    doseStruct = doseIndex(1);

else
    %An index was passed, extract the doseStruct.
	if ~exist('planC', 'var') %wy
        global planC
	end

	if ~iscell(planC)
        error('Cannot get dose. PlanC is not a valid cell array.');
	end

	indexS = planC{end};

	if doseIndex > length(planC{indexS.dose}) | doseIndex < 1
        error('Cannot get dose.  Requested doseIndex does not exist.')
	end

    doseStruct = planC{indexS.dose}(doseIndex);

end

doseArray = doseStruct.doseArray;

%If remote or compressed, and struct is same as last time, return cached array.
if (isCompressed(doseArray) || ~isLocal(doseArray)) && isequal(doseStruct, lastDoseStruct);
    doseArray = lastDoseArray;
    isCompress = isLastDoseCompressed;
    isRemote = isLastDoseRemote;
    return;
%If remote or compressed and NOT the same as last time, clear cache.
elseif (isCompressed(doseArray) || ~isLocal(doseArray)) && ~isequal(doseStruct, lastDoseStruct);
	lastDoseArray           = [];
	lastDoseStruct          = [];
	isLastDoseCompressed    = [];
	isLastDoseRemote        = [];
end

%To be output for calling function's use.
isCompress  = 0;
isRemote    = 0;

%Decompress and follow all file pointers until get to an array.
while isCompressed(doseArray) || ~isLocal(doseArray);
    if isCompressed(doseArray)
        doseArray   = decompress(doseArray);
        isCompress  = 1;
    elseif ~isLocal(doseArray);
        doseArray   = getRemoteVariable(doseArray);
        isRemote    = 1;
    end
end

lastDoseArray           = doseArray;
lastDoseStruct          = doseStruct;
isLastDoseCompressed    = isCompress;
isLastDoseRemote        = isRemote;

%temp


function noiseBand = GetNoiseBand(view, scan)
%
% noiseBand = GetNoiseBand(view, scan)
%
% Gets the noise band, the frequency-domain indices of that
% portion of the power spectrum to be used to estimate the
% noise power. Returns value of zero to indicate default
% behavior: use ALL power-spectral samples to estimate noise.
%
% Ress, 8/30/02
global dataTYPES;
if ~exist('scan', 'var')
    if isfield(view, 'ui')
        scan = getCurScan(view);
    else
        scan = 1;
    end
end

noiseBand = 0;
if isfield(dataTYPES(view.curDataType).blockedAnalysisParams(scan), 'noiseBand')
  noiseBand = dataTYPES(view.curDataType).blockedAnalysisParams(scan).noiseBand;
end


function [uniqName,scanUID] = genScanUniqName(planC, scanNum)
% previously from register_scans.m
if nargin < 2
    scanNum = 1;
end

randPart = num2str(floor(rand*1000));

if iscell(planC)
    indexS = planC{end};
    scanUID = planC{indexS.scan}(scanNum).scanUID;
    uniqName = [scanUID randPart];
else
    [~,f,ext] = fileparts(planC);
    if strcmp(ext,'.gz')
        [~,f,~] = fileparts(f);
    end
    orgRoot = '1.3.6.1.4.1.9590.100.1.2';
    scanUID = char(javaMethod('createUID','org.dcm4che3.util.UIDUtils',...
        orgRoot));
    %scanUID = dicomuid;
    uniqName = [f '_' scanUID];
end


close all
clear all
rootDir = '\\Snarp\u1\data\reading_longitude\fmri';

cd(rootDir);
[fileNum dirName] = countDirs(pwd);

for count = 3:fileNum
    try
        currentDir = dirName{count};

        cd(fullfile(rootDir,currentDir));
        mrVista;
        vw = getSelectedInplane;
        motionCompPlotMI(vw);

    end

    close all;
    clear all;

    rootDir = '\\Snarp\u1\data\reading_longitude\fmri';

	cd(rootDir);
	[fileNum dirName] = countDirs(pwd);

    pause(0.001);
end


% Copyright 2019 Jonas Koenemann, Moritz Diehl, University of Freiburg
% Redistribution is permitted under the 3-Clause BSD License terms. Please
% ensure the above copyright notice is visible in any derived work.
%
function checkStartup()
  OCL_CASADI_SETUP = getenv('OCL_CASADI_SETUP');

  if strcmp(OCL_CASADI_SETUP, 'true')
    ocl_casadi_setup_completed = true;
  else
    ocl_casadi_setup_completed = false;
  end

  if isempty(ocl_casadi_setup_completed) || ~ocl_casadi_setup_completed
    disp('Running OpenOCL setup procedure. This may required your input, and may take a while at the first time.')
    ocl.utils.startup();
    setenv('OCL_CASADI_SETUP', 'true');
  end
end


classdef GUI < handle
%GUI - The class of the main figure of PlatEMO.

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    properties(SetAccess = private)
        app = struct();     % All the components
        icon;               % Icons
        algList;            % Algorithm list
        proList;            % Problem list
        metList;            % Metric list
    end
    methods
        %% Establish the figure window
        function obj = GUI()
            % Load the data
            obj.icon = load(fullfile(fileparts(mfilename('fullpath')),'GUI'),'-mat');
            obj.readList();

            % Create the window
            obj.app.figure   = uifigure('Name','PlatEMO v4.1','Position',[0 0 1200 650],'Interruptible','off','icon',obj.icon.logo1,'BusyAction','cancel','Visible','off','WindowButtonMotionFcn',@(~,~)[]);
            obj.app.maingrid = uigridlayout(obj.app.figure,'RowHeight',{25,80,'1x'},'ColumnWidth',{'1x'},'Padding',[0 0 0 0],'RowSpacing',0);

            % Create the tab buttons
            obj.app.grid(1)    = GUI.APP(1,1,uigridlayout(obj.app.maingrid,'RowHeight',{'1x'},'ColumnWidth',{80,80,'1x',100},'Padding',[0 0 0 0],'ColumnSpacing',0,'BackgroundColor',[0 .25 .45]));
            tempPanel          = GUI.APP(1,1,uipanel(obj.app.grid(1),'BorderType','none','BackgroundColor',[0 .25 .45]));
            obj.app.buttonT(1) = uibutton(tempPanel,'Position',[-5 -5 90 35],'Text','Modules','FontSize',14,'FontColor','k','BackgroundColor',[.94 .94 .94],'ButtonpushedFcn',{@obj.cb_tab,1});
            tempPanel          = GUI.APP(1,2,uipanel(obj.app.grid(1),'BorderType','none','BackgroundColor',[0 .25 .45]));
            obj.app.buttonT(2) = uibutton(tempPanel,'Position',[-5 -5 90 35],'Text','Support','FontSize',14,'FontColor','w','BackgroundColor',[0 .25 .45],'ButtonpushedFcn',{@obj.cb_tab,2});
            tempPanel          = GUI.APP(1,4,uipanel(obj.app.grid(1),'BorderType','none','BackgroundColor',[0 .25 .45]));
            tempImage          = uiimage(tempPanel,'Position',[0 3 99 21],'ImageSource',obj.icon.bar);
            tempPanel2         = uipanel(tempPanel,'Position',[13 4 18 18],'BorderType','none','BackgroundColor',[.549 .6627 .7529]);
            obj.app.buttonT(3) = uibutton(tempPanel2,'Position',[-2 -2 24 24],'Text','','Icon',obj.icon.researchgate,'BackgroundColor',[.549 .6627 .7529],'Tooltip','ResearchGate','ButtonpushedFcn',@(~,~)web('https://www.researchgate.net/publication/312061859','-browser'));
            tempPanel2         = uipanel(tempPanel,'Position',[43 4 18 18],'BorderType','none','BackgroundColor',[.549 .6627 .7529]);
            obj.app.buttonT(4) = uibutton(tempPanel2,'Position',[-2 -2 24 24],'Text','','Icon',obj.icon.github,'BackgroundColor',[.549 .6627 .7529],'Tooltip','GitHub','ButtonpushedFcn',@(~,~)web('https://github.com/BIMK/PlatEMO','-browser'));
            tempPanel2         = uipanel(tempPanel,'Position',[73 4 18 18],'BorderType','none','BackgroundColor',[.549 .6627 .7529]);
            obj.app.buttonT(5) = uibutton(tempPanel2,'Position',[-2 -2 24 24],'Text','','Icon',obj.icon.qq,'BackgroundColor',[.549 .6627 .7529],'Tooltip','QQ','ButtonpushedFcn',@(~,~)web('https://jq.qq.com/?_wv=1027&k=cA5nUOl4','-browser'));

            % Create the menu
            obj.app.grid(2)   = GUI.APP(2,1,uigridlayout(obj.app.maingrid,'RowHeight',{'1x',13,1},'ColumnWidth',{1,75,75,75,'1x',13,1},'Padding',[0 0 0 5],'RowSpacing',5));
            obj.app.button(1) = GUI.APP([1 2],2,uibutton(obj.app.grid(2),'Text',{'Test','Module'},'VerticalAlignment','bottom','FontSize',11,'Icon',obj.icon.test,'IconAlignment','top','Tooltip',{'Test one algorithm on a problem with specified parameter settings.','You can analyse the result and study the performance of the algorithm from various aspects.'},'ButtonpushedFcn',{@obj.cb_module,1}));
            obj.app.button(2) = GUI.APP([1 2],3,uibutton(obj.app.grid(2),'Text',{'Application','Module'},'VerticalAlignment','bottom','FontSize',11,'Icon',obj.icon.application,'IconAlignment','top','Tooltip',{'Use algorithms to solve your own problem.','You can design your own problem and solve it by the suggested algorithms.'},'ButtonpushedFcn',{@obj.cb_module,2}));
            obj.app.button(3) = GUI.APP([1 2],4,uibutton(obj.app.grid(2),'Text',{'Experiment','Module'},'VerticalAlignment','bottom','FontSize',11,'Icon',obj.icon.experiment,'IconAlignment','top','Tooltip',{'Do experiment on multiple algorithms and problems.','You can observe the statistical results shown in a table and save it as an Excel or LaTeX table.'},'ButtonpushedFcn',{@obj.cb_module,3}));
            obj.app.button(4) = GUI.APP([1 2],2,uibutton(obj.app.grid(2),'Visible',false,'Text',{'About','PlatEMO'},'VerticalAlignment','bottom','FontSize',11,'Icon',obj.icon.author,'IconAlignment','top','ButtonpushedFcn',@obj.cb_author));
            obj.app.button(5) = GUI.APP([1 2],3,uibutton(obj.app.grid(2),'Visible',false,'Text',{'User','Manual'},'VerticalAlignment','bottom','FontSize',11,'Icon',obj.icon.help,'IconAlignment','top','ButtonpushedFcn',@(~,~)web(['file://',fullfile(fileparts(fileparts(mfilename('fullpath'))),'manual.pdf')],'-browser')));
            obj.app.tip       = GUI.APP(2,6,uiimage(obj.app.grid(2),'ImageSource',obj.icon.tip2,'ImageClickedFcn',@obj.cb_fold,'UserData',true));
            tempLine          = GUI.APP(3,[1 7],uipanel(obj.app.grid(2),'BackgroundColor',[.8 .8 .8]));

            % Create the modules
            movegui(obj.app.figure,'center');
            obj.app.figure.addlistener('CurrentPoint','PostSet',@obj.cb_motion);
            obj.cb_module([],[],obj.icon.GUIsetting);
            obj.app.figure.Visible = 'on';
        end
    end
	methods(Access = private)
        %% Change the menu buttons
        function cb_tab(obj,~,~,type)
            switch type
                case 1
                    [obj.app.button(1:3).Visible] = deal(true);
                    [obj.app.button(4:5).Visible] = deal(false);
                    obj.app.buttonT(1).BackgroundColor = [.94 .94 .94];
                    obj.app.buttonT(1).FontColor       = 'k';
                    obj.app.buttonT(2).BackgroundColor = [0 .25 .45];
                    obj.app.buttonT(2).FontColor       = 'w';
                case 2
                    [obj.app.button(1:3).Visible] = deal(false);
                    [obj.app.button(4:5).Visible] = deal(true);
                    obj.app.buttonT(1).BackgroundColor = [0 .25 .45];
                    obj.app.buttonT(1).FontColor       = 'w';
                    obj.app.buttonT(2).BackgroundColor = [.94 .94 .94];
                    obj.app.buttonT(2).FontColor       = 'k';
            end
            obj.app.maingrid.RowHeight = {25,80,'1x'};
        end
        %% Fold or unfold the menu
        function cb_fold(obj,~,~)
            obj.app.tip.UserData = ~obj.app.tip.UserData;
            if obj.app.tip.UserData
                obj.app.tip.ImageSource = obj.icon.tip2;
            else
                obj.app.tip.ImageSource = obj.icon.tip1;
                obj.app.buttonT(1).BackgroundColor = [0 .25 .45];
                obj.app.buttonT(1).FontColor       = 'w';
                obj.app.buttonT(2).BackgroundColor = [0 .25 .45];
                obj.app.buttonT(2).FontColor       = 'w';
                obj.app.maingrid.RowHeight         = {25,0,'1x'};
            end
        end
        %% Hide the menu when moving out of it
        function cb_motion(obj,~,~)
            if obj.app.maingrid.RowHeight{2} > 0 && ~obj.app.tip.UserData && obj.app.figure.CurrentPoint(2) < obj.app.figure.Position(4)-105
                obj.app.buttonT(1).BackgroundColor = [0 .25 .45];
                obj.app.buttonT(1).FontColor       = 'w';
                obj.app.buttonT(2).BackgroundColor = [0 .25 .45];
                obj.app.buttonT(2).FontColor       = 'w';
                obj.app.maingrid.RowHeight         = {25,0,'1x'};
            end
        end
        %% Read the function lists
        function readList(obj)
            % Read the algorithm list
            LabelStr    = {'none','single','multi','many','real','integer','label','binary','permutation','large','constrained','expensive','multimodal','sparse','dynamic','multitask','bilevel','robust'};
            obj.algList = obj.readList2('Algorithms',LabelStr);
            obj.proList = obj.readList2('Problems',LabelStr);
            obj.metList = obj.readList2('Metrics',[LabelStr,'min','max']);
        end
        function List = readList2(obj,folder,LabelStr)
            List    = {};
            Folders = split(genpath(fullfile(fileparts(mfilename('fullpath')),'..',folder)),pathsep);
            for i = 1 : length(Folders)
                Files = what(Folders{i});
                Files = Files.m;
                for j = 1 : length(Files)
                    f = fopen(Files{j});
                    fgetl(f);
                    str = regexprep(fgetl(f),'^\s*%\s*','','once');
                    fclose(f);
                    labelstr = regexp(str,'(?<=<).*?(?=>)','match');
                    if ~isempty(labelstr)
                        label = false(length(labelstr),length(LabelStr));
                        for k = 1 : length(labelstr)
                            label(k,:) = ismember(LabelStr,split(labelstr{k},'/'));
                        end
                        if any(label(:))
                            List = [List;{label},Files{j}(1:end-2)];
                        end
                    end
                end
            end
        end
        %% Change the module
        function cb_module(obj,~,~,GUIsetting)
            name = {'module_test','module_app','module_exp'};
            for i = 1 : length(name)
                if isfield(obj.app,name{i})
                    obj.app.(name{i}).app.maingrid.Visible = i==GUIsetting;
                elseif i == GUIsetting
                    obj.app.(name{i}) = feval(name{i},obj);
                end
            end
            save(fullfile(fileparts(mfilename('fullpath')),'GUI'),'GUIsetting','-append');
        end
        %% Show the figure of about PlatEMO
        function cb_author(obj,~,~)
            P = obj.app.figure.Position;
            C = obj.app.figure.CurrentPoint;
            f = uifigure('Name','About PlatEMO','Position',[P(1)+C(1) P(2)+C(2)-220 290 200],'Color','w','icon',obj.icon.logo1,'Resize','off');
            uiimage(f,'Position',[145 40 150 150],'ImageSource',obj.icon.logo2);
            uilabel(f,'Position',[10 160 170 30],'Text',obj.app.figure.Name,'HorizontalAlignment','left','FontSize',18);
            uilabel(f,'Position',[10 130 160 40],'Text',{'Evolutionary Multi-Objective','Optimization Platform'},'HorizontalAlignment','left','FontSize',12,'FontAngle','italic','FontColor',[.4 .4 .4]);
            uilabel(f,'Position',[10 80 150 40],'Text',{'Copyright (c) 2023','BIMK Group'},'HorizontalAlignment','left','FontSize',12);
            uilabel(f,'Position',[10 20 150 50],'Text',{'<Contact>','field910921@gmail.com','bimk.ahu.edu.cn'},'HorizontalAlignment','left','FontSize',12);
            uibutton(f,'Position',[210 10 70 22],'Text','OK','ButtonpushedFcn',@(~,~)delete(f));
        end
    end
    methods(Static)
        %% Generate a component
        function app = APP(row,column,app)
            app.Layout.Row    = row;
            app.Layout.Column = column;
        end
    end
end


function [prevhold] = takehold(ax, mode)
%TAKEHOLD  hold axes and return previous hold status.
%   TAKEHOLD(ax) is equivalent to hold(ax, 'on'), where ax is the handle to
%   an axes object.
%
%   TAKEHOLD(ax, 'local') clears the axes ax if their previous hold state
%   is off and then holds the axes, i.e., hold(ax, 'on').
%   This is useful when a plotting function draws multiple
%   graphics objects, so it needs to hold the plot intermediately, but
%   maintains pre-existing graphics in the plot only if hold(ax 'on') has
%   been issued by another source. This is the same behavior that the plot
%   function exhibits.
%
%   TAKEHOLD(ax, 'add') or TAKEHOLD(ax) does not clear the axes ax, but
%   instead holds it. It adds to the plot, without erasing previous
%   graphics.
%
%   prevhold = TAKEHOLD(ax, ...) returns the previous hold status of the
%   axes object ax. This can then be restored by calling
%
% usage
%   prevhold = TAKEHOLD
%   prevhold = TAKEHOLD(ax)
%   prevhold = TAKEHOLD(ax, 'add')
%   prevhold = TAKEHOLD(ax, 'local')
%
% input
%   ax = axes object handle
%   mode = 'add' | 'local'
%
% output
%   held = 1 if ax already held
%          0 if ax not already held
%
% See also RESTOREHOLD, HOLD, ISHOLD.
%
% File:      takehold.m
% Author:    Ioannis Filippidis, jfilippidis@gmail.com
% Date:      2012.01.22 - 2012.05.10
% Language:  MATLAB R2012a
% Purpose:   hold(ax, 'on') and return current hold status
% Copyright: Ioannis Filippidis, 2012-

% which axes' handle ?
if nargin < 1
    ax = gca;
end

% which mode ?
if nargin < 2
    mode = 'add';
end

prevhold = ishold(ax);

if prevhold == 1
    return
end

if strcmp(mode, 'local')
    disp('heh')
    cla(ax)
end

hold(ax, 'on')


% Copyright (C) 2018  Symeon Symeonidis, Stefanos Tsantilas, Stelios Mitilineos
% simos421@gmail.com, steftsantilas@gmail.com, smitil@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 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.

function CstPickMidPoint(mws,Name,id)

Pick = invoke(mws,'Pick');
invoke(Pick,'PickMidpointFromId',strcat('component1:',Name),num2str(id));
end


function varargout = exp_eval(x,iters)
% Evaluate the given expression data structure (or short: expression).
% Out-Args = exp_eval(Expression, Iterations)
%
% exp_eval operates on data structures that represent expressions, and evaluates them. The canonical
% expression data structure is of the form:
%  struct
%    .head: function_handle
%    .parts: cell array
%
% This structure represents the expression head(parts{:}). Expression data structures can be nested,
% and can have their value attached, if that value is a struct (they can have a "payload", in a
% sense). In this case, they are structured in the form:
%  struct
%    .whatever_fields_belong_to_the_value
%    .tracking: struct
%      .expression: the actual expression data structure
%
% This way, EEG and STUDY data sets can be regular value types and expressions at the same time,
% which allows to annotate EEGLAB data sets with an expression which (uniquely) identifies them, and
% which reproduces them. Expressions are created by some of the expressions/exp_* functions, and by
% functions using the exp_beginfun/exp_endfun contract (i.e., BCILAB filters and data set editing
% components). For this reason, a call like io_quickload('/data/test.set') or
% flt_resample(eeg,[],200) do by default return an unevaluated expression data structure, which must
% be evaluated first (using exp_eval()), to get access to its value. In other words,
% exp_eval(io_quickload('/data/test.set')) gives the EEGLAB data set. This can be viewed as "lazy"
% evaluation. BCILABs framework functions (bci_train, bci_predict, bci_preproc, etc.) do this
% implicitly and automatically.
%
%
% In:
%   Expression : an expression
%   Iterations : maximum number of repeated evaluations applied (default: 1)
%                for real symbolic computations, pass Inf here
%
% Out:
%   Out-Args   : the result of the evaluation, may still be unevaluated if the expression could not
%                be completely evaluated
%
% Notes:
%   For the purposes of exp_eval(), every data structure that can be expressed in MATLAB is an
%   expression.
%   * Almost all data structures, however, are considered to be 'literal' (and atomic) expressions,
%     such as numbers, strings, function handles, but also recursive data structures, such as cell
%     arrays and structs. These literals cannot be further evaluated. Therefore, almost all MATLAB
%     expressions produce literal expressions, such as, for example, fft(randn(100,1)).
%
%   * A subset of expressions, however, yields by default data that represents unevaluated (or
%     partially evaluated) expressions. Such expressions are formed using either functions that
%     follow the exp_beginfun/exp_endfun protocol, or symbols introduced using exp_symbol or
%     exp_declare. The bulk of these expressions "evaluate" into structures with the two fields
%     'head' and 'parts', where 'head' is a function_handle and 'parts' is a cell array. The purpose
%     of exp_eval() is to fully evaluate these unevaluated expressions, by applying the head to the
%     parts ("calling" the function head with parts as its arguments, in MATLAB terms).
%
%   * To ease interaction with other MATLAB code, some expressions may retain, after having been
%     evaluated (into a MATLAB structure), a subfield that holds the original unevaluated expression
%     that reproduces the data when re-evaluated. These expressions are called "impure" expressions,
%     because they can be viewed both as an unevaluated expression and an evaluated expression. They
%     can thus be processed both by expression-oriented code, and by code that expects values.
%
% Usage Notes:
%   * any MATLAB function can be converted into one that is not immediately evaluated, by adding the
%     two lines "if ~exp_beginfun() return; end", and "exp_endfun;" to its definition, before and
%     after the remaining code.
%   * using exp_symbol, exp_declare_symbols, or @name_of_no_defined_function, arbitrary identifiers
%     can be introduced which are not immediately evaluated (but some of which could be evaluated by
%     exp_eval, given that function code and/or values are defined for them).
%
% Further Reading:
%   A good way to understand symbolic expressions and the operations on them is to read the
%   Mathematica online documentation. The expression system shares some commonalities with
%   Mathematica, with the following considerations:
%    * A subset of functions is implemented with analogous semantics, where SomeFunction is called
%      exp_somefunction in MATLAB
%    * MATLAB has a larger palette of atomic expressions (in addition to String, Number, Symbol, it
%      has Value, which reflects structs, matrices, etc.) In the future, more builtin data structure
%      may be reflected as List, SparseArray, etc.
%    * () are used instead of [], and most operators, such as //., :> cannot be expressed in MATLAB,
%      so that their functional forms must be used.
%    * symbols must be formally introduced before use (with exp_declare_symbols), or expressed
%      either as exp_symbol('x') or as @x
%    * expressions of the form f(a)(b) cannot be interpreted by MATLAB. The workaround is
%      x=f(a);x(b).
%    * expressions are not automatically evaluated; this must be done explicitly with exp_eval().
%      also, the evaluator implemented here is less aggressive, and can be invoked for a limited
%      number of steps.
%    * for the implementation of functions, the exp_beginfun/exp_endfun prologue-epilogue pattern is
%      available.
%
% Examples:
%   % evaluate a dataset-loading expression
%   eeg = exp_eval(io_loadset('/data/projects/test.set'))
%
%   % write up a sequence of filter steps, and finally evalate it; note that, if this particular
%   % sequence had been executed previously, and was cached on disk, the result will be directly
%   % retrieved from the disk cache
%   eeg = io_loadset('/data/projects/test.set')
%   eeg = flt_resample(eeg,200)
%   eeg = flt_iir(eeg,[0.5 2],'highpass')
%   eeg = exp_eval(eeg);
%
% See also:
%   exp_beginfun, exp_endfun, exp_eval_optimized
%
%                                Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                2010-04-15
dp;

if nargin < 2
    iters = 1;
elseif ~(isnumeric(iters) && isreal(iters) && isscalar(iters) && round(iters) == iters) || iters < 1
    error('The given Iterations argument must be a positive integer.');
end

varargout = {x};
while iters > 0
    % check if we got a canonically represented expression
    if isscalar(x) && all(isfield(x,{'head','parts'}))
        chead = char(x.head);
        % we did, check if it's an application of a lambda or builtin function
        if chead(1) == '@' || (exist(char(x.head),'builtin') && ~exist(char(x.head),'file'))
            % if so, need to pre-evaluate the parts
            x.parts = cellfun(@(v)exp_eval(v,iters),x.parts,'UniformOutput',false);
            % if not all of the args could be evaluated: return unevaluated
            if ~all(cellfun(@is_evaluated,x.parts))
                return; end
        end
        % apply the function
        try
            varargout = hlp_wrapresults(x.head,x.parts{:});
        catch e
            if ~(strcmp(e.identifier,'MATLAB:UndefinedFunction') && strcmp(e.stack(1).name,'hlp_wrapresults'))
                % got a legitimate error, check if we're in dbstop-if-error mode
                settings = dbstatus;
                if any(strcmp({settings.cond},'error')) && ~hlp_resolve('disable_dbstop_if_error_msg',false)
                    % if in dbstop if error mode, we're re-running the line to get the debugger to stop at the right place
                    disp_once('exp_eval: caught error while in "dbstop if error" mode; re-running offending code to get break point...\n  error traceback was: %s\n',hlp_handleerror(e));
                    varargout = hlp_wrapresults(x.head,x.parts{:});
                else
                    rethrow(e);
                end
            else
                % otherwise we just return unevaluated
                return;
            end
        end
    elseif isa(x,'function_handle')
        str = char(x);
        if str(1) ~= '@'
            % regular function handle and undefined?: do a lookup
            if is_undefined_function(x)
                varargout = {hlp_resolve(x,x)}; end
        else
            % lambda function
            try
                % try to obtain the function symbol, if it's a symbolic lambda function
                varargout = {hlp_resolve(get_function_symbol(x),x)};
            catch
            end
        end
    end

    iters = iters-1;

    if iters == 0 || isempty(varargout) || utl_same(x,varargout{1}) || (length(varargout) > 1 && is_evaluated(varargout{1}))
        % evaluation terminates only when the expression no longer changes, or the maximum number of
        % iterations is exceeded (or when multiple evaluated args are being returned and the first
        % one is fully evaluated... - because we want to return these additional outputs)
        break;
    else
        % otherwise we start over...
        x = varargout{1};
    end
end


function C = blue()
  % BLUE Returns a nice bluecolor
  %
  % Outputs:
  %   [0.2 0.3 0.8]
  C = [0.2 0.3 0.8];
end


function setfontsizefigure(fontsize)
% setfontsizefigure(fontsize)
% set font size (axes, labels) of the current figure
set(get(gca,'XLabel'),'FontSize',fontsize)
set(get(gca,'YLabel'),'FontSize',fontsize)
set(get(gca,'ZLabel'),'FontSize',fontsize)
set(gca,'FontSize',fontsize)


function t = chanhandle(varargin)
% T = CHANHANDLE; Constructor for class CHANHANDLE
% Chanhandle class contains channel-specific information only.
% An object belonging to chanhandle has the following properties:
%   ChannelNumber
%   Sensitivity
%   SensorInfo
% Usage:
% t = chanhandle; Default values
% t = chanhandle(t1); where t1 is a chanhandle
% t = chanhandle(fname,channelnum); where fname is name of the sqd file
% See also,
% @chanhandle/get.m,set.m,writechanloc.m

% Note:
% Object structure:
% Chanhandle can be a handle to only one channel, or several channels.
% To accomodate an object array, the object is structured as follows:
% Chanhandle_obj has only one field - "handle". Subfields of "handle" are
% the above named properties. ie
% ChanHandle_Obj ->
%       handle   ->
%           ChannelNumber
%           Sensitivity
%           SensorInfo
% When the ChanHandle_obj contains several channels, "handle" is an array of
% structures.
%
% Also, note that:
% The ChannelNumber subfield indicates the hardware channel number. Whereas, the
% index of handle is software index to it. The index of handle is monotonically
% increasing from 1. So Chanhandle_obj contains HwChannels = 0,1,3
% then  handle(1) -> HwChannel = 0
%       handle(2) -> HwChannel = 1
%       handle(3) -> HwChannel = 3
% ChanHandle_obj is be indexed as the "handle" substructure.
%
% For internal use only, an additional way of initialising object:
%   t = chanhandle(handle); where "handle" is a structure with the channel's info
%       Fields for "handle": ChannelNumber,Sensitivity,SensorInfo

% initialize the fields of the object to default values
t.handle.ChannelNumber             = 0; % hardware channel number (0-191)
t.handle.Sensitivity               = []; % Sensitivity Gain/Offset
t.handle.SensorInfo                = []; % type,position,size,etc. of sensor

% Define class definition
t = class(t,'chanhandle');
switch nargin
case 0
    % Default object, return
case 1
    if isa(varargin{1},'chanhandle'), % if argin = chanhandle_obj
        t = varargin{1};
    elseif ischar(varargin{1})        % if argin = sqd-filename
        fname = varargin{1};
        t.handle = readsqdinfo(t.handle,varargin{1});
    elseif isstruct(varargin{1})      % if argin = "handle" substructure
        t.handle = varargin{1};
    else
        error('Incorrect input to chanhandle.m');
    end;
case 2                                  % if argin = sqd-filename,channelnumber
    if ischar(varargin{1})&isnumeric(varargin{2})
        for i = 1:length(varargin{2})
            t.handle(i).ChannelNumber = varargin{2}(i);
            if ~isempty(varargin{1})    % In case no file name is passed - default values
                t.handle(i) = readsqdinfo(t.handle(i),varargin{1});
            end;
        end;
    else
        error('Incorrect inputs to chanhandle.m');
    end;
otherwise
    error('Incorrect inputs to chanhandle.m');
end;

function t = readsqdinfo(t,fname)
% T = READSQDINFO(T,FNAME); Update values of CHANHANDLE object 'T'
% to those given in sqd-file FNAME

seekset=-1; % Start point for fseek: -1 => beginning of the file

if nargin<2|~ischar(fname),error('Incorrect arguments');end;

% open file as binary and little endian
fid = fopen(fname,'rb','l');
if fid==-1,
    disp('File not found');
    [f,p] = uigetfile('*.sqd','MEG160 files');
    if ((~isstr(f)) | ~min(size(f))),
        t = [];
        return;
    end;
    fname = [p f];
    t.FileName = [p f];
    fid = fopen(fname,'rb','l');
end;

%Read in info regarding sensitivity of sensors
t.Sensitivity   = sensitivityinfo(fid,seekset,t.ChannelNumber);
% Read in sensor location
t.SensorInfo    = sensorinfo(fid,seekset,t.ChannelNumber);

% Close file
fclose(fid);