function out = domainCheck(f, g)
%DOMAINCHECK   True if the domains of two CHEBFUN3T objects are the same.
%   DOMAINCHECK(F, G) returns TRUE if the domains of the two CHEBFUN3T
%   objects F and G coincide up to a tolerance depending on their
%   horizontal scales or if both F and G are empty CHEBFUN objects.
%
% See also CHEBFUN/DOMAINCHECK.

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The CHEBFUN3T class uses this function internally to compare the domains of
% CHEBFUN3T objects before attempting to perform operations on multiple
% CHEBFUN3T objects that require the CHEBFUN3T objects to reside on the same interval.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Empty check:
if ( isempty(f) && isempty(g) )
    out = true;
    return
elseif ( xor(isempty(f), isempty(g) ) )
    out = false;
    return
end

% Compute INF norm of the domains:
hscaleF = norm(f.domain, inf);
hscaleG = norm(g.domain, inf);
hscale = max(hscaleF, hscaleG);

% Compare the domains:
err = f.domain - g.domain;

% Should be less than tolerance.
out = all(abs(err) < 1e-15*hscale);

end


% COMPHEADS - plot multiple TOPOPLOT maps of ICA component topographies
%
% Usage:
%       >> compheads(winv,'spline_file',compnos,'title',rowscols,labels,view)
%
% Inputs:
%   winv       - Inverse weight matrix = EEG scalp maps. Each column is a
%                map; the rows correspond to the electrode positions
%                defined in the eloc_file. Normally, winv = inv(weights*sphere).
%  spline_file - Name of the eloctrode position file in BESA spherical coords.
%   compnos    - Vector telling which (order of) component maps to show
%                Indices <0 tell COMPHEADS to invert a map; = 0 leave blank subplot
%                Example [1 0 -2 3 0 -6] {default|0 -> 1:columns_in_winv}
%  'title'     - Title string for each page {default|0 -> 'ICA Component Maps'}
%   rowscols   - Vector of the form [m,n] where m is total vertical tiles and n
%                is horizontal tiles per page. If the number of maps exceeds m*n,
%                multiple figures will be produced {def|0 -> one near-square page}.
%   labels     - Vector of numbers or a matrix of strings to use as labels for
%                each map {default|0 -> 1:ncolumns_in_winv}
%   view       - TOPOPLOT view, either [az el] or keyword ('top',...)
%                See >> help TOPOPLOT for options.
%
% Note: Map scaling is to +/-max(abs(data); green = 0
%
% Author: Scott Makeig, SCCN/INC/UCSD, La Jolla, 4-28-1998
%
% See also: TOPOPLOT

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

% 01-25-02 reformated help & license, added links -ad

function compheads(Winv,eloc_file,compnos,titleval,pagesize,srclabels,view)

if nargin<1
   help compheads
   return
end

[chans, frames] = size (Winv);

DEFAULT_TITLE = 'ICA Component Maps';
DEFAULT_EFILE = 'chan_file';
NUMCONTOUR = 5;     % topoplot() style settings
OUTPUT = 'screen';  % default: 'screen' for screen colors,
                    %          'printer' for printer colors
STYLE = 'both';
INTERPLIMITS = 'head';
MAPLIMITS = 'absmax';
SQUARE    = 1; % 1/0 flag making topoplot() asex square -> round heads

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check inputs and set defaults
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

printlabel = OUTPUT; % default set above
if nargin < 7
   view = [-127 30];
end

if nargin < 6
   srclabels = 0;
end
if nargin < 5
   pagesize = 0;
end
if nargin < 4
   titleval = 0;
end
if nargin < 3
   compnos = 0;
end
if nargin < 2
   eloc_file = 0;
end

if srclabels == 0
  srclabels = [];
end
if titleval == 0;
   titleval = DEFAULT_TITLE;
end
if compnos == 0
   compnos = (1:frames);
end
if pagesize == 0
   numsources = length(compnos);
   DEFAULT_PAGE_SIZE = ...
[floor(sqrt(numsources)) ceil(numsources/floor(sqrt(numsources)))];
   m = DEFAULT_PAGE_SIZE(1);
   n = DEFAULT_PAGE_SIZE(2);
elseif length(pagesize) ==1
   help compheads
   return
else
   m = pagesize(1);
   n = pagesize(2);
end
if eloc_file == 0
   eloc_file = DEFAULT_EFILE;
end

totalsources = length(compnos);
if ~isempty(srclabels)
  if ~ischar(srclabels(1,1)) % if numbers
    if size(srclabels,1) == 1
       srclabels = srclabels';
    end
  end
  if size(srclabels,1) ~= totalsources,
     fprintf('compheads(): numbers of components and component labels do not agree.\n');
     return
  end
end
pages = ceil(totalsources/(m*n));
if pages > 1
   fprintf('compheads(): will create %d figures of %d by %d maps: ',...
            pages,m,n);
end

pos = get(gcf,'Position');
off = [ 25 -25 0 0];  % position offsets for multiple figures

fid = fopen(eloc_file);
if fid<1,
  fprintf('compheads()^G: cannot open eloc_file (%s).\n',eloc_file);
  return
end
fclose(fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%% plot the maps %%%%%%%%%%%%%%%%%%%%%%%

for i = (1:pages)
  if i > 1
    figure('Position',pos+(i-1)*off); % place figures in right-downward stack
  end
  set(gcf,'Color','w') %CJH - set background color to white

  if (totalsources > i*m*n)
    sbreak = n*m;
  else
    sbreak = totalsources - (i-1)*m*n;
  end

  for j = (1:sbreak) % maps on this page
    comp = j+(i-1)*m*n; % compno index
    if compnos(comp)~=0
      if compnos(comp)>0
       source_var = Winv(:,compnos(comp))';       % plot map
      elseif compnos(comp)<0
       source_var = -1*Winv(:,-1*compnos(comp))'; % invert map
      end

      subplot(m,n,j)
      headplot(source_var,eloc_file,'electrodes','off','view',view);
      %topoplot(source_var,eloc_file,'style',STYLE,...
      % 'numcontour',NUMCONTOUR,'interplimits',INTERPLIMITS,...
      % 'maplimits',MAPLIMITS); % draw map
      if SQUARE,
         axis('square');
      end

      if isempty(srclabels)
          t=title(int2str(compnos(comp)));
          set(t,'FontSize',16);
      else
        if ischar(srclabels)
          t=title(srclabels(comp,:));
          set(t,'FontSize',16);
        else
	      t=title(num2str(srclabels(comp)));
          set(t,'FontSize',16);
        end
      end
      drawnow  % draw one map at a time
    end
  end

  ax = axes('Units','Normal','Position',[.5 .04 .32 .05],'Visible','Off');
  colorbar(ax)
  axval = axis;
  Xlim = get(ax,'Xlim');
  set(ax,'XTick',(Xlim(2)+Xlim(1))/2)
  set(gca,'XTickLabel','0')
  set(gca,'XTickMode','manual')

  axbig = axes('Units','Normalized','Position',[0 0 1 1],'Visible','off');
  t1 = text(.25,.070,titleval,'HorizontalAlignment','center','FontSize',14);
  if pages > 1
     fprintf('%d ',i);
  end
end
if pages > 1
   fprintf('\n');
end


% *************************************************************************************
% * DESCRIPTION:                                                                      *
% * This script computes parts of the experiments performed in ref. [1]               *
% * ('fast' version).                                                                 *
% * --------------------------------------------------------------------------------- *
% * REFERENCE:                                                                        *
% * [1] Vallieres, M. et al. (2015). A radiomics model from joint FDG-PET and         *
% *     MRI texture features for the prediction of lung metastases in soft-tissue     *
% *     sarcomas of the extremities. Physics in Medicine and Biology, 60(14),         *
% *     5471-5496. doi:10.1088/0031-9155/60/14/5471                                   *
% * --------------------------------------------------------------------------------- *
% * AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>                            *
% * --------------------------------------------------------------------------------- *
% * HISTORY:                                                                          *
% * - Creation: May 2015                                                              *
% * --------------------------------------------------------------------------------- *
% * STATEMENT:                                                                        *
% * This file is part of <https://github.com/mvallieres/radiomics/>,                  *
% * a package providing MATLAB programming tools for radiomics analysis.              *
% * --> Copyright (C) 2015  Martin Vallieres                                          *
% *                                                                                *
% *   This package 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 package 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 package.  If not, see <http://www.gnu.org/licenses/>.           *
% *************************************************************************************

fprintf('\n')
help masterScriptExample_STS
fprintf('\n')
warning off

% INITIALIZATION
pathWORK = pwd;
roiNumb = load('contour_Mass'); roiNumb = struct2cell(roiNumb); roiNumb = roiNumb{1};
outcome = load('outcome'); outcome = struct2cell(outcome); outcome = outcome{1};
nPatient = numel(outcome);

% TEXTURE EXTRACTION PARAMETERS AND DEGREES OF FREEDOM
MRIinv_cell = {'NoInv','Inv'};
MRIweight_mat = [1/3,2/3];
R_mat = [2/3,3/2];
scale_cell = {4,5};
algo_cell = {'Equal','Lloyd'};
Ng_mat = [8,16];
paramSEP = {R_mat,scale_cell,algo_cell,Ng_mat};                           % NOTE: paramSEP and paramFUS must always be of the same format and size for SEPARATE
paramFUS = {MRIinv_cell,MRIweight_mat,R_mat,scale_cell,algo_cell,Ng_mat}; % and FUSED SCANS as presented here, with the same ordering of different extraction parameters.
baselineSEP = [2,2,1,1]; % Arbitrarily chosen for the example
baselineFUS = [1,1,2,2,1,1]; % Arbitrarily chosen for the example
freedomSEP = [1 1 1 1 ; 0 0 0 0 ; 0 1 0 1]; % Arbitrarily chosen for the example
freedomFUS = [1 1 1 1 1 1 ; 0 0 0 0 0 0 ;  0 1 0 1 0 1]; % Arbitrarily chosen for the example

% MULTIVARIABLE ANALYSIS PARAMETERS
nBoot = 100;
alpha = 0.5; delta = 0.5;
setSize = 25;
fSetName = {'PET','SEPARATE','FUSED'};
maxOrder = 10;

% ************** START COMPUTATION **************

% 1. READ DATA DOWNLOADED FROM THE TCIA WEBSITE (http://dx.doi.org/10.7937/K9/TCIA.2015.7GO2GSKS)
fprintf('\n\n******************* ORGANIZING AND PROCESSING DICOM DATA FROM TCIA WEBSITE *******************\n')
readAllDICOM_STS([pathWORK,'/Soft-tissue-Sarcoma'],nPatient)

% 2. COMPUTE NON-TEXTURE FEATURES
fprintf('\n\n*********************** COMPUTING NON-TEXTURE FEATURES ***********************\n')
calcAllNonTextureFeatures_STS(pathWORK,nPatient,roiNumb,outcome)

% 3. COMPUTE AND ORGANIZING ALL TEXTURE FEATURES
mkdir('TEXTURES'), fprintf('\n')
calcAllSeparateTextures_STS(pathWORK,nPatient,roiNumb,R_mat,scale_cell,algo_cell,Ng_mat)
organizeSeparateTextures_STS(pathWORK,nPatient,R_mat,scale_cell,algo_cell,Ng_mat)
calcAllFusedTextures_STS(pathWORK,nPatient,roiNumb,MRIinv_cell,MRIweight_mat,R_mat,scale_cell,algo_cell,Ng_mat)
organizeFusedTextures_STS(pathWORK,nPatient,MRIinv_cell,MRIweight_mat,R_mat,scale_cell,algo_cell,Ng_mat)

% 5. PERFORM FEATURE SET REDUCTION
mkdir('FSET')
nonTextures = load('nonTextures'); nonTextures = struct2cell(nonTextures); nonTextures = nonTextures{1};
PET  = load('textures_PET');  PET  = struct2cell(PET);  PET  = PET{1};
T1   = load('textures_T1');   T1   = struct2cell(T1);   T1   = T1{1};
T2FS = load('textures_T2FS'); T2FS = struct2cell(T2FS); T2FS = T2FS{1};
PET_T1   = load('textures_PET_T1');   PET_T1   = struct2cell(PET_T1);   PET_T1   = PET_T1{1};
PET_T2FS = load('textures_PET_T2FS'); PET_T2FS = struct2cell(PET_T2FS); PET_T2FS = PET_T2FS{1};

tic
fprintf('\n\nFinding the path to the ''MINE.jar'' application on the system ... ')
pathMINE = findMINE('Linux');
fprintf('DONE\n')
toc

% For Feature set 1: PET
fprintf('\n*********************** PERFORMING FEATURE SET REDUCTION FOR ''PET'' FEATURE SET ***********************\n')
calcAllFeatureSets_STS(pathWORK,pathMINE,fSetName{1},outcome,setSize,nonTextures,{PET},{'PET'},paramSEP,freedomSEP,baselineSEP,alpha,delta,nBoot)

% For Feature set 2: PET, T1, T2FS
fprintf('\n*********************** PERFORMING FEATURE SET REDUCTION FOR ''SEPARATE'' FEATURE SET **********************\n')
calcAllFeatureSets_STS(pathWORK,pathMINE,fSetName{2},outcome,setSize,nonTextures,{PET,T1,T2FS},{'PET','T1','T2FS'},paramSEP,freedomSEP,baselineSEP,alpha,delta,nBoot)

% For Feature set 3: PET_T1, PET_T2FS
fprintf('\n*********************** PERFORMING FEATURE SET REDUCTION FOR ''FUSED'' FEATURE SET ***********************\n')
calcAllFeatureSets_STS(pathWORK,pathMINE,fSetName{3},outcome,setSize,nonTextures,{PET_T1,PET_T2FS},{'PET_T1','PET_T2FS'},paramFUS,freedomFUS,baselineFUS,alpha,delta,nBoot)

% 6. PERFORM FEATURE SET SELECTION
mkdir('MODELS')
fprintf('\n\nFinding the path to''fastAUC.cpp'' on the system --> COMPILATION ... ')
try
    compileFastAUC('Linux')
    fprintf('DONE\n')
catch
    fprintf('FAILED (AUC computations will be slower)\n')
end

% For Feature set 1: PET
fprintf('\n*********************** PERFORMING FEATURE SELECTION FOR ''PET'' FEATURE SET ***********************\n')
computeAllModelChoice_STS(pathWORK,fSetName{1},outcome,freedomSEP,maxOrder,nBoot)

% For Feature set 2: PET, T1, T2FS
fprintf('\n*********************** PERFORMING FEATURE SELECTION  FOR ''SEPARATE'' FEATURE SET ***********************\n')
computeAllModelChoice_STS(pathWORK,fSetName{2},outcome,freedomSEP,maxOrder,nBoot)

% For Feature set 3: PET_T1, PET_T2FS
fprintf('\n*********************** PERFORMING FEATURE SELECTION  FOR ''FUSED'' FEATURE SET ***********************\n')
computeAllModelChoice_STS(pathWORK,fSetName{3},outcome,freedomFUS,maxOrder,nBoot)

% 7. PERFORM PREDICTION PERFORMANCE ESTIMATION
mkdir('RESULTS'), fprintf('\n')

% For Feature set 1: PET
fprintf('\n*********************** PERFORMING PREDICTION PERFORMANCE ESTIMATION FOR ''PET'' FEATURE SET ***********************\n')
computeAllPrediction_STS(pathWORK,fSetName{1},outcome,freedomSEP,maxOrder,nBoot)

% For Feature set 2: PET, T1, T2FS
fprintf('\n*********************** PERFORMING PREDICTION PERFORMANCE ESTIMATION FOR ''SEPARATE'' FEATURE SET ***********************\n')
computeAllPrediction_STS(pathWORK,fSetName{2},outcome,freedomSEP,maxOrder,nBoot)

% For Feature set 3: PET_T1, PET_T2FS
fprintf('\n*********************** PERFORMING PREDICTION PERFORMANCE ESTIMATION FOR ''FUSED'' FEATURE SET ***********************\n')
computeAllPrediction_STS(pathWORK,fSetName{3},outcome,freedomFUS,maxOrder,nBoot)

% Finding the best combinations of model order and texture extraction parameter degree of freedom for all feature set types
groupExperiments_STS(pathWORK,fSetName{1},freedomSEP,maxOrder)
groupExperiments_STS(pathWORK,fSetName{2},freedomSEP,maxOrder)
groupExperiments_STS(pathWORK,fSetName{3},freedomFUS,maxOrder)

% 8. CHOICE OF BEST PARSIMONIOUS MODEL (requires user input)
fprintf('\n')
plotPredictionResults_STS([pathWORK,'/RESULTS'],fSetName,{'AUC632','Sensitivity632','Specificity632'},maxOrder)
while 1
    set = input(['\nWhich feature set provides the best parsimonious model? \n' ...
                 '--> For the ',fSetName{1},' feature set, type ''1'' and press ENTER \n' ...
                 '--> For the ',fSetName{2},' feature set, type ''2'' and press ENTER \n' ...
                 '--> For the ',fSetName{3},' feature set, type ''3'' and press ENTER \n' ...
                 'ANSWER: ']);
    fprintf('\n')
    if isnumeric(set) && (set == 1 || set == 2 || set == 3)
        break
    end
end
while 1
    order = input(['Which model order of the ',fSetName{set},' feature set provides the best parsimonious model? \n' ...
                   '--> Type a number between 1 to ',num2str(maxOrder),' and press ENTER \n' ...
                   'ANSWER: ']);
    fprintf('\n')
    if isnumeric(order) && order <= 10 && order >= 1
        break
    end
end
cd([pathWORK,'/RESULTS'])
results = load(['RESULTS_',fSetName{set},'_BEST']); results = struct2cell(results); results = results{1};
finalModel = results.(['Order',num2str(order)]);
cd(pathWORK), mkdir('FINAL_MODEL'), cd('FINAL_MODEL'), save('finalModel', 'finalModel')

% 9. COMPUTING THE LOGISTIC REGRESSION COEFFICIENTS AND BOOTSTRAP CONFIDENCE INTERVALS OF THE FINAL MODEL
fprintf('\n\nCOMPUTING THE LOGISTIC REGRESSION COEFFICIENTS OF THE FINAL MODEL ... ')
tic
[coeff,response,modelCI] = computeModelCoefficients(finalModel.Data,outcome,'IABR');
save('coeff','coeff'), save('response','response'), save('modelCI','modelCI')
fprintf('DONE\n')
toc

% 10. DISPLAYING THE FINAL MODEL AND CORRESPONDING PREDICTION PERFORMANCE ESTIMATION
plotSigmoidalResponse(response,outcome,modelCI,'LungMets')
fprintf(['\n\n\n --> THE FINAL MULTIVARIABLE MODEL IS:\n\n'...
         '               g(x) =               \n'])
for i = 1:order
    fprintf([num2str(coeff(i)),' X ',finalModel.Name{i},'\n'])
    fprintf('                    +               \n')
end
fprintf(['                   ',num2str(coeff(end)),'\n'])
fprintf('\nWITH CORRESPONDING PREDICTION PERFORMANCE ESTIMATION:\n')
fprintf(['AUC = ',num2str(roundsd(finalModel.AUC632,ceil(log10(finalModel.AUC632/roundsd(finalModel.SE_AUC632,1))))),' ± ',num2str(roundsd(finalModel.SE_AUC632,1)),'\n'])
fprintf(['Sensitivity = ',num2str(roundsd(finalModel.Sensitivity632,ceil(log10(finalModel.Sensitivity632/roundsd(finalModel.SE_Sensitivity632,1))))),' ± ',num2str(roundsd(finalModel.SE_Sensitivity632,1)),'\n'])
fprintf(['Specificity = ',num2str(roundsd(finalModel.Specificity632,ceil(log10(finalModel.Specificity632/roundsd(finalModel.SE_Specificity632,1))))),' ± ',num2str(roundsd(finalModel.SE_Specificity632,1)),'\n'])
fprintf('\n')
cd(pathWORK)


classdef marrmotBMI_oct < handle
    % MARRMoT m01 implemented as a BMI model

    properties
        % BMI required
        startTime           % start time
        endTime             % end time
        dt                  % time step size
        time_unit           % units of time
        time = 1;           % current time step
        lat                 % latitude
        lon                 % longitude

        % Indepdendent of model
        forcing = struct('precip',0,...             % time series of precipitation
                         'temp',0,...               % time series of temperature
                         'pet',0,...                % time series of potential evapotranspiration
                         'delta_t',0,...            % time step size in [days]
                         'time_unit','str');        % string with time units
        solver = struct('name','str',...            % string with solver function name
                        'resnorm_tolerance',0,...   % approximation accuracy
                        'resnorm_maxiter',0);       % max number of re-runs

            % Output storage for a single time-step
            output_externalFluxes = struct('Q',0,...    % Streamflow
                                           'Ea',0);     % Actual evap
            output_internalFluxes = struct('tmp',0);    % Internal fluxes, will be appended later
            output_modelStorages  = struct('S1',0);     % Model stores, can be appended later
            output_waterBalance   = 0;                  % Can be an optional argument to return a water balance check

        % Dependent on the model
        model_name          % name of the model function file
        parameters          % parameter values from some source
        store_num           % number of stores
        path                % location of config file
        store_cur           % vector with current model states
    end

    %the following is the heart of the BMI class. Every BMI model needs to
    %implement these methods. For some methods a standard implementation is
    %provided (example: update_until). These can be overwritten by
    %implementing them in the model class file. See the AR1class.m for an
    %example. Methods that are not implemented will throw an error msg
    %declaring they are not implemented.
    %See the BMI reference for more details.
    methods

        % Unsure whether this is still needed - check
%         function obj=m01BMI()
%         end

%% Model control functions

        % Initialize the model: this (1) loads data, (2) selects the model,
        % (3) sets all the settings needed to run the model; all from a
        % single _model-specific_ config file.
        function  initialize(obj,path)
            % Load config file
            load(path)                          % contains everything needed to run the model, plus BMI stuff

            % Assign values to object
            obj.model_name = model_name;
            obj.startTime  = time_start;
            obj.endTime    = time_end;
            obj.dt         = forcing.delta_t_days;
            obj.time_unit  = forcing.time_unit;
            obj.forcing    = forcing;
            obj.solver     = solver;
            obj.parameters = parameters;
            obj.store_cur  = store_ini;         % this value gets updated on every update() call
            obj.store_num  = length(store_ini);
            obj.path       = path;
            obj.lat        = data_origin(1);
            obj.lon        = data_origin(2);
        end

        % Run model for 1 time step
        function update(obj)

           % Get the forcing for this time step
            input_forcing.precip       = obj.forcing.precip(obj.time);
            input_forcing.temp         = obj.forcing.temp(obj.time);
            input_forcing.pet          = obj.forcing.pet(obj.time);
            input_forcing.delta_t      = obj.forcing.delta_t_days;

           % Run model for 1 time step
            [output_ex,...                                                  % Fluxes leaving the model: simulated flow (Q) and evaporation (Ea)
             output_in,...                                                  % Internal model fluxes
             output_ss,...                                                  % Internal storages
             ] = ...                                                        % Water balance check
                                feval(obj.model_name,...                    % Model function name
                                      input_forcing,...                     % Time series of climatic fluxes in simulation period
                                      obj.store_cur,...                     % Initial storages
                                      obj.parameters,...                    % Parameter values
                                      obj.solver);                          % Solver settings

            % Update variables
            obj.store_cur             = structfun(@mean,output_ss);         % ugly hack to get the current storages out of the structure, but works in octave
            obj.output_externalFluxes = output_ex;
            obj.output_internalFluxes = output_in;
            obj.output_modelStorages  = output_ss;
%            obj.output_waterBalance   = output_wb;
            obj.time                  = obj.time + obj.dt;
        end

        % Function to continously run the model
        function update_until(obj,until_time)
            while (obj.time <= until_time)
                obj.update;
            end
        end

        % Finalize (empty)
        function finalize()
        end

%% Variable getter and setter

        % Get current values
        function output = get_value(obj,long_var_name)
            switch long_var_name
                case 'P'
                    output = obj.forcing.precip;
                case 'T'
                    output = obj.forcing.temp;
                case 'Ep'
                    output = obj.forcing.pet;
                case 'S(t)'
                    output = obj.store_cur;
                case 'mod'
                    output = obj.model_name;
                case 'par'
                    output = obj.parameters;
                case 'sol'
                    output = obj.solver;
                case 'flux_out'
                    output = obj.output_externalFluxes;
                case 'flux_in'
                    output = obj.output_internalFluxes;
                case 'wb'
                    output = obj.output_waterBalance;
                otherwise
                    error('unkown variable');
            end
        end

        function output = get_value_at_indices(obj,long_var_name, inds)
            if inds ~= [0,0]
                error(['Indices out of bounds.']);
            else
                output = get_value(obj,long_var_name);
            end
        end

        % Set inputs using handles
        function set_value(obj,long_var_name, src)
            switch long_var_name
                case 'P'
                    obj.forcing.precip = src;
                case 'T'
                    obj.forcing.temp = src;
                case 'Ep'
                    obj.forcing.pet = src;
                case 'S(t)'
                    obj.store_cur = src;
                case 'mod'
                    obj.model_name = src;
                case 'par'
                    obj.parameters = src;
                case 'sol'
                    obj.solver = src;
                case 'flux_out'
                    obj.output_externalFluxes = src;
                case 'flux_in'
                    obj.output_internalFluxes = src;
                case 'wb'
                    obj.output_waterBalance = src;
                otherwise
                    error('unkown variable');
            end
        end

        function set_value_at_indices(obj,long_var_name, inds, src)
            if inds ~= [0,0]
                error(['Indices out of bounds.']);
            else
                set_value(obj,long_var_name, src);
            end
        end

%% Model information functions

        % Get input variable names
        function output = get_input_var_names(obj)
            output={'Precipitation time series > P',...
                    'Temperature time series > T',...
                    'Potential evapotranspiration time series > Ep',...
                    'Storages (time = t) > S(t)',...
                    'Model function name > mod',...
                    'Parameters > par',...
                    'Solver > sol'};
        end

        % Get output variable names
        function output = get_output_var_names(obj)
            output={'Fluxes leaving the model > flux_out',...
                    'Internal fluxes > flux_in',...
                    'Storages (time = t) > S(t)',...
                    'Water balance check > wb'};
        end

        % Model components
        function output = get_component_name(obj)
            output=['BMI implemented for MARRMoT models, currently running ',obj.model_name];
        end

%% Time functions

        % Start time
        function output = get_start_time(obj)
            # datenum returns the date as a serial number since Jan 1 0000
            # output will return the date as a number of days since CUT - 1 Jan 1970
            CUT_time = [1970 01 01 0 0 0];
            output = datenum(obj.startTime) - datenum(CUT_time);
            # output = datenum(obj.startTime);
        end

        % End time
        function output = get_end_time(obj)
            # output will return the date as a number of days since CUT - 1 Jan 1970
            CUT_time = [1970 01 01 0 0 0];
            output = datenum(obj.endTime) - datenum(CUT_time);
        end

        % Time units
        function output = get_time_units(obj)
            timeformat_index = strncmp(obj.time_unit, 'days', 3);
            if timeformat_index ~= 0
              commandstring = "days since 1970-01-01 00:00:00.0 00:00";
              output = commandstring;
            else
              output = obj.time_unit;
            end
        end

        % Current time
        function output = get_current_time(obj)
            CUT_time = [1970 01 01 0 0 0];
            t_current = obj.time + datenum(obj.startTime)- datenum(CUT_time) - 1;
            output = t_current;
        end

        % Time step
        function output = get_time_step(obj)
            output=obj.dt;
        end

%% Model grid

        % Grid type
        function output = get_grid_type(~)
            output = 'uniform_rectilinear';         % Fixed for all MARRMoT models
        end

        % Grid rank
        function output = get_grid_rank(~)
            output = 2;                             % Fixed for all MARRMoT models
        end

        % Grid size
        function output = get_grid_size(~)
            output = 1;                             % Fixed for all MARRMoT models
        end

        % Grid shape
        function output = get_grid_shape(~)
            output = [1,1];                         % Fixed for all MARRMoT models
        end

        % Grid origin
        function output = get_grid_origin(obj)
            output = [obj.lat,obj.lon];
        end

        % Grid spacing
        function output = get_grid_spacing(~)
            output = [0,0];                         % Fixed for all MARRMoT models
        end

        % Grid X
        function output = get_grid_x(~)
            output = 1;                              % Fixed for all MARRMoT models
        end

        % Grid Y
        function output = get_grid_y(~)
            output = 1;                              % Fixed for all MARRMoT models
        end

        % Grid Z
        function output = get_grid_z(~)
            output = 1;                              % Fixed for all MARRMoT models
        end

%% Variable information

        % Units
        function output = get_var_units(obj,long_var_name)
            switch long_var_name
                case 'P'
                    output = ['mm ',obj.time_unit];
                case 'T'
                    output = 'degree C';
                case 'Ep'
                    output = ['mm ',obj.time_unit];
                case 'S(t)'
                    output = 'mm';
                case 'mod'
                    output = '-';
                case 'par'
                    output = 'see model documentation';
                case 'sol'
                    output = '-';
                case 'flux_out'
                    output = ['mm ',obj.time_unit];
                case 'flux_in'
                    output = ['mm ',obj.time_unit];
                case 'wb'
                    output = 'mm';
                otherwise
                    error('unkown variable. please use one of the following variables: P, T, Ep, S, mod, par, sol, f;ux_out, flux_in, wb');
            end
        end

        % Type
        function output = get_var_type(obj,long_var_name)
            switch long_var_name
                case 'P'
                    tmp = obj.forcing.precip;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'T'
                    tmp = obj.forcing.temp;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'Ep'
                    tmp = obj.forcing.pet;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'S(t)'
                    tmp = obj.store_cur;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'mod'
                    tmp = obj.model_name;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'par'
                    tmp = obj.parameters;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'sol'
                    tmp = obj.solver;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'flux_out'
                    tmp = obj.output_externalFluxes;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'flux_in'
                    tmp = obj.output_internalFluxes;
                    tmp = whos('tmp');
                    output = tmp.class;
                case 'wb'
                    tmp = obj.output_waterBalance;
                    tmp = whos('tmp');
                    output = tmp.class;
                otherwise
                    error('unkown variable');
            end
        end

        % Item size
        function output = get_var_itemsize(obj,long_var_name)
            switch long_var_name
                case 'P'
                    tmp = obj.forcing.precip;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'T'
                    tmp = obj.forcing.temp;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'Ep'
                    tmp = obj.forcing.pet;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'S(t)'
                    tmp = obj.store_cur;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'mod'
                    tmp = obj.model_name;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'par'
                    tmp = obj.parameters;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'sol'
                    tmp = obj.solver;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'flux_out'
                    tmp = obj.output_externalFluxes;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'flux_in'
                    tmp = obj.output_internalFluxes;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                case 'wb'
                    tmp = obj.output_waterBalance;
                    tmp = whos('tmp');
                    output = tmp.bytes/(tmp.size(1)*tmp.size(2));
                otherwise
                    error('unkown variable');
            end
        end

        % Item nbytes
        function output = get_var_nbytes(obj,long_var_name)
            switch long_var_name
                case 'P'
                    tmp = obj.forcing.precip;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'T'
                    tmp = obj.forcing.temp;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'Ep'
                    tmp = obj.forcing.pet;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'S(t)'
                    tmp = obj.store_cur;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'mod'
                    tmp = obj.model_name;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'par'
                    tmp = obj.parameters;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'sol'
                    tmp = obj.solver;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'flux_out'
                    tmp = obj.output_externalFluxes;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'flux_in'
                    tmp = obj.output_internalFluxes;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                case 'wb'
                    tmp = obj.output_waterBalance;
                    tmp = whos('tmp');
                    output = tmp.bytes;
                otherwise
                    error('unkown variable');
            end
        end

        % Grid
        function output = get_var_grid(obj,long_var_name)
            output = 1;                 % Grid size is 1 for all models, so arbitrary values
        end

        % Location
        function output = get_var_location(obj,long_var_name)
            output = 'face';            % Grid size is 1 for all models, so arbitrary values
        end

    end
end


function RegOpticalFlow(handles, clipBox)
%
% 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/>.

global planC stateS;

indexS = planC{end};

    [originF, spacingF, centerF] = getScanOriginSpacing(planC{indexS.scan}(stateS.imageRegistrationBaseDataset));

    [originM, spacingM, centerM] = getScanOriginSpacing(planC{indexS.scan}(stateS.imageRegistrationMovDataset));

    method = get(handles.para.optFlowMethod, 'value');
    RegLevels = str2double(get(handles.para.optFlowRegistLevel, 'string'));

    output = cell(1, 16);

    if isempty(clipBox)
        FixedImg = planC{indexS.scan}(stateS.imageRegistrationBaseDataset).scanArray;
        MovingImg = planC{indexS.scan}(stateS.imageRegistrationMovDataset).scanArray;
    else
        FixedImg = planC{indexS.scan}(stateS.imageRegistrationBaseDataset).scanArray(clipBox(2):clipBox(4), clipBox(1):clipBox(3), :);
        MovingImg = planC{indexS.scan}(stateS.imageRegistrationMovDataset).scanArray(clipBox(2):clipBox(4), clipBox(1):clipBox(3), :);
    end

    xyScale =  1; zScale = 1; DesampleTime = '0';
    %downsample the input datasets
    if (get(handles.dsampleCheck,'Value') == get(handles.dsampleCheck,'Max'))

        tic;
        xyScale =  2; zScale = 2;
        spacingF = [spacingF(1)*xyScale spacingF(2)*xyScale spacingF(3)*zScale];
        spacingM = [spacingM(1)*xyScale spacingM(2)*xyScale spacingM(3)*zScale];
        disp('downSampling ...');

%         FImg = imdesample3d(FixedImg,xyScale,zScale);
%         MImg = imdesample3d(MovingImg,xyScale,zScale);
        FImg=GPReduce2(FixedImg,2,0);
        MImg=GPReduce2(MovingImg,2,0);

        toc;
        DesampleTime = num2str(ceil(toc/60));
    else
        FImg = FixedImg;
        MImg = MovingImg;
    end

%     call registration method
    switch method
        case 1
            methodIndex = 1;
        case 2
            methodIndex = 2;
        case 3
            methodIndex = 9;
        case 4
            methodIndex = 13;
        case 5
            methodIndex = 15;
        case 6
            methodIndex = 16;
        case 7
            methodIndex = 17;
        case 8
            methodIndex = 18;

    end

    tic;
    RegTime = '0';

    try
        [mvy,mvx,mvz,im]=multigrid_nogui6(          methodIndex, ... %method,
                                                    MImg, ...%Moving Image,
                                                    FImg, ...%Fixed Image,
                                                    spacingF,   ...%ratio,
                                                    RegLevels);    %steps,

        maxv = max(max(MImg(:)),max(FImg(:)));
        im = im * single(maxv);
        im = cast(im, class(FImg));

        toc;
        RegTime = num2str(ceil(toc/60));
    catch
        disp('Out of Memory, Registration failed, please restart Matlab!');
        return;
    end

% if downsampled, upsample the deformation fields.
    imIsDownsampled = 0;
    if ~(xyScale == 1 && zScale == 1)
        try
            [mvy,mvx,mvz] = recalculate_mvs(mvy,mvx,mvz);
            im = move3dimage(single(MovingImg),mvy,mvx,mvz); %deform the image with upsampled df fields.
        catch
            disp('Out of Memory, can not upscaling the motion field, system will save the downsampled field!');
            imIsDownsampled = 1;
        end
    end

% save the base image for analysis
    if ~isempty(clipBox) || imIsDownsampled

        planC{indexS.scan}(end+1) = planC{indexS.scan}(stateS.imageRegistrationBaseDataset);
        planC{indexS.scan}(end).scanArraySuperior = [];
        planC{indexS.scan}(end).scanArrayInferior = [];

        if (imIsDownsampled)
            bImg = FImg;
        else
            bImg = FixedImg;
        end
        planC{indexS.scan}(end).scanArray = int16(bImg);

        % setup scan info
        [xV, yV, zV] = getScanXYZVals(planC{indexS.scan}(stateS.imageRegistrationBaseDataset));
        if ~isempty(clipBox)
            xRange = [xV(clipBox(1)) xV(clipBox(3))];
            yRange = [yV(clipBox(4)) yV(clipBox(2))];
        else
            xRange = [xV(1) xV(end)];
            yRange = [yV(end) yV(1)];
        end

        for i = 1:length(planC{indexS.scan}(end).scanInfo)
            planC{indexS.scan}(end).scanInfo(i).sizeOfDimension1 = size(bImg,1);
            planC{indexS.scan}(end).scanInfo(i).sizeOfDimension2 = size(bImg,2);
            %planC{indexS.scan}(end).scanInfo(i).CTOffset = -1*min(bImg(:));
            planC{indexS.scan}(end).scanInfo(i).xOffset = (xRange(1)+xRange(2))/2;
            planC{indexS.scan}(end).scanInfo(i).yOffset = (yRange(1)+yRange(2))/2;
        end
    end

% save the deformed image and deformation fields
    scanSetM = stateS.imageRegistrationMovDataset;
    scanSetF = stateS.imageRegistrationBaseDataset;

    planC{indexS.scan}(end+1) = planC{indexS.scan}(scanSetF);
    planC{indexS.scan}(end).scanArraySuperior = [];
    planC{indexS.scan}(end).scanArrayInferior = [];
    planC{indexS.scan}(end).scanArray = int16(im);
    planC{indexS.scan}(end).deformInfo.BaseUID = planC{indexS.scan}(scanSetF).scanUID;
    planC{indexS.scan}(end).deformInfo.MoveUID = planC{indexS.scan}(scanSetM).scanUID;
    planC{indexS.scan}(end).deformInfo.DFX = mvx;
    planC{indexS.scan}(end).deformInfo.DFY = mvy;
    planC{indexS.scan}(end).deformInfo.DFZ = mvz;

    planC{indexS.scan}(end).scanUID = createUID('CT');

    planC{indexS.scan}(end).deformInfo.clipBox = clipBox;
    if ~(xyScale == 1 && zScale == 1)
        planC{indexS.scan}(end).deformInfo.downSampled = 'true';
    else
        planC{indexS.scan}(end).deformInfo.downSampled = 'false';
    end
% setup scan info
    [xV, yV, zV] = getScanXYZVals(planC{indexS.scan}(scanSetF));
    xRange = [xV(clipBox(1)) xV(clipBox(3))];
    yRange = [yV(clipBox(4)) yV(clipBox(2))];
    for i = 1:length(planC{indexS.scan}(end).scanInfo)
        planC{indexS.scan}(end).scanInfo(i).sizeOfDimension1 = size(im,1);
        planC{indexS.scan}(end).scanInfo(i).sizeOfDimension2 = size(im,2);
        %planC{indexS.scan}(end).scanInfo(i).CTOffset = -1*min(im(:));
        planC{indexS.scan}(end).scanInfo(i).xOffset = (xRange(1)+xRange(2))/2;
        planC{indexS.scan}(end).scanInfo(i).yOffset = (yRange(1)+yRange(2))/2;
    end

% refresh view
    controlFrame('refresh');
    sliceCallBack('refresh');
    close('Registration Setup');

end


% The COBRAToolbox: testPartition.m
%
% Purpose:
%     - tests the basic functionality of swiftcc++ algorithm
%
% Authors:
%     - Original file: Mojtaba Tefagh, March 2019
%

global CBTDIR

% require the specified toolboxes and solvers
solvers = prepareTest('needsLP', true, 'useSolversIfAvailable', {'gurobi'}, ...
    'requiredToolboxes', {'bioinformatics_toolbox'});

% save the current path
currentDir = pwd;

% initialize the test
testPass = fileparts(which('testPartition.m'));
cd(testPass);

% load the model
model = getDistributedModel('ecoli_core_model.mat');
model.rev = double(model.lb < 0);
A = fastcc(model, 1e-4, 0);

% set the cobra solver
solverLPOK = changeCobraSolver(solvers.LP{1}, 'LP', 0);

fprintf('\n -- Running swiftcc++ using the %s solver...\n\n', solvers.LP{1});
component = partition(model, solvers.LP{1}, 'swift');
assert(all(component(A)));
assert(length(A) == sum(component));

% output a success message
fprintf('\nDone.\n');

% change the directory
cd(currentDir)


function mesh( PSF )
%
%  Overload mesh for psf object.  This is preliminary
%  version, and needs some work.
%

%  J. Nagy 1/8/02

I = PSF.image;
switch length(size(I{1}))
case 1
  plot(I)
case 2
  [m, n] = size(I);
  for i=1:m
    for j = 1:n
      subplot(m,n,(i-1)*n+j), mesh(I{i,j})
    end
  end
case 3
  if size(I,3) > 1
    disp('We only display one of the spatially variant PSFs')
  end
  P = I{1,1,1};
  v = [0, size(P,1), 0, size(P,2), min(P(:)), max(P(:))];
  for k = 1:size(P,3)
    mesh(P(:,:,k)), axis(v), drawnow
  end
otherwise
  error('illegal PSF dimension')
end


function [f, df, d2f] = eval_legacy_cost(om, x, name, idx)
%EVAL_LEGACY_COST  Evaluates individual or full set of legacy user costs.
%   F = OM.EVAL_LEGACY_COST(X ...)
%   [F, DF] = OM.EVAL_LEGACY_COST(X ...)
%   [F, DF, D2F] = OM.EVAL_LEGACY_COST(X ...)
%   [F, DF, D2F] = OM.EVAL_LEGACY_COST(X, NAME)
%   [F, DF, D2F] = OM.EVAL_LEGACY_COST(X, NAME, IDX_LIST)
%   Evaluates an individual named set or the full set of legacy user
%   costs and their derivatives for a given value of the optimization vector
%   X, based on costs added by ADD_LEGACY_COST.
%
%   Example:
%       [f, df, d2f] = om.eval_legacy_cost(x)
%       [f, df, d2f] = om.eval_legacy_cost(x, name)
%       [f, df, d2f] = om.eval_legacy_cost(x, name, idx)
%
%   See also OPT_MODEL, ADD_LEGACY_COST, PARAMS_LEGACY_COST.

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

if om.cost.N
    done = 0;

    %% collect cost parameters
    if nargin < 3                       %% full set
        [cp, vs] = om.params_legacy_cost();
    elseif nargin < 4 || isempty(idx)   %% name, no idx provided
        dims = size(om.cost.idx.i1.(name));
        if prod(dims) == 1              %% simple named set
            [cp, vs] = om.params_legacy_cost(name);
        elseif nargout == 1             %% indexing required, recurse
            f = 0;          %% initialize cumulative cost
            idx = num2cell(ones(size(dims))); %% initialize idx
            while ~done     %% call eval_legacy_cost() recursively
                f = f + om.eval_legacy_cost(x, name, idx);

                %% increment idx
                D = length(dims);
                idx{D} = idx{D} + 1;    %% increment last dimension
                for d = D:-1:2          %% increment next dimension, if necessary
                    if idx{d} > dims(d)
                        idx{d} = 1;
                        idx{d-1} = idx{d-1} + 1;
                    end
                end
                if idx{1} > dims(1)     %% check if done
                    done = 1;
                end
            end
        else
            error('@opt_model/eval_legacy_cost: legacy cost set ''%s'' requires an IDX_LIST arg when requesting DF output', name)
        end
    else                                %% indexed named set
        [cp, vs] = om.params_legacy_cost(name, idx);
    end

    if ~done
        %% assemble appropriately-sized x vector
        xx = om.varsets_x(x, vs, 'vector');

        %% compute function & derivatives
        if nargout == 1
            f = opf_legacy_user_cost_fcn(xx, cp);
        elseif nargout == 2
            [f, df] = opf_legacy_user_cost_fcn(xx, cp);
        else    %% nargout == 3
            [f, df, d2f] = opf_legacy_user_cost_fcn(xx, cp);
        end
    end
else
    f = 0;
    if nargout > 1
        df = [];
        if nargout > 2
            d2f = [];
        end
    end
end


function varargout = atanh(varargin)

switch class(varargin{1})

    case 'sdpvar'
        varargout{1} = InstantiateElementWise(mfilename,varargin{:});

    case 'char'

        operator = CreateBasicOperator('increasing','callback');
        operator.derivative = @(x)((1 + x.^2).^-0.5);
        operator.inflection = [-inf -1 0 1];
        operator.domain = [-1 1];

        varargout{1} = [];
        varargout{2} = operator;
        varargout{3} = varargin{3};

    otherwise
        error(['SDPVAR/' upper(mfilename) ' called with weird argument']);
end


function h = ne(f, g)
%~=   Not equal operator for CHEBFUN objects.
%   H = F ~= G, where F and/or G are CHEBFUN objects, constructs a logical
%   CHEBFUN H which is true (i.e., takes the value 1) where F ~= G, and false
%   (0) elsewhere.
%
% See also EQ, ROOTS.

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

% Trivial empty case:
if ( isempty(f) )
    h = f;
    return
elseif ( isempty(g) )
    h = g;
    return
end

% Array-valued?
if ( min(size(f)) > 1 || min(size(g)) > 1 )
	error('CHEBFUN:CHEBFUN:ne:array', ...
        '~= does not support array-valued CHEBFUN objects.');
end

% Call SIGN() to do the work:
h = sign(f - g);

% Get value in interior of each FUN by taking left-sided limit at the breaks:
vals = get(h, 'rval-local');

% Set FUNs that are nonzero to FUNs which are identically 1:
for k = 1:numel(h.funs)
    if ( vals(k) ~= 0 )
        h.funs{k} = 1 + 0*h.funs{k};
    end
end

% pointValues:
ind = isnan(h.pointValues);
h.pointValues = double(logical(h.pointValues(~ind)));

% Tidy the result:
h = merge(h);

end


function [fx,tt]=fxrapt(s,fs,mode,q)
%FXRAPT RAPT pitch tracker [FX,VUV]=(S,FS,M,Q)
%
% Input:   s(ns)      Speech signal
%          fs         Sample frequency (Hz)
%          mode       'g' will plot a graph [default if no output arguments]
%                     'u' will include unvoiced fames (with fx=NaN)
%          q          stucture with parameter values (e.g. q.f0min=40); see below for a list
%
% Outputs: fx(nframe)     Larynx frequency for each fram,e (or NaN for silent/unvoiced)
%          tt(nframe,3)  Start and end samples of each frame. tt(*,3)=1 at the start of each talk spurt
%
% Plots a graph if no outputs are specified showing lag candidates and selected path
%

% Bugs/Suggestions:
%   (1) Include backward DP pass and output the true cost for each candidate.
%   (2) Add an extra state to distinguish between voiceless and silent
%   (3) N-best DP to allow longer term penalties (e.g. for frequent pitch doubling/halving)

% The algorithm is taken from [1] with the following differences:
%
%      (a)  the factor AFACT which in the Talkin algorithm corresponds roughly
%           to the absolute level of harmonic noise in the correlation window. This value
%           is here calculated as the maximum of three figures:
%                   (i) an absolute floor set by p.absnoise
%                  (ii) a multiple of the peak signal set by p.signoise
%                 (iii) a multiple of the noise floor set by p.relnoise
%      (b) The LPC used in calculating the Itakura distance uses a Hamming window rather than
%          a Hanning window.
%
% A C implementation of this algorithm by Derek Lin and David Talkin is included as  "get_f0.c"
% in the esps.zip package available from http://www.speech.kth.se/esps/esps.zip under the BSD
% license.
%
% Refs:
%      [1]   D. Talkin, "A Robust Algorithm for Pitch Tracking (RAPT)"
%            in "Speech Coding & Synthesis", W B Kleijn, K K Paliwal eds,
%            Elsevier ISBN 0444821694, 1995

%      Copyright (C) Mike Brookes 2006-2013
%      Version: $Id: fxrapt.m 9312 2017-01-19 13:19:13Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

s=s(:); % force s to be a column
if nargin<4
    q=[];
    if nargin<3
        mode=' ';
    end
end
doback=0;   % don't do backwards DP for now

% set default parameters

p0.f0min=50;           % Min F0 (Hz)
p0.f0max=500;          % Max F0 (Hz)
p0.tframe=0.01;        % frame size (s)
p0.tlpw=0.005;         % low pass filter window size (s)
p0.tcorw=0.0075;       % correlation window size (s)
p0.candtr=0.3;         % minimum peak in NCCF
p0.lagwt=0.3;          % linear lag taper factor
p0.freqwt=0.02;        % cost factor for F0 change
p0.vtranc=0.005;       % fixed voice-state transition cost
p0.vtrac=0.5;          % delta amplitude modulated transition cost
p0.vtrsc=0.5;          % delta spectrum modulated transition cost
p0.vobias=0.0;         % bias to encourage voiced hypotheses
p0.doublec=0.35;       % cost of exact doubling or halving
p0.absnoise=0;         % absolute rms noise level
p0.relnoise=2;         % rms noise level relative to noise floor
p0.signoise=0.001;     % ratio of peak signal rms to noise floor (0.001 = 60dB)
p0.ncands=20;          % max hypotheses at each frame
p0.trms=0.03;                      % window length for rms measurement
p0.dtrms=0.02;                     % window spacing for rms measurement
p0.preemph=-7000;                  % s-plane position of preemphasis zero
p0.nfullag=7;                      % number of full lags to try (must be odd)
p=paramsetch(p0,q);

% redefine commonly used parameters

candtr=p.candtr;          % minimum peak in NCCF                      [0.3]
vtranc=p.vtranc;          % fixed voice-state transition cost         [0.005]
vtrac=p.vtrac;            % delta amplitude modulated transition cost [0.5]
vtrsc=p.vtrsc;            % delta spectrum modulated transition cost  [0.5]
vobias=p.vobias;          % bias to encourage voiced hypotheses       [0.0]
doublec=p.doublec;        % cost of exact doubling or halving         [0.35]
ncands=p.ncands;          % max hypotheses at each frame              [20]
nfullag=p.nfullag;        % number of full lags to try (must be odd)  [7]

% derived parameters (mostly dependent on sample rate fs)

krms=round(p.trms*fs);            % window length for rms measurement
kdrms=round(p.dtrms*fs);          % window spacing for rms measurement
rmswin=hanning(krms).^2;
kdsmp=round(0.25*fs/p.f0max);
hlpw=round(p.tlpw*fs/2);          % force window to be an odd length
blp=sinc((-hlpw:hlpw)/kdsmp).*hamming(2*hlpw+1).';
fsd=fs/kdsmp;
kframed=round(fsd*p.tframe);      % downsampled frame length
kframe=kframed*kdsmp;           % frame increment at full rate
rmsix=(1:krms)+floor((kdrms-kframe)/2); % rms index according to Talkin; better=(1:krms)+floor((kdrms-krms+1)/2)
minlag=ceil(fsd/p.f0max);
maxlag=round(fsd/p.f0min);        % use round() only because that is what Talkin does
kcorwd=round(fsd*p.tcorw);        % downsampled correlation window
kcorw=kcorwd*kdsmp;             % full rate correlation window
spoff=max(hlpw-floor(kdsmp/2),1+kdrms-rmsix(1)-kframe);  % offset for first speech frame at full rate
sfoff=spoff-hlpw+floor(kdsmp/2); % offset for downsampling filter
sfi=1:kcorwd;                   % initial decimated correlation window index array
sfhi=1:kcorw;                   % initial correlation window index array
sfj=1:kcorwd+maxlag;
sfmi=repmat((minlag:maxlag)',1,kcorwd)+repmat(sfi,maxlag-minlag+1,1);
lagoff=(minlag-1)*kdsmp;        % lag offset when converting to high sample rate
beta=p.lagwt*p.f0min/fs;            % bias towards low lags
log2=log(2);
lpcord=2+round(fs/1000);        % lpc order for itakura distance
hnfullag=floor(nfullag/2);
jumprat=exp((doublec+log2)/2);  % lag ratio at which octave jump cost is lowest
ssq=s.^2;
csssq=cumsum(ssq);
sqrt(min(csssq(kcorw+1:end)-csssq(1:end-kcorw))/kcorw);
afact=max([p.absnoise^2,max(ssq)*p.signoise^2,min(csssq(kcorw+1:end)-csssq(1:end-kcorw))*(p.relnoise/kcorw)^2])^2*kcorw^2;

% downsample signal to approx 2 kHz to speed up autocorrelation calculation
% kdsmp is the downsample factor

sf=filter(blp/sum(blp),1,s(sfoff+1:end));
sp=filter([1 exp(p.preemph/fs)],1,s); % preemphasised speech for LPC calculation
sf(1:length(blp)-1)=[];         % remove startup transient
sf=sf(1:kdsmp:end);             % downsample to =~2kHz
nsf=length(sf);                 % length of downsampled speech
ns=length(s);                   % length of full rate speech

% Calculate the frame limit to ensure we don't run off the end of the speech or decimated speech:
%   (a) For decimated autocorrelation when calculating sff():  (nframe-1)*kframed+kcorwd+maxlag <= nsf
%   (b) For full rate autocorrelation when calculating sfh():  max(fho)+kcorw+maxlag*kdsamp+hnfllag <= ns
%   (c) For rms ratio window when calculating rr            :  max(fho)+rmsix(end) <= ns
% where max(fho) = (nframe-1)*kframe + spoff

nframe=floor(1+min((nsf-kcorwd-maxlag)/kframed,(ns-spoff-max(kcorw-maxlag*kdsmp-hnfullag,rmsix(end)))/kframe));

% now search for autocorrelation peaks in the downsampled signal

cost=zeros(nframe,ncands);      % cumulative cost
prev=zeros(nframe,ncands);      % traceback pointer
mcands=zeros(nframe,1);         % number of actual candidates excluding voiceless
lagval=repmat(NaN,nframe,ncands-1);    % lag of each voiced candidate
tv=zeros(nframe,3);             % diagnostics: 1=voiceless cost, 2=min voiced cost, 3:cumulative voiceless-min voiced
if doback
    costms=cell(nframe,1);
end

% Main processing loop for each 10 ms frame

for iframe=1:nframe       % loop for each frame (~10 ms)

    % Find peaks in the normalized autocorrelation of subsampled (2Khz) speech
    % only keep peaks that are > 30% of highest peak

    fho=(iframe-1)*kframe+spoff;
    sff=sf((iframe-1)*kframed+sfj);
    sffdc=mean(sff(sfi));       % mean of initial correlation window length
    sff=sff-sffdc;              % subtract off the mean
    nccfd=normxcor(sff(1:kcorwd),sff(minlag+1:end));
    [ipkd,vpkd]=v_findpeaks(nccfd,'q');

    % Debugging: execute the line below to plot the autocorrelation peaks.
    % v_findpeaks(nccfd,'q'); xlabel(sprintf('Lag = (x+%d)*%g ms',minlag-1,1000*kdsmp/fs)); ylabel('Normalized Cross Correlation'); title (sprintf('Frame %d/%d',iframe,nframe));

    vipkd=[vpkd ipkd];
    vipkd(vpkd<max(vpkd)*candtr,:)=[];          % eliminate peaks that are small
    if size(vipkd,1)
        if size(vipkd,1)>ncands-1
            vipkd=sortrows(vipkd);
            vipkd(1:size(vipkd,1)-ncands+1,:)=[];   % eliminate lowest to leave only ncands-1
        end
        lagcan=round(vipkd(:,2)*kdsmp+lagoff);        % convert the lag candidate values to the full sample rate
        nlcan=length(lagcan);
    else
        nlcan=0;
    end

    % If there are any candidate lag values (nlcan>0) then refine their accuracy at the full sample rate

    if nlcan
        laglist=reshape(repmat(lagcan(:)',nfullag,1)+repmat((-hnfullag:hnfullag)',1,nlcan),nfullag*nlcan,1);
        sfh=s(fho+(1:kcorw+max(lagcan)+hnfullag));
        sfhdc=mean(sfh(sfhi));
        sfh=sfh-sfhdc;
        e0=sum(sfh(sfhi).^2);                     % energy of initial correlation window (only needed to store in tv(:,6)
        lagl2=repmat(lagcan(:)',nfullag+kcorw-1,1)+repmat((1-hnfullag:hnfullag+kcorw)',1,nlcan);
        nccf=normxcor(sfh(1:kcorw),sfh(lagl2),afact);

        [maxcc,maxcci]=max(nccf,[],1);
        vipk=[maxcc(:) lagcan(:)+maxcci(:)-hnfullag-1];
        vipk=vipk(:,[1 2 2]);
        maxccj=maxcci(:)'+nfullag*(0:nlcan-1);    % vector index into nccf array
        msk=mod(maxcci,nfullag-1)~=1 & 2*nccf(maxccj)-nccf(mod(maxccj-2,nfullag*nlcan)+1)-nccf(mod(maxccj,nfullag*nlcan)+1)>0;  % don't do quadratic interpolation for the end ones
        if any(msk)
            maxccj=maxccj(msk);
            vipk(msk,3)=vipk(msk,3)+(nccf(maxccj+1)-nccf(maxccj-1))'./(2*(2*nccf(maxccj)-nccf(maxccj-1)-nccf(maxccj+1)))';
        end
        vipk(maxcc<max(maxcc)*candtr,:)=[];          % eliminate peaks that are small
        if size(vipk,1)>ncands-1
            vipk=sortrows(vipk);
            vipk(1:size(vipk,1)-ncands+1,:)=[];   % eliminate lowest to leave only ncands-1
        end

        % vipk(:,1) has NCCF value, vipk(:,2) has integer peak position, vipk(:,3) has refined peak position

        mc=size(vipk,1);
    else
        mc=0;
    end

    % We now have mc lag candidates at the full sample rate

    mc1=mc+1;               % total number of candidates including "unvoiced" possibility
    mcands(iframe)=mc;      % save number of lag candidates (needed for pitch consistency cost calculation)
    if mc
        lagval(iframe,1:mc)=vipk(:,3)';
        cost(iframe,1)=vobias+max(vipk(:,1));   % voiceless cost
        cost(iframe,2:mc1)=1-vipk(:,1)'.*(1-beta*vipk(:,3)');   % local voiced costs
        tv(iframe,2)=min(cost(iframe,2:mc1));
    else
        cost(iframe,1)=vobias;          % if no lag candidates (mc=0), then the voiceless case is the only possibility
    end
    tv(iframe,1)=cost(iframe,1);
    if iframe>1                         % if it is not the first frame, then calculate pitch consistency and v/uv transition costs
        mcp=mcands(iframe-1);
        costm=zeros(mcp+1,mc1);         % cost matrix: rows and cols correspond to candidates in previous and current frames (incl voiceless)

        % if both frames have at least one lag candidate, then calculate a pitch consistency cost

        if mc*mcp
            lrat=abs(log(repmat(lagval(iframe,1:mc),mcp,1)./repmat(lagval(iframe-1,1:mcp)',1,mc)));
            costm(2:end,2:end)=p.freqwt*min(lrat,doublec+abs(lrat-log2));  % allow pitch doubling/halving
        end

        % if either frame has a lag candidate, then calculate the cost of voiced/voiceless transition and vice versa

        if mc+mcp
            rr=sqrt((rmswin'*s(fho+rmsix).^2)/(rmswin'*s(fho+rmsix-kdrms).^2)); % amplitude "gradient"
            ss=0.2/(distitar(lpcauto(sp(fho+rmsix),lpcord),lpcauto(sp(fho+rmsix-kdrms),lpcord),'e')-0.8);   % Spectral stationarity: note: Talkin uses Hanning instead of Hamming windows for LPC
            costm(1,2:end)= vtranc+vtrsc*ss+vtrac/rr;   % voiceless -> voiced cost
            costm(2:end,1)= vtranc+vtrsc*ss+vtrac*rr;
            tv(iframe,4:5)=[costm(1,mc1) costm(mcp+1,1)];
        end
        costm=costm+repmat(cost(iframe-1,1:mcp+1)',1,mc1);  % add in cumulative costs
        [costi,previ]=min(costm,[],1);
        cost(iframe,1:mc1)=cost(iframe,1:mc1)+costi;
        prev(iframe,1:mc1)=previ;
    else                            % first ever frame
        costm=zeros(1,mc1); % create a cost matrix in case doing a backward recursion
    end
    if mc
        tv(iframe,3)=cost(iframe,1)-min(cost(iframe,2:mc1));
        tv(iframe,6)=5*log10(e0*e0/afact);
    end
    if doback
        costms{iframe}=costm; % need to add repmatted cost into this
    end
end

% now do traceback

best=zeros(nframe,1);
[cbest,best(nframe)]=min(cost(nframe,1:mcands(nframe)+1));
for i=nframe:-1:2
    best(i-1)=prev(i,best(i));
end
vix=find(best>1);
fx=repmat(NaN,nframe,1);                        % unvoiced frames will be NaN
fx(vix)=fs*lagval(vix+nframe*(best(vix)-2)).^(-1); % leave as NaN if unvoiced
tt=zeros(nframe,3);
tt(:,1)=(1:nframe)'*kframe+spoff;       % find frame times
tt(:,2)=tt(:,1)+kframe-1;
jratm=(jumprat+1/jumprat)/2;
tt(2:end,3)=abs(fx(2:end)./fx(1:end-1)-jratm)>jumprat-jratm;    % new spurt if frequency ratio is outside (1/jumprat,jumprat)
tt(1,3)=1;           % first frame always starts a spurt
tt(1+find(isnan(fx(1:end-1))),3)=1; % NaN always forces a new spurt

% plot results if there are no output arguments of if the 'g' mode option is specified

if ~nargout || any(mode=='g')
    tf=spoff+(0:nframe-1)'*kframe;      % one sample before start of each frame
    blag=repmat(NaN,nframe,1);                        % unvoiced frames will be NaN
    blag(vix)=lagval(vix+nframe*(best(vix)-2)); % leave as NaN if unvoiced
    ts=(1:ns)/fs;                       % time scale for speech samples
    tsa=[1:tf(1) tf(end)+kframe+1:ns];  % indexes for unprocessed speech [-1 term is an error methinks]
    sup=repmat(NaN,ns,1);               % unprocessed speech - plot in black
    sup(tsa)=s(tsa);
    sv=reshape(s(tf(1)+1:tf(end)+kframe),kframe,nframe);               % processed speech
    su=sv;
    su(:,best>1)=NaN;                   % delete all voiced samples
    sv(:,best==1)=NaN;                  % delete all unvoiced samples
    tsuv=(tf(1)+1:tf(end)+kframe)/fs;
    su=su(:);
    sv=sv(:);
    ax=zeros(2,1);
    ax(1)=subplot(211);
    plot(ts,sup,'-k',tsuv,su,'r-',tsuv,sv,'b-');
    title('Speech');
    ax(2)=subplot(212);
    plot((tf+(kframe+1)/2)/fs,lagval*1000/fs,'xr',(tf+(kframe+1)/2)/fs,blag*1000/fs,'-b')
    xlabel('Time (s)');
    ylabel('Period (ms)');
    title('Lag Candidates');
    linkaxes(ax,'x');
end
if ~any(mode=='u')
    tt(isnan(fx),:)=[];    % remove NaN spurts
    fx(isnan(fx),:)=[];
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function v=normxcor(x,y,d)
% Calculate the normalized cross correlation of column vectors x and y
% we can calculate this in two ways but fft is much faster even for nx small
% We must have nx<=ny and the output length is ny-nx+1
% note that this routine does not do mean subtraction even though this is normally a good idea
% if y is a matrix, we correlate with each column
% d is a constant added onto the normalization factor
% v(j)=x'*yj/sqrt(d + x'*x * yj'*yj) where yj=y(j:j+nx-1) for j=1:ny-nx+1

if nargin<3
    d=0;
end
nx=length(x);
[ny,my]=size(y);
nv=1+ny-nx;
if nx>ny
    error('second argument is shorter than the first');
end

nf=pow2(nextpow2(ny));
w=irfft(repmat(conj(rfft(x,nf,1)),1,my).*rfft(y,nf,1));
s=zeros(ny+1,my);
s(2:end,:)=cumsum(y.^2,1);
v=w(1:nv,:)./sqrt(d+(x'*x).*(s(nx+1:end,:)-s(1:end-nx,:)));


function Study = readLeksellStudyFile(filename)
%"readLeksellStudyFile"
%   Reads a Leksell Study file using decodeLeksellData and places the
%   fields into a datastructure with meaningful names.  Many of the values
%   in Leksell files are a mystery at the moment, and are stored in
%   variables called "mystery_value_x" where x is a number.  If anyone
%   discovers the meaning of these values please report them on the CERR
%   webpage at radium.wustl.edu/cerr or to jalaly@radium.wustl.edu.
%
%JRA 6/13/05
%
%Usage:
%   Study = readLeksellStudyFile(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);

%If data does not have at least two elements it is effectively empty.
if length(data) < 2
    Study = [];
    return;
end

for i=1:length(data) - 1
    rawStudy = data{i};

	Study(i).modality           = rawStudy{1};
    Study(i).mystery_value_1    = rawStudy{2}; %always a small integer
    %Read in the original transM from the file
    originalTransM = reshape(rawStudy{3}, [4 4]);
    %Take the transpose and the inverse to put into the format used by CERR
    modifiedTransM = inv(originalTransM');
    %Divide the translations by 10 since the matrix was originally for mm
    %(converts the translations to cm)
    modifiedTransM(1,4) = modifiedTransM(1,4)/10;
    modifiedTransM(2,4) = modifiedTransM(2,4)/10;
    modifiedTransM(3,4) = modifiedTransM(3,4)/10;
    Study(i).rcsToxyzTransM = modifiedTransM;
    Study(i).pixelIntensityRange = rawStudy{4}; % appears to be the image intensity range, but does not need to be used for CERR import
    Study(i).registration_value = rawStudy{5};

end


function RightImpactConstraints(nlp, src, tar, bounds, varargin)
    plant = nlp.Plant;

    % no need to be time-continuous
    removeConstraint(nlp,'tContDomain');

    % first call the class method (calling impact model since it no longer
    % applies if we have a custom function)
    plant.rigidImpactConstraint(nlp, src, tar, bounds, varargin{:});

    % the relabeling/periodicity of joint coordiante is no longer valid
    % (this only affects position peridicity, velocity still applies)
    removeConstraint(nlp,'xDiscreteMapRightImpact');

    % Readding Periodicity (ignoring first 6 coordinates)
    R = plant.R;
    x = plant.States.x;
    xn = plant.States.xn;
    x_diff = R*x-xn;
    x_map = SymFunction(['xPartialDiscreteMap' plant.Name],x_diff(7:end),{x,xn});

    addNodeConstraint(nlp, x_map, {'x','xn'}, 'first', 0, 0, 'Linear');
end


function [surface_original] = ft_surfacerealign(cfg, surface_original)

% FT_SURFACEREALIGN realigns surface
%
% FIDUCIAL - You can apply a rigid body realignment based on three fiducial
% locations. After realigning, the fiducials in the input surface
% (typically nose, left and right ear) are along the same axes as the
% fiducials in the template surface set.
%
%   cfg.method         = string representing the method for aligning the surface
%                        'fiducial'        realign using three fiducials
%                        (e.g. NAS, LPA and RPA)
%
% If you want to realign the surface using fiducials, the target and the
% objective have to contain the three fiducials which relate , e.g.
%   cfg.target.elecpos(1,:)    = [110 0 0]     % location of the nose
%   cfg.target.elecpos(2,:)    = [0  90 0]     % location of the left ear
%   cfg.target.elecpos(3,:)    = [0 -90 0]     % location of the right ear
%   cfg.target.label       = {'NAS', 'LPA', 'RPA'}
%   cfg.objective.elecpos(1,:) = [0 -110 0]      % location of the nose
%   cfg.objective.elecpos(2,:) = [90   0 0]      % location of the left ear
%   cfg.objective.elecpos(3,:) = [-90  0 0]      % location of the right ear
%   cfg.objective.label    = {'NAS', 'LPA', 'RPA'}
%
% See also FT_MESHREALIGN

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

% DEPRECATED by roboos on 22 August 2017
% see http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=1830
% support for this functionality can be removed mid 2018
warning('FT_SURFACEREALIGN is deprecated, please use FT_MESHREALIGN instead.')

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

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

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

usefiducial              = isfield(cfg, 'target') & isfield(cfg, 'objective') & strcmp(cfg.method,'fiducial');

if usefiducial
  cfg.elec                 = cfg.objective;
  %use ft_electroderealign for realign the surface
  surface_realigned           = ft_electroderealign(cfg);
  %use transformation obtained by ft_electroderealign
  transform                = [surface_original.pos, ones(length(surface_original.pos),1)]*surface_realigned.homogeneous';
  surface_original.pos        = transform(:,1:3);
  surface_original.cfg        = surface_realigned.cfg;
else
  ft_error('Cannot perform ft_surfacerealign. Please read help ft_surfacerealign, and check your cfg')
end


% This script evaluates the percentage of space time coevered by
%alarms
%
re = [];

% Stefan Wiemer    4/95

report_this_filefun(mfilename('fullpath'));

global abo;
abo = abo2;

for tre2 = min(abo(:,4))+1.5:0.2:max(abo(:,4)-0.1)
    tre2
    abo = abo2;
    abo(:,5) = abo(:,5)* par1/365 + a(1,3);
    l = abo(:,4) >= tre2;
    abo = abo(l,:);
    l = abo(:,3) < tresh;
    abo = abo(l,:);
    size(abo)
    hold on

    j = 0;
    tmp = abo;

    while length(abo) > 1
        j = j+1;
        global iala
        [k,m] = findnei(1);
        po = [k];
        for i = 1:length(k)
            [k2,m2]  = findnei(k(i));
            po = [po ; k2];
            po = sort(po);
            po2 = [0;  po(1:length(po)-1)] ;
            l = find(po-po2 > 0) ;
            po = [po(l) ] ;
        end
        do = ['an' num2str(j) ' = abo(po3,:);'];
        disp([num2str(j) '  Anomalie groups  found'])
        eval(do)
        abo(po3,:) =[];
    end   % while j

    re = [re ; tre2 j ];
end   % for tre2

figure

matdraw
axis off

uicontrol('Units','normal',...
    'Position',[.0 .65 .08 .06],'String','Save ',...
     'Callback',{@calSave9, re(:,1), re(:,2)})

rect = [0.20,  0.10, 0.70, 0.60];
axes('position',rect)
hold on
pl = plot(re(:,1),re(:,2),'r');
set(pl,'LineWidth',1.5)
pl = plot(re(:,1),re(:,2),'ob');
set(pl,'LineWidth',1.5,'MarkerSize',10)

set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.m,'FontWeight','bold',...
    'FontWeight','bold','LineWidth',1.5,...
    'Box','on')
grid

ylabel('Number of Alarm Groups')
xlabel('Zalarm ')
watchoff


function [A] = dicomrt_rotate180y(matrix)
% dicomrt_rotate180y(matrix)
%
% Rotate 3D matrix accordingly with original patient position.
%
% Example:
%
% [A]=dicomrt_rotate180y(Dose)
%
% rotate Dose 3D matrice of 180 degrees about the Y axis
%
% See also dicomrt_ctcreate, dicomrt_loaddose, dicomrt_rotate180x
%
% Copyright (C) 2002 Emiliano Spezi (emiliano.spezi@physics.org)

% Check cases
if ndims(matrix) ~= 3
    error ('Only 3D matrices are supported. Exit now !');
end

% Execute rotation
for i=1:size(matrix,1)
    temp=squeeze(matrix(i,:,:));
    A(i,:,:)=rot90(temp,2);
end


% ijcvLocationFigureScript

outdir = '/IUS/vmr20/dhoiem/data/ijcv06/results';

vimages = zeros(200, 200, 3);
himages = zeros(200, 200, 5);

for f = 1:numel(imsegs)

    tmpseg = imresize(imsegs(f).segimage, [200 200]);

    for v = 1:3
        lab = (imsegs(f).vert_labels==v);
        vimages(:, :, v) = vimages(:, :, v) + lab(tmpseg);
    end

    for h = 1:5
        lab = (imsegs(f).horz_labels==h);
        himages(:, :, h) = himages(:, :, h) + lab(tmpseg);
    end

    if mod(f, 50)==0
        disp(f)
    end
end
vimages = vimages ./ repmat(sum(vimages, 3), [1 1 3]);
himages = himages ./ repmat(sum(himages, 3), [1 1 5]);

[tmp, bestv] = max(vimages, [], 3);
[tmp, besth] = max(himages, [], 3);

locimseg.nseg = 7;
locimseg.segimage = (bestv==1) + (bestv==2).*(1+besth) + 7*(bestv==3);
for k = 1:7
    locimseg.npixels(k) = sum(locimseg.segimage(:)==k);
end
lim = APPgetLabeledImage(ones(200,200, 3), locimseg, ...
    {'000', '090', '090', '090', '090', '090', 'sky'}, ones(7, 1), ...
    {'---', '045', '090', '135', 'por', 'sol', '---'}, ones(7, 1));

imwrite(vimages(:, :, [2 1 3]), [outdir '/mainclassloc.jpg'], 'Quality', 100);
for v = 1:3
    imwrite(vimages(:, :, v), [outdir '/vloc' num2str(v) '.jpg'], 'Quality', 100);
end

for h = 1:5
    imwrite(himages(:, :, h), [outdir '/hloc' num2str(h) '.jpg'], 'Quality', 100);
end

imwrite(lim, [outdir '/labeledloc.jpg'], 'Quality', 100);

lim2 = (lim>0).*vimages(:, :, [2 1 3]);
imwrite(lim2, [outdir '/labeledloc2.jpg'], 'Quality', 100);


function suppData_GatherResultsRF(pathRF,pathSUPP)

startpath = pwd;

% INITIALIZATION
tables = struct;
% nameOutcomes = {'Locoregional','Distant','Death','Death','DeathSign'};
% fSetNames = {'PET','CT','PETCT','CT','CT'};
nameOutcomes = {'Locoregional','Distant','Death'};
fSetNames = {'PET','CT','CT'};
metrics = {'AUC','Sensitivity','Specificity','Accuracy','CI'}; nMetrics = numel(metrics);
strMetrics = [];
for m = 1:nMetrics
    strMetrics = [strMetrics,metrics{m},','];
end
strMetrics(end) = [];
paths = {pathSUPP,pathSUPP,pathRF}; nComp = numel(paths);
prefixRead = {'radiomics','clinical',''};
fields = {'radiomics','clinical','combined'};

% PROCESSING
for c = 1:nComp
    if strcmp(fields{c},'clinical')
        nExp = 3; % 3 clinical outcomes
        rowNames = cell(nExp,1);
        for o = 1:nExp
            rowNames{o} = nameOutcomes{o};
        end
    else
        nExp = numel(nameOutcomes);
        rowNames = cell(nExp,1);
        for o = 1:nExp
            rowNames{o} = [nameOutcomes{o},'_',fSetNames{o}];
        end
    end
    cd(paths{c})
    for m = 1:nMetrics
        eval([metrics{m},' = zeros(nExp,1);']);
    end
    for o = 1:nExp
        if strcmp(fields{c},'clinical') || strcmp(fields{c},'volClinical')
            load(['testResultsRF',prefixRead{c},'_',nameOutcomes{o}]) % results gets out of there
        else
            load(['testResultsRF',prefixRead{c},'_',fSetNames{o},'_',nameOutcomes{o}]) % results gets out of there
        end
        for m = 1:nMetrics
            eval([metrics{m},'(o,1) = results.',metrics{m},';']);
        end
    end
    eval(['tableExp = table(',strMetrics,',''RowNames'',rowNames);']);
    tables.(fields{c}) = tableExp;
end

cd(pathSUPP), save('summaryTables','tables')

cd(startpath)
end


chi_095_2 = 5.9915;
% chi_099_2 = 9.2103;
chi_095_3 = 7.8147;
% chi_099_3 = 11.3449;

% plot image stuff
figure(figure_all);
subplot(im_fig);
hold off;
imagesc(tracker.lastImg);
colormap gray;
hold on;
title('Thick red: low innovation inliers. Thin red: high innovation inliers. \newline Magenta: rejected by 1-point RANSAC. Blue: No match found by pyramid KLT.');
half_patch_size_when_initialized = 20;
half_patch_size_when_matching = 6;
features_info=filter.features_info;

for i=1:length(features_info)

    if (~isempty(features_info(i).h)&&~isempty(features_info(i).S))

        %         imagesc( features_info(i).h(1) - half_patch_size_when_matching,...
        %             features_info(i).h(2) - half_patch_size_when_matching, features_info(i).patch_when_matching);

        if features_info(i).low_innovation_inlier
            plotUncertainEllip2D( features_info(i).S,...
                features_info(i).h, chi_095_2, 'r', 4 )
            plot( features_info(i).h(1), features_info(i).h(2),'r+','Markersize',10);
        end
        if features_info(i).high_innovation_inlier
            plotUncertainEllip2D( features_info(i).S,...
                features_info(i).h, chi_095_2, 'r', 2 )
            plot( features_info(i).h(1), features_info(i).h(2),'r+','Markersize',10);
        end
        if (~isempty(features_info(i).z))&&(features_info(i).high_innovation_inlier==0)&&(features_info(i).low_innovation_inlier==0)
            plotUncertainEllip2D( features_info(i).S,...
                features_info(i).h, chi_095_2, 'm', 2 )
            plot( features_info(i).h(1), features_info(i).h(2),'m+','Markersize',10);
        end

        if (isempty(features_info(i).z)&&~isempty(features_info(i).h))
            plotUncertainEllip2D( features_info(i).S,...
                features_info(i).h, chi_095_2, 'b', 2 )
            plot( features_info(i).h(1), features_info(i).h(2),'b+','Markersize',10);
        end

        if (~isempty(features_info(i).z))
            plot( features_info(i).z(1), features_info(i).z(2),'g+','Markersize',10);
            plot([features_info(i).z(1),features_info(i).h(1)],[features_info(i).z(2),features_info(i).h(2)],'Color','r','LineWidth',2);
        end
    end

end

% plot predicted and measured
% which_are_predicted = predicted_measurements(:,1)>0;
% plot( predicted_measurements(which_are_predicted,1), predicted_measurements(which_are_predicted,2),'r+','Markersize',10);
% which_are_measured = measurements(:,1)>0;
% plot( measurements(which_are_measured,1), measurements(which_are_measured,2),'g+');

axes_handler = get(gcf,'CurrentAxes');
set(axes_handler,'XTick',[],'YTick',[]);

% plot 3D stuff
figure(figure_all);
subplot(near3D_fig);
hold off;

imgctr=step-firstGroupFrameId;
qs02c0=filter.camPose(1:4);
% obtain qc2c0 current camera frame c to start camera frame c0, T c in c0
qs02c=quatmult_v001(filter.camPose(1:4),filter.rvqs0(7:10),0);
qc2c0=quatmult_v001(qs02c0,qs02c,2);
Tc2c0=-quatrot_v000(qc2c0, filter.camPose(5:7),0)+...
    quatrot_v000(qs02c0,filter.rvqs0(1:3),0)+filter.camPose(5:7);
trajectory(:,imgctr) =[Tc2c0; qc2c0];
draw_camera( trajectory(:,imgctr), 'k' );
hold on;
title(sprintf('Camera motion and scene [m] in top view at frmId(1 based)%d.',step));

plot3( trajectory(1, 1:imgctr), trajectory(2, 1:imgctr),...
    trajectory(3, 1:imgctr), 'k', 'LineWidth', 2 );

% for each group frame, compute Cci2c0 and Tcj2c0
grpLeg=length(filter.groupPose);
groupTransform=zeros(7, length(filter.groupPose));
qs02c0=filter.camPose(1:4);
for apple=1:grpLeg
    qs02cj=quatmult_v001(filter.camPose(1:4),filter.groupPose(apple).pose(1:4),0);
    groupTransform(1:4,apple)=quatmult_v001(qs02c0,qs02cj,2);
    groupTransform(5:7,apple)=-quatrot_v000(groupTransform(1:4,apple), filter.camPose(5:7),0)+...
        quatrot_v000(qs02c0,filter.groupPose(apple).pose(5:7),0)+...
        filter.camPose(5:7);
end
groupIds=[filter.groupPose.grpId];
covDim=filter.groupFrameSIP-1+length(filter.groupPose)*6+length(filter.features_info);
featSIP=filter.groupFrameSIP+length(filter.groupPose)*6;
%for each feature with lostNo==0, obtain its position in c0 frame
for wasp = 1:length(features_info)
    if (features_info(wasp).lostNo==0)
        % the feature is still being tracked, note some point
        % may be lost. But before a new group comes, it is still in
        % the states
        apple=find(groupIds==filter.features_info(wasp).grpId);

        % because grpId contains gap, this instruction can be sped up by making use of bisection search
        rho=filter.features_info(wasp).invDepth;
        XYZ=quatrot_v000(groupTransform(1:4,apple), [filter.features_info(wasp).xyn; 1]/rho,0)+...
            groupTransform(5:7,apple);
        if rho-3*sqrt(filter.p_k_k(featSIP+wasp-1,featSIP+wasp-1))<0
            if ( rho>0)
                plot3(XYZ(1),XYZ(2),XYZ(3),'k^','Markersize',10)
            end
        else
            if ( rho>0)
                plot3(XYZ(1),XYZ(2),XYZ(3),'r+','Markersize',10)
            end
        end
    end
end

axes_handler = get(gcf,'CurrentAxes');
axis([-100 150 -5 6 -200 210]);
xlabel('x');
ylabel('y');
zlabel('z');
grid on;
hold off
view([0, 0]);% only x and z


function X = trans_cam2fisheye_X(Xcam, M, D)

xcam = Xcam(1, :) ;
ycam = Xcam(2, :) ;
zcam = Xcam(3, :) ;

[x, y] = trans_cam2fisheye(xcam, ycam, zcam, M, D);

X = [x; y; ones(1, size(x, 2))] ;

end


function [inflMap, colXCoord, rowYCoord, colDividerXCoord, rowDividerYCoord, rowLeafPositions,MLCopeningSize] = getLSInfluenceMapFactorNoBar(LS,leak)
%"getLSInfluenceMap"
%   Gets an image of the influence generated by the beam described in LS.
%   Use getDICOMLeafPositions to generate LS.
%
%JRA&KZ 02/8/05
%
%Usage:
%   function inflMap = getLSInfluenceMap(LS);
%
% 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/>.

%Maximum precision of leaf position, in mm. Varian End and Side Accuracy 1.0 mm at
%isocenter. End and Side Repeatability 0.5 mm
precision = .5;

%Get x max, min and round to precision value.

%If X jaws dosn't exist in DICOM
if ~isfield(LS,'xLimits')
    xMax = ceil(max(vertcat(LS.xLeafPositions{:}),[],1) / precision) * precision;
    xMin = floor(min(vertcat(LS.xLeafPositions{:}),[],1) / precision) * precision;
    LS.xLimits{1}(1) = xMin;
    LS.xLimits{1}(2) = xMax;
end

xMax = ceil(max(vertcat(LS.xLimits{:}),[],1) / precision) * precision;
xMin = floor(min(vertcat(LS.xLimits{:}),[],1) / precision) * precision;
fieldSize.x = max(xMax) - min(xMin);
fieldLim.x  = [max(xMax) min(xMin)];

yMax = ceil(max(vertcat(LS.yLimits{:}),[],1) / precision) * precision;
yMin = floor(min(vertcat(LS.yLimits{:}),[],1) / precision) * precision;
fieldSize.y = max(yMax) - min(yMin);
fieldLim.y  = [max(yMax) min(yMin)];

yRes = precision;
nyElements = ceil(fieldSize.y/yRes);
xRes = precision;
nxElements = ceil(fieldSize.x/xRes);

inflMap=zeros(nyElements, nxElements);
colDividerXCoord = linspace(fieldLim.x(2), fieldLim.x(1), nxElements+1);
rowDividerYCoord = linspace(fieldLim.y(2), fieldLim.y(1), nyElements+1);

if isfield(LS, 'yLeafPositions')
    rowLeafPositions = round(interp1(rowDividerYCoord, 1:nyElements+1, LS.yLeafPositions,'linear', 'extrap'));
    rowLeafPositions = clip(rowLeafPositions, 1, nyElements+1, 'limits');
    leafBoundariesToKeep = [diff(rowLeafPositions)>0;true];
    rowLeafPositions = rowLeafPositions(leafBoundariesToKeep);
    leavesToKeep = leafBoundariesToKeep(1:end-1);
else
    LS.xLeafPositions{1} = [xMin xMax];
    LS.meterSetWeight = {1};
    rowLeafPositions = [1 nyElements+1];
    leavesToKeep = 1;
end

if length(LS.meterSetWeight) == 1
    doses = LS.meterSetWeight{:};
else
    doses = [0 diff([LS.meterSetWeight{:}])];
end

% backupMap = inflMap;
%h = waitbar(0,['Generating Fluence Map From MLC Positions For Beam ',num2str(beamIndex)],'Name','Please wait...');

%HCF - head scatter radiation parametrs for varian 2100CD Zhu, MedPhys,
%Vol. 31, No 9 , Sept 2004
if LS.energy == 6 && strcmpi(LS.manufacturer(1),'V')
    A1 = 0.0013;
    A2 = 0.078;
    K = 1.5;
    LAMDA = 7.69;
elseif LS.energy == 18 && strcmpi(LS.manufacturer(1),'V')
    A1 = 0.0013;
    A2 = 0.082;
    K = 1.5;
    LAMDA = 8.16;
elseif LS.energy == 6 && strcmpi(LS.manufacturer(1),'E')
    A1 = 0.0005;
    A2 = 0.072;
    K = 1.2;
    LAMDA = 9.85;
elseif LS.energy == 18 && strcmpi(LS.manufacturer(1),'E')
    A1 = 0.0004;
    A2 = 0.088;
    K = 1.2;
    LAMDA = 8.57;
elseif LS.energy == 6 && strcmpi(LS.manufacturer(1),'S')
    A1 = 0.0004;
    A2 = 0.094;
    K = 1.5;
    LAMDA = 9.8;
elseif LS.energy == 18 && strcmpi(LS.manufacturer(1),'S')
    A1 = 0.0004;
    A2 = 0.099;
    K = 1.5;
    LAMDA = 9.52;
else
    errordlg('This MLC Manufacturer or Energy is not supported or Missed Info in DICOM');
    return
end

for i=1:length(LS.xLeafPositions)
    %    inflMap = backupMap;
    nLeaves = length(LS.xLeafPositions{i})/2;

    if length(LS.xLimits) > 1
        jpL = LS.xLimits{i}(1);
        jpR = LS.xLimits{i}(2);
    else
        jpL = LS.xLimits{1}(1);
        jpR = LS.xLimits{1}(2);
    end

    lpL = LS.xLeafPositions{i}(1:nLeaves);
    lpR = LS.xLeafPositions{i}(nLeaves+1:end);
    lpLK = lpL(leavesToKeep);
    lpRK = lpR(leavesToKeep);

    MLCopeningSize(:,i) = lpRK - lpLK;

    lpLCols = interp1(colDividerXCoord, 1:nxElements+1, lpLK, 'linear', 'extrap');
    lpRCols = interp1(colDividerXCoord, 1:nxElements+1, lpRK, 'linear', 'extrap');

    %Column divider positions of jaws.
    jpLCol = interp1(colDividerXCoord, 1:nxElements+1, jpL, 'linear', 'extrap');
    jpRCol = interp1(colDividerXCoord, 1:nxElements+1, jpR, 'linear', 'extrap');

    jpLCol = round(jpLCol);
    jpRCol = round(jpRCol);

    lpLCols = clip(lpLCols, jpLCol, jpRCol, 'limits');
    lpRCols = clip(lpRCols, jpLCol, jpRCol, 'limits');

    lpLCols = round(lpLCols);
    lpRCols = round(lpRCols);

   for j=1:length(lpLCols)
        %HCF from output ratio for MLC fields Zhu, MedPhys
        F_X = abs(lpLCols(j) - (lpRCols(j)-1))*precision/10;
        F_Y = abs(rowLeafPositions(j+1) - rowLeafPositions(j))*precision/10;
        F = (1+K)*F_X * F_Y/(K*F_X + F_Y);
        HCF = (1+A1*F)*(1+A2*(erf(F/LAMDA))^2)/((1+A1*10)*(1+A2*(erf(10/LAMDA))^2));
        inflMap(rowLeafPositions(j):rowLeafPositions(j+1)-1, lpLCols(j):lpRCols(j)-1) = inflMap(rowLeafPositions(j):rowLeafPositions(j+1)-1, lpLCols(j):lpRCols(j)-1) + HCF*doses(i);
        inflMap(rowLeafPositions(j):rowLeafPositions(j+1)-1, jpLCol:lpLCols(j)-1) = inflMap(rowLeafPositions(j):rowLeafPositions(j+1)-1, jpLCol:lpLCols(j)-1) + leak*doses(i);
        inflMap(rowLeafPositions(j):rowLeafPositions(j+1)-1, lpRCols(j):jpRCol-1) = inflMap(rowLeafPositions(j):rowLeafPositions(j+1)-1, lpRCols(j):jpRCol-1) + leak*doses(i);
    end

    %waitbar(i/length(LS.xLeafPositions));
    %    frame = inflMap;
    %    imagesc(inflMap);
    %    mi(:,:,i) = inflMap;
    %    inflMap(inflMap == 0) = 1;
    %    inflMap(inflMap ~= 0) = 2;
    %    colormap([0 0 0; 1 1 1]);
    %    %mi(:,:,i) = inflMap;
    %    %mi(i) = im2frame(inflMap, [0 0 0; 1 1 1]);
    %    drawnow;
    %    pause(.006);
end
%close(h);
colXCoord = colDividerXCoord(1:end-1) + precision/2;
rowYCoord = rowDividerYCoord(1:end-1) + precision/2;


% -------------------------------------------------------------------------
function net = cnn_init_cafferef(net,opts)
% -------------------------------------------------------------------------

drop6p = find(cellfun(@(a) strcmp(a.name, 'dropout6'), net.layers)==1);
drop7p = find(cellfun(@(a) strcmp(a.name, 'dropout7'), net.layers)==1);

if ~isempty(drop6p)
  assert(~isempty(drop7p));
  net.layers{drop6p}.rate = opts.DropOutRate;
  net.layers{drop7p}.rate = opts.DropOutRate;
else
  relu6p = find(cellfun(@(a) strcmp(a.name, 'relu6'), net.layers)==1);
  relu7p = find(cellfun(@(a) strcmp(a.name, 'relu7'), net.layers)==1);

  drop6 = struct('type','dropout','rate', opts.DropOutRate,'name','dropout6') ;
  drop7 = struct('type','dropout','rate', opts.DropOutRate,'name','dropout7') ;
  net.layers = [net.layers(1:relu6p) drop6 net.layers(relu6p+1:relu7p) drop7 net.layers(relu7p+1:end)];
end

% replace fc8
fc8l = cellfun(@(a) strcmp(a.name, 'fc8'), net.layers)==1;

nCls = opts.nCls ;
% nCls = 101;
sizeW = size(net.layers{fc8l}.weights{1});

if sizeW(4)~=nCls
  net.layers{fc8l}.weights = {zeros(sizeW(1),sizeW(2),sizeW(3),nCls,'single'), ...
    zeros(1, nCls, 'single')};
end

% change loss
% net.layers(end) = [];
net.layers{end} = struct('name','loss', 'type','softmaxloss') ;

% convert to dagnn
net = dagnn.DagNN.fromSimpleNN(net, 'canonicalNames', true) ;

poolLyr1 = find(arrayfun(@(a) strcmp(a.name, opts.pool1Layer), net.layers)==1);
assert(~isempty(poolLyr1));
% configure appr-rank-pool
switch opts.pool1Type
  case 'arpool'
    if strcmp(opts.pool1Layer,'conv1')
      net.addLayer('arpool',AppRankPooling('scale',1),{net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImgN');
      net.addLayer('l2normalize',L2Normalize('scale',6000,'clip',[-128 128]),...
        'DynImgN','DynImg');
    else
      net.addLayer('arpool',AppRankPooling('scale',0.1),{net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImgN');
      net.addLayer('reluP',dagnn.ReLU(),...
      {'DynImgN'},'DynImg');
    end
    net.setLayerInputs(opts.pool1Layer,{'DynImg'}) ;
  case 'ppool1'
    if strcmp(opts.pool1Layer,'conv1')
      net.addLayer('parampool',LinComb('pad',[1 1 10 1]),...
      {net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImg',{'conv0f','conv0b'});
    else
      net.addLayer('parampool',LinComb('pad',[1 1 10 1]),...
      {net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImgN',{'conv0f','conv0b'});
    net.addLayer('reluP',dagnn.ReLU(),...
      {'DynImgN'},'DynImg');
    end

    net.layers(poolLyr1).inputs{1} = 'DynImg' ;
%     net.params(end-1).value = 0.01 * randn(1,1,10,1,'single');
    net.params(end-1).value = 0.1 * ones(1,1,10,1,'single');
    net.params(end).value = zeros(1,1,'single');

    net.params(end-1).learningRate = 0.1 ;
    net.params(end).learningRate = 0.2 ;
  case 'ppool2'
    if strcmp(opts.pool1Layer,'conv1')
      net.addLayer('parampool',LinComb('pad',[1 1 10 1]),...
      {net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImg',{'conv0f','conv0b'});
    else
      net.addLayer('parampool',LinComb('pad',[1 1 10 1]),...
      {net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImgN',{'conv0f','conv0b'});
    net.addLayer('reluP',dagnn.ReLU(),...
      {'DynImgN'},'DynImg');
    end

    net.layers(poolLyr1).inputs{1} = 'DynImg' ;
%     net.params(end-1).value = 0.01 * randn(1,1,10,1,'single');
    net.params(end-1).value = 0.1 * ones(1,1,10,1,'single');
    net.params(end).value = zeros(1,1,'single');

    net.params(end-1).learningRate = 0.1 ;
    net.params(end).learningRate = 0.2 ;
  case 'none'

  otherwise
    error('Unknown pool type %s', opts.pool1Type) ;
end

% second pool layer (max pooling)
poolLyr2 = find(arrayfun(@(a) strcmp(a.name, opts.pool2Layer), net.layers)==1);
net.addLayer('tempPoolMax',TemporalPooling('method','max'),...
  {net.layers(poolLyr2(1)).inputs{1},'VideoId2'},'tempPoolMax');

net.layers(poolLyr2).inputs{1} = 'tempPoolMax';

% add multi-class error
net.addLayer('errMC',ErrorMultiClass(),{'prediction','label'},'mcerr');

net_ = net.saveobj ;
net = dagnn.DagNN.loadobj(net_) ;

net.removeLayer('loss') ;
net.addLayer('loss', ...
             LossNormalized('loss', 'softmaxlog') ,...
             {'prediction', 'label'}, ...
             'objective') ;

% replace standard matconvnet bnorm with my version
bns = find(arrayfun(@(a) strcmp(class(a.block), 'dagnn.BatchNorm'), net.layers)==1);
for i=1:numel(bns)
  bb = net.layers(bns(i)).block ;
  net.layers(bns(i)).block = BatchNormN('numChannels',bb.numChannels,...
  'epsilon',bb.epsilon,...
  'opts',bb.opts) ;
end


function rtk=udstate(rtk,obsr,obsb,nav,ind)

global glc
tt=rtk.tt;

% update the position/velocity/acceleration
rtk=udpos(rtk,tt);

% update ionosphereic parameter
if rtk.opt.ionoopt==glc.IONOOPT_EST
    bl=norm(rtk.x(1:3)-rtk.basepos);
    rtk=udion(rtk,tt,bl,ind);
end

% update tropspheric parameter
if rtk.opt.tropopt>=glc.TROPOPT_EST
    rtk=udtrop(rtk,tt,bl);
end

% update reciever inter-frequency bias for glonass
if rtk.opt.glomodear==2&&rtk.mask(2)==1
    rtk=udrcvbias(rtk,tt);
end

% update the ambiguity
if rtk.opt.mode>glc.PMODE_DGNSS
    rtk=udbias(rtk,obsr,obsb,nav,ind);
end

return