function spp_cache_convX_features(imdb, varargin)
% spp_cache_convX_features(imdb, varargin)
%   Computes last conv features and saves them to disk.
%
%   Keys that can be passed in:
%
%   imdb_copy_from    An imdb with partial scales cache which can copy from
%   start             Index of the first image in imdb to process
%   end               Index of the last image in imdb to process
%   spm_im_size       Scales of image resize to
%   spp_params_def    spp pooling def file, only for adaptive scale
%   roidb             only for adaptive scale
%   net_def_file      Path to the Caffe CNN to use
%   net_file          Path to the Caffe CNN to use
%   cache             Path to the precomputed feature cache
%   cache_copy_from   Path to the precomputed feature cache to copy from
%
% Adapted from spp code written by Ross Girshick
% AUTORIGHTS
% ---------------------------------------------------------
% Copyright (c) 2014, Shaoqing Ren
%
% This file is part of the SPP code and is available
% under the terms of the Simplified BSD License provided in
% LICENSE. Please retain this notice and LICENSE if you use
% this file (or any portion of it) in your project.
% ---------------------------------------------------------
% Copyright (c) 2014, Ross Girshick
%
% This file is part of the R-CNN code and is available
% under the terms of the Simplified BSD License provided in
% LICENSE. Please retain this notice and LICENSE if you use
% this file (or any portion of it) in your project.
% ---------------------------------------------------------

ip = inputParser;
ip.addRequired('imdb', @isstruct);
ip.addOptional('imdb_copy_from', struct(), @isstruct);
ip.addOptional('start', 1, @isscalar);
ip.addOptional('end', 0, @isscalar);
ip.addOptional('spm_im_size', 688, @ismatrix);
ip.addOptional('spp_params_def', '', @isstr);
ip.addOptional('roidb', '', @isstruct);
ip.addOptional('net_def_file', '', @isstr);
ip.addOptional('net_file', '', @isstr);
ip.addOptional('cache', 'feat_cache', @isstr);
ip.addOptional('cache_copy_from', 'feat_cache', @isstr);

ip.parse(imdb, varargin{:});
opts = ip.Results;

% load caffe model
spp_load_model(spp_create_model(opts.net_def_file, opts.net_file, opts.spp_params_def));

% Where to save feature cache
opts.output_dir = ['./feat_cache/' opts.cache '/' imdb.name '/'];
copy_from_previous_cache = false;
if ~isempty(opts.imdb_copy_from) && isfield(opts.imdb_copy_from, 'name');
    copy_from_previous_cache = true;
    opts.output_dir_copy_from = ['./feat_cache/' opts.cache_copy_from '/' opts.imdb_copy_from.name '/'];
end
mkdir_if_missing(opts.output_dir);
conf = spp_config();

% Log feature extraction
timestamp = datestr(datevec(now()), 'yyyymmdd_HHMMSS');
diary_file = [opts.output_dir 'spp_train_' opts.cache '_'  timestamp '.txt'];
diary(diary_file);
fprintf('Logging output in %s\n', diary_file);

fprintf('\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n');
fprintf('Feature caching options:\n');
disp(opts);
fprintf('~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n');

image_ids = imdb.image_ids;
if opts.end == 0
  opts.end = length(image_ids);
end

total_time = 0;
count = 0;
for i = opts.start:opts.end
  fprintf('%s: cache features: %d/%d\n', procid(), i, opts.end);

  save_file = [opts.output_dir image_ids{i} '.mat'];
  if exist(save_file, 'file') ~= 0
    fprintf(' [already exists]\n');

    broken = false;
    if 1 % check all cache files
        try
            d = load(save_file);
            assert(isfield(d, 'feat'));
            assert(~isempty(d.feat));
            if ~isempty(opts.spm_im_size)
                assert(isequal(d.feat.scale, opts.spm_im_size));
                assert(length(d.feat.rsp) == length(opts.spm_im_size));
            end
        catch
            broken = true;
        end
    end

    if ~broken
        continue;
    end
  end
  mkdir_if_missing(fileparts(save_file));

  feat_cache = [];
  if copy_from_previous_cache
      load_file = [opts.output_dir_copy_from image_ids{i} '.mat'];
      if exist(load_file, 'file') == 0
         fprintf(' [missing]\n');
      else
         cache = load(load_file);
         feat_cache = cache.feat;
      end
  end

  tot_th = tic;
  count = count + 1;

  d.gt = []; d.overlap = []; d.boxes = []; d.class = []; d.feat = [];
  try
        im = imread(imdb.image_at(i));
        th = tic;

        d.feat = spp_features_convX(im, opts.spm_im_size, feat_cache, conf.use_gpu);

        fprintf(' [features: %.3fs]\n', toc(th));
  catch err
        fprintf(' extract feature error : %s \n', err.message);
  end

  th = tic;
  save(save_file, '-struct', 'd');
  fprintf(' [saving:   %.3fs]\n', toc(th));

  total_time = total_time + toc(tot_th);
  fprintf(' [avg time: %.3fs (total: %.3fs)]\n', ...
      total_time/count, total_time);
end


function [sens] = ft_appendsens(cfg, varargin)

% FT_APPENDSENS concatenates multiple sensor definitions that have been processed
% separately.
%
% Use as
%   combined = ft_appendsens(cfg, sens1, sens2, ...)
%
% A call to FT_APPENDSENS results in the label, pos and ori fields to be
% concatenated, and the tra matrix to be merged. Any duplicate electrodes
% will be removed. The labelold and chanposold fields are kept under the
% condition that they are identical across the inputs.
%
% See also FT_ELECTRODEPLACEMENT, FT_ELECTRODEREALIGN, FT_DATAYPE_SENS,
% FT_APPENDDATA, FT_APPENDTIMELOCK, FT_APPENDFREQ, FT_APPENDSOURCE

% Copyright (C) 2017-2018, Arjen Stolk
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble loadvar    varargin
ft_preamble provenance varargin
ft_preamble trackconfig

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% check if the input data is valid for this function
% and ensure it is up to the latest standards
for i=1:length(varargin)
  assert(ft_datatype(varargin{i}, 'sens'), 'incorrect input, should be a grad/elec/opto structure');
  varargin{i} = ft_datatype_sens(varargin{i});
end

% do a basic check whether the senstype, units, and coordinate systems match
senstype = cell(1,length(varargin));
for i=1:length(varargin)
  senstype{i} = ft_senstype(varargin{i});
end
typematch = all(strcmp(senstype{1}, senstype));

unitmatch = 1;
if isfield(varargin{1}, 'unit')
  unit = cell(1,length(varargin));
  for i=1:length(varargin)
    unit{i} = varargin{i}.unit;
  end
  unitmatch = all(strcmp(unit{1}, unit));
end

coordsysmatch = 1;
if isfield(varargin{1}, 'coordsys')
  coordsys = cell(1,length(varargin));
  for i=1:length(varargin)
    coordsys{i} = varargin{i}.coordsys;
  end
  coordsysmatch = all(strcmp(coordsys{1}, coordsys));
end

if ~typematch || ~unitmatch || ~coordsysmatch
  ft_error('the senstype, units, or coordinate systems of the inputs do not match');
end

% keep these fields (when present) in the output
sens = keepfields(varargin{1}, {'type', 'unit', 'coordsys'});

% make inventory
haselecpos = 0;
hascoilpos = 0;
hascoilori = 0;
haschanori = 0;
hasoptopos = 0;
hastra     = 0;
haslabelold = 0;
haschanposold = 0;
for i=1:length(varargin)
  % the following fields should be present in any sens structure
  if isfield(varargin{i}, 'label')
    label{i} = varargin{i}.label(:); % ensure column orientation
  end
  if isfield(varargin{i}, 'chanpos')
    chanpos{i} = varargin{i}.chanpos;
  end

  % some the following fields are likely present in a sens structure
  if isfield(varargin{i}, 'elecpos') % EEG
    elecpos{i} = varargin{i}.elecpos;
    haselecpos = 1;
  end
  if isfield(varargin{i}, 'coilpos') % MEG
    coilpos{i} = varargin{i}.coilpos;
    hascoilpos = 1;
  end
  if isfield(varargin{i}, 'coilori') % MEG
    coilori{i} = varargin{i}.coilori;
    hascoilori = 1;
  end
  if isfield(varargin{i}, 'chanori') % MEG
    chanori{i} = varargin{i}.chanori;
    haschanori = 1;
  end
  if isfield(varargin{i}, 'optopos') % NIRS
    optopos{i} = varargin{i}.optopos;
    hasoptopos = 1;
  end
  if isfield(varargin{i}, 'tra') % tra
    tra{i} = varargin{i}.tra;
    hastra = 1;
  end

  % the following fields might be present in a sens structure
  if isfield(varargin{i}, 'labelold')
    labelold{i} = varargin{i}.labelold(:); % ensure column orientation
    haslabelold = 1;
  end
  if isfield(varargin{i}, 'chanposold')
    chanposold{i} = varargin{i}.chanposold;
    haschanposold = 1;
  end
end

% concatenate the main fields and remove duplicates
sens.label = cat(1,label{:});
[dum, labidx] = unique(sens.label, 'stable');
if ~isequal(numel(labidx), numel(sens.label))
  fprintf('removing duplicate labels\n')
  sens.label = sens.label(labidx);
end

sens.chanpos = cat(1,chanpos{:});
[dum, chanidx] = unique(sens.chanpos, 'rows', 'stable');
if ~isequal(numel(chanidx), size(sens.chanpos,1))
  fprintf('removing duplicate channels\n')
  sens.chanpos = sens.chanpos(chanidx,:);
  if ~isequal(labidx, chanidx) % check for matching order
    ft_error('inconsistent order or number of channel labels and positions')
  end
end
if ~isequal(numel(sens.label), size(sens.chanpos,1)) % check for matching number
  ft_error('inconsistent number of channel labels and positions')
end
if haschanori
  sens.chanori = cat(1,chanori{:});
  if ~isequal(numel(chanidx), size(sens.chanpos,1))
    sens.chanori = sens.chanori(chanidx,:); % chanori should match chanpos
  end
end

if hastra && ~any(cellfun(@isempty, tra))
  sens.tra = [];
  for t = 1:numel(tra)
    trarow = [1:size(tra{t},1)]+size(sens.tra,1);
    tracol = [1:size(tra{t},2)]+size(sens.tra,2);
    sens.tra(trarow, tracol) = tra{t};
  end
end

if haselecpos
  sens.elecpos = cat(1,elecpos{:});
  [dum, elecidx, elecidx2] = unique(sens.elecpos, 'rows', 'stable');
  if ~isequal(numel(elecidx), size(sens.elecpos,1))
    fprintf('removing duplicate electrodes\n')
    sens.elecpos = sens.elecpos(elecidx,:);
  end
  if isfield(sens, 'tra')
    % shape duplicates into a single column, if necessary
    for idx = 1:numel(elecidx)
      tmp(:, idx) = sum(sens.tra(chanidx, find(idx==elecidx2)),2); % find and take sum over duplicates
    end
    sens.tra = tmp;
    % check for expected size and non-empty rows
    if ~isequal(size(sens.tra,1), size(sens.chanpos,1)) || ~isequal(size(sens.tra,2), size(sens.elecpos,1)) ...
        || any(any(sens.tra,2)==0) % all channels need to be linked to their origins
      fprintf('removing inconsistent tra matrix\n')
      sens = rmfield(sens, 'tra');
    end
  end
end

if hasoptopos
  sens.optopos = cat(1,optopos{:});
  [dum, optoidx, optoidx2] = unique(sens.optopos, 'rows', 'stable');
  if ~isequal(numel(optoidx), size(sens.optopos,1))
    fprintf('removing duplicate optodes\n')
    sens.optopos = sens.optopos(optoidx,:);
  end
  if isfield(sens, 'tra')
    % shape duplicates into a single column, if necessary
    for idx = 1:numel(optoidx)
      tmp(:, idx) = sum(sens.tra(chanidx, find(idx==optoidx2)),2); % find and take sum over duplicates
    end
    sens.tra = tmp;
    % check for expected size and non-empty rows
    if ~isequal(size(sens.tra,1), size(sens.chanpos,1)) || ~isequal(size(sens.tra,2), size(sens.optopos,1)) ...
        || any(any(sens.tra,2)==0) % all channels need to be linked to their origins
      fprintf('removing inconsistent tra matrix\n')
      sens = rmfield(sens, 'tra');
    end
  end
end

if hascoilpos
  sens.coilpos = cat(1,coilpos{:});
  [dum, coilidx, coilidx2] = unique(sens.coilpos, 'rows', 'stable');
  if ~isequal(numel(coilidx), size(sens.coilpos,1))
    fprintf('removing duplicate coils\n')
    sens.coilpos = sens.coilpos(coilidx,:);
  end
  if isfield(sens, 'tra')
    % shape duplicates into a single column, if necessary
    for idx = 1:numel(coilidx)
      tmp(:, idx) = sum(sens.tra(chanidx, find(idx==coilidx2)),2); % find and take sum over duplicates
    end
    sens.tra = tmp;
    % check for expected size and non-empty rows
    if ~isequal(size(sens.tra,1), size(sens.chanpos,1)) || ~isequal(size(sens.tra,2), size(sens.coilpos,1)) ...
        || any(any(sens.tra,2)==0) % all channels need to be linked to their origins
      fprintf('removing inconsistent tra matrix\n')
      sens = rmfield(sens, 'tra');
    end
  end
end
if hascoilori
  sens.coilori = cat(1,coilori{:});
  if ~isequal(numel(coilidx), size(sens.coilori,1))
    sens.coilori = sens.coilori(coilidx,:); % coilori should match coilpos
  end
end

% keep the following fields only when identical across inputs
if haslabelold && all(isequal(labelold{1}, labelold{:})) % labeloldmatch
  sens.labelold = labelold{1};
end
if haschanposold && all(isequal(chanposold{1}, chanposold{:})) % chanposoldmatch
  sens.chanposold = chanposold{1};
end

% ensure up-to-date and consistent output sensor description
sens = ft_datatype_sens(sens);

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble trackconfig
ft_postamble previous varargin
ft_postamble provenance sens
ft_postamble history sens
ft_postamble savevar sens


function cvx_setup( varargin )

% CVX_SETUP   Sets up and tests the cvx distribution.
%    This function is to be called any time CVX is installed on a new machine,
%    to insure that the paths are set properly and the MEX files are compiled.

global cvx___
try

    cvx___ = [];
    squares = {}; %#ok
    nret = false;
    oldpath = '';
    line = '---------------------------------------------------------------------------';

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Get version and portability information %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    cvx_version( '-install', varargin{:} );
    if ~isfield( cvx___, 'loaded' ) || ~cvx___.loaded, %#ok
        error( 'CVX:Expected', 'Error detected by cvx_version' );
    end
    isoctave = cvx___.isoctave;
    mpath = cvx___.where;
    fs = cvx___.fs;
    ps = cvx___.ps;

    %%%%%%%%%%%%%%%%%%%%%%%
    % Reset the CVX paths %
    %%%%%%%%%%%%%%%%%%%%%%%

    oldpath = cvx_startup( false );
    if ~isempty( oldpath ),
        fprintf( 'Saving updated path...' );
        nret = true;
        s = warning('off'); %#ok
        stat = savepath;
        warning(s);
        if stat,
            fprintf('failed. (see below)\n');
        else
            fprintf('done.\n');
            oldpath = [];
        end
    end

    %%%%%%%%%%%%%%%%%%%%%%
    % Search for solvers %
    %%%%%%%%%%%%%%%%%%%%%%

    try
        selected = cvx___.solvers.names{cvx___.solvers.map.default};
    catch
        selected = 'sdpt3';
    end
    cvx___.solvers = struct( 'selected', 0, 'active', 0, 'list', [], 'names', {{}}, 'map', struct( 'default', 0 ) );
    fprintf( 'Searching for solvers...' ); nret = true;
    shimpath = [ mpath, fs, 'shims', fs ];
    solvers = dir( shimpath );
    solvers = { solvers(~[solvers.isdir]).name };
    if isoctave, efilt = '\.m$'; else efilt = '\.(m|p)$'; end
    solvers = solvers( ~cellfun( @isempty, regexp( solvers, efilt ) ) );
    solvers = unique( cellfun( @(x)x(1:end-2), solvers, 'UniformOutput', false ) );
    sconfig =  struct;
    solvers = struct( ...
        'name', '', 'version', '', 'location', '', 'fullpath', '', ...
        'error', '', 'warning', '', 'path', '', 'solve', [], ...
        'settings', struct, 'sname', solvers, 'spath', shimpath, ...
        'params', struct, 'config', sconfig, 'eargs', {{}} );
    solver2 = which( 'cvx_solver_shim', '-all' );
    if ~isempty(solver2) && ~iscell(solver2),
        solver2 = { solver2 };
    end
    for k = 1 : length(solver2),
        tsolv = solver2{k};
        ndxs = find(tsolv==fs,1,'last');
        solvers(end+1).spath = tsolv(1:ndxs); %#ok
        solvers(end).sname = tsolv(ndxs+1:end-2);
    end
    cur_d = pwd;
    nsolvers = [];
    nshims = length(solvers);
    for k = 1 : nshims,
        tsolv = solvers(k);
        try
            cd(tsolv.spath);
            tsolv = feval( tsolv.sname, tsolv );
            nsolv = length(tsolv);
            if nsolv == 1,
                if ~isempty(tsolv.error), tsolv.solve = []; end
            else
               sndx = 0;
               for e = 0 : 1,
                    for j = 1 : nsolv,
                        if e ~= ( isempty( tsolv(j).error ) && ~isempty( tsolv(j).solve ) ),
                            if e, tsolv(j).solve = []; end
                            sndx = sndx + 1;
                            if sndx > 1,
                                tsolv(j).name = sprintf( '%s_%d', tsolv(j).name, sndx );
                            end
                        end
                    end
                end
            end
        catch errmsg
            errmsg = cvx_error( errmsg, 63, false, '  ' );
            if isempty( tsolv.name ),
                tsolv.name = [ tsolv.spath, tsolv.sname ];
            end
            tsolv.error = sprintf( 'unexpected error:\n%s', errmsg );
            tsolv.solve = [];
        end
        try
            nsolvers = [ nsolvers, tsolv ]; %#ok
        catch
            tsolv = solvers(k);
            tsolv.error = 'This solver shim is not compatible with CVX 3.0. Please contact the authors for an update.';
            nsolvers = [ nsolvers, tsolv ]; %#ok
        end
    end
    solvers = nsolvers;
    cd( cur_d );

    %%%%%%%%%%%%%%%%%%%%%%%%%
    % Process solver errors %
    %%%%%%%%%%%%%%%%%%%%%%%%%

    plurals = { 's', '', 's' };
    nsolv   = length(solvers);
    srej    = cellfun( @isempty, { solvers.solve } );
    sgood   = ~srej;
    fprintf( '%d shim%s found.\n', nshims, plurals{min(nshims+1,3)} );
    lens = [ 0, 0 ];
    for k = 1 : nsolv,
        lens = max( lens, [ length(solvers(k).name), length(solvers(k).version) ] );
    end
    fmt = sprintf( ' %%s  %%-%ds   %%-%ds    %%s\\n', lens(1), lens(2) );
    if any( sgood ),
        ngood = nnz(sgood);
        fprintf( '%d solver%s initialized (* = default):\n', ngood, plurals{min(ngood+1,3)} );
        stats =  { ' ', '*' };
        for k = find(sgood),
            fprintf( fmt, stats{1+strcmpi(solvers(k).name,selected)}, solvers(k).name, solvers(k).version, solvers(k).location );
            if ~isempty(solvers(k).warning),
                cvx_error( [ 'WARNING: ', solvers(k).warning ], 63, false, '        ' );
            end
        end
    else
        fprintf( [ ...
            'No valid solvers were found. This suggests a corrupt installation. Please\n', ...
            'try re-installing the files and re-running cvx_setup. If the same error\n', ...
            'occurs, please contact CVX support.\n' ] );
        error('CVX:Unexpected','No valid solvers were found.');
    end
    if any( srej ),
        t1 = srej & ( cellfun( @(x)isempty(x)||strncmp(x,'http',4), {solvers.error} ) );
        if any(t1),
            nrej = nnz(t1);
            fprintf( '%d solver%s not found:\n', nrej, plurals{min(nrej+1,3)} );
            for k = find(t1),
                err = solvers(k).error;
                if isempty(err), err = ''; end
                fprintf( fmt, ' ', solvers(k).name, err, '' ); %#ok
            end
        end
        t2 = cellfun( @(x)isequal(x,'A CVX Professional license is required.'), {solvers.error} );
        if any(t2),
            nrej = nnz(t2);
            fprintf( '%d solver%s require%s a CVX Professional license:\n', nrej, plurals{min(nrej+1,3)}, plurals{max(4-nrej,2)} );
            for k = find(t2),
                fprintf( fmt, ' ', solvers(k).name, solvers(k).version, solvers(k).location ); %#ok
            end
        end
        t3 = srej & ( ~t1 & ~t2 );
        if any(t3),
            nrej = nnz(t3);
            fprintf( '%d solver%s skipped due to errors:\n', nrej, plurals{min(nrej+1,3)} );
            for k = find(t3),
                fprintf( fmt, ' ', solvers(k).name, solvers(k).version, solvers(k).location ); %#ok
                cvx_error( solvers(k).error, 63, false, '        ' );
            end
        end
    end
    solvers = solvers(sgood);
    cvx___.solvers.list  = solvers;
    cvx___.solvers.names = { solvers.name };
    cvx___.solvers.map   = struct( 'default', 0 );
    for k = 1 : length(solvers),
        cvx___.solvers.map.(lower(solvers(k).name)) = k;
        if strcmpi( solvers(k).name, selected ),
            cvx___.solvers.map.default = k;
            cvx___.solvers.selected = k;
        end
    end
    if cvx___.solvers.selected == 0,
        cvx___.solvers.selected = 1;
        cvx___.solvers.map.default = 1;
        fprintf( [ ...
            'WARNING: The default solver %s is missing; %s has been selected as a\n', ...
            '    new default. If this was unexpected, try re-running cvx_setup.\n' ], ...
            selected, cvx___.solvers.list(cvx___.solvers.selected).name, lower(cvx___.solvers.list(cvx___.solvers.selected).name) );
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Create the global data structure %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    cvx_global;
    if isempty( cvx___.solvers.list ),
        error('CVX:Unexpected','No valid solvers were found.');
    end

    %%%%%%%%%%%%%%%%%%%%
    % Save preferences %
    %%%%%%%%%%%%%%%%%%%%

    fprintf( 'Saving updated preferences...' ); nret = true;
    try
        cvx_save_prefs( 'save' );
        fprintf( 'done.\n' ); nret = false;
    catch errmsg
        fprintf( 'unexpected error:\n' ); nret = false;
        cvx_error( errmsg, 67, true, '    ' );
        fprintf( 'Please attempt to correct this error and re-run cvx_setup. If you cannot,\n' );
        fprintf( 'you will be forced to re-run cvx_setup every time you start MATLAB.\n' );
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%
    % Test the distribution %
    %%%%%%%%%%%%%%%%%%%%%%%%%

    fprintf( 'Testing with a simple model...' ); nret = true;
    need_cc = false;
    try
        m = 16; n = 8;
        A = randn(m,n);
        b = randn(m,1);
        cvx_begin('quiet')
            variable('x(n)');
            minimize( norm(A*x-b,1) );
        cvx_end
        fprintf( 'done!\n' ); nret = false;
    catch exc
        if any(strfind(exc.message,'clear classes')),
            fprintf( 'problem (see below).\n' );
            need_cc = true;
        else
            rethrow( exc );
        end
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Quick instructions on changing the solver %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if length( cvx___.solvers.list ) > 1,
        fprintf( '%s\n', line );
        fprintf( 'To change the default solver, type "cvx_solver <solver_name>".\n')
        fprintf( 'To save this change for future sessions, type "cvx_save_prefs".\n' );
        fprintf( 'Please consult the users'' guide for more information.\n' );
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Instruct the user to save the path %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if ~isempty( oldpath )
        need_upr = false;
        need_disclaim = true;
        user_path = which( 'startup.m' );
        if isempty( user_path ),
            user_path = userpath;
            if length(user_path) <= 1,
                need_upr = true;
                user_path = system_dependent('getuserworkfolder', 'default');
                if ~isempty( user_path ),
                    if isempty( strfind( user_path, [ fs, 'MATLAB' ] ) ),
                        user_path = [ user_path, fs, 'MATLAB' ];
                    end
                end
            elseif user_path(end) == ps,
                user_path(end) = '';
            end
            if ~isempty( user_path ),
                user_file = [ user_path, fs, 'startup.m' ];
            else
                user_file = '';
            end
        else
            user_file = user_path;
            user_path = user_path(1:end-10);
        end
        fprintf( '%s\n', line );
        fprintf('NOTE: the MATLAB path has been changed to point to the CVX distribution. To\n' );
        fprintf('use CVX without having to re-run CVX_SETUP every time MATLAB starts, you\n' );
        fprintf('will need to save this path permanently. This script attempted to do this\n' );
        if fs == '/',
            fprintf('for you, but failed---likely due to UNIX permissions restrictions.\n' );
            nextword = 'To solve the problem';
        else
            fprintf('for you, but failed, due to the Windows User Access Control (UAC) settings.\n');
            fprintf('Click here for a MATLAB document that discusses the issue.\n\n');
            fprintf('To solve this problem, please take the following steps:\n');
            fprintf('    1) Exit MATLAB.\n');
            fprintf('    2) Right click on the MATLAB icon, and select "Run as administrator."\n' );
            fprintf('    3) Re-run "cvx_setup".\n\n');
            nextword = 'Alternatively, if you do not have administrator access';
        end
        if exist( user_file, 'file' ),
            fprintf( '%s, edit the file\n    %s\nand add the following line to the end of the file:\n', nextword, user_file );
            fprintf( '    run %s%scvx_startup.m\n', mpath, fs );
        elseif ~isempty( user_path ),
            fprintf( '%s, create a new file\n    %s\ncontaining the following line:\n', nextword, user_file );
            fprintf( '    run %s%scvx_startup.m\n', mpath, fs );
        else
            fprintf( '%s, create a startup.m file containing the line:\n', nextword );
            fprintf( '    run %s%scvx_startup.m\n', mpath, fs );
            fprintf( 'Consult the MATLAB documentation for the proper location for that file.\n' );
            need_disclaim = false;
        end
        if need_upr,
            fprintf( 'Then execute the following MATLAB commands:\n    userpath reset; startup\n' );
        end
        if need_disclaim,
            fprintf( 'Please consult the MATLAB documentation for more information about the\n' );
            fprintf( 'startup.m file and its proper placement and usage.\n' );
        end
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Warn about class conflict with previous version of CVX %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if need_cc,
        fprintf( '%s\n', line );
        fprintf('WARNING: CVX was unable to run the test model due to a conflict with the\n' );
        fprintf('previous version of CVX. If no other errors occurred, then the setup was\n' );
        fprintf('still successful; however, to use CVX, you will need to re-start MATLAB.\n' );
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Warn about signal processing toolbox conflict %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    squares = which( 'square', '-all' );
    if iscell( squares ) && length( squares ) > 1,
        squares = squares(~cellfun(@(x)any(strfind(x,[fs,'@cvx',fs])),squares));
        if length(squares) == 1 || ~strncmp(squares{1},[mpath,fs],length(mpath)+1),
            squares = {};
        end
    else
        squares = {};
    end
    if ~isempty(squares),
        fprintf( '%s\n', line );
        fprintf('WARNING: CVX includes a function\n    %s\n', squares{1} );
        fprintf('that conflicts with a function of the same name found here:\n    %s\n', squares{2} );
        fprintf('If you wish to use this second function, you will need to rename or delete\n' );
        fprintf('the CVX version, as it will likely produce different results. This will not\n' );
        fprintf('affect the use of SQUARE() within CVX models, because CVX relies on a\n' );
        fprintf('different, internal version of SQUARE() when constructing CVX models.\n')
    end

catch errmsg

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Restore the environment in the event of an error %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if nret, fprintf( '\n' ); end
    switch errmsg.identifier,
        case { 'CVX:Expected', 'CVX:Licensing' },
            unexpected = false;
            if ~isempty( errmsg.message ),
                cvx_error( errmsg, 67, 'ERROR: ', '    ' );
            end
        case 'CVX:Unexpected',
            unexpected = true;
        otherwise,
            cvx_error( errmsg, 67, 'UNEXPECTED ERROR: ', '    ' );
            unexpected = true;
    end
    if ~isempty( oldpath ),
        path( oldpath );
    end
    clear global cvx___
    if unexpected,
        fprintf( 'Please report this error to support, and include entire output of\n' );
        fprintf( 'CVX_SETUP in your support request.\n' );
    else
        fprintf( 'The installation of CVX was not completed. Please correct the error\n' );
        fprintf( 'and re-run CVX_SETUP.\n' );
    end

end

fprintf( '%s\n\n', line );

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


function viewHotKeyAcc(figNo)
	% Allows hotkeys to be added to the current figure for manipulation
	% Biafra Ahanonu
	% started: 2017.04.12
	% inputs
	    %
	% outputs
	    %
	% changelog
	    %
	% TODO
	    % add options for how much to offset

	% allows hotkeys to be added to the current figure for manipulation
	% A figure
	% fig = figure('menubar','none');
	fig = figure(figNo);
	% Add menus with Accelerators
	mymenu = uimenu('Parent',fig,'Label','Hot Keys');
	uimenu('Parent',mymenu,'Label','Data Cursor','Accelerator','d','Callback',@(src,evt)datacursormode(fig,'on'));
	uimenu('Parent',mymenu,'Label','Zoom','Accelerator','f','Callback',@(src,evt)zoom(fig,'on'));
	uimenu('Parent',mymenu,'Label','Pan','Accelerator','g','Callback',@(src,evt)pan(fig,'on'));
	% Some plot
	%plot(rand(1,50))
end


%Terminal organelle assembly test cases
%
% Author: Jonathan Karr, jkarr@stanford.edu
% Affiliation: Covert Lab, Department of Bioengineering, Stanford University
% Last updated: 7/13/2010
classdef TerminalOrganelleAssembly_Test < edu.stanford.covert.cell.sim.ReactionProcessTestCase
    methods
        function this = TerminalOrganelleAssembly_Test(name)
            this = this@edu.stanford.covert.cell.sim.ReactionProcessTestCase(name);
        end

        function testSimpleFixture(this)
            this.loadSimpleTestFixture();
            m = this.process;

            m.evolveState();
            assertAllEqual(0, m.substrates(:, m.compartmentIndexs_unincorporated));
            assertAllEqual(20, m.substrates(:, m.compartmentIndexs_incorporated));
        end

        function testNoIncorporatedProteins(this)
            m = this.process;
            m.substrates(:, m.compartmentIndexs_incorporated) = 0;
            m.substrates(:, m.compartmentIndexs_unincorporated) = 10;

            m.evolveState();
            assertAllEqual(0, m.substrates(:, m.compartmentIndexs_unincorporated));
            assertAllEqual(10, m.substrates(:, m.compartmentIndexs_incorporated));
        end

        function testNoUnincorporatedProteins(this)
            m = this.process;
            m.substrates(:, m.compartmentIndexs_incorporated) = 10;
            m.substrates(:, m.compartmentIndexs_unincorporated) = 0;

            m.evolveState();
            assertAllEqual(0, m.substrates(:, m.compartmentIndexs_unincorporated));
            assertAllEqual(10, m.substrates(:, m.compartmentIndexs_incorporated));
        end

        function testNoHMW12(this)
            m = this.process;

            m.substrates(:,m.compartmentIndexs_unincorporated) = 1e6;
            m.substrates(:,m.compartmentIndexs_incorporated) = 0;
            m.substrates(m.substrateIndexs_HMW1,:) = 0;
            m.substrates(m.substrateIndexs_HMW2,:) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertFalse(someUseOfAllSubstrates(m, initialState));

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW1, m.compartmentIndexs_incorporated) = 0;
            m.substrates(m.substrateIndexs_HMW2, m.compartmentIndexs_incorporated) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertTrue(someUseOfAllSubstrates(m, initialState));

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW1, m.compartmentIndexs_unincorporated) = 0;
            m.substrates(m.substrateIndexs_HMW2, m.compartmentIndexs_unincorporated) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertTrue(someUseOfAllSubstrates(m, initialState));
        end

        function testNoHMW1(this)
            m = this.process;

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW1,:)=0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertFalse(someUseOfAllSubstrates(m, initialState));

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW1, m.compartmentIndexs_incorporated) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertTrue(someUseOfAllSubstrates(m, initialState));

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW1, m.compartmentIndexs_unincorporated) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertTrue(someUseOfAllSubstrates(m, initialState));
        end

        function testNoHMW2(this)
            m = this.process;

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW2,:) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertFalse(someUseOfAllSubstrates(m, initialState));

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW2, m.compartmentIndexs_incorporated) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertTrue(someUseOfAllSubstrates(m, initialState));

            m.substrates(:) = 100;
            m.substrates(m.substrateIndexs_HMW2, m.compartmentIndexs_unincorporated) = 0;
            initialState = struct('substrates', m.substrates);
            m.evolveState();
            assertTrue(someUseOfAllSubstrates(m, initialState));
        end

        function testGeneEssentiality(this)
            m = this.process;
            m.substrates(:) = 100;
            this.helpTestGeneEssentiality({
                'MG_218';     %hmw2, high molecular weight cytadherence accessory protein 2
                'MG_312';     %hmw1, high molecular weight cytadherence accessory protein 1
                'MG_317';     %hmw3, high molecular weight cytadherence accessory protein 3
                'MG_318'},... %p32, P32 adhesin
                @someUseOfAllSubstrates);
        end
    end

    methods (Access = private)
        function loadSimpleTestFixture(this)
            m = this.process;

            enzymeSubstrateIndexs = [
                m.enzymeIndexs_HMW1;
                m.enzymeIndexs_HMW2;
                m.enzymeIndexs_HMW3;
                m.enzymeIndexs_P32];

            m.substrateWholeCellModelIDs = sort(m.substrateWholeCellModelIDs__);
            m.enzymeWholeCellModelIDs = m.substrateWholeCellModelIDs(enzymeSubstrateIndexs);

            m.reactionWholeCellModelIDs = {
                'MG_191_TerminalOrganelleAssembly_01';
                'MG_192_TerminalOrganelleAssembly_01';
                'MG_217_TerminalOrganelleAssembly_01';
                'MG_218_TerminalOrganelleAssembly_01';
                'MG_218_TerminalOrganelleAssembly_02';
                'MG_312_TerminalOrganelleAssembly_01';
                'MG_312_TerminalOrganelleAssembly_02';
                'MG_317_TerminalOrganelleAssembly_01';
                'MG_318_TerminalOrganelleAssembly_01';
                'MG_386_TerminalOrganelleAssembly_01'};
            m.reactionNames = m.reactionWholeCellModelIDs;

            nSubstrates = length(m.substrateWholeCellModelIDs);
            nReactions  = length(m.reactionWholeCellModelIDs);

            m.localizationSubstrates = zeros(nReactions, nSubstrates);
            m.localizationSubstrates(1, substrateIdx('MG_191_MONOMER')) = 1;
            m.localizationSubstrates(2, substrateIdx('MG_192_MONOMER')) = 1;
            m.localizationSubstrates(3, substrateIdx('MG_217_MONOMER')) = 1;
            m.localizationSubstrates(4, substrateIdx('MG_218_MONOMER')) = 1;
            m.localizationSubstrates(5, substrateIdx('MG_218_MONOMER')) = 1;
            m.localizationSubstrates(6, substrateIdx('MG_312_MONOMER')) = 1;
            m.localizationSubstrates(7, substrateIdx('MG_312_MONOMER')) = 1;
            m.localizationSubstrates(8, substrateIdx('MG_317_MONOMER')) = 1;
            m.localizationSubstrates(9, substrateIdx('MG_318_MONOMER')) = 1;
            m.localizationSubstrates(10, substrateIdx('MG_386_MONOMER')) = 1;

            i = m.compartmentIndexs_incorporated;
            u = m.compartmentIndexs_unincorporated;

            m.localizationReactions = zeros(nReactions, nSubstrates, 2);
            m.localizationReactions(1, substrateIdx('MG_312_MONOMER'), i) = 1;
            m.localizationReactions(3, substrateIdx('MG_318_MONOMER'), i) = 1;
            m.localizationReactions(4, substrateIdx('MG_312_MONOMER'), u) = 1;
            m.localizationReactions(5, substrateIdx('MG_312_MONOMER'), i) = 1;
            m.localizationReactions(6, substrateIdx('MG_218_MONOMER'), u) = 1;
            m.localizationReactions(7, substrateIdx('MG_218_MONOMER'), i) = 1;
            m.localizationReactions(8, substrateIdx('MG_312_MONOMER'), i) = 1;
            m.localizationReactions(9, substrateIdx('MG_317_MONOMER'), i) = 1;
            m.localizationReactions(10, substrateIdx('MG_312_MONOMER'), i) = 1;

            m.localizationThreshold = sum(sum(m.localizationReactions,3),2);

            m.substrates = repmat(10, length(m.substrateWholeCellModelIDs), 2);
            m.enzymes    = m.substrates(enzymeSubstrateIndexs, :);

            function i = substrateIdx(id)
                [~,i] = ismember(id, m.substrateWholeCellModelIDs);
            end
        end
    end
end

function result = someUseOfAllSubstrates(m, i)
    result = all(...
        i.substrates(:,m.compartmentIndexs_unincorporated)==0 | ...
        i.substrates(:,m.compartmentIndexs_unincorporated) > ...
        m.substrates(:,m.compartmentIndexs_unincorporated));
end


function val = getHomer2_paramValue(funcName, paramName, file)

val = [];

DEBUG=0;
if DEBUG
    fprintf('Searching Homer2 output %s for %s: %s value\n', file.name, funcName, paramName);
end
load(file.name);
for jj=1:length(group.subjs)
    for kk=1:length(group.subjs(jj).runs)
        for iFunc=1:length(group.subjs(jj).runs)
            if strcmp(group.subjs(jj).runs(kk).procInput.procFunc.funcName{iFunc}, funcName)
                for iParam=1:group.subjs(jj).runs(kk).procInput.procFunc.nFuncParam(iFunc)
                    if strcmp(group.subjs(jj).runs(kk).procInput.procFunc.funcParam{iFunc}{iParam}, paramName)
                        val = group.subjs(jj).runs(kk).procInput.procFunc.funcParamVal{iFunc}{iParam};
                        break
                    end
                end
            end
            if ~isempty(val)
                break;
            end
        end
        if ~isempty(val)
            break;
        end
    end
    if ~isempty(val)
        break;
    end
end


function toolboxSfmGenDoc()
% Generate documentation, must run from dir toolbox.
%
% Requires external/m2html to be in path.
%
% Prior to running, update a few things in the overview.html file in:
%   toolbox/external/m2html/templates/frame-vincent/overview.html
%   1) The version / date
%   2) Link to rar/zip file
% Might be useful to use:
%
% USAGE
%  toolboxGenDoc
%
% INPUTS
%
% OUTPUTS
%
% EXAMPLE
%
% See also
%
% Vincent's Structure From Motion Toolbox      Version 3.0
% Copyright (C) 2008-2011 Vincent Rabaud.  [vrabaud-at-cs.ucsd.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the GPL [see external/gpl.txt]

% run m2html
params = {'mfiles',{'@Animation','csfm','linearAlgebra','nrsfm','sfm','visualize'}};
params = {params{:},'htmldir','doc','recursive','on','source','off'};
matlabpathTmp = matlabpath;
tmp = which('m2html','-all');
for i = 1 : length(tmp); rmpath( fileparts( tmp{i} ) ); end
addpath( genpath( fileparts( mfilename('fullpath') ) ) );
params = {params{:},'template','frame-vincent','index','menu','global','on'};
m2html(params{:});
addpath( matlabpathTmp );

% copy custom menu.html
copyfile('external\m2html\templates\menu-for-frame-vincent.html','doc/menu.html');

% copy history file
copyfile('external\history.txt','doc/history.txt');

% remove links to .svn and private in the menu.html files
d = { './doc' };

while ~isempty(d)
  dTmp = dir(d{1});
  for i = 1 : length(dTmp)
    name = dTmp(i).name;
    if strcmp( name,'.') || strcmp( name,'..'); continue; end
    if dTmp(i).isdir; d{end+1} = [ d{1} '/' name ]; continue; end
    if ~strcmp( name,'menu.html'); continue; end
    fid = fopen( [ d{1} '/' name ], 'r' ); c = fread(fid, '*char')'; fclose( fid );
    c = regexprep( c, '
([^<]*[<]?[^<]*)\.svn([^<]*[<]?[^<]*)
', '');
    c = regexprep( c, '
([^<]*[<]?[^<]*)private([^<]*[<]?[^<]*)
', '');
    fid = fopen( [ d{1} '/' name ], 'w' ); fwrite( fid, c ); fclose( fid );
  end
  d(1) = [];
end

% Zip the whole toolbox
s = dir( './' );
goodFolder = { '@Animation' 'csfm' 'doc' 'external' 'linearAlgebra' 'nrsfm' 'sfm' 'visualize' };
for i = length(s) : -1 : 1
  isGood = false;
  for j = 1 : length(goodFolder)
    if strcmp( s(i).name, goodFolder{j} )
      isGood = true;
    end
  end
  if isGood
    s(i).name = [ './' s(i).name ];
  else s(i) = [];
  end
end
files = cell(1,0);

while ~isempty(s)
  if s(1).isdir
    ls = length(s);
    s = [ s; dir( s(1).name ) ];
    for i = length(s) : -1 : ls+1
      if ~strcmp( s(i).name(1), '.' )
        s(i).name = [ s(1).name '/' s(i).name ];
      else s(i) = [];
      end
    end
    s(1) = [];
  else
    if ~strcmp( s(1).name(end), '~' )
      files{end+1} = s(1).name;
    end
    s(1) = [];
  end
end

zip( 'vincentToolbox.zip', files );


% Instantiate simulation from modified knowledge base.
%
% Author: Jonathan Karr, jkarr@stanford.edu
% Author: Bonny Jain, bonny.jain@mit.edu
% Affilitation: Covert Lab, Department of Bioengineering, Stanford University
% Last updated: 12/20/2012
classdef Repressilator < edu.stanford.covert.cell.sim.runners.SimulationRunner
    methods
        function this = Repressilator(varargin)
            this = this@edu.stanford.covert.cell.sim.runners.SimulationRunner(varargin{:});
        end
    end

    methods (Access = protected)
        function modifyNetworkStructure(this, kb)
            import edu.stanford.covert.cell.kb.Gene;
            import edu.stanford.covert.cell.kb.ProteinMonomer;
            import edu.stanford.covert.cell.kb.ProteinComplex;
            import edu.stanford.covert.cell.kb.Stimuli;
            import edu.stanford.covert.cell.kb.TranscriptionUnit;

            %% create new genes, transcription units, etc.
            meanHL = mean([kb.mRNAGenes.halfLife]);
            expression = zeros(1, 3); %normal, cold shock, heat shock
            geneA = Gene(kb, NaN, {'GeneA'}, {'Gene A'}, {'genA'}, {''}, {'mRNA'}, 0, {''}, ...
                580500, 300, true, {''}, meanHL, expression);
            geneB = Gene(kb, NaN, {'GeneB'}, {'Gene B'}, {'genB'}, {''}, {'mRNA'}, 0, {''}, ...
                581000, 300, true, {''}, meanHL, expression);
            geneC = Gene(kb, NaN, {'GeneC'}, {'Gene C'}, {'genC'}, {''}, {'mRNA'}, 0, {''}, ...
                581500, 300, true, {''}, meanHL, expression);

            tuA = TranscriptionUnit(kb, NaN, {'TuA'}, {'Transcription unit A'},...
                -35, 6, ...
                -10, 6, ...
                -1);
            tuB = TranscriptionUnit(kb, NaN, {'TuB'}, {'Transcription unit B'},...
                -35, 6, ...
                -10, 6, ...
                -1);
            tuC = TranscriptionUnit(kb, NaN, {'TuC'}, {'Transcription unit C'},...
                -35, 6, ...
                -10, 6, ...
                -1);

            monA = ProteinMonomer(kb, NaN, {'MonomerA'}, {'Protein monomer A'},...
                {''}, {''}, {''}, ...
                10, {'dsDNA'}, {'dsDNA'}, ...
                {''}, {''}, {''}, {''}, {''}, {''}, ...
                false, {''}, {''}, 0, ...
                {''});
            monB = ProteinMonomer(kb, NaN, {'MonomerB'}, {'Protein monomer B'},...
                {''}, {''}, {''}, ...
                10, {'dsDNA'}, {'dsDNA'}, ...
                {''}, {''}, {''}, {''}, {''}, {''}, ...
                false, {''}, {''}, 0, ...
                {''});
            monC = ProteinMonomer(kb, NaN, {'MonomerC'}, {'Protein monomer C'},...
                {''}, {''}, {''}, ...
                10, {'dsDNA'}, {'dsDNA'}, ...
                {''}, {''}, {''}, {''}, {''}, {''}, ...
                false, {''}, {''}, 0, ...
                {''});

            cpxAA = ProteinComplex(kb, NaN, {'ComplexAA'}, {'Macromolecular complex AA'},...
                10, {'dsDNA'}, {'dsDNA'}, ...
                {''}, {''}, {''}, {''}, {''}, {''}, ...
                {'!StimulusA'}, {''});

            cpxBB = ProteinComplex(kb, NaN, {'ComplexBB'}, {'Macromolecular complex BB'},...
                10, {'dsDNA'}, {'dsDNA'}, ...
                {''}, {''}, {''}, {''}, {''}, {''}, ...
                {'!StimulusB'}, {''});

            cpxCC = ProteinComplex(kb, NaN, {'ComplexCC'}, {'Macromolecular complex CC'},...
                10, {'dsDNA'}, {'dsDNA'}, ...
                {''}, {''}, {''}, {''}, {''}, {''}, ...
                {''}, {''});

            stimA = Stimuli(kb, NaN, {'StimulusA'}, {'Stimulus A'});
            stimB = Stimuli(kb, NaN, {'StimulusB'}, {'Stimulus B'});

            this.createDefaultDisplacementReactions(kb, [cpxAA; cpxBB; cpxCC]);

            acgt = 'ACGT';
            genome = kb.genome;
            randSeq = ceil(rand(1, 582500-genome.sequenceLength) * 4);
            genome.sequence = [genome.sequence  acgt(randSeq)];
            genome.sequence(geneA.startCoordinate : geneA.endCoordinate) = acgt(ceil(rand(1, geneA.endCoordinate - geneA.startCoordinate + 1) * 4));
            genome.sequence(geneB.startCoordinate : geneB.endCoordinate) = acgt(ceil(rand(1, geneB.endCoordinate - geneB.startCoordinate + 1) * 4));
            genome.sequence(geneC.startCoordinate : geneC.endCoordinate) = acgt(ceil(rand(1, geneC.endCoordinate - geneC.startCoordinate + 1) * 4));
            genome.sequence(geneA.startCoordinate+(0:2)) = 'ATG';
            genome.sequence(geneB.startCoordinate+(0:2)) = 'ATG';
            genome.sequence(geneC.startCoordinate+(0:2)) = 'ATG';
            genome.sequence(geneA.endCoordinate+(-2:0)) = 'TAA';
            genome.sequence(geneB.endCoordinate+(-2:0)) = 'TAA';
            genome.sequence(geneC.endCoordinate+(-2:0)) = 'TAA';

            cytosol = kb.compartments(kb.cytosolCompartmentIndexs);
            extracellularSpace = kb.compartments(kb.extracellularCompartmentIndexs);

            %% create new relationships among new genes, transcription units, etc.
            geneA.genome = genome;
            geneA.transcriptionUnits = tuA;
            geneA.proteinMonomers = monA;
            geneA.compartment = cytosol;

            geneB.genome = genome;
            geneB.transcriptionUnits = tuB;
            geneB.proteinMonomers = monB;
            geneB.compartment = cytosol;

            geneC.genome = genome;
            geneC.transcriptionUnits = tuC;
            geneC.proteinMonomers = monC;
            geneC.compartment = cytosol;

            tuA.genome = genome;
            tuA.genes = geneA;
            tuA.geneCompartments = cytosol;
            tuA.compartment = cytosol;
            tuA.transcriptionFactorProteinComplexs = cpxBB;
            tuA.transcriptionFactorProteinComplexAffinitys = NaN; %nM
            tuA.transcriptionFactorProteinComplexActivitys = 1/10;
            tuA.transcriptionFactorProteinComplexConditions = {''};
            tuA.transcriptionFactorProteinComplexBindingSiteStartCoordinates = 580460;
            tuA.transcriptionFactorProteinComplexBindingSiteLengths = 10;
            tuA.transcriptionFactorProteinComplexBindingSiteDirections = true;
            tuA.transcriptionFactorProteinComplexCompartments = cytosol;

            tuB.genome = genome;
            tuB.genes = geneB;
            tuB.geneCompartments = cytosol;
            tuB.compartment = cytosol;
            tuB.transcriptionFactorProteinComplexs = cpxCC;
            tuB.transcriptionFactorProteinComplexAffinitys = NaN; %nM
            tuB.transcriptionFactorProteinComplexActivitys = 1/10;
            tuB.transcriptionFactorProteinComplexConditions = {''};
            tuB.transcriptionFactorProteinComplexBindingSiteStartCoordinates = 580960;
            tuB.transcriptionFactorProteinComplexBindingSiteLengths = 10;
            tuB.transcriptionFactorProteinComplexBindingSiteDirections = true;
            tuB.transcriptionFactorProteinComplexCompartments = cytosol;

            tuC.genome = genome;
            tuC.genes = geneC;
            tuC.geneCompartments = cytosol;
            tuC.compartment = cytosol;
            tuC.transcriptionFactorProteinComplexs = cpxAA;
            tuC.transcriptionFactorProteinComplexAffinitys = NaN; %nM
            tuC.transcriptionFactorProteinComplexActivitys = 1/10;
            tuC.transcriptionFactorProteinComplexConditions = {''};
            tuC.transcriptionFactorProteinComplexBindingSiteStartCoordinates = 581460;
            tuC.transcriptionFactorProteinComplexBindingSiteLengths = 10;
            tuC.transcriptionFactorProteinComplexBindingSiteDirections = true;
            tuC.transcriptionFactorProteinComplexCompartments = cytosol;

            monA.gene = geneA;
            monA.geneCompartments = cytosol;
            monA.compartment = cytosol;

            monB.gene = geneB;
            monB.geneCompartments = cytosol;
            monB.compartment = cytosol;

            monC.gene = geneC;
            monC.geneCompartments = cytosol;
            monC.compartment = cytosol;

            cpxAA.proteinMonomers = monA;
            cpxAA.proteinMonomerCompartments = cytosol;
            cpxAA.proteinMonomerCoefficients = 2;
            cpxAA.regulatedTranscriptionUnits = tuC;
            cpxAA.compartment = cytosol;
            cpxAA.complexFormationProcess = kb.processes.findobj('wholeCellModelID', 'Process_MacromolecularComplexation');
            cpxAA.stimuliRegulators = stimA;

            cpxBB.proteinMonomers = monB;
            cpxBB.proteinMonomerCompartments = cytosol;
            cpxBB.proteinMonomerCoefficients = 2;
            cpxBB.regulatedTranscriptionUnits = tuA;
            cpxBB.compartment = cytosol;
            cpxBB.complexFormationProcess = kb.processes.findobj('wholeCellModelID', 'Process_MacromolecularComplexation');
            cpxBB.stimuliRegulators = stimB;

            cpxCC.proteinMonomers = monC;
            cpxCC.proteinMonomerCompartments = cytosol;
            cpxCC.proteinMonomerCoefficients = 2;
            cpxCC.regulatedTranscriptionUnits = tuB;
            cpxCC.compartment = cytosol;
            cpxCC.complexFormationProcess = kb.processes.findobj('wholeCellModelID', 'Process_MacromolecularComplexation');

            %specificy dynamics of stimuli piece-wise
            stimA.compartments = [extracellularSpace; extracellularSpace];
            stimA.values = [true; false];
            stimA.initialTimes = [0; 10];
            stimA.finalTimes = [10; inf];
            stimA.regulatedProteinComplexs = cpxAA;

            stimB.compartments = extracellularSpace;
            stimB.values = true;
            stimB.initialTimes = 0;
            stimB.finalTimes = inf;
            stimB.regulatedProteinComplexs = cpxBB;

            genome.genes = [genome.genes; geneA; geneB; geneC];
            genome.transcriptionUnits = [genome.transcriptionUnits; tuA; tuB; tuC];

            kb.genes = genome.genes;
            kb.transcriptionUnits = genome.transcriptionUnits;
            kb.proteinMonomers = [kb.proteinMonomers; monA; monB; monC];
            kb.proteinComplexs = [kb.proteinComplexs; cpxAA; cpxBB; cpxCC];
            kb.stimulis = [kb.stimulis; stimA; stimB];

            %% class super class method
            this.modifyNetworkStructure@edu.stanford.covert.cell.sim.runners.SimulationRunner(kb);
        end

        function modifyNetworkParameters(~, sim)
            %% get handles
            g = sim.gene;
            time = sim.state('Time');
            rna = sim.state('Rna');
            trn = sim.process('Transcription');

            %% get constants
            nascentMRNAIndexs = find(any(rna.nascentRNAGeneComposition(g.mRNAIndexs, :), 1));
            [~, modTuIndexs] = ismember({'TuA'; 'TuB'; 'TuC'}, rna.wholeCellModelIDs(rna.nascentIndexs));

            %% get parameter values
            tuBindProb = trn.transcriptionUnitBindingProbabilities;
            meanBindProb = mean(tuBindProb(setdiff(nascentMRNAIndexs, modTuIndexs)));
            rnaDecayRates = rna.decayRates(rna.matureIndexs);

            %% calculate modified parameter values
            %set binding probability of new TUs
            modTuBindProb = tuBindProb;
            modTuBindProb(modTuIndexs) = meanBindProb;

            %renormalize
            modTuBindProb(nascentMRNAIndexs) = modTuBindProb(nascentMRNAIndexs) * sum(tuBindProb(nascentMRNAIndexs)) / sum(modTuBindProb(nascentMRNAIndexs));

            %update expression
            modRnaExp = (rna.nascentRNAMatureRNAComposition * modTuBindProb) ./ (log(2) / time.cellCycleLength + rnaDecayRates);
            modRnaExp = modRnaExp / sum(modRnaExp);

            %% update parameter values
            trn.transcriptionUnitBindingProbabilities = modTuBindProb;
            rna.expression(rna.matureIndexs) = modRnaExp;
        end
    end
end


function mrSESSION = UpdateSessionFunctionals(mrSESSION,scanParams,doCrop);
% mrSESSION = UpdateSessionFunctionals(mrSESSION,scanParams,doCrop);
%
% Set the fields of mrSESSION.functionals
%
% djh & dbr, 9/2001
% ras, 4/04: fixed (in a somewhat ugly way) a bug that
% occurs when you don't want to crop -- it sometimes
% ends up setting the cropSize off by 0.5, for some
% really weird reason I don't get.
if ~exist('doCrop','var')   doCrop = 1;     end

if isfield(mrSESSION, 'functionals')
    nOldScans = length(mrSESSION.functionals);
    nNewScans = length(scanParams);
    if nOldScans > 0
        oldNames = {mrSESSION.functionals(:).PfileName};
    else
        oldNames = {};
    end
    for iNew=1:nNewScans
        newName = scanParams(iNew).PfileName;
        if ~any(strcmp(newName, oldNames))
            % If the Pfile name is new, append it
            mrSESSION.functionals = [mrSESSION.functionals scanParams(iNew)];
        end
    end
else
    mrSESSION.functionals = scanParams;
end

% Update functionals.crop & cropSize
% (This is very confusing, and doesn't
% seem to work if you don't want to crop:
% e.g. if your crop is [1 1; 128 128], it
% makes the cropSize [128.5 128.5], and
% breaks everything.
%   Therefore, if doCrop is not selected,
% don't do this). -ras, 04/04
if doCrop
    ipCrop = mrSESSION.inplanes.crop;
    ipCrop(1,:) = ipCrop(1,:)-1;
    ipFullSize = mrSESSION.inplanes.fullSize;
    for iScan = 1:length(mrSESSION.functionals)
        funcFullSize = mrSESSION.functionals(iScan).fullSize;
        sizeRatio = ipFullSize ./ funcFullSize;
        crop(1,:) = ipCrop(1,:)./sizeRatio;
        crop(2,:) = ipCrop(2,:)./sizeRatio;
        if any(sizeRatio - floor(sizeRatio) <0)
            FatalInitError('Crop is busted, inplane size not a multiple of functional size. Start over and redo the crop.');
        end
        if any(crop - floor(crop) <0)
            FatalInitError('Crop is busted, inplane crop not a multiple of sizeRatio. Start over and redo the crop.');
        end
        crop(1,:) = crop(1,:) + 1;
        mrSESSION.functionals(iScan).crop = crop;
        cropSize = diff(fliplr(crop)) + 1;
        mrSESSION.functionals(iScan).cropSize = cropSize;
    end
else
    for iScan = 1:length(mrSESSION.functionals)
        cropSize = mrSESSION.functionals(iScan).crop(2,:);
        mrSESSION.functionals(iScan).cropSize = cropSize;
    end
end


% The COBRAToolbox: testSelMatrix.m
%
% Purpose:
%     - testSelMatrix tests the functionality of testSelMatrix()
%
% Authors:
%     - Lemmer El Assal February 2017
%

% save the current path
currentDir = pwd;

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

% load reference data
load('refData_selMatrix.mat');

selMat1 = selMatrix(selVec1);
selMat2 = selMatrix(selVec2);
assert(isequal(selMat1, ref_selMat1))
assert(isequal(selMat2, ref_selMat2))

%return to original directory
cd(currentDir);


fid = fopen('results_20130124.token');
fid2 = fopen('flickr30k-train&val.txt','w');
load('train_val_test_split.mat');
test_index = find(set==3);
% uid sid tweet
tline = fgetl(fid);
raw_txt = [];
count = 1;
while ischar(tline)
    %skip test
    if ~isempty(find(ceil(count/5)==test_index))
        disp(count);
        count = count+1;
        tline = fgetl(fid);
        continue;
    end
    split_tline = strsplit(tline);
    s1 = numel(split_tline{1})+1;
    tline = tline(s1+1:end);
    fprintf(fid2,'%s\n',tline);
    %disp(tline)
    raw_txt{count,1} = tline;
    tline = fgetl(fid);
    count = count+1;
end
fclose(fid);
fclose(fid2);


function [varargout] = min(varargin)

% MIN compile the missing mex file on the fly

% Copyright (C) 2012, Donders Centre for Cognitive Neuroimaging, Nijmegen, NL
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% remember the original working directory
pwdir = pwd;

% determine the name and full path of this function
funname = mfilename('fullpath');
mexsrc  = [funname '.c'];
[mexdir, mexname] = fileparts(funname);

try
  % try to compile the mex file on the fly
  warning('trying to compile MEX file from %s', mexsrc);
  cd(mexdir);
  mex(mexsrc);
  cd(pwdir);
  success = true;

catch
  % compilation failed
  disp(lasterr);
  error('could not locate MEX file for %s', mexname);
  cd(pwdir);
  success = false;
end

if success
  % execute the mex file that was just created
  funname   = mfilename;
  funhandle = str2func(funname);
  [varargout{1:nargout}] = funhandle(varargin{:});
end


function model = ivmDowndateSites(model, index)

% IVMDOWNDATESITES Downdate site parameters.
% FORMAT
% DESC remove a given data point from the site parameters.
% ARG model : the IVM structure from which the point is to be
% removed.
% ARG index : the index of the point to be removed.
% RETURN model : the model with the given point removed.
%
% COPYRIGHT : Neil D. Lawrence, 2005
%
% SEEALSO : ivmEpUpdateM, ivmRemovePoint

% IVM

model.m(index, :) = 0;
model.beta(index, :) = 0;


function res = trialtag(this, varargin)
% Method for getting/setting trial tag
% FORMAT res = trialtag(this, ind, tag)
%   ind = indices of trials
% The user can put any data here that will be attached to
% the respective trial. This is useful e.g. to make sure the
% relation between regressors and data is not broken when
% removing bad trials or merging files.
% _______________________________________________________________________
% Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak
% $Id: trialtag.m 6618 2015-12-01 16:25:38Z spm $

res = getset(this, 'trials', 'tag', varargin{:});


function DisplayLocation(city, lat, lng)
%#event
    disp(['Latitude = ' num2str(lat) '; Longitude = ' num2str(lng)]);
    disp(['Grid center near: ' city]);


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

%%
clear; close all; clc;

%% Syntax
% |[Lb]=logicRemoveInterior(L);|

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


function kernDisplay(kern, varargin)

% KERNDISPLAY Display the parameters of the kernel.
% FORMAT
% DESC displays the parameters of the kernel and the kernel type to
% the console.
% ARG kern : the kernel to display.
%
% FORMAT does the same as above, but indents the display according to the amount specified.
% ARG kern : the kernel to display.
% ARG spacing : how many spaces to indent the display of the kernel by.
%
% SEEALSO modelDisplay
%
% COPYRIGHT Neil D. Lawrence, 2006, 2005, 2004

% KERN

fhandle = str2func([kern.type 'KernDisplay']);
fhandle(kern, varargin{:});


function obj = matRad_exportDicomRTStruct(obj)
% matRad function to export dicom RT structure set.
% Class method of matRad_DicomExporter
%
% call
%   matRad_DicomExporter.matRad_exportDicomRTStruct()
%
%
% References
%   -
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2015 the matRad development team.
%
% This file is part of the matRad project. It is subject to the license
% terms in the LICENSE file found in the top-level directory of this
% distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part
% of the matRad project, including this file, may be copied, modified,
% propagated, or distributed except according to the terms contained in the
% LICENSE file.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispInfo('Exporting DICOM RTStruct...\n');

env = matRad_getEnvironment();
isOctave = strcmp(env,'OCTAVE');

if isOctave
    matRad_cfg.dispWarning('RTStruct export currently not supported by matRad running in Octave due to crashing dicomwrite! Skipping...');
    return;
end

%% Metadata
%Class UID
ClassUID = '1.2.840.10008.5.1.4.1.1.481.3'; %RT Structure Set
meta.MediaStorageSOPClassUID = ClassUID;
meta.SOPClassUID             = ClassUID;
%TransferSyntaxUID = '1.2.840.10008.1.2.1'; %Explicit VR Little Endian - correct?
%meta.TransferSyntaxUID = TransferSyntaxUID;

%Identifiers
meta.SOPInstanceUID             = dicomuid;
meta.MediaStorageSOPInstanceUID = meta.SOPInstanceUID;
meta.SeriesInstanceUID          = dicomuid;
meta.SeriesNumber               = 1;
meta.InstanceNumber             = 1;

%Remaining Meta Data
meta.Modality = 'RTSTRUCT';
meta.Manufacturer = '';
meta.ReferringPhysicianName = obj.dicomName();
meta.OperatorsName = obj.OperatorsName;
meta.StationName = '';
meta = obj.assignDefaultMetaValue(meta,'ManufacturerModelName','matRad DicomExport');

meta.PatientName = obj.PatientName;
meta.PatientID = obj.PatientID;
meta.PatientBirthDate = obj.PatientBirthDate;
meta.PatientSex = obj.PatientSex;

%Name
meta = matRad_DicomExporter.assignDefaultMetaValue(meta,'StructureSetLabel','matRad_cst');
meta = matRad_DicomExporter.assignDefaultMetaValue(meta,'StructureSetName','matRad exported cst');

%ID of the Study
meta.StudyInstanceUID = obj.StudyInstanceUID;
meta.StudyID          = obj.StudyID;

%Dates & Times
currDate = now;
currDateStr = datestr(currDate,'yyyymmdd');
currTimeStr = datestr(currDate,'HHMMSS');
meta.InstanceCreationDate = currDateStr;
meta.InstanceCreationTime = currTimeStr;
meta.StudyDate = obj.StudyDate;
meta.StudyTime = obj.StudyTime;
meta = matRad_DicomExporter.assignDefaultMetaValue(meta,'StructureSetDate',currDateStr);
meta = matRad_DicomExporter.assignDefaultMetaValue(meta,'StructureSetTime',currTimeStr);

%Remaining stuff
meta.AccessionNumber = '';

%meta.PatientBirthDate = '';
%meta.PatientSex = 'O';
%meta.SoftwareVersion = '';

ct = obj.ct;

%Create X Y Z vectors if not present
if ~any(isfield(ct,{'x','y','z'}))
    %positionOffset = transpose(ct.cubeDim ./ 2);
    positionOffset = ct.cubeDim ./ 2;
    ct.x = ct.resolution.x*[0:ct.cubeDim(2)-1] - positionOffset(2);
    ct.y = ct.resolution.y*[0:ct.cubeDim(1)-1] - positionOffset(1);
    ct.z = ct.resolution.z*[0:ct.cubeDim(3)-1] - positionOffset(3);
end

%Since we are exporting HU directly --> no rescaling in any case
%meta.SliceThickness = ct.resolution.z;
%meta.PixelSpacing = [ct.resolution.y; ct.resolution.x];
%meta.ImageOrientationPatient = [1;0;0;0;1;0]; %lps

%meta.RescaleSlope = 1;
%meta.RescaleIntercept = 0;

obj.cst = matRad_computeVoiContoursWrapper(obj.cst,ct);

for i = 1:size(obj.cst,1)

    fprintf('Processinging VOI ''%s''...',obj.cst{i,2});
   %Select contours in axial slices
    contours        = obj.cst{i,7}(:,3);
    contourSliceIx  = find(~cellfun(@isempty,contours));
    contourSlicePos = ct.z(contourSliceIx);
    contours        = contours(contourSliceIx);

    % consider multiple contours of the same object
    for slice = 1:numel(contours)

       tmpContour = [];
       lower         = 1; % lower marks the beginning of a section
       cnt           = 0;

       while lower-1 ~= size(contours{slice,1},2)

          steps = contours{slice,1}(2,lower); % number of elements of current line section

          tmpContour(:,lower-cnt:lower-cnt+steps-1) = contours{slice,1}(:,lower+1:lower+steps);

          lower = lower+steps+1;
          cnt   = cnt + 1;
       end

       contours{slice,1} = tmpContour;

    end

    contours = cellfun(@(c) [ct.resolution.x; ct.resolution.y].* c + [ct.x(1) - ct.resolution.x;...
                             ct.y(1) - ct.resolution.y],contours,'UniformOutput',false);

    contours = cellfun(@(c,pos) addSlicePos(c,pos),contours,num2cell(contourSlicePos)','UniformOutput',false);
    %contours = cellfun(@transpose,contours,'UniformOutput',false);

    %Structure Definition
    ROISequenceItem.ROINumber = i;
    ROISequenceItem.ReferencedFrameOfReferenceUID = obj.FrameOfReferenceUID;
    ROISequenceItem.ROIName = obj.cst{i,2};
    ROISequenceItem.ROIGenerationAlgorithm = '';

    meta.StructureSetROISequence.(['Item_' num2str(i)]) = ROISequenceItem;

    %Contour Sequence
    if ~isOctave
        ROIContourSequenceItem.ROIDisplayColor = int32(round(255 * obj.cst{i,5}.visibleColor));
    end

    %Now create Contour subitems
    ContourSequence = struct;
    for c = 1:numel(contours)
        ContourItem = struct;

        %First store Image Sequence
        currCtSliceMeta = obj.ctSliceMetas(contourSliceIx(c));
        %currCtSliceMeta = matRad_DicomExporter.assignDefaultMetaValue(currCtSliceMeta,'SOPClassUID','1.2.840.10008.5.1.4.1.1.2');

        %Not sure about this
        ContourItem.ContourImageSequence.Item_1.ReferencedSOPClassUID = currCtSliceMeta.SOPClassUID; %We are referencing the CT
        ContourItem.ContourImageSequence.Item_1.ReferencedSOPInstanceUID = currCtSliceMeta.SOPInstanceUID; %TODO: ID of the respective ctSlice

        %Now remaing data
        ContourItem.ContourGeometricType = 'CLOSED_PLANAR';
        ContourItem.NumberOfContourPoints = size(contours{c},2);
        ContourItem.ContourData = contours{c}(:);

        %Now store Item
        ContourSequence.(['Item_' num2str(c)]) = ContourItem;
    end
    ROIContourSequenceItem.ContourSequence = ContourSequence;

    ROIContourSequenceItem.ReferencedROINumber = i;

    %Store to meta data
    meta.ROIContourSequence.(['Item_' num2str(i)]) = ROIContourSequenceItem;

    %RTROI Observation Sequence
    RTROIObservationsSequenceItem.ObservationNumber = i;
    RTROIObservationsSequenceItem.ReferencedROINumber = i;
    RTROIObservationsSequenceItem.ROIObservationLabel = obj.cst{i,2};

    if strcmp(obj.cst{i,3},'TARGET')
        if ~isempty(regexpi(obj.cst{i,2},['(' strjoin(obj.targetPtvDict) ')']))
            RTROIObservationsSequenceItem.RTROIInterpretedType = 'PTV';
            fprintf('identified target type as PTV...');
        elseif ~isempty(regexpi(obj.cst{i,2},['(' strjoin(obj.targetGtvDict) ')']))
            RTROIObservationsSequenceItem.RTROIInterpretedType = 'GTV';
            fprintf('identified target type as GTV...');
        elseif ~isempty(regexpi(obj.cst{i,2},['(' strjoin(obj.targetGtvDict) ')']))
            RTROIObservationsSequenceItem.RTROIInterpretedType = 'CTV';
            fprintf('identified target type as CTV...');
        else
            RTROIObservationsSequenceItem.RTROIInterpretedType = 'CTV';
            fprintf('Defaulting target type to CTV...');
        end
    else
        if ~isempty(regexpi(obj.cst{i,2},['(' strjoin(obj.externalContourDict) ')']))
            fprintf('automatically identified as External Contour...');
            RTROIObservationsSequenceItem.RTROIInterpretedType = 'EXTERNAL';
        else
            RTROIObservationsSequenceItem.RTROIInterpretedType = 'AVOIDANCE';
        end
    end

    RTROIObservationsSequenceItem.ROIInterpreter = obj.dicomName();

    meta.RTROIObservationsSequence.(['Item_' num2str(i)]) = RTROIObservationsSequenceItem;

    fprintf('Done!\n');
    %matRad_progress(i,size(obj.cst,1));
end

for i = 1:numel(obj.ctSliceMetas)
    ImageSequenceItem.ReferencedSOPClassUID = obj.ctSliceMetas(i).SOPClassUID;
    ImageSequenceItem.ReferencedSOPInstanceUID = obj.ctSliceMetas(i).SOPInstanceUID;
    ContourImageSequence.(['Item_' num2str(i)]) = ImageSequenceItem;
end

RTReferencedSeriesSequenceItem.SeriesInstanceUID = obj.ctSliceMetas(1).SeriesInstanceUID;
RTReferencedSeriesSequenceItem.ContourImageSequence = ContourImageSequence;

RTReferencedStudySequenceItem.ReferencedSOPClassUID = '1.2.840.10008.3.1.2.3.2'; %Apparently this class UID is deprecated in DICOM standard - what to use instead?
RTReferencedStudySequenceItem.ReferencedSOPInstanceUID = obj.StudyInstanceUID;
RTReferencedStudySequenceItem.RTReferencedSeriesSequence.Item_1 = RTReferencedSeriesSequenceItem;

meta.ReferencedFrameOfReferenceSequence.Item_1.FrameOfReferenceUID = obj.FrameOfReferenceUID;
meta.ReferencedFrameOfReferenceSequence.Item_1.RTReferencedStudySequence.Item_1 = RTReferencedStudySequenceItem;

filename = 'RTstruct.dcm';
filepath = obj.dicomDir;
filename = fullfile(filepath,filename);

if isOctave
	dicomwrite(int16(zeros(2)),filename,meta);
else
    obj.rtssExportStatus = dicomwrite([],filename,meta,'CreateMode','copy');%,'TransferSyntax',TransferSyntaxUID);
end

obj.rtssMeta = meta;
end

function c = addSlicePos(c,slicePos)
    nPoints  = size(c,2);
    slicePos = slicePos * ones(1,nPoints);
    c(3,:)   = slicePos;
end


function [err] = FigPrint (Opt, colopt)
%
%   mode 1:
%   [err] = FigPrint ([Opt])
%   mode 2:
%   [err] = FigPrint (h, [col])
%Purpose:
%   Prints the figure, or save to a file
%   Printing only works if you add the printer setup on your machine
%   in this file. I recommend you make your own copy of this function
%   should you choose to modify it.
%
%Input Parameters:
%   Usage mode 1:
%   Opt is an optional structure with the following optional fields
%      .Handle : Handle to the current figure to print.
%              Default is the current figure
%      .Color : Choose 'c' for color  printer
%                      'b' for bw (default)  printer
%      .Layout : Layout of the figure, choose from
%               'p' for portrait
%               'l' for landscape
%               't' for tall (print to fit)(default)
%      .GUI : flag (0/1) uses some special recommended settings to print GUIs
%             Default is 0
%      .Prompt : flag (0/1/2). Asks if you want to print the figure. Default is 0
%                 1 is command line prompt, 2 is GUI prompt
%      .PrintOpt : a string containing additional printing options such as
%                '-zbuffer -r200' for example, default is ''
%      .PaperPosition : a four element vector specifying the position
%               of the figure when printed on the page like
%               [0.25 0.25 4 6] (for [left bottom width height])
%               the units are inches
%Output options:
%    Paper:
%      .prndriver: One of MATLAB's built in drivers, like '-dpsc2',
%                  See help print
%      .prnname: Name of printer, something like '-P_128.231.212.205'
%                prndriver and prnname are set automatically
%                for recognized machines
%    TreeHugging:
%      .as: 'jpg', or 'pdf' , prints electronic instead of paper version
%      .prefix: prefix for electronic printout.
%
%    Usage mode 2:
%       h is the figure handle (h can be a vector of handles)
%       col is either 'b' for bw or 'c' for color
%
%Output Parameters:
%   err : 0 No Problem
%       : 1 Mucho Problems
%
%
%
%More Info :
%   print, printopt
%
%
%
%     Author : Ziad Saad
%     Date : Fri Jun 05 13:49:26 CDT 1998

%Define the function name for easy referencing
FuncName = 'FigPrint';

%initailize return variables
err = 1;

%Set up the default Options
OptDef.Handle = gcf;
OptDef.Color = 'b';
OptDef.Layout = 't';
OptDef.GUI = 0;
OptDef.Prompt = 0;
OptDef.PrintOpt = '';
OptDef.PaperPosition = [];
OptDef.as = [];
OptDef.prefix = 'FigPrint';
OptDef.prndriver = [];
OptDef.prnname = [];

%if nothing was passed
if (nargin == 0),
   Opt = OptDef;
else
   if (~isstruct(Opt)),
      h = Opt; Opt = []; Opt.Handle = h;
      if (nargin == 2),
         Opt.Color = colopt;
      end
   end
   if (~isfield(Opt,'Handle') | isempty (Opt.Handle)),   Opt.Handle = OptDef.Handle;   end
   if (~isfield(Opt,'Color') | isempty (Opt.Color)),   Opt.Color = OptDef.Color;   end
   if (~isfield(Opt,'Layout') | isempty (Opt.Layout)),   Opt.Layout = OptDef.Layout;   end
   if (~isfield(Opt,'GUI') | isempty (Opt.GUI)),   Opt.GUI = OptDef.GUI;   end
   if (~isfield(Opt,'Prompt') | isempty (Opt.Prompt)),   Opt.Prompt = OptDef.Prompt;   end
   if (~isfield(Opt,'PrintOpt') | isempty (Opt.PrintOpt)),   Opt.PrintOpt = OptDef.PrintOpt;   end
   if (~isfield(Opt,'PaperPosition') | isempty (Opt.PaperPosition)),   Opt.PaperPosition = []; end
   if (~isfield(Opt,'as') | isempty (Opt.as)),   Opt.as = []; end
   if (~isfield(Opt,'prefix') | isempty (Opt.prefix)),
      Opt.prefix = 'FigPrint';
   end
   if (~isfield(Opt,'prnname')),   Opt.prnname = []; end
   if (~isfield(Opt,'prndriver')),   Opt.prndriver = []; end
end

for (kk=1:1:length(Opt.Handle)),
   figh = Opt.Handle(kk);

   if (Opt.Prompt == 1),
      figure (figh);
      s = input ('Print figure (y/n) ?','s');
      if (isempty(s) | s ~= 'y'), err = 0; return;   end
   elseif (Opt.Prompt == 2),
      figure (figh);
      Butt = questdlg(sprintf('Print figure %d?', figh), 'Print Figure', 'Yes', 'No', 'No');
      switch Butt,
         case 'No',
            err = 0;
            return;
      end
   end

   %Now form the command line
      %The handle
      Hndl = sprintf('-f%g',figh);

      %The layout
      if (Opt.Layout == 'p'),
        orient(figh, 'portrait');
      elseif (Opt.Layout == 'l'),
        orient(figh, 'landscape');
      elseif (Opt.Layout == 't'),
        orient(figh, 'tall');
      else
        fprintf (2,'%s: Wrong layout specification\n\a', mfilename);
        err = 1;
        return;
      end

      %The colors
      [e,mc] = unix('hostname -s'); ilt = find(isletter(mc)); mc = mc(ilt);
      if (isempty(Opt.prnname) | isempty(Opt.prndriver)),
         switch mc,
         case 'rhodium',
            if (Opt.Color == 'b')
              prnname = '-Plp';
              prndriver = '-dps2';
            elseif (Opt.Color == 'c')
              prnname = '-Plpc';
              prndriver = '-dpsc2';
            else
              fprintf (2,'%s: Wrong printer (Color) specification\n\a', mfilename);
              err = 1;
              return;
            end
         case 'eomer',
            if (Opt.Color == 'b')
              prnname = '-P_128.231.212.205';
              prndriver = '-dps2';
            elseif (Opt.Color == 'c')
              prnname = '-PPhaser_8550DT__00_00_aa_9b_d2_6b_';
              prndriver = '-dpsc2';
            else
              fprintf (2,'%s: Wrong printer (Color) specification\n\a', mfilename);
              err = 1;
              return;
            end
         case 'iodine',
            if (Opt.Color == 'b')
              prnname = '-PHP8100DN';
              prndriver = '-dps2';
            elseif (Opt.Color == 'c')
              prnname = '-PTek';
              prndriver = '-dpsc2';
            else
              fprintf (2,'%s: Wrong printer (Color) specification\n\a', mfilename);
              err = 1;
              return;
            end
         otherwise,
            fprintf (2,'%s: Machine %s not recognized.\n\a',mfilename , mc);
            err = 1;
            return
         end
      else
         prnname = Opt.prnname;
         prndriver = Opt.prndriver;
      end
      %The GUI settings
      if (Opt.GUI),
         set(figh,'PaperPositionMode','auto');
         set(figh,'InvertHardcopy','off');
      end

      %the size settings
      if (~isempty(Opt.PaperPosition)),
         set(figh,'PaperUnits','inches');
         set(figh,'PaperPosition', Opt.PaperPosition);
      end

      if (isempty(Opt.as)),
            CmndLine = sprintf ('print %s %s %s %s',prndriver, Opt.PrintOpt, prnname, Hndl);

       else
         if (length(Opt.Handle) > 1),
            CmndLine = sprintf ('saveas(%d, ''%s'' ,''%s'')', ...
               figh, sprintf('%s.%02d.%s', Opt.prefix, kk, Opt.as), Opt.as);
         else,
            CmndLine = sprintf ('saveas(%d, ''%s'' ,''%s'')', ...
               figh, sprintf('%s.%s', Opt.prefix, Opt.as), Opt.as);
         end
       end
       fprintf (1,'%s verbose : Executing %s ...\n',FuncName,CmndLine);

       eval([CmndLine]);
   end

   err = 0;
   return;


clear;
options.J = 1;
options.M = 2;
options.L = 3;

field_list = {'J', 'M', 'aa'};

%%
options2 = sub_options(options, field_list);


%FEACHECKMEX Check/test for valid mex file usage.
%
%   [ TF ] = FEACHECKMEX( MEX_FILE, ...ARGS ) Check/test for valid mex
%   file usage. MEX_FILE is an optional mex file to check/test against
%   (default chkmex/ftsparse), and ARGS optional input arguments in
%   test tex function call.

% Copyright 2013-2022 Precise Simulation, Ltd.


function title = p03_title ( )

%*****************************************************************************80
%
%% P03_TITLE returns the title of problem p03.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 August 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, the title of the problem.
%
  title = 'Corner Peak';

  return
end


function varargout = lu(varargin)
%LU   LU factorization of a SPHEREFUN.
%
%   This is not allowed and returns an error.  This function exists so that
%   the error message is meaningful to a SPHEREFUN user.

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

error('CHEBFUN:SPHEREFUN:CUMPROD:notSupported',...
        'LU factorization of a SPHEREFUN is not supported.');

end


function slshow()
    % slshow slide show of images in a directory
    % now essentially self-contained.
    % - CGR

    report_this_filefun();
    setup_slideshow();
end

function setup_slideshow()
    hodi = ZmapGlobal.Data.hodi;
    file_extensions = {'jpg','png','bmp','gif'};
    slides = dir('this will be an empty anwser');
    for n=1:numel(file_extensions)
        slides = [slides; dir(fullfile(hodi, 'resrc','slides', ['*.', file_extensions{n}]))];  %#ok<AGROW>
    end

    fn = fullfile(slides(1).folder,{slides.name});
    slides = sort(fn);

    % set up slide viewer

    fsl = figure_w_normalized_uicontrolunits('Menubar','none','NumberTitle','off');
    viewport = axes('pos',[0 0 1 1]);axis off; axis ij

    userdata.slides = slides;
    userdata.idx = 0;
    userdata.ga = viewport;

    uicontrol(fsl,...
        'Units','normalized',...
        'Callback',@(s,e)close(fsl),...
        'String','Close',...
        'BackgroundColor' ,[0.8 0.8 0.8],...
        'Position',[0.90 0.01 0.10 0.06]);

    next_button = uicontrol(fsl,...
        'Units','normalized',...
        'Callback',@next_slide,...
        'String','Next ',...
        'BackgroundColor' ,[0.8 0.8 0.8],...
        'Position',[0.90 0.12 0.10 0.06],...
        'UserData', userdata);
    next_slide(next_button,[]);
end

function next_slide(s, ~)
    s.UserData.idx = s.UserData.idx + 1;
    if s.UserData.idx > numel(s.UserData.slides)
        s.UserData.idx = 1;
    end
    this_slide_info = s.UserData.slides{s.UserData.idx};
    try
        [x,~] = imread(this_slide_info);
    catch ME
        error_handler(ME, @do_nothing)
    end

    image(s.UserData.ga, x);
    drawnow
end


classdef nme_gizmo_acp < mp.nme_gizmo_ac & mp.form_acp

%   MATPOWER
%   Copyright (c) 2019-2020, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%     properties
%     end     %% properties

%     methods
%     end     %% methods
end         %% classdef


function [image_type, principal_filename, secondary_filenames] = MimGuessFileType(file_path, image_filename, default_guess, reporting)
    % MimGuessFileType. Heuristically determines a file format
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, Copyright Tom Doel 2014.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    [~, name, ext] = fileparts(image_filename);
    image_filename_without_extension = fullfile(file_path, name);
    if strcmp(ext, '.mat')
        image_type = MimImageFileFormat.Matlab;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.gipl')
        image_type = MimImageFileFormat.Gipl;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.hdr')
        image_type = MimImageFileFormat.Analyze;
        principal_filename = {image_filename};
        secondary_filenames = {};
        if CoreDiskUtilities.FileExists(file_path, [name '.img'])
            secondary_filenames = [image_filename_without_extension '.img'];
        end
        return;

    elseif strcmp(ext, '.nii')
        image_type = MimImageFileFormat.Nifti;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.img')
        hdr_filename = [name '.hdr'];
        nii_filename = [name '.nii'];
        if CoreDiskUtilities.FileExists(file_path, nii_filename)
            image_type = MimImageFileFormat.Nifti;
            principal_filename = {nii_filename};
            secondary_filenames = {image_filename};
            return;
        elseif CoreDiskUtilities.FileExists(file_path, hdr_filename)
            image_type = MimImageFileFormat.Analyze;
            principal_filename = {hdr_filename};
            secondary_filenames = {image_filename};
            return;
        end

    elseif strcmp(ext, '.isi')
        image_type = MimImageFileFormat.Isi;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.v3d')
        image_type = MimImageFileFormat.V3d;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.vmp')
        image_type = MimImageFileFormat.Vmp;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.xif')
        image_type = MimImageFileFormat.Xif;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.vtk')
        image_type = MimImageFileFormat.Vtk;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.vff')
        image_type = MimImageFileFormat.MicroCT;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;

    elseif strcmp(ext, '.par') || strcmp(ext, '.rec')
        image_type = MimImageFileFormat.Par;
        par_filename = {[name '.par']};
        rec_filename = {[name '.rec']};
        par_found = CoreDiskUtilities.FileExists(file_path, par_filename);
        rec_found = CoreDiskUtilities.FileExists(file_path, rec_filename);
        if par_found
            if rec_found
                principal_filename = {par_filename};
                secondary_filenames = {fullfile(file_path, rec_filename)};
                return;
            else
                principal_filename = {par_filename};
                secondary_filenames = {};
                return;
            end
        else
            if rec_found
                principal_filename = {rec_filename};
                secondary_filenames = {};
                return;
            end
        end

    % For metaheader files (mhd/mha) we also fetch the filename of the
    % raw image data
    elseif strcmp(ext, '.mhd') || strcmp(ext, '.mha')
        image_type = MimImageFileFormat.Metaheader;
        [is_meta_header, raw_filename] = MimDiskUtilities.IsFileMetaHeader(fullfile(file_path, image_filename), reporting);
        if ~is_meta_header
            reporting.Error('MimGuessFileType:OpenMHDFileFailed', ['Unable to read metaheader file ' image_filename]);
        end
        principal_filename = {image_filename};
        secondary_filenames = {raw_filename}; % ToDo: what if no secondary file?
        return;

    % If a .raw file is selected, look for the corresponding .mha or
    % .mhd file. We thrown an exception if no file is found, it cannot
    % be loaded or the raw filename does not match the raw file we are
    % loading
    elseif strcmp(ext, '.raw')
        [principal_filename, secondary_filenames] = MimDiskUtilities.GetHeaderFileFromRawFile(file_path, name, reporting);
        if isempty(principal_filename)
            reporting.ShowWarning('MimGuessFileType:HeaderFileLoadError', ['Unable to find valid header file for ' fullfile(file_path, image_filename)], []);
        else
            if ~strcmp(secondary_filenames{1}, image_filename)
                reporting.Error('MimGuessFileType:MetaHeaderRawFileMismatch', ['Mismatch between specified image filename and entry in ' principal_filename{1}]);
            end
            image_type = MimImageFileFormat.Metaheader;
            return;
        end
    end

    % Unknown file type. Try looking for a header file
    [principal_filename_mh, secondary_filenames_mh] = MimDiskUtilities.GetHeaderFileFromRawFile(file_path, name, reporting);
    if (~isempty(principal_filename_mh)) && (strcmp(secondary_filenames_mh{1}, image_filename))
        image_type = MimImageFileFormat.Metaheader;
        principal_filename = principal_filename_mh;
        secondary_filenames = secondary_filenames_mh;
        return;
    end

    % Test for a DICOM image
    if DMUtilities.IsDicom(file_path, image_filename)
        image_type = MimImageFileFormat.Dicom;
        principal_filename = {image_filename};
        secondary_filenames = {};
        return;
    end

    % If all else fails, use the guess
    image_type = default_guess;
    principal_filename = {image_filename};
    secondary_filenames = {};
end