function [net,stats] = cnn_train_dag(net, imdb, getBatch, varargin)
%CNN_TRAIN_DAG Demonstrates training a CNN using the DagNN wrapper
%    CNN_TRAIN_DAG() is similar to CNN_TRAIN(), but works with
%    the DagNN wrapper instead of the SimpleNN wrapper.

% Copyright (C) 2014-16 Andrea Vedaldi.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).
addpath(fullfile(vl_rootnn, 'examples'));

opts.expDir = fullfile('data','exp') ;
opts.continue = true ;
opts.batchSize = 256 ;
opts.numSubBatches = 1 ;
opts.train = [] ;
opts.val = [] ;
opts.gpus = [] ;
opts.prefetch = false ;
opts.epochSize = inf;
opts.numEpochs = 300 ;
opts.learningRate = 0.001 ;
opts.weightDecay = 0.0005 ;

opts.solver = [] ;  % Empty array means use the default SGD solver
[opts, varargin] = vl_argparse(opts, varargin) ;
if ~isempty(opts.solver)
  assert(isa(opts.solver, 'function_handle') && nargout(opts.solver) == 2,...
    'Invalid solver; expected a function handle with two outputs.') ;
  % Call without input arguments, to get default options
  opts.solverOpts = opts.solver() ;
end

opts.momentum = 0.9 ;
opts.saveSolverState = true ;
opts.nesterovUpdate = false ;
opts.randomSeed = 0 ;
opts.profile = false ;
opts.parameterServer.method = 'mmap' ;
opts.parameterServer.prefix = 'mcn' ;

opts.derOutputs = {'objective', 1} ;
opts.extractStatsFn = @extractStats ;
opts.plotStatistics = true;
opts.postEpochFn = [] ;  % postEpochFn(net,params,state) called after each epoch; can return a new learning rate, 0 to stop, [] for no change
opts = vl_argparse(opts, varargin) ;

if ~exist(opts.expDir, 'dir'), mkdir(opts.expDir) ; end
if isempty(opts.train), opts.train = find(imdb.images.set==1) ; end
if isempty(opts.val), opts.val = find(imdb.images.set==2) ; end
if isscalar(opts.train) && isnumeric(opts.train) && isnan(opts.train)
  opts.train = [] ;
end
if isscalar(opts.val) && isnumeric(opts.val) && isnan(opts.val)
  opts.val = [] ;
end

% -------------------------------------------------------------------------
%                                                            Initialization
% -------------------------------------------------------------------------

evaluateMode = isempty(opts.train) ;
if ~evaluateMode
  if isempty(opts.derOutputs)
    error('DEROUTPUTS must be specified when training.\n') ;
  end
end

% -------------------------------------------------------------------------
%                                                        Train and validate
% -------------------------------------------------------------------------

modelPath = @(ep) fullfile(opts.expDir, sprintf('net-epoch-%d.mat', ep));
modelFigPath = fullfile(opts.expDir, 'net-train.pdf') ;

start = opts.continue * findLastCheckpoint(opts.expDir) ;
if start >= 1
  fprintf('%s: resuming by loading epoch %d\n', mfilename, start) ;
  [net, state, stats] = loadState(modelPath(start)) ;
else
  state = [] ;
end

for epoch=start+1:opts.numEpochs

  % Set the random seed based on the epoch and opts.randomSeed.
  % This is important for reproducibility, including when training
  % is restarted from a checkpoint.

  rng(epoch + opts.randomSeed) ;
  prepareGPUs(opts, epoch == start+1) ;

  % Train for one epoch.
  params = opts ;
  params.epoch = epoch ;
  params.learningRate = opts.learningRate(min(epoch, numel(opts.learningRate))) ;
  params.train = opts.train(randperm(numel(opts.train))) ; % shuffle
  params.train = params.train(1:min(opts.epochSize, numel(opts.train)));
  params.val = opts.val(randperm(numel(opts.val))) ;
  params.imdb = imdb ;
  params.getBatch = getBatch ;

  if numel(opts.gpus) <= 1
    [net, state] = processEpoch(net, state, params, 'train') ;
    [net, state] = processEpoch(net, state, params, 'val') ;
    if ~evaluateMode
      saveState(modelPath(epoch), net, state) ;
    end
    lastStats = state.stats ;
  else
    spmd
      [net, state] = processEpoch(net, state, params, 'train') ;
      [net, state] = processEpoch(net, state, params, 'val') ;
      if labindex == 1 && ~evaluateMode
        saveState(modelPath(epoch), net, state) ;
      end
      lastStats = state.stats ;
    end
    lastStats = accumulateStats(lastStats) ;
  end

  stats.train(epoch) = lastStats.train ;
  stats.val(epoch) = lastStats.val ;
  clear lastStats ;
  saveStats(modelPath(epoch), stats) ;

  if opts.plotStatistics
    switchFigure(1) ; clf ;
    plots = setdiff(...
      cat(2,...
      fieldnames(stats.train)', ...
      fieldnames(stats.val)'), {'num', 'time'}) ;
    for p = plots
      p = char(p) ;
      values = zeros(0, epoch) ;
      leg = {} ;
      for f = {'train', 'val'}
        f = char(f) ;
        if isfield(stats.(f), p)
          tmp = [stats.(f).(p)] ;
          values(end+1,:) = tmp(1,:)' ;
          leg{end+1} = f ;
        end
      end
      subplot(1,numel(plots),find(strcmp(p,plots))) ;
      plot(1:epoch, values','o-') ;
      xlabel('epoch') ;
      title(p) ;
      legend(leg{:}) ;
      grid on ;
    end
    drawnow ;
    print(1, modelFigPath, '-dpdf') ;
  end

  if ~isempty(opts.postEpochFn)
    if nargout(opts.postEpochFn) == 0
      opts.postEpochFn(net, params, state) ;
    else
      lr = opts.postEpochFn(net, params, state) ;
      if ~isempty(lr), opts.learningRate = lr; end
      if opts.learningRate == 0, break; end
    end
  end
end

% With multiple GPUs, return one copy
if isa(net, 'Composite'), net = net{1} ; end

% -------------------------------------------------------------------------
function [net, state] = processEpoch(net, state, params, mode)
% -------------------------------------------------------------------------
% Note that net is not strictly needed as an output argument as net
% is a handle class. However, this fixes some aliasing issue in the
% spmd caller.

% initialize with momentum 0
if isempty(state) || isempty(state.solverState)
  state.solverState = cell(1, numel(net.params)) ;
  state.solverState(:) = {0} ;
end

% move CNN  to GPU as needed
numGpus = numel(params.gpus) ;
if numGpus >= 1
  net.move('gpu') ;
  for i = 1:numel(state.solverState)
    s = state.solverState{i} ;
    if isnumeric(s)
      state.solverState{i} = gpuArray(s) ;
    elseif isstruct(s)
      state.solverState{i} = structfun(@gpuArray, s, 'UniformOutput', false) ;
    end
  end
end
if numGpus > 1
  parserv = ParameterServer(params.parameterServer) ;
  net.setParameterServer(parserv) ;
else
  parserv = [] ;
end

% profile
if params.profile
  if numGpus <= 1
    profile clear ;
    profile on ;
  else
    mpiprofile reset ;
    mpiprofile on ;
  end
end

num = 0 ;
epoch = params.epoch ;
subset = params.(mode) ;
adjustTime = 0 ;

stats.num = 0 ; % return something even if subset = []
stats.time = 0 ;

start = tic ;
for t=1:params.batchSize:numel(subset)
  fprintf('%s: epoch %02d: %3d/%3d:', mode, epoch, ...
          fix((t-1)/params.batchSize)+1, ceil(numel(subset)/params.batchSize)) ;
  batchSize = min(params.batchSize, numel(subset) - t + 1) ;

  for s=1:params.numSubBatches
    % get this image batch and prefetch the next
    batchStart = t + (labindex-1) + (s-1) * numlabs ;
    batchEnd = min(t+params.batchSize-1, numel(subset)) ;
    batch = subset(batchStart : params.numSubBatches * numlabs : batchEnd) ;
    num = num + numel(batch) ;
    if numel(batch) == 0, continue ; end

    inputs = params.getBatch(params.imdb, batch) ;

    if params.prefetch
      if s == params.numSubBatches
        batchStart = t + (labindex-1) + params.batchSize ;
        batchEnd = min(t+2*params.batchSize-1, numel(subset)) ;
      else
        batchStart = batchStart + numlabs ;
      end
      nextBatch = subset(batchStart : params.numSubBatches * numlabs : batchEnd) ;
      params.getBatch(params.imdb, nextBatch) ;
    end

    if strcmp(mode, 'train')
      net.mode = 'normal' ;
      net.accumulateParamDers = (s ~= 1) ;
      net.eval(inputs, params.derOutputs, 'holdOn', s < params.numSubBatches) ;
    else
      net.mode = 'test' ;
      net.eval(inputs) ;
    end
  end

  % Accumulate gradient.
  if strcmp(mode, 'train')
    if ~isempty(parserv), parserv.sync() ; end
    state = accumulateGradients(net, state, params, batchSize, parserv) ;
  end

  % Get statistics.
  time = toc(start) + adjustTime ;
  batchTime = time - stats.time ;
  stats.num = num ;
  stats.time = time ;
  stats = params.extractStatsFn(stats,net) ;
  currentSpeed = batchSize / batchTime ;
  averageSpeed = (t + batchSize - 1) / time ;
  if t == 3*params.batchSize + 1
    % compensate for the first three iterations, which are outliers
    adjustTime = 4*batchTime - time ;
    stats.time = time + adjustTime ;
  end

  fprintf(' %.1f (%.1f) Hz', averageSpeed, currentSpeed) ;
  for f = setdiff(fieldnames(stats)', {'num', 'time'})
    f = char(f) ;
    fprintf(' %s: %.3f', f, stats.(f)) ;
  end
  fprintf('\n') ;
end

% Save back to state.
state.stats.(mode) = stats ;
if params.profile
  if numGpus <= 1
    state.prof.(mode) = profile('info') ;
    profile off ;
  else
    state.prof.(mode) = mpiprofile('info');
    mpiprofile off ;
  end
end
if ~params.saveSolverState
  state.solverState = [] ;
else
  for i = 1:numel(state.solverState)
    s = state.solverState{i} ;
    if isnumeric(s)
      state.solverState{i} = gather(s) ;
    elseif isstruct(s)
      state.solverState{i} = structfun(@gather, s, 'UniformOutput', false) ;
    end
  end
end

net.reset() ;
net.move('cpu') ;

% -------------------------------------------------------------------------
function state = accumulateGradients(net, state, params, batchSize, parserv)
% -------------------------------------------------------------------------
numGpus = numel(params.gpus) ;
otherGpus = setdiff(1:numGpus, labindex) ;

for p=1:numel(net.params)

  if ~isempty(parserv)
    parDer = parserv.pullWithIndex(p) ;
  else
    parDer = net.params(p).der ;
  end

  switch net.params(p).trainMethod

    case 'average' % mainly for batch normalization
      thisLR = net.params(p).learningRate ;
      net.params(p).value = vl_taccum(...
          1 - thisLR, net.params(p).value, ...
          (thisLR/batchSize/net.params(p).fanout),  parDer) ;

    case 'gradient'
      thisDecay = params.weightDecay * net.params(p).weightDecay ;
      thisLR = params.learningRate * net.params(p).learningRate ;

      if thisLR>0 || thisDecay>0
        % Normalize gradient and incorporate weight decay.
        parDer = vl_taccum(1/batchSize, parDer, ...
                           thisDecay, net.params(p).value) ;

        if isempty(params.solver)
          % Default solver is the optimised SGD.
          % Update momentum.
          state.solverState{p} = vl_taccum(...
            params.momentum, state.solverState{p}, ...
            -1, parDer) ;

          % Nesterov update (aka one step ahead).
          if params.nesterovUpdate
            delta = params.momentum * state.solverState{p} - parDer ;
          else
            delta = state.solverState{p} ;
          end

          % Update parameters.
          net.params(p).value = vl_taccum(...
            1,  net.params(p).value, thisLR, delta) ;

        else
          % call solver function to update weights
          [net.params(p).value, state.solverState{p}] = ...
            params.solver(net.params(p).value, state.solverState{p}, ...
            parDer, params.solverOpts, thisLR) ;
        end
      end
    otherwise
      error('Unknown training method ''%s'' for parameter ''%s''.', ...
        net.params(p).trainMethod, ...
        net.params(p).name) ;
  end
end

% -------------------------------------------------------------------------
function stats = accumulateStats(stats_)
% -------------------------------------------------------------------------

for s = {'train', 'val'}
  s = char(s) ;
  total = 0 ;

  % initialize stats stucture with same fields and same order as
  % stats_{1}
  stats__ = stats_{1} ;
  names = fieldnames(stats__.(s))' ;
  values = zeros(1, numel(names)) ;
  fields = cat(1, names, num2cell(values)) ;
  stats.(s) = struct(fields{:}) ;

  for g = 1:numel(stats_)
    stats__ = stats_{g} ;
    num__ = stats__.(s).num ;
    total = total + num__ ;

    for f = setdiff(fieldnames(stats__.(s))', 'num')
      f = char(f) ;
      stats.(s).(f) = stats.(s).(f) + stats__.(s).(f) * num__ ;

      if g == numel(stats_)
        stats.(s).(f) = stats.(s).(f) / total ;
      end
    end
  end
  stats.(s).num = total ;
end

% -------------------------------------------------------------------------
function stats = extractStats(stats, net)
% -------------------------------------------------------------------------
sel = find(cellfun(@(x) isa(x,'dagnn.Loss'), {net.layers.block})) ;
for i = 1:numel(sel)
  if net.layers(sel(i)).block.ignoreAverage, continue; end;
  stats.(net.layers(sel(i)).outputs{1}) = net.layers(sel(i)).block.average ;
end

% -------------------------------------------------------------------------
function saveState(fileName, net_, state)
% -------------------------------------------------------------------------
net = net_.saveobj() ;
save(fileName, 'net', 'state') ;

% -------------------------------------------------------------------------
function saveStats(fileName, stats)
% -------------------------------------------------------------------------
if exist(fileName)
  save(fileName, 'stats', '-append') ;
else
  save(fileName, 'stats') ;
end

% -------------------------------------------------------------------------
function [net, state, stats] = loadState(fileName)
% -------------------------------------------------------------------------
load(fileName, 'net', 'state', 'stats') ;
net = dagnn.DagNN.loadobj(net) ;
if isempty(whos('stats'))
  error('Epoch ''%s'' was only partially saved. Delete this file and try again.', ...
        fileName) ;
end

% -------------------------------------------------------------------------
function epoch = findLastCheckpoint(modelDir)
% -------------------------------------------------------------------------
list = dir(fullfile(modelDir, 'net-epoch-*.mat')) ;
tokens = regexp({list.name}, 'net-epoch-([\d]+).mat', 'tokens') ;
epoch = cellfun(@(x) sscanf(x{1}{1}, '%d'), tokens) ;
epoch = max([epoch 0]) ;

% -------------------------------------------------------------------------
function switchFigure(n)
% -------------------------------------------------------------------------
if get(0,'CurrentFigure') ~= n
  try
    set(0,'CurrentFigure',n) ;
  catch
    figure(n) ;
  end
end

% -------------------------------------------------------------------------
function clearMex()
% -------------------------------------------------------------------------
clear vl_tmove vl_imreadjpeg ;

% -------------------------------------------------------------------------
function prepareGPUs(opts, cold)
% -------------------------------------------------------------------------
numGpus = numel(opts.gpus) ;
if numGpus > 1
  % check parallel pool integrity as it could have timed out
  pool = gcp('nocreate') ;
  if ~isempty(pool) && pool.NumWorkers ~= numGpus
    delete(pool) ;
  end
  pool = gcp('nocreate') ;
  if isempty(pool)
    parpool('local', numGpus) ;
    cold = true ;
  end

end
if numGpus >= 1 && cold
  fprintf('%s: resetting GPU\n', mfilename)
  clearMex() ;
  if numGpus == 1
    gpuDevice(opts.gpus)
  else
    spmd
      clearMex() ;
      gpuDevice(opts.gpus(labindex))
    end
  end
end


function [x,fval,exitflag,output,optimState,gpstruct] = fixedbads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options,fixidx,nout)
%FIXEDBADS Run BADS with reduced dimensionality due to fixed variables.

nvars = size(x0,2);

% Initialize outputs
fval = [];
exitflag = [];
output = [];
optimState = [];
gpstruct = [];

freeidx = ~fixidx;
fixedvars = LB(fixidx);

% Update periodic variables, if present in OPTIONS
if isfield(options,'PeriodicVars') && ~isempty(eval(options.PeriodicVars))
    pervars = false(1,nvars);
    pervars(eval(options.PeriodicVars)) = true;
    pervars(fixidx) = [];
    options.PeriodicVars = find(pervars);
end

% Fix input FUNVALUES, if present
if isfield(options,'FunValues') && ~isempty(options.FunValues) && ...
        isfield(options.FunValues,'X') && ~isempty(options.FunValues.X)
    options.FunValues.X = options.FunValues.X(:,freeidx);
end

% Downlift
x0 = x0(freeidx);
LB = LB(freeidx);
UB = UB(freeidx);
PLB = PLB(freeidx);
PUB = PUB(freeidx);

switch nout
    case 1
        x_free = bads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options);
    case 2
        [x_free,fval] = bads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options);
    case 3
        [x_free,fval,exitflag] = bads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options);
    case 4
        [x_free,fval,exitflag,output] = bads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options);
    case 5
        [x_free,fval,exitflag,output,optimState] = bads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options);
    case 6
        [x_free,fval,exitflag,output,optimState,gpstruct] = bads(fun_fix,x0,LB,UB,PLB,PUB,nonbcon_fix,options);
end

% Uplift solution
x = zeros(1,nvars);
x(freeidx) = x_free;
x(fixidx) = fixedvars;

if nout > 4
    % Uplift points in OPTIMSTATE
    nx = size(optimState.X,1);
    Xtemp = zeros(nx,nvars);
    Xtemp(:,freeidx) = optimState.X;
    Xtemp(:,fixidx) = repmat(fixedvars, [nx 1]);
    optimState.X = Xtemp;
end

end


function h=huniform(p,varargin)

%   Copyright (C) 2004-2006 Per-Olof Persson. See COPYRIGHT.TXT for details.

h=ones(size(p,1),1);


function varargout = subsref(this, S)
% Allows subscript referencing with dot notation of dimLabels
%
%   Y = MrDimInfo()
%   Y.subsref(S)
%
% This is a method of class MrDimInfo.
% It checks whether the provided S(1).subs is
%   a) a valid dimLabel and returns the reduced MrDimInfo for this dimension (via get_dims(dimLabel)).
%       e.g. dimInfo.z.samplingPoints
%   b) a valid property of MrDimInfo and S(2).subs a valid dimLabel, which
%       is transformed into a dim-index to allow referencing
%       e.g. dimInfo.nSamples('z')
% For anything but these first-level dot notations, it uses the builtin subsref.
%
% IN
%   S   structure with two fields:
%           type is a char vector containing '()', '{}', or '.', indicating the type of indexing used.
%           NOTE: we only overload the dot notation here to index dimLabels
%           subs is a cell array or character array containing the actual subscripts.% OUT
%
% EXAMPLE
%   This enables the usage of dimLabels in the dot notation, e.g.
%
%   dimInfo = MrDimInfo('dimLabels', {'x', 'y', 'z'},
%                       'samplingPoints', {1:10, -10:-1, 5:14});
%   dimInfo.z.samplingPoints
%       => ans =
%      5     6     7     8     9    10    11    12    13    14
%
%   dimInfo.nSamples('z');
%
%   See also MrDimInfo builtin.subsref

% Author:   Lars Kasper & Saskia Bollmann
% Created:  2017-06-28
% Copyright (C) 2017 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 License (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/>.

switch S(1).type
    case '.'
        % do custom dot-referencing  for valid dimLabels (e.g. dimInfo.x etc)
        if ismember(S(1).subs, this.dimLabels)

            if numel(S) == 1 % return reduced dimInfo object
                varargout = {this.get_dims(S(1).subs)};
            else
                % retrieve reduced dimInfo and continue with classical subsref
                % from there
                varargout = {builtin('subsref',this.get_dims(S(1).subs),S(2:end))};
            end
        elseif ismember(S(1).subs, properties(this)) && numel(S) > 1 && numel(S(2).subs) == 1
                % do custom dot-referencing allowing for property(dimLabel), e.g. resolutions('x')
                % by converting char/cell indices to numerical ones and run normal
                % subsref
                % note: allows only 1D indexing, i.e. not for ranges(:, 1:2)
                S(2).subs = {this.get_dim_index(S(2).subs{:})};
                varargout = {builtin('subsref',this,S)};
        elseif ismember(S(1).subs, methods(this))
            % a method call in dot notation, e.g. dimInfo.select() shall be
            % treated correctly, even for variable number of output
            % arguments
            if nargout
                [varargout{1:nargout}] = builtin('subsref',this,S);
            else
                varargout = {builtin('subsref',this,S)};
            end
        else % hope for the best
                varargout = {builtin('subsref',this,S)};
        end
    case '()' % allow to retrieve dimInfo('x'), dimInfo({'x','y'}), dimInfo(1:3)
        % for valid dimension labels/ indices
        sub = S(1).subs{:};
        isValidDimLabel = (ischar(sub) || iscellstr(sub)) && all(ismember(sub, this.dimLabels));
        % dimIndices have to be integer and within range of validdimensions
        isValidDimIndex = isnumeric(sub) && isequal(fix(sub),sub) ...
            && all(sub >=1) && all(sub <= this.nDims);
        if isValidDimLabel || isValidDimIndex
            varargout = {this.get_dims(S(1).subs{:})};
        else
            % use builtin indexing and hope for the best
            varargout = {builtin('subsref',this,S)};
        end
    otherwise
        % use builtin indexing for Y{i,j}
        varargout = {builtin('subsref',this,S)};
end


function [overlaps] = cat_overlap(varargin)
%%%%%%%%%%%%%%%%%%%%%%%%%%% concatenate overlap %%%%%%%%%%%%%%%%%%%%%%%%%%%
% Allows daisy-chaining of multiple registers2p regi variables. NB all must
% have been registered to the same time-point 1.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Inputs:
% -------
% - none: opens a file selection gui, select multiple regi variables

% - cell-array of strings: each cell contains the full file-path to a regi
% variable

% - structure: multiple regi variables saved into one structure with
% fields .rois, .targets and .dat (and their corresponding sub-fields)

% Output:
% -------
% - overlaps.fnames: cell array where each cell contains the name of an
% F...proc.mat file containing the ROIs from which the correspondingly
% indexed columns in the below fields are drawn (i.e. overlaps.fnames{1}
% gives the filename for overlaps.rois.idcs(:,1))

% - overlaps.rois.idcs: n * m matrix where n = number of overlapping ROIs
% and m = timepoints. Each element of a given column can be directly
% indexed into the variables Fcell & FcellNeu of the F...proc.mat file
% dictated by the corresponding cell in overlaps.fnames (see above).

% - overlaps.rois.iscell_idcs: same as overlaps.rois.idcs except these
% indices correspond to the non-zero elements of the iscell classifier. To
% index into Fcell & FcellNeu do:
%       nn_idcs = find(iscell);
%       Fcell(nn_idcs(overlaps.rois.iscell_idcs(:,1)))

% - overlaps.targets.idcs: n * m matrix where n = number of targets user
% imported to registers2p and m = timepoints. Elements are either NaN if
% target didn't overlap with a suite2P ROI, or else the index of the
% overlapping ROI in Fcell & Fcell Neu of F...proc.mat file dictated by the
% corresponding cell in overlaps.fnames (see above).

% - overlaps.targets.iscell_idcs: Same as overlaps.targets.idcs except
% non-NaN elements are indices of non-zero elements of the iscell
% classifier (see overlaps.rois.iscell_idcs for an example of how to index
% this into Fcell & FcellNeu).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
overlaps = [];
f = {};
d = {};
if ~isempty(varargin)
    if iscell(varargin{1})
        if ischar(varargin{1}{1})
            in = varargin{1};
        end
        for i = 1:numel(in)
            [d{i},ff,ee] = fileparts(in{i});
            f{i} = [ff ee];
        end
    elseif isstruct(varargin{1})
        f = varargin{1};
    end
else
    [f,in] = uigetfile('MultiSelect','on');
    if ~iscell(f)
        f = {f};
    end
    for i = 1:numel(f)
        d{i} = in;
    end
end
if iscell(f)
    rois_idcs = cell(numel(f),1);
    rois_iscell_idcs = rois_idcs;
    targets_idcs = rois_idcs;
    targets_iscell_idcs = rois_idcs;
    overlaps.fname = cell(numel(f)+1,1);
    for i = 1:numel(f)
        load([d{i} filesep f{i}])
        rois_idcs{i} = regi.rois.idcs;
        rois_iscell_idcs{i} = regi.rois.iscell_idcs;
        targets_idcs{i} = regi.targets.idcs;
        targets_iscell_idcs{i} = regi.targets.iscell_idcs;
        if i == 1
            [~,overlaps.fname{1}] = fileparts(regi.dat.files(1).filepath);
            [~,overlaps.fname{2}] = fileparts(regi.dat.files(2).filepath);
        else
            [~,overlaps.fname{i+1}] = fileparts(regi.dat.files(2).filepath);
        end
    end
    overlaps.rois.idcs = find_consistent_rois(rois_idcs);
    overlaps.rois.iscell_idcs = find_consistent_rois(rois_iscell_idcs);
    if max(cellfun('isempty',targets_idcs)) == 0
        overlaps.targets.idcs = [targets_idcs{1}(:,1) cell2mat(cellfun(@(x) x(:,2),targets_idcs,'UniformOutput',0)')];
        overlaps.targets.iscell_idcs = [targets_iscell_idcs{1}(:,1) cell2mat(cellfun(@(x) x(:,2),targets_iscell_idcs,'UniformOutput',0)')];
    else
        overlaps.targets.idcs = [];
        overlaps.targets.iscell_idcs = [];
    end
elseif isstruct(f)
    rois_idcs = cell(numel(f),1);
    rois_iscell_idcs = rois_idcs;
    targets_idcs = rois_idcs;
    targets_iscell_idcs = rois_idcs;
    overlaps.fname = cell(numel(f)+1,1);
    for i = 1:numel(f)
        rois_idcs{i} = f(i).rois.idcs;
        rois_iscell_idcs{i} = f(i).rois.iscell_idcs;
        targets_idcs{i} = f(i).targets.idcs;
        targets_iscell_idcs{i} = f(i).targets.iscell_idcs;
        if i == 1
            [~,overlaps.fname{1}] = fileparts(f(i).dat.files(1).filepath);
            [~,overlaps.fname{2}] = fileparts(f(i).dat.files(2).filepath);
        else
            [~,overlaps.fname{i+1}] = fileparts(f(i).dat.files(2).filepath);
        end
    end
    overlaps.rois.idcs = find_consistent_rois(rois_idcs);
    overlaps.rois.iscell_idcs = find_consistent_rois(rois_iscell_idcs);
    if max(cellfun('isempty',targets_idcs)) == 0
        overlaps.targets.idcs = [targets_idcs{1}(:,1) cell2mat(cellfun(@(x) x(:,2),targets_idcs,'UniformOutput',0)')];
        overlaps.targets.iscell_idcs = [targets_iscell_idcs{1}(:,1) cell2mat(cellfun(@(x) x(:,2),targets_iscell_idcs,'UniformOutput',0)')];
    else
        overlaps.targets.idcs = [];
        overlaps.targets.iscell_idcs = [];
    end
else
    warning('Import error - either provide no input and use file-selection gui or provide a cell-array of filepath strings')
end
end


function net = our_vl_simplenn_move(net, destination)
%VL_SIMPLENN_MOVE  Move a SimpleNN network between CPU and GPU.
%   NET = VL_SIMPLENN_MOVE(NET, 'gpu') moves the network to the
%   current GPU device. NET = VL_SIMPLENN_MOVE(NET, 'cpu') moves the
%   network to the CPU.
%
%   See also: VL_SIMPLENN().

% Copyright (C) 2014-15 Andrea Vedaldi.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

switch destination
  case 'gpu', moveop = @(x) gpuArray(x) ;
  case 'cpu', moveop = @(x) gather(x) ;
  otherwise, error('Unknown destination ''%s''.', destination) ;
end
for l=1:numel(net.layers)
  switch net.layers{l}.type
    case {'conv', 'convt', 'bnorm','conv_mask'}
      for f = {'filters', 'biases', 'filtersMomentum', 'biasesMomentum'}
        f = char(f) ;
        if isfield(net.layers{l}, f)
          net.layers{l}.(f) = moveop(net.layers{l}.(f)) ;
        end
      end
      for f = {'weights', 'momentum'}
        f = char(f) ;
        if isfield(net.layers{l}, f)
          for j=1:numel(net.layers{l}.(f))
            net.layers{l}.(f){j} = moveop(net.layers{l}.(f){j}) ;
          end
        end
      end
      if(strcmp(net.layers{l}.type,'conv_mask'))
          net.layers{l}.posTemp{1}=moveop(net.layers{l}.posTemp{1});
          net.layers{l}.posTemp{2}=moveop(net.layers{l}.posTemp{2});
      end
    otherwise
      % nothing to do ?
  end
end


%
% subcortical_labeling_table.m
%
% Original Author: Laurence Wastiaux
% CVS Revision Info:
%    $Author: nicks $
%    $Date: 2011/03/02 00:04:13 $
%    $Revision: 1.4 $
%
% Copyright © 2011 The General Hospital Corporation (Boston, MA) "MGH"
%
% Terms and conditions for use, reproduction, distribution and contribution
% are found in the 'FreeSurfer Software License Agreement' contained
% in the file 'LICENSE' found in the FreeSurfer distribution, and here:
%
% https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferSoftwareLicense
%
% Reporting: freesurfer@nmr.mgh.harvard.edu
%

[Dvolume,Ivol]=subcortical_labeling_dir_afd('/space/neo/2/recon/buckner', 0.01)
% load('/space/okapi/3/data/laurence/ADF/subcortical_labeling/Percent_Vol0517.mat') %loads Dvolume
% load('/space/okapi/3/data/laurence/ADF/subcortical_labeling/Subj_nb_Vol0517.mat') %loads Ivol
files=dir('/space/neo/2/recon/buckner');
fp=fopen('~/subcortlab_table.txt', 'w');
sz=size(Dvolume);
fprintf(fp,'# FSAFD SubcorticalLabelingCheck 1\n# date 20050516\n# $Id: subcortical_labeling_table.m,v 1.4 2011/03/02 00:04:13 nicks Exp $\n# Buckner data set\n# ncols 20\n# nrows %d\n', sz(1));
ROI_Labels=[4 43 17 53 10 49 11 50 12 51 13 52 18 54 26 58 14 15 5 44];
labmapfile=('/space/lyon/1/fsdev/freesurfer_dev');
labmap=strcat(labmapfile,'/','tkmeditColorsCMA');
[label name val1 val2 val3 val4]=textread(labmap,'%d %s %d %d %d %d',89);
nn=1;
for u=1:length(ROI_Labels)
    fprintf(fp, '# label_col %d %s\n', u, char(name(ROI_Labels(u)+1)));
end
for i=1:sz(1)
     if(Dvolume(i,1)>0)
        nb=Ivol(i);
        fprintf(fp, '# label_row %d %s\n',nn, char(files(nb).name));
         nn=nn+1;
     end
end
for j=1:sz(1)
    for k=1:20
        fprintf(fp,'%f  ', Dvolume(j,k));
    end
    fprintf(fp, '\n');
end
fclose(fp)


function modelFile = trainModel(imSet, paths, param)

	featureParam = param.featureParam;
	gtParam = param.gtParam;
	classifierParam = param.classifierParam;
	bParam = param.bParam;

	for i = 1:2,
		imList{i} = getImageSet(imSet{i});
	end

	% Loading the features here
	cacheFile = fullfile(paths.featureCache, strcat(featureParam.featureCacheName, '_', param.fileSuffix, '.mat'))
	if(exist(cacheFile, 'file') & param.useCache)
		dt = load(cacheFile);
		assert(isequal(imList, dt.imList), 'Image sets not same.... re-gathering features.. \n');
		feature = dt.feature; gt = dt.gt; sp = dt.sp;
		spArea = dt.spArea;
	else
		for i = 1:length(imList),
			[feature{i} sp{i} spArea{i} gt{i}] = loadExamples(imList{i}, paths, struct('featureParam', featureParam, 'gtParam', gtParam), true);
		end
		save(cacheFile,'-v7.3','gt','feature','sp','spArea','imList','param','imSet');
	end
	fprintf('Loaded Features!\n');

	for i = 1:length(imList),
		gt{i} = cat(2, gt{i}{:});
		spArea{i} = cat(2, spArea{i}{:});
		feature{i} = cat(2, feature{i}{:});
	end

	% Training the model here
	modelFile = fullfile(paths.modelDir, strcat(sprintf('%s_%s', param.classifierFileName, param.fileSuffix), '.mat'));
	try
		dt = load(modelFile);
		model = dt.model;
	catch
		switch param.classifierType
	   		case 'svm-full',
	   			model = svmMulticlassTrain(feature, gt, spArea, classifierParam);
	   		case 'tree-full',
	   			model = trainTreeBagging(feature, gt, spArea, classifierParam);
		end
	   save(modelFile, 'model', 'param', 'imList', 'imSet');
	end

	%% Test the model on the validation data here and pick the threshold for projection and store it again in the model
	try
		dt = load(modelFile);
		thresh = dt.thresh;
	catch
		outputDir = testModel(imSet{2}, paths, modelFile);

		evalResVal = benchmarkSSInternal(outputDir, imSet{2}, bParam);
		[~, ind] = max(evalResVal.detailsIU.fwavacc);
		thresh = bParam.threshIU(ind);
		fprintf('Threshold found to be %0.2f\n', thresh);
		save(modelFile, '-append', 'thresh', 'evalResVal');
	end
end


function ret = write_rgbe(img, filename, hdr_info)
%
%       ret = write_rgbe(img, filename, hdr_info)
%
%       This function writes an image using RGBE encoding.
%	Exposure and gamma, in the hdr_info, have to be applied before
%	by the user.
%
%
%        Input:
%           -img: the image to write on the hard disk
%           -filename: the name of the image to write
%           -hdr_info: RGBE format extra datum such as: RLE comression, exposure, gamma, etc.
%
%        Output:
%           -ret: a boolean value, it is set to 1 if the write succeed, 0 otherwise
%
%     Copyright (C) 2011-14  Francesco Banterle
%
%     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/>.
%

if(~exist('hdr_info', 'var'))
    hdr_info = struct('exposure', 1.0, 'gamma', 1.0, 'bRLE', 1);
end

if(~exist('hdr_info.bRLE','var'))
    bRLE = 1;
else
    bRLE = hdr_info.bRLE;
end

if(~exist('hdr_info.exposure', 'var'))
    exposure = 1.0;
else
    exposure = hdr_info.exposure;
end

if(~exist('hdr_info.gamma', 'var'))
    gamma = 1.0;
else
    gamma = hdr_info.gamma;
end

ret = 0;

[n, m, c] = size(img);

if(c ~= 3)
    error('RGBE encoding requires a three color channels image!');
end

fid = fopen(filename, 'W');
fprintf(fid,'#?RADIANCE\n');
fprintf(fid,'#Generated by the HDR Toolbox by Francesco Banterle\n');
fprintf(fid,'FORMAT=32-bit_rle_rgbe\n');
fprintf(fid,'EXPOSURE= %f\n\n', exposure);
fprintf(fid,'-Y %d +X %d\n', n, m);

%convert from float to RGBE
RGBEbuffer = uint8(float2RGBE(img));

if((n < 8) || (n > 32767)) %RLE encoding is not allowed in these cases
    bRLE = 0;
end

%MIN_RLE_RUN = 4;

if(bRLE)
    buffer_line_start = uint8([2, 2, bitshift(m, -8), bitand(m, 255)]);

    for i=1:n
        fwrite(fid, buffer_line_start, 'uint8');
        for j=1:4
            buffer_line = reshape(RGBEbuffer(i,:,j), m, 1);
            write_rgbe_line(buffer_line, fid);
        end
    end
else
    %data reshape
    tot = n * m * 4;
    data = zeros(tot, 1, 'uint8');
    for i=1:4
        C = i:4:(tot);
        data(C) = reshape(RGBEbuffer(:,:,i)', m * n, 1);
    end

    fwrite(fid, data, 'uint8');

end

fclose(fid);

ret = 1;

end


function varargout=lpcpp2pz(varargin)
%
% For calling details please see v_lpcpp2pz.m
%
% This dummy routine is included for backward compatibility only
% and will be removed in a future release of voicebox. Please use
% v_lpcpp2pz.m in future and/or update with v_voicebox_update.m
%
%      Copyright (C) Mike Brookes 2018
%      Version: $Id: lpcpp2pz.m 10863 2018-09-21 15:39:23Z dmb $
%
if nargout
    varargout=cell(1,nargout);
    [varargout{:}]=v_lpcpp2pz(varargin{:});
else
    v_lpcpp2pz(varargin{:});
end


function [valid, message] = applyUserValidation(SBMLStructure, level, version, packages, pkgVersion)
%  [valid, message] = applyUserValidation(SBMLStructure, level, version, packages, pkgVersion)
%
% a script that can be customized by the user to add additional
%   validation to the isSBML_Model function
%
% Takes
%
% 1. SBMLstructure - a MATLAB_SBML structure
% 2. level - an integer representing the SBML level
% 3. version - an integer representing the SBML version
% 4. packages - a cell array of the package prefixes used
%                              e.g. {'fbc'}
% 5. pkgVersion - an array of integers representing the version of each
%                               package; note indexing should match the
%                               packages indexing e.g. [1]
%
% Returns
%
% 1. valid =
%   - 1, if the structure represents passes the tests imposed
%   - 0, otherwise
% 2. a message explaining any failure

%<!---------------------------------------------------------------------------
% This file is part of libSBML.  Please visit http://sbml.org for more
% information about SBML, and the latest version of libSBML.
%
% Copyright (C) 2013-2018 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
%     3. University of Heidelberg, Heidelberg, Germany
%
% Copyright (C) 2009-2013 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
%
% Copyright (C) 2006-2008 by the California Institute of Technology,
%     Pasadena, CA, USA
%
% Copyright (C) 2002-2005 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. Japan Science and Technology Agency, Japan
%
% This library is free software; you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as
% published by the Free Software Foundation.  A copy of the license
% agreement is provided in the file named "LICENSE.txt" included with
% this software distribution and also available online as
% http://sbml.org/software/libsbml/license.html
%----------------------------------------------------------------------- -->

valid = 1;
message = '';

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% example check that all GeneProducts listed have an id value

% if isempty(packages{1})
%     present = 0;
% else
%     [present, index] = ismember('fbc', packages);
% end;
%
% if (present)
%     if (pkgVersion(index) == 2)
%         gp = SBMLStructure.fbc_geneProduct;
%         [a, num] = size(gp);
%         for i=1:num
%             if (isempty(gp(num).fbc_id))
%                 valid = 0;
%                 message = 'geneProduct is missing the id attribute';
%             end;
%         end;
%     end;
% end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function hdr = mrReadEfile(EfileName)
% header = mrReadEfile(EfileName)
%
% Returns header info from Efile produced by G. Glover's auto-recon program.
% Output is structure having field names corresponding to Glover's parameters.
%
% Ress 9/01
% $Author: bob $
% $Date: 2008/02/14 19:50:01 $
% ras, 07/05: imported into mrVista 2.0.
% ras, 10/08: reads alignment points for each slice.
if notDefined('EfileName')
	EfileName = mrvSelectFile('r', {'E*.7' '*.*'}, 'Select an E file ...');
end

hdr = [];

fid = fopen(EfileName);
if fid == -1
	Alert(['Could not open file: ' EfileName])
	return
end

% initialize empty fields for alignment info
% * ras 10/08: after some empirical testing, I believe gw_point1 represents
% the upper left-hand corner of each slice in scanner space, gw_point2
% represents the lower left-hand corner, and gw_point3 represents the
% uppper right-hand corner. In the output header structure, I will store
% each set of points as a 3xnSlices array. The rows are the L->R, P->A, and
% I->S position of each point, respectively; and the columns are different
% slices.
hdr.gw_point1 = [];
hdr.gw_point2 = [];
hdr.gw_point3 = [];

nLine = 0;
while 1
	line = fgetl(fid);
	if ~ischar(line), break, end
	ieq = findstr(line, '=');
	lhs = deblank(line(1:ieq-1));
	rhs = line(ieq+2:end);
	switch lhs
		case 'rev'
			% Revision
			hdr.rev = rhs;
		case 'date of scan'
			% Date
			hdr.date = rhs;
			% Make this more reasonable
			hdr.date=[hdr.date(1:6),hdr.date(8:end)];
		case 'time of scan'
			% Time
			hdr.time = rhs;
		case 'patient name'
			% Name
			hdr.name = rhs;
		case 'psd'
			% PSD
			hdr.psd = rhs;
		case 'coil'
			% Coil
			hdr.coil = rhs;
		case 'examnum/seriesnum'
			vals = explode('/', rhs);
			hdr.examNum = str2num(vals{1});
			hdr.seriesNum = str2num(vals{2});
		case 'series description'
			hdr.seriesDescription = rhs;
		case 'patient id'
			hdr.patientID = rhs;
		case 'exam description'
			hdr.examDescription = rhs;
		case 'series description'
			hdr.seriesDescription = rhs;
		case 'num echoes'
			hdr.nechos = getNumberFromString(rhs);
		case 'slquant'
			% Number of slices
			hdr.slquant = getNumberFromString(rhs);
		case 'num time frames'
			% Number of frames
			hdr.nframes = getNumberFromString(rhs);
		case {'numextra discards' 'nextra discards'}
			% Number of discarded shots
			hdr.nextra = getNumberFromString(rhs);
		case 'nshot'
			% Number of interleaves
			hdr.nshots = getNumberFromString(rhs);
		case 'FOV'
			% Field of view (mm)
			hdr.FOV = getNumberFromString(rhs);
		case 'slice thick'
			% Slice thickness (mm)
			hdr.sliceThickness = getNumberFromString(rhs);
		case 'skip'
			% Slice spacing (skip)
			hdr.skip = getNumberFromString(rhs);
		case 'TR'
			% Echo time, TR (ms)
			hdr.TR = getNumberFromString(rhs);
		case 'TE'
			% Repetition time, TE (ms)
			hdr.TE = getNumberFromString(rhs);
		case 'time/frame'
			% Acquisition time (ms)
			hdr.tAcq = getNumberFromString(rhs);
		case 'equiv matrix size'
			% Equivalent matrix size
			hdr.equivMatSize = getNumberFromString(rhs);
		case 'imgsize'
			% Image size
			hdr.imgsize = getNumberFromString(rhs);
		case 'pixel size'
			% Pixel size (mm)
			hdr.pixel = getNumberFromString(rhs);
		case 'freq'
			% Frequency (MHz)
			hdr.freq = getNumberFromString(rhs)/1.e6;
		case 'flip angle'
			% Flip Angle (deg)
			hdr.flipAngle = str2num(rhs);
		case 'R1, R2, TG (mps)'
			% Gains [R1, R2, TG]
			hdr.R1 = getNumberFromString(rhs, 1);
			hdr.R2 = getNumberFromString(rhs, 2);
			hdr.TG = getNumberFromString(rhs, 3);
		case 'BigEndian'
			hdr.BigEndian = str2num(rhs);
		case 'start_loc'
			hdr.start_loc = [sscanf(rhs, '%f %f %f', 3)]';
		case 'gw_point1'
			hdr.gw_point1(:,end+1) = sscanf(rhs, '%f %f %f', 3);
		case 'gw_point2'
			hdr.gw_point2(:,end+1) = sscanf(rhs, '%f %f %f', 3);
		case 'gw_point3'
			hdr.gw_point3(:,end+1) = sscanf(rhs, '%f %f %f', 3);
		otherwise
			% try to record the remaining fields, if the descriptions are
			% valid field names
			try
				hdr.(lhs) = rhs;
			catch
				% oh well...
% 				fprintf('Missed: %s, %s\n', lhs, rhs);  % debug
			end
	end
end


% The COBRAToolbox: testSubSystemModification.m
%
% Purpose:
%     - test Manipulation of subSystems and retrieval by subSystems in
%     addSubSystemsToReactions, setRxnSubSystem, removeSubSystemFromReaction,
%     findRxnsFromSubSystem, getModelSubSystems, isReactionInSubSystem
%
% Authors:
%     Thomas Pfau - Nov 2017

% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testSubSystemModification.m'));
cd(fileDir);

model = getDistributedModel('ecoli_core_model.mat');
%This is a correct model. Now lets do some subSystem Manipulation
originalSubSystems = {'Exchange','Anaplerotic reactions','Citric Acid Cycle','Glutamate Metabolism','Glycolysis/Gluconeogenesis','Inorganic Ion Transport and Metabolism','Oxidative Phosphorylation','Pentose Phosphate Pathway','Pyruvate Metabolism','Transport, Extracellular'};
subSysToManipulate = 'Citric Acid Cycle';
originalPositions = [4;5;8;15;46;59;64;90];

%First get all reactions with 'Citric Acid Cycle' subSystem annotation
[reactionNames,reactionPos] = findRxnsFromSubSystem(model,subSysToManipulate);
assert(isempty(setxor(reactionPos,[4;5;8;15;46;59;64;90]))); %These and only these
assert(isequal(reactionNames,model.rxns(reactionPos))); %Same order

%Now, get all subSystems in the model
subsInModel = getModelSubSystems(model);
assert(isempty(setxor(subsInModel,originalSubSystems)));

%Now, add Citric Acid Cycle to the first three reactions
originalSubsystems = model.subSystems;
modelNew = addSubSystemsToReactions(model,model.rxns(1:3),subSysToManipulate);
[reactionNames,reactionPos] = findRxnsFromSubSystem(modelNew,subSysToManipulate);
assert(isempty(setxor(union(originalPositions,[1:3]),reactionPos))); %Added only to those and not changed elsewhere.
assert(all(~cellfun(@(x) isequal(x,{''}),originalSubsystems(1:3)))); %The first three subSystems are non Empty, i.e. this empty is not removed
assert(all(cellfun(@(x,y) all(ismember(y,x)),modelNew.subSystems,originalSubsystems))); %Old subSystems are retained.

%Add it to an empty reactions
modelWithEmptyReplaced = addSubSystemsToReactions(model,13,subSysToManipulate); %Biomass gets assigned to Citric Acid Cycle
assert(isequal(modelWithEmptyReplaced.subSystems{13},{subSysToManipulate})); %Assert that the '' was removed and only the Citric Acid cycle is there.

%Remove the Citric Acid Cycle from all reactions
rxnToDo = true(numel(model.rxns),1);
modelWOTCA = removeSubSystemsFromRxns(modelNew,rxnToDo,subSysToManipulate); %Remove it from model with the added SubSystems.
assert(all(cellfun(@(x) isequal(x,{''}),modelWOTCA.subSystems(originalPositions)))); %The former TCA reactions should have no subSystem left.
rxnToDo(originalPositions) = false; %Ignore them
assert(all(cellfun(@(x,y) isempty(setxor(x,y)),modelWOTCA.subSystems(rxnToDo),model.subSystems(rxnToDo)))); %All others should have their original

%Now, set the TCA as subSystem for a batch of reactions:
reactionsToSet = [3 4 7 8 13];
modelWithSet = setRxnSubSystems(model,reactionsToSet,subSysToManipulate);
assert(all(cellfun(@(x) isequal(x,{subSysToManipulate}),modelWithSet.subSystems(reactionsToSet))));
notChanged = setdiff(1:numel(model.rxns),reactionsToSet);
assert(all(cellfun(@(x,y) isequal(x,y), modelWithSet.subSystems(notChanged),model.subSystems(notChanged))));

%Test for multiple values
SomeSubSys = 'testtSubSys';
modelTest = addSubSystemsToReactions(model,1:4,SomeSubSys);
newSubs = getModelSubSystems(modelTest);
assert(isempty(setxor(newSubs,union(originalSubSystems,SomeSubSys))));

%finally test isReactionInSubSystem
assert(~isReactionInSubSystem(model,model.rxns{9},'Citric Acid Cycle'))
assert(all(isReactionInSubSystem(model,model.rxns(4:5),'Citric Acid Cycle')));
assert(isequal(isReactionInSubSystem(model,21:-1:18,'Exchange'),[true; true; false; false]));

%Return to old path
cd(currentDir)


classdef BriefDescriptorExtractor < handle
    %BRIEFDESCRIPTOREXTRACTOR  Class for computing BRIEF descriptors
    %
    % As described in [calon2010].
    %
    % ## References
    % [calon2010]:
    % > Michael Calonder, Vincent Lepetit, Christoph Strecha, and Pascal Fua.
    % > "Brief: Binary robust independent elementary features".
    % > In Computer Vision-ECCV 2010, pages 778-792. Springer, 2010.
    %
    % See also: cv.BriefDescriptorExtractor.BriefDescriptorExtractor,
    %  cv.DescriptorExtractor
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    methods
        function this = BriefDescriptorExtractor(varargin)
            %BRIEFDESCRIPTOREXTRACTOR  Constructor
            %
            %     obj = cv.BriefDescriptorExtractor()
            %     obj = cv.BriefDescriptorExtractor(..., 'OptionName',optionValue, ...)
            %
            % ## Options
            % * __Bytes__ legth of the descriptor in bytes, valid values are:
            %   16, 32 (default) or 64.
            % * __UseOrientation__ sample patterns using keypoints orientation,
            %   disabled by default. default false.
            %
            % See also: cv.BriefDescriptorExtractor.compute
            %
            this.id = BriefDescriptorExtractor_(0, 'new', varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.BriefDescriptorExtractor
            %
            if isempty(this.id), return; end
            BriefDescriptorExtractor_(this.id, 'delete');
        end

        function typename = typeid(this)
            %TYPEID  Name of the C++ type (RTTI)
            %
            %     typename = obj.typeid()
            %
            % ## Output
            % * __typename__ Name of C++ type
            %
            typename = BriefDescriptorExtractor_(this.id, 'typeid');
        end
    end

    %% Algorithm
    methods
        function clear(this)
            %CLEAR  Clears the algorithm state
            %
            %     obj.clear()
            %
            % See also: cv.BriefDescriptorExtractor.empty,
            %  cv.BriefDescriptorExtractor.load
            %
            BriefDescriptorExtractor_(this.id, 'clear');
        end

        function b = empty(this)
            %EMPTY  Checks if detector object is empty
            %
            %     b = obj.empty()
            %
            % ## Output
            % * __b__ Returns true if the detector object is empty (e.g in the
            %   very beginning or after unsuccessful read).
            %
            % See also: cv.BriefDescriptorExtractor.clear,
            %  cv.BriefDescriptorExtractor.load
            %
            b = BriefDescriptorExtractor_(this.id, 'empty');
        end

        function save(this, filename)
            %SAVE  Saves the algorithm parameters to a file
            %
            %     obj.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in the specified
            % XML or YAML file.
            %
            % See also: cv.BriefDescriptorExtractor.load
            %
            BriefDescriptorExtractor_(this.id, 'save', filename);
        end

        function load(this, fname_or_str, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     obj.load(fname)
            %     obj.load(str, 'FromString',true)
            %     obj.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from the specified XML or
            % YAML file (either from disk or serialized string). The previous
            % algorithm state is discarded.
            %
            % See also: cv.BriefDescriptorExtractor.save
            %
            BriefDescriptorExtractor_(this.id, 'load', fname_or_str, varargin{:});
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = obj.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.BriefDescriptorExtractor.save,
            %  cv.BriefDescriptorExtractor.load
            %
            name = BriefDescriptorExtractor_(this.id, 'getDefaultName');
        end
    end

    %% Features2D: DescriptorExtractor
    methods
        function ntype = defaultNorm(this)
            %DEFAULTNORM  Returns the default norm type
            %
            %     ntype = obj.defaultNorm()
            %
            % ## Output
            % * __ntype__ Norm type. One of `cv::NormTypes`:
            %   * __Inf__
            %   * __L1__
            %   * __L2__
            %   * __L2Sqr__
            %   * __Hamming__
            %   * __Hamming2__
            %
            % Always `Hamming` for BRIEF.
            %
            % See also: cv.BriefDescriptorExtractor.compute,
            %  cv.DescriptorMatcher
            %
            ntype = BriefDescriptorExtractor_(this.id, 'defaultNorm');
        end

        function sz = descriptorSize(this)
            %DESCRIPTORSIZE  Returns the descriptor size in bytes
            %
            %     sz = obj.descriptorSize()
            %
            % ## Output
            % * __sz__ Descriptor size, as specified in `Bytes` argument in
            %   constructor.
            %
            % See also: cv.BriefDescriptorExtractor.descriptorType,
            %  cv.BriefDescriptorExtractor.compute
            %
            sz = BriefDescriptorExtractor_(this.id, 'descriptorSize');
        end

        function dtype = descriptorType(this)
            %DESCRIPTORTYPE  Returns the descriptor type
            %
            %     dtype = obj.descriptorType()
            %
            % ## Output
            % * __dtype__ Descriptor type, one of numeric MATLAB class names.
            %
            % Always `uint8` for BRIEF.
            %
            % See also: cv.BriefDescriptorExtractor.descriptorSize,
            %  cv.BriefDescriptorExtractor.compute
            %
            dtype = BriefDescriptorExtractor_(this.id, 'descriptorType');
        end

        function [descriptors, keypoints] = compute(this, img, keypoints)
            %COMPUTE  Computes the descriptors for a set of keypoints detected in an image or image set
            %
            %     [descriptors, keypoints] = obj.compute(img, keypoints)
            %     [descriptors, keypoints] = obj.compute(imgs, keypoints)
            %
            % ## Input
            % * __img__ Image (first variant), 8-bit grayscale image.
            % * __imgs__ Image set (second variant), cell array of images.
            % * __keypoints__ Input collection of keypoints. Keypoints for
            %   which a descriptor cannot be computed are removed. Sometimes
            %   new keypoints can be added, for example: cv.SIFT duplicates
            %   keypoint with several dominant orientations (for each
            %   orientation). In the first variant, this is a struct-array of
            %   detected keypoints. In the second variant, it is a cell-array,
            %   where `keypoints{i}` is a set of keypoints detected in
            %   `imgs{i}` (a struct-array like before).
            %
            % ## Output
            % * __descriptors__ Computed descriptors. In the second variant of
            %   the method `descriptors{i}` are descriptors computed for a
            %   `keypoints{i}`. Row `j` in `descriptors` (or `descriptors{i}`)
            %   is the descriptor for `j`-th keypoint.
            % * __keypoints__ Optional output with possibly updated keypoints.
            %
            % See also: cv.BriefDescriptorExtractor.BriefDescriptorExtractor
            %
            [descriptors, keypoints] = BriefDescriptorExtractor_(this.id, 'compute', img, keypoints);
        end
    end

end


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

curr_dir = pwd;
cd(model_dir);
model_obj_rec.net = caffe_load_model(model_obj_rec.net_def_file, model_obj_rec.net_weights_file, model_phase);

if use_detection_svms
    assert(exist(model_obj_rec.svm_weights_file, 'file')>0);
    weights = read_svm_detection_weights(model_obj_rec.svm_weights_file);
    model_obj_rec.net = set_net_layer_weights(model_obj_rec.net, model_obj_rec.svm_layer_name, weights);
end

cd(curr_dir);
end


function view = blurDialog(view);

if isempty(view)
   myErrorDlg('Volume window must be open to blur phase.');
   return;
end
if ~strcmp('Gray',view.viewType)
   myErrorDlg('Blur phase only in gray view.');
   return;
end
if (isempty(view.ph) | isempty(view.co))
   myErrorDlg('Correlation matrices not loaded.  Load them from the File menu');
   return;
end

% Make ui.blur structure
if ~isfield(view.ui,'blur');
    view.ui.blur = [];
end
if ~isfield(view.ui.blur,'Lambda');
   view.ui.blur.Lambda = 0;
end
if ~isfield(view.ui.blur,'weightFlag');
   view.ui.blur.weightFlag = 0;
end

windowPos = [150 200 300 50];

blurwin = figure('MenuBar','none');

set(blurwin,'Position', windowPos);
set(blurwin, 'Name', 'Blurring');

view.ui.blur.WindowHandle = gcf;

radioPos = [0.05 0.5 0.3 0.4];
radioOff = [0 0.4 0 0];
view.ui.blur.Radio(1) = uicontrol('Style','radiobutton',...
    'String','Blur',...
    'Units','normalized',...
    'Position',radioPos,...
    'Callback', [view.name,'.ui.blur.weightFlag=0; ',...
    'selectButton(',view.name,'.ui.blur.Radio,1)']);
view.ui.blur.Radio(2) = uicontrol('Style','radiobutton',...
    'String','Weighted blur',...
    'Units','normalized',...
    'Position',radioPos-radioOff,...
    'Callback', [view.name,'.ui.blur.weightFlag=1; ',...
    'selectButton(',view.name,'.ui.blur.Radio,2)']);

 % Select the appropriate radio button
 if view.ui.blur.weightFlag
    selectButton(view.ui.blur.Radio,2);
 else
    selectButton(view.ui.blur.Radio,1);
 end

view.ui.blur.SliderPos = [0.4 0.5 0.4 0.4];
view.ui.blur.LabelOffset = [0 0.4 0 0];

range = [-1 1];
sliderCallback = [view.name '.ui.blur.Lambda = get(' view.name '.ui.blur.Slider,''Value''); ',...
      'uicontrol(''Style'',''text'',''Units'',''normalized'',''Position'',',...
       view.name '.ui.blur.SliderPos - ',...
      view.name '.ui.blur.LabelOffset, ''String'',[''Blurring: '' num2str(10^(',...
      view.name '.ui.blur.Lambda))])'];
view.ui.blur.Slider = uicontrol('Style','slider',...
   'Units','normalized',...
   'Position',view.ui.blur.SliderPos,...
   'Min',range(1), 'Max',range(2),...
   'Value',view.ui.blur.Lambda,...
	'Callback',sliderCallback);

uicontrol('Style','text',...
   'Units','normalized',...
   'Position',view.ui.blur.SliderPos - view.ui.blur.LabelOffset,...
   'String',['Blurring: ' num2str(10^(view.ui.blur.Lambda))]);
OKposition = [0.85 0.1 0.1 0.8];
uicontrol('String','Blur',...
   'Units','normalized',...
   'Position', OKposition,...
   'Callback', ['close(',num2str(view.ui.blur.WindowHandle),'); ',...
      view.name,' = blurPh(',view.name,...
      ',',view.name,'.ui.blur.weightFlag',...
      ',10^(',view.name,'.ui.blur.Lambda)); ',...
      view.name,'=refreshScreen(',view.name,',1);']);


function ok = t_ok(cond, msg)
%T_OK  Tests whether a condition is true.
%   T_OK(EXPR, MSG) increments the global test count and if the EXPR
%   is true it increments the passed tests count, otherwise increments
%   the failed tests count. Prints 'ok' or 'not ok' followed by the
%   MSG, unless T_BEGIN was called with input QUIET equal true. Intended
%   to be called between calls to T_BEGIN and T_END.
%
%   Optionally returns a true or false value indicating whether or
%   not the test succeeded.
%
%   Example:
%       quiet = 0;
%       t_begin(5, quiet);
%       t_ok(pi > 3, 'size of pi');
%       t_skip(3, 'not yet written');
%       t_is(2+2, 4, 12, '2+2 still equals 4');
%       t_end;
%
%   See also T_IS, T_SKIP, T_BEGIN, T_END, T_RUN_TESTS.

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

global t_quiet;
global t_counter;
global t_ok_cnt;
global t_not_ok_cnt;

if nargin < 2 || strcmp(msg, '')
    msg = '';
else
    msg = [' - ', msg];
end
if cond
    t_ok_cnt = t_ok_cnt + 1;
else
    t_not_ok_cnt = t_not_ok_cnt + 1;
    if ~t_quiet
        fprintf('not ');
    end
end
if ~t_quiet
    fprintf('ok %d%s\n', t_counter, msg);
end
t_counter = t_counter + 1;
if nargout
    ok = cond;
end


function res = ctranspose(a)
a.adjoint = xor(a.adjoint,1);
res = a;


function info = Demo()

varargin=cell(1,2);

varargin(1,1)={'train'};
varargin(1,2)={struct('gpus', 1)};

run ../matconvnet/matlab/vl_setupnn ;
addpath ../matconvnet/examples ;

opts.expDir = 'exp/' ;
opts.dataDir = 'exp/data/' ;
opts.modelType = 'tracking' ;
opts.sourceModelPath = 'exp/models/' ;
[opts, varargin] = vl_argparse(opts, varargin) ;

% experiment setup
opts.imdbPath = fullfile(opts.expDir, 'imdb.mat') ;
opts.imdbStatsPath = fullfile(opts.expDir, 'imdbStats.mat') ;
opts.vocEdition = '11' ;
opts.vocAdditionalSegmentations = false ;

global resize;
display=1;

g=gpuDevice(1);
clear g;

test_seq='Skiing';
[config]=config_list(test_seq);

result=CREST_tracking(opts,varargin,config,display);


function isomapInfo = isomapDeconstruct(model)

% ISOMAPDECONSTRUCT break isomap in pieces for saving.
% FORMAT
% DESC takes an isomap model structure and breaks it into component
% parts for saving.
% ARG model : the model that needs to be saved.
% RETURN isomapInfo : a structure containing the other information
% from the isomap: what the sparse approximation is, what the inducing
% variables are.
%
% SEEALSO : isomapReconstruct
%
% COPYRIGHT : Neil D. Lawrence, 2009

% MLTOOLS

isomapInfo = model;
removeFields = {'Y'};

for i = 1:length(removeFields)
  if isfield(isomapInfo, removeFields{i})
    isomapInfo = rmfield(isomapInfo, removeFields{i});
  end
end


classdef noutput < dml.method
%NOUTPUT wrapper class to make methods handle multiple outputs.
%
%   DESCRIPTION
%
%
%   REFERENCE
%
%
%   EXAMPLE
%
%
%   DEVELOPER
%   Marcel van Gerven (m.vangerven@donders.ru.nl)

  properties

    method  % the method which should be replicated

  end

  methods

    function obj = noutput(varargin)

     obj@dml.method(varargin{:});

     if ~iscell(obj.method)
       obj.verbose = obj.method.verbose;
     else
       obj.verbose = obj.method{1}.verbose;
     end

    end

    function obj = train(obj,X,Y)

      ny = size(Y,2);

      if ~iscell(obj.method)
        obj.method = repmat({obj.method},[1 ny]);
      end

      for c=1:ny

        if obj.method{c}.verbose
          fprintf('training output %d of %d\n',c,ny);
        end

        obj.method{c} = obj.method{c}.train(X,Y(:,c));
      end

    end

    function Y = test(obj,X)

      ny = length(obj.method);

      Y = [];
      for c=1:ny

        if obj.method{c}.verbose
          fprintf('testing output %d of %d\n',c,ny);
        end

        Y = [Y obj.method{c}.test(X)];

      end

    end

    function m = model(obj)

      ny = length(obj.method);

      m = cell(1,ny);
      for c=1:ny

        m{c} = obj.method{c}.model;

      end

    end

  end

end


function varargout = spm_changepath(Sf, oldp, newp, verbose)
% Recursively replace all occurences of a text pattern in a MATLAB variable.
% FORMAT S = spm_changepath(Sf, oldp, newp)
%
% Sf       - MATLAB variable to fix, or char array of MAT filenames,
%            or directory name (all found MAT files will be analysed)
% oldp     - old string to replace
% newp     - new string replacing oldp
%
% S        - updated MATLAB variable (only if Sf is one)
%
% If the pattern is found in a string, any occurence of an invalid file
% separator is replaced to match that of the current system.
%
% If MAT filenames are specified, they will be overwritten with the new
% version. A backup of the initial version is made with a ".old" suffix.
%__________________________________________________________________________
% Copyright (C) 2009-2016 Wellcome Trust Centre for Neuroimaging

% Guillaume Flandin
% $Id: spm_changepath.m 6948 2016-11-24 10:34:01Z guillaume $

%-Input arguments
%--------------------------------------------------------------------------
if ~nargin
    Sf = spm_select(Inf,'mat','Select MAT files to fix');
end

if nargin <= 1
    oldp = spm_input('Old pattern','+1','s');
end

if nargin <= 2
    newp = spm_input('New pattern','+1','s');
end

if nargin <= 3
    verbose = true;
end

%-Replace pattern in given MAT-files
%--------------------------------------------------------------------------
if ischar(Sf)
    if nargout
        error('Output argument only valid for MATLAB variable input');
    end
    if exist(Sf,'dir')
        Sf = spm_select('FPList',Sf,'^.*\.mat$'); % FPListRec for recursive
    end
    if isempty(Sf), Sf = {}; else Sf = cellstr(Sf); end
    for i=1:numel(Sf)
        f = Sf{i};
        try
            S = load(f);
        catch
            error('Cannot load "%s".',f);
        end
        tmp = changepath(S,oldp,newp,verbose);
        if ~isequalwithequalnans(tmp,S)
            if verbose, fprintf('=> Fixing %s\n',f); end
            [sts, msg] = movefile(f,[f '.old']);
            if ~sts, error(msg); end
            save(f ,'-struct','tmp', spm_get_defaults('mat.format'));
        end
    end
else
    varargout = { changepath(Sf,oldp,newp,verbose) };
end

%==========================================================================
function S = changepath(S,oldp,newp,verbose)

check = false;

switch class(S)
    case {'double','single','logical','int8','uint8','int16','uint16',...
            'int32','uint32','int64','uint64','function_handle'}

    case 'cell'
        for i=1:numel(S)
            S{i} = changepath(S{i},oldp,newp,verbose);
        end

    case 'struct'
        for i=1:numel(S)
            fn = fieldnames(S);
            for j=1:length(fn)
                S(i).(fn{j}) = changepath(S(i).(fn{j}),oldp,newp,verbose);
            end
        end

    case 'char'
        f = {'\' '/'};
        if ispc, f = fliplr(f); end
        tmp = cellstr(S);
        for i=1:numel(tmp)
            t = strrep(tmp{i},oldp,newp);
            if ~isequal(tmp{i},t)
                t = strrep(t,f{1},f{2});
                if check
                    if spm_existfile(t)
                        sts = ' (OK) ';
                    else
                        sts = ' (NOT FOUND) ';
                    end
                else
                    sts = '';
                end
                if verbose, fprintf('%s%s\n',t,sts); end
            end
            tmp{i} = t;
        end
        S = char(tmp);

    case 'nifti'
        for i=1:numel(S)
            S(i).dat = changepath(S(i).dat,oldp,newp,verbose);
        end

    case 'file_array'
        S.fname = changepath(S.fname,oldp,newp,verbose);

    case 'gifti'
        if isfield(S,'cdata') && isa(S.cdata,'file_array')
            fa = struct(S.cdata);
            fa.fname = changepath(fa.fname,oldp,newp,verbose);
            S.cdata = file_array(fa);
        end

    otherwise
        warning('Unknown class "%s".',class(S));
end


function storeLabelListGT(varargin)
% storeLabelListGT(varargin)
%
% Create the labelListGT entry for each ground-truth segmentation file of the dataset.
%
% Copyright by Holger Caesar, 2015

% Parse input
p = inputParser;
addParameter(p, 'projectName', 'WeaklySupervisedLearning');
addParameter(p, 'dataset', SiftFlowDatasetMC());
addParameter(p, 'proposalNameGT', 'GroundTruth');
addParameter(p, 'subset', 'all');
parse(p, varargin{:});

projectName = p.Results.projectName;
dataset = p.Results.dataset;
proposalNameGT = p.Results.proposalNameGT;
subset = p.Results.subset;

% Create paths
global glFeaturesFolder;
segmentFolder = fullfile(glFeaturesFolder, projectName, dataset.name, 'segmentations', proposalNameGT);

% Get list of images in dataset
if strcmp(subset, 'all'),
    [imageList, imageCount] = dataset.getImageList();
elseif strcmp(subset, 'train'),
    [imageList, imageCount] = dataset.getImageListTrn();
elseif strcmp(subset, 'test'),
    [imageList, imageCount] = dataset.getImageListTst();
else
    error('Error: Unknown subset: %s', subset);
end;

for imageIdx = 1 : imageCount,
    printProgress('Processing image', imageIdx, imageCount, 50);

    % Get segmentation
    imageName = imageList{imageIdx};
    segmentPath = [segmentFolder, filesep, imageName, '.mat'];
    segmentStruct = load(segmentPath);
    if isfield(segmentStruct, 'labelListGT'),
        fprintf('Skipping existing file %s...\n', segmentPath);
        continue;
    end;
    propBlobs = segmentStruct.propBlobs;
    blobCount = numel(propBlobs);

    % Get labelMap
    labelMap = dataset.getImLabelMap(imageName);
    labelListGT = nan(blobCount, 1);

    for blobIdx = 1 : blobCount,
        % Get labels for that blob
        blob = propBlobs(blobIdx);
        blobInds = blobToImageInds(blob, size(labelMap));
        blobLabel = unique(labelMap(blobInds));
        assert(numel(blobLabel) == 1 && blobLabel > 0);
        labelListGT(blobIdx) = blobLabel;
    end;

    % Sanity check
    assert(~any(isnan(labelListGT)));

    % Append to file
    save(segmentPath, 'labelListGT', '-append');
end;


function [voiContourHandles] = matRad_plotVoiContourSlice(axesHandle,cst,ct,ctIndex,selection,plane,slice,cMap,varargin)
% matRad function that plots the contours of the segmentations given in cst
%
% call
% voiContourHandles = matRad_plotVoiContourSlice(axesHandle,cst,ct,ctIndex,selection,plane,slice)
% voiContourHandles = matRad_plotVoiContourSlice(axesHandle,cst,ct,ctIndex,selection,plane,slice,cMap)
% voiContourHandles = matRad_plotVoiContourSlice(axesHandle,cst,ct,ctIndex,selection,plane,slice,cMap,...)
%
% input
%   axesHandle          handle to axes the slice should be displayed in
%   cst                 matRad cst cell array
%   ct                  matRad ct structure
%   ctIndex             index of the ct cube
%   selection           logicals defining the current selection of contours
%                       that should be plotted. Can be set to [] to plot
%                       all non-ignored contours.
%   plane               plane view (coronal=1,sagittal=2,axial=3)
%   slice               slice in the selected plane of the 3D cube
%   cMap                optional argument defining the colormap, default is
%                       colorcube
%   varargin            Additional Matlab Line-Property/value pairs
%
% output
%   voiContourHandles:  handles of the plotted contours
%   visibleOnSlice:     logicals defining if the contour is actually
%                       visible on the current slice
%
% 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.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[env, ~] = matRad_getEnvironment();

% overwrite colormap
if exist('cMap', 'var') && ~isempty(cMap)
    cMapScale = size(cMap,1)-1;
    %determine colors
    colors = cMap(round(linspace(1,cMapScale,size(cst,1))),:);
else
    for i = 1:size(cst,1)
        if isfield(cst{i,5},'visibleColor')
            colors(i,:) = cst{i,5}.visibleColor;
        else
            colors(i,:) = [0 0 0];
        end
    end
end

if isempty(selection) || numel(selection) ~= size(cst,1)
    selection = true(size(cst,1),1);
end

voiContourHandles = cell(0);
switch env
    case 'MATLAB'
        voiContourHandles = gobjects(0);
    case 'OCTAVE'
        voiContourHandles = [];
end

for s = 1:size(cst,1)

    if ~strcmp(cst{s,3},'IGNORED') && selection(s)
        %Check for precalculated contours
        C =[];
        if size(cst,2) >= 7 && ~isempty(cst{s,7})
            C = cst{s,7}{slice,plane};
        else
            %If we do not have precomputed contours available, then compute them
            mask = zeros(size(ct{ctIndex}));
            mask(cst{s,4}{ctIndex}) = 1;

            if plane == 1 && any(any(mask(slice,:,:) > 0))
                C = contourc(squeeze(mask(slice,:,:)),.5*[1 1]);
            elseif plane == 2 && any(any(mask(:,slice,:) > 0))
                C = contourc(squeeze(mask(:,slice,:)),.5*[1 1]);
            elseif plane == 3 && any(any(mask(:,:,slice) > 0))
                C = contourc(squeeze(mask(:,:,slice)),.5*[1 1]);
            end
        end

        % plot precalculated contourc data

         switch env
            case 'MATLAB'
                tmpLineHandle = gobjects(0);
            case 'OCTAVE'
                tmpLineHandle = [];
         end

         if any(C(:))
            lower = 1; % lower marks the beginning of a section
            while lower-1 ~= size(C,2)
                hold on
                steps = C(2,lower); % number of elements of current line section
                tmpLineHandle(end+1) = line(C(1,lower+1:lower+steps),...
                    C(2,lower+1:lower+steps),...
                    'Color',colors(s,:),'Parent',axesHandle,varargin{:});

                lower = lower+steps+1;
            end
            voiContourHandles{end+1} = tmpLineHandle;
         else
            % create empty line object
            voiContourHandles{end+1} = {};
         end

    end
end

end


function [modelComp] = createModelNewCompartment(model,OldComp,NewComp,NewCompName,LB,UB,RemoveExch)
% This function converts a two compartment metabolic model into a three compartment metabolic model model
%
% function [modelComp] = createModelNewCompartment(model,OldComp,NewComp,NewCompName,LB,UB,RemoveExch)
%
% INPUT
% model         Model structure
% OldComp       Name of the current (to be replicated) compartment to be
%               replicated and added
% NewCompName   Name of new compartment e.g., 'lumen'
% LB            Value for Lower bound on new exchange compartment (default:-1000)
% UB            Value for Upper bound on new exchange compartment (default:1000)
%
% NewComp       Abrreviation for the new compartment,m e.g., 'lu'
% RemoveExch    Option (if set to 1) to remove the old compartment
%
% OUTPUT
% modelComp     Model with three compartments
%
% Ines Thiele 2016-2017

warning off
if ~exist('LB','var')
    LB = -1000;
end

if ~exist('UB','var')
    UB = 1000;
end

if ~exist('RemoveExch','var')
    RemoveExch = 0;
end
% find exchange reactions
cnt = 1;
for t=1:length(model.rxns)
    if  strfind(model.rxns{t}, 'EX_')
        Ex_RxnsAll(cnt,1) =model.rxns(t); %make exchange reaction list
        cnt=cnt+1;
    elseif  strfind(model.rxns{t}, 'Ex_')
        Ex_RxnsAll(cnt,1) =model.rxns(t); %make exchange reaction list
        cnt=cnt+1;
    end
end

% duplicate all ExtRxns in a new compartment [i] for the New Compartment and
% for new exchange reactions
%a = printRxnFormulaOri(model, Ex_RxnsAll,[],[],[],[],false);
a = printRxnFormula(model,'rxnAbbrList',Ex_RxnsAll,'printFlag',0,'lineChangeFlag',0,'metNameFlag',0,'fid',0,'directionFlag',0);

aOri = a;
modelComp = model;

for i = 1 : length(Ex_RxnsAll)
    b = find(ismember(model.rxns,Ex_RxnsAll(i)));
    if ~isempty(strfind(a{i},strcat('[',OldComp,']'))) && length(find(model.S(:,b))) ==1
        % add new reactions to model
        [metaboliteList,stoichCoeffList] = parseRxnFormula(a{i});
        metaboliteListA = regexprep(metaboliteList,strcat('\[',OldComp,'\]'),strcat('\[',NewComp,'\]'));
        if UB == 0
            UBO = -1*LB;
            LBO = 0;
            revFlag = 0;
            RxnName = strcat(model.rxnNames{b},' (from ',NewCompName,'to ',strcat('[',OldComp,']'));
            modelComp = addReaction(modelComp,{strcat(Ex_RxnsAll{i},'_[',NewComp,']'),RxnName},[metaboliteListA metaboliteList],...
                [-1 1], revFlag,LBO,UBO,0,strcat('Transport'),'',[],[],0,0);
        else
            metaboliteList = [metaboliteList metaboliteListA];
            stoichCoeffList = [-1 1];
            if LB < 0
                revFlag = 1;
            else
                revFlag = 0;
            end
            RxnName = strcat(model.rxnNames{b},' (from ',strcat('[',OldComp,']'),' to ',NewCompName,')');
            %replaced addReactionOri - Ronan
            modelComp = addReaction(modelComp,{strcat(Ex_RxnsAll{i},'_[',NewComp,']'),RxnName},metaboliteList,stoichCoeffList,...
                revFlag,LB,UB,0,strcat('Transport'),'',[],[],0,0);
            %modelComp = addReaction(modelComp,{strcat(Ex_RxnsAll{i},'_[',NewComp,']'),RxnName},'metaboliteList',metaboliteList,'stoichCoeffList',stoichCoeffList,...
             %'lowerBound',LB,'upperBound',UB,'objectiveCoef',0,'subSystem',{'Transport'},'geneRule','','geneNameList',[],'systNameList',[],'checkDuplicate',0,'printLevel',0);
        end
    end
end
a=aOri;
if RemoveExch == 1
    for i = 1 : length(Ex_RxnsAll)
        % remove original reactions
        b = find(ismember(modelComp.rxns,Ex_RxnsAll(i)));
        if ~isempty(strfind(a{i},strcat('[',OldComp,']'))) && length(find(modelComp.S(:,b))) ==1
            if isfield(modelComp,'rxnGeneMat')
            modelComp = rmfield(modelComp,'rxnGeneMat');
            end
            modelComp = removeRxns(modelComp,Ex_RxnsAll{i});
        end
    end
end


function short_sample()
% Short syntax highlighting sample
global gbl_value;
gbl_value = 20
hghlghtvar = 'a_string_example_here';

%% Title of cell
badstring = 'unterminated_string;
unusedvar = hghlghtvar;
!echo "Example `!` system command"
for iterval = 1:2:gbl_value
  % This is a very informative comment
  fprintf('%s:%d\n',hghlghtvar,iterval);
end
end


function vec_out = struct2array(struct_in)
% SYNTAX:
%   [vec_out] = struct2array(struct_in);
%
% INPUT:
%   struct_in = structure with fields of the same type
%
% OUTPUT:
%   vec_out = vectorized content of the struct
%
% DESCRIPTION:
%   Convert to a vector the fields of the structure in input
%   Note: It works only when the fields are of the same type

%--- * --. --- --. .--. ... * ---------------------------------------------
%               ___ ___ ___
%     __ _ ___ / __| _ | __|
%    / _` / _ \ (_ |  _|__ \
%    \__, \___/\___|_| |___/
%    |___/                    v 1.0RC1
%
%--------------------------------------------------------------------------
%  Copyright (C) 2021 Geomatics Research & Development srl (GReD)
%  Written by:       Andrea Gatti
%  Contributors:     Andrea Gatti
%  A list of all the historical goGPS contributors is in CREDITS.nfo
%--------------------------------------------------------------------------
%
%   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/>.
%
%--------------------------------------------------------------------------
% 01100111 01101111 01000111 01010000 01010011
%--------------------------------------------------------------------------

tmp = struct2cell(struct_in);
vec_out = [tmp{:}];


function write_brainvoyager(filename, data, dataformat, vmpversion)

% helper function to write volumetric data for brainvoyager.
% this is old code that moved from ft_volumewrite to clean up
% the high level function a bit. it is assumed that the orientation
% of the volume is correct.

data = double(data);
siz  = size(data);
maxval = max(data(:));

[p, f, e] = fileparts(filename);
filename  = fullfile(p, f);

switch dataformat
  case 'vmp'
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % write in BrainVoyager VMP format
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    fid = fopen(sprintf('%s.vmp', filename),'w');
    if fid < 0
      ft_error('Cannot write to file %s.vmp\n',filename);
    end

    switch vmpversion
      case 1
        % write the header
        fwrite(fid, 1, 'short');      % version
        fwrite(fid, 1, 'short');      % number of maps
        fwrite(fid, 1, 'short');      % map type
        fwrite(fid, 0, 'short');      % lag

        fwrite(fid, 0, 'short');      % cluster size
        fwrite(fid, 1, 'float');      % thresh min
        fwrite(fid, maxval, 'float'); % thresh max
        fwrite(fid, 0, 'short');      % df1
        fwrite(fid, 0, 'short');      % df2
        fwrite(fid, 0, 'char');       % name

        fwrite(fid, siz, 'short');    % size
        fwrite(fid, 0, 'short');
        fwrite(fid, siz(1)-1, 'short');
        fwrite(fid, 0, 'short');
        fwrite(fid, siz(2)-1, 'short');
        fwrite(fid, 0, 'short');
        fwrite(fid, siz(3)-1, 'short');
        fwrite(fid, 1, 'short');      % resolution

        % write the data
        fwrite(fid, data, 'float');
      case 2
        % determine relevant subvolume
        % FIXME, this is not functional at the moment, since earlier in this function all nans have been replaced by zeros
        minx = min(find(~isnan(max(max(data,[],3),[],2))));
        maxx = max(find(~isnan(max(max(data,[],3),[],2))));
        miny = min(find(~isnan(max(max(data,[],3),[],1))));
        maxy = max(find(~isnan(max(max(data,[],3),[],1))));
        minz = min(find(~isnan(max(max(data,[],1),[],2))));
        maxz = max(find(~isnan(max(max(data,[],1),[],2))));

        % write the header
        fwrite(fid, 2, 'short');      % version
        fwrite(fid, 1, 'int');        % number of maps
        fwrite(fid, 1, 'int');        % map type
        fwrite(fid, 0, 'int');        % lag

        fwrite(fid, 0, 'int');        % cluster size
        fwrite(fid, 0, 'char');       % cluster enable
        fwrite(fid, 1, 'float');      % thresh
        fwrite(fid, maxval, 'float'); % thresh
        fwrite(fid, 0, 'int');        % df1
        fwrite(fid, 0, 'int');        % df2
        fwrite(fid, 0, 'int');        % bonf
        fwrite(fid, [255,0,0], 'uchar');   % col1
        fwrite(fid, [255,255,0], 'uchar'); % col2
        fwrite(fid, 1, 'char');       % enable SMP
        fwrite(fid, 1, 'float');      % transparency
        fwrite(fid, 0, 'char');       % name

        fwrite(fid, siz, 'int');      % original size
        fwrite(fid, minx-1, 'int');
        fwrite(fid, maxx-1, 'int');
        fwrite(fid, miny-1, 'int');
        fwrite(fid, maxy-1, 'int');
        fwrite(fid, minz-1, 'int');
        fwrite(fid, maxz-1, 'int');
        fwrite(fid, 1, 'int');        % resolution

        % write the data
        fwrite(fid, data(minx:maxx,miny:maxy,minz:maxz), 'float');
    end
    fclose(fid);

  case 'vmr'
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % write in BrainVoyager VMR format
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    fid = fopen(sprintf('%s.vmr',filename),'w');
    if fid < 0
      ft_error('Cannot write to file %s.vmr\n',filename);
    end

    % data should be scaled between 0 and 225
    data = data - min(data(:));
    data = round(225*data./max(data(:)));

    % write the header
    fwrite(fid, siz, 'ushort');
    % write the data
    fwrite(fid, data, 'uint8');
    fclose(fid);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spherical Harmonic Modeling and Analysis Toolkit (SPHARM-MAT) is a 3D
% shape modeling and analysis toolkit.
% It is a software package developed at Shenlab in Center for Neuroimaging,
% Indiana University (SpharmMat@gmail.com, http://www.iupui.edu/~shenlab/)
% It is available to the scientific community as copyright freeware
% under the terms of the GNU General Public Licence.
%
% Copyright 2009, 2010, ShenLab, Center for Neuroimaging, Indiana University
%
% This file is part of SPHARM-MAT.
%
% SPHARM-MAT 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.
%
% SPHARM-MAT 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 SPHARM-MAT. If not, see <http://www.gnu.org/licenses/>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function outNames = SpharmMatAlignment(confs, objs, method)

numSbj = length(objs);
if ~exist(confs.OutDirectory,'dir')
    mkdir(confs.OutDirectory);
end
if (~exist([confs.OutDirectory '/Logs'],'dir'))
    mkdir([confs.OutDirectory '/Logs']);
end
outNames = {};

%class(confs) - struct
%confs.vars -list of variable
%class(objs) - cell

h = waitbar(0,'Please wait...');
for i = 1:numSbj
    file = objs{i};
    [path, name, ext] = fileparts(file);

    switch method
        case 'AligSHREC'
            diary(fullfile([confs.OutDirectory '/Logs'],[date, '_', num2str(round(cputime)), '_' name '_AlignSHREC.log']));
            % Call AligSHREC method
            if isempty(confs.Template)
                disp('SHREC needs a template object');
                return;
            end
            [vertices, sph_verts, faces, fvec, outNames{end+1}] = align_CPS_SHREC(file, confs);
            clear('vertices', 'sph_verts', 'faces', 'fvec');
        case 'AligFOE'
            diary(fullfile([confs.OutDirectory '/Logs'],[date, '_', num2str(round(cputime)), '_' name '_AlignFOE.log']));
            % Call AligFOE method
            [vertices, sph_verts, faces, fvec, outNames{end+1}] = align_FOE(file, confs);
            clear('vertices', 'sph_verts', 'faces', 'fvec');
        case 'AligLandmark'
            diary(fullfile([confs.OutDirectory '/Logs'],[date, '_', num2str(round(cputime)), '_' name '_AlignLDMK.log']));
            % Call AligLandmark method
            disp('Not Implmented');
    end
    diary('off');
    waitbar(i/numSbj)
end
close(h);

return


%This function develop by Renoald Tang
%University Teknologi Malaysia, Photogrammetry and Laser scanning group
%for academic purpose
%Email:renoald@live.com
%This function read Ply file

function readPly(file)
nv=numvert(file);
fprintf('Number_of_point:%d\n',nv);
nh=numhead(file);
fprintf('Number of end line:%d\n',nh);
nf=numface(file,nh);
fprintf('Number_of_face:%d\n',nf);
value(nh,file,nv)

%return number of vertext
function nv=numvert(file)
C=0;
fid=fopen(file);
while 1
    tline = fgetl(fid);
    C=C+1;
    if C==4

      num=textscan(tline,'%s %s %d');
        break;
    end
    if ~ischar(tline),   break,   end

end
fclose(fid);
nv=num{1,3};
%return number of face
function nf=numface(file,nh)
nh=nh-2;
C=0;
fid=fopen(file);
while 1
    tline = fgetl(fid);
    C=C+1;
     if ~ischar(tline),   break,   end

    if C==nh

      num=textscan(tline,'%s %s %d');
        break;
    end

end
fclose(fid);
nf=num{1,3};
%return the number of end_hearder
function nh=numhead(file)
C=0;
fid=fopen(file);
while 1
    tline = fgetl(fid);
    C=C+1;
    map1=findstr(tline,'end_header');
  b1=isempty(map1);
  if b1==0
      nh=C;

      break;
  end

    if ~ischar(tline),   break,   end

end
fclose(fid);
function value(nh,file,n)
%[K1,R]=check(file);
C=0;
K=0;
fid=fopen(file);
fid1=fopen('point','w');
fid2=fopen('face','w');
while 1
    tline=fgetl(fid);
    C=C+1;
     if ~ischar(tline) , break , end
    if C > nh
       K=K+1;
       if K <=n
           fprintf(fid1,'%s\n',tline);
       else
           fprintf(fid2,'%s\n',tline);
       end

    end

end
fclose(fid);
fclose(fid1);
fclose(fid2);%return and extract face and point value
%disp(K)


function pco_errdisp(txt,errorcode)
%if errorcode display error text with errornumber in HEX
%
err=pco_uint32err(errorcode);
if(err)
 disp([txt,' failed with error 0x',num2str(err,'%08X')]);
end
end

%if(errorcode<0)
%disp([txt,' failed with error 0x',num2str(4294967296+errorcode,'%08X')]);
%elseif(errorcode~=0)
% disp([txt,' failed with error 0x',num2str(errorcode,'%08X')]);
%end


hydro = struct();

hydro = readWAMIT(hydro,'sphere.out',[]);
hydro = radiationIRF(hydro,15,[],[],[],[]);
hydro = radiationIRFSS(hydro,[],[]);
hydro = excitationIRF(hydro,15,[],[],[],[]);
writeBEMIOH5(hydro)
plotBEMIO(hydro)


classdef Projector < handle

    properties (Access = protected)
        mesh
        connec
    end

    methods (Static, Access = public)

        function obj = create(cParams)
            p = ProjectorFactory();
            obj = p.create(cParams);
        end

    end

    methods (Static, Access = protected)

        function ord = determineQuadratureOrder(fun)
            switch fun.fType
                case 'L2'
                    ord = 'QUADRATIC';
                case 'FE'
%                     ord = 'LINEAR';
                    ord = 'QUADRATIC'; % needed to project P1 to P1D
                case 'GAUSSPOINTS'
                    ord = fun.quadrature.order;
            end
        end

    end

    methods (Access = protected)

        function init(obj, cParams)
            obj.mesh   = cParams.mesh;
            obj.connec = cParams.mesh.connec;
        end

    end

end


%demo_SingleRoomSRIR - Demonstrates the usage of the SingleRoomSRIR conventions.

% #Author: Michael Mihocic
% #Author: Michael Mihocic: header documentation updated (28.10.2021)
%
% SOFA Toolbox - demo script
% Copyright (C) Acoustics Research Institute - Austrian Academy of Sciences
% Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: https://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing  permissions and limitations under the License.

%% Get an empy conventions structure
clear;
conventions='SingleRoomSRIR';
disp(['Creating SOFA file with ' conventions 'conventions...']);
Obj = SOFAgetConventions(conventions);

%% Fill random data...
Obj.Data.IR=rand(4800,1);
Obj.ListenerPosition=zeros(4800,3); Obj.ListenerPosition(:,1)=1;
Obj.SourcePosition=zeros(4800,3); Obj.SourcePosition(:,2)=1;

% Add ReceiverDescriptions as string array
str={};
for ii=1:Obj.API.R
  str{ii,1}=['String' num2str(round(rand(1,1)*10000))];
end
Obj = SOFAaddVariable(Obj,'ReceiverDescriptions','RS',str);

%% Update dimensions
Obj=SOFAupdateDimensions(Obj);

%% Fill with attributes
Obj.GLOBAL_ListenerShortName = 'dummy';
Obj.GLOBAL_History = 'created with a demo script';
Obj.GLOBAL_DatabaseName = 'none';
Obj.GLOBAL_ApplicationName = 'Demo of the SOFA Toolbox';
Obj.GLOBAL_ApplicationVersion = SOFAgetVersion('API');
Obj.GLOBAL_Organization = 'Acoustics Research Institute';
Obj.GLOBAL_AuthorContact = 'michael.mihocic@oeaw.ac.at';

%% save the SOFA file
SOFAfn=fullfile(SOFAdbPath,'sofatoolbox_test',[conventions '_' Obj.GLOBAL_SOFAConventionsVersion '.sofa']);
disp(['Saving:  ' SOFAfn]);
Obj=SOFAsave(SOFAfn, Obj);


function volumeStruct = readLeksellVolumeFile(filename)
%"readLeksellVolumeFile"
%   Reads a Leksell volume file using decodeLeksellData and places the
%   fields into a datastructure with meaningful names.  This file contains
%   all contouring information for CERR.
%
%JRA 6/13/05
%
%LM: KRK, 8/11/07,  Added scaling on the xy contour positions to change mm
%                   to cm.
%
%Usage:
%   function volumeStruct = readLeksellVolumeFile(filename)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
% CERR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
% without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with CERR.  If not, see <http://www.gnu.org/licenses/>.

fid = fopen(filename, 'r', 'b');

data = decodeLeksellData(fid);

fclose(fid);

%First iterate over structures included in volume file.
for i = 1:length(data) - 1

    rawStruct = data{i};

    structureS(i).structName = rawStruct{2};
    structureS(i).registeredTo = rawStruct{1};

    allContours = rawStruct{4};

    contourS = [];

    %Iterate over contours for this structure
    for j=1:length(allContours)-1

        oneContour = allContours{j};

        contourS(j).sliceNum = oneContour{1};
        contourS(j).nVertices = oneContour{2};

        cData     = oneContour{3};
        xyMat = [];
        for k = 1:length(cData)
            xyMat = [xyMat;cData{k}{1}'];
        end

        contourS(j).contour = xyMat;
        contourS(j).rowExtent = [oneContour{6} oneContour{7}];
        contourS(j).colExtent = [oneContour{8} oneContour{9}];
        contourS(j).slcExtent = [oneContour{10} oneContour{11}];

    end

    structureS(i).contour = contourS;

end

volumeStruct = structureS;


% function inlap
% inlap.m
%
% make dialog interface for seislap
%
% Last change 7/95               A.Allmann

%
report_this_filefun(mfilename('fullpath'));

global ptime
global seis_inpu1 seis_inpu2 seis_inpu3 qui1
global repeat_button lapf maepi

%set catalog
if size(newcat)==0
    newcat=a;
end

%initial values
figure_w_normalized_uicontrolunits(mess)
clf
set(gca,'visible','off')
set(gcf,'Units','pixel','NumberTitle','off','Name','Input Parameters for Seislap');

set(gcf,'pos',[ wex  wey welx+100 wely+50])

bev=find(newcat.Magnitude==max(newcat.Magnitude)); %biggest events in catalog

%default values of input parameters
ldx=100;
latt=newcat(bev(1),2);
longt=newcat(bev(1),1);
Mmin=3;
ldepth=newcat(bev(1),7);
if quie==1
    qui1=1;
    tlap=100;
    binlength=10;
elseif quie==2
    qui1=2;
    tlap=10;
    binlength=1;
end

% creates a dialog box to input some parameters
%
txt1 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.96 0 ],...
    'Rotation',0 ,...
    'FontWeight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Minimum Magnitude: ');

txt2 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.81 0 ],...
    'Rotation',0 ,...
    'FontWeight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Please input DX in km ');

txt3 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.66 0 ],...
    'Rotation',0 ,...
    'FontWeight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Please input overlap time in days:');

txt4 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.51 0 ],...
    'Rotation',0 ,...
    'FontWeight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Longitude of point of interest:');
txt5 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.36 0 ],...
    'Rotation',0 ,...
    'FontWeight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Lattitude of point of interest:');

txt6 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.21 0 ],...
    'Rotation',0 ,...
    'FontWeight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Binlength in days:');

inp1_field  = uicontrol('Style','edit',...
    'Position',[.85 .87 .13 .08],...
    'Units','normalized','String',num2str(Mmin),...
    'Callback','Mmin=str2double(get(inp1_field,''String''));set(inp1_field,''String'',num2str(Mmin));');

inp2_field  = uicontrol('Style','edit',...
    'Position',[.85 .75 .13 .08],...
    'Units','normalized','String',num2str(ldx),...
    'Callback','ldx=str2double(get(inp2_field,''String''));set(inp2_field,''String'',num2str(ldx));');

inp3_field=uicontrol('Style','edit',...
    'Position',[.85 .63 .13 .08],...
    'Units','normalized','String',num2str(tlap),...
    'Callback','tlap=str2double(get(inp3_field,''String''));     set(inp3_field,''String'',num2str(tlap));');

inp4_field=uicontrol('Style','edit',...
    'Position',[.85 .51 .13 .08],...
    'Units','normalized','String',num2str(longt),...
    'Callback','longt=str2double(get(inp4_field,''String'')); set(inp4_field,''String'',num2str(longt));');

inp5_field=uicontrol('Style','edit',...
    'Position',[.85 .39 .13 .08],...
    'Units','normalized','String',num2str(latt),...
    'Callback','latt=str2double(get(inp5_field,''String'')); set(inp5_field,''String'',num2str(latt));');

inp6_field=uicontrol('Style','edit',...
    'Position',[.85 .27 .13 .08],...
    'Units','normalized','String',num2str(binlength),...
    'Callback','binlength=str2double(get(inp6_field,''String'')); set(inp6_field,''String'',num2str(binlength));');

close_button=uicontrol('Style','Pushbutton',...
    'Position', [.7 .05 .15 .12 ],...
    'Units','normalized','Callback','welcome','String','Cancel');

inflap_button=uicontrol('Style','Pushbutton',...
    'Position', [.47 .05 .15 .12 ],...
    'Units','normalized','Callback','clinfo(13)','String','Info');

go_button=uicontrol('Style','Pushbutton',...
    'Position',[.25 .05 .15 .12 ],...
    'Units','normalized',...
    'Callback','tlap=str2num(get(inp3_field,''String''));ldx=str2num(get(inp2_field,''String''));binlength=str2num(get(inp6_field,''String''));latt=str2num(get(inp5_field,''String''));longt=str2num(get(inp4_field,''String''));Mmin=str2num(get(inp1_field,''String''));clf;welcome;if quie==1 lap1=seislap2(ldx,tlap,binlength,longt,latt,Mmin,ldepth,1);elseif quie==2 lap1=seislap2(ldx,tlap,binlength,longt,latt,Mmin,ldepth,2);end;',...
    'String','Go');

%freeze_button = uicontrol(...
%'BackgroundColor',[ 0.7 0.7 0.7 ],...
%'Callback','fre = get(freeze_button,''Value'');',...
%'ForegroundColor',[ 0 0 0 ],...
%'Position',[ 0.25 0.30 0.4 0.15 ],...
%'String','Freeze Colorbar? ',...
%'Style','checkbox',...
%'Units','normalized',...
%'Visible','on');
%

set(gcf,'visible','on');watchoff