function genSimTests()

% Read template line by line into cell array
fid = fopen('simTemp.qmr');
allScript = textscan(fid,'%s','Delimiter','\n');
fclose(fid);
allScript = allScript{1}; % This is a cell aray that contains template

MethodList = list_models;
disp('Copy below section and paste them into Travis config.')
disp('------------------------------------------------------')
for ii = 1:length(MethodList)

    Model = str2func(MethodList{ii}); Model = Model();
    if Model.voxelwise

        newScript = replaceJoker('*-modelName-*',MethodList{ii},allScript,1);

        writeName = ['SimTest_' MethodList{ii} '_test' '.m'];

        fileID = fopen(writeName,'w');
        formatSpec = '%s\n';
        [nrows,~] = size(newScript);
        for row = 1:nrows
            fprintf(fileID,formatSpec,newScript{row,:});
        end
        fclose(fileID);

        disp('- stage: Test');
        disp(['  script: travis_wait 30 octave --no-gui --eval "bootstrapTest;cd(' char(39) '/home/travis/build/neuropoly/qMRLab/Test/MoxUnitCompatible' char(39) ');res=moxunit_runtests(' char(39) writeName char(39) ');exit(~res);"']);
    end

end

end

function newScript = replaceJoker(thisJoker,replaceWith,inScript,type)

% thisJoker: Joker definition *- joker_def_here -*
% replaceWith: Cell Aray or cell to be repaced with thisJoker
% inScript : Input script (thisJoker will be replaced in inSCript)
% type: 1 or 2: In-line replacements or block replacements

IndexC = strfind(inScript, char({thisJoker}));
idx = find(not(cellfun('isempty', IndexC)));

if type == 1 % In-line replacements

    for i=1:length(idx)

        inScript(idx(i)) = strrep(inScript(idx(i)),{thisJoker},{replaceWith});

    end

    newScript = inScript;

elseif type ==2 % Code blocks

    lenNew = length(replaceWith);
    newScript = cell(length(inScript)+lenNew-1,1);
    try
        newScript(idx:(idx+lenNew-1)) = replaceWith;
    catch
        newScript(idx:(idx+lenNew-1)) = replaceWith';
    end
    newScript(1:(idx-1)) = inScript(1:(idx-1));
    newScript((idx+lenNew):(length(inScript)+lenNew-1)) = inScript((idx+1):end);

else

end

end


moviename = '/home/mayank/Work/FlySpaceTime/walkMovies/SS03500_test/movie.ufmf';
trackfilename = '/home/mayank/Work/FlySpaceTime/walkMovies/SS03500_test/trx.mat';
stationary = true;
method = 'deep-sup';
flowname = 'DS';

ff = fopen('DebugDeepCrash.txt','w');

tracks = load(trackfilename);
tracks = tracks.trx;

[readfcn,nframes,fid,headerinfo] = get_readframe_fcn(moviename);
fclose(fid);

blocksize = 50;

minfirst = min([tracks.firstframe]);
maxlast = max([tracks.endframe]);
nframes = maxlast-minfirst+1;
nblocks = ceil((nframes-1)/blocksize);

allftrs ={};

% compute features in parallel for different intervals of frames.
% parfor ndx = 1:nblocks
for ndx = 41:80
  [readfcn,nframes,fid,headerinfo] = get_readframe_fcn(moviename);
  fstart = minfirst + (ndx-1)*blocksize;
  fend = min(maxlast,ndx*blocksize);
  tic;
  allftrs{ndx} = genFeatures(readfcn,headerinfo,fstart,fend,tracks,stationary,method);
  telapsed = toc;
  fclose(fid);
  fprintf(ff,'%d\n',ndx);

end


function view = LoadLaminarIndices(view)

% view = LoadLaminarIndices(view);
%
% Load the laminar indices, if they are available as a file in the current
% view directory. If not, offer to calculate them. For backward style
% conformance, this takes an optional volume view input, and returns the
% volume with laminar coordinate indices field "laminarIndices" loaded.
% However, if the view is not supplied, the currently selected VOLUME is
% operated upon and returned. Returns an empty variable if something goes
% wrong, e.g., the user % decides not to calculate the indices, which takes
% some time.
%
% Ress, 10/05

mrGlobals

if ieNotDefined('view')
  selectedVOLUME = viewSelected('Volume');
  view = VOLUME{selectedVOLUME};
end
if ~strcmp(view.viewType, 'Gray'), view = switch2Gray(view); end
fName = fullfile(viewDir(view), 'laminarIndices.mat');
if exist(fName, 'file')
  data = load(fName);
  VOLUME{selectedVOLUME}.laminarIndices = data.laminarIndices;
else
  yn = questdlg('No laminar coordinates file. Calculate coordinates?');
  if strcmp(yn, 'Yes'), MapLaminarIndices, end
end

if isfield(VOLUME{selectedVOLUME}, 'laminarIndices')
  view = VOLUME{selectedVOLUME};
else
  view = [];
end


%  internal function

%  - Jimmy Shen (jimmy@rotman-baycrest.on.ca)

function [img,hdr] = load_nii_img(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB)

   if ~exist('hdr','var') || ~exist('filetype','var') || ~exist('fileprefix','var') || ~exist('machine','var')
      error('Usage: [img,hdr] = load_nii_img(hdr,filetype,fileprefix,machine,[img_idx],[dim5_idx],[dim6_idx],[dim7_idx],[old_RGB]);');
   end

   if ~exist('img_idx','var') || isempty(img_idx) || hdr.dime.dim(5)<1
      img_idx = [];
   end

   if ~exist('dim5_idx','var') || isempty(dim5_idx) || hdr.dime.dim(6)<1
      dim5_idx = [];
   end

   if ~exist('dim6_idx','var') || isempty(dim6_idx) || hdr.dime.dim(7)<1
      dim6_idx = [];
   end

   if ~exist('dim7_idx','var') || isempty(dim7_idx) || hdr.dime.dim(8)<1
      dim7_idx = [];
   end

   if ~exist('old_RGB','var') || isempty(old_RGB)
      old_RGB = 0;
   end

   %  check img_idx
   %
   if ~isempty(img_idx) && ~isnumeric(img_idx)
      error('"img_idx" should be a numerical array.');
   end

   if length(unique(img_idx)) ~= length(img_idx)
      error('Duplicate image index in "img_idx"');
   end

   if ~isempty(img_idx) && (min(img_idx) < 1 || max(img_idx) > hdr.dime.dim(5))
      max_range = hdr.dime.dim(5);

      if max_range == 1
         error(['"img_idx" should be 1.']);
      else
         range = ['1 ' num2str(max_range)];
         error(['"img_idx" should be an integer within the range of [' range '].']);
      end
   end

   %  check dim5_idx
   %
   if ~isempty(dim5_idx) && ~isnumeric(dim5_idx)
      error('"dim5_idx" should be a numerical array.');
   end

   if length(unique(dim5_idx)) ~= length(dim5_idx)
      error('Duplicate index in "dim5_idx"');
   end

   if ~isempty(dim5_idx) && (min(dim5_idx) < 1 || max(dim5_idx) > hdr.dime.dim(6))
      max_range = hdr.dime.dim(6);

      if max_range == 1
         error(['"dim5_idx" should be 1.']);
      else
         range = ['1 ' num2str(max_range)];
         error(['"dim5_idx" should be an integer within the range of [' range '].']);
      end
   end

   %  check dim6_idx
   %
   if ~isempty(dim6_idx) && ~isnumeric(dim6_idx)
      error('"dim6_idx" should be a numerical array.');
   end

   if length(unique(dim6_idx)) ~= length(dim6_idx)
      error('Duplicate index in "dim6_idx"');
   end

   if ~isempty(dim6_idx) && (min(dim6_idx) < 1 || max(dim6_idx) > hdr.dime.dim(7))
      max_range = hdr.dime.dim(7);

      if max_range == 1
         error(['"dim6_idx" should be 1.']);
      else
         range = ['1 ' num2str(max_range)];
         error(['"dim6_idx" should be an integer within the range of [' range '].']);
      end
   end

   %  check dim7_idx
   %
   if ~isempty(dim7_idx) && ~isnumeric(dim7_idx)
      error('"dim7_idx" should be a numerical array.');
   end

   if length(unique(dim7_idx)) ~= length(dim7_idx)
      error('Duplicate index in "dim7_idx"');
   end

   if ~isempty(dim7_idx) && (min(dim7_idx) < 1 || max(dim7_idx) > hdr.dime.dim(8))
      max_range = hdr.dime.dim(8);

      if max_range == 1
         error(['"dim7_idx" should be 1.']);
      else
         range = ['1 ' num2str(max_range)];
         error(['"dim7_idx" should be an integer within the range of [' range '].']);
      end
   end

   [img,hdr] = read_image(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB);

   return					% load_nii_img

%---------------------------------------------------------------------
function [img,hdr] = read_image(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB)

   switch filetype
   case {0, 1}
      fn = [fileprefix '.img'];
   case 2
      fn = [fileprefix '.nii'];
   end

   fid = fopen(fn,'r',machine);

   if fid < 0,
      msg = sprintf('Cannot open file %s.',fn);
      error(msg);
   end

   %  Set bitpix according to datatype
   %
   %  /*Acceptable values for datatype are*/
   %
   %     0 None                     (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN
   %     1 Binary                         (ubit1, bitpix=1) % DT_BINARY
   %     2 Unsigned char         (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8
   %     4 Signed short                  (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16
   %     8 Signed integer                (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32
   %    16 Floating point    (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32
   %    32 Complex, 2 float32      (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64
   %    64 Double precision  (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64
   %   128 uint8 RGB                 (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24
   %   256 Signed char            (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8
   %   511 Single RGB              (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96
   %   512 Unsigned short               (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16
   %   768 Unsigned integer             (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32
   %  1024 Signed long long              (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64
   %  1280 Unsigned long long           (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64
   %  1536 Long double, float128  (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128
   %  1792 Complex128, 2 float64  (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128
   %  2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128
   %
   switch hdr.dime.datatype
   case   1,
      hdr.dime.bitpix = 1;  precision = 'ubit1';
   case   2,
      hdr.dime.bitpix = 8;  precision = 'uint8';
   case   4,
      hdr.dime.bitpix = 16; precision = 'int16';
   case   8,
      hdr.dime.bitpix = 32; precision = 'int32';
   case  16,
      hdr.dime.bitpix = 32; precision = 'float32';
   case  32,
      hdr.dime.bitpix = 64; precision = 'float32';
   case  64,
      hdr.dime.bitpix = 64; precision = 'float64';
   case 128,
      hdr.dime.bitpix = 24; precision = 'uint8';
   case 256
      hdr.dime.bitpix = 8;  precision = 'int8';
   case 511
      hdr.dime.bitpix = 96; precision = 'float32';
   case 512
      hdr.dime.bitpix = 16; precision = 'uint16';
   case 768
      hdr.dime.bitpix = 32; precision = 'uint32';
   case 1024
      hdr.dime.bitpix = 64; precision = 'int64';
   case 1280
      hdr.dime.bitpix = 64; precision = 'uint64';
   case 1792,
      hdr.dime.bitpix = 128; precision = 'float64';
   otherwise
      error('This datatype is not supported');
   end

   hdr.dime.dim(find(hdr.dime.dim < 1)) = 1;

   %  move pointer to the start of image block
   %
   switch filetype
   case {0, 1}
      fseek(fid, 0, 'bof');
   case 2
      fseek(fid, hdr.dime.vox_offset, 'bof');
   end

   %  Load whole image block for old Analyze format or binary image;
   %  otherwise, load images that are specified in img_idx, dim5_idx,
   %  dim6_idx, and dim7_idx
   %
   %  For binary image, we have to read all because pos can not be
   %  seeked in bit and can not be calculated the way below.
   %
   if hdr.dime.datatype == 1 || isequal(hdr.dime.dim(5:8),ones(1,4)) || ...
	(isempty(img_idx) && isempty(dim5_idx) && isempty(dim6_idx) && isempty(dim7_idx))

      %  For each frame, precision of value will be read
      %  in img_siz times, where img_siz is only the
      %  dimension size of an image, not the byte storage
      %  size of an image.
      %
      img_siz = prod(hdr.dime.dim(2:8));

      %  For complex float32 or complex float64, voxel values
      %  include [real, imag]
      %
      if hdr.dime.datatype == 32 || hdr.dime.datatype == 1792
         img_siz = img_siz * 2;
      end

      %MPH: For RGB24, voxel values include 3 separate color planes
      %
      if hdr.dime.datatype == 128 || hdr.dime.datatype == 511
	 img_siz = img_siz * 3;
      end

      img = fread(fid, img_siz, sprintf('*%s',precision));

      d1 = hdr.dime.dim(2);
      d2 = hdr.dime.dim(3);
      d3 = hdr.dime.dim(4);
      d4 = hdr.dime.dim(5);
      d5 = hdr.dime.dim(6);
      d6 = hdr.dime.dim(7);
      d7 = hdr.dime.dim(8);

      if isempty(img_idx)
         img_idx = 1:d4;
      end

      if isempty(dim5_idx)
         dim5_idx = 1:d5;
      end

      if isempty(dim6_idx)
         dim6_idx = 1:d6;
      end

      if isempty(dim7_idx)
         dim7_idx = 1:d7;
      end
   else

      d1 = hdr.dime.dim(2);
      d2 = hdr.dime.dim(3);
      d3 = hdr.dime.dim(4);
      d4 = hdr.dime.dim(5);
      d5 = hdr.dime.dim(6);
      d6 = hdr.dime.dim(7);
      d7 = hdr.dime.dim(8);

      if isempty(img_idx)
         img_idx = 1:d4;
      end

      if isempty(dim5_idx)
         dim5_idx = 1:d5;
      end

      if isempty(dim6_idx)
         dim6_idx = 1:d6;
      end

      if isempty(dim7_idx)
         dim7_idx = 1:d7;
      end

      %  compute size of one image
      %
      img_siz = prod(hdr.dime.dim(2:4));

      %  For complex float32 or complex float64, voxel values
      %  include [real, imag]
      %
      if hdr.dime.datatype == 32 || hdr.dime.datatype == 1792
         img_siz = img_siz * 2;
      end

      %MPH: For RGB24, voxel values include 3 separate color planes
      %
      if hdr.dime.datatype == 128 || hdr.dime.datatype == 511
         img_siz = img_siz * 3;
      end

      % preallocate img
      img = zeros(img_siz, length(img_idx)*length(dim5_idx)*length(dim6_idx)*length(dim7_idx) );
      currentIndex = 1;

      for i7=1:length(dim7_idx)
         for i6=1:length(dim6_idx)
            for i5=1:length(dim5_idx)
               for t=1:length(img_idx)

                  %  Position is seeked in bytes. To convert dimension size
                  %  to byte storage size, hdr.dime.bitpix/8 will be
                  %  applied.
                  %
                  pos = sub2ind([d1 d2 d3 d4 d5 d6 d7], 1, 1, 1, ...
			img_idx(t), dim5_idx(i5),dim6_idx(i6),dim7_idx(i7)) -1;
                  pos = pos * hdr.dime.bitpix/8;

                  if filetype == 2
                     fseek(fid, pos + hdr.dime.vox_offset, 'bof');
                  else
                     fseek(fid, pos, 'bof');
                  end

                  %  For each frame, fread will read precision of value
                  %  in img_siz times
                  %
                  img(:,currentIndex) = fread(fid, img_siz, sprintf('*%s',precision));
                  currentIndex = currentIndex +1;

               end
            end
         end
      end
   end

   %  For complex float32 or complex float64, voxel values
   %  include [real, imag]
   %
   if hdr.dime.datatype == 32 || hdr.dime.datatype == 1792
      img = reshape(img, [2, length(img)/2]);
      img = complex(img(1,:)', img(2,:)');
   end

   fclose(fid);

   %  Update the global min and max values
   %
   hdr.dime.glmax = double(max(img(:)));
   hdr.dime.glmin = double(min(img(:)));

   %  old_RGB treat RGB slice by slice, now it is treated voxel by voxel
   %
   if old_RGB && hdr.dime.datatype == 128 && hdr.dime.bitpix == 24
      % remove squeeze
      img = (reshape(img, [hdr.dime.dim(2:3) 3 hdr.dime.dim(4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)]));
      img = permute(img, [1 2 4 3 5 6 7 8]);
   elseif hdr.dime.datatype == 128 && hdr.dime.bitpix == 24
      % remove squeeze
      img = (reshape(img, [3 hdr.dime.dim(2:4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)]));
      img = permute(img, [2 3 4 1 5 6 7 8]);
   elseif hdr.dime.datatype == 511 && hdr.dime.bitpix == 96
      img = double(img(:));
      img = single((img - min(img))/(max(img) - min(img)));
      % remove squeeze
      img = (reshape(img, [3 hdr.dime.dim(2:4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)]));
      img = permute(img, [2 3 4 1 5 6 7 8]);
   else
      % remove squeeze
      img = (reshape(img, [hdr.dime.dim(2:4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)]));
   end

   if ~isempty(img_idx)
      hdr.dime.dim(5) = length(img_idx);
   end

   if ~isempty(dim5_idx)
      hdr.dime.dim(6) = length(dim5_idx);
   end

   if ~isempty(dim6_idx)
      hdr.dime.dim(7) = length(dim6_idx);
   end

   if ~isempty(dim7_idx)
      hdr.dime.dim(8) = length(dim7_idx);
   end

   return						% read_image


function minmax_install
% function minmax_install
% Installation by building the C-mex files for min/max selection package
%
% Author Bruno Luong <brunoluong@yahoo.com>
% Last update: 29-Jun-2009 built inplace functions

thisfile = mfilename('fullpath');
path = fileparts(thisfile);
oldpath = cd(path);

arch=computer('arch');
mexopts = {'-v' '-O' ['-' arch]};
% 64-bit platform
if ~isempty(strfind(computer(),'64'))
    mexopts(end+1) = {'-largeArrayDims'};
end

if ispc() && datenum(version('-date')) < datenum('January 11, 2014')
    compiler = getmexopts('COMPILER');
    islcc = strcmpi(compiler,'lcc');
    % Define the C-symbol for LCC compiler
    if islcc
        mexopts(end+1) = {'-D_LCC'};
    end
end

% Internal representation of mxArray
try
    buildInternal_mxArrayDef('Internal_mxArray.h');
catch
    if ispc()
        cpcmd = 'copy';
    else
        cpcmd = ' cp';
    end
    cmd = [cpcmd ' Internal_mxArray_2010B.h Internal_mxArray.h'];
    system(cmd);
end

% Inplace tool
mex(mexopts{:},'inplacecolumnmex.c');
mex(mexopts{:},'releaseinplace.c');

% Mex MIN/MAX functions
mex(mexopts{:},'minkmex.c');
mex(mexopts{:},'maxkmex.c');

cd(oldpath);

end


%helpme_ch4    helpme  for Chapter 4 specialized functions
%  IFISS scriptfile: HCE; 27 April 2005.

fprintf(' \n');
fprintf(' The files in the directory solvers/ch4_code can be used to reproduce \n');
fprintf(' results from Chapter 4 of the Elman-Silvester-Wathen monograph.\n');
fprintf(' Type "help ch4_code" for details.\n');
fprintf(' \n');


function V = spm_close_vol(V)
% Close image volume
% See: spm_create_vol and spm_write_plane.
%_______________________________________________________________________
% @(#)spm_close_vol.m	2.4 John Ashburner 02/08/16
for i=1:prod(size(V)),
	if isfield(V,'private') & isfield(V(i).private,'fid') & ~isempty(V(i).private.fid),
		if ~isempty(fopen(V(i).private.fid)),
			fclose(V(i).private.fid);
		end;
		V(i).private = rmfield(V(i).private,'fid');
	end;
end;


function flag = isProblem(problem)
% Check the input problem has all the mandatory fields
mandatory_fields = {'type', 'N', 'outliers', 'priors', 'dof'};
flag = all(isfield(problem, mandatory_fields));
end


function SetPerFrameData(obj,fn,x,varargin)

nidx = numel(varargin);
if nidx < 1,
  error('Index not specified');
end
if nidx > 2,
  error('At most two indexing parameters allowed');
end
if ischar(varargin{1}),
  n = find(strcmp(obj.expdirs,varargin{1}),1);
  if isempty(n),
    error('Unknown experiment %s',varargin{1});
  end
elseif isnumeric(varargin{1}),
  n = varargin{1};
  if numel(n) > 1 || n < 1 || round(n) ~= n || n > obj.nexpdirs,
    error('Illegal experiment index %s',mat2str(n));
  end
else
  error('Illegal experiment index');
end
if nidx == 1,
  flies = 1:obj.nfliespermovie(n);
else
  flies = varargin{2};
  if ~isnumeric(flies) || any(flies < 1) || any(flies > obj.nfliespermovie(n)) || ...
      any(flies ~= round(flies)),
    error('Illegal fly indices');
  end
end

if iscell(x),
  ndataadd = sum(cellfun(@numel,x(1:numel(flies))));
else
  ndataadd = numel(x);
end
obj.FreeDataCache(ndataadd);

obj.nfnscached(n) = obj.nfnscached(n) + 1;
j = obj.nfnscached(n);
%fprintf('Incremented nfnscached(%d) to %d for %s\n',n,obj.nfnscached(n),fn);
obj.fnscached{n}{j} = fn;
obj.datacached{n}{j} = cell(1,numel(flies));

for flyidx = 1:numel(flies),
  fly = flies(flyidx);
  % delete data from cache if necessary
  if iscell(x),
    xcurr = x{flyidx};
  else
    xcurr = x;
  end
%   ndataadd = numel(xcurr);
%   obj.FreeDataCache(ndataadd);

  % add to cache
  %fprintf('Adding %s to data cache for fly %d at idx %d\n',fn,fly,j);
  obj.datacached{n}{j}{fly} = xcurr;

end

% update cache size
obj.ndatacached = obj.ndatacached + ndataadd;
obj.ndatacachedperexp(n) = obj.ndatacachedperexp(n) + ndataadd;

% update access time for this property
j = find(strcmp(obj.perframehistory(:,1),fn),1);
if isempty(j),
  j = size(obj.perframehistory,1)+1;
end
obj.perframehistory{j,1} = fn;
obj.perframehistory{j,2} = now;


function blockplay(f)
%BLOCKPLAY Schedules block to be played
%   Usage: blockplay(L)
%
%   Input parameters:
%      f    : Samples.
%
%   Function schedules samples in *f* to be played. Since playrec handles
%   playing and recording in a single command, the actual relay of samples
%   to playrec is done in the next call of |blockread|.
%   In case no audio output is expected (in the rec only mode),
%   the function does nothing.

complainif_notenoughargs(nargin,1,'BLOCKPLAY');

source = block_interface('getSource');

if ( iscell(source) && strcmp(source{1},'rec')) || ...
   strcmp(source,'rec')
   % Do nothing in rec only mode.
   return;
   % error('%s: Blocks cannot be played in the rec only mode.',upper(mfilename));
end

% Reformat f if necessary
f = comp_sigreshape_pre(f,'BLOCKPLAY',0);

block_interface('setToPlay',f);


function stopfun = stopifdeletedfile(filename)
% Create an interactive stopping criterion based on the existence of a file
%
% function stopfun = stopifdeletedfile()
% function stopfun = stopifdeletedfile(filename)
%
% Use on the options structure passed to a Manopt solver, e.g.:
%
%   problem = ... % manopt problem structure with manifold, cost function, ...
%   options.stopfun = stopifdeletedfile(); % add this option
%   trustregions(problem, x0, options); % run this or any other solver
%
% This will create a temporary file called MANOPT_DELETE_ME_TO_STOP_SOLVER
% in the present working directory. If this file is deleted at any time
% during the solver's execution, the solver will terminate gracefully and
% return its current iterate as soon as it gets to the point of evaluating
% stopping criteria. A different file name can also be specified using the
% input string filename (optional).
%
% Note: certain solvers (including trustregions) check stopping criteria
% only at outer iterations, not during inner iterations; hence, their may
% be a delay before actual termination.
%
% See also: statsfunhelper stopifclosedfigure

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Aug. 2, 2018.
% Contributors:
% Change log:

    % Default name for the temporary file.
    if ~exist('filename', 'var') || isempty(filename)
        filename = 'MANOPT_DELETE_ME_TO_STOP_SOLVER';
    end

    % Make sure the file exists, and release our handle on it.
    fid = fopen(filename, 'a');
    if fid >= 0
        fclose(fid);
        % The stopping criterion is a function handle.
        stopfun = @checkcriterion;
    else
        warning('manopt:stopifdeletedfile', ...
              'Couldn''t create the file: no stopping criterion created.');
        stopfun = @(problem, x, info, last) false;
    end

    % The function is defined as a subfunction so that it has access to
    % filename without the need for an @() construct. This makes it easier
    % for Matlab to determine the number of output arguments of the
    % function handle @checkcriterion, which ultimately helps
    % stoppingcriterion determine how to call it.
    function [stop, reason] = checkcriterion(problem, x, info, last) %#ok<INUSD>

        reason = sprintf(['Interactive stopping criterion ' ...
                     '(file %s deleted). See options.stopfun.'], filename);

        % Try to access the file.
        fid = fopen(filename, 'r');

        % If we can't, it means the file no longer exists: stop the solver.
        % Otherwise, release our handle on the file to make sure it can be
        % deleted by another program.
        if fid < 0
            stop = true;
        else
            fclose(fid);
            stop = false;
        end

    end

end


function DebugBatch(mfile,bfile,item,varargin)

%DebugBatch - Help debug a batch job.
%
%  This function can be used to help debug a batch. It retrieves the parameters
%  corresponding to the required item from the batch file, and either starts
%  the batch function with these parameters in debug mode, or simply assigns
%  these parameters to new variables in matlab's workspace so they can be
%  directly manipulated.
%
%  Set breakpoints in the batch function before running DebugBatch. If no
%  breakpoints have been defined, DebugBatch will stop at the first line.
%
%  USAGE
%
%    DebugBatch(mfile,bfile,item,<options>)
%
%    mfile          batch function (M-file name or function handle)
%    bfile          batch file listing the parameters for each iteration
%    item           item number in batch function
%    <options>      optional list of property-value pairs (see table below)
%
%    =========================================================================
%     Properties    Values
%    -------------------------------------------------------------------------
%     'mode'        run the batch function ('run', default) or simply set
%                   variables in matlab's workspace ('set')
%    =========================================================================
%
%  OUTPUT
%
%    Instantiates the variables of the batch function using the values in the
%    batch file ('set' mode).
%
%  SEE
%
%    See also StartBatch.
%

% Copyright (C) 2007-2013 by Michaël Zugaro
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 3 of the License, or
% (at your option) any later version.

% Default values
mode = 'run';

% Check number of parameters
if nargin < 3,
	error(['Incorrect number of parameters (type ''help DebugBatch'' for details).']);
end

% Batch function name
if isa(mfile,'function_handle'),
	mfile = func2str(mfile);
end

% Check batch file and function are valid
if ~isstring(bfile) || ~exist(bfile,'file'),
	error(['Batch file not found (type ''help DebugBatch'' for details).']);
end
if isempty(which(mfile)),
	error(['Batch function not found (type ''help DebugBatch'' for details).']);
end

% Item
if ~isiscalar(item),
	error(['Incorrect item (type ''help DebugBatch'' for details).']);
end

% Parse parameter list
for i = 1:2:length(varargin),
  if ~ischar(varargin{i}),
    error(['Parameter ' num2str(i+1) ' is not a property (type ''help DebugBatch'' for details).']);
  end
  switch(lower(varargin{i})),
    case 'mode',
      mode = lower(varargin{i+1});
      if ~isstring(mode,'run','set'),
        error('Incorrect value for property ''mode'' (type ''help DebugBatch'' for details).');
      end
    otherwise,
      error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help DebugBatch'' for details).']);
  end
end

% Open batch file
f = fopen(bfile,'r');
if f == -1, error(['Could not open file ''' bfile '''.']); end

% Parse batch file
b = ParseBatch(bfile);

if strcmp(mode,'run'),

	% Check breakpoints
	if length(dbstatus(mfile)) == 0,
		eval(['dbstop in ' mfile ' at 1;']);
	end

	% Run batch function with appropriate parameters
	for i = 1:size(b.field,2),
		args{i} = b.field{item,i};
	end
	outputs = cell(1,nargout(mfile));
	[outputs{:}] = feval(mfile,args{:})

else

	% Open batch function
	if isa(mfile,'function_handle'),
		mfile = func2str(mfile);
	end
	f = fopen(which(mfile));

	% Find first line containing the (uncommented) 'function' keyword
	found = [];
	while isempty(found),
		line = fgets(f);
		if line == -1, error('Could not find function definition in batch function.'); end
		line = regexprep(line,'%.*function.*','');
		found = regexp(line,'.*function[^(]*\(([^)]*)\).*');
	end
	fclose(f);

	% Extract parameter names, and assign them in 'base' workspace
	parameters = regexprep(line,'.*function[^(]*\(([^)]*)\).*','$1');
	parameters = regexp(parameters,'[^,]*','match');
	for i = 1:length(parameters),
		assignin('base',parameters{i},b.field{item,i});
	end

end


function MimSaveAsNifti(image_to_save, path, filename, reporting)
    % MimSaveAsNifti. Writes out a PTKImage in NIFTI format
    %
    %     Syntax
    %     ------
    %
    %         MimSaveAsNifti(image_data, path, filename, data_type, orientation, reporting)
    %
    %             image_to_save   is a PTKImage (or PTKDicomImage) class containing the image
    %                             to be saved
    %             path, filename  specify the location to save the NIFTI data.
    %             reporting       an object implementing CoreReportingInterface
    %                             for reporting progress and warnings
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, Copyright Tom Doel 2014.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    if nargin < 4
        reporting = CoreReportingDefault();
    end

    if ~isa(image_to_save, 'PTKImage')
        reporting.Error('MimSaveAsNifti:InputMustBePTKImage', 'Requires a PTKImage as input');
    end

    image_data = image_to_save.RawImage;

    full_filename = fullfile(path, filename);

    resolution = image_to_save.VoxelSize([2, 1, 3]);

    offset = [0 0 0];
    if isa(image_data, 'PTKDicomImage')
        metadata = image_data. MetaHeader;
        if isfield(metadata, 'Offset')
            offset = metadata.Offset;
        end
    end

    image_data = permute(image_data, [2, 1, 3]);
    image_data = flip(flip(flip(image_data, 3), 2), 1);

    nii_data = make_nii(image_data, resolution, offset, [], image_to_save.Title);
    save_nii(nii_data, full_filename);
end


classdef prtUiDataSetClassExploreWidget < prtUiManagerPanel
    % ToDo:
    %   onClickCallback
    %   axesDeleteCallbacl
    %   Make the legened stay where we put it
    %   uicontext menu feature select

    properties
        plotManager

        titleStr = 'prtDataSetClass Explorer Widget';

        tabObjectConstructors = {@prtUiDataSetClassExploreWidgetTabSelectAxes @prtUiDataSetClassExploreWidgetTabPlotOptions @prtUiDataSetClassExploreWidgetTabClickDisplay};

        handles
        tabs

        madeThisWindow = false;
    end

    methods
        function self = prtUiDataSetClassExploreWidget(varargin)

            if mod(nargin,2)
                varargin = cat(2,{'plotManager'},varargin);
            end
            self = self@prtUiManagerPanel(varargin{:});

            if isempty(self.plotManager)
                error('prt:prtUiDataSetClassExploreWidget:noInput','plotManager must be specified');
            end

            init(self);
        end

        function create(self)

            navFigSize = [300 250];
            navFigPad = [18 54];

            plotAxesFigPos = get(self.plotManager.handles.figure,'position');

            oldUnits = get(self.plotManager.handles.axes,'units');
            set(self.plotManager.handles.axes,'Units','pixels');
            plotAxesOuterPos = get(self.plotManager.handles.axes,'outerposition');
            set(self.plotManager.handles.axes,'units',oldUnits);

            navFigPosTop = plotAxesFigPos(2)+plotAxesOuterPos(2)-1+plotAxesOuterPos(4) + navFigPad(2);
            navFigPosLeft = plotAxesFigPos(1)+plotAxesOuterPos(1)-1+plotAxesOuterPos(3) + navFigPad(1);

            % Make sure we aren't off the screen
            screenSize = get(0,'screensize');
            navFigPosTop = min([navFigPosTop, screenSize(4)-50]);
            navFigPosLeft = min([navFigPosLeft, screenSize(3)-navFigSize(2)-60]);

            navFigPos = cat(2,navFigPosLeft, navFigPosTop-navFigSize(2), navFigSize(1), navFigSize(2));

            self.handles.figure = figure('units','pixels',...
                'position', navFigPos,...
                'menubar','none',...
                'toolbar','none',...
                'numberTitle','off',...
                'Name',self.titleStr,...
                'Interruptible','off',...
                'BusyAction','cancel',...
                'DockControls','off',...
                'NextPlot','new');

            self.managedHandle = uipanel(self.handles.figure, ...
                'units','normalized',...
                'BorderType','none',...
                'Position',[0 0 1 1]);

            self.madeThisWindow = true;

            % Just in case anyone tries to plot in this window we will plot that inside
            % an invisible axes
            self.handles.invisibleAxes = axes('parent',self.handles.figure,...
                'units','pixels',...
                'position',[0 0  1 1],...
                'visible','off',...
                'handlevisibility','on');
        end

        function init(self)
            self.handles.tabGroup = prtUtilUitabgroup('parent',self.managedHandle);
            nTabs = length(self.tabObjectConstructors);
            self.handles.tabs = prtUtilPreAllocateHandles(nTabs,1);
            self.handles.tabPanels = prtUtilPreAllocateHandles(nTabs,1);
            for iTab = 1:nTabs
                self.handles.tabs(iTab) = prtUtilUitab(self.handles.tabGroup, 'title', 'Temp');
                self.handles.tabPanels(iTab) = uipanel('parent',self.handles.tabs(iTab));
                %uicontrol(self.handles.tabPanels(iTab),'style','pushbutton','string','hi');

                self.tabs{iTab} = self.tabObjectConstructors{iTab}('managedHandle',self.handles.tabPanels(iTab),'widget',self);
                set(self.handles.tabs(iTab), 'title', self.tabs{iTab}.titleStr);
            end

            %self.handles.listenerClose = addlistener(self.plotManager.handles.axes,'BeingDeleted',@(~,~)close(self.handles.figure));
            cDeleteFcn = get(self.plotManager.handles.axes,'DeleteFcn');
            if ~isempty(cDeleteFcn)
                warning('prtUiDataSetClassExploreWidget removed an existing axes DeleteFcn. This is a bug that will be removed in a future release');
            end
            set(self.plotManager.handles.axes,'DeleteFcn',@(~,~)self.onPlotAxesDelete())

        end
        function onPlotAxesDelete(self)
            try  %#ok<TRYNC>
                close(self.handles.figure);
            end
        end
        function close(self)
            try  %#ok<TRYNC>
                close(self.handles.figure);
            end
        end
    end
end


function [err,p,f] = GetPath (s, allmc)
%
%   [err,PathString,FileString] = GetPath (s, allmc)
%
%Purpose:
%   Breaks the string s into a path and file part
%
%
%Input Parameters:
%   s is a string like How/Didley/Doo
%   allmc : 1 --> search for path using both types of file-separators / and \
%           0 --> search for path using filesep's output (default)
%
%Output Parameters:
%
%if nargout = 1
%  returns PathString
%
%Otherwise:
%   err : 0 No Problem
%       : 1 Mucho Problems
%
%   PathString is a string like How/Didley/
%   FileString is a string like Doo
%
%More Info :
%
%
%
%
%     Author : Ziad Saad
%     Date : Thu Apr 23 11:41:06 CDT 1998

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

if (nargin == 1),
   allmc = 0;
end

%initailize return variables
err = 1;
p = '.';
f = '';

N = length(s);
if (N == 0),
	err = ErrEval(FuncName,'Err_Emtpy string');
   if (nargout == 1) err = ''; end
   return;
end

if (allmc == 0),
   [i] = findstr(s,filesep);
else
   [i] = union(findstr(s,'/'), findstr(s,'\'));
end
if (isempty(i)),
	p = ['.' filesep];
	f = s;
elseif (max(i)==N);
	p = s;
	f = '';
else
	p = s(1:max(i));
	f = s(max(i)+1:N);
end

if (nargout < 2) err = p; else err = 0; end

return;


function f = make(varargin)
%MAKE   Constructor shortcut for SINGFUN objects.
%   For SINGFUN methods implemented at the ONEFUN level, it is not possible to
%   call the class constructor file corresponding to a ONEFUN object directly.
%   F = MAKE(VARARGIN) allows us to get around this and construct a SINGFUN.
%
% See also SINGFUN.

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Developer note: This is essentially a "factory method" in the sense of
% _Design Patterns_ by Gamma, Helm, Johnson, and Vlissides.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

f = singfun(varargin{:});

end


function varargout = offset(varargin)
% file_array's offset property
% For getting the value
% dat = offset(obj)
%
% For setting the value
% obj = offset(obj,dat)
%__________________________________________________________________________
% Copyright (C) 2005-2017 Wellcome Trust Centre for Neuroimaging

%
% $Id: offset.m 7147 2017-08-03 14:07:01Z spm $

if nargin==2
    varargout{1} = asgn(varargin{:});
elseif nargin==1
    varargout{1} = ref(varargin{:});
else
    error('Wrong number of arguments.');
end

%==========================================================================
% function dat = ref(obj)
%==========================================================================
function dat = ref(obj)
dat = obj.offset;

%==========================================================================
% function obj = asgn(obj,dat)
%==========================================================================
function obj = asgn(obj,dat)
if isnumeric(dat) && numel(dat)==1 && dat>=0 && rem(dat,1)==0
    obj.offset = double(dat);
else
    error('"offset" must be a positive integer.');
end


classdef LiftCoefficientModelEnum < matlab.mixin.SetGet
    %LiftCoefficientModelEnum Summary of this class goes here
    %   Detailed explanation goes here

    enumeration
        KSPCylinder('KSP Cylinder',"Models the vehicle as a circular cylinder with constant radius and height whose long axis is the body X axis.  Uses the KSP 'lifting body' lift coefficient curves in physics.cfg.");
    end

    properties
        name(1,:) char
        desc(1,1) string
    end

    methods
        function obj = LiftCoefficientModelEnum(name, desc)
            obj.name = name;
            obj.desc = desc;
        end
    end

    methods(Static)
        function [listBoxStr, m] = getListBoxStr()
            m = enumeration('LiftCoefficientModelEnum');
            [~,I] = sort({m.name});
            listBoxStr = {m(I).name};
            m = m(I);
        end
    end
end


%kvadil 'Conditionally Translation Invariant Anti-Dilation'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros vadil.pane file
%
% Parameters:
% InputFile: i 'Input Image', required: 'input image'
% InputFile: str 'Struct Element', required: 'Structuring Element'
% OutputFile: o 'Output Image ', required: 'resulting output image'
%
% Example: o = kvadil({i, str}, {'i','';'str','';'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% vadil - Conditionally Translation Invariant Anti-Dilation
%
%  DESCRIPTION
% .I vadil
% will do the anti-dilation of an input image by a set structuring element.
%
% The output image data type will be the same as that of the highest data type
% of the input image.
%
%
%
%  EXAMPLES
% vadil -i ball.xv -str b272.str -o outimage.xv
%
% Will do the anti-dilation of image "ball.xv" by the structuring set b272.str, with the resulting image written to "outimage.xv".
%
%  "SEE ALSO"
% vcast1(1)
%
%  RESTRICTIONS
% .I vadil
% can be defined for all data types supported by Khoros, but at the moment it has been implemented just for the bit and unsigned char types.
% The structuring elements are subsets of the 3x3 matrix and the origin is always at the center of this matrix.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993-1997 Junior Barrera, Roberto Lotufo.  All rights reserved.
%

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

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


function multimodelDisplay(model, spacing)

% MULTIMODELDISPLAY Display parameters of the MULTIMODEL model.
% FORMAT
% DESC displays the parameters of the multi-task learning wrapper
% model and the model type to the console.
% ARG model : the model to display.
%
% FORMAT does the same as above, but indents the display according
% to the amount specified.
% ARG model : the model to display.
% ARG spacing : how many spaces to indent the display of the model by.
%
% SEEALSO : multimodelCreate, modelDisplay
%
% COPYRIGHT : Neil D. Lawrence, 2007

% MLTOOLS

if nargin > 1
  spacing = repmat(32, 1, spacing);
else
  spacing = [];
end
spacing = char(spacing);
fprintf(spacing);
fprintf('Multi-model:\n')
for i = 1:length(model.comp)
  fprintf('Component %d:\n', i)
  spacing = length(spacing)+2;
  modelDisplay(model.comp{i}, spacing);
end


%% Load ground truth image and SR results from real and simulated data.
load('G:\results\baselineDatasets\coffee\Uncoded\mat\global_pan_translation_xyz_inlier_bin4_sr0_f17_win01.mat');
I_gt = srImages.groundTruth;

load('G:\results\baselineDatasets\coffee\Uncoded\mat\global_pan_translation_xyz_inlier_bin4_sr19_f17_win01.mat');
I_real = srImages.vdsr;

load('G:\results\simulatedDatasets\coffee\Uncoded\mat\global_pan_translation_xyz_inlier_bin4_sr19_f17_win01.mat');
I_simulated = srImages.vdsr;

%% Error map for real data.
ROI = [570, 420, 290, 400];
rangeIn = [1e-4 2e-1];
rangeOut = [0.15 0.85];
gamma = 0.9;

errorMap = abs(I_gt - I_real);
errorMap = errorMap(ROI(1):(ROI(1) + ROI(3) - 1), ROI(2):(ROI(2) + ROI(4) - 1));

figure;
I_real = I_real(ROI(1):(ROI(1) + ROI(3) - 1), ROI(2):(ROI(2) + ROI(4) - 1));
I_real = imadjust(I_real, [], [], gamma);
imshow(I_real);
imwrite(I_real, 'D:\Paper\cvpr2017\latex\images\teaser_real_SR.png');
figure;
errorMap = imadjust(errorMap, rangeIn, rangeOut);
imwrite(gray2ind(errorMap), jet, 'D:\Paper\cvpr2017\latex\images\teaser_real_diff.png');
imshow(errorMap);
colormap(gca, jet);

%% Error map for simulated data.
errorMap = abs(I_gt - I_simulated);
errorMap = errorMap(ROI(1):(ROI(1) + ROI(3) - 1), ROI(2):(ROI(2) + ROI(4) - 1));

figure;
I_simulated = I_simulated(ROI(1):(ROI(1) + ROI(3) - 1), ROI(2):(ROI(2) + ROI(4) - 1));
I_simulated = imadjust(I_simulated, [], [], gamma);
imshow(I_simulated);
imwrite(I_simulated, 'D:\Paper\cvpr2017\latex\images\teaser_simulated_SR.png');
figure;
errorMap = imadjust(errorMap, rangeIn, rangeOut);
imwrite(gray2ind(errorMap), jet, 'D:\Paper\cvpr2017\latex\images\teaser_simulated_diff.png');
imshow(errorMap);
colormap(gca, jet)


function yml=mbmling(xml,plt)

%MBMLING_CELL converts any XML into MbML (Matlab Markup Language) compliant string
%
%Syntax: yml=mbmling(xml,plt)
%
%Description:
%   Converts any XML syntax into Matlab Markup Language (MbML)
%
% Jonas Almeida, almeidaj@musc.edu, 18 May 2002, MAT4NAT Tbox

if nargin<2;plt=0;end
if plt==1;disp('MbMLing progress report');disp('---------BEGIN----(9 steps)----------');end

% Remove non-content lines if they exist
if plt==1;disp('1. Removing non-content lines if they exist');end
xml=regexprep(xml,'<[?!].*?>','');
% Remove empty spaces between tags
if plt==1;disp('2. Removing empty spaces between tags');end
%xml=regexprep(xml,'>[ ]+?<','><');
xml=strrep(xml,char([13,10]),' '); %replace chariage returns by spaces
n=length(xml)+1;
while n>length(xml)
    n=length(xml);
    xml=strrep(xml,'> ','>');
end
% Replace symbols that may conflict with matlab variable naming by underscore characters
if plt==1;disp('3. Replacing symbols that may conflict with matlab variable naming by underscore characters');end
xml=regexprep(xml,'<[\/]{0,1}(\w*)[^\w\/> ]+(.*?)([ >])','<$1_$2$3','tokenize');
% Replace one-tag format by open / close tagging
if plt==1;disp('4. Replace one-tag format by open / close tagging');end
xml_=regexprep(xml,'<(\w+)([^>]*?)/>','<$1$2></$1>','tokenize');
% Turn attributes into contents
if plt==1;disp('5. Turn attributes into contents');end
xml=regexprep(xml_,'<([^>]+) +(\w+)="(.*?)" *>','<$1><$2>$3</$2>','tokenize');
while ~strcmp(xml,xml_)
    %disp('...')
    xml_=xml;xml=regexprep(xml_,'<([^>]+) +(\w+)="(.*?)" *>','<$1><$2>$3</$2>','tokenize');
end
% remove leftover spaces in tag names
if plt==1;disp('6. Removing leftover spaces in tag names');end
xml=regexprep(xml,'(<\w+) +>','$1>','tokenize');
% Tag untagged contents
if plt==1;disp('7. Tagging untagged contents');end
yml=regexprep(xml,'(</\w+>)([^<>]+)</(\w+)','$1<$3>$2</$3></$3','tokenize');
% Tag cell structures
if plt==1;disp('8. Tag cell structures');end
yml=regexprep(yml,'<(\w+)>','<$1 class="cell"><cell>','tokenize');
yml=regexprep(yml,'<(/\w+)>','</""""><$1>','tokenize');
yml=regexprep(yml,'<(/\w+)>(<\w+ )','<$1></""""><cell>$2','tokenize');
% Remove cell tag arround content values
if plt==1;disp('9. Remove cell tag arround content values');end
yml=regexprep(yml,'class="cell"><cell>([^<]*)</"""">','class="char">$1','tokenize');
yml=strrep(yml,'</"""">','</cell>');
if plt==1;disp('------------END----------------------');end


function LMprogressiveinstall(folderlist, HOMEIMAGES, HOMEANNOTATIONS);
%
% Downloads a set of folders from the LabelMe dataset.
%  LMprogressiveinstall(folderlist, HOMEIMAGES, HOMEANNOTATIONS);
%
% This function is useful if you do not want to download the entire
% dataset. You can first browse the dataset, and when you have decided for
% a set of folders that you want to use, you can use this function to
% download only those folders.
%
% Contribute to the dataset by labeling few images:
% http://people.csail.mit.edu/brussell/research/LabelMe/intro.html

Nfolders = length(folderlist);
webpageanno = 'http://people.csail.mit.edu/brussell/research/LabelMe/Annotations'
webpageimg = 'http://people.csail.mit.edu/brussell/research/LabelMe/Images'

% create folders:
disp('create folders');
for i = 1:Nfolders
    [SUCCESS,MESSAGE,MESSAGEID] = mkdir(HOMEIMAGES, folderlist{i});
    [SUCCESS,MESSAGE,MESSAGEID] = mkdir(HOMEANNOTATIONS, folderlist{i});
end

disp('progressively downloading images ..., # of folders:')
for f = 1:Nfolders
    disp(sprintf('%d/%d, %s', f, Nfolders, folderlist{f}))
    wpi = [webpageimg  '/' folderlist{f}];
    images = urldir(wpi, 'IMG');
    Nimages = length(images);
    for i = 1:Nimages
        % if the image already exist, then overwrite
        fp = fopen(fullfile(HOMEIMAGES,folderlist{f},images(i).name));
        if fp < 0
            [F,STATUS] = urlwrite([wpi '/' images(i).name], fullfile(HOMEIMAGES,folderlist{f},images(i).name));
%            disp(sprintf('downloading: %s', images(i).name))
        else
            fclose(fp);
%            disp(sprintf('no need to download: %s', images(i).name))
        end
    end
    end

disp('downloading all annotations..., # of folders:')
for f = 1:Nfolders
    disp(sprintf('%d/%d, %s', f, Nfolders, folderlist{f}))

    wpa = [webpageanno '/' folderlist{f}];
    annotations = urldir(wpa, 'TXT');
    Nanno= length(annotations);
    for i = 1:Nanno
        [F,STATUS] = urlwrite([wpa '/' annotations(i).name], fullfile(HOMEANNOTATIONS,folderlist{f},annotations(i).name));
    end
end


function res = rcnn_test(rcnn_model, imdb, suffix)
% res = rcnn_test(rcnn_model, imdb, suffix)
%   Compute test results using the trained rcnn_model on the
%   image database specified by imdb. Results are saved
%   with an optional suffix.

% AUTORIGHTS
% ---------------------------------------------------------
% Copyright (c) 2014, Ross Girshick
%
% This file is part of the R-CNN code and is available
% under the terms of the Simplified BSD License provided in
% LICENSE. Please retain this notice and LICENSE if you use
% this file (or any portion of it) in your project.
% ---------------------------------------------------------

conf = rcnn_config();
image_ids = imdb.image_ids;

% assume they are all the same
feat_opts = rcnn_model.feat_opts;
training_opts = rcnn_model.training_opts;
num_classes = length(rcnn_model.classes);

exists_or_mkdir(fullfile(conf.cache_dir, 'detections'));
exists_or_mkdir(fullfile(conf.cache_dir, 'pr-curves'));

try
  aboxes = cell(num_classes, 1);
  for i = 1:num_classes
    load(fullfile_ext(conf.cache_dir, 'detections', [rcnn_model.classes{i} '_boxes_' imdb.name suffix], 'mat'));
    aboxes{i} = boxes;
  end
catch
  aboxes = cell(num_classes, 1);
  box_inds = cell(num_classes, 1);
  for i = 1:num_classes
    aboxes{i} = cell(length(image_ids), 1);
    box_inds{i} = cell(length(image_ids), 1);
  end

  if ~isfield(rcnn_model, 'folds')
    folds{1} = 1:length(image_ids);
  else
    folds = rcnn_model.folds;
  end

  fold_for_image = zeros(1, length(imdb.image_ids));
  count = 0;
  for f = 1:length(folds)
    for i = folds{f},
      assert(fold_for_image(i) == 0);
      fold_for_image(i) = f;
    end
  end

  parfor i = 1:length(imdb.image_ids),
    tic_toc_print('%s: test (%s) %d/%d\n', procid(), imdb.name, i, length(image_ids));
    d = get_features(imdb, i, feat_opts, false);
    d.feat = rcnn_scale_features(d.feat, training_opts.feat_norm_mean);
    zsAll{i} = bsxfun(@plus, d.feat*rcnn_model.detectors(fold_for_image(i)).W, rcnn_model.detectors(fold_for_image(i)).B);
    boxesAll{i} = d.boxes;
    gtAll{i} = d.gt;
  end

  for i = 1:length(imdb.image_ids),
    boxes = boxesAll{i};
    zs = zsAll{i};
    gt = gtAll{i};
    for j = 1:num_classes,
      z = zs(:,j);
      I = find(~gt);
      aboxes{j}{i} = cat(2, single(boxes(I,:)), z(I));
      allboxes{j}{i} = cat(2, single(boxes), z);
    end
  end

  for i = 1:num_classes
    save_file = fullfile_ext(conf.cache_dir, 'detections', [rcnn_model.classes{i} '_boxes_' imdb.name suffix], 'mat');
    parsave(save_file, 'boxes', aboxes{i}, 'allboxes', allboxes{i}, 'imdb', imdb);
  end
end

% ------------------------------------------------------------------------
% Peform AP evaluation
% ------------------------------------------------------------------------
for model_ind = 1:num_classes
  cls = rcnn_model.classes{model_ind};
  res(model_ind) = imdb.eval_func(cls, aboxes{model_ind}, imdb);
  resI = res(model_ind);

  % Generate and save the precision recall curve
  print(res(model_ind).plotHandle, '-djpeg', '-r0', ...
      fullfile(conf.cache_dir, 'pr-curves', [cls '_pr_' imdb.name suffix '.jpg']));

  save(fullfile_ext(conf.cache_dir, 'pr-curves', [cls '_pr_' imdb.name suffix], 'mat'), ...
    '-STRUCT', 'resI');
end

save(fullfile_ext(conf.cache_dir, 'pr-curves', ['results_' imdb.name suffix], 'mat'), 'res', 'imdb');

fprintf('\n~~~~~~~~~~~~~~~~~~~~\n');
fprintf('Results:\n');
aps = [res(:).ap]';
disp(aps);
disp(mean(aps));
fprintf('~~~~~~~~~~~~~~~~~~~~\n');


function mrcnn_build()
if ~exist('liblinear_train')
  fprintf('Compiling liblinear version 1.94\n');
  fprintf('Source code page:\n');
  fprintf('   http://www.csie.ntu.edu.tw/~cjlin/liblinear/\n');
  mex -outdir bin ...
      CFLAGS="\$CFLAGS -std=c99 -O3 -fPIC" -largeArrayDims ...
      external/liblinear-1.94/matlab/train.c ...
      external/liblinear-1.94/matlab/linear_model_matlab.c ...
      external/liblinear-1.94/linear.cpp ...
      external/liblinear-1.94/tron.cpp ...
      "external/liblinear-1.94/blas/*.c" ...
      -output liblinear_train;
end

if ~exist('adaptive_region_pooling_mex')
  fprintf('Compiling adaptive_region_pooling_mex\n');

  mex -outdir bin ...
      -largeArrayDims ...
      code/adaptive_region_pooling/adaptive_region_pooling_mex.cpp ...
      -output adaptive_region_pooling_mex;
end

if ~exist('nms_mex')
  fprintf('Compiling nms_mex\n');

  mex -outdir bin ...
      -largeArrayDims ...
      code/postprocessing/nms_mex.cpp ...
      -output nms_mex;
end
end


classdef MimZoomTool < MimTool
    % MimZoomTool. A tool for interactively zooming an image with MimViewerPanel
    %
    %     MimZoomTool is a tool class used with MimViewerPanel to allow the user
    %     to zoom an image using mouse and keyboard controls.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, 2013.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    properties
        ButtonText = 'Zoom'
        Cursor = 'circle'
        ToolTip = 'Zoom tool'
        Tag = 'Zoom'
        ShortcutKey = ''
    end

    properties (Access = private)
        Callback
    end

    properties (Access = private)
        StartImageLimitsMin
        StartImageLimitsMax
        ImageParameters
        StartCoords
    end

    methods
        function obj = MimZoomTool(image_parameters, callback)
            obj.Callback = callback;
            obj.ImageParameters = image_parameters;
        end

        function MouseDragged(obj, screen_coords, last_coords)
            if ~isempty(obj.StartCoords) && ~isempty(obj.StartImageLimitsMin)
                min_coords = obj.StartImageLimitsMin;
                max_coords = obj.StartImageLimitsMax;
                x_range = max_coords(1) - min_coords(1);
                y_range = max_coords(2) - min_coords(2);

                coords_offset = screen_coords - obj.StartCoords;
                y_relative_movement = coords_offset(2)/y_range;

                relative_scale = y_relative_movement;
                x_range_scale = relative_scale*x_range/1.5;
                y_range_scale = relative_scale*y_range/1.5;

                x_lim = [min_coords(1) - x_range_scale, max_coords(1) + x_range_scale];

                y_lim = [min_coords(2) - y_range_scale, max_coords(2) + y_range_scale];

                if (abs(x_lim(2) - x_lim(1)) > 10) && (abs(y_lim(2) - y_lim(1)) > 10) && ...
                        (abs(x_lim(2) - x_lim(1)) < 1000) && (abs(y_lim(2) - y_lim(1)) < 800)
                    obj.Callback.SetImageLimits([x_lim(1), y_lim(1)], [x_lim(2), y_lim(2)]);
                end
            end
        end

        function MouseDown(obj, screen_coords)
            [obj.StartImageLimitsMin, obj.StartImageLimitsMax] = obj.Callback.GetImageLimits();
            obj.StartCoords = screen_coords;
        end

        function NewOrientation(obj)
            obj.StartCoords = [];
        end

        function ImageChanged(obj)
            obj.StartImageLimitsMin = [];
            obj.StartImageLimitsMax = [];
            obj.StartCoords = [];
        end

        function Enter(obj)
            obj.StartImageLimitsMin = [];
            obj.StartImageLimitsMax = [];
            obj.StartCoords = [];
        end
    end
end


function targNames = prtUtilGenerateDefaultTargetNames(indices2)
% targNames = prtUtilGenerateDefaultTargetNames(indices2)

% Previously static in prtDataSetBase
%     function targNames = generateDefaultTargetNames(indices2)
%         targNames = prtUtilCellPrintf('Target %d',num2cell(indices2));
%         targNames = targNames(:);
%     end
targNames = prtUtilCellPrintf('Target %d',num2cell(indices2));
targNames = targNames(:);


function options = IRset(varargin)
%IRset Set options for IR Tools functions
%
% options = IRset('param1',value1,'param2',value2,...)
%
% Create/alter options structure for methods in IR Tools, in which the
% named parameters have the specified values.  Any unspecified parameters
% are set to [] (they indicate to use the default value for that parameter
% when passed to an IR function). It is sufficient to type only the
% leading characters that uniquely identify the parameter, and  case is
% ignored for parameter names.
% NOTE: For values that are strings, the complete string is required.
%
% options = IRset(OLDOPTS,'param1',value1,...) creates a copy of OLDOPTS
%   with the named parameters altered with the specified values.
%
% options = IRset(OLDOPTS,NEWOPTS) combines an existing options structure
%   OLDOPTS with a new structure NEWOPTS.  Any parameters in NEWOPTS with
%   non-empty values overwrite the corresponding old parameters in OLDOPTS.
%
% options = IRset('IRmethod') creates an options structure with all the
% parameter names and default values relevant to an IR method. That is,
%           IRset('IRmethod')
% or
%           IRset(@IRmethod)
% returns an options structure containing all the parameter names and
% default values relevant to an IR method.
%
% Examples:
%   To create options with the default options for an IR nethod
%       options = IRset('IRmethod');
%   To change the maximum iterations to 150 in options
%       options = IRset(options,'MaxIter',150);
%
% See also: IRget, PRget, PRset

% Silvia Gazzola, University of Bath
% Per Christian Hansen, Technical University of Denmark
% James G. Nagy, Emory University
% April, 2018.

% This file is part of the IR Tools package and is distributed under the
% 3-Clause BSD License. A separate license file should be provided as part
% of the package.

% Create a struct of all the fields. Note that if new options are added
% then IRoptions_fields.m should be edited to include the field name in
% the list created in IRoptions_fields.m.
%
allfields = IRoption_fields;

% Create cell array.
structinput = cell(2,length(allfields));
% Fields go in first row.
structinput(1,:) = allfields';
% []'s go in second row.
structinput(2,:) = {[]};
% Turn it into correctly ordered comma separated list and call struct
options = struct(structinput{:});

numberargs = nargin; % We might change this value, so assign it.

% If we pass in a function name then return the defaults.
if (numberargs==1) && (ischar(varargin{1}) || isa(varargin{1},'function_handle') )
  if ischar(varargin{1})
    funcname = lower(varargin{1});
  elseif isa(varargin{1},'function_handle')
    funcname = func2str(varargin{1});
  end
  if ~exist(funcname, 'file')
     error('Undefined function.  Please use IRset(''funcname'') or IRset(@funcname), where funcname is a IR method')
  end
  try
    optionsfcn = feval(varargin{1},'defaults');
  catch
    error('IRset ONLY works with an IR method.  Please use IRset(@IR).')
  end
  % The defaults from IR functions don't include all the fields typically,
  % so run the rest of IRset as if called with IRset(options,optionsfcn)
  % to get all the fields.
  varargin{1} = options;
  varargin{2} = optionsfcn;
  numberargs = 2;
end

Names = allfields;
m = size(Names,1);
names = lower(Names);

i = 1;
while i <= numberargs
  arg = varargin{i};
  if ischar(arg)                         % arg is an option name.
    break;
  end
  if ~isempty(arg)                      % [] is a valid options argument.
    if ~isa(arg,'struct')
      error(['Expected argument %d to be a string parameter name ' ...
             'or an options structure \n created with IRset.'], i);
    end
    for j = 1:m
      if any(strcmp(fieldnames(arg),Names{j,:}))
        val = arg.(Names{j,:});
      else
        val = [];
      end
      if ~isempty(val)
        if ischar(val)
          val = lower(deblank(val));
        end
        checkfield(Names{j,:},val)
        options.(Names{j,:}) = val;
      end
    end
  end
  i = i + 1;
end

% A finite state machine to parse name-value pairs.
if rem(numberargs-i+1,2) ~= 0
  error('Arguments must occur in name-value pairs.');
end

expectval = 0;                    % Start expecting a name, not a value.
while i <= numberargs
  arg = varargin{i};

  if ~expectval
    if ~ischar(arg)
      error('Expected argument %d to be a string parameter name.', i);
    end

    lowArg = lower(arg);
    j = find(strcmp(lowArg,names));
    if isempty(j)                       % If no matches.
      error('Invalid parameter name ''%s'' ', arg);
    elseif length(j) > 1                % If more than one match.
      % Check for any exact matches (in case any names are subsets of others).
      k = find(strcmp(lowArg,names));
      if length(k) == 1
        j = k;
      else
        error('Ambiguous parameter name ''%s'' ', arg);
      end
    end
    expectval = 1;                      % We expect a value next.

  else
    if ischar(arg)
      arg = lower(deblank(arg));
    end
    checkfield(Names{j,:},arg);
    options.(Names{j,:}) = arg;
    expectval = 0;
  end
  i = i + 1;
end

if expectval
  error( 'Expected value for parameter ''%s''.', arg);
end

%----SUBFUNCTIONS---------------------------------------------

function checkfield(field,value)
%CHECKFIELD Check validity of structure field contents.
%   CHECKFIELD('field',V) checks the contents of the specified
%   value V to be valid for the field 'field'.

% Empty matrix is always valid.
if isempty(value)
  return
end

% See if 'field' is a valid field.
%validfield = true;
switch field
  case {'MaxIter'} % real positive integer
    [validvalue, errmsg] = PosInteger(field,value);
  case {'MaxIterIn'} % real positive integer
    [validvalue, errmsg] = PosInteger(field,value);
  case {'MaxIterOut'} % real positive integer
    [validvalue, errmsg] = PosInteger(field,value);
  case {'InProjIt'} % real positive integer
    [validvalue, errmsg] = PosInteger(field,value);
  case{'TotIterMax'}
    [validvalue, errmsg] = PosInteger2(field, value);
  case{'ktotcount'}
    [validvalue, errmsg] = nonNegInteger2(field, value);
  case {'x0'} % numeric array, none
    [validvalue, errmsg] = x0type(field,value);
  case {'IterBar'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'x_true'} % numeric array, off
    [validvalue, errmsg] = x_truetype(field,value);
  case {'AllX'} %  off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'NoStop'} %  off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'NoStopIn'} %  off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'NoStopOut'} %  off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'restart'} %  off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'MatUpdate'}
    [validvalue, errmsg] = onOffType(field,value);
  case {'stopGCV'}
    [validvalue, errmsg] = stopGCVtype(field,value);
  case {'stopCrit'}
    [validvalue, errmsg] = stopCritype(field,value);
  case {'stopOut'}
    [validvalue, errmsg] = stopOutype(field,value);
  case {'tollalpha'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'NE_Rtol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'thr0'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'stabOut'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'RegMatrix'} % character string
    [validvalue, errmsg] = tikFunType(field,value);
  case {'enrichment'} % character string
    [validvalue, errmsg] = enrichType(field,value);
  case {'stdCGLS_out'}
    [validvalue, errmsg] = onOffType(field,value);
  case {'transf'} % character string
    [validvalue, errmsg] = spTransf(field,value);
  case {'Reorth'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'stoprule'} % character string
    [validvalue, errmsg] = stopruleType(field,value);
  case {'xMin'} % real scalar
    [validvalue, errmsg] = realScalar(field,value);
  case {'xMax'} % real scalar
    [validvalue, errmsg] = realScalar(field,value);
  case {'xEnergy'} % real positive scalar or 'none'
    [validvalue, errmsg] = positiveScalar2(field,value);
  case {'taudelta'} % real non-negative scalar or 'none'
    [validvalue, errmsg] = nonNegScalar2(field,value);
  case {'nonneg'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'verbosity'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'Ubound'} % real positive scalar or 'none'
    [validvalue, errmsg] = positiveScalar2(field,value);
  case {'relaxParam'}% real non-negative scalar
    [validvalue, errmsg] = nonNegScalar2(field,value);
  case {'RegParam'} %
    [validvalue, errmsg] = RegPartype(field,value);
  case {'GCVweight'} % real non-negative scalar, adapt
    [validvalue, errmsg] = WeightType(field,value);
  case {'GCVflatTol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'tolX'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'GCVminTol'}% real positive integer
    [validvalue, errmsg] = PosInteger(field,value);
  case {'resflatTol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'jbdTol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'jbdTolx'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'regPflatTol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'LSQRtols'}% real non-negative vector of length 2
    [validvalue, errmsg] = nonNeg2vector(field,value);
  case {'RegParam0'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'RegParamVect0'}% real non-negative scalar
    [validvalue, errmsg] = nonNegVector(field,value);
  case {'NoiseLevel'}% real non-negative scalar
    [validvalue, errmsg] = NoiseLevelType(field,value);
  case {'eta'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'BestEnrm'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'trunc'}
    [validvalue, errmsg] = truncation(field,value);
  case {'noiseType'}
    [validvalue, errmsg] = noiseType(field,value);
  case {'noiseParam'}
    [validvalue, errmsg] = PosVector2(field,value);
  case {'inSolver'} % character string
    [validvalue, errmsg] = inSolverType(field,value);
  case {'solver'} % character string
    [validvalue, errmsg] = SolverType(field,value);
  case {'adaptConstr'} % character string
    [validvalue, errmsg] = adaptConstrType(field,value);
  case {'Ktot'} % vector with all real positive integers
    [validvalue, errmsg] = PosIntegerVector(field,value);
  case {'nonnegativity'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'DecompOut'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case{'sirt_method'}
    [validvalue, errmsg] = sirtType(field,value);
  case {'shrink'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'stepsize'}% real non-negative scalar
    [validvalue, errmsg] = stepsizeoption(field,value);
  case {'backtracking'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'backscalar'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'backit'} % real positive integer
    [validvalue, errmsg] = PosInteger(field,value);
  case{'SparsityTrans'}
    [validvalue, errmsg] = SparsityTransType(field,value);
  case{'hybridvariant'}
    [validvalue, errmsg] = hybridvariantType(field,value);
  case{'wname'}
    [validvalue, errmsg] = wnameType(field,value);
  case{'wlevels'}
    [validvalue, errmsg] = PosInteger(field,value);
  case{'warmrestart'} % off, on
    [validvalue, errmsg] = onOffType(field,value);
  case {'weight0'} % numeric array, none
    [validvalue, errmsg] = x0type(field,value);
  case {'svdbasis'} % numeric array, none
    [validvalue, errmsg] = PosIntegerBound(field,value);
  case {'qnorm'} % real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'dimension'} % real non-negative scalar
    [validvalue, errmsg] = dimensionsize(field,value);
  case {'reginskaExp'}
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'plotty'}
    [validvalue, errmsg] = onOffType(field,value);
  case {'RegParamRange'}
    [validvalue, errmsg] = nonNegBounds(field,value);
  case {'RegParRegRange'}
    [validvalue, errmsg] = nonNegBounds(field,value);
  case {'discrbilStopTol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'discrflatTol'}
    [validvalue, errmsg] = nonNegscalar(field,value);
  case {'regbilStopTol'}% real non-negative scalar
    [validvalue, errmsg] = nonNegscalar(field,value);
  otherwise
    %validfield = false;
    validvalue = false;
    errmsg = sprintf('Unrecognized parameter name ''%s''.', field);
end

if validvalue
    return;
else
  error(errmsg)
end

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

function [valid, errmsg] = PosIntegerVector(field,value)
% Any vector with all postive real integers
valid =  (isreal(value) && (all(value > 0)) && all(value == floor(value))) | (ischar(value) && any(strcmp(value,{'none'}))) ;
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be positive real integers.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = PosVector2(field,value)
% Any vector with all postive real integers
valid =  (isreal(value) && (all(value > 0))) && (length(value) == 2) || (ischar(value) && any(strcmp(value,{'none'}))) ;
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be positive real vector of length 2.',field);
else
    if value(1)>value(2)
        warning('For the methods to be meaningful, the Poisson parameter (%s(2)) should be bigger than the Gaussian std deviation (%s(1)).', field, field);
        errmsg = '';
    else
        errmsg = '';
    end
end

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

function [valid, errmsg] = PosInteger(field,value)
% Any positive real integer
valid =  isreal(value) && isscalar(value) && (value > 0) && value == floor(value) ;
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive real integer.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = PosIntegerBound(field,value)
% Any positive real integer
valid =  isreal(value) && isscalar(value) && (value > 0) && (value < 7) && value == floor(value) ;
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive real integer between 1 and 6.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = PosInteger2(field,value)
% Any positive real integer
valid =  (isreal(value) && isscalar(value) && (value > 0) && value == floor(value)) || ...
    (ischar(value) && strcmp(value,{'none'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive real integer, or ''none''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = nonNegInteger2(field,value)
% Any positive real integer
valid =  (isreal(value) && isscalar(value) && (value >= 0) && value == floor(value)) || ...
    (ischar(value) && strcmp(value,{'none'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive real integer, or ''none''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = onOffType(field,value)
% One of these strings: on, off
valid =  ischar(value) && any(strcmp(value,{'on';'off'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''off'' or ''on''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = SparsityTransType(field,value)
valid =  ischar(value) && any(strcmpi(value,{'none';'dwt';'dct';'svd';'tv1D';'tv2D'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''none'' or ''dwt'' or ''dct'' or ''svd'' or ''tv1D'' or ''tv2D''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = x_truetype(field,value)
% Either a numeric array or off
valid =  isnumeric(value) | (ischar(value) && any(strcmp(value,{'none'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a numeric array or ''none''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = x0type(field,value)
% Either a numeric array or none
valid =  isnumeric(value) | (ischar(value) && any(strcmp(value,{'none'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a numeric array or ''none''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = nonNegscalar(field,value)
% Any real non-negative scalar
valid =  isreal(value) && isscalar(value) && (value >= 0);
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a real non-negative scalar.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = realScalar(field,value)
% Any real  scalar
valid =  (isreal(value) && isscalar(value)) || (ischar(value) && strcmpi(value, 'none'));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a real non-negative scalar.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = tikFunType(field,value)
% One of these strings: none, Identity, Laplacian
valid =  (ischar(value) && any(strcmpi(value,{'none';'Identity';'Laplacian1D';'Laplacian2D';'Gradient1D';'Gradient2D';'tv';'tv1D';'tv2D'}))) || ...
         (~ischar(value) && ismatrix(value));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''none'' or ''Identity'' or ''Laplacian1D'' or ''Laplacian2D'' or ''tv'' or a matrix.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = enrichType(field,value)
% One of these strings: none, Identity, Laplacian
valid =  (ischar(value) && (strcmpi(value,'none')||strcmpi(value,'ones')))|| ...
         (~ischar(value) && ismatrix(value));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''none'' or ''ones'' or a matrix of coherent size.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = spTransf(field,value)
% One of these strings: none, Identity, Laplacian
valid =  ischar(value) && any(strcmpi(value,{'none';'dct'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''none'' or ''dct''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = stopruleType(field,value)
% One of these strings: none, Identity, Laplacian
valid =  ischar(value) && any(strcmpi(value,{'none';'NCP';'DP'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''none'' or ''NCP'' or ''DP''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = nonNegScalar2(field,value)
% Either a numeric array or none
valid =  (isreal(value) && isscalar(value) && value >= 0) || (ischar(value) && any(strcmp(value,{'none'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be non-negative scalar or ''none''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = positiveScalar2(field,value)
% Either a numeric array or none
valid =  (isreal(value) && isscalar(value) && value > 0) || (ischar(value) && any(strcmp(value,{'none'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be positive scalar or ''none''.',field);
else
  errmsg = '';
end%--------------------------------------------------------------------------

function [valid, errmsg] = RegPartype(field,value)
% One of these: real nonnegative scalar, GCV, WGCV, optimal
valid =  (isreal(value) && isscalar(value) && (value >= 0)) | (ischar(value) && any(strcmpi(value,{'gcv','wgcv','modgcv','optimal','discrep','discrepit','discrepbil','Lcurve','off','none','reginskait','reginskabil'})));

if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a non-negative scalar or ''GCV'' or ''WGCV'' or ''discrep'' or ''discrepit'' or ''optimal'' or ''none''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = stopGCVtype(field,value)
% One of these: resflat, GCVflat
valid =  (ischar(value) && any(strcmpi(value,{'resflat', 'GCVvalues'})));
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''resflat'' or ''GCVvalues''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = stopCritype(field,value)
% One of these: resflat, GCVflat
valid =  (ischar(value) && any(strcmpi(value,{'none', 'resflat', 'discrep'}))); % 'outer'
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''resflat'' or ''discrep''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = stopOutype(field,value)
% One of these: xstab, Lxstab, regPstab
valid =  (ischar(value) && any(strcmpi(value,{'xstab', 'Lxstab', 'regPstab'})));
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''xstab'' or ''Lxstab'' or ''regPstab''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = WeightType(field,value)
% One of these: real non-negative scalar, adapt
valid =  (isreal(value) && isscalar(value) && (value >= 0) )| (ischar(value) && any(strcmp(value,{'adapt'})));
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a non-negative scalar or ''adapt''.',field);
else
  errmsg = '';
end

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

%function [valid, errmsg] = InSolvetype(field,value)
% % One of these strings: tsvd, tikhonov, none
%valid =  ischar(value) && any(strcmp(value,{'tsvd','tikhonov','none'}));
%if ~valid
% errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''tsvd'', ''tikhonov'' or ''none''.',field);
%else
%  errmsg = '';
%end

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

function [valid, errmsg] = nonNeg2vector(field,value)
% Any real non-negative scalar
valid =  isreal(value) && isvector(value) && sum(value>=0)==length(value) && (length(value)==2);
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a real non-negative vector of length 2.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = nonNegBounds(field,value)
% Any real non-negative scalar
valid =  isreal(value) && isvector(value) && sum(value>=0)==length(value) && (length(value)==2) && (value(1)<value(2));
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a real non-negative vector of length 2, with the first entry smaller than the second entry.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = nonNegVector(field,value)
% Any real non-negative scalar
valid =  isreal(value) && isvector(value) && sum(value>=0)==length(value);
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a real non-negative vector of length 2.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = NoiseLevelType(field,value)
% One of these: real nonnegative scalar, GCV, WGCV, optimal
valid =  (isreal(value) && isscalar(value) && (value >= 0)) |...
         (ischar(value));

if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: a nonnegative scalar noise level should be provided.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = truncation(field,value)
% One of these: real nonnegative scalar, GCV, WGCV, optimal
valid =  (isreal(value) && isscalar(value) && (value > 0) && value == floor(value)) | (ischar(value) && any(strcmpi(value,{'full', 'none'})));
if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive integer or ''none'' or ''full''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = noiseType(field,value)
% One of these strings: none, Identity, Laplacian
valid =  ischar(value) && any(strcmpi(value,{'gauss';'poisson'}));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''gauss'' or ''poisson''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = inSolverType(field,value)
% One of these strings: gmres, lsqr, fgmres
valid =  (ischar(value) && any(strcmpi(value,{'gmres';'fgmres';'lsqr';'cgls';'rrgmres'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS inSolver %s: must be ''gmres'' or ''fgmres'' or ''lsqr'' or ''cgls''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = SolverType(field,value)
% One of these strings: gmres, lsqr, fgmres
valid =  (ischar(value) && any(strcmpi(value,{'fgmres';'flsqr'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS inSolver %s: must be ''fgmres'' or ''flsqr''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = adaptConstrType(field,value)
% One of these strings: tv, nn
valid =  (ischar(value) && any(strcmpi(value,{'tv';'nn';'tvnn';'box';'energy';'project';'spnn';'sp';'none'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS inSolver %s: must be ''tv'' or ''nn'' or ''tvnn'' or ''box'' or ''spnn''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = sirtType(field,value)
% One of these strings: cav, cimmino, drop, landweber, sart
valid =  (ischar(value) && any(strcmpi(value,{'cav';'cimmino';'drop';'landweber';'sart'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''cav'' or ''cimmino'' or ''drop'' or ''landweber'' or ''sart''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = hybridvariantType(field,value)
% One of these strings: tv, nn
valid =  (ischar(value) && any(strcmpi(value,{'I';'R'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS inSolver %s: must be ''I'' or ''R''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = wnameType(field,value)
% One of these strings: cav, cimmino, drop, landweber, sart
valid =  (ischar(value) && any(strcmpi(value,{'db1'})));
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be ''db1''.',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = dimensionsize(field,value)
% Any positive real integer
valid =  (value == 1 || value == 2);
if ~valid
  errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be either 1 or 2 (scalar).',field);
else
  errmsg = '';
end

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

function [valid, errmsg] = stepsizeoption(field,value)
% Any real non-negative scalar
valid =  (isreal(value) && isscalar(value) && (value >= 0)) || (ischar(value) && (strcmp(value, 'none') ));

if ~valid
 errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a real non-negative scalar.',field);
else
  errmsg = '';
end


function y = horzcat( varargin )
y = cat( 2, varargin{:} );

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


function vw = switch2Vol(vw)
%
% Switches Volume view to volume mode:
% - changes vw.subdir to 'Volume'
% - sets vw.ui.grayVolButtons=2
% - computes/loads vw.coords
% - empties co, amp, ph, map
%
% djh, 7/98
% ress, 6/03: added UI controls for 3D buttons

if isempty(vw)
  myErrorDlg('Volume window must be open to switch it to volume mode.');
end
if ~strcmp(vw.viewType,'Volume') && ~strcmp(vw.viewType,'Gray')
  myErrorDlg('Only volume window can be switched to volume mode.');
end

% Set viewType
vw = viewSet(vw, 'viewType', 'Volume');
vw = viewSet(vw, 'subdir', 'Volume');

% Compute/load VOLUME.coords
vw = getVolCoords(vw);

% Empty data matrices
vw = viewSet(vw, 'co',  []);
vw = viewSet(vw, 'amp',  []);
vw = viewSet(vw, 'ph',  []);
vw = viewSet(vw, 'map',  []);

% Only do this for VOLUME, not for hiddenVolume
if strfind(viewGet(vw, 'name') ,'VOLUME')
  % Set vw.ui.grayVolButtons
  selectButton(vw.ui.grayVolButtons,2);
  % Hide the 3D buttons:
%   HideButtons(vw.ui.gray3dButtons);
%   vw = Disable3D(vw);
  % Load user preferences
  vw = loadPrefs(vw);
end


classdef ProjectorsTestsSuite < handle

    methods

        function obj = ProjectorsTestsSuite()
            warning('off', 'MATLAB:structOnObject')
            results = runtests("ProjectorsTests","ProcedureName","testProjectorsInFEM", 'Debug', true);
            table(results)
            warning('on', 'MATLAB:structOnObject')
        end

    end
end


function y = In
y = cvxin;

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


classdef YawAngleTermCondOptimVar < AbstractOptimizationVariable
    %YawAngleTermCondOptimVar Summary of this class goes here
    %   Detailed explanation goes here

    properties
        varObj(1,1) YawTermCondition = YawTermCondition(0);

        lb(1,1) double = 0;
        ub(1,1) double = 0;

        useTf(1,1) = false;
    end

    methods
        function obj = YawAngleTermCondOptimVar(varObj)
            obj.varObj = varObj;
            obj.varObj.optVar = obj;

            obj.id = rand();
        end

        function x = getXsForVariable(obj)
            x = [];

            if(obj.useTf)
                x = obj.varObj.targetYawAngle;
            end
        end

        function [lb, ub] = getBndsForVariable(obj)
            lb = obj.lb(obj.useTf);
            ub = obj.ub(obj.useTf);
        end

        function [lb, ub] = getAllBndsForVariable(obj)
            lb = obj.lb;
            ub = obj.ub;
        end

        function setBndsForVariable(obj, lb, ub)
            obj.lb = lb;
            obj.ub = ub;
        end

        function useTf = getUseTfForVariable(obj)
            useTf = obj.useTf;
        end

        function setUseTfForVariable(obj, useTf)
            obj.useTf = useTf;
        end

        function updateObjWithVarValue(obj, x)
            obj.varObj.targetYawAngle = x;
        end

        function nameStrs = getStrNamesOfVars(obj, evtNum, varLocType)
            nameStrs = {sprintf('Event %i Yaw Angle Termination Condition', evtNum)};
        end

        function varsStoredInRad = getVarsStoredInRad(obj)
            varsStoredInRad = true;
        end
    end
end


function res = verification( des, varargin)
%VERIFICATION Run the patch verification task
%  RES = VERIFICATION(DESCRIPTOR) Compute the results for descriptor
%  DESCRIPTOR. Descriptor can either be an object of `desc.memdesc` or a
%  string, in which case a descriptor from
%
%     `<HBROOT>/data/descriptors/DESCRIPTOR`
%
%  are loaded.
%  Stores the results in csv files in:
%
%      `<HBROOT>/matlab/results/default/DESCRIPTOR/verification.csv`
%
%  If the scores file already exists, skips the computation. Use
%  `'override', true` to change this behaviour.
%
%  Additionally accepts the following 'OptionName', OptionValue arguments:
%
%  'scoresroot' :: '<HBROOT>/matlab/results/default/'
%   Change for a different target path for scores.
%
%  'taskpath' :: '<HBROOT>/tasks'
%   Location of te tasks files.
%
%  'geom_noise' :: {'easy', 'hard', 'tough'}
%  Limit the geometry noise used for positives.
%
%  'negs' :: {'inter', 'intra'}
%  Used negative sets.
%
%  'split' :: {'a', 'b', 'c', 'illum', 'view', 'full'}
%  Limit the splits on which the scores are computed.
%
%  'override' :: false
%   If true, do override existing score file.

% Copyright (C) 2017 Karel Lenc
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).
if ischar(des), [des, varargin] = desc.memdesc(des, varargin{:}); end;
opts.scoresroot = fullfile(hb_path, 'matlab', 'scores', 'default');
[opts, varargin] = vl_argparse(opts, varargin);
opts.taskspath = fullfile(hb_path, 'tasks');
opts.scorespath = fullfile(opts.scoresroot, des.name, 'verification.csv');
opts.split = {'a', 'b', 'c', 'illum', 'view', 'full'};
opts.negs = {'inter', 'intra'};
opts.geom_noise = {'easy', 'hard', 'tough'};
opts.methods = struct('name', {'balanced', 'imbalanced'}, ...
  'args', {{}, {'posneg_ratio', 0.2}});
opts.override = false;
opts.verbose = false;
[opts, ~] = vl_argparse(opts, varargin);

if opts.verbose, display(opts); end;
if ~iscell(opts.split), opts.split = {opts.split}; end;
if ~iscell(opts.negs), opts.negs = {opts.negs}; end;
if ~iscell(opts.geom_noise), opts.geom_noise  = {opts.geom_noise}; end;
vl_xmkdir(fileparts(opts.scorespath));
if ~opts.override && exist(opts.scorespath, 'file')
  res = readtable(opts.scorespath);
  fprintf('Results loaded from %s.\n', opts.scorespath);
  return;
end;

pospairs = @(split) fullfile(opts.taskspath, ...
  sprintf('verif_pos_split-%s.csv', split));
negpairs = @(split, neg) fullfile(opts.taskspath, ...
  sprintf('verif_neg_%s_split-%s.csv', neg, split));

numtasks = numel(opts.split)*numel(opts.negs)*numel(opts.geom_noise);
status = utls.textprogressbar(numtasks, 'updatestep', 1, ...
  'startmsg', sprintf('Evaluating "verification" for %s ', des.name));
stepi = 1;
res = {};
descs_n = des;
for gni = 1:numel(opts.geom_noise)
  gnoise = opts.geom_noise{gni};
  for si = 1:numel(opts.split)
    split = opts.split{si};
    pos_dists = bench.verification.compute(pospairs(split), descs_n, gnoise);
    for ni = 1:numel(opts.negs)
      neg = opts.negs{ni};
      neg_dists = bench.verification.compute(negpairs(split, neg), descs_n, gnoise);
      for mi = 1:numel(opts.methods)
        method = opts.methods(mi);
        res_s = bench.verification.eval(pos_dists, neg_dists, method.args{:});
        res{end+1} = struct(...
          'descriptor', descs_n.name, 'split', split, 'negs', neg, ...
          'geom_noise', gnoise, 'method', method.name, ...
          'pr_auc', res_s.pr_auc, 'pr_ap', res_s.pr_ap, 'roc_auc', res_s.roc_auc);
      end
      status(stepi); stepi = stepi+1;
    end
  end
end
res = struct2table(cell2mat(res), 'AsArray', true);
writetable(res, opts.scorespath);
fprintf('\n');