function [varargout] = ft_plot_patch(hdat, vdat, varargin)

% FT_PLOT_PATCH plot a colored shape, similar to the MATLAB patch() function. It is
% similar in usage as ft_plot_vector, and they can be combined, for example,
% to plot an area equivalent to a SEM or STD-DEV around a line.
%
% Use as
%   ft_plot_patch(X, Y, ...)
% where X and Y are similar as the input to the MATLAB patch() function.
%
% Optional arguments should come in key-value pairs and can include
%   'axis'            = draw the local axis,  can be 'yes', 'no', 'xy', 'x' or 'y'
%   'box'             = draw a box around the local axes, can be 'yes' or 'no'
%   'tag'             = string, the name assigned to the object. All tags with the same name can be deleted in a figure, without deleting other parts of the figure.
%   'facecolor'       = see MATLAB standard patch properties
%   'facealpha'       = see MATLAB standard patch properties (note, approx. transparency can be achieved using 'facecolor')
%   'edgecolor'       = see MATLAB standard patch properties (default is 'none') (equivalent to 'linecolor' in PLOT)
%   'linestyle'       = see MATLAB standard patch properties
%   'linewidth'       = see MATLAB standard patch properties
%
% The color of the patchand the edges (i.e. border lines) can be specified in a variety of ways
%   - as a string with one character per line that you want to plot. Supported colors are the same as in PATCH, i.e. 'bgrcmykw'.
%   - as an 'RGB triplet', a 1x3 vector with values between 0 and 1
%   - as 'none' if you do not want the face of the patch to be filled (useful when you want to plot an empty box).
%
% It is possible to plot the object in a local pseudo-axis (c.f. subplot), which is specfied as follows
%   'hpos'            = horizontal position of the center of the local axes
%   'vpos'            = vertical position of the center of the local axes
%   'width'           = width of the local axes
%   'height'          = height of the local axes
%   'hlim'            = horizontal scaling limits within the local axes
%   'vlim'            = vertical scaling limits within the local axes
%
% Example
%   hdat = [1:10 10:-1:1];
%   vdat = rand(1,10);
%   vdat = [vdat vdat(end:-1:1)+1];
%   ft_plot_patch(hdat, vdat)
%
% See also FT_PLOT_VECTOR, PATCH, PLOT

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

% get the optional input arguments
hpos            = ft_getopt(varargin, 'hpos');
vpos            = ft_getopt(varargin, 'vpos');
width           = ft_getopt(varargin, 'width');
height          = ft_getopt(varargin, 'height');
hlim            = ft_getopt(varargin, 'hlim', 'maxmin');
vlim            = ft_getopt(varargin, 'vlim', 'maxmin');
axis            = ft_getopt(varargin, 'axis', false);
box             = ft_getopt(varargin, 'box', false);
tag             = ft_getopt(varargin, 'tag', '');
parent          = ft_getopt(varargin, 'parent', []);
facecolor       = ft_getopt(varargin, 'facecolor', 'b');
facealpha       = ft_getopt(varargin, 'facealpha', 1);
edgecolor       = ft_getopt(varargin, 'edgecolor', 'none');
linestyle       = ft_getopt(varargin, 'linestyle', 'none');
linewidth       = ft_getopt(varargin, 'linewidth', .5);

% convert the yes/no strings into boolean values
box = istrue(box);

% color management
if ischar(facecolor) && exist([facecolor '.m'], 'file')
  facecolor = feval(facecolor);
end
if ischar(edgecolor) && exist([edgecolor '.m'], 'file')
  edgecolor = feval(edgecolor);
end

% this should be a string, because valid options include yes, no, xy, x, y
if isequal(axis, true)
  axis = 'yes';
elseif isequal(axis, false)
  axis = 'no';
end

% everything is added to the current figure
holdflag = ishold;
if ~holdflag
  hold on
end

if ischar(hlim)
  switch hlim
    case 'maxmin'
      hlim = [min(hdat) max(hdat)];
    case 'maxabs'
      hlim = max(abs(hdat));
      hlim = [-hlim hlim];
    otherwise
      ft_error('unsupported option for hlim')
  end % switch
end % if ischar

if ischar(vlim)
  switch vlim
    case 'maxmin'
      vlim = [min(vdat(:)) max(vdat(:))];
    case 'maxabs'
      vlim = max(abs(vdat(:)));
      vlim = [-vlim vlim];
    otherwise
      ft_error('unsupported option for vlim')
  end % switch
end % if ischar

if vlim(1)==vlim(2)
  % vertical scaling cannot be determined, behave consistent to the plot() function
  vlim = [-1 1];
end

% these must be floating point values and not integers, otherwise the scaling fails
hdat = double(hdat);
vdat = double(vdat);
hlim = double(hlim);
vlim = double(vlim);

if isempty(hpos) && ~isempty(hlim)
  hpos = (hlim(1)+hlim(2))/2;
end
if isempty(vpos) && ~isempty(vlim)
  vpos = (vlim(1)+vlim(2))/2;
end

if isempty(width) && ~isempty(hlim)
  width = hlim(2)-hlim(1);
end

if isempty(height) && ~isempty(vlim)
  height = vlim(2)-vlim(1);
end

% first shift the horizontal axis to zero
if any(hlim) ~= 0
  hdat = hdat - (hlim(1)+hlim(2))/2;
  % then scale to length 1
  if hlim(2)-hlim(1)~=0
    hdat = hdat ./ (hlim(2)-hlim(1));
  else
    hdat = hdat /hlim(1);
  end
  % then scale to the new width
  hdat = hdat .* width;
end
% then shift to the new horizontal position
hdat = hdat + hpos;

if any(vlim) ~= 0
  % first shift the vertical axis to zero
  vdat = vdat - (vlim(1)+vlim(2))/2;
  % then scale to length 1
  vdat = vdat / (vlim(2)-vlim(1));
  % then scale to the new width
  vdat = vdat .* height;
end
% then shift to the new vertical position
vdat = vdat + vpos;

% plot the patch
h = patch(hdat, vdat, facecolor, 'facealpha', facealpha, 'edgecolor', edgecolor, 'linestyle', linestyle, 'linewidth', linewidth);

if box
  % this plots a box around the original hpos/vpos with appropriate width/height
  x1 = hpos - width/2;
  x2 = hpos + width/2;
  y1 = vpos - height/2;
  y2 = vpos + height/2;

  X = [x1 x2 x2 x1 x1];
  Y = [y1 y1 y2 y2 y1];
  h = line(X, Y);
  set(h, 'color', 'k');

  % this plots a box around the original hpos/vpos with appropriate width/height
  % boxposition = zeros(1,4);
  % boxposition(1) = hpos - width/2;
  % boxposition(2) = hpos + width/2;
  % boxposition(3) = vpos - height/2;
  % boxposition(4) = vpos + height/2;
  % ft_plot_box(boxposition, 'facecolor', 'none', 'edgecolor', 'k');

  % this plots a box around the complete data
  % boxposition = zeros(1,4);
  % boxposition(1) = hlim(1);
  % boxposition(2) = hlim(2);
  % boxposition(3) = vlim(1);
  % boxposition(4) = vlim(2);
  % ft_plot_box(boxposition, 'hpos', hpos, 'vpos', vpos, 'width', width, 'height', height, 'hlim', hlim, 'vlim', vlim);
end

if ~isempty(axis) && ~strcmp(axis, 'no')
  switch axis
    case {'yes' 'xy'}
      xaxis = true;
      yaxis = true;
    case {'x'}
      xaxis = true;
      yaxis = false;
    case {'y'}
      xaxis = false;
      yaxis = true;
    otherwise
      ft_error('invalid specification of the "axis" option')
  end

  if xaxis
    % x-axis should touch 0,0
    xrange = hlim;
    if sign(xrange(1))==sign(xrange(2))
      [dum, minind] = min(abs(hlim));
      xrange(minind) = 0;
    end
    ft_plot_line(xrange, [0 0], 'hpos', hpos, 'vpos', vpos, 'hlim', hlim, 'vlim', vlim, 'width', width, 'height', height);
  end
  if yaxis
    % y-axis should touch 0,0
    yrange = vlim;
    if sign(yrange(1))==sign(yrange(2))
      [dum, minind] = min(abs(vlim));
      yrange(minind) = 0;
    end
    ft_plot_line([0 0], yrange, 'hpos', hpos, 'vpos', vpos, 'hlim', hlim, 'vlim', vlim, 'width', width, 'height', height);
  end
end

set(h, 'tag', tag);

if ~isempty(parent)
  set(h, 'Parent', parent);
end

% the (optional) output is the handle
if nargout == 1
  varargout{1} = h;
end

if ~holdflag
  hold off
end


function [featureVector,selectedheaderskeys] = featurize_bigram(inputcellarray, nminFeatures, removeStopWords, doStem)
%
%
% featureVector = featurize_bigram(inputcellarray, nminFeatures, removeStopWords, doStem)
%
% Takes an input cell array in which each cell is a review or text and
% outputs a feature vector with a number of features (nminFeatures is the
% number of times that a feature should be presented in the corpus to be
% included in the feature vector.)
%
% The approach is basically a bag-of-word but we also add bigrams to the
% feature vector too
%
% removeStopWords is a flag, if it is true it will remove the stop words.
%
% Inputs:
%       inputcellarray: a cell array with texts as the content of each cell
%       nFeatures: the number of features that we like to see in the vetor
%       removeStopWords: if ==1 it will remove all the stop words
%       doStem: a flag if true porter stemmer will be used
% Outputs:
%       featureVector

% Test case:

% inputcellarray = {' MATLAB desktop keyboard shortcuts, such as Ctrl+S,  are now customizable.';' To customize keyboard shortcuts, use Preferences. From there, you can also  restore previous default settings by following the steps outlined in Help.'}
% nminFeatures = 1;
% removeStopWords = 0;
% doStem =1;
% featureVector = featurize_bigram(inputcellarray, nminFeatures, removeStopWords, doStem)

%
fid = fopen('english.stop');

stopwords = textscan(fid, '%s');
stopwords = stopwords{1,1};
fclose(fid);

% params
% n:minimum appearances of a stem
n=nminFeatures;

g = containers.Map();
bigs = containers.Map();
lastword = '';
for i = 1:size(inputcellarray,1)
    fprintf('%d/%d\n', i, size(inputcellarray,1));
    comment = inputcellarray{i};
    comment = SanitizeComment(comment);
    comment = lower(comment);
    r=regexp(comment,' ','split');
    for j =1:size(r,2)

        if doStem
            word = porterStemmer(cell2mat(r(j)));
        else
            word = (cell2mat(r(j)));
        end

        if removeStopWords % if the function caller wants to remove stopwords
            tfflag = ~isStopWord(word, stopwords);
        else
            tfflag = 1;
        end

        if isKey(g, word) && tfflag
            g(word) = g(word)+1;
        elseif tfflag & (~strcmp(word,' ')) & (~strcmp(word,''))
            g(word) = 1;
        end
        if  (~strcmp(lastword,'')) & (~strcmp(word,' ')) & (~strcmp(lastword,' ')) & (~strcmp(word,''))
            bigram = char(strcat(lastword, {' '}, word));
            % for debugging :) fprintf('DDD%sDDDDDD%sDDD%sDDD\n',bigram,lastword,word);
            if isKey(g, bigram)
                g(bigram) = g(bigram)+1;
            else
                bigs(bigram) =1;
                g(bigram) = 1;

            end
        end
        lastword = word;

    end

end

selectedheaders =containers.Map();
gkeys = keys(g);

for i=1:size(gkeys,2)
    if g(gkeys{i})>=n

        selectedheaders(gkeys{i})=1;

    end

end
headers = keys(selectedheaders);

outputMatrix = zeros(size(inputcellarray,1),length(headers));
for i = 1:size(inputcellarray,1)
    fprintf('%d/%d ', i, size(inputcellarray,1));
    comment = inputcellarray{i};
    comment = SanitizeComment(comment);
    comment = lower(comment);

    r=regexp(comment,' ','split');
    comment = [];
    for j =1:size(r,2)
        if doStem
            word = porterStemmer(cell2mat(r(j)));
        else
            word = (cell2mat(r(j)));
        end

        comment = [comment,' ',word];
    end
    outputMatrix(i,:) = term_count(comment, headers);

    if mod(i,300)==0
        a = sprintf('%d', i);
        disp(a)
    end

end

featureVector = outputMatrix;
selectedheaderskeys = keys(selectedheaders);
%csvwrite('forWeka_featuresonly.csv', outputMatrix);
disp('');

end


function progressbar(n,N,w)
%PROGRESSBAR Display a progress bar.
%
%    progressbar(n,N,w);
%
% displays the progress of n out of N.
% n should start at 1.
% w is the width of the bar (default w=20).
%
%   Copyright (c) Gabriel Peyré 2006

if nargin<3
    w = 20;
end

% progress char
cprog = '.';
cprog1 = '*';
% begining char
cbeg = '[';
% ending char
cend = ']';

p = min( floor(n/N*(w+1)), w);

global pprev;
if isempty(pprev)
    pprev = -1;
end

if not(p==pprev)
    ps = repmat(cprog, [1 w]);
    ps(1:p) = cprog1;
    ps = [cbeg ps cend];
    if n>1
        % clear previous string
        fprintf( repmat('\b', [1 length(ps)]) );
    end
    fprintf(ps);
end
pprev = p;
if n==N
    fprintf('\n');
end


function dt = samplePeriod

% SAMPLEPERIOD  Sample period.
%   SAMPLEPERIOD returns the time elapsed sinc last time called.
%
%   See also TIC, TOC.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

dt = toc;
tic;

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB 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.
%
%   SLAMTB is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function ppma_io_test02 ( )

%*****************************************************************************80
%
%% TEST02 tests PPMA_READ.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 May 2011
%
%  Author:
%
%    John Burkardt
%
  file_name = 'test02.ascii.ppm';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST02\n' );
  fprintf ( 1, '  PPMA_READ reads an ASCII PPMA file.\n' );

  ppma_write_test ( file_name );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PPMA_WRITE_TEST created data,\n' );
  fprintf ( 1, '  and wrote it to the file "%s".\n', file_name );

  [ r, g, b ] = ppma_read ( file_name );
  [ nrow, ncol ] = size ( r );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PPMA_READ has read the file "%s"\n', file_name );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of rows of data =    %d\n', nrow );
  fprintf ( 1, '  Number of columns of data = %d\n', ncol );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Sample values:\n' );
  fprintf ( 1, '\n' );

  for k = 1 : 10
    i = floor ( ( ( 10 - k ) * 1 + ( k - 1 ) * nrow ) / ( 10 - 1 ) );
    j = floor ( ( ( 10 - k ) * 1 + ( k - 1 ) * ncol ) / ( 10 - 1 ) );
    fprintf ( 1, '  %4d  %4d  %6d  %6d  %6d\n', i, j, r(i,j), g(i,j), b(i,j) );
  end

  return
end


function hb_structure_write ( output_unit, ncol, mxtype, nnzero, neltvl, ...
  ptrfmt, indfmt, colptr, rowind )

%*****************************************************************************80
%
%% HB_STRUCTURE_WRITE writes the structure of an HB file.
%
%  Discussion:
%
%    The user should already have opened the file, and written
%    the header records.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 April 2004
%
%  Author:
%
%    John Burkardt
%    Xiaoye Li, UC Berkeley.
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, file pointer OUTPUT_UNIT, the unit to which data is written.
%
%    Input, integer NCOL, the number of columns or elements.
%
%    Input, string MXTYPE, the matrix type, up to 3 characters
%    First character is R for Real, C for complex, P for pattern only.
%    Second character is S for symmetric, U for unsymmetric, H for
%      Hermitian, Z for skew symmetric, R for rectangular.
%    Third character is A for assembled and E for unassembled
%      finite element matrices.
%
%    Input, integer NNZERO.  In the case of assembled sparse matrices,
%    this is the number of nonzeroes.  In the case of unassembled finite
%    element matrices, in which the right hand side vectors are also
%    stored as unassembled finite element vectors, this is the total
%    number of entries in a single unassembled right hand side vector.
%
%    Input, integer NELTVL, the number of finite element matrix entries,
%    set to 0 in the case of assembled matrices.
%
%    Input, string PTRFMT, the format for writing pointers,
%    up to 16 characters.
%
%    Input, string INDFMT, the format for writing row indices,
%    up to 16 characters.
%
%    Input, integer COLPTR(NCOL+1), COLPTR(I) points to the location of
%    the first entry of column I in the sparse matrix structure.
%
%    Input, integer ROWIND(NNZERO) or ROWIND(NELTVL), the row index of
%    each item.
%

%
%  From the FORTRAN format string PTRFMT, determine the number of
%  integers per line, and their width.
%
  line = ptrfmt(2:length(ptrfmt));
  [ ptr_nperline, count, errmsg, nextindex ] = sscanf ( line, '%d' );
  line = line(nextindex+1:length(line));
  [ ptr_len, count, errmsg, nextindex ] = sscanf ( line, '%d' );
%
%  Column pointers.
%
%  ptrfmt has the form '(nIw)'
%  where n is ptr_nperline
%  and w is ptr_len.
%
  s = int2str ( ptr_len );
  ptr_format = [ '%' s 'd' ];

  for j = 1 : ncol + 1
    fprintf ( output_unit, ptr_format, colptr(j) );
    if ( mod ( j, ptr_nperline ) == 0 )
      fprintf ( output_unit, '\n' );
    end
  end

  if ( mod ( ncol + 1, ptr_nperline ) ~= 0 )
    fprintf ( output_unit, '\n' );
  end
%
%  From the FORTRAN format string INDFMT, determine the number of
%  integers per line, and their width.
%
  line = indfmt(2:length(indfmt));
  [ ind_nperline, count, errmsg, nextindex ] = sscanf ( line, '%d' );
  line = line(nextindex+1:length(line));
  [ ind_len, count, errmsg, nextindex ] = sscanf ( line, '%d' );
%
%  Row indices.
%
  s = int2str ( ind_len );
  ind_format = [ '%' s 'd' ];

  if ( mxtype(3) == 'A' )

    for j = 1 : nnzero
      fprintf ( output_unit, ind_format, rowind(j) );
      if ( mod ( j, ind_nperline ) == 0 )
        fprintf ( output_unit, '\n' );
      end
    end

  elseif ( mxtype(3) == 'E' )

    number = colptr(ncol) - colptr(1);

    for j = 1 : number
      fprintf ( output_unit, ind_format, rowind(j) );
      if ( mod ( j, ind_nperline ) == 0 )
        fprintf ( output_unit, '\n' );
      end
    end

  end

  return
end


function Model = hlp_sift_emptymodel(varargin)
% create a new (empty) Model datastructure with default fields initialized
% varargin is an optional set of <name,value> pairs indicating fields and
% associated values to store into the set
%
% MODEL
%   .morder             Autoregressive model order
%   .AR                 Autoregressive coefficient matrices [A1 A2 ... Ap]
%                       for model order p. This is of dimension [num_vars x num_vars*p]
%   .PE                 Prediction errors (noise covariance matrices) [E0 E1 .. Ep]
%                       This is of dimension [num_vars x num_vars*(p +1)]
%   .RC                 Reflection (parcorr) coefficients [num_vars x num_vars*(p +1)]
%   .mu                 Process mean [num_vars x 1]
%   .th                 Statistics structure (if using ARFIT)
%   .winStartTimes      Timestamps of window start points (sec)
%   .winstep            Sliding window step size (sec)
%   .winlen             Sliding window length (sec)
%   .algorithm          Algorithm used (see hlp_getMVARalgorithms)
%   .modelclass         Class of algorithm ('mvar')
%   .timeelapsed        CPU time required for each time window (sec)
%   .normalize          Data normalizion method used
%   .modelapproach      Approach used ('Segmentation VAR', 'SSM',...)
%   .taperFcn           Taper function used
%
% See Also: hlp_sift_emptyconn(), hlp_sift_emptyset()

if nargin > 1 && mod(length(varargin),2)
    error('SIFT:hlp_sift_emptymodel', ...
        ['Additional arguments must be a list of <name,value> pairs. ' ...
         'At least one name is missing its corresponding value.']);
end

Model.AR = {};
Model.PE = {};
Model.RC = {};
Model.mu = {};
Model.th = {};
Model.winStartTimes = []; %EEG.CAT.times(g.winStartIdx)/1000;
Model.morder        = [];
Model.winstep       = [];
Model.winlen        = [];
Model.algorithm     = '';
Model.modelclass    = '';
Model.timeelapsed   = [];
Model.normalize     = [];
Model.modelapproach = '';
Model.taperFcn      = '';

% append additional arguments
if nargin > 1
    Model = hlp_varargin2struct(varargin,Model);
end


function pf = rdivide(arg1,arg2)
% implements pf1 ./ b and a ./ pf2
%
% overload the .* operator, i.e. one can now write x .* pf in order to
% scale the @PoleFigure pf by the factor x
%
% See also
% PoleFigure/PoleFigure PoleFigure/plus PoleFigure/minus

if isa(arg2,'double')
  arg2 = 1./arg2;
else
  for i = 1:arg2.numPF, arg2.allI{i} = 1./arg2.allI{i};end
end

pf = arg1 .* arg2;


function msm_to_mm ( output_filename, a, format, type, symmetry )

%*****************************************************************************80
%
%% MSM_TO_MM writes a MATLAB Sparse Matrix to a Matrix Market file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the name of the file to which the information
%    should be written.
%
%    Input, sparse matrix A, the NROW by NCOL matrix, stored in MATLAB sparse
%    matrix format, which is to be written to the file.
%
%    Input, string FORMAT, is 'COORDINATE' for a sparse matrix, or 'ARRAY'
%    for a dense matrix.
%
%    Input, string TYPE, is 'REAL', 'INTEGER', 'COMPLEX', or 'PATTERN'.
%
%    Input, string SYMMETRY is 'GENERAL', 'SYMMETRIC', 'SKEW-SYMMETRIC'
%    or 'HERMITIAN'.
%
  if ( s_eqi ( format, 'coordinate' ) )
    msm_to_mm_coordinate ( output_filename, a, type, symmetry );
  elseif ( s_eqi ( format, 'array' ) )
    msm_to_mm_array ( output_filename, a, type, symmetry );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'MSM_TO_MM - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized choice for FORMAT = "%s".\n', format );
    error ( 'MSM_TO_MM - Fatal error!' );
  end

  return
end


classdef TonemapDurand < handle
    %TONEMAPDURAND  Tonemapping algorithm used to map HDR image to 8-bit range
    %
    % This algorithm decomposes image into two layers: base layer and detail
    % layer using bilateral filter and compresses contrast of the base layer
    % thus preserving all the details.
    %
    % This implementation uses regular bilateral filter from OpenCV.
    %
    % Saturation enhancement is possible as in cv.TonemapDrago.
    %
    % For more information see [DD02].
    %
    % ## References
    % [DD02]:
    % > Fredo Durand and Julie Dorsey. "Fast bilateral filtering for the
    % > display of high-dynamic-range images". In ACM Transactions on Graphics
    % > (TOG), volume 21, pages 257-266. ACM, 2002.
    %
    % See also: cv.Tonemap, cv.TonemapDrago, cv.TonemapReinhard,
    %  cv.TonemapMantiuk, tonemap
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    properties (Dependent)
        % positive value for gamma correction.
        %
        % Gamma value of 1.0 implies no correction, gamma equal to 2.2 is
        % suitable for most displays. Generally gamma > 1 brightens the image
        % and gamma < 1 darkens it.
        Gamma
        % resulting contrast on logarithmic scale
        %
        % i.e. `log(max/min)`, where `max` and `min` are maximum and minimum
        % luminance values of the resulting image.
        Contrast
        % positive saturation enhancement value.
        %
        % 1.0 preserves saturation, values greater than 1 increase saturation
        % and values less than 1 decrease it.
        Saturation
        % bilateral filter sigma in color space.
        SigmaSpace
        % bilateral filter sigma in coordinate space.
        SigmaColor
    end

    %% TonemapDurand
    methods
        function this = TonemapDurand(varargin)
            %TONEMAPDURAND  Creates TonemapDurand object
            %
            %     obj = cv.TonemapDurand()
            %     obj = cv.TonemapDurand('OptionName',optionValue, ...)
            %
            % ## Options
            % * __Gamma__ default 1.0
            % * __Contrast__ default 4.0
            % * __Saturation__ default 1.0
            % * __SigmaSpace__ default 2.0
            % * __SigmaColor__ default 2.0
            %
            % See also: cv.TonemapDurand.process
            %
            this.id = TonemapDurand_(0, 'new', varargin{:});
        end

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

    %% Tonemap
    methods
        function dst = process(this, src)
            %PROCESS  Tonemaps image
            %
            %     dst = obj.process(src)
            %
            % ## Input
            % * __src__ source RGB image, 32-bit `single` 3-channel array.
            %
            % ## Output
            % * __dst__ destination image of same size as `src`, 32-bit
            %   `single` 3-channel array with values in [0,1] range.
            %
            % See also: cv.TonemapDurand.TonemapDurand
            %
            dst = TonemapDurand_(this.id, 'process', src);
        end
    end

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

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

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

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

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

    %% Getters/Setters
    methods
        function value = get.Gamma(this)
            value = TonemapDurand_(this.id, 'get', 'Gamma');
        end
        function set.Gamma(this, value)
            TonemapDurand_(this.id, 'set', 'Gamma', value);
        end

        function value = get.Contrast(this)
            value = TonemapDurand_(this.id, 'get', 'Contrast');
        end
        function set.Contrast(this, value)
            TonemapDurand_(this.id, 'set', 'Contrast', value);
        end

        function value = get.Saturation(this)
            value = TonemapDurand_(this.id, 'get', 'Saturation');
        end
        function set.Saturation(this, value)
            TonemapDurand_(this.id, 'set', 'Saturation', value);
        end

        function value = get.SigmaSpace(this)
            value = TonemapDurand_(this.id, 'get', 'SigmaSpace');
        end
        function set.SigmaSpace(this, value)
            TonemapDurand_(this.id, 'set', 'SigmaSpace', value);
        end

        function value = get.SigmaColor(this)
            value = TonemapDurand_(this.id, 'get', 'SigmaColor');
        end
        function set.SigmaColor(this, value)
            TonemapDurand_(this.id, 'set', 'SigmaColor', value);
        end
    end

end


function saveinr(vol,fname)
%
% saveinr(vol,fname)
%
% save a surface mesh to INR Format
%
% author: Qianqian Fang, <q.fang at neu.edu>
% date: 2009/01/04
%
% input:
%      vol: input, a binary volume
%      fname: output file name
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

fid=fopen(fname,'wb');
if(fid==-1)
    error('You do not have permission to save mesh files.');
end
dtype=class(vol);
if(islogical(vol) || strcmp(dtype,'uint8'))
   btype='unsigned fixed';
   dtype='uint8';
   bitlen=8;
elseif(strcmp(dtype,'uint16'))
   btype='unsigned fixed';
   dtype='uint16';
   bitlen=16;
elseif(strcmp(dtype,'single'))
   btype='float';
   dtype='float';
   bitlen=32;
elseif(strcmp(dtype,'double'))
   btype='float';
   dtype='double';
   bitlen=64;
else
   error('volume format not supported');
end
header=sprintf(['#INRIMAGE-4#{\nXDIM=%d\nYDIM=%d\nZDIM=%d\nVDIM=1\nTYPE=%s\n' ...
  'PIXSIZE=%d bits\nCPU=decm\nVX=1\nVY=1\nVZ=1\n'],size(vol),btype,bitlen);
header=[header char(10*ones(1,256-4-length(header))) '##}' char(10)];
fwrite(fid,header,'char');
fwrite(fid,vol,dtype);
fclose(fid);


function varargout = figureResized( screenratio, varargin )
% Creates a figures that takes up certain area of screen.
%
% Almost same as figure, except get to specify what fraction of available
% screen space figure should take up.  Figure appears in center of screen.
%
% USAGE
%  varargout = figureResized( screenratio, varargin )
%
% INPUTS
%  screenratio - controls fraction of screen image takes out (<=.8)
%  varargin    - parameters to figure
%
% OUTPUTS
%  varargout   - out from figure
%
% EXAMPLE
%  figureResized( .75 )
%
% See also FIGURE
%
% Piotr's Image&Video Toolbox      Version 2.0
% Copyright 2012 Piotr Dollar.  [pdollar-at-caltech.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the Simplified BSD License [see external/bsd.txt]

if( nargin<1 ); screenratio=.3; end
if( screenratio>1 ); error('screenratio must be <= 1'); end

% call figure
h = figure( varargin{:} );
if( nargout ); varargout = {h}; end;

% get dimensions of screen and what want figure to be
units = get(0,'Units');
ss = get(0,'ScreenSize');
st = (1 - screenratio)/2;
pos = [st*ss(3), st*ss(4), screenratio*ss(3), screenratio*ss(4)];

% set dimensions of figure
set( h, 'Units', units );
set( h, 'Position', pos );


function info = optiSolverInfo(solver,probtype,nlprob,opts)
%OPTISOLVERINFO  Return Configuration Information about a particular solver
%
%   info = optiSolverInfo(solver,probtype)

%Default input args and checks
if(nargin < 4), opts = []; end
if(nargin < 3), nlprob = []; end
if(nargin < 2 || isempty(probtype)), probtype = ''; end
if(nargin < 1 || ~ischar(solver)), error('You must supply the name of the solver to this function'); end

%Create default information structure
info.der1 = 0;
info.der2 = 0;
info.global = 0;
info.sparse = 0;
info.multialg = 0;
info.parallel = 0;
info.whitebox = 0;
info.con = struct('con',0,'bnd',0,'lineq',0,'leq',0,'qineq',0,'qeq',0,'sdp',0,'nlineq',0,...
                  'nleq',0,'int',0);
info.opt = struct('miter',0,'meval',0,'mnode',0,'mtime',0,'tolr',0,...
                  'tola',0,'tolint',0,'disp',0,'opts',0,'ctrlc',0,...
                  'iterf',0);
info.unq = struct('x0',0,'qpform',0,'hform',0,'jstr',0,'hstr',0);

%Constants
YES = 1;
SOME = -1;

%Fill in information based on selected solver
switch(lower(solver))
    case 'baron'
        info.global = YES;
        info.sparse = YES;
        info.whitebox = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,yes,no,yes,yes,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.qineq = YES;
        info.con.nlineq = YES;
        info.con.nleq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(some,no,yes,yes,yes,no,no,yes,no,yes,no);
        info.opt.miter = SOME;
        info.opt.mnode = YES;
        info.opt.mtime = YES;
        info.opt.tola = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = SOME;

    case 'bonmin'
        info.der1 = YES;
        info.der2 = SOME;
        info.sparse = YES;
        info.multialg = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,some,some,no,no,yes,yes,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.nlineq = YES;
        info.con.nleq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(some,no,yes,yes,some,no,yes,yes,yes,yes,no);
        info.opt.miter = SOME;
        info.opt.mnode = YES;
        info.opt.mtime = YES;
        info.opt.tolr = SOME;
        info.opt.tolint = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        %unique
        info.unq.x0 = YES;
        info.unq.hform = 'tril';
        info.unq.jstr = YES;
        info.unq.hstr = YES;

    case 'clp'
        info.sparse = YES;
        info.multialg = YES;
        info.parallel = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,no,no,yes,no,yes,no);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp =  YES;
        info.opt.ctrlc = YES;
        info.opt.opts = YES;
        %unique
        info.unq.qpform = 'tril';

    case 'cbc'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(no,no,yes,yes,no,no,yes,yes,no,yes,no);
        info.opt.mnode = YES;
        info.opt.mtime = YES;
        info.opt.tolint = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;

    case 'cplex'
        info.sparse = YES;
        info.parallel = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,yes,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.qineq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,yes,yes,yes,no,yes,yes,yes,yes,no);
        info.opt.miter = YES;
        info.opt.mnode = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.tolint = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        %unique
        info.unq.x0 = SOME;
        info.unq.qpform = 'sym';

    case 'csdp'
        info.sparse = YES;
        info.parallel = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,some,no,yes,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = SOME;
        info.con.sdp = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,no,no,yes,yes,yes,no);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        %unique
        info.unq.x0 = SOME;

    case 'dsdp'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,some,no,yes,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = SOME;
        info.con.sdp = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,no,yes,no,yes,yes,yes,no);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tola = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        %unique
        info.unq.x0 = SOME;

    case 'filtersd'
        info.der1 = YES;
        info.sparse = YES;
        info.multialg = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,some,some,no,no,yes,yes,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = SOME;
        info.con.leq = SOME;
        info.con.nlineq = YES;
        info.con.nleq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,no,yes,no,some,no,yes,no,yes,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tola = SOME;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;
        info.unq.jstr = YES;

    case 'glpk'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,no,yes,yes,no,yes,no);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.tolint = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;

    case 'gmatlab'
        info.global = YES;
        info.sparse = YES;
        info.multialg = YES;
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.nlineq = YES;
        info.con.int = YES;
        switch(lower(probtype))
            case {'uno','nlp',''}
                %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,yes,yes,yes);
                info.con.leq = YES;
                info.con.nleq = YES;
        end
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,some,yes,yes,no,some,yes,yes,yes,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.mnode = SOME;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.tolint = SOME;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = SOME;

    case 'hybrj'
        info.der1 = SOME;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(no,yes,no,yes,no,no,no,yes,no,yes,yes);
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'ipopt'
        info.der1 = YES;
        info.der2 = SOME;
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,some,some,no,no,yes,yes,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.nlineq = YES;
        info.con.nleq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,no,no,yes,yes,yes,yes);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;
        info.unq.hform = 'tril';
        info.unq.jstr = YES;
        info.unq.hstr = YES;

    case 'lbfgsb'
        info.der1 = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,no,no,no,no,no,no,no);
        info.con.con = YES;
        info.con.bnd = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,no,no,yes,no,yes,yes);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'levmar'
        info.der1 = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,no);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,no,no,no,no,yes,no,some,yes);
        info.opt.miter = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = SOME;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'lipsol'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = SOME;
        info.con.leq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,no,no,yes,no,yes,no);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp =  YES;
        info.opt.ctrlc = YES;

    case 'lmder'
        info.der1 = SOME;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(no,yes,no,yes,yes,no,no,yes,no,yes,yes);
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'lp_solve'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(no,no,some,yes,no,no,yes,yes,no,no,no);
        info.opt.mnode = SOME;
        info.opt.mtime = YES;
        info.opt.tolint = YES;
        info.opt.disp = YES;

    case 'm1qn3'
        info.der1 = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,no,yes,no,some,no,yes,no,yes,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tola = SOME;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'matlab'
        info.der1 = SOME;
        info.der2 = SOME;
        info.sparse = YES;
        info.multialg = YES;
        info.con.con = YES;
        info.con.bnd = YES;
        switch(lower(probtype))
            case {'lp','qp','bilp'}
                %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
                info.con.lineq = YES;
                info.con.leq = YES;
                %unique
                info.unq.x0 = SOME;
            case {'nlp',''}
                info.der1 = YES;
                info.der2 = SOME;
                %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,yes,yes,yes);
                info.con.lineq = YES;
                info.con.leq = YES;
                info.con.nlineq = YES;
                info.con.nleq = YES;
                %unique
                info.unq.x0 = YES;
                info.unq.hform = 'sym';
                info.unq.jstr = YES;
                info.unq.hstr = YES;
        end
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,some,yes,yes,no,some,yes,yes,yes,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;

    case 'mkltrnls'
        %If we don't have options, assume not called by OPTI and don't allow internal mklJac
        if(isempty(opts))
           info.der1 = SOME;
        end
        %bnd = yes;
        info.con.con = YES;
        info.con.bnd = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,yes,yes,yes,no,yes,no,yes,yes);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.tola = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'mosek'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,yes,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.qineq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,yes,yes,yes,no,yes,yes,yes,yes,no);
        info.opt.miter = YES;
        info.opt.mnode = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.tolint = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        %unique
        info.unq.x0 = SOME;
        info.unq.qpform = 'tril';

    case 'mumps'
        %Nothing!

    case 'nl2sol'
        info.der1 = SOME;
        %bnd = yes;
        info.con.con = YES;
        info.con.bnd = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,no,no,yes,yes,no,yes,no,some,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.tolr = YES;
        info.opt.tola = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = SOME;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'nlopt'
        %Some NLOPT algorithms don't require derivatives, see if we have problem data
        if(~isempty(opts))
            if(isfield(opts,'solverOpts') && ~isempty(opts.solverOpts) && isfield(opts.solverOpts,'algorithm'))
                [~,~,~,~,~,info.der1] = nloptSolver(opts.solverOpts.algorithm);
            elseif(~isempty(nlprob) && isfield(nlprob,'algorithm'))
                [~,~,~,~,~,info.der1] = nloptSolver(nlprob.algorithm);
            end %else assume not required (default based on solver)
        else
            info.der1 = SOME; %generally some do
        end
        info.global = SOME;
        info.multialg = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,some,some,no,no,yes,yes,no);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = SOME;
        info.con.leq = SOME;
        info.con.nlineq = YES;
        info.con.nleq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(no,yes,no,yes,yes,yes,no,yes,yes,some,yes);
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.tola = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = SOME;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'nomad'
        info.global = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,some,no,no,no,yes,no,no);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = SOME;
        info.con.nlineq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,no,yes,yes,no,no,yes,yes,yes,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'ooqp'
        info.sparse = YES;
        info.multialg = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(no,no,no,no,no,no,no,yes,no,no,no);
        info.opt.miter = YES;
        info.opt.mtime = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        %unique
        info.unq.qpform = 'tril';

    case 'pswarm'
        info.global = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,no,no,no,no,no,no);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,yes,no,yes,yes,no,no,yes,yes,yes,yes);
        info.opt.miter = YES;
        info.opt.meval = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.opts = YES;
        info.opt.ctrlc = YES;
        info.opt.iterf = YES;
        %unique
        info.unq.x0 = YES;

    case 'qsopt'
        info.sparse = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,no,no,no,no,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(yes,no,no,some,no,no,no,some,no,no,no);
        info.opt.miter = YES;
        info.opt.mtime = SOME;
        info.opt.disp = SOME;

    case 'scip'
        info.global = YES;
        info.sparse = YES;
        info.whitebox = YES;
        %[bnd,lineq,leq,qineq,sdp,nlineq,nleq,sp] = fillFields(yes,yes,yes,yes,no,yes,yes,yes);
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = YES;
        info.con.qineq = YES;
        info.con.qeq = YES;
        info.con.nlineq = YES;
        info.con.nleq = YES;
        info.con.int = YES;
        %[miter,meval,mnode,mtime,tolr,tola,tolint,disp,opts,ctrlc,iterf] = fillCFields(some,no,yes,yes,yes,no,no,yes,no,yes,no);
        info.opt.miter = SOME;
        info.opt.mnode = YES;
        info.opt.mtime = YES;
        info.opt.tolr = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;

    case 'sedumi'
        info.sparse = YES;
        info.multialg = YES;
        %Constraints
        info.con.con = YES;
        info.con.bnd = YES;
        info.con.lineq = YES;
        info.con.leq = SOME;
        info.con.sdp = YES;
        %Options
        info.opt.miter = YES;
        info.opt.disp = YES;
        info.opt.ctrlc = YES;

    case 'auto'
        %Assume we require derivatives
        info.der1 = YES;

    otherwise
        error('Unknown solver: %s',solver);
end


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


function info = roi_contour_map(dat, varargin)
% Draw a pattern map of one slice (either saggital, axial, or coronal) that
% shows the most voxels, or the slice that you specify (e.g., x = #).
% You can also draw outlines for the significant voxels from a statistical test.
%
% :Usage:
% ::
%
%    info = roi_contour_map(dat, varargin)
%
% ..
%     Author and copyright information:
%
%     Copyright (C) 2014 Choong-Wan (Wani) Woo
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
% ..
%
% :Inputs:
%
%   **dat:**
%        dat can be fmri_data, statistic_image (to mark significant
%        voxels), and region objects. If your dat is the "region"
%        object, please add 'cluster' as an optional input.
%        You can display two pattern maps for the purpose of
%        comparison by putting additional columns of data in cell array.
%
%        An example of displaying two pattern maps:
%        ::
%
%            dat{1} = region('img1.nii');
%            dat{2} = region('img2.nii'); )
%
% :Optional Inputs:
%
%   **'cluster':**
%        When the data is a region object, you need this option.
%
%   **'sig':**
%        This option outlines significant voxels. To use this
%        option, data in a format of statistic_image with a "sig"
%        field should be given.
%
%   **'colorbar':**
%        display colorbar under the plot.
%
%   **'use_same_range':**
%        When you display two pattern maps, this option uses the
%        same color range for the two maps.
%
%   **'surf':**
%        surface plot rather than voxel-by-voxel mapping.
%
%   **'xyz':**
%        When you want a specific view and slice, you can use this
%        option with 'coord'. (1:x - saggital view, 2:y - coronal
%        view, 3:z - axial view)
%
%   **'coord':**
%        With 'xyz' option, this specifies the slice displayed.
%
%   **'notfill':**
%        Default is to fill in the blank voxels using a black
%        color. With this option, you can color the blank voxels
%        with the white color.
%
%   **'whole':**
%        Default is dividing the data into contiguous regions and
%        show only one region that has the most voxels. This option
%        akes this function not to divide into contiguous regions.
%
%   **'colors' or 'color':**
%        you can specify your own colormap.
%
%   **'contour':**
%        Not fully implemented yet.
%
% :Outputs:
%
%   **info:**
%        information about the display with the following fields.
%
%   info.dat:
%     - [2x30 double] (xyz mesh)
%     - Z: [1x30 double] (z values)
%     - xyz: 3 (1:x-saggital, 2:y-coronal, 3:z-axial)
%     - xyz_coord: -2 (slice coordinate; in this case, z = 3)
%     - region_idx: 1
%
%
% :Examples: you can also see the same example and output in
% http://wagerlab.colorado.edu/wiki/doku.php/help/core/figure_gallery
% ::
%
%    mask{1} = 'dACC_hw_pattern_sl6mm.nii';
%    mask{2} = 'dACC_rf_pattern_sl6mm.nii';
%    for i = 1:2, cl{i} = region(mask{i}); end
%    info = roi_contour_map([cl{1} cl{2}], 'cluster', 'use_same_range', 'colorbar');
%
% ..
%    Copyright (C) 2014  Wani Woo
% ..

docolor = 0; % parsing optional inputs
dosig = 0;
docolorbar = 0;
usesamerange = 0;
usecluster = 0;
dosurf = 0;
docontour = 0; % needs to be implemented.
doxyz = 0;
docoord = 0;
donotfill = 0;
dowhole = 0;
outline_color_pos = 'r';
outline_color_neg = 'b';

for i = 1:length(varargin)
    if ischar(varargin{i})
        switch varargin{i}
            % functional commands
            case {'colors', 'color'}
                docolor = 1; colors = varargin{i+1};
            case {'sig'}
                dosig = 1;
            case {'sigcolor'}
                outline_color_pos = varargin{i+1};
                outline_color_neg = varargin{i+2};
            case {'colorbar'}
                docolorbar = 1;
            case {'use_same_range'}
                usesamerange = 1;
            case {'cluster'}
                usecluster = 1;
            case {'surf'}
                dosurf = 1;
            case {'contour'}
                docontour = 1;
            case {'xyz'}
                doxyz = 1;
                xyz_idx = varargin{i+1};
            case {'coord'}
                docoord = 1;
                coord_idx = varargin{i+1};
            case {'notfill'}
                donotfill = 1;
            case {'whole'}
                dowhole = 1;
        end
    end
end

% data inputs
if ~usecluster
    if ~iscell(dat)
        dat_temp{1} = dat;
        dat = dat_temp;
    end
end

rnum  = numel(dat);

for jj = 1:rnum
    if ~usecluster
        if dosig
            if any(strcmp(fields(dat{jj}), 'sig'))
                datsig{jj} = dat{jj};
                datsig{jj}.dat = dat{jj}.sig;
                datsig{jj}.dat = dat{jj}.dat.*~dat{jj}.sig*10^-6 + dat{jj}.sig;
                dat{jj}.sig = ones(size(dat{jj}.dat)); datsig{jj}.sig = ones(size(datsig{jj}.dat));
            else
                error('There is no sig data. Please check your data.');
            end
        else
            if any(strcmp(fields(dat{jj}), 'sig'))
                dat{jj}.sig = ones(size(dat{jj}.dat));
            end
        end

        ri = region(dat{jj});
        if dosig, risig = region(datsig{jj}); end
        if dowhole, ri = combine_region(ri); risig = combine_region(risig); end
    else
        ri = dat(jj);
    end
    clear max_vox idx idxidx;

    for i = 1:numel(ri)

        if ~docoord
            mm_c{i} = center_of_mass(ri(i).XYZmm, ones(1,size(ri(i).XYZmm, 2)));
        elseif docoord && ~doxyz
            warning('''coord'' option should be used with ''xyz''. This will use center of mass.');
            mm_c{i} = center_of_mass(ri(i).XYZmm, ones(1,size(ri(i).XYZmm, 2)));
        else
            mm_c{i} = center_of_mass(ri(i).XYZmm, ones(1,size(ri(i).XYZmm, 2)));
            [~, idx_coord_idx] = min(abs(ri(i).XYZmm(xyz_idx,:)-coord_idx));
            new_coord_idx = ri(i).XYZmm(xyz_idx,idx_coord_idx);
            mm_c{i}(xyz_idx) = new_coord_idx;
        end

        if ~doxyz
            [max_vox(i), idx(i)] = max([sum(ri(i).XYZmm(1,:) == mm_c{i}(1)), sum(ri(i).XYZmm(2,:) == mm_c{i}(2)), sum(ri(i).XYZmm(3,:) == mm_c{i}(3))]);
        else
            voxs = [sum(ri(i).XYZmm(1,:) == mm_c{i}(1)), sum(ri(i).XYZmm(2,:) == mm_c{i}(2)), sum(ri(i).XYZmm(3,:) == mm_c{i}(3))];
            idx(i) = xyz_idx;
            max_vox(i) = voxs(xyz_idx);
        end

    end

    [~, idxidx] = max(max_vox);

    xyz = 1:3;
    xyz(idx(idxidx)) = [];

    coord{jj}.dat = ri(idxidx).XYZmm(xyz,ri(idxidx).XYZmm(idx(idxidx),:) == mm_c{idxidx}(idx(idxidx)));
    coord{jj}.Z = ri(idxidx).Z(ri(idxidx).XYZmm(idx(idxidx),:) == mm_c{idxidx}(idx(idxidx)));
    if dosig
        coord{jj}.sig = risig(idxidx).Z(risig(idxidx).XYZmm(idx(idxidx),:) == mm_c{idxidx}(idx(idxidx)));
    end
    coord{jj}.xyz = idx(idxidx);
    coord{jj}.xyz_coord = mm_c{idxidx}(idx(idxidx));
    coord{jj}.region_idx = idxidx;

end

info = coord;

%% basic settingfor drawing

close all;
clear xyz;
figure;
if docolorbar
    set(gcf, 'color', 'w', 'position', [ 6   221   500*rnum   485]); % with colorbar
else
    set(gcf, 'color', 'w', 'position', [ 6   322   500*rnum   384]);
end

col = [0.0461    0.3833    0.5912
    0.2461    0.5833    0.7912
    0.4000    0.7608    0.6471
    0.6706    0.8667    0.6431
    0.9020    0.9608    0.5961
    1.0000    1.0000    0.7490
    0.9961    0.8784    0.5451
    0.9922    0.6824    0.3804
    0.9569    0.4275    0.2627
    0.8353    0.2431    0.3098
    0.6196    0.0039    0.2588];

colormap(col);
if docolor, colormap(colors); end

for jj = 1:rnum

    if dosig
        xyz = [coord{jj}.dat(1,:)', coord{jj}.dat(2,:)', coord{jj}.Z', sign(coord{jj}.Z') .* coord{jj}.sig'];
    else
        xyz = [coord{jj}.dat(1,:)', coord{jj}.dat(2,:)', coord{jj}.Z'];
    end

    [vX, vY] = meshgrid(unique(xyz(:,1)), unique(xyz(:,2)));

    vZ{jj} = NaN(size(vX));

    for i = 1:size(vX,2)
        for j = 1:size(vY,1)
            for k = 1:length(xyz)
                if isequal([vX(1,i) vY(j,1)], xyz(k,1:2))
                    vZ{jj}(j,i) = xyz(k,3);
                    if dosig
                        vsig{jj}(j,i) = xyz(k,4);
                    end
                end
            end
        end
    end

    vZ{jj} = flipud(vZ{jj});
    if dosig
        vsig{jj} = flipud(vsig{jj});
    end
    if docontour
        vZ{jj} = interp2(vZ{jj},5);
    end

    vox_size = vX(1,2)-vX(1,1);
    newX = vX/vox_size-vX(1,1)/vox_size+1;
    newY = vY/vox_size-vY(1,1)/vox_size+1;

    if docontour
        newX = repmat(1:size(vZ{jj},2), size(vZ{jj},1),1);
        newY = repmat((1:size(vZ{jj},1))', 1, size(vZ{jj},2));
    end

    %newX = (vX+2)/3-(vX(1,1)+2)/3+1;
    %newY = (vY+2)/3-(vY(1,1)+2)/3+1;

    xx{jj} = [newX(isnan(vZ{jj}))-.5 newX(isnan(vZ{jj}))-.5 newX(isnan(vZ{jj}))+.5 newX(isnan(vZ{jj}))+.5];
    yy{jj} = [newY(isnan(vZ{jj}))-.5 newY(isnan(vZ{jj}))+.5 newY(isnan(vZ{jj}))+.5 newY(isnan(vZ{jj}))-.5];

    if donotfill
        xx_outline{jj} = [newX(~isnan(vZ{jj}))-.5 newX(~isnan(vZ{jj}))-.5 newX(~isnan(vZ{jj}))+.5 newX(~isnan(vZ{jj}))+.5 newX(~isnan(vZ{jj}))-.5];
        yy_outline{jj} = [newY(~isnan(vZ{jj}))-.5 newY(~isnan(vZ{jj}))+.5 newY(~isnan(vZ{jj}))+.5 newY(~isnan(vZ{jj}))-.5 newY(~isnan(vZ{jj}))-.5];
    end

    if dosig
        x_out_pos{jj} = [newX(vsig{jj}==1)-.5 newX(vsig{jj}==1)-.5 newX(vsig{jj}==1)+.5 newX(vsig{jj}==1)+.5 newX(vsig{jj}==1)-.5];
        y_out_pos{jj} = [newY(vsig{jj}==1)-.5 newY(vsig{jj}==1)+.5 newY(vsig{jj}==1)+.5 newY(vsig{jj}==1)-.5 newY(vsig{jj}==1)-.5];
        x_out_neg{jj} = [newX(vsig{jj}==-1)-.5 newX(vsig{jj}==-1)-.5 newX(vsig{jj}==-1)+.5 newX(vsig{jj}==-1)+.5 newX(vsig{jj}==-1)-.5];
        y_out_neg{jj} = [newY(vsig{jj}==-1)-.5 newY(vsig{jj}==-1)+.5 newY(vsig{jj}==-1)+.5 newY(vsig{jj}==-1)-.5 newY(vsig{jj}==-1)-.5];
    end

    lim_max(jj) = max(max(vZ{jj}));
    lim_min(jj) = min(min(vZ{jj}));
end

if usesamerange
    lim_max = max(lim_max); lim_min = min(lim_min);
end

for jj = 1:rnum

    subplot(1,rnum,jj);

    if dosurf % not work that well yet, but kind of work
        % surf(newX, newY, vZ{jj}, 'EdgeColor','k');
        surf(interp2(vZ{jj}, 5), 'EdgeColor','none');
        set(gca, 'view', [-21.5 70])
        % axis off;
        % camlight left; lighting phong;
        set(gca, 'linewidth', 1, 'xtick', [], 'ytick', [], 'ztick', [], 'fontsize', 15);
        if usesamerange
            set(gca, 'zlim', [lim_min lim_max]);
        end
    else
        if ~usesamerange
            if docontour
                imagesc(vZ{jj}, [lim_min(jj) lim_max(jj)]);
            else
                imagesc(vZ{jj}, [lim_min(jj) lim_max(jj)]);
                if ~donotfill
                    set(gca, 'linewidth', 5, 'xtick', [], 'ytick', []);
                else
                    set(gca, 'linewidth', 0.0001, 'xtick', [], 'ytick', [], 'xcolor', 'w', 'ycolor', 'w', 'zcolor', 'w');
                end
            end
        else
            if docontour
                imagesc(vZ{jj}, [lim_min lim_max]);
                set(gca, 'linewidth', 0.0001, 'xtick', [], 'ytick', [], 'xcolor', 'w', 'ycolor', 'w', 'zcolor', 'w');
            else
                imagesc(vZ{jj}, [lim_min lim_max]);
                if ~donotfill
                    set(gca, 'linewidth', 5, 'xtick', [], 'ytick', []);
                else
                    set(gca, 'linewidth', 0.0001, 'xtick', [], 'ytick', [], 'xcolor', 'w', 'ycolor', 'w', 'zcolor', 'w');
                end
            end
        end

        if ~docontour
            y = size(vZ{jj},1); x = size(vZ{jj},2);
            if ~donotfill
                %for i = 1:x, line([i+.5,i+.5], [0 y+.5], 'color', [.2 .2 .2], 'linewidth', 1.5, 'linestyle', '-'); end
                %for i = 1:y, line([0 x+.5], [i+.5,i+.5], 'color', [.2 .2 .2], 'linewidth', 1.5, 'linestyle', '-'); end

                % black lines
                for i = 1:x, line([i+.5,i+.5], [0 y+.5], 'color', [.2 .2 .2], 'linewidth', 1, 'linestyle', '-'); end
                for i = 1:y, line([0 x+.5], [i+.5,i+.5], 'color', [.2 .2 .2], 'linewidth', 1, 'linestyle', '-'); end

                % white lines
%                 for i = 1:x, line([i+.5,i+.5], [0 y+.5], 'color', 'w', 'linewidth', 1, 'linestyle', '-'); end
%                 for i = 1:y, line([0 x+.5], [i+.5,i+.5], 'color', 'w', 'linewidth', 1, 'linestyle', '-'); end
            else
                for i = 1:x, line([i+.5,i+.5], [0 y+.5], 'color', repmat(.2, 1, 3), 'linewidth', 1.5, 'linestyle', '-'); end
                for i = 1:y, line([0 x+.5], [i+.5,i+.5], 'color', repmat(.2, 1, 3), 'linewidth', 1.5, 'linestyle', '-'); end
            end
        end

        hold on;
        if docontour
            for i = 1:size(xx{jj},1), fill(xx{jj}(i,:), yy{jj}(i,:), 'w'); end % this is wrong.
        else
            if ~donotfill
                % fill black
                for i = 1:size(xx{jj},1), fill(xx{jj}(i,:), yy{jj}(i,:), 'k'); end

                % fill white
%                 for i = 1:size(xx{jj},1), fill(xx{jj}(i,:), yy{jj}(i,:), 'w', 'edgecolor', 'w'); end
            else
                for i = 1:size(xx{jj},1), fill(xx{jj}(i,:), yy{jj}(i,:), 'w', 'edgecolor', 'w'); end
                xy_outline_idx{jj} = outline(xx_outline{jj}, yy_outline{jj});
                draw_outline(xx_outline{jj},yy_outline{jj},xy_outline_idx{jj},'k',5);
            end
        end

        if dosig
            xy_idx_pos{jj} = outline(x_out_pos{jj}, y_out_pos{jj});
            draw_outline(x_out_pos{jj},y_out_pos{jj},xy_idx_pos{jj},outline_color_pos,7)

            xy_idx_neg{jj} = outline(x_out_neg{jj}, y_out_neg{jj});
            draw_outline(x_out_neg{jj},y_out_neg{jj},xy_idx_neg{jj},outline_color_neg,7)
%             for i = 1:size(x_out{jj},1)
%                 for i2 = 1:4
%                     if xy_idx{jj}(i,i2)
%                         line([x_out{jj}(i,i2) x_out{jj}(i,i2+1)], [y_out{jj}(i,i2) y_out{jj}(i,i2+1)], 'color', 'y', 'linewidth', 5);
%                     end
%                 end
%             end
        end
    end
    if docolorbar
        hh = colorbar('southoutside');
        set(hh, 'fontSize', 25, 'lineWidth', 3);
    end

    info{jj}.vZ = vZ{jj};
end

end

% subfunctions
function xy_idx = outline(x, y)

xy_idx = true(size(x,1),4);

for i = 1:size(x,1)
    for ii = 1:4
        for j = i+1:size(x,1)
            for jj = 1:4
                if sum(abs([sort(x(i,(ii:ii+1))) sort(y(i,(ii:ii+1)))] - [sort(x(j,(jj:jj+1))), sort(y(j,(jj:jj+1)))]) < .0001) == 4
                    xy_idx(i,ii) = false; xy_idx(j,jj) = false;
                end
            end
        end
    end
end

end

function draw_outline(x,y,idx,color, linewidth)
for i = 1:size(x,1)
    for j = 1:4
        if idx(i,j)
            line([x(i,j) x(i,j+1)], [y(i,j) y(i,j+1)], 'color', color, 'linewidth', linewidth);
        end
    end
end

end

function r = combine_region(r)
rr = r(1);

if numel(r) > 1
    for i = 2:numel(r)
        rr.XYZ = [rr.XYZ r(i).XYZ];
        rr.XYZmm = [rr.XYZmm r(i).XYZmm];
        rr.val = [rr.val; r(i).val];
        rr.Z = [rr.Z r(i).Z];
    end
end

r = rr;

end


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


function [x] = getjet(i)
file    = matfile('jet_data/jetLES.mat');
x       = squeeze(file.p(i,:,:));
end


function h = helicorder(varargin)

%HELICORDER: Helicorder generates a multi-line display of input waveform
%   data. Helicorder can display waveform data from multiple stations and
%   channels as long as the time range is the same for each. Helicorder
%   can also display detected events over the raw data.
%
%USAGE: helicorder()----------------------- Empty helicorder
%       helicorder(wave)------------------- Default properties
%       helicorder(wave,prop_1,val_1,...)-- User-defined properties
%
%VALID PROP/VAL:
%  'mpl'-->(Minutes Per Line)
%     single numeric value specifying number of minutes per helicorder
%     line. (This applies to all waveforms in the helicorder)
%     DEFAULT = 10
%
%  'ytick'-->(Y-Axis Ticks)
%     single numeric value specifying number of minutes between y-axis
%     tick marks and labels. 'ytick' depends on 'mpl', for example, if
%     'mpl' is 20, an attempt to set 'ytick' to 10 will be result in
%     'ytick' rounded to nearest multiple of 'mpl' (20 in this case). Note
%     also that manually setting 'mpl' will result in an automatic
%     adjustment of 'ytick'.
%     DEFAULT = 30
%
%  'e_sst'-->(Event Start/Stop Times)
%     If wave contains only one wavefrom object, 'e_sst' can be entered
%     as an Nx2 array of matlab times. If there is more than one waveform
%     in wave (M waveforms), 'e_sst' must be a 1xM cell array, each cell
%     containing Nx2 array of start/stop times. A single waveform can also
%     have multiple sets of start/stop times as in a waveform with multiple
%     event families. In this case 'e_sst' should be entered as a 1xL cell
%     array for a particular waveform (with L separate groups to be
%     highlighted).
%     EXAMPLE: h = helicorder(w,'e_sst',A) where w is a 1x2 waveform object
%        A is a 1x2 cell array
%        A(1,1) is a Nx2 numeric array
%        A(1,2) is a 1x3 cell
%        A(1,2){1} is a Nx2 numeric array
%        A(1,2){2} is a Nx2 numeric array
%        A(1,2){3} is a Nx2 numeric array
%     DEFAULT = [] (No events)
%
%  'trace_color'-->(Trace Color)
%     If wave contains only one wavefrom object, 'trace_color' can be
%     entered as a 1x3 array of RGB values (between 0 and 1). For wave
%     arguments longer than 1, 'trace_color' should be entered as a 1xN
%     cell array, each containing a 1x3 array of RGB values.
%
%  'event_color'-->(Event Color)
%     Only use this property when 'e_sst' property exists. 'event_color'
%     follows the same structure as 'e_sst'. If wave contains only one
%     waveform object, 'event_color' can be entered as a 1x3 array of RGB
%     values (between 0 and 1). For wave arguments longer than 1,
%     'event_color' should be entered as a 1xN cell array, each containing
%     a 1x3 array of RGB values. If multiple event sets exist for a single
%     waveform, 'event_color' must be specified accordingly
%     EXAMPLE: h = helicorder(w,'e_sst',A,'event_color',B)
%        A is the same as the previous example
%        B(1,1) is a 1x3 RGB array
%        A(1,2) is a 1x3 cell
%        A(1,2){1} is a 1x3 RGB array
%        A(1,2){2} is a 1x3 RGB array
%        A(1,2){3} is a 1x3 RGB array
%     DEFAULT = [] (No events)
%
%  'display'-->(Multi-Waveform Display Type)
%     'single' - used when there is only one waveform in wave. None of the
%        multi-waveform display types can be set unless multiple waveforms
%        are passed.
%     'stack' - plots multiple waveforms over top of each other.
%        (Multiple motivations could exist for wanting to display data in
%        this way such as overlaying VLP energy)
%     'alternate' - Alternate helicorder lines
%        i.e. Helicorder containing 3 waveforms would look like:
%        w1(t0 --> t1), w2(t0 --> t1), w3(t0 --> t1), w1(t1 -- t2),...
%     'group' - Plot all lines from individual waveforms in separate blocks
%        i.e. Helicorder containing 3 waveforms would look like:
%        w1(t0 --> t1), w1(t1 --> t2), w1(t2 --> t3),... w1(t_end-1 -->
%        t_end),w2(t0 --> t1), w2(t1 --> t2), w2(t2 --> t3),...
%     DEFAULT = 'single','alternate' (1 or multiple waveforms)
%
%INPUTS: wave     - a waveform object to be plotted on multiple helicorder
%                   trace lines
%        varargin - user-defined helicorder properties (argument pairs)
%
%OUTPUTS: h - helicorder object
%
%   See also HELICORDER/DISP, HELICORDER/BUILD, HELICORDER/GET,
%            HELICORDER/SET
%
% Author: Dane Ketner, Alaska Volcano Observatory
% $Date$
% $Revision$

%% EMPTY HELICORDER
if nargin == 0
   h.wave = waveform();
   h.e_sst = {};
   nw = 0;

%% ANOTHER HELICORDER OBJECT
elseif nargin==1 && isa(varargin{1},'helicorder')
    h = varargin{1};
    return

%% WAVEFORM OBJECT PROVIDED
elseif (nargin >= 1) && isa(varargin{1},'waveform')
   h.wave = varargin{1}; % Helicorder waveform data
   nw = numel(h.wave);
else
   error('helicorder: first argument must be a waveform')
end

%% DEFAULT PROPERTIES
for n = 1:nw,
   h.e_sst{n} = []; % Empty event start/stop time array
end

h.mpl = 10;   % 10 Minutes per line
h.ytick = 30; % Time Ticks every 30 Minutes (3 Lines)

if nw <= 1                     % Default trace color scheme
   h.trace_color{1} = [0 0 0]; % black
   h.event_color{1} = [1 0 0]; % red
elseif nw == 2
   h.trace_color{1} = [0 0 0]; % black
   h.trace_color{2} = [0 0 1]; % blue
else
   rr = zeros(1,nw);              % red values
   gg = round(linspace(-255,255,nw));
   gg = sign(sign(gg)+1).*gg/255; % green values
   bb = round(linspace(255,-255,nw));
   bb = sign(sign(bb)+1).*bb/255; % blue values
   for n = 1:nw
      h.trace_color{n} = [rr(n) gg(n) bb(n)];
   end
end

h.event_color = [];

if nw <= 1
   h.display = 'single';
else
   h.display = 'alternate';
end

h.scale = ones(1,nw); % Waveform amplitude scale is automatically set based
                      % on maximum values in wave. scale can be set after
                      % the fact. 1 is default, going higher or lower will
                      % scale wave proportionally.
h = class(h,'helicorder');

%% USER-DEFINED PROPERTIES
if (nargin > 1)
   v = varargin(2:end);
   nv = nargin-1;
   if ~rem(nv,2) == 0
      error(['helicorder: Arguments after wave must appear in ',...
             'property name/val pairs'])
   end
   for n = 1:2:nv-1
      name = lower(v{n});
      val = v{n+1};
      switch name
         case 'e_sst' % Event Start/Stop Times
            h = set(h,'e_sst',val);
            for n = 1:nw       % Default event color scheme (shades of red)
               if ~iscell(h.e_sst{n})
                  h.event_color{n} = [1 0 0];
               else
                  for m = 1:numel(h.e_sst{n})
                     rr = m/numel(h.e_sst{n});
                     h.event_color{n}{m} = [rr 0 0];
                  end
               end
            end
         case 'ytick' % Y-Tick Spacing
            h = set(h,'ytick',val);
         case 'mpl' % Minutes Per Line
            h = set(h,'mpl',val);
         case 'trace_color' % Minutes Per Line
            h = set(h,'trace_color',val);
         case 'event_color' % Minutes Per Line
            h = set(h,'event_color',val);
         case 'display' % Multiple Waveform Display Type
            h = set(h,'display',val);
         case 'scale' % Waveform Data Scaling Factor
            h = set(h,'scale',val);
         otherwise
            error('helicorder: Property name not recognized')
      end
   end
end


function s2 = s_escape_tex ( s1 )

%*****************************************************************************80
%
%% S_ESCAPE_TEX de-escapes TeX escape sequences.
%
%  Discussion:
%
%    In particular, every occurrence of the characters '\', '_',
%    '^', '{' and '}' will be replaced by '\\', '\_', '\^',
%    '\{' and '\}'.  A TeX interpreter, on seeing these character
%    strings, is then likely to return the original characters.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S1, the string to be de-escaped.
%
%    Output, string S2, a copy of the string, modified to avoid TeX escapes.
%
  s1_length = length ( s1 );

  s1_pos = 0;
  s2_pos = 0;
  s2 = [];

  while ( s1_pos < s1_length )

    s1_pos = s1_pos + 1;

    if ( s1(s1_pos) == '\' || ...
         s1(s1_pos) == '_' || ...
         s1(s1_pos) == '^' || ...
         s1(s1_pos) == '{' || ...
         s1(s1_pos) == '}' )
      s2_pos = s2_pos + 1;
      s2 = strcat ( s2, '\' );
    end

    s2_pos = s2_pos + 1;
    s2 = strcat ( s2, s1(s1_pos) );

  end

  return
end


function value = ch_indexi ( s, c )

%*****************************************************************************80
%
%% CH_INDEXI is the (case insensitive) first occurrence of a character in a string.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be searched.
%
%    Input, character C, the character to be searched for.
%
%    Output, integer VALUE, the location of the first occurrence of C
%    (upper or lowercase), or 0 if C does not occur.
%
  value = 0;

  for i = 1 : length ( s )

    if ( ch_eqi ( s(i), c ) )
      value = i;
      return
    end

  end

  return
end


 function x = ir_read_mat(file, pick)
%function x = ir_read_mat(file, pick)
%|
%| Read a matlab matrix from file, e.g., 'data.mat'
%| If pick is an integer, it indexes which field in the file is desired.
%| Jeff Fessler, University of Michigan

if nargin < 1, ir_usage, end
if ~isvar('pick') || isempty(pick), pick = 0; end

s = load(file);
names = fieldnames(s);
name = names{1};
if length(names) > 1
	if ~isa(pick, 'numeric')
		error 'only numeric picking done now'
	end
	if pick < 1
		disp(names)
		warn('using default first array: %s', name)
	elseif pick > length(names)
		error 'pick too large'
	else
		name = names{pick};
		printm('Using array %s', name)
	end
end
x = s.(name);