%kkappend 'Append (or Prepend) Input Objects to Base Object'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kappend.pane file
%
% Parameters:
% InputFile: i1 'Input 1 (Base)', required: 'Base Input data object (input 1)'
% InputFile: i2 'Input 2', optional: 'input file 2'
% InputFile: i3 'Input 3', optional: 'input file 3'
% InputFile: i4 'Input 4', optional: 'input file 4'
% InputFile: i5 'Input 5', optional: 'input file 5'
% InputFile: i6 'Input 6', optional: 'input file 6'
% InputFile: i7 'Input 7', optional: 'input file 7'
% InputFile: i8 'Input 8', optional: 'input file 8'
% InputFile: i9 'Input 9', optional: 'input file 9'
% InputFile: i10 'Input 10', optional: 'input file 10'
% OutputFile: o 'Output', required: 'Resulting output data object'
% Toggle: w 'Width', default: 0: 'Stack objects along width dimension'
% Toggle: h 'Height', default: 0: 'Stack objects along height dimension'
% Toggle: d 'Depth', default: 0: 'Stack objects along depth dimension'
% Toggle: t 'Time', default: 0: 'Stack objects along time dimension'
% Toggle: e 'Elements', default: 0: 'Stack objects along elements dimension'
%
% Example: o = kkappend({i1, i2, i3, i4, i5, i6, i7, i8, i9, i10}, {'i1','';'i2','';'i3','';'i4','';'i5','';'i6','';'i7','';'i8','';'i9','';'i10','';'o','';'w',0;'h',0;'d',0;'t',0;'e',0})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kappend - Append (or Prepend) Input Objects to Base Object
%
%  DESCRIPTION
% The "Append" operator (kappend) combines all input data objects
% (i1 to i10) into a single output object (o).
% The objects are combined in order from Input 1 to Input 10.  If the
% user specifies placement as "Prepend Objects to Base Object" (-append 0),
% then the first input will be the last appended to the output object.
% The dimension flags Width (w_flag), Height (h_flag), Depth (d_flag),
% Time (t_flag), and Elements (e_flag), specify which dimension the objects
% will be stacked along.  For example, stacking two images along width
% would produce an output with the images side by side.  One and only one
% of the dimension flags can be true.
%
%  "Value Data" 5
% All input objects must have value data.  The value size of each input
% object will be zero-padded to the maximum of all sizes, except in the
% stacking dimension.  The output size in the stacking dimension will
% be the sum of that dimension across all input objects.  The output object
% data type will be the highest data type of the input data objects.
%
%  "Map Data" 5
% When some or all of the input objects have map data, the treatment of the
% maps, and how the data is represented in the output object, depends on the
% mapping option (mapping) specified by the user.
% Possible mapping options are:  (0) Map Data Thru Maps, (1) Use First Map Only,
% and (2) Create a Map for Each Input.
% If no input objects have maps, the mapping option is ignored.
% If there are doubts about which
% mapping option to use, the safest bet is to map the data thru the maps.
%
%
%  "Map Data Thru Maps:" 5
% 	All data will be mapped before the data objects are combined.  The output
% 	object will not have a map.
%
%  "Use First Map Only:" 5
% 	In this case, the map data and color attributes of the first input
% 	object that has a map are directly transferred to the output object.
% 	The depth, time, and elements dimensions of that map must be 1, otherwise
% 	this mapping option will fail.  Note that by selecting this mapping
% 	option, you are assuming that the value segments of all objects being
% 	appended have valid indices into that map.
%
%  "Create a Map for Each Input:" 5
% 	(All input objects may have maps.)
% 	For each input object that does not have a map, one will be created for it.
% 	The the output object color attributes will be copied from the first
% 	input object that has a map.  New map values will be assigned using the
% 	autocolor attribute.
%
%
% 	The map dimension corresponding to the stacking dimension (Depth, Time,
% 	or Elements) will reflect the new size of the value data in that dimension,
% 	and the maps from each object will be appended accordingly.
% 	The maximum width and height of all maps will be propagated to the output,
% 	with zero-padding being applied where necessary.
% 	Padding in the other map dimensions may occur as well.
% 	For example, if objects with the following map and value
% 	Depth sizes are being stacked along the Depth dimension,
%
% 			obj1  DEP=3  MAP_DEP = 3
% 			obj2  DEP=4  MAP_DEP = 1
% 			obj2  DEP=2  MAP_DEP = 2
%
% 	the resulting value data will have a depth of 9, so the map depth will be 9
% 	too.  In this example, the second object's map will be zero-padded to have
% 	a map depth of four.
%
%
% 	If the objects are being combined along the width or
% 	height dimensions, this mapping option will fail.
%
%
%
% The output object map data type will be the highest of the input object map
% data types.
%
%  "Mask Data" 5
% If any input object has mask data, then the output
% object will also have mask data.  The mask data will be resized
% in the same manner as value data is resized.  The mask will be padded
% as valid (1). The highest
% data type of input masks will be propagated to the output mask.
%
%  "Location and Time Data" 5
% In all cases, the time and location data and/or attributes
% of the first input object will transferred to the output
% object.  If location or time data is propagated, data values
% along the stacking dimension will not be changed, and
% therefore, the location or time data may become invalid.
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
% DATAMANIP::kinset
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkappend(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kkappend(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'i2', '__input';'i3', '__input';'i4', '__input';'i5', '__input';'i6', '__input';'i7', '__input';'i8', '__input';'i9', '__input';'i10', '__input';'o', '__output';'w', 0;'h', 0;'d', 0;'t', 0;'e', 0};
maxval={0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0};
minval={0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0};
istoggle=[0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1];
was_set=istoggle * 0;
paramtype={'InputFile','InputFile','InputFile','InputFile','InputFile','InputFile','InputFile','InputFile','InputFile','InputFile','OutputFile','Toggle','Toggle','Toggle','Toggle','Toggle'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'kappend"  '],Inputs,narglist);


function P = subsasgn(P, index, val)
%
%  SUBSASGN  Define index assignment for psf object.
%
%               P = subsref(P, index, val)
%
%          This is called whenever an assignment statement of a
%          psf object is made, such as:
%              P(i) = val, i = 1, 2
%              P.fieldname = val, fieldname = image, center
%

%  J. Nagy 5/1/01

switch index.type
case '()'
  switch index.subs{:}
  case 1
    P.image = val;
  case 2
    P.center = val;
  otherwise
    error('Index out of range.')
  end

case '.'
  switch index.subs
  case 'image'
    P.image = val;
  case 'center'
    P.center = val;
  otherwise
    error('Invalid field names.');
  end

case '{}'
  error('Cell array indexing not supported for psf object.')
end


mex pochhammer.c ../lightspeed/util.obj -I../lightspeed
mex di_pochhammer.c ../lightspeed/util.obj -I../lightspeed
%mex tri_pochhammer.c ../lightspeed/util.obj -I../lightspeed
%mex s_derivatives.c ../lightspeed/util.obj -I../lightspeed


function GPIB
hMainFigure = figure(...       % The main GUI figure
                    'MenuBar','none', ...
                    'Toolbar','none', ...
                    'HandleVisibility','callback', ...
                    'Color', get(0,...
                             'defaultuicontrolbackgroundcolor'));

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

global eje;
global inicial;
global final;
global paso;
global hcontrol;
global ESP300;
global hmanual;
global hautomatico;
global hvar;

clc

h = uicontrol(hMainFigure,'Style', 'pushbutton', 'String', 'Mover',...
    'Position', [400 50 100 20],'Callback',@Mover);
%--------------------------------------------------------------------------
hcerrar = uicontrol(hMainFigure,'Style', 'pushbutton', 'String', 'Cerrar',...
    'Position', [50 50 100 20],'Callback',@Cerrar);
%--------------------------------------------------------------------------
uicontrol(hMainFigure,'Style', 'text','String', 'Eje',...
    'Position', [20 365 80 20])
heje = uicontrol(hMainFigure,'Style', 'edit','String', '1',...
    'Position', [20 350 80 20],'Callback',@heje_call);
eje = str2double(get(heje,'String'));
%--------------------------------------------------------------------------
uicontrol(hMainFigure,'Style', 'text','String', 'Inicial',...
    'Position', [20 315 80 20])
hinicial = uicontrol(hMainFigure,'Style', 'edit', 'String', '0',...
    'Position', [20 300 80 20],'Callback',@hinicial_call);
inicial = str2double(get(hinicial,'String'));
%--------------------------------------------------------------------------
uicontrol(hMainFigure,'Style', 'text','String', 'Final',...
    'Position', [20 265 80 20])
hfinal = uicontrol(hMainFigure,'Style', 'edit', 'String', '0',...
    'Position', [20 250 80 20],'Callback',@hfinal_call);
final = str2double(get(hfinal,'String'));
%--------------------------------------------------------------------------
uicontrol(hMainFigure,'Style', 'text','String', 'Paso',...
    'Position', [20 215 80 20])
hpaso = uicontrol(hMainFigure,'Style', 'edit', 'String', '0.05',...
    'Position', [20 200 80 20],'Callback',@hpaso_call);
paso = str2double(get(hpaso,'String'));
%--------------------------------------------------------------------------
uicontrol(hMainFigure,'Style', 'text','String', 'Control',...
    'Position', [20 165 80 20])
hcontrol = uicontrol(hMainFigure,'Style', 'edit',...
    'Position', [20 150 80 20]);
%--------------------------------------------------------------------------

%--------------------------------------------------------------------------
hmanual = uicontrol(hMainFigure,'Style', 'radiobutton',...
    'String', 'Manual',...
    'Position', [200 350 100 20],...
    'Callback',@Manual);
%--------------------------------------------------------------------------
hautomatico = uicontrol(hMainFigure,'Style', 'radiobutton',...
    'String', 'Automatico',...
    'Position', [200 320 100 20],...
    'Callback',@Automatico);
%--------------------------------------------------------------------------
heje1 = uicontrol(hMainFigure,'Style', 'radiobutton',...
    'String', 'Eje 1',...
    'Position', [300 350 100 20],...
    'Callback',@Eje1);
%--------------------------------------------------------------------------
heje2 = uicontrol(hMainFigure,'Style', 'radiobutton',...
    'String', 'Eje 2',...
    'Position', [300 320 100 20],...
    'Callback',@Eje2);
%--------------------------------------------------------------------------
heje3 = uicontrol(hMainFigure,'Style', 'radiobutton',...
    'String', 'Eje 3',...
    'Position', [300 290 100 20],...
    'Callback',@Eje3);
%--------------------------------------------------------------------------
ESP300 = gpib('ni',0,1);
ESP300.Timeout = 0.5;
fopen(ESP300);

function Mover(hObject, eventdata)

global eje
global inicial
global final
global paso
global hcontrol;
global ESP300;
global hmanual;
global hautomatico;

%--------------------------------------------
if (get(hmanual,'Value') == get(hmanual,'Max'))
    MovManual(eje,inicial,final,paso,ESP300,hcontrol);
end
if (get(hautomatico,'Value') == get(hautomatico,'Max'))
    MovAutomatico(eje,inicial,final,paso,ESP300,hcontrol);
end

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

function [PosFinal] = MovManual(eje,inicial,final,paso,ESP300,hcontrol)
ESP300.EOIMode = 'on';
ESP300.EOSMode = 'read';
ESP300.EOSCharCode = 'X';

Send = ([num2str(eje),'PA',num2str(final)]);
fprintf(ESP300,Send);

%--------------------------------------------
fprintf(ESP300,'TS')
Dato1a  = fscanf(ESP300,'%s');

while ~(strcmp(Dato1a,'P'))
    fprintf(ESP300,'TS')
    Dato1a  = fscanf(ESP300,'%s')
end

if Dato1a == 'P'

    Send1 = ([num2str(eje),'TP']);
    fprintf(ESP300,Send1);
    Dato1 = fscanf(ESP300,'%s')
   % [Dato1 Resi1] = query(ESP300,Send1,'%s','%s');
    set(hcontrol,'String',num2str(Dato1));
    pause(0.5)
end

function MovAutomatico(eje,inicial,final,paso,ESP300,hcontrol)

var = (inicial)

while final+paso >= var

    MovManual(eje,inicial,var,paso,ESP300,hcontrol)
    var = var+paso
end

function Eje1(hObject, eventdata)

global ESP300;

ESP300.EOIMode = 'on';
ESP300.EOSMode = 'read';
ESP300.EOSCharCode = 'X';

if (get(hObject,'Value') == get(hObject,'Max'))
	Send1 = (['1','MO']);
    fprintf(ESP300,Send1);
    set(hObject,'String','Eje 1 ON');
else
    Send1 = (['1','MF']);
    fprintf(ESP300,Send1);
	set(hObject,'String','Eje 1');
end

function Eje2(hObject, eventdata)

global ESP300;

ESP300.EOIMode = 'on';
ESP300.EOSMode = 'read';
ESP300.EOSCharCode = 'X';

if (get(hObject,'Value') == get(hObject,'Max'))
	Send1 = (['2','MO']);
    fprintf(ESP300,Send1);
    set(hObject,'String','Eje 2 ON');
else
    Send1 = (['2','MF']);
    fprintf(ESP300,Send1);
	set(hObject,'String','Eje 2');
end

function Eje3(hObject, eventdata)

global ESP300;

ESP300.EOIMode = 'on';
ESP300.EOSMode = 'read';
ESP300.EOSCharCode = 'X';

if (get(hObject,'Value') == get(hObject,'Max'))
	Send1 = (['3','MO']);
    fprintf(ESP300,Send1);
    set(hObject,'String','Eje 3 ON');
else
    Send1 = (['3','MF']);
    fprintf(ESP300,Send1);
	set(hObject,'String','Eje 3');
end

function Cerrar(hObject, eventdata)

global ESP300;

fclose(ESP300);
delete(ESP300);
close all

function Manual(hObject, eventdata)

global hautomatico;

if (get(hObject,'Value') == get(hObject,'Max'))
	set(hautomatico,'Value',0);
else
	% Radio button is not selected-take approriate action
end

function Automatico(hObject, eventdata)

global hmanual;

if (get(hObject,'Value') == get(hObject,'Max'))
	set(hmanual,'Value',0);
else
	% Radio button is not selected-take approriate action
end

function heje_call(hObject, eventdata)
global eje
eje = str2double(get(hObject,'String'));

function hinicial_call(hObject, eventdata)
global inicial
inicial = str2double(get(hObject,'String'));

function hfinal_call(hObject, eventdata)
global final
final = str2double(get(hObject,'String'));

function hpaso_call(hObject, eventdata)
global paso
paso = str2double(get(hObject,'String'));


function [conds,labels,stimData] = StimCSV_Reader()
    %Open File
%     filename = "StimCSV_Sample_Error.csv";
    [file,path,~] = uigetfile({'*.csv','CSV File (*.csv)'});
    filename = [path file];
    stimFileID = fopen(filename);

    %Initial Variables
    i = 1;
    stimNameIndicator = true;
    stimLabelIndicator = true;
    labels = cell(1,1);
    data = [];
    stimData = cell(1,1);

    %Get Line
    linestr = fgetl(stimFileID);

    while(linestr ~= -1)
        strCell = strsplit(linestr,',');
        strCell = strCell(~cellfun(@isempty,strCell));
        if isempty(strCell) %Update Stim (Finalize)
            try
                stimData{:,i} = data;
            catch
                errordlg('Invalid Stim CSV Syntax. Please check reference file for guidance');
                return;
            end
            i = i+1;
            stimNameIndicator = true;
            stimLabelIndicator = true;
            data = [];
        elseif stimNameIndicator %Update Stim Name
            try
                conds{i} = strCell(1);
            catch
                errordlg('Invalid Stim CSV Syntax. Please check reference file for guidance');
                return;
            end
            stimNameIndicator = false;
        elseif stimLabelIndicator %Update Stim Label
            labels{i} = strCell;
            stimLabelIndicator = false;
        else %Update Stim Data
            try
                data = [data; strCell];
            catch
                errordlg('Invalid Stim CSV Syntax. Please check reference file for guidance');
                return;
            end
        end
        %Read Next Line
        linestr = fgetl(stimFileID);
    end

    %Final Stim Update
    stimData{:,i} = data;

    %Close File
    fclose(stimFileID);
end


%kkcp 'Copy a toolbox, software object, or file'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kcp.pane file
%
% Parameters:
% Toggle: force 'Force Output', default: 0: 'force output?'
% String: otb 'Old Toolbox', default: ' ': 'origination toolbox'
% String: ntb 'New Toolbox', default: ' ': 'destination toolbox'
% String: oname 'Object Name', default: ' ': 'software object to be copied'
% InputFile: i 'Old File', optional: 'original file'
% OutputFile: o 'New File', optional: 'copied file'
%
% Example: o = kkcp(i, {'force',0;'otb',' ';'ntb',' ';'oname',' ';'i','';'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kcp - Copy a toolbox, software object, or file
%
%  DESCRIPTION
% When a program or library object is copied from one toolbox to another,
% the directory structure of the program or library object must be duplicated
% in the second toolbox.  Then, all the files associated with the object must be
% copied from the first toolbox to the second.  Note that the relative paths
% from the toolbox top level source are preserved during the copy.  After all
% the files are copied, the new object is registered in the toolbox.
%
% If the object already exists in the destination toolbox,
% "\s-1kcpobj\s+1" will
% prompt whether to cancel the operation, remove the existing object in the
% destination toolbox before re-creating it, or to overwrite the existing object
% in the destination toolbox.
%
% When the [-force] option is used, if the object already exists in the
% destination toolbox, the object will be removed completely and then re-created.
%
% This program allows you to copy your object out of your distribution toolbox
% to a work toolbox so you can work on it.  This method of work is recommended,
% if a program needs to be worked on for an extended period of time.
%
% It is not recommended that the overwrite mode of kcpobj is used after
% major enhancements are made to the object, especially if one or more filenames
% have changed or files have been deleted (because over-write mode will not
% delete files, only add them).
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkcp(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kkcp(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'force', 0;'otb', ' ';'ntb', ' ';'oname', ' ';'i', '__input';'o', '__output'};
maxval={0,0,0,0,1,1};
minval={0,0,0,0,1,1};
istoggle=[1,1,1,1,1,1];
was_set=istoggle * 0;
paramtype={'Toggle','String','String','String','InputFile','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=0; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'kcp"  '],Inputs,narglist);


classdef String
  % String utils

  % comma-separated list of items
  methods (Static)

    function c = commaSepList2CellStr(s)
      c = regexp(s,',','split');
      c = strtrim(c);
    end

    function s = cellstr2CommaSepList(c)
      if isempty(c)
        s = '';
      else
        s = [sprintf('%s,',c{1:end-1}) c{end}];
      end
    end

    function s = cellstr2DelimList(c,d)
      if isempty(c)
        s = '';
      else
        pat = sprintf('%%s%s',d);
        s = [sprintf(pat,c{1:end-1}) c{end}];
      end
    end

    % see civilizedStringFromCellArrayOfStrings

    function s = niceUpperCase(s)
      s = lower(s);
      if ~isempty(s)
        s(1) = upper(s(1));
      end
    end

  end

end


function opts = mergeOptions(opts1, opts2)
% Merges two options structures with one having precedence over the other.
%
% function opts = mergeOptions(opts1, opts2)
%
% input: opts1 and opts2 are two structures.
% output: opts is a structure containing all fields of opts1 and opts2.
% Whenever a field is present in both opts1 and opts2, it is the value in
% opts2 that is kept.
%
% The typical usage is to have opts1 contain default options and opts2
% contain user-specified options that overwrite the defaults.
%
% See also: getGlobalDefaults

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Dec. 30, 2012.
% Contributors:
% Change log:

    if isempty(opts1)
        opts1 = struct();
    end
    if isempty(opts2)
        opts2 = struct();
    end

    opts = opts1;
    fields = fieldnames(opts2);
    for i = 1 : length(fields)
        opts.(fields{i}) = opts2.(fields{i});
    end

end


% plugin_getweb - support function to get plugin information from the web

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

function [plugin,eeglabVersionStatus] = plugin_getweb(type, pluginOri, varargin)
plugin = [];
eeglabVersionStatus = [];

if nargin < 1, help plugin_getweb; return; end
if nargin < 2, pluginOri = []; end

% convert plugin list format if necessary
if isfield(pluginOri, 'plugin'), pluginOri = plugin_convert(pluginOri); end

[~,dateTmp] = version;
if datenum(dateTmp) < 736583
    error( [ 'The plugin manager is only available for Matlab version 2016b and later versions.' 10 ...
              'Download plugins from the internet and unzip them in the plugin folder instead.' ] );
end

% retrieving statistics
eeglab_options;
try
    disp( [ 'Retrieving download statistics...' ] );
    if exist('OCTAVE_VERSION', 'builtin') == 0
        [plugin, status] = plugin_urlread([ 'http://sccn.ucsd.edu/eeglab/plugin_uploader/plugin_getcountall_nowiki_json.php?type=' type '&upload=' num2str(option_showpendingplugins)]);
    else
        [plugin, status] = urlread([ 'http://sccn.ucsd.edu/eeglab/plugin_uploader/plugin_getcountall_nowiki_json.php?type=' type '&upload=' num2str(option_showpendingplugins)]);
    end
    if isempty(plugin)
        disp('Issue with retrieving statistics for extensions');
        return;
    end
    try
        plugin = jsondecode(plugin);
    catch
        disp('Issue with decoding plugin information, Octave 7.x required to decode JSON strings');
    end
catch
    disp('Cannot connect to the Internet to retrieve statistics for extensions');
    return
end

if status == 0
    disp('Cannot connect to the Internet to retrieve extension list');
    return
end

%% rename fields for backward compabitiligy
renameField = { 'plugin' 'name';
                'count'  'downloads';
                'curversion' 'version';
                'link'   'zip' };

if ~isempty(pluginOri)
    currentNames = lower({ pluginOri.name });
else
    currentNames = {};
end
for iRow = 1:length(plugin)

    % rename fields
    for iField = 1:size(renameField, 1)
        plugin(iRow).(renameField{iField, 2}) = plugin(iRow).(renameField{iField, 1});
    end

    % decode tags
    plugin(iRow).rawtags = plugin(iRow).tags;
    if ~isempty(plugin(iRow).rawtags)
        tmpTags = textscan(plugin(iRow).rawtags, '%s', 'delimiter', ',');
        plugin(iRow).tags = tmpTags{1}';
    end

    plugin(iRow).numrating =  str2double(plugin(iRow).numrating);
    plugin(iRow).rating    =  str2double(plugin(iRow).rating);
    plugin(iRow).critical  =  str2double(plugin(iRow).critical);
    plugin(iRow).downloads =  str2double(plugin(iRow).downloads);
    plugin(iRow).size      =  sscanf(plugin(iRow).size, '%f'); % Only numeric part is taken, possible KB or MB additions are ignored
    plugin(iRow).webrating = [ 'https://sccn.ucsd.edu/eeglab/plugin_uploader/simplestar.php?plugin=' plugin(iRow).name '&version=' plugin(iRow).version ];

    % match with existiting plugins
    indMatch = strmatch(lower(plugin(iRow).name), currentNames, 'exact');
    if isempty(indMatch)
        plugin(iRow).currentversion  = '-';
        plugin(iRow).installed       = 0;
        plugin(iRow).installorupdate = 1;
        plugin(iRow).status          = 'notinstalled';
    else
        if length(indMatch) > 1
            disp([ 'Warning: duplicate extension ' plugin(iRow).name ' installed' ]);
        end
        plugin(iRow).currentversion = pluginOri(indMatch).currentversion;
        plugin(iRow).foldername     = pluginOri(indMatch).foldername;
        plugin(iRow).status         = pluginOri(indMatch).status;
        plugin(iRow).installed      = 1;
        if strcmpi(plugin(iRow).currentversion, plugin(iRow).version)
            plugin(iRow).installorupdate = 0;
        else
            plugin(iRow).installorupdate = 1;
        end
    end
end
plugin = rmfield(plugin, renameField(:,1)');

% handle the special case of EEGLAB version
indEEGLAB = cellfun(@(x)isequal(x, 'eeglab'), lower( { plugin.name } ));
eeglabVersionStatus = plugin(indEEGLAB);
plugin(indEEGLAB) = [];

% remove plugins with no zip file
% -------------------------------
plugin(cellfun(@isempty, {plugin.zip })) = [];

function plugin = plugin_convert(pluginOri)

for iRow = 1:length(pluginOri)
    plugin(iRow).currentversion = pluginOri(iRow).version;
    plugin(iRow).foldername     = pluginOri(iRow).foldername;
    plugin(iRow).status         = pluginOri(iRow).status;
    plugin(iRow).name           = pluginOri(iRow).plugin;
    plugin(iRow).installed      = 1;
end


function [data] = tapas_sem_multiv_prepare_data(data, model, inference)
%% Return a structure ready to be used.
%
% Input
%
% Output
%

% aponteeduardo@gmail.com
% copyright (C) 2016
%

data = data;

end


%EPS2PDF  Convert an eps file to pdf format using ghostscript
%
% Examples:
%   eps2pdf source dest
%   eps2pdf(source, dest, crop)
%   eps2pdf(source, dest, crop, append)
%   eps2pdf(source, dest, crop, append, gray)
%   eps2pdf(source, dest, crop, append, gray, quality)
%
% This function converts an eps file to pdf format. The output can be
% optionally cropped and also converted to grayscale. If the output pdf
% file already exists then the eps file can optionally be appended as a new
% page on the end of the eps file. The level of bitmap compression can also
% optionally be set.
%
% This function requires that you have ghostscript installed on your
% system. Ghostscript can be downloaded from: http://www.ghostscript.com
%
%IN:
%   source - filename of the source eps file to convert. The filename is
%            assumed to already have the extension ".eps".
%   dest - filename of the destination pdf file. The filename is assumed to
%          already have the extension ".pdf".
%   crop - boolean indicating whether to crop the borders off the pdf.
%          Default: true.
%   append - boolean indicating whether the eps should be appended to the
%            end of the pdf as a new page (if the pdf exists already).
%            Default: false.
%   gray - boolean indicating whether the output pdf should be grayscale or
%          not. Default: false.
%   quality - scalar indicating the level of image bitmap quality to
%             output. A larger value gives a higher quality. quality > 100
%             gives lossless output. Default: ghostscript prepress default.

% Copyright (C) Oliver Woodford 2009-2011

% Suggestion of appending pdf files provided by Matt C at:
% http://www.mathworks.com/matlabcentral/fileexchange/23629

% Thank you to Fabio Viola for pointing out compression artifacts, leading
% to the quality setting.
% Thank you to Scott for pointing out the subsampling of very small images,
% which was fixed for lossless compression settings.

% 9/12/2011 Pass font path to ghostscript.

function eps2pdf(source, dest, crop, append, gray, quality)
% Intialise the options string for ghostscript
options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"'];
% Set crop option
if nargin < 3 || crop
    options = [options ' -dEPSCrop'];
end
% Set the font path
fp = font_path();
if ~isempty(fp)
    options = [options ' -sFONTPATH="' fp '"'];
end
% Set the grayscale option
if nargin > 4 && gray
    options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray'];
end
% Set the bitmap quality
if nargin > 5 && ~isempty(quality)
    options = [options ' -dAutoFilterColorImages=false -dAutoFilterGrayImages=false'];
    if quality > 100
        options = [options ' -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -c ".setpdfwrite << /ColorImageDownsampleThreshold 10 /GrayImageDownsampleThreshold 10 >> setdistillerparams"'];
    else
        options = [options ' -dColorImageFilter=/DCTEncode -dGrayImageFilter=/DCTEncode'];
        v = 1 + (quality < 80);
        quality = 1 - quality / 100;
        s = sprintf('<< /QFactor %.2f /Blend 1 /HSample [%d 1 1 %d] /VSample [%d 1 1 %d] >>', quality, v, v, v, v);
        options = sprintf('%s -c ".setpdfwrite << /ColorImageDict %s /GrayImageDict %s >> setdistillerparams"', options, s, s);
    end
end
% Check if the output file exists
if nargin > 3 && append && exist(dest, 'file') == 2
    % File exists - append current figure to the end
    tmp_nam = tempname;
    % Copy the file
    copyfile(dest, tmp_nam);
    % Add the output file names
    options = [options ' -f "' tmp_nam '" "' source '"'];
    try
        % Convert to pdf using ghostscript
        [status, message] = ghostscript(options);
    catch me
        % Delete the intermediate file
        delete(tmp_nam);
        rethrow(me);
    end
    % Delete the intermediate file
    delete(tmp_nam);
else
    % File doesn't exist or should be over-written
    % Add the output file names
    options = [options ' -f "' source '"'];
    % Convert to pdf using ghostscript
    [status, message] = ghostscript(options);
end
% Check for error
if status
    % Report error
    if isempty(message)
        error('Unable to generate pdf. Check destination directory is writable.');
    else
        error(message);
    end
end
return

% Function to return (and create, where necessary) the font path
function fp = font_path()
fp = user_string('gs_font_path');
if ~isempty(fp)
    return
end
% Create the path
% Start with the default path
fp = getenv('GS_FONTPATH');
% Add on the typical directories for a given OS
if ispc
    if ~isempty(fp)
        fp = [fp ';'];
    end
    fp = [fp getenv('WINDIR') filesep 'Fonts'];
else
    if ~isempty(fp)
        fp = [fp ':'];
    end
    fp = [fp '/usr/share/fonts:/usr/local/share/fonts:/usr/share/fonts/X11:/usr/local/share/fonts/X11:/usr/share/fonts/truetype:/usr/local/share/fonts/truetype'];
end
user_string('gs_font_path', fp);
return


mex abs.c
mex max.c
mex min.c
mex minus.c
mex plus.c
mex rdivide.c
mex times.c


function ui = mrViewEditCbar(ui, o);
%
% ui = mrViewEditCbar(ui, o);
%
% Edit the colorbar for a given overlay in a mrViewer UI.
%
% ras, 08/2006.
if ~exist('ui','var') | isempty(ui),    ui = mrViewGet; end
if ishandle(ui), ui = get(ui, 'UserData'); end

if ~exist('o','var') | isempty(o)
    o = length(ui.overlays);
end

ui.overlays(o).cbar = cbarEdit(ui.overlays(o).cbar);

% if isfield(ui, 'fig') & ishandle(ui.fig)
%     set(ui.fig, 'UserData', ui);
% end

% update the cbar
mrViewRefresh(ui);

return


function varargout = gui_gridOmori(varargin)
    %    Application M-file for gui_gridOmori.fig
    %    FIG = SV_GRID launch sv_grid GUI.
    %    SV_GRIDMc('callback_name', ...) invoke the named callback.

    % Last Modified by GUIDE v2.0 22-Aug-2002 10:30:09

    if nargin == 1  % LAUNCH GUI

        fig = openfig(mfilename,'reuse');

        % Use system color scheme for figure:
        set(fig,'Color',get(groot,'defaultUicontrolBackgroundColor'));

        % Generate a structure of handles to pass to callbacks, and store it.
        handles = guihandles(fig);
        guidata(fig, handles);

        if varargin{1} == 1
            set(handles.lblSpacingDepth, 'String', 'Latitude spacing [deg]:');
            set(handles.txtSpacingDepth, 'String', '0.1');
            set(handles.lblSpacingHorizontal, 'String', 'Longitude spacing [deg]:');
            set(handles.txtSpacingHorizontal, 'String', '0.1');
        else
            set(handles.lblSpacingDepth, 'String', 'Depth spacing [km]:');
            set(handles.txtSpacingDepth, 'String', '1');
            set(handles.lblSpacingHorizontal, 'String', 'Horizontal spacing [km]:');
            set(handles.txtSpacingHorizontal, 'String', '1');
        end
        if get(handles.radNumber, 'Value') == 1
            set(handles.txtNumber, 'Enable', 'on');
            set(handles.radRadius, 'Value', 0);
            set(handles.txtRadius, 'Enable', 'off');
        else
            set(handles.txtNumber, 'Enable', 'off');
            set(handles.radRadius, 'Value', 1);
            set(handles.txtRadius, 'Enable', 'on');
        end

        % if get(handles.radSplitTime, 'Value') == 1
        %     set(handles.txtSplitTime, 'Enable', 'on');
        %     set(handles.txtTimePeriod, 'Enable', 'on');
        % else
        %     set(handles.radSplitTime, 'Value', 1);
        %     set(handles.txtSplitTime, 'Enable', 'on');
        %     set(handles.txtTimePeriod, 'Enable', 'on');
        % end
        % Wait for callbacks to run and window to be dismissed:
        uiwait(fig);

        if nargout > 0
            varargout{1} = fig;
        end

    elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

        try
            if (nargout)
                [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
            else
                feval(varargin{:}); % FEVAL switchyard
            end
        catch
            disp(lasterr);
        end

    end

    %| ABOUT CALLBACKS:
    %| GUIDE automatically appends subfunction prototypes to this file, and
    %| sets objects' callback properties to call them through the FEVAL
    %| switchyard above. This comment describes that mechanism.
    %|
    %| Each callback subfunction declaration has the following form:
    %| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
    %|
    %| The subfunction name is composed using the object's Tag and the
    %| callback type separated by '_', e.g. 'slider2_Callback',
    %| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
    %|
    %| H is the callback object's handle (obtained using GCBO).
    %|
    %| EVENTDATA is empty, but reserved for future use.
    %|
    %| HANDLES is a structure containing handles of components in GUI using
    %| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
    %| structure is created at GUI startup using GUIHANDLES and stored in
    %| the figure's application data using GUIDATA. A copy of the structure
    %| is passed to each callback.  You can store additional information in
    %| this structure at GUI startup, and you can change the structure
    %| during callbacks.  Call guidata(h, handles) after changing your
    %| copy to replace the stored original so that subsequent callbacks see
    %| the updates. Type "help guihandles" and "help guidata" for more
    %| information.
    %|
    %| VARARGIN contains any extra arguments you have passed to the
    %| callback. Specify the extra arguments by editing the callback
    %| property in the inspector. By default, GUIDE sets the property to:
    %| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
    %| Add any extra arguments after the last argument, before the final
    %| closing parenthesis.

    % --------------------------------------------------------------------
    % Radiobutton: Number of events
function varargout = radNumber_Callback(h, eventdata, handles, varargin)

    if get(handles.radNumber, 'Value') == 1
        set(handles.txtNumber, 'Enable', 'on');
        set(handles.txtMaxRadius, 'Enable', 'on');
        set(handles.radRadius, 'Value', 0);
        set(handles.txtRadius, 'Enable', 'off');
        set(handles.radRectangle, 'Value', 0);
        set(handles.txtSizeRectHorizontal, 'Enable', 'off');
        set(handles.txtSizeRectDepth, 'Enable', 'off');
    else
        set(handles.txtNumber, 'Enable', 'off');
        set(handles.txtMaxRadius, 'Enable', 'off');
        set(handles.radRadius, 'Value', 1);
        set(handles.txtRadius, 'Enable', 'on');
        set(handles.radRectangle, 'Value', 0);
        set(handles.txtSizeRectHorizontal, 'Enable', 'off');
        set(handles.txtSizeRectDepth, 'Enable', 'off');
    end

    % --------------------------------------------------------------------
    % Radiobutton: Constant radius
function varargout = radRadius_Callback(h, eventdata, handles, varargin)

    if get(handles.radRadius, 'Value') == 1
        set(handles.txtRadius, 'Enable', 'on');
        set(handles.radNumber, 'Value', 0);
        set(handles.txtMaxRadius, 'Enable', 'off');
        set(handles.txtNumber, 'Enable', 'off');
        set(handles.radRectangle, 'Value', 0);
        set(handles.txtSizeRectHorizontal, 'Enable', 'off');
        set(handles.txtSizeRectDepth, 'Enable', 'off');
    else
        set(handles.txtRadius, 'Enable', 'off');
        set(handles.txtMaxRadius, 'Enable', 'on');
        set(handles.radNumber, 'Value', 1);
        set(handles.txtNumber, 'Enable', 'on');
        set(handles.radRectangle, 'Value', 0);
        set(handles.txtSizeRectHorizontal, 'Enable', 'off');
        set(handles.txtSizeRectDepth, 'Enable', 'off');
    end

    % --------------------------------------------------------------------
    % Radiobutton: Rectangle size
function varargout = radRectangle_Callback(h, eventdata, handles, varargin)

    if get(handles.radRectangle, 'Value') == 1
        set(handles.txtSizeRectHorizontal, 'Enable', 'on');
        set(handles.txtSizeRectDepth, 'Enable', 'on');
        set(handles.radRadius, 'Value', 0);
        set(handles.txtRadius, 'Enable', 'off');
        set(handles.radNumber, 'Value', 0);
        set(handles.txtNumber, 'Enable', 'off');
        set(handles.txtMaxRadius, 'Enable', 'off');
    else
        set(handles.radRadius, 'Value', 0);
        set(handles.txtRadius, 'Enable', 'off');
        set(handles.radNumber, 'Value', 1);
        set(handles.txtNumber, 'Enable', 'on');
        set(handles.txtMaxRadius, 'Enable', 'on');
    end

    % --------------------------------------------------------------------
    % Radiobutton: Split Time
function varargout = radSplitTime_Callback(h, eventdata, handles, varargin)

    if get(handles.radSplitTime, 'Value') == 1
        set(handles.txtSplitTime, 'Enable', 'on');
        set(handles.txtTimePeriod, 'Enable', 'on');
    else
        set(handles.txtTimePeriod, 'Enable', 'on');
        set(handles.txtSplitTime, 'Enable', 'off');
    end

    % --------------------------------------------------------------------
function varargout = chkTimePeriod_Callback(h, eventdata, handles, varargin)

    if get(handles.chkTimeperiod, 'Value') == 1
        set(handles.txtTimeperiod, 'Enable', 'on');
    else
        set(handles.txtTimeperiod, 'Enable', 'off');
    end

    % --------------------------------------------------------------------
function varargout = chkSaveParameter_Callback(h, eventdata, handles, varargin)

    if get(handles.chkSaveParameter, 'Value') == 1
        set(handles.btnSaveParameter, 'Enable', 'on');
    else
        set(handles.btnSaveParameter, 'Enable', 'off');
    end

    % --------------------------------------------------------------------
function varargout = btnSaveParameter_Callback(h, eventdata, handles, varargin)

    [newfile, newpath] = uiputfile('*.mat','Choose parameter file');
    % Cancel pressed?
    if isequal(newfile, 0)  ||  isequal(newpath, 0)
        return;
    end
    % Everything ok?
    newfile = [newpath newfile];
    if length(newfile) > 1
        set(handles.lblSaveParameter, 'String', newfile);
    end

    % --------------------------------------------------------------------
function varargout = btnOK_Callback(h, eventdata, handles, varargin)

    handles.answer = 1;
    guidata(h, handles);
    uiresume(handles.figGrid);

    % --------------------------------------------------------------------
function varargout = btnCancel_Callback(h, eventdata, handles, varargin)

    handles.answer = 0;
    guidata(h, handles);
    uiresume(handles.figGrid);


function flat = vol2flatCurROILevels(volume,flat);
%
% flat = vol2flatCurROILevels(volume,flat)
%
% Calls vol2flatROI with the currently selected ROI.  Called from
% callback in xformFlatMenu.
%
% djh, 8/98
%
% djh, 2/2001, replaced globals with local variables
% ras, 10/2004, version for flat level view

if ~volume.selectedROI
  myErrorDlg('Must have a selected ROI in the Volume window before it can be transformed to the Inplane window.');
end

volROI = volume.ROIs(volume.selectedROI);
flatROI = vol2flatROILevels(volROI,volume,flat);
flat = addROI(flat,flatROI,1);


classdef MimRemapGrey < MimGuiPlugin
    % MimRemapGrey. Gui Plugin for setting paint colour
    %
    %     You should not use this class within your own code. It is intended to
    %     be used by the gui of the TD MIM Toolkit.
    %
    %     MimRemapGrey is a Gui Plugin for the MIM Toolkit.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, Copyright Tom Doel 2014.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    properties
        ButtonText = 'Multiple'
        SelectedText = 'Multiple'
        ToolTip = 'Marks airway as supplying multiple lobes'
        Category = 'Airway label'
        Visibility = 'Dataset'
        Mode = 'Edit'

        HidePluginInDisplay = false
        PTKVersion = '1'
        ButtonWidth = 5
        ButtonHeight = 1
        Icon = 'paint.png'
        IconColour = GemMarkerPoint.DefaultColours{7}
        Location = 37
    end

    methods (Static)
        function RunGuiPlugin(gui_app)
            gui_app.ImagePanel.PaintBrushColour = 7;
        end

        function enabled = IsEnabled(gui_app)
             enabled = gui_app.IsDatasetLoaded && gui_app.ImagePanel.OverlayImage.ImageExists && ...
                isequal(gui_app.ImagePanel.SelectedControl, 'Map');
        end

        function is_selected = IsSelected(gui_app)
            is_selected = gui_app.ImagePanel.PaintBrushColour == 7;
        end
    end
end


function result = runScriptFile(fileName)
% This function runs the test in fileName
% It can distinguish between skipped and Failed tests. A test is considered
% to be skipped if it throws a COBRA:RequirementsNotMet error.
%
% OUTPUTS:
%
%    result:    A structure array with the following fields:
%
%                - `.passed`: true if the test passed otherwise false
%                - `.skipped`: true if the test was skipped otherwise false
%                - `.failed`: true if the test failed, or was skipped, otherwise false
%                - `.status`: a string representing the status of the test ('failed','skipped' or'passed')
%                - `.fileName`: the fileName of the test
%                - `.time`: the duration of the test (if passed otherwise NaN)
%                - `.statusMessage`: Informative string about potential problems.
%                - `.Error`: Error message received from a failed or skipped test
%
% .. Author:   - Thomas Pfau Jan 2018.

global CBT_MISSING_REQUIREMENTS_ERROR_ID

COBRA_TESTSUITE_TESTFILE = fileName;

% get the timinig (and hope these values are not overwritten.
COBRA_TESTSUITE_STARTTIME = clock();

try
    % run the file
    executefile(fileName);
catch ME
    % vatch errors and interpret them
    clearvars -except ME COBRA_TESTSUITE_STARTTIME COBRA_TESTSUITE_TESTFILE CBT_MISSING_REQUIREMENTS_ERROR_ID
    scriptTime = etime(clock(), COBRA_TESTSUITE_STARTTIME);
    result = struct('status', 'failed', 'failed', true, 'passed', false, 'skipped', false, 'fileName', ...
                    COBRA_TESTSUITE_TESTFILE, 'time', scriptTime, 'statusMessage', 'fail', 'Error', ME);
    if strcmp(ME.identifier, CBT_MISSING_REQUIREMENTS_ERROR_ID)
        % requirement missing, so the test was skipped.
        result.status = 'skipped';
        result.skipped = true;
        result.failed = false;
        result.statusMessage = ME.message;
    else
        % actual error in the test.
        result.skipped = false;
        result.status = 'failed';
        result.statusMessage = ME.message;
    end
    return
end

% get the timinig.
scriptTime = etime(clock(), COBRA_TESTSUITE_STARTTIME);

result = struct('status', 'passed', 'failed', false, 'passed', true, 'skipped', false, 'fileName', ...
                COBRA_TESTSUITE_TESTFILE, 'time', scriptTime, 'statusMessage', 'success', 'Error', MException('', ''));

end

function executefile(fileName)
% runs a script file (used to separate workspaces)
    run(fileName)
end


function s1=copyStructFieldByField(s1,s2)

if ~strcmp(class(s1),class(s2))
    if ~isobject(s1) && ~isstruct(s2)
        if ~isstruct(s1) && ~isobject(s2)
            return;
        end
    end
end

if isstruct(s1) || isobject(s1)

    if ~isstruct(s2) && ~isobject(s2)
        return;
    end

    for jj=1:length(s2)
        fields = fieldnames(s2(jj));
        for ii=1:length(fields)
            field_class = eval(sprintf('class(s2(jj).%s)',fields{ii}));
            if ~isproperty(s1,fields{ii}) || length(s1)<jj
                if isobject(s1)
                    continue;
                end
                if strcmp(field_class,'cell')
                    field_arg='{}';
                else
                    field_arg='[]';
                end
                eval(sprintf('s1(jj).%s = %s(%s);',fields{ii},field_class,field_arg));
            end
            eval(sprintf('s1(jj).%s = copyStructFieldByField(s1(jj).%s, s2(jj).%s);', fields{ii}, fields{ii}, fields{ii}));
        end
    end

else

    s1 = s2;

end


function [status] = putexif(dat,fname, refname)
%[status] = putexif(dat,fname, refname) save and image with Exif data from
%                  a reference image file
% dat     = array of image data
% fname   = name of image file to be saved, e.g., 'myfile.jpg'
% refname = name (path) of reference image file
%
%Needs ExifTool.exe, written by Phil Harvey
% http://www.sno.phy.queensu.ca/~phil/exiftool/
% 1. Download the file, exiftool(-k).exe
% 2. Rename this file, exiftool.exe
% 3. Save this file in a folder on your Matlab path, e.g. .../matlab
%Peter Burns, 28 May 2013
%             22 July 2013, following suggestions from jhh and Jonathan via
%                           Matlab Central.

test = which('exiftool.exe');
if isempty(test)
    disp('ExifTool not available:');
    disp('Please download from,')
    disp('   http://www.sno.phy.queensu.ca/~phil/exiftool/')
    disp('or make sure that the installed exiftool.exe is on your Matlab path')
    beep
    status =1;
    return
else

    [exifdata, nf] = getexif(refname);
   % Save data as image file with Matlab metadata
    imwrite(dat, fname, 'quality', 100);
    [exifdata2, nf2] = getexif(fname);
   % Replace matadata from this file with desired tags from reference file
   % temp1=['exiftool -m -tagsfromfile ',refname,' -all:all ', fname];
    temp1=['"' test '" -m -tagsfromfile "',refname,'" -all:all "', fname, '"'];

    %[status, junk] = system(temp1);
    %Second output variable appears to suppress '1 image files updated'
    % being returned to Command window (~ also works).
    [status, junk] = system(temp1);

   % Approximate check
    [exifdata3, nf3] = getexif(fname);

   % Delete extra copy of reference image file
    temp3 = ['del "',fname,'_original"'];
    status = system(temp3);

   % Test approx. number of tags
    if abs(nf3-nf2<10)
        disp('Warning: Exif tags may not have been copied');
        status = 1;
    end

end


classdef KnowledgeBaseUtil_Test < TestCase
    properties
        database
    end

    methods
        function this = KnowledgeBaseUtil_Test(name)
            this = this@TestCase(name);
        end

        function setUp(this)
            this.database = edu.stanford.covert.db.MySQLDatabase(getConfig());
        end

        function tearDown(this)
            this.database.close();
        end
    end

    methods
        function testSelectLatestKnowledgeBase(this)
            import edu.stanford.covert.cell.kb.KnowledgeBaseUtil;
            kbWID = KnowledgeBaseUtil.selectLatestKnowledgeBase(this.database);
            validateattributes(kbWID, {'numeric'}, {'positive', 'real', 'integer', 'finite'});
        end

        function testSelectLatestSimulation(this)
            import edu.stanford.covert.cell.kb.KnowledgeBaseUtil;

            kbWID = KnowledgeBaseUtil.selectLatestKnowledgeBase(this.database);
            simWID = KnowledgeBaseUtil.selectLatestSimulation(kbWID, this.database);

            if isempty(simWID)
                simWID2 = this.saveSimulation(kbWID, this.database);
                simWID = KnowledgeBaseUtil.selectLatestSimulation(kbWID, this.database);
                this.deleteSimulation(simWID2, this.database);
                assertEqual(simWID2, simWID);
            end

            validateattributes(simWID, {'numeric'}, {'positive', 'real', 'integer', 'finite', 'scalar'});
        end

        function testGetSimulationCodeArchive(this)
            import edu.stanford.covert.cell.kb.KnowledgeBaseUtil;

            kbWID = KnowledgeBaseUtil.selectLatestKnowledgeBase(this.database);
            simWID = KnowledgeBaseUtil.selectLatestSimulation(kbWID, this.database);

            %if no simulation already saved, save small simulation to database
            newSim = 0;
            if isempty(simWID)
                newSim = 1;
                simWID = this.saveSimulation(kbWID, this.database);
            end

            %get code archive
            fileName = 'output/runSmallTests/differencesFromRevision.txt';
            if exist(fileName, 'file')
                delete(fileName);
            end
            KnowledgeBaseUtil.getSimulationCodeArchive(simWID, fileName, this.database);
            assertEqual(2, exist(fileName, 'file'));

            %delete the added small simulation
            if newSim
                this.deleteSimulation(simWID, this.database);
            end
        end

        function testGetContact(this)
            import edu.stanford.covert.cell.kb.KnowledgeBaseUtil;

            contact = struct('email', 'jkarr@stanford.edu');

            kbWID = KnowledgeBaseUtil.selectLatestKnowledgeBase(this.database);
            wid = KnowledgeBaseUtil.getContact(contact, kbWID, this.database);
            validateattributes(wid, {'numeric'}, {'positive', 'real', 'integer', 'finite'});
        end

        function testNewContact(this)
            import edu.stanford.covert.cell.kb.KnowledgeBaseUtil;

            contact = struct(...
                'firstName', 'Jonathan', ...
                'lastName', 'Karr', ...
                'affiliation', 'Covert Lab, Department of Bioengineering, Stanford University', ...
                'email', 'jkarr@stanford.edu');

            kbWID = KnowledgeBaseUtil.selectLatestKnowledgeBase(this.database);
            wid = KnowledgeBaseUtil.newContact(contact, kbWID, this.database);
            validateattributes(wid, {'numeric'}, {'positive', 'real', 'integer', 'finite'});
        end
    end

    %helper methods
    methods (Static)
        function simWID = saveSimulation(kbWID, database)
            import edu.stanford.covert.cell.sim.SimulationFixture;
            import edu.stanford.covert.cell.sim.util.ConditionSet;
            import edu.stanford.covert.cell.sim.util.DatabaseLogger;

            sim = SimulationFixture.load([], true);
            sim.applyOptions('lengthSec', 10);

            metadata = ConditionSet.parseConditionSet(sim, 'src_test/+edu/+stanford/+covert/+cell/+sim/+util/fixtures/runSimulations.xml').metadata;
            metadata.knowledgeBaseWID = kbWID;
            metadata.revision = edu.stanford.covert.util.revision;

            downsampleStepSec = 2;
            logger = DatabaseLogger(database, downsampleStepSec, metadata);
            logger.addMetadata(metadata);
            sim.run(logger);

            simWID = logger.simulationWID;
        end

        function deleteSimulation(simWID, database)
            database.prepareStatement('CALL delete_simulation("{Si}")', simWID);
            database.query();
        end
    end
end


function varargout = ihashfind(varargin)
% VL_IHASHFIND
%  SEL = VL_IHASHFIND(ID, NEXT, K, X)
[varargout{1:nargout}] = vl_ihashfind(varargin{:});


function ni = niftiRead(fileName, volumesToLoad)
% Matlab wrapper to call the mex readFileNifti
%
% *******************************************************
% NOTE:  As of 2017 Matlab has a "niftiread" function in its
%        distribution.
%
% NOTE: JAN 2020 GLU & JW: this version uses an external tool called nii_util.m
%       taken from the toolset https://github.com/xiangruili/dicm2nii
%       It will be used only if it detects that the file to read is a Nifti-2,
%       otherwise it will use the old code
% *******************************************************
%
%   niftiImage = niftiRead(fileName,volumesToLoad)
%
% Reads a NIFTI image and populates a structure that should be the
% NIFTI 1 standard.  We expect that the filename has an extension of
% either .nii or .nii.gz
%
% If volumesToLoad is not included in the arguments, all the data
% are returned. If volumesToLoad is empty ([]) returns only the header
%
% Web Resources
%  web('http://nifti.nimh.nih.gov/nifti-1/','-browser')
%
% See also:  niftiCreate, niftiGetStruct
%
% Example:
%  niFile = fullfile(mrvDataRootPath,'mrQ','T1_lsqnabs_SEIR_cfm.nii.gz');
%  ni = niftiRead(niFile);
%
% Copyright, Vista Team Stanford, 2011

% This normally calls the mex file for your system
if ~exist('fileName','var') || isempty(fileName)
    % Return the default structure.  Equivalent to niftiCreate
    % ni = niftiRead;
    ni = readFileNifti;
elseif ischar(fileName) && exist(fileName,'file')
    % fileName is a string and the file exists.
    % For some reason, the volumeToLoad is not yet implemented.
    % We should just implement it here, by reading the whole
    % thing and only returning the relevant volumes.  I think
    % that is represented by the 4th dimension, but I should ask
    % someone who knows.
    if exist('volumesToLoad','var')
        % ni = niftiRead('foo.nii.gz',1:20);
        % We let readFileNifti complain about not implemented for
        % now.
        %
        % GLU EDIT: throw same error as the mex file
        % ni = readFileNifti(fileName,volumesToLoad);
        error('(volume selection) Not yet implemented!')
    else
        % Example:
        %     ni = niftiRead('foo.nii.gz');
        % Select the reader depending on nifti version
        % We need to read only the header first, to save time.
        % Matlab's niftiinfo will be a nice option in the future, it was
        % introduced in 2017a.
        hdr = nii_tool('hdr',fileName);
        if isfield(hdr,'version')
            if hdr.version==2
                % New call to the nii_tool wrapper
                ni = nii_tool_read_wrapper(fileName);
            else
                % Old call to the mex file, for backward compatibility
                ni = readFileNifti(fileName);
            end
        else
            % Old call to the mex file, for backward compatibility
            ni = readFileNifti(fileName);
        end

    end
else
    % Make sure the the file includes the .nii.gz extensions
    % Really, someone should
    [p,n,e] = fileparts(fileName);
    if isempty(e), fileNameExtended = [p,filesep,n,'.nii.gz'];
    else
        % The can be file.nii or file.nii.gz
        if strcmp(e,'.gz') || strcmp(e,'.nii')
            fileNameExtended = fileName;
        else
            warning('Unexpected file name extension %s\n',e);
        end
    end
    if exist(fileNameExtended,'file')
        % HERE WE MODIFY THE OLD VERSION
        hdr = nii_tool('hdr',fileName);
        if isfield(hdr,'version')
            if hdr.version==2
                % New call to the nii_tool wrapper
                ni = nii_tool_read_wrapper(fileName);
            else
                % Old call to the mex file, for backward compatibility
                ni = readFileNifti(fileName);
            end
        else
            % Old call to the mex file, for backward compatibility
            ni = readFileNifti(fileName);
        end
    else
        error('Cannot find the file %s\n',fileNameExtended);
    end
end

end


function [results]=updateCD(text,parsed,note)
% Correct(Update) the species name according to a reference list of the names.
%
% USAGE:
%
%    [results] = updateCD(text, parsed, note)
%
% INPUTS:
%    text:            A matlab variable that saves the lines of the XML file.
%    parsed:          A parsed CD model structure generated by `parseCD` function.
%
% OPTIONAL INPUT:
%    note:            The default value is '0'; It can be set as 'true';
%                     Record the column number of the species that are to be
%                     replaced with a new name.
%
% OUTPUTS:
%    text:            The corrected lines of the XML file.
%    number:          The number of the line.
%    changdStrLines:  The changed line of text.
%    col:             Record the column number of the species that is to be
%                     replaced with a new species name.
%
% EXAMPLE:
%
%    [text, number, numberofchanges, col] = updateCD(annotedText, ref_corrected)

if nargin<3;
    ConductCol=0;
    col={};

elseif strcmp(note,'true')
    ConductCol=1;
    col={};
end

col_name=2; % the column 2 contains metabolite names.

ref=parsed.r_info;

pool={'<species (\w*)','<celldesigner:name>'}; % the format in CellDesiginer XML file
keywords={' name', ':nam'};
mark={'"','<'};

for i=1:length(pool);
     a=0;
    if i==2
        warning('starting the second round of the program');
    end

    str=pool{i}

    key=keywords{i}

    mark_key=mark{i}
    % str='<celldesigner:species(\w*) id=' ;

    for ln=1:length(text);

        line_species=regexpi(text(ln).str,str); % find the line that contains the string ('str').
        % dd=str2num({line_species})
        if ~isempty(line_species{1})
            % reText=cellstr(text(line).str)

            % if strcmpi(reText,ref.species{line,1})
            a=a+1;
            number(a,1)=ln;  % ln stores line number.
            % disp(line_species);%(number(a,1));
        end
    end
    if i==1;
        totalCount=length(number(:,1))
    else
        totalCount=totalCount;
    end

    changedStrLines={};
    nC=0;

    for d=1:totalCount  % d increase discretely from 1 to the end.

        nRxn=number(d,1); % d is the count, whereas nRxn contains the row number.
        if isfield(ref,'species');

            reText=cellstr(text(nRxn).str)
            %for nn=1:length(ref.species(:,1))
            sizeRef=size(ref.species);
            disp(sizeRef)
            disp(d);
            disp(col_name);
            disp(length(number(:,1)))

            if ~isempty(ref.species(d,col_name))
                %if strcmpi(text(line).str,ref.species{d,1});
                strd=strfind(reText,key) % ' name')
                if (~isempty(strd{1}))  % in some cases, the line does not contain ' name'.
                    %if (~isempty(str))

                    if iscell(reText) % convert cell type into string type
                        reText=reText{1};
                    else
                        error('the format of the reText is not right');
                    end
                    [p_st,p_ed]=position(reText,key,mark_key) % ' name')
                    fprintf(' the text: %s',reText);
                    ToBeRplaced=reText(p_st:p_ed);
                    % disp(ToBeRplaced);
                    %ToBeRplaced=ref.species{nn,3};
                    try
                        text(nRxn).str=strrep(text(nRxn).str,ToBeRplaced,ref.species{d,col_name})
                    catch
                        %                     disp(text(nRxn).str);
                        %                     disp(ToBeRplaced);
                        %                     dusp(ref.species{d,3});
                    end
                    nC=nC+1;
                    changedStrLines(nC,1)=text(nRxn).str;
                    fprintf('original text is %s and is replaced with %s',ToBeRplaced,ref.species{d,col_name});
                    if  ConductCol==1;
                    col{nC,1}=ToBeRplaced;
                    col{nC,2}=ref.species{d,col_name}
                    end
                end
                %end
            end
            %end
        else
            warning('cannot find the field name ''species''');
        end
    end
end

results.text=text;
results.number=number;
results.changedStrLines=changedStrLines;
results.col=col;

end

function [p_st,p_ed]=position(str_long,str_ID,mark)
%% name='metaid';

ind_pos=strfind(str_long,str_ID);
l=length(str_ID)+2;
try
    p_st=ind_pos(1)+l
catch
    error('cannot find the Keyword in the the line')
end
end_rem=strfind(str_long(p_st:end),mark) % '"');
p_ed=end_rem(1)+p_st-2;
% disp(ind_pos);
% disp(l);
% disp(p_ed)

end


clear
addpath(genpath('code'));
addpath(genpath('manopt'));


%% The MTEX Documentation
%
% Documenting a project like MTEX is a challenging and ongoing task for the
% entire community. Therefore we are extremely happy about any spelling
% fixes, examples, theoretical explainations, special use cases, etc. As a
% bonus everybody who contributed to MTEX will automatically appear at the
% <https://github.com/mtex-toolbox/mtex/graphs/contributors contributors
% page>.
%
%% Making Changes Online
%
% The easiest way to suggest changes to the MTEX documentation is online
% visa Github. This is done as follows:
%
% # sign into <https://github.com GitHub>
% # open the help page you want to change, e.g., this one
% # click
% <https://github.com/mtex-toolbox/mtex/blob/develop/doc/GeneralConcepts/Contribute2Doc.m
% edit page> - this leads you to the file on <https://github.com GitHub>
% # click the little pencil in the top right corner which allows you to
% edit the script online
% # enter of copy and paste your changes into the site
% # click at the bottom *suggest changes*
% # click create *pull request*
%
%% Making Changes Within Matlab
%
% Since all documentation pages are essentially MTEX scripts they can be
% opened in Matlab by the command
%
%   edit hepPageName
%
% This allows you to run through all the commands and investiage the effect
% of different parameters or different input files or add further analysis
% steps.
%
% If you like the changes you made simply copy and paste the changes into
% the GitHub page as explained above or send it to one of the developers by
% email.
%
%% Publish command
%
% You may can a visual preview of your altered documentation page by using
% the matlab function
% <https://de.mathworks.com/help/matlab/matlab_prog/publishing-matlab-code.html
% publish>
%
%   publish filename
%
% which creates an folder, named 'html', in your current directory where
% you can find the generated html page.
%


function SaveVARtoMat(hfig)
save_dir = getappdata(hfig,'save_dir');

% copy of VAR files will be saved into this subfolder:
arcmatfolder = fullfile(save_dir, 'arc mat');
if ~exist(arcmatfolder, 'dir')
    mkdir(arcmatfolder);
end

global VAR; %#ok<NUSED>
timestamp  = datestr(now,'mmddyy_HHMM');
matname = [timestamp '.mat'];
save(fullfile(arcmatfolder,matname),'VAR','-v6');

% also save the current VAR file
save(fullfile(save_dir,'VAR_new.mat'),'VAR','-v6');
disp('saved both to workspace and .mat');

end


function D=imdir(dirname,filter)

% IMDIR lists image content in the directory specified by dirname.
%   Returns a structure similar to the one returned by MATLAB's dir
%   function. Additional filter on the image file name can be specified.
%
% See also DIR
% (c) Michael Rubinstein, MIT
%

if nargin<2
    filter='';
end

if ~exist(dirname,'dir')
    error([dirname ' not found.']);
end

D=dir(fullfile(dirname,sprintf('*%s*',filter)));
D=D(cellfun(@isImageFile,{D(:).name}));

function tf=isImageFile(filename)

% supported formats
formats = {'jpg','jpeg','png','bmp','pgm','gif','ppm','tif','tiff'};

[path,name,ext]=fileparts(filename);
ext = ext(2:end); % remove '.'

tf = any(strcmpi(ext,formats));


function func = ft_getuserfun(func, prefix)

% FT_GETUSERFUN will search the MATLAB path for a function with the
% appropriate name, and return a function handle to the function.
% Considered are, in this order:
%  - the name itself, i.e. you get exactly the same func back as you put in;
%  - the name with the specified prefix;
%  - the name with 'ft_' and the specified prefix.
%
% For example, calling FT_GETUSERFUN('general', 'trialfun') might return a
% function named 'general', 'trialfun_general', or 'ft_trialfun_general',
% whichever of those is found first and is not a compatibility wrapper.
%
% func can be a function handle, in which case it is returned as-is.
%
% If no appropriate function is found, the empty array [] will be returned.

% Copyright (C) 2012, Eelke Spaak
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip 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.
%
%    FieldTrip 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 FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

if isa(func, 'function_handle')
  % treat function handle as-is
elseif isfunction(func) && ~iscompatwrapper(func)
  func = str2func(func);
elseif isfunction([prefix '_' func]) && ~iscompatwrapper([prefix '_' func])
  func = str2func([prefix '_' func]);
elseif isfunction(['ft_' prefix '_' func])
  func = str2func(['ft_' prefix '_' func]);
else
  ft_warning(['no function by the name ''' func ''', ''' prefix '_' func...
    ''', or ''ft_' prefix '_' func ''' could be found']);
  func = [];
end


classdef MIndenter < handle
    % Performs code indenting. Should not be used directly but only by
    % MBeautify.

    properties (Constant)
        Delimiters = {' ', '\f', '\n', '\r', '\t', '\v', ...
            ','};
        KeywordsIncrease = {'function', 'classdef', 'properties', ...
            'methods', 'if', 'for', 'parfor', 'switch', 'try', 'while', ...
            'arguments', 'enumeration'};
        KeywordsSandwich = {'else', 'elseif', 'case', 'otherwise', ...
            'catch'};
        KeywordsDecrease = {'end', 'end;'};
    end

    properties (Access = private)
        Configuration;
    end

    methods
        function obj = MIndenter(configuration)
            % Creates a new formatter using the passed configuration.
            obj.Configuration = configuration;
        end

        function indentedSource = performIndenting(obj, source)
            % indentation strategy:
            % allfunctions (default) = AllFunctionIndent
            % nestedfunctions = MixedFunctionIndent (MATLAB default)
            % noindent = ClassicFunctionIndent
            strategy = obj.Configuration.specialRule('Indentation_Strategy').Value;

            % determine indent string
            indentationCharacter = obj.Configuration.specialRule('IndentationCharacter').Value;
            indentationCount = obj.Configuration.specialRule('IndentationCount').ValueAsDouble;
            if strcmpi(indentationCharacter, 'white-space')
                indent = ' ';
                for i = 2:indentationCount
                    indent = [' ', indent];
                end
            elseif strcmpi(indentationCharacter, 'tab')
                indent = '\t';
            else
                warning('MBeautifier:IllegalSetting:IndentationCharacter', 'MBeautifier: The indentation character must be set to "white-space" or "tab". MBeautifier using MATLAB defaults.');
                indent = '    ';
            end

            % TODO
            makeBlankLinesEmpty = obj.Configuration.specialRule('Indentation_TrimBlankLines').ValueAsDouble;

            % currently in continuation mode (line before ended with ...)?
            continuationMode = 0;
            % layer of indentatino (next line)
            layerNext = 0;
            % this stack keeps track of the keywords
            stack = {};

            % start indenting
            newLine = MBeautifier.Constants.NewLine;
            lines = regexp(source, newLine, 'split');
            for linect = 1:numel(lines)
                % layer of indentation (current line)
                layer = layerNext;

                % remove existing indentation and whitespace
                lines{linect} = strtrim(lines{linect});

                % split line in words
                pattern = ['[', obj.joinString(obj.Delimiters, '|'), ']'];
                words = regexp(lines{linect}, pattern, 'split');
                % ignore empty lines and comments
                if (~isempty(lines{linect}) && (lines{linect}(1) ~= '%'))
                    % find keywords and adjust indent
                    for wordct = 1:numel(words)
                        % detect end of line comments
                        if (strcmp(words{wordct}, '%'))
                            break;
                        end

                        % look for keywords that increase indent
                        if (sum(strcmp(words{wordct}, obj.KeywordsIncrease)))
                            layerNext = layerNext + 1;
                            % push keyword onto stack
                            stack = [stack, words{wordct}];

                            % correction for function keywords according to
                            % configuration
                            if (strcmp(stack{end}, 'function'))
                                switch lower(strategy)
                                    case 'nestedfunctions'
                                        if (numel(stack) == 1)
                                            % top level function
                                            layerNext = layerNext - 1;
                                        else
                                            if (strcmp(stack{end-1}, 'function'))
                                                % nested function
                                                layer = layer + 1;
                                                layerNext = layerNext + 1;
                                            else
                                                % class method
                                                % do nothing
                                            end
                                        end
                                    case 'noindent'
                                        layerNext = layerNext - 1;
                                    otherwise
                                end
                            end

                            % correction for switch
                            if (strcmp(stack{end}, 'switch'))
                                layerNext = layerNext + 1;
                            end
                        end

                        % look for sandwich keywords
                        if (sum(strcmp(words{wordct}, obj.KeywordsSandwich)))
                            if (wordct == 1)
                                % at the beginning, decrease only current indent
                                layer = layer - 1;
                            end
                        end

                        % look for end that decreases the indent
                        if (sum(strcmp(words{wordct}, obj.KeywordsDecrease)))
                            if (wordct == 1)
                                % end at the beginning decreases indent of this line
                                layer = layer - 1;
                            end
                            % inline end may alter the indent of the next line
                            layerNext = layerNext - 1;

                            if isempty(stack)
                               continue
                            end

                            % correction for function keywords according to
                            % configuration
                            if (strcmp(stack{end}, 'function'))
                                switch lower(strategy)
                                    case 'nestedfunctions'
                                        if (numel(stack) == 1)
                                            % top level function
                                            layerNext = layerNext + 1;
                                        else
                                            if (strcmp(stack{end-1}, 'function'))
                                                % nested function
                                                layer = layer - 1;
                                            else
                                                % class method
                                                % do nothing
                                            end
                                        end
                                    case 'noindent'
                                        if (wordct == 1)
                                            % end at the beginning decreases indent of this line
                                            layer = layer + 1;
                                        end
                                        layerNext = layerNext + 1;
                                    otherwise
                                        % do nothing
                                end
                            end

                            % correction for switch
                            if (strcmp(stack{end}, 'switch'))
                                if (wordct == 1)
                                    % end at the beginning decreases indent of this line
                                    layer = layer - 1;
                                end
                                layerNext = layerNext - 1;
                            end

                            % pop keyword
                            stack(end) = [];
                        end
                    end

                    % look for continuation lines
                    if (strcmp(words{end}, '...'))
                        if (~continuationMode)
                            continuationMode = 1;
                            layerNext = layerNext + 1;
                        end
                    else
                        if (continuationMode)
                            continuationMode = 0;
                            layerNext = layerNext - 1;
                        end
                    end
                end

                % add correct indentation
                for ict = 1:layer
                    if ~makeBlankLinesEmpty || ~isempty(lines{linect})
                        lines{linect} = [indent, lines{linect}];
                    end
                end
            end

            indentedSource = obj.joinString(lines, MBeautifier.Constants.NewLine);
        end
    end

    methods (Access = private, Static)
        % TODO: Create a public utility function
       function outStr = joinString(cellStr, delim)
            outStr = '';
            for i = 1:numel(cellStr)
                outStr = [outStr, cellStr{i}, delim];
            end

            outStr(end-numel(delim)+1:end) = '';
        end
    end
end


function r = fieldnamesContain(names, id)
  r = any(strcmp(names,id));
end


function test_suite = test_mocov_is_absolute_path()
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
            test_functions=localfunctions();
        catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_mocov_is_absolute_path_basics()
    if ispc()
        assertTrue(mocov_is_absolute_path('C:\\'));
        assertTrue(mocov_is_absolute_path('C:'));
        assertTrue(mocov_is_absolute_path('C:\\aa\\bb'));
        assertTrue(mocov_is_absolute_path('D:/bb/cc'));
        assertFalse(mocov_is_absolute_path('C\\'));
        assertFalse(mocov_is_absolute_path('/bb/cc'));
        assertFalse(mocov_is_absolute_path('./bb/cc'));
        assertFalse(mocov_is_absolute_path('../bb/cc'));
    else
        assertFalse(mocov_is_absolute_path('C:\\'));
        assertFalse(mocov_is_absolute_path('C:'));
        assertTrue(mocov_is_absolute_path('/bb/cc'));
        assertTrue(mocov_is_absolute_path('/'));
        assertFalse(mocov_is_absolute_path('./bb/cc'));
        assertFalse(mocov_is_absolute_path('../bb/cc'));
    end


function cx = getcx(X)

cx = X.cx;


function [sSubject, iSubject] = db_add_subject( varargin )
% DB_ADD_SUBJECT: Add a subject to data base.
%
% USAGE:                        db_add_subject(sSubject, iSubject)
%        [sSubject, iSubject] = db_add_subject(sSubject)
%        [sSubject, iSubject] = db_add_subject(SubjectName)
%        [sSubject, iSubject] = db_add_subject(SubjectName, iSubject)
%        [sSubject, iSubject] = db_add_subject(SubjectName, iSubject, UseDefaultAnat, UseDefaultChannel)
%
% INPUT:
%     - SubjectName : Name of the subject
%     - sSubject    : subject structure
%     - iSubject    : Indice of the subject in the ProtocolSubjects.Subject array
%                     Set to [] to create a new subject
%     - UseDefaultAnat, UseDefaultChannel : values for new subject
% OUTPUT:
%     - sSubject : Subject structure (set to [] if an error occurs)
%     - iSubject : Subject indice in current protocol

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2008-2011

% Get protocol description
ProtocolInfo     = bst_get('ProtocolInfo');
ProtocolSubjects = bst_get('ProtocolSubjects');
nbSubjects = length(ProtocolSubjects.Subject);

%% ===== PARSE INPUTS =====
% CALL: db_add_subject( sSubject )
if isstruct(varargin{1})
    sSubject = varargin{1};
% CALL: db_add_subject( SubjectName )
elseif ischar(varargin{1})
    % Get subject name
    SubjectName = file_standardize(varargin{1});
    % Create a new empty subject
    sSubject = db_template('Subject');
    sSubject.Name              = SubjectName;
    sSubject.FileName          = bst_fullfile(SubjectName, 'brainstormsubject.mat');
    sSubject.UseDefaultAnat    = ProtocolInfo.UseDefaultAnat;
    sSubject.UseDefaultChannel = ProtocolInfo.UseDefaultChannel;
else
    error('Invalid call to db_add_subject()');
end
% CALL: db_add_subject( ..., iSubject )
if (nargin < 2) || isempty(varargin{2})
    % New indice
    iSubject = nbSubjects + 1;
else
    iSubject = varargin{2};
end
% CALL: db_add_subject( ..., UseDefaultAnat, UseDefaultChannel )
if (nargin >= 3)
    sSubject.UseDefaultAnat = varargin{3};
end
if (nargin >= 4)
    sSubject.UseDefaultChannel = varargin{4};
end

% Is new subject ?
isNewSubject = (iSubject > nbSubjects);

%% ===== CHECK SUBJECT UNICITY =====
% Only if creating a new subject
if isNewSubject
    % Check the subject unicity
    if ~isempty(bst_get('Subject', sSubject.Name, 1))
        % A subject with the same Name is found : display an error box and return to 'Subject editor' window
        bst_error(sprintf('Subject "%s" already exists in protocol.', sSubject.Name), 'Subject editor', 0);
        sSubject = [];
        return
    end
end

%% ===== SAVE SUBJECT FILE =====
SubjectMat = db_template('subjectmat');
SubjectMat.Comments          = sSubject.Comments;
SubjectMat.UseDefaultAnat    = sSubject.UseDefaultAnat;
SubjectMat.UseDefaultChannel = sSubject.UseDefaultChannel;
try
    fullFileName = bst_fullfile(ProtocolInfo.SUBJECTS, sSubject.FileName);
    % Create target directory
    if ~file_exist(bst_fileparts(fullFileName))
        mkdir(bst_fileparts(fullFileName));
    end
    % Save file
    bst_save(fullFileName, SubjectMat, 'v7');
catch
    bst_error(sprintf('Error : cannot save subject file "%s".', sSubject.Name), 'Subject editor');
    sSubject = [];
    return
end

%% ===== UPDATE DATABASE =====
% === Update Subjects ===
% Register subject in ProtocolSubjects
ProtocolSubjects.Subject(iSubject) = sSubject;
% Update database in Matlab preferences
bst_set('ProtocolSubjects', ProtocolSubjects);

% === Create extra system conditions ===
% Only if it is a new subject
if isNewSubject
    % Add conditions: analysis_intra and default_study
    db_add_condition(sSubject.Name, bst_get('DirAnalysisIntra'), 0);
    db_add_condition(sSubject.Name, bst_get('DirDefaultStudy'),  0);
end
% Save database
db_save();