function this = load(this, fileName)
% Loads Geometry info from affine image header (.nii/.hdr/.img) or Philips
% (par/rec) or recon6-ImageData (.mat, Geometry-object)
%
% NOTE: .mat-header files (for 4D niftis) are ignored, since the same voxel
%       position is assumed in each volume for MrImage
%
%   geom = MrAffineTransformation()
%   geom = geom.load(fileName)
%
% This is a method of class MrAffineTransformation.
%
% IN
%
%
% EXAMPLE
%   geom = MrAffineTransformation()
%   geom.load('test.nii')
%   geom.load('test.hdr/img')
%   geom.load('test.par/rec')
%
%   See also MrAffineTransformation MrAffineTransformation.update

% Author:   Saskia Klein & Lars Kasper
% Created:  2014-07-15
% Copyright (C) 2014 Institute for Biomedical Engineering
%                    University of Zurich and ETH Zurich
%
% This file is part of the TAPAS UniQC Toolbox, which is released
% under the terms of the GNU General Public Licence (GPL), version 3.
% You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version).
% For further details, see the file COPYING or
%  <http://www.gnu.org/licenses/>.

if exist(fileName, 'file')
    [~, ~, ext] = fileparts(fileName);

    switch ext
        case {'.hdr', '.nii', '.img'}
            V = spm_vol(fileName);
            affineMatrix = V.mat;

            if ~isempty(affineMatrix)
                this.update_from_affine_matrix(affineMatrix);
            end

        case {'.par', '.rec'}
            this = this.load_par(fileName);
        case {'.mat'} % recon 6
            this = this.load_recon6_mat(fileName);
        otherwise
            warning('Only Philips (.par/.rec), nifti (.nii) and analyze (.hdr/.img) files are supported');
    end
else
    fprintf('Geometry data could not be loaded: file %s not found.\n', ...
        fileName);
end

end


%SETDATA Set data field in mapping or dataset
%
% 	W = SETDATA(W,DATA,FIELD)
% 	W = SETDATA(W,DATA,N)
%
%   A = SETDATA(A,DATA,FEATLAB)
%
% INPUT
%   W        Mapping
%   DATA     Data to be put in the data field.
%   FIELD    String, name of data field structure to be used for DATA
%            (optional)
%   N        Index of cell array to be used for DATA (optional)
%
%   A        Dataset
%   FEATLAB  Desired feature labels for dataset (optional)
%
% OUTPUT
%   W        Mapping
%   A        Dataset
%
% DESCRIPTION
% This routine can be used to store data in the data fields of either a
% mapping W or a dataset A.
%
% The data field of a mapping consists of a matrix, cell array or a structure.
% In case nor FIELD neither N are given the entire dats field is replaced by
% DATA. In case the data field is a structure DATA is assigned to field FIELD.
% In case the datafield is a cell array, DATA is assigned to cell N.
% DATA cannot be a structure in case of untrained or fixed mappings.
%
% The data field of a dataset A is an array of doubles. It is replaced by
% DATA which may be doubles or another dataset, which will be converted to
% doubles. The numbers of objects in A and DATA should be equal. The feature
% labels of A are replaced by FEATLAB, or, if not supplied and DATA is a
% dataset by the feature labels of DATA. Labels and class probabilities of
% A are preserved.
%
% SEE ALSO (PRTools Guide)
% MAPPINGS, DATASETS


%STATSCHECK  Check whether the STATS toolbox is in the path

function n = statscheck

  n = ~isempty(ver('stats'));
  if (nargout == 0) & (n == 0)
		error([newline 'The Matlab STATS toolbox is missing.'])
  end

return


% http://www.mathworks.com/matlabcentral/fileexchange/33381

function data = loadjson(fname,varargin)
%
% data=loadjson(fname,opt)
%    or
% data=loadjson(fname,'param1',value1,'param2',value2,...)
%
% parse a JSON (JavaScript Object Notation) file or string
%
% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
%            date: 2011/09/09
%         Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713
%            date: 2009/11/02
%         Fran�ois Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393
%            date: 2009/03/22
%         Joel Feenstra:
%         http://www.mathworks.com/matlabcentral/fileexchange/20565
%            date: 2008/07/03
%
% $Id: loadjson.m 371 2012-06-20 12:43:06Z fangq $
%
% input:
%      fname: input file name, if fname contains "{}" or "[]", fname
%             will be interpreted as a JSON string
%      opt: a struct to store parsing options, opt can be replaced by
%           a list of ('param',value) pairs. The param string is equivallent
%           to a field in opt.
%
% output:
%      dat: a cell array, where {...} blocks are converted into cell arrays,
%           and [...] are converted to arrays
%
% license:
%     BSD, see LICENSE_BSD.txt files for details
%
% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%

global pos inStr len  esc index_esc len_esc isoct arraytoken

if(regexp(fname,'[\{\}\]\[]','once'))
   string=fname;
elseif(exist(fname,'file'))
   fid = fopen(fname,'rt');
   string = fscanf(fid,'%c');
   fclose(fid);
else
   error('input file does not exist');
end

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

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

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

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

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

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

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

function object = parse_object(varargin)
    parse_char('{');
    object = [];
    if next_char ~= '}'
        while 1
            str = parseStr(varargin{:});
            if isempty(str)
                error_pos('Name of value at position %d cannot be empty');
            end
            parse_char(':');
            val = parse_value(varargin{:});
            eval( sprintf( 'object.%s  = val;', valid_field(str) ) );
            if next_char == '}'
                break;
            end
            parse_char(',');
        end
    end
    parse_char('}');
end

function object = parse_array(varargin) % JSON array is written in row-major order
global pos inStr isoct
    parse_char('[');
    object = cell(0, 1);
    dim2=[];
    if next_char ~= ']'
        [endpos e1l e1r maxlevel]=matching_bracket(inStr,pos);
        arraystr=['[' inStr(pos:endpos)];
        arraystr=regexprep(arraystr,'"_NaN_"','NaN');
        arraystr=regexprep(arraystr,'"([-+]*)_Inf_"','$1Inf');
        arraystr(find(arraystr==sprintf('\n')))=[];
        arraystr(find(arraystr==sprintf('\r')))=[];
        %arraystr=regexprep(arraystr,'\s*,',','); % this is slow,sometimes needed
        if(~isempty(e1l) && ~isempty(e1r)) % the array is in 2D or higher D
            astr=inStr((e1l+1):(e1r-1));
            astr=regexprep(astr,'"_NaN_"','NaN');
            astr=regexprep(astr,'"([-+]*)_Inf_"','$1Inf');
            astr(find(astr==sprintf('\n')))=[];
            astr(find(astr==sprintf('\r')))=[];
            astr(find(astr==' '))='';
            if(isempty(find(astr=='[', 1))) % array is 2D
                dim2=length(sscanf(astr,'%f,',[1 inf]));
            end
        else % array is 1D
            astr=arraystr(2:end-1);
            astr(find(astr==' '))='';
            [obj count errmsg nextidx]=sscanf(astr,'%f,',[1,inf]);
            if(nextidx>=length(astr)-1)
                object=obj;
                pos=endpos;
                parse_char(']');
                return;
            end
        end
        if(~isempty(dim2))
            astr=arraystr;
            astr(find(astr=='['))='';
            astr(find(astr==']'))='';
            astr(find(astr==' '))='';
            [obj count errmsg nextidx]=sscanf(astr,'%f,',inf);
            if(nextidx>=length(astr)-1)
                object=reshape(obj,dim2,numel(obj)/dim2)';
                pos=endpos;
                parse_char(']');
                return;
            end
        end
        arraystr=regexprep(arraystr,'\]\s*,','];');
        try
           if(isoct && regexp(arraystr,'"','once'))
                error('Octave eval can produce empty cells for JSON-like input');
           end
           object=eval(arraystr);
           pos=endpos;
        catch
         while 1
            val = parse_value(varargin{:});
            object{end+1} = val;
            if next_char == ']'
                break;
            end
            parse_char(',');
         end
        end
    end
    try
        object=cell2mat(object')';
        if(size(object,1)>1 && ndims(object)==2)
            object=object';
        end
    catch
    end
    parse_char(']');
end

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

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

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

function str = parseStr(varargin)
    global pos inStr len  esc index_esc len_esc
 % len, ns = length(inStr), keyboard
    if inStr(pos) ~= '"'
        error_pos('String starting with " expected at position %d');
    else
        pos = pos + 1;
    end
    str = '';
    while pos <= len
        while index_esc <= len_esc && esc(index_esc) < pos
            index_esc = index_esc + 1;
        end
        if index_esc > len_esc
            str = [str inStr(pos:len)];
            pos = len + 1;
            break;
        else
            str = [str inStr(pos:esc(index_esc)-1)];
            pos = esc(index_esc);
        end
        nstr = length(str); switch inStr(pos)
            case '"'
                pos = pos + 1;
                if(~isempty(str))
                    if(strcmp(str,'_Inf_'))
                        str=Inf;
                    elseif(strcmp(str,'-_Inf_'))
                        str=-Inf;
                    elseif(strcmp(str,'_NaN_'))
                        str=NaN;
                    end
                end
                return;
            case '\'
                if pos+1 > len
                    error_pos('End of file reached right after escape character');
                end
                pos = pos + 1;
                switch inStr(pos)
                    case {'"' '\' '/'}
                        str(nstr+1) = inStr(pos);
                        pos = pos + 1;
                    case {'b' 'f' 'n' 'r' 't'}
                        str(nstr+1) = sprintf(['\' inStr(pos)]);
                        pos = pos + 1;
                    case 'u'
                        if pos+4 > len
                            error_pos('End of file reached in escaped unicode character');
                        end
                        str(nstr+(1:6)) = inStr(pos-1:pos+4);
                        pos = pos + 5;
                end
            otherwise % should never happen
                str(nstr+1) = inStr(pos), keyboard
                pos = pos + 1;
        end
    end
    error_pos('End of file while expecting end of inStr');
end

function num = parse_number(varargin)
    global pos inStr len isoct
    currstr=inStr(pos:end);
    numstr=0;
    if(isoct~=0)
        numstr=regexp(currstr,'^\s*-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+\-]?\d+)?','end');
        [num, one] = sscanf(currstr, '%f', 1);
        delta=numstr+1;
    else
        [num, one, err, delta] = sscanf(currstr, '%f', 1);
        if ~isempty(err)
            error_pos('Error reading number at position %d');
        end
    end
    pos = pos + delta-1;
end

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

    switch(inStr(pos))
        case '"'
            val = parseStr(varargin{:});
            return;
        case '['
            val = parse_array(varargin{:});
            return;
        case '{'
            val = parse_object(varargin{:});
            return;
        case {'-','0','1','2','3','4','5','6','7','8','9'}
            val = parse_number(varargin{:});
            return;
        case 't'
            if pos+3 <= len && strcmpi(inStr(pos:pos+3), 'true')
                val = true;
                pos = pos + 4;
                return;
            end
        case 'f'
            if pos+4 <= len && strcmpi(inStr(pos:pos+4), 'false')
                val = false;
                pos = pos + 5;
                return;
            end
        case 'n'
            if pos+3 <= len && strcmpi(inStr(pos:pos+3), 'null')
                val = [];
                pos = pos + 4;
                return;
            end
    end
    error_pos('Value expected at position %d');
end

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

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

function endpos = matching_quote(str,pos)
len=length(str);
while(pos<len)
    if(str(pos)=='"')
        if(~(pos>1 && str(pos-1)=='\'))
            endpos=pos;
            return;
        end
    end
    pos=pos+1;
end
error('unmatched quotation mark');
end

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

function opt=varargin2struct(varargin)
%
% opt=varargin2struct('param1',value1,'param2',value2,...)
%   or
% opt=varargin2struct(...,optstruct,...)
%
% convert a series of input parameters into a structure
%
% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
% date: 2012/12/22
%
% input:
%      'param', value: the input parameters should be pairs of a string and a value
%       optstruct: if a parameter is a struct, the fields will be merged to the output struct
%
% output:
%      opt: a struct where opt.param1=value1, opt.param2=value2 ...
%
% license:
%     BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
%
% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%

len=length(varargin);
opt=struct;
if(len==0) return; end
i=1;
while(i<=len)
    if(isstruct(varargin{i}))
        opt=mergestruct(opt,varargin{i});
    elseif(ischar(varargin{i}) && i<len)
        opt=setfield(opt,varargin{i},varargin{i+1});
        i=i+1;
    else
        error('input must be in the form of ...,''name'',value,... pairs or structs');
    end
    i=i+1;
end

end


function [trial_indx, subject_indx, datavar_matrix, datavar_cell] = select_trials_and_subjects(DAT, conditioning_text_var_name, text_pattern, varargin)
% Filter an event-level variable:
% - Return a logical vector of which events and subjects have values on a
% string variable (conditioning_text_var_name) that match a string pattern
% (text_pattern)
%
% - If the name of a second variable is entered as an optional argument,
% extract data from that variable, selecting only events that match the
% filter. [var name to extract data] in the command string below is the
% optional argument.
%
% conditioning_text_var_name is the name of an Event_Level variable in your dataset
% text_pattern is a string pattern to match with regexp
%
% [trial_indx, subject_indx, datavar_matrix, datavar_cell] = select_trials_and_subjects(DAT, conditioning_text_var, text_pattern, [var name to extract data])
%
% datavar_matrix is matrix of subjects x trials with extracted data
% datavar_cell is cell array of length subjects containing column vectors with extracted data

[datavar_matrix, datavar_cell] = deal([]);

[~, block] = get_var(DAT, conditioning_text_var_name);

% This function turns a string into a vector of which trials match that string.
subj_indx = @(subjcell) ~cellfun(@isempty, regexp(subjcell, text_pattern, 'match'));

% This function tests for all empty or nans in a cell.
nanfun = @(block) all(cellfun(@(x) all(isempty(x) | isnan(x)), block{1}));
%nanfun(block(1))

% This function tests whether any trials match the string
anyfun = @(x) any(subj_indx(x{1}));

% This function operates on one cell, for use with cellfun wrapper
onesubjfun = @(x) subj_indx(x{1});

% subj_indx(block{5})
% onesubjfun(block(5))

% doesn't work for unknown reasons - actually, can't handle nans.
% indic = cellfun(onesubjfun, block, 'UniformOutput', false)
% indic = cellfun(@(x) any(x), block)

clear trial_indx subject_indx
for i = 1:length(block)

    if nanfun(block(i))
        trial_indx{i} = false(size(block{i}));
        subject_indx(i, 1) = false;
    else
        trial_indx{i} = subj_indx(block{i});
        subject_indx(i, 1) = anyfun(block(i));

    end

end

% retrieve target data variable, removing NaNs and concatenating
if length(varargin) > 0

    var_name_to_extract = varargin{1};

    [~, datavar_cell, ~, ~, ~, textflag] = get_var(DAT, var_name_to_extract);

    for i = 1:length(trial_indx)

        datavar_cell{i} = datavar_cell{i}(trial_indx{i});

    end

    % pad to longest and concatenate into matrix

    %[~, textflag] = get_varlevel(DAT, var_name_to_extract);

    d = pad_cells_with_nan(datavar_cell, textflag);

    datavar_matrix = cat(2, d{:})';

end

end % function

function d = pad_cells_with_nan(d, textflag)

slen = max(cellfun(@length, d)); % max length for any subject

refvec = ones(slen, 1);

for i = 1:length(d)

    if textflag % text var
        reftext = cell(1, abs(length(d{i}) - length(refvec)))';
        [reftext{:}] = deal('');

        d{i} = [d{i}; reftext];

    else % numeric
        d{i} = padwithnan(d{i}, refvec, 1);
    end

end

end


% Author: Francesco Ledda
%
% The Image Smoothing Filter implements a set of utilities for the digital treatment of images. The main purpose is the image cleaning from noise
% but there are also other utilities like noise addition, conversion in gray-scale, border emphasis, bidimensional FFT calculation and so on.
%
% This file is just for a brief description of the project and it aims to be the driver of the actual GUI.
%
% For more information about the code, you can send me an e-mail at leddafrancesco89@gmail.com
%
% If you use this code, please don't forget to mention the author. :)
%

% Start the GUI

Progetto


function [im,header] = ufmf_read_mean(header,varargin)

[meani,framei,dopermute] = myparse(varargin,'meani',[],'framei',[],'dopermute',true);
fp = header.fid;

meani = [meani,header.frame2mean(framei)];

if isempty(meani),
  [im,header] = ufmf_read_mean_helper(fp,header);
else
  if length(meani) > 1,
    im = zeros([header.ncolors,header.nr,header.nc,length(meani)],header.meandataclass);
  end
  if isfield(header,'cachedmeans_idx'),
    [idx,cachei] = ismember(meani,header.cachedmeans_idx);
  else
    idx = false(size(meani));
  end
  for i = find(idx),
    im(:,:,:,i) = header.cachedmeans(:,:,:,cachei(i));
    header.cachedmeans_accesstime(i) = now;
  end
  for i = find(~idx),
    fseek(fp,header.mean2file(meani(i)),'bof');
    [im(:,:,:,i),header] = ufmf_read_mean_helper(fp,header);
  end
end
if dopermute,
  im = permute(im,[2,3,1,4]);
end

function [im,header,timestamp] = ufmf_read_mean_helper(fp,header)

% Keyframe file format:
%
% 0 (chunk type)                       uchar
% 4 (length of keyframe type)          uchar
% 'mean' (keyframe type)               char x 4
% timestamp                            double
% number of boxes/points               ushort
% dtype ('f' for float, 'B' for uint8) char
% width                                ushort
% height                               ushort
% timestamp                            double
% background mean                      dtype x width x height x ncolors
% (iterate over colors,
%  followed by columns in sideways im,
%  followed by rows)

KEYFRAME_CHUNK = 0;
MEAN_KEYFRAME_TYPE = 'mean';

loc = ftell(fp);
meani = find(header.mean2file == loc,1);
if isempty(meani),
  error('Could not find current file location in mean2file index');
end

% chunktype: 1
chunktype = fread(fp,1,'uchar');
if chunktype ~= KEYFRAME_CHUNK,
  error('Expected chunktype = %d at start of keyframe.');
end

% keyframe type
l = fread(fp,1,'uchar');
keyframe_type = fread(fp,[1,l],'*char');
if ~strcmp(keyframe_type,MEAN_KEYFRAME_TYPE),
  error('Expected keyframe type = ''%s'' at start of mean keyframe',MEAN_KEYFRAME_TYPE);
end

% data type
dtypechar = fread(fp,1,'*char');
matlabclass = dtypechar2matlabclass(dtypechar);

% images are sideways: swap width and height
% width, height
sz = double(fread(fp,2,'ushort'));
height = sz(1); width = sz(2);

% timestamp
timestamp = fread(fp,1,'double');

% actual frame data
im = fread(fp,width*height*header.bytes_per_pixel,['*',matlabclass]);
% TODO: handle colorspaces other than RGB8 and MONO8
if ~ismember(lower(header.coding),{'mono8','rgb8'}),
  error('Colorspace %s not yet supported. Only MONO8 and RGB8 allowed.',header.coding);
end
im = reshape(im,[header.ncolors,height,width]);

% store in cache
if isfield(header,'cachedmeans'),
  [~,idxreplace] = min(header.cachedmeans_accesstime);
  header.cachedmeans(:,:,:,idxreplace) = im;
  header.cachedmeans_idx(idxreplace) = meani;
  header.cachedmeans_accesstime(idxreplace) = now;
end


% std_checkfiles() - Check all STUDY files consistency
%
% Usage:
%                >> boolval = std_checkfiles(STUDY, ALLEEG);
% Inputs:
%   STUDY      - EEGLAB STUDY set comprising some or all of the EEG datasets in ALLEEG.
%   ALLEEG     - All EEGLAB datasets
%
% Outputs:
%   boolval    - [0|1] 1 if uniform
%
% Authors: Arnaud Delorme, CERCO, 2010-

% Copyright (C) Arnaud Delorme, CERCO
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

function [boolval npersubj] = std_checkfiles(STUDY, ALLEEG);

if nargin < 2
    help std_checkfiles;
    return;
end;
return;

filetypes = { 'daterp' 'datspec' 'datersp' 'datitc' 'dattimef' ...
              'icaerp' 'icaspec' 'icaersp' 'icaitc' 'icatopo' };

% set channel interpolation mode
% ------------------------------
uniformchannels = std_uniformsetinds( STUDY );

disp('---------------------------------------------');
disp('Checking data files integrity and consistency');
passall = 1;
for index = 1:length(filetypes)

    % scan datasets
    % -------------
    [ tmpstruct compinds filepresent ] = std_fileinfo(ALLEEG, filetypes{index});
    if ~isempty(tmpstruct)
        fprintf('Files of type "%s" detected, checking...',  filetypes{index});
    end;

    % check if the structures are equal
    % ---------------------------------
    notequal = any(~filepresent);
    if ~isempty(tmpstruct)
        if any(filepresent == 0)
            fprintf(' Error, some files inconsistent or missing\n');
            notequal = 1;
            passall = 0;
        else
            firstpass = 1;
            fields = fieldnames(tmpstruct);
            for f_ind = 1:length(fields)

                firstval = getfield(tmpstruct, {1}, fields{f_ind});
                for dat = 2:length(tmpstruct)
                    tmpval = getfield(tmpstruct, {dat}, fields{f_ind});
                    if ~isequal(firstval, tmpval)

                        % check for NaNs
                        if iscell(firstval) && iscell(tmpval)
                            for cind = 1:length(firstval)
                                if isreal(firstval{cind}) && ~isempty(firstval{cind}) && isnan(firstval{cind}(1))
                                    firstval{cind} = 'NaN';
                                end;
                            end;
                            for cind = 1:length(tmpval)
                                if isreal(tmpval{cind}) && ~isempty(tmpval{cind}) && isnan(tmpval{cind}(1))
                                    tmpval{cind} = 'NaN';
                                end;
                            end;
                        end;

                        if ~isequal(firstval, tmpval)
                            if ~strcmpi(fields{f_ind}, 'labels') || strcmpi(uniformchannels, 'on')
                                if firstpass == 1, fprintf('\n'); firstpass = 0; end;
                                fprintf('  Error, difference accross data files for field "%s"\n', fields{f_ind});
                                notequal = 1;
                                passall = 0;
                                break;
                            end;
                        end;
                    end;
                end;
            end;
        end;
    end;

    % check the consistency of changrp and cluster with saved information
    % -------------------------------------------------------------------
    if isempty(tmpstruct), notequal = 1; end;
    if filetypes{index}(1) == 'd' && notequal == 0
        % scan all channel labels
        % -----------------------
        if isfield(tmpstruct(1), 'labels')
            for cind = 1:length(STUDY.changrp)
                if notequal == 0
                    for inddat = 1:length(ALLEEG)
                        tmpind = cellfun(@(x)(find(x == inddat)), STUDY.changrp(cind).setinds(:), 'uniformoutput', false);
                        indnonempty = find(~cellfun(@isempty, tmpind(:)));
                        if ~isempty(indnonempty)
                            tmpchan = STUDY.changrp(cind).allinds{indnonempty}(tmpind{indnonempty}); % channel index for dataset inddat

                            tmpchan2 = strmatch(STUDY.changrp(cind).name, tmpstruct(inddat).labels, 'exact'); % channel index in file
                            if ~isempty(tmpchan2) || ~strcmpi(filetypes{index}, 'datspec') % the last statement is because channel labels did not use to be saved in spec files
                                if ~isequal(tmpchan2, tmpchan)
                                    fprintf('\nError: channel index in STUDY.changrp(%d) for dataset %d is "%d" but "%d" in data files\n', cind, inddat, tmpchan, tmpchan2);
                                    notequal = 1;
                                    break;
                                end;
                            end;
                        end;
                    end;
                end;
            end;
        end;
    elseif notequal == 0 && ~isempty(STUDY.cluster) % components
        % check that the cell structures are present
        % ------------------------------------------
        if ~isfield(STUDY.cluster, 'setinds')
            STUDY.cluster(1).setinds = [];
            STUDY.cluster(1).allinds = [];
        end;
        for cind = 1:length(STUDY.cluster)
            if isempty(STUDY.cluster(cind).setinds)
                STUDY.cluster(cind) = std_setcomps2cell(STUDY, cind);
            end;
        end;
        for cind = 1:length(STUDY.cluster)
            if notequal == 0
                for inddat = 1:length(ALLEEG)
                    tmpind = cellfun(@(x)(find(x == inddat)), STUDY.cluster(cind).setinds(:), 'uniformoutput', false);
                    indnonempty = find(~cellfun(@isempty, tmpind(:)));
                    tmpcomp = [];
                    for jind = 1:length(indnonempty)
                        tmpcomp = [ tmpcomp STUDY.cluster(cind).allinds{indnonempty(jind)}(tmpind{indnonempty(jind)}) ];
                    end;

                    if ~isempty(setdiff(tmpcomp, compinds{inddat}))
                        if ~(isempty(compinds{inddat}) && strcmpi(filetypes{index}, 'icatopo'))
                            fprintf('\nError: some components in clusters %d are absent from .%s files\n', cind, filetypes{index});
                            notequal = 1;
                            passall  = 0;
                            break;
                        end;
                    end;
                end;
            end;
        end;
    end;
    if notequal == 0, fprintf(' Pass\n'); end;
end;

if ~passall
    disp('**** Recompute any measure above not receiving a "Pass" by')
    disp('**** calling menu items "STUDY > Precompute Channel/Component measures" ');
    disp('**** and by selecting the "Recompute even if present on disk" checkbox');
end;
disp('Checking completed.');


function filum_test14 ( )

%*****************************************************************************80
%
%% TEST14 tests FILENAME_INC.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 September 2005
%
%  Author:
%
%    John Burkardt
%
  ntest = 4;

  string(1,1:11) = 'file???.dat';
  string(2,1:11) = 'file072.dat';
  string(3,1:11) = '2cat9.dat  ';
  string(4,1:11) = 'fred98.txt ';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST14\n' );
  fprintf ( 1, '  FILENAME_INC increments a string\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '     Input             Output\n' );

  for i = 1 : ntest
    fprintf ( 1, '\n' );
    filename = string(i,:);
    for j = 1 : 4
      filename_old = filename;
      filename = filename_inc ( filename );
      fprintf ( 1, '  %20s  %20s\n', filename_old, filename );
      if ( s_len_trim ( filename ) == 0 )
        fprintf ( 1, '  (Empty output string.  Quit loop!)\n' );
        break
      end
    end
  end

  return
end


% ismember_bc2 - ismember backward compatible with Matlab versions prior to 2013a

function [C,IA] = ismember_bc2(A,B,varargin)
% errorFlag = false;
v = version;
indp = find(v == '.');
v = str2num(v(1:indp(2)-1));
if v > 7.19
        v = floor(v) + rem(v,1)/10;
end
if nargin > 2
        ind = find(ismember(varargin, 'legacy'));
        if ~isempty(ind)
                varargin(ind) = [];
        end
end
if v >= 7.14
        %disp('legacy')
        [C,IA] = ismember(A,B,varargin{:},'legacy');
        %if true
        %        [C2,IA2] = ismember(A,B,varargin{:});
        %        if (~isequal(C, C2) || ~isequal(IA, IA2))
        %                warning('Warn:BckwrdcompTest','ismember_bc2: Backward compatibility issue with call to ismember function');
        %        end
        %end
else
        %disp('old')
        [C,IA] = ismember(A,B,varargin{:});
end


function outkey = filter(inkey,modlist,seglist,keep)
% Removes some of the information in a key.  Useful for creating a
% gender specific key from a pooled gender key.  Depending on the
% value of 'keep', the two input lists indicate the strings to
% retain or the strings to discard.
% Inputs:
%   inkey: A Key object.
%   modlist: A cell array of strings which will be compared with
%     the modelset of 'inkey'.
%   seglist: A cell array of strings which will be compared with
%     the segset of 'inkey'.
%   keep: A boolean indicating whether modlist and seglist are the
%     models to keep or discard.
% Outputs:
%   outkey: A filtered version of 'inkey'.

if nargin == 0
    test_this();
    return
else
    assert(nargin==4)
end

assert(isa(inkey,'Key'))
assert(iscell(modlist))
assert(iscell(seglist))
assert(inkey.validate())

if keep
    keepmods = modlist;
    keepsegs = seglist;
else
    keepmods = setdiff(inkey.modelset,modlist);
    keepsegs = setdiff(inkey.segset,seglist);
end

keepmodidx = ismember(inkey.modelset,keepmods);
keepsegidx = ismember(inkey.segset,keepsegs);

outkey = Key();
outkey.modelset = inkey.modelset(keepmodidx);
outkey.segset = inkey.segset(keepsegidx);
outkey.tar = inkey.tar(keepmodidx,keepsegidx);
outkey.non = inkey.non(keepmodidx,keepsegidx);

assert(outkey.validate())

if length(inkey.modelset) > length(outkey.modelset)
    log_info('Number of models reduced from %d to %d.\n',length(inkey.modelset),length(outkey.modelset));
end
if length(inkey.segset) > length(outkey.segset)
    log_info('Number of test segments reduced from %d to %d.\n',length(inkey.segset),length(outkey.segset));
end

end

function test_this()

key = Key();
key.modelset = {'aaa','bbb','ccc','ddd'};
key.segset = {'11','22','33','44','55'};
key.tar = logical([1,0,0,1,0;0,1,0,1,1;0,0,0,1,0;1,1,0,0,0]);
key.non = logical([0,1,0,0,0;1,0,0,0,0;1,1,1,0,0;0,0,1,1,1]);

fprintf('key.modelset\n');
disp(key.modelset)
fprintf('key.segset\n');
disp(key.segset)
fprintf('key.tar\n');
disp(key.tar)
fprintf('key.non\n');
disp(key.non)

modlist = {'bbb','ddd'}
seglist = {'11','55'}

keep = true

out = Key.filter(key,modlist,seglist,keep);

fprintf('out.modelset\n');
disp(out.modelset)
fprintf('out.segset\n');
disp(out.segset)
fprintf('out.tar\n');
disp(out.tar)
fprintf('out.non\n');
disp(out.non)

keep = false

out = Key.filter(key,modlist,seglist,keep);

fprintf('out.modelset\n');
disp(out.modelset)
fprintf('out.segset\n');
disp(out.segset)
fprintf('out.tar\n');
disp(out.tar)
fprintf('out.non\n');
disp(out.non)

modlist = {'bbb','ddd','eee'}
seglist = {'11','66','77','55'}

keep = true

out = Key.filter(key,modlist,seglist,keep);

fprintf('out.modelset\n');
disp(out.modelset)
fprintf('out.segset\n');
disp(out.segset)
fprintf('out.tar\n');
disp(out.tar)
fprintf('out.non\n');
disp(out.non)

keep = false

out = Key.filter(key,modlist,seglist,keep);

fprintf('out.modelset\n');
disp(out.modelset)
fprintf('out.segset\n');
disp(out.segset)
fprintf('out.tar\n');
disp(out.tar)
fprintf('out.non\n');
disp(out.non)

end


% openbdf() - Opens an BDF File (European Data Format for Biosignals) in MATLAB (R)
%
% Usage:
%   >> EDF=openedf(FILENAME)
%
% Note: About EDF -> www.biosemi.com/faq/file_format.htm
%
% Author: Alois Schloegl, 5.Nov.1998
%
% See also: readedf()

%   Copyright (C) 1997-1998 by Alois Schloegl
%   a.schloegl@ieee.org
%   Ver 2.20    18.Aug.1998
%   Ver 2.21    10.Oct.1998
%   Ver 2.30     5.Nov.1998
%
%   For use under Octave define the following function
% function s=upper(s); s=toupper(s); end

% V2.12    Warning for missing Header information
% V2.20    EDF.AS.* changed
% V2.30    EDF.T0 made Y2K compatible until Year 2090

% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License
% as published by the Free Software Foundation; either version 2
% of the  License, or (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

% Name changed for bdf files Sept 6,2002  T.S. Lorig
% Header updated for EEGLAB format (update web link too) - Arnaud Delorme 14 Oct 2002

function [DAT,H1]=openbdf(FILENAME)

SLASH='/';      % defines Seperator for Subdirectories
BSLASH=char(92);

cname=computer;
if cname(1:2)=='PC' SLASH=BSLASH; end

fid=fopen_or_error(FILENAME,'r','ieee-le');

EDF.FILE.FID=fid;
EDF.FILE.OPEN = 1;
EDF.FileName = FILENAME;

PPos=min([max(find(FILENAME=='.')) length(FILENAME)+1]);
SPos=max([0 find((FILENAME=='/') | (FILENAME==BSLASH))]);
EDF.FILE.Ext = FILENAME(PPos+1:length(FILENAME));
EDF.FILE.Name = FILENAME(SPos+1:PPos-1);
if SPos==0
    EDF.FILE.Path = pwd;
else
    EDF.FILE.Path = FILENAME(1:SPos-1);
end
EDF.FileName = [EDF.FILE.Path SLASH EDF.FILE.Name '.' EDF.FILE.Ext];

H1=char(fread(EDF.FILE.FID,256,'char')');     %
EDF.VERSION=H1(1:8);                     % 8 Byte  Versionsnummer
%if 0 fprintf(2,'LOADEDF: WARNING  Version EDF Format %i',ver); end
EDF.PID = deblank(H1(9:88));                  % 80 Byte local patient identification
EDF.RID = deblank(H1(89:168));                % 80 Byte local recording identification
%EDF.H.StartDate = H1(169:176);         % 8 Byte
%EDF.H.StartTime = H1(177:184);         % 8 Byte
EDF.T0=[str2num(H1(168+[7 8])) str2num(H1(168+[4 5])) str2num(H1(168+[1 2])) str2num(H1(168+[9 10])) str2num(H1(168+[12 13])) str2num(H1(168+[15 16])) ];

% Y2K compatibility until year 2090
if EDF.VERSION(1)=='0'
        if EDF.T0(1) < 91
                EDF.T0(1)=2000+EDF.T0(1);
        else
                EDF.T0(1)=1900+EDF.T0(1);
        end
else
        % in a future version, this is hopefully not needed
end

EDF.HeadLen = str2num(H1(185:192));  % 8 Byte  Length of Header
% reserved = H1(193:236);            % 44 Byte
EDF.NRec = str2num(H1(237:244));     % 8 Byte  # of data records
EDF.Dur = str2num(H1(245:252));      % 8 Byte  # duration of data record in sec
EDF.NS = str2num(H1(253:256));       % 8 Byte  # of signals

EDF.Label = char(fread(EDF.FILE.FID,[16,EDF.NS],'char')');
EDF.Transducer = char(fread(EDF.FILE.FID,[80,EDF.NS],'char')');
EDF.PhysDim = char(fread(EDF.FILE.FID,[8,EDF.NS],'char')');

EDF.PhysMin= str2num(char(fread(EDF.FILE.FID,[8,EDF.NS],'char')'));
EDF.PhysMax= str2num(char(fread(EDF.FILE.FID,[8,EDF.NS],'char')'));
EDF.DigMin = str2num(char(fread(EDF.FILE.FID,[8,EDF.NS],'char')')); %
EDF.DigMax = str2num(char(fread(EDF.FILE.FID,[8,EDF.NS],'char')')); %

% check validity of DigMin and DigMax
if (length(EDF.DigMin) ~= EDF.NS)
        fprintf(2,'Warning OPENEDF: Failing Digital Minimum\n');
        EDF.DigMin = -(2^15)*ones(EDF.NS,1);
end
if (length(EDF.DigMax) ~= EDF.NS)
        fprintf(2,'Warning OPENEDF: Failing Digital Maximum\n');
        EDF.DigMax = (2^15-1)*ones(EDF.NS,1);
end
if (any(EDF.DigMin >= EDF.DigMax))
        fprintf(2,'Warning OPENEDF: Digital Minimum larger than Maximum\n');
end
% check validity of PhysMin and PhysMax
if (length(EDF.PhysMin) ~= EDF.NS)
        fprintf(2,'Warning OPENEDF: Failing Physical Minimum\n');
        EDF.PhysMin = EDF.DigMin;
end
if (length(EDF.PhysMax) ~= EDF.NS)
        fprintf(2,'Warning OPENEDF: Failing Physical Maximum\n');
        EDF.PhysMax = EDF.DigMax;
end
if (any(EDF.PhysMin >= EDF.PhysMax))
        fprintf(2,'Warning OPENEDF: Physical Minimum larger than Maximum\n');
        EDF.PhysMin = EDF.DigMin;
        EDF.PhysMax = EDF.DigMax;
end
EDF.PreFilt= char(fread(EDF.FILE.FID,[80,EDF.NS],'char')'); %
tmp = fread(EDF.FILE.FID,[8,EDF.NS],'char')';   %   samples per data record
EDF.SPR = str2num(char(tmp));   %   samples per data record

fseek(EDF.FILE.FID,32*EDF.NS,0);

EDF.Cal = (EDF.PhysMax-EDF.PhysMin)./ ...
    (EDF.DigMax-EDF.DigMin);
EDF.Off = EDF.PhysMin - EDF.Cal .* EDF.DigMin;
tmp = find(EDF.Cal < 0);
EDF.Cal(tmp) = ones(size(tmp));
EDF.Off(tmp) = zeros(size(tmp));

EDF.Calib=[EDF.Off';(diag(EDF.Cal))];
%EDF.Calib=sparse(diag([1; EDF.Cal]));
%EDF.Calib(1,2:EDF.NS+1)=EDF.Off';

EDF.SampleRate = EDF.SPR / EDF.Dur;

EDF.FILE.POS = ftell(EDF.FILE.FID);
if EDF.NRec == -1   % unknown record size, determine correct NRec
  fseek(EDF.FILE.FID, 0, 'eof');
  endpos = ftell(EDF.FILE.FID);
  EDF.NRec = floor((endpos - EDF.FILE.POS) / (sum(EDF.SPR) * 2));
  fseek(EDF.FILE.FID, EDF.FILE.POS, 'bof');
  H1(237:244)=sprintf('%-8i',EDF.NRec);      % write number of records
end

EDF.Chan_Select=(EDF.SPR==max(EDF.SPR));
for k=1:EDF.NS
    if EDF.Chan_Select(k)
        EDF.ChanTyp(k)='N';
    else
        EDF.ChanTyp(k)=' ';
    end
    if contains(upper(EDF.Label(k,:)),'ECG')
        EDF.ChanTyp(k)='C';
    elseif contains(upper(EDF.Label(k,:)),'EKG')
        EDF.ChanTyp(k)='C';
    elseif contains(upper(EDF.Label(k,:)),'EEG')
        EDF.ChanTyp(k)='E';
    elseif contains(upper(EDF.Label(k,:)),'EOG')
        EDF.ChanTyp(k)='O';
    elseif contains(upper(EDF.Label(k,:)),'EMG')
        EDF.ChanTyp(k)='M';
    end
end

EDF.AS.spb = sum(EDF.SPR);  % Samples per Block
bi=[0;cumsum(EDF.SPR)];

idx=[];idx2=[];
for k=1:EDF.NS,
    idx2=[idx2, (k-1)*max(EDF.SPR)+(1:EDF.SPR(k))];
end
maxspr=max(EDF.SPR);
idx3=zeros(EDF.NS*maxspr,1);
for k=1:EDF.NS, idx3(maxspr*(k-1)+(1:maxspr))=bi(k)+ceil((1:maxspr)'/maxspr*EDF.SPR(k));end;

%EDF.AS.bi=bi;
EDF.AS.IDX2=idx2;
%EDF.AS.IDX3=idx3;

DAT.Head=EDF;
DAT.MX.ReRef=1;

%DAT.MX=feval('loadxcm',EDF);

return


function prepare_voc12val_det_imgs(output_img_dir, bbox_mat_filelist, resize_dim)
% PREPARE_VOC12VAL_DET
%   Prepare testing images from detector outputs on VOC12 val set.
% input:
%   output_img_dir: output image folder name, output will be like <output_img_dir>/<category>/<imgs>
%   bbox_mat_filenames: txt files containing a list of bbox mat filenames
%   resize_dim (D): if >0 resize images to DxD.
%

addpath(fullfile(mfilename('fullpath'), '../../'));
global_variables;
cls_names = g_cls_names;

% paths
annotation_path = fullfile(g_pascal3d_root_folder, 'Annotations');
image_path = fullfile(g_pascal3d_root_folder, 'PASCAL/VOCdevkit/VOC2012/JPEGImages');
addpath(fullfile(g_pascal3d_root_folder, 'VDPM'));
addpath(fullfile(g_pascal3d_root_folder, 'PASCAL/VOCdevkit/VOCcode'));

% read ids of train/val set images
VOCinit;
img_set = 'val';
ids = textread(sprintf(VOCopts.imgsetpath, img_set), '%s');
M = numel(ids);

bbox_mat_filenames = importdata(bbox_mat_filelist);
for k = 1:numel(bbox_mat_filenames)
    bbox_mat_filenames{k} = fullfile(g_detection_results_folder, bbox_mat_filenames{k});
end

% avoid duplication
assert(exist(output_img_dir,'dir')==0);
mkdir(output_img_dir);
for cls_idx = 1:numel(cls_names)
    mkdir([output_img_dir '/' cls_names{cls_idx}]);
end

for cls_idx = 1:numel(cls_names)
    cls = cls_names{cls_idx};

    imgfile = fopen(fullfile(output_img_dir, sprintf('%s.txt', cls)),'w');

    % load detection bboxes of all images for class
    detection_filename = bbox_mat_filenames{cls_idx};
    assert(~isempty(strfind(detection_filename, cls)));
    mat = load(detection_filename);
    det_bboxes_all = mat.boxes;

    for i = 1:M
        if mod(i,100) == 0
            fprintf('%s: %d/%d\n', cls, i, M);
        end

        % bboxes for image i, class cls
        det_bboxes = det_bboxes_all{i};

        % load i-th image in VOC val
        img_filename = fullfile(image_path, sprintf('%s.jpg', ids{i}));
        im = imread(img_filename);

        for k = 1:size(det_bboxes,1)
            box = det_bboxes(k,:);
            box = box(1:4);
            w = box(3)-box(1)+1;
            h = box(4)-box(2)+1;
            rect = [box(1),box(2), w, h];

            % write cropped img
            cropped_im = imcrop(im, rect);
            if resize_dim > 0
                copped_im = imresize(cropped_im, [resize_dim, resize_dim]);
            end
            cropped_im_filename = sprintf('%s/%s/%s_%s_%s.jpg', output_img_dir, cls, cls, ids{i}, num2str(k));
            imwrite(cropped_im, cropped_im_filename);
            fprintf(imgfile, '%s\n', cropped_im_filename);
        end
    end
    fclose(imgfile);
end


%% APAP-conssite
% %{
imfolder = 'images\APAP-conssite';
im_n = 5;
imfile = cell(im_n,1);
imfile{1} = [imfolder '\' 'DSC03002.jpg'];
imfile{2} = [imfolder '\' 'DSC03003.jpg'];
imfile{3} = [imfolder '\' 'DSC03004.jpg'];
imfile{4} = [imfolder '\' 'DSC03005.jpg'];
imfile{5} = [imfolder '\' 'DSC03006.jpg'];

im = cell(im_n,1);
for ii = 1:im_n
    im{ii} = imread(imfile{ii});
end

edge_list = [1,2; 1,3; 1,4; 2,3; 2,4; 2,5; 3,4; 3,5; 4,5];

imsize = zeros(im_n,3);

for ii = 1:im_n
    imsize(ii,:) = size(im{ii});
    if imsize(ii,1) > 720
        scale = 720/size(im{ii}, 1);
        im{ii} = imresize(im{ii}, scale);

        imsize(ii,:) = size(im{ii});
    end
end

mosaic = REW_mosaic( im, edge_list, 1, 'equi', 0, imfolder );
%}


function rtk = detslip_LLI(rtk,obs,i,rcv)

global glc;
sat=obs(i).sat;

for f=1:rtk.opt.nf

    if obs(i).L(f)==0||abs(timediff(obs(i).time,rtk.sat(sat).pt(rcv,f)))<glc.DTTOL
        continue;
    end

    % restore previous LLI
    if rcv==1
        LLI=getbitu(rtk.sat(sat).slip(f),0,2);
    else
        LLI=getbitu(rtk.sat(sat).slip(f),2,2);
    end

    % detect slip by cycle slip flag in LLI
    if rtk.tt>=0
        slip=obs(i).LLI(f);
    else
        slip=LLI;
    end

    if (bitand(LLI,2)&&~bitand(obs(i).LLI(f),2))||(~bitand(LLI,2)&&bitand(obs(i).LLI(f),2))
        slip=bitor(slip,1);
    end

    if rcv==1
        rtk.sat(sat).slip(f)=setbitu(rtk.sat(sat).slip(f),0,2,obs(i).LLI(f));
    else
        rtk.sat(sat).slip(f)=setbitu(rtk.sat(sat).slip(f),2,2,obs(i).LLI(f));
    end

    rtk.sat(sat).slip(f)=bitor(rtk.sat(sat).slip(f),slip);
    if bitand(obs(i).LLI(f),2)
        rtk.sat(sat).half(f)=0;
    else
        rtk.sat(sat).half(f)=1;
    end

end

return


function D = spm_eeg_inv_mesh_ui(varargin)
% Cortical Mesh user interface
% FORMAT D = spm_eeg_inv_mesh_ui(D, val, sMRI, Msize)
%
% D        - input data struct (optional)
% val      -
% sMRI     -  0 - use template (default), or string with image file name
% Msize    -
%
% D        - same data struct including the meshing files and variables
%__________________________________________________________________________
%
% Invokes spatial normalisation (if required) and the computation of
% the individual mesh.
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Jeremie Mattout & Christophe Phillips
% $Id: spm_eeg_inv_mesh_ui.m 4027 2010-07-31 12:49:19Z vladimir $

SVNrev = '$Rev: 4027 $';

%-Startup
%--------------------------------------------------------------------------
spm('FnBanner', mfilename, SVNrev);
spm('FigName','Define head model');

%-Initialisation
%--------------------------------------------------------------------------
[D,val] = spm_eeg_inv_check(varargin{:});

if val == 0
    val = 1;
end

if ~isfield(D, 'inv') || ~isfield(D.inv{val}, 'comment')
    D.inv = {struct('mesh', [])};
    D.inv{val}.date    = strvcat(date,datestr(now,15));
    D.inv{val}.comment = {''};
else
    inv = struct('mesh', []);
    inv.comment = D.inv{val}.comment;
    inv.date    = D.inv{val}.date;
    D.inv{val} = inv;
end

if nargin > 2
    sMRI = varargin{3};
else
    sMRI = [];
end

if isempty(sMRI)
    template = spm_input('Select head  model', '+1','template|individual', [1 0]);
elseif ~ischar(sMRI)
    template = sMRI; % for backward compatibility
else
    template = 0;
end

if template
    sMRI = [];
elseif ~ischar(sMRI)
    % get sMRI file name
    sMRI = spm_select([0 1],'image','Select subject''s structural MRI (Press Done if none)');
    if isempty(sMRI)
        error('No structural MRI selected.');
    end
end

if nargin>3
    Msize = varargin{4};
else
    Msize = spm_input('Cortical mesh', '+1', 'coarse|normal|fine', [1 2 3]);
end

D.inv{val}.mesh = spm_eeg_inv_mesh(sMRI, Msize);

%-Check meshes and display
%--------------------------------------------------------------------------
spm_eeg_inv_checkmeshes(D);

%-Cleanup
%--------------------------------------------------------------------------
spm('FigName','Define head model: done');


%
% write_matrix(FID,data)
%
% This function write a matrix to the specified file. Both two dimensional
% matrix and one dimensional vector are accepted.
%
% Author: Xiao Xiong
% Created: 6 Feb, 2007
% Last modified: 6 Feb, 2007

function write_matrix_file(filename, data)

FID = fopen(filename, 'w');
write_matrix(FID, data);
fclose(FID);


function printmark(i, resolution, num_iterations)
    if ~mod(i, resolution)
        fprintf('.');
    end

    newline_thresh = 50*resolution;

    if ~mod(i, newline_thresh)
        fprintf(' %d\n', i);
    end

    if (i == num_iterations)
        fprintf(' %d\n', i);
    end

end


function varargout = resultManager(varargin)
% RESULTMANAGER MATLAB code for resultManager.fig
%      RESULTMANAGER, by itself, creates a new RESULTMANAGER or raises the existing
%      singleton*.
%
%      H = RESULTMANAGER returns the handle to a new RESULTMANAGER or the handle to
%      the existing singleton*.
%
%      RESULTMANAGER('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RESULTMANAGER.M with the given input arguments.
%
%      RESULTMANAGER('Property','Value',...) creates a new RESULTMANAGER or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before resultManager_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to resultManager_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help resultManager
% Last Modified by GUIDE v2.5 13-Jul-2013 16:20:41
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file is part of OLPS: http://OLPS.stevenhoi.org/
% Original authors: Doyen Sahoo
% Contributors: Bin LI, Steven C.H. Hoi
% Change log:
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @resultManager_OpeningFcn, ...
                   'gui_OutputFcn',  @resultManager_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before resultManager is made visible.
function resultManager_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to resultManager (see VARARGIN)

    % Read the 6 parameters
    handles.returns_daily = varargin{1};
    handles.returns = cumprod(handles.returns_daily+1 );
    handles.portfolio = varargin{2};
    handles.stats = varargin{3};
    handles.benchmarks = varargin{4};
    handles.benchmarks_daily = varargin{5}-1;
    handles.algorithmName = varargin{6};
    handles.frequency = varargin{7};
    [handles.r handles.c] = size(handles.portfolio);

    % Clear old values
    clearRadio(handles, [] , handles);
    set(handles.day,'String', 1);

    % Initial display
    cumReturns = [handles.benchmarks handles.returns];
    dailyReturns = [handles.benchmarks_daily handles.returns_daily];
    set(handles.rd_cumulativeReturns,'Value', 1);
	plot(handles.mainGraph, cumReturns);
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend(handles.mainGraph, 'Uniform BAH', 'Uniform CRP', 'Best Stock', 'Best CRP', handles.algorithmName, 'Location', 'Best');
    grid on;

    % Compute the statsand display the important numbers in table using the
    % library functions
    addpath('./lib');

    % Get final Values
    [r c] = size(cumReturns);
    handles.finalValues = cumReturns(r,:);

    % Get the mean returnfor every day - This is a simple average
    handles.meanReturns = mean(dailyReturns);

    % Get annualised returns
    denominator = 252/handles.frequency;
    Y = r/denominator;
    handles.annualisedReturns = handles.finalValues.^(1/Y)-1;

    % Get standard deviation- a measureof risk
    handles.standardDeviation = std(dailyReturns);

    % Get annualised standard deviation
    handles.annualisedStandardDeviation = handles.standardDeviation * sqrt(denominator);

    % Get sharpe ratios
    handles.sharpeRatios = sharpe(dailyReturns, handles.finalValues,handles.frequency);

    % Get Sortino ratios                                                   %%%%%%%%%%%%%%% DO NOT KNOW HOW TO ANNUALIZE
    handles.sortinoRatios = sortino(dailyReturns, 0);

    % Get Value risks at level 5%
    handles.valueAtRisks = var5(dailyReturns);

    % Get Maximum draw down
    handles.mdds = maxDD_general(cumReturns);

    % Get Calmar ratios
    handles.calmars = calmar(cumReturns, handles.mdds, handles.frequency);

    % Fill up the tables
    tableData = [handles.finalValues; handles.meanReturns; handles.annualisedReturns; handles.standardDeviation; handles.annualisedStandardDeviation; handles.sharpeRatios; handles.calmars; handles.sortinoRatios; handles.valueAtRisks; handles.mdds];
    set(handles.table,'Data',tableData);

    rmpath('./lib');

    guidata(hObject, handles);

% Choose default command line output for resultManager
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

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

% --- Outputs from this function are returned to the command line.
function varargout = resultManager_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
% hObject    handle to slider1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

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

    window =  str2double(get(handles.windowAnimation,'string'));
    if isnan(window) || window < 2
        errorMessage('Window size must be a number greater than or equal to 2');
        return;
    end
    window = round(window);

    try
        animation(handles.portfolio, window);
    catch exception
        disp('Animation closed before completion');
    end

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

% Hints: get(hObject,'String') returns contents of windowAnimation as text
%        str2double(get(hObject,'String')) returns contents of windowAnimation as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

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

    clearRadio(handles, [] , handles);
    set(handles.rd_portfolioConcentration,'Value', 1);

    portfolio = handles.portfolio;
    expected = mean(portfolio);
    deviation = std(portfolio);

    errorbar(handles.mainGraph, expected, deviation, 'xr');

    xlim(handles.mainGraph, [0 handles.c+1]);

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

% --- Executes on button press in rd_stepByStep.
function rd_stepByStep_Callback(hObject, eventdata, handles)
% hObject    handle to rd_stepByStep (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_stepByStep,'Value', 1);
    [r c] = size(handles.portfolio);
    bar(handles.portfolio(1,:));
    set(handles.day,'String', 1);
    xlim(handles.mainGraph, [0 handles.c+1]);
    ylim(handles.mainGraph, [-0.1 1.1]);
    grid on;
% Hint: get(hObject,'Value') returns toggle state of rd_stepByStep

% --- Executes on button press in previous.
function previous_Callback(hObject, eventdata, handles)
% hObject    handle to previous (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    [r c] = size(handles.portfolio);
    day = str2double(get(handles.day,'string'));
    if get(handles.rd_stepByStep,'Value') == 1 && day <= r && (day-1) >= 1
        bar(handles.portfolio(day-1,:));
        set(handles.day,'String', (day-1));
        xlim(handles.mainGraph, [0 handles.c+1]);
        ylim(handles.mainGraph, [-0.1 1.1]);
        grid on;
    end

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

    [r c] = size(handles.portfolio);
    day = str2double(get(handles.day,'string'));
    if get(handles.rd_stepByStep,'Value') == 1 && day >= 1 && (day+1) <= r
        bar(handles.portfolio(day+1,:));
        set(handles.day,'String', (day+1));
        xlim(handles.mainGraph, [0 handles.c+1]);
        ylim(handles.mainGraph, [-0.1 1.1]);
        grid on;
    end

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

    % Reads the day number in the inputbox and changes barchart to
    % represent that day - 2 conditions - day must lie in range, step by
    % step is selected
    [r c] = size(handles.portfolio);
    day = str2double(get(handles.day,'string'));
    if get(handles.rd_stepByStep,'Value') == 1 && day >= 1 && day <= r
        bar(handles.portfolio(day,:));
        xlim(handles.mainGraph, [0 handles.c+1]);
        ylim(handles.mainGraph, [-0.1 1.1]);
        grid on;
    end

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

% --- Executes on button press in rd_sharpe.
function rd_sharpe_Callback(hObject, eventdata, handles)
% hObject    handle to rd_sharpe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_sharpe,'Value', 1);

    window = str2double(get(handles.windowSharpe,'string'));

    if isnan(window) || window < 2
        errorMessage('Window size must be a number greater than or equal to 2');
        return;
    end
    window = round(window);

    addpath('./lib');

    [r c] = size(handles.returns_daily);
    sharpeRatios = zeros(r,1);
    for i = 50:1:r
        start = max(i-window+1, 1);
        finish = i;
        sharpeRatios(i) = sharpe(handles.returns_daily(start:finish), handles.returns(finish)/handles.returns(start), handles.frequency);
    end

    rmpath('./lib');

    plot(handles.mainGraph, sharpeRatios);
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend('Sharpe Ratio', 'Location', 'Best');

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

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

% Hints: get(hObject,'String') returns contents of windowSharpe as text
%        str2double(get(hObject,'String')) returns contents of windowSharpe as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in rd_calmar.
function rd_calmar_Callback(hObject, eventdata, handles)
% hObject    handle to rd_calmar (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_calmar,'Value', 1);

    window = str2double(get(handles.windowCalmar,'string'));
    if isnan(window) || window < 2
        errorMessage('Window size must be a number greater than or equal to 2');
        return;
    end
    window = round(window);

    addpath('./lib');

    [r c] = size(handles.returns_daily);
    calmarRatios = zeros(r,1);
    for i = 50:1:r
        start = max(i-window+1, 1);
        finish = i;
        mdd = maxDD(handles.returns(start:finish));
        calmarRatios(i) = calmar(handles.returns(start:finish), mdd, handles.frequency);
    end

    rmpath('./lib');

    plot(handles.mainGraph, calmarRatios);
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend('Calmar Ratio', 'Location', 'Best');

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

% --- Executes on button press in rd_var.
function rd_var_Callback(hObject, eventdata, handles)
% hObject    handle to rd_var (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_var,'Value', 1);

    window = str2double(get(handles.windowVar,'string'));
    if isnan(window) || window < 2
        errorMessage('Window size must be a number greater than or equal to 2');
        return;
    end
    window = round(window);

    addpath('./lib');

    [r c] = size(handles.returns_daily);
    vars = zeros(r,1);
    for i = 50:1:r
        start = max(i-window+1, 1);
        finish = i;
        vars(i) = var5(handles.returns_daily(start:finish));
    end

    rmpath('./lib');

    plot(handles.mainGraph, vars);
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend('Value At Risk 5%', 'Location', 'Best');

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

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

% Hints: get(hObject,'String') returns contents of windowCalmar as text
%        str2double(get(hObject,'String')) returns contents of windowCalmar as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in rd_mdd.
function rd_mdd_Callback(hObject, eventdata, handles)
% hObject    handle to rd_mdd (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_mdd,'Value', 1);

    window = str2double(get(handles.windowMDD,'string'));
    if isnan(window) || window < 2
        errorMessage('Window size must be a number greater than or equal to 2');
        return;
    end
    window = round(window);

    addpath('./lib');

    [r c] = size(handles.returns_daily);
    mdds = zeros(r,1);
    for i = 50:1:r
        start = max(i-window+1, 1);
        finish = i;
        mdds(i) = maxDD(handles.returns(start:finish));
    end

    rmpath('./lib');

    plot(handles.mainGraph, mdds);
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend('Maximum Draw Down', 'Location', 'Best');

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

% --- Executes on button press in rd_sortino.
function rd_sortino_Callback(hObject, eventdata, handles)
% hObject    handle to rd_sortino (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_sortino,'Value', 1);

    window = str2double(get(handles.windowSortino,'string'));
    if isnan(window) || window < 2
        errorMessage('Window size must be a number greater than or equal to 2');
        return;
    end
    window = round(window);

    addpath('./lib');

    [r c] = size(handles.returns_daily);
    sortinos = zeros(r,1);
    for i = 50:1:r
        start = max(i-window+1, 1);
        finish = i;
        sortinos(i) = sortino(handles.returns_daily(start:finish),0);
    end

    rmpath('./lib');

    plot(handles.mainGraph, sortinos);
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend('Sortino Ratio', 'Location', 'Best');

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

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

% Hints: get(hObject,'String') returns contents of windowSortino as text
%        str2double(get(hObject,'String')) returns contents of windowSortino as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in rd_cumulativeReturns.
function rd_cumulativeReturns_Callback(hObject, eventdata, handles)
% hObject    handle to rd_cumulativeReturns (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_cumulativeReturns,'Value', 1);
    logCheck = get(handles.logPlot, 'Value');
    if logCheck == 1
        semilogy([ handles.benchmarks handles.returns]);
    else
        plot([ handles.benchmarks handles.returns]);
    end
    xlim(handles.mainGraph, [0 handles.r+1]);
    legend(handles.mainGraph ,'Uniform BAH', 'Uniform CRP', 'Best Stock', 'Best CRP', handles.algorithmName, 'Location', 'Best');
    grid on;
% Hint: get(hObject,'Value') returns toggle state of rd_cumulativeReturns

% --- Executes on button press in rd_dailyReturns.
function rd_dailyReturns_Callback(hObject, eventdata, handles)
% hObject    handle to rd_dailyReturns (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    clearRadio(handles, [] , handles);
    set(handles.rd_dailyReturns,'Value', 1);
    bar(handles.mainGraph, handles.returns_daily);
    xlim(handles.mainGraph, [0 handles.r+1]);
% Hint: get(hObject,'Value') returns toggle state of rd_dailyReturns

function clearRadio(hObject, eventdata, handles)
% The function is a helper function to uncheck all radio buttons

    set(handles.rd_cumulativeReturns,'Value', 0);
    set(handles.rd_dailyReturns,'Value', 0);
    set(handles.rd_sharpe,'Value', 0);
    set(handles.rd_calmar,'Value', 0);
    set(handles.rd_sortino,'Value', 0);
    set(handles.rd_var,'Value', 0);
    set(handles.rd_mdd,'Value', 0);
    set(handles.rd_portfolioConcentration,'Value', 0);
    set(handles.rd_stepByStep,'Value', 0);

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

% Hints: get(hObject,'String') returns contents of day as text
%        str2double(get(hObject,'String')) returns contents of day as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

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

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

    % Check if user wants to see cumulative returns
    selected  = get(handles.rd_cumulativeReturns,'Value');

    % only if user wants to see the cumulative returns
    if selected == 1
        logCheck = get(handles.logPlot,'Value');

        if logCheck == 1
            semilogy([ handles.benchmarks handles.returns]);
        else
            plot([ handles.benchmarks handles.returns]);
        end
        xlim(handles.mainGraph, [0 handles.r+1]);
        legend(handles.mainGraph ,'Uniform BAH', 'Uniform CRP', 'Best Stock', 'Best CRP', handles.algorithmName, 'Location', 'Best');
        grid on;
    end

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

% Hints: get(hObject,'String') returns contents of windowVar as text
%        str2double(get(hObject,'String')) returns contents of windowVar as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

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

% Hints: get(hObject,'String') returns contents of windowMDD as text
%        str2double(get(hObject,'String')) returns contents of windowMDD as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


%kkgt 'IF Input 1 is Greater Than (Input 2 or Constant), Output = TRUE'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kgt.pane file
%
% Parameters:
% InputFile: i1 'Input 1', required: 'First input data object'
% OutputFile: o 'Output', required: 'Resulting output data object'
% InputFile: i2 'Input 2', optional: 'Second input data object'
%
% Example: o = kkgt({i1, i2}, {'i1','';'o','';'i2',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kgt - IF Input 1 is Greater Than (Input 2 or Constant), Output = TRUE
%
%  DESCRIPTION
% The GREATER THAN comparison operator compares each point
% in \fBInput 1" either with the corresponding point in \fBInput 2\fP
% or with the \fBConstant" value, which ever is specified by the user. If the
% value from \fBInput 1" is greater than the value from \fBInput 2\fP
% or the \fBConstant", the corresponding point in \fBOutput\fP will be assigned
% the value specified by \fBTRUE Value".  If the value from \fBInput 1\fP
% is not greater than the value against which it is being compared, the
% corresponding point in \fBOutput" will be the value specified by \fBFALSE
% Value".
%
%  "Data Type - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_1input
%
%  "Data Type - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_2input
%
%  "Map Data" 5
% The comparison operations have not been written to be fully polymorphic yet.
% They does not
% check for map data, and will therefore always operate on the value data,
% even if a map exists.  This will most likely corrupt indexing into the map.
% In the case of a single input, it is recommended to use the "Copy to
% Value" (kcptoval) segment operator to temporarily move the map data into
% the value segment, run the operator on the data, then move it back to the
% map with the "Copy from Value" (kcpfromval) operator.
% When operating with two input objects, where at least one of the objects
% contains map data, data should be mapped prior to running the comparison
% operator.  The "Map Data" operator (kmapdata) can be used to perform
% the mapping operation.
%
%  "Validity Mask - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/mask_1input
%
%  "Validity Mask - Two Input Objects" 5
% Masking has not been implemented yet for the comparison operators.  Therefore,
% only the mask from the first input object will be transferred to the output.
%
%  "Input Objects of Different Sizes" 5
% .cI $DATAMANIP/repos/shared/man/sections/resize_2input
% The value used to pad the data when the input files are not the same size is
% zero.
%
%  "Explicit Location and Time Data - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_1input
%
%  "Explicit Location and Time Data - Two Input Objects" 5
% The comparison operations have not been extended to understand location and
% time data.  Therefore, only location and time data present in the first input
% object will be transferred to the output.
%
% Executing the Greater Than operator runs the program "kcompare" with
% the -gt flag.
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
% DATAMANIP::kcompare
%
%  RESTRICTIONS
% This routine is still under development, and has not been modified to fully
% support the polymorphic data model.  See paragraphs above for discussions
% concerning the polymorphic data segments.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkgt(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,..] = kkgt(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'o', '__output';'i2', '__input'};
maxval={0,0,1};
minval={0,0,1};
istoggle=[0,0,1];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile','InputFile'};
% 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 'kcompare"  -gt'],Inputs,narglist);


function [varargout]=icolorbar(varargin)

% function [h]=icolorbar(cLim,h)
%-------------------------------------------------------------------------
%
%
% Change log:
% 2018/05/10 Fixed bug in relation to older matlab versions which do not
% support h.Colormap=c for axis specific color maps. Older versions use
% colormap(h,c) instead.
% 2019/08/14 Added colorbar handle output
%-------------------------------------------------------------------------

%% parse input

switch nargin
    case 0
        h=[];
        cLim=caxis;
    case 1
        cLim=varargin{1};
        h=[];
    case 2
        cLim=varargin{1};
        h=varargin{2};
end

if isempty(cLim)
    cLim=caxis;
end

if isempty(h)
    %Get current figure or open a new one
    if isempty(findobj('type','figure'))
        hf=cFigure; %Open a new figure
    else
        hf=gcf; %Get the current figure
    end
   figure(hf);
   if isempty(hf.CurrentAxes) %isempty(get(hf,'CurrentAxes'))
       h=axes;
   else
       h=gca;
   end
else
    switch class(h)
        case {'matlab.ui.Figure'} %A figure handle
            hf=h;
            if isempty(hf.CurrentAxes) %isempty(get(hf,'CurrentAxes'))
                h=axes;
            else
                h=gca;
            end
        case {'matlab.graphics.axis.Axes'} %An axes handle
            hf=h.Parent; %Get figure handle
        otherwise
            error('Handle does not represent an axis or figure handle');
    end
end

%% Get colormap
if isprop(h,'Colormap') %Available in MATLAB 2018
    c=h.Colormap;
    matlabNew=1;
else %Older MATLAB versions
    c=colormap(h);
    matlabNew=0;
end

%% Set limits and tick labels
caxis([cLim(1)-0.5 cLim(2)+0.5]);
hc=colorbar;
hc.Ticks=cLim(1):1:cLim(2);
cn=resampleColormap(c,numel(hc.Ticks));
if matlabNew==1 %axis colormap
    h.Colormap=cn;
else %Figure colormap
    colormap(h,cn);
end

%% Collect output
switch nargout
    case 1
        varargout{1}=h;
    case 2
        varargout{1}=h;
        varargout{2}=hc;
end

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2019  Kevin Mattheus Moerman
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function [system] = LoadTransSystem(model, load_path)
    % Load the hybrid system model

    if nargin < 2
        load_path = [];
    end

    rightStance1 = sys.domains.RightStance(model, load_path);
    rightStance1.UserNlpConstraint = @trans_opt.callback.RightStance1Constraints;
    leftStance1 = sys.domains.LeftStance(model, load_path);
    leftStance1.UserNlpConstraint = @trans_opt.callback.LeftStance1Constraints;

    rightStance2 = copy(rightStance1);
    rightStance2.setName('RightStance2');
    rightStance2.UserNlpConstraint = @trans_opt.callback.RightStance2Constraints;
    leftStance2 = copy(leftStance1);
    leftStance2.setName('LeftStance2');
    leftStance2.UserNlpConstraint = @trans_opt.callback.LeftStance2Constraints;

    leftImpact1 = RigidImpact('LeftImpact', leftStance1, 'leftFootHeight'); % To leftStance
    leftImpact1.addImpactConstraint(struct2array(leftStance1.HolonomicConstraints), load_path);
    leftImpact1.UserNlpConstraint = @trans_opt.callback.LeftImpactConstraints;

    rightImpact1 = RigidImpact('RightImpact', rightStance1, 'rightFootHeight'); % To rightStance
    rightImpact1.addImpactConstraint(struct2array(rightStance1.HolonomicConstraints), load_path);
    rightImpact1.UserNlpConstraint = @trans_opt.callback.RightImpactConstraints;

    leftImpact2 = copy(leftImpact1);
    %     leftImpact2 = RigidImpact('LeftImpact2', leftStance2, 'leftFootHeight'); % To leftStance
    %     leftImpact2.addImpactConstraint(struct2array(leftStance2.HolonomicConstraints), load_path);
    %     leftImpact2.UserNlpConstraint = @trans_opt.callback.LeftImpact2Constraints;

    %     rightImpact2 = RigidImpact('RightImpact2', rightStance2, 'rightFootHeight'); % To rightStance
    %     rightImpact2.addImpactConstraint(struct2array(rightStance2.HolonomicConstraints), load_path);
    %     rightImpact2 = copy(rightImpact1);
    %     rightImpact2.setName('RightImpact2');
    %     rightImpact2.UserNlpConstraint = @trans_opt.callback.RightImpact2Constraints;
    %

    io_control  = IOFeedback('IO');

    system = HybridSystem('atrias');
    system = addVertex(system, 'RightStance1', 'Domain', rightStance1, ...
        'Control', io_control);
    system = addVertex(system, 'LeftStance1', 'Domain', leftStance1, ...
        'Control', io_control);
    system = addVertex(system, 'RightStance2', 'Domain', rightStance2, ...
        'Control', io_control);
    system = addVertex(system, 'LeftStance2', 'Domain', leftStance2, ...
        'Control', io_control);

    srcs = {'RightStance1'
        'LeftStance1'
        'RightStance2'};

    tars = {'LeftStance1'
        'RightStance2'
        'LeftStance2'};

    system = addEdge(system, srcs, tars);
    system = setEdgeProperties(system, srcs, tars, ...
        'Guard', {leftImpact1, rightImpact1, leftImpact2});

end


function out=zeros(in,varargin)

if nargin==1
 out=mp(zeros(double(in)));
else
 out=mp(zeros([double(in),double([varargin{:}])]));
end


% The COBRAToolbox: testWriteSBML.m
%
% Purpose:
%     - read in a model from a .xml file, write it as a .sbml file,
%       read it back in and assess any differences
%
% Authors:
%     - Partial original file: Joseph Kang 04/07/09
%     - CI integration: Laurent Heirendt

% save the current path
currentDir = pwd;

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

testModelXML = readCbModel('Ec_iJR904.xml');

% write the model as a .sbml file
writeCbModel(testModelXML, 'sbml', 'testModelSBML.sbml');

% read the model from the newly written .sbml file
testModelSBML = readCbModel('testModelSBML.sbml');

%Due to the original model being SBML 2.1, no proteins/geneNames were
%generated.
%These models are not the same, since the References given by the xml (in
%the notes field), are not PubMed IDs, so they are transferred to the
%rxnNotes field,
testModelSBML = rmfield(testModelSBML,'rxnNotes');
testModelXML = rmfield(testModelXML,'rxnNotes');
testModelXML = rmfield(testModelXML,'rxnReferences');

% check whether both models are the same
 [isSame numDiff fieldNames] = isSameCobraModel(testModelXML, testModelSBML);

% assess any potential differences
assert(~any(numDiff))

% obtain SBML structure
testSBMLstruct = writeSBML(testModelSBML,'testModelSBML.sbml');

% asses if lower/upper bounds have proper SBO terms assigned
for i = 1:length(testSBMLstruct.parameter)
    value = testSBMLstruct.parameter(i).value;
    if abs(value) == 1000 || isinf(value) || value == 0
        assert(testSBMLstruct.parameter(i).sboTerm == 626)
    else
        assert(testSBMLstruct.parameter(i).sboTerm == 625)
    end
end

% remove the written file to clean up
delete 'testModelSBML.sbml.xml';

%read/writeSBML should be the only methods used for cobra sbml conversion.
% change the directory
cd(currentDir)

% try to shut down any left open parpool
try
    poolobj = gcp('nocreate');
    delete(poolobj);
catch
    % pass
end