function [ icc, ccc, acc ] = cc_data_read ( prefix, ncc, n )

%*****************************************************************************80
%
%% CC_DATA_READ reads data about a sparse matrix in CC format.
%
%  Discussion:
%
%    Three files are presumed to exist:
%    * prefix_icc.txt contains NCC ICC values;
%    * prefix_ccc.txt contains N+1 CCC values;
%    * prefix_acc.txt contains NCC ACC values.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 July 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string PREFIX, a common prefix for the filenames.
%
%    Input, integer NCC, the number of CC elements.
%
%    Input, integer N, the number of columns in the matrix.
%
%    Output, integer ICC(NCC), the CC rows.
%
%    Output, integer CCC(N+1), the compressed CC columns.
%
%    Output, real ACC(NCC), the CC values.
%
  filename_icc = strcat ( prefix, '_icc.txt' );
  icc = i4vec_data_read ( filename_icc, ncc );

  filename_ccc = strcat ( prefix, '_ccc.txt' );
  ccc = i4vec_data_read ( filename_ccc, n + 1 );

  filename_acc = strcat ( prefix, '_acc.txt' );
  acc = r8vec_data_read ( filename_acc, ncc );

  return
end


function [subs,vals] = find(t)
%FIND Find subscripts of nonzero elements in a sparse tensor.
%
%   [SUBS,VALS] = FIND(T) returns the subscripts and corresponding
%   values of the nonzero elements of T.
%
%   Note that unlike the standard MATLAB find function for an array,
%   find does not return linear indices. Instead, it returns an M x N
%   array where M is the number of nonzero values and N = ndims(T).
%   Thus, I(k,:) specifies the subscript of value V(k).
%
%   See also SPTENSOR, FIND.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

subs = t.subs;
vals = t.vals;


function varargout = conj(varargin)
%CONJ   Complex conjugate of a DISKFUN.
%   CONJ(F) returns the complex conjugate of F.  For a complex F, CONJ(F) =
%   REAL(F) - i*IMAG(F).
%
%   Since only real-valued DISKFUNS are presently supported, this
%   function is trivial.
%
% See also DISKFUN/REAL, DISKFUN/IMAG.

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

[varargout{1:nargout}] = conj@separableApprox(varargin{:});

end


function done = mission7(occupiers, target)

for i = 1:6
    if any(occupiers{i} == target)
        done = false;
        return
    end
end

done = true;


function b = uplus(a)
% function B=uplus(A)
%
% DESCRIPTION
%   Unary plus
%
% INPUTS
%   A: polynomial
%
% OUTPUTS
%   B: unary plus of input, +A
%
% SYNTAX
%   B = +A;
%     Unary plus.
%   B = uplus(A);
%     Function-call form for unary plus.

% 6/8/2002: PJS  Initial Coding

b = a;


function jed = epoch_to_jed_eg_civil ( )

%*****************************************************************************80
%
%% EPOCH_TO_JED_EG_CIVIL: epoch of the Egyptian Civil calendar as a JED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real JED, the Julian Ephemeris Date of the epoch.
%
  jed = 1448637.5;

  return
end


%ISEMPTY Dataset overload
%
%	I = ISEMPTY(A,FIELD)
%
% INPUT
%  A     Dataset
%  FIELD Dataset field, default 'data'
%
% OUTPUT
%  I     Flag, 1 if field is empty, 0 otherwise.
%
% DESCRIPTION
% Dataset overload for ISEMPTY. This is particulary useful for
% ISEMPTY(A) to test on an empty dataset, and
% ISEMPTY(A,'prior') to test on an undefined PRIOR field
%
% SEE ALSO (PRTools Guide)
% PRDATASET, SETPRIOR, GETPRIOR


function test_suite = test_polygonSubcurve
%TESTPOLYGONSUBCURVE  One-line description here, please.
%   output = testPolygonSubcurve(input)
%
%   Example
%   testPolygonSubcurve
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2009-06-16,    using Matlab 7.7.0.471 (R2008b)
% Copyright 2009 INRA - Cepia Software Platform.
% Licensed under the terms of the LGPL, see the file "license.txt"

test_suite = functiontests(localfunctions);

function testSquare(testCase) %#ok<*DEFNU>

p1 = [10 10];
p2 = [20 10];
p3 = [20 20];
p4 = [10 20];
square = [p1;p2;p3;p4];

subcurve = polygonSubcurve(square, .5, 1.5);
testCase.assertEqual(subcurve, [15 10;20 10;20 15], 'AbsTol', .01);

subcurve = polygonSubcurve(square, 3.5, .5);
testCase.assertEqual(subcurve, [10 15;10 10;15 10], 'AbsTol', .01);


function writeBB(filename,D,type)
  % WRITEBB  write medit data file
  %
  % writeBB(filename,D,type)
  %
  % Inputs:
  %   filename  path to *.bb file
  %   D  #D by dim  data matrix
  %   type  type identifier as per
  %     http://www.ann.jussieu.fr/frey/publications/RT-0253.pdf page 34
  %     2 means defined at vertices
  %     1 means defined at elements

  f = fopen(filename,'w');
  % print header
  % only vector data is supported
  fprintf(f,'%d %d %d %d\n',2,1,size(D,1),type);
  fprintf(f,'%g\n',D');
  fclose(f);

end


function y = rdivide(X,Y)
%RDIVIDE (overloaded)

% Check dimensions
[nx,mx] = size(X);
[ny,my] = size(Y);
if ~((prod(size(X))==1) | (prod(size(Y))==1))
    if ~((nx==ny & (mx ==my)))
        error('Matrix dimensions must agree.')
    end
end

% Quick exit for simple case X/scalar
if isnumeric(Y) & prod(size(Y))==1
    y = X;
    y.basis = y.basis/Y;
    % Reset info about conic terms
    y.conicinfo = [0 0];
    return
end

if isa(X,'sdpvar') & isnumeric(Y)
    y = X.*(1./Y);
    return
end

% normalize scalar./matrix and matrix./scalar
[nx,mx] = size(X);
[ny,my] = size(Y);
if prod(size(X)) == 1 & prod(size(Y))~=1
    X = repmat(X,ny,my);
end;
if prod(size(Y)) == 1 & prod(size(X))~=1
    Y = repmat(Y,nx,mx);
end

% power is optimized already for simple cases
y = X.*(Y.^(-1));

% Reset info about conic terms
if isa(y,'sdpvar')
    y.conicinfo = [0 0];
end


function test07 ( input_file_name )

%*****************************************************************************80
%
%% TEST07 tests STLA_SIZE and STLA_SIZE_FAST.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2007
%
%  Author:
%
%     John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST07\n' );
  fprintf ( 1, '  Compare two routines with the same functionality.\n' );
  fprintf ( 1, '  One is designed to run faster than the other,\n' );
  fprintf ( 1, '  especially on large problems with thousands of faces.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  STLA_SIZE determines the size of various objects\n' );
  fprintf ( 1, '    in an ASCII STL file.\n' );
  fprintf ( 1, '  STLA_SIZE_FAST determines the size of various objects\n' );
  fprintf ( 1, '    in an ASCII STL file.\n' );
  fprintf ( 1, '\n' );

  t1 = clock;

  [ solid_num, node_num, face_num, line_num ] = stla_size_fast ( input_file_name );

  t2 = clock;

  diff1 = etime ( t2, t1 );

  fprintf ( 1, '  STLA_SIZE_FAST scanned the file in %f seconds.\n', diff1 );

  t3 = clock;

  [ solid_num, node_num, face_num, line_num ] = stla_size ( input_file_name );

  t4 = clock;

  diff2 = etime ( t4, t3 );

  fprintf ( 1, '  STLA_SIZE      scanned the file in %f seconds.\n', diff2 );

  stla_size_print ( input_file_name, solid_num, node_num, face_num, line_num );

  return
end


function tbxStruct=Demos
% Demos   Demo List infomation for NURBS Toolbox

% D.M. Spink
% Copyright (c) 2000

if nargout == 0; demo toolbox; return; end

tbxStruct.Name='nurbs';
tbxStruct.Type='Toolbox';

tbxStruct.Help= ...
        {' The NURBS Toolbox provides commands for the construction'
         ' and use of Non-Uniform Rational B-Splines (NURBS).'
         ' '};

tbxStruct.DemoList={
                '3D Line','demoline',
                'Rectangle','demorect',
                'Circle and Arc','democirc',
                'Helix','demohelix',
                'Ellipse', 'demoellip',
                'Test Curve','democurve',
                'Test Surface','demosurf',
                'Bilinear Surface','demo4surf',
                'Knot Insertion','demokntins',
                'Degree Elevation','demodegelev',
                'Curve derivatives','demodercrv',
                'Surface derivatives','demodersrf'
                'Cylinderical arc','democylind',
                'Ruled Surface','demoruled',
                'Coons Surface','democoons',
                'Test Extrusion','demoextrude',
                'Test Revolution - Cup','demorevolve',
                'Test Revolution - Ball & Torus','demotorus',
                '2D Geomtery','demogeom'};


function navego_plot_outage (nav_t, nav_var, OUTAGE, times_out)
% navego_plot_outage: plots GNSS outages periods.
%
% INPUT
%   nav_t,   Nx1 vector time.
%   nav_var, Nx1 navigation variable.
%   OUTAGE, 'ON' or 'OFF' (string).
%   times_out, Tx1 vector with outage times where times_out(1) is the start
%     time of 1st GNSS OUTAGE, times_out(2) is the end of 1st GNSS OUTAGE,
%     times_out(3) is the start of the 2nd GNSS OUTAGE, and so on. T should
%     be even.
%
% OUTPUT
%   One figure.
%
%   Copyright (C) 2014, Rodrigo Gonzalez, all rights reserved.
%
%   This file is part of NaveGo, an open-source MATLAB toolbox for
%   simulation of integrated navigation systems.
%
%   NaveGo is free software: you can redistribute it and/or modify
%   it under the terms of the GNU Lesser General Public License (LGPL)
%   version 3 as published by the Free Software Foundation.
%
%   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 Lesser General Public License for more details.
%
%   You should have received a copy of the GNU Lesser General Public
%   License along with this program. If not, see
%   <http://www.gnu.org/licenses/>.
%
% Version: 001
% Date:    2021/12/14
% Author:  Rodrigo Gonzalez <rodralez@frm.utn.edu.ar>
% URL:     https://github.com/rodralez/navego

if (nargin < 3)

    OUTAGE = 'OFF';
end

%% PARAMETERS

plot_parameters;

%% OUTAGES

if (strcmp(OUTAGE,'ON'))

    OUTAGE_N = max(size(times_out)) / 2;

    for k = 1:OUTAGE_N

        idx  = find(nav_t >= times_out(2*k-1), 1, 'first' );
        fdx  = find(nav_t <= times_out(2*k), 1, 'last' );

        plot(nav_t(idx:fdx), nav_var(idx:fdx), '.r', 'MarkerSize', ms, ...
            'LineWidth', lw, 'DisplayName','GNSS OUTAGE') ;
    end
end


classdef MshReader < FileReader

    properties (Access = public)

    end

    properties (Access = private)
        strcontent
        contentCell
        coord
        connec
        nElem
        nNodes
        nNodeElem
        numbers
    end

    methods (Access = public)

        function obj = MshReader(cParams)
            obj.init(cParams)
        end

        function m = read(obj)
            obj.openFile();
            obj.splitIntoLines();
            obj.getDimensions();
            obj.extractNumbers();
            obj.getCoordAndConnec();
            obj.closeFile();
            m = obj.createMesh();
        end

        function d = getDataBase(obj)
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.filePath = cParams.filePath;
        end

        function splitIntoLines(obj)
            obj.strcontent = fileread(obj.filePath);
            obj.contentCell = splitlines(obj.strcontent);
        end

        function getDimensions(obj)
            fLCell = split(obj.contentCell{1});
            fLCoor = 3;
            lLCoor = find(strcmp(obj.contentCell, 'End Coordinates'))-1;
            fLConnec = find(strcmp(obj.contentCell, 'Elements')) +1;
            lLConnec  = length(obj.contentCell) - 2;
            obj.nNodes    = lLCoor - fLCoor + 1;
            obj.nElem     = lLConnec - fLConnec + 1;
            obj.nNodeElem = str2double(fLCell{end});
        end

        function extractNumbers(obj)
            expr = '(-?0?\.?\d*)';
            match = regexp(obj.strcontent,expr, 'tokens', 'dotexceptnewline');
            cellfunres2 = cellfun(@cell2mat,match,'UniformOutput',false);
            numbersAll = str2double(cellfunres2);
            obj.numbers = numbersAll(3:end);
        end

        function getCoordAndConnec(obj)
            nN  = obj.nNodes;
            nE  = obj.nElem;
            nNE = obj.nNodeElem;
            coordRaw  = reshape(obj.numbers(1:nN*4), [4, nN])';
            connecRaw = reshape(obj.numbers(nN*4+1:end), [nNE+1, nE])';
            if isequal(coordRaw(:,4),zeros(length(coordRaw),1))
                coordRaw = coordRaw(:,1:3);
            end
            obj.coord  = coordRaw(:,2:end);
            obj.connec = connecRaw(:,2:end);
        end

        function m = createMesh(obj)
            s.coord  = obj.coord;
            s.connec = obj.connec;
            m = Mesh(s);
        end
    end

end


function tutorial_raw(tutorial_dir)
% TUTORIAL_RAW: Script that reproduces the results of the online tutorials "MEG median nerve (Yokogawa)".
%
% DESCRIPTION:
%     It is based on a median nerve stimulation experiment recorded at the Montreal Neurological Institute in 2011
%     with a CTF MEG 275 system. The sample dataset contains 6 minutes of recordings at 1200Hz for one subject
%     and includes 100 stimulations of each arm.
%
% CORRESPONDING ONLINE TUTORIALS:
%     https://neuroimage.usc.edu/brainstorm/Tutorials/MedianNerveCtf
%
% INPUTS:
%     tutorial_dir: Directory where the sample_raw.zip file has been unzipped

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Author: Francois Tadel, 2013-2016

% ===== FILES TO IMPORT =====
% You have to specify the folder in which the tutorial dataset is unzipped
if (nargin == 0) || isempty(tutorial_dir) || ~file_exist(tutorial_dir)
    error('The first argument must be the full path to the tutorial dataset folder.');
end
% Build the path of the files to import
AnatDir = fullfile(tutorial_dir, 'sample_raw', 'Anatomy');
RawFile = fullfile(tutorial_dir, 'sample_raw', 'Data', 'subj001_somatosensory_20111109_01_AUX-f.ds');
% Check if the folder contains the required files
if ~file_exist(RawFile)
    error(['The folder ' tutorial_dir ' does not contain the folder from the file sample_raw.zip.']);
end

% ===== CREATE PROTOCOL =====
% The protocol name has to be a valid folder name (no spaces, no weird characters...)
ProtocolName = 'TutorialRaw';
% Start brainstorm without the GUI
if ~brainstorm('status')
    brainstorm nogui
end
% Delete existing protocol
gui_brainstorm('DeleteProtocol', ProtocolName);
% Create new protocol
gui_brainstorm('CreateProtocol', ProtocolName, 0, 0);
% Start a new report
bst_report('Start');

% ===== ANATOMY =====
% Subject name
SubjectName = 'Subject01';
% Process: Import anatomy folder
bst_process('CallProcess', 'process_import_anatomy', [], [], ...
    'subjectname', SubjectName, ...
    'mrifile',     {AnatDir, 'FreeSurfer'}, ...
    'nvertices',   15000, ...
    'nas',         [127, 212, 123], ...
    'lpa',         [ 55, 124, 119], ...
    'rpa',         [200, 129, 114]);

% ===== LINK CONTINUOUS FILE =====
% Process: Create link to raw file
sFilesRaw = bst_process('CallProcess', 'process_import_data_raw', [], [], ...
    'subjectname',    SubjectName, ...
    'datafile',       {RawFile, 'CTF'}, ...
    'channelreplace', 1, ...
    'channelalign',   1);
% Process: Snapshot: Sensors/MRI registration
bst_process('CallProcess', 'process_snapshot', sFilesRaw, [], ...
    'target',   1, ...  % Sensors/MRI registration
    'modality', 1, ...  % MEG (All)
    'orient',   1, ...  % left
    'Comment',  'MEG/MRI Registration');

% ===== REMOVE 60/180/240 Hz =====
% Process: Notch filter: 60Hz 120Hz 180Hz
sFilesClean = bst_process('CallProcess', 'process_notch', sFilesRaw, [], ...
    'freqlist',    [60, 120, 180], ...
    'sensortypes', 'MEG', ...
    'read_all',    0);

% Process: Power spectrum density (Welch)
sFilesPsd = bst_process('CallProcess', 'process_psd', [sFilesRaw, sFilesClean], [], ...
    'timewindow',  [0, 50], ...
    'win_length',  4, ...
    'win_overlap', 50, ...
    'clusters',    {}, ...
    'sensortypes', 'MEG', ...
    'edit', struct(...
         'Comment',         'Power', ...
         'TimeBands',       [], ...
         'Freqs',           [], ...
         'ClusterFuncTime', 'none', ...
         'Measure',         'power', ...
         'Output',          'all', ...
         'SaveKernel',      0));

% Process: Snapshot: Frequency spectrum
bst_process('CallProcess', 'process_snapshot', sFilesPsd, [], ...
    'target',   10, ...  % Frequency spectrum
    'modality', 1, ...   % MEG (All)
    'Comment',  'Power spectrum density');

% ===== CORRECT BLINKS AND HEARTBEATS =====
% Process: Detect heartbeats
sFilesClean = bst_process('CallProcess', 'process_evt_detect_ecg', sFilesClean, [], ...
    'channelname', 'EEG057', ...
    'timewindow',  [], ...
    'eventname',   'cardiac');

% Process: Detect eye blinks
sFilesClean = bst_process('CallProcess', 'process_evt_detect_eog', sFilesClean, [], ...
    'channelname', 'EEG058', ...
    'timewindow',  [], ...
    'eventname',   'blink');

% Process: Remove simultaneous
sFilesClean = bst_process('CallProcess', 'process_evt_remove_simult', sFilesClean, [], ...
    'remove', 'cardiac', ...
    'target', 'blink', ...
    'dt',     0.25, ...
    'rename', 0);

% % Process: SSP ECG: cardiac
% sFilesClean = bst_process('CallProcess', 'process_ssp_ecg', sFilesClean, [], ...
%     'eventname',   'cardiac', ...
%     'sensortypes', 'MEG', ...
%     'usessp',       1, ...
%     'select',       []);   % Force selection of some components

% Process: SSP EOG: blink
sFilesClean = bst_process('CallProcess', 'process_ssp_eog', sFilesClean, [], ...
    'eventname',   'blink', ...
    'sensortypes', 'MEG', ...
    'usessp',       1, ...
    'select',       1);   % Force selection of some components

% Process: Snapshot: SSP projectors
bst_process('CallProcess', 'process_snapshot', sFilesClean, [], ...
    'target',  2, ...  % SSP projectors
    'Comment', 'SSP projectors');

% ===== IMPORT EVENTS =====
% Process: Import MEG/EEG: Events
sFilesEpochs = bst_process('CallProcess', 'process_import_data_event', sFilesClean, [], ...
    'subjectname', SubjectName, ...
    'condition',   '', ...
    'eventname',   'left, right', ...
    'timewindow',  [], ...
    'epochtime',   [-0.1, 0.3], ...
    'createcond',  0, ...
    'ignoreshort', 1, ...
    'usectfcomp',  1, ...
    'usessp',      1, ...
    'freq',        [], ...
    'baseline',    [-0.1, 0]);

% Process: Add time offset: -4.20ms
sFilesEpochs = bst_process('CallProcess', 'process_timeoffset', sFilesEpochs, [], ...
    'offset',    -0.0042, ...
    'overwrite', 1);

% Process: Average: By condition (subject average)
sFilesAvg = bst_process('CallProcess', 'process_average', sFilesEpochs, [], ...
    'avgtype',    6, ...  % By trial groups (subject average)
    'avg_func',   1, ...  % Arithmetic average: mean(x)
    'keepevents', 0);

% Process: Snapshot: Recordings time series
bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ...
    'target',   5, ...  % Recordings time series
    'modality', 1, ...  % MEG (All)
    'Comment',  'Evoked response');

% ===== SOURCE MODELING =====
% Process: Compute head model
bst_process('CallProcess', 'process_headmodel', sFilesAvg, [], ...
    'comment',      '', ...
    'sourcespace',  1, ...
    'meg',          3);  % Overlapping spheres

% Process: Compute noise covariance
bst_process('CallProcess', 'process_noisecov', sFilesEpochs, [], ...
    'baseline',     [-0.104, -0.005], ...
    'sensortypes',  'MEG, EEG', ...
    'target',       1, ...  % Noise covariance     (covariance over baseline time window)
    'dcoffset',     1, ...
    'identity',     0, ...
    'copycond',     0, ...
    'copysubj',     0, ...
    'replacefile',  1);  % Replace

% Process: Snapshot: Noise covariance
bst_process('CallProcess', 'process_snapshot', sFilesAvg, [], ...
    'target',  3, ...  % Noise covariance
    'Comment', 'Noise covariance');

% Process: Compute sources
sFilesSrcAvg = bst_process('CallProcess', 'process_inverse', sFilesAvg, [], ...
    'comment', '', ...
    'method',  2, ...  % dSPM
    'wmne',    struct(...
         'NoiseCov',      [], ...
         'InverseMethod', 'dspm', ...
         'ChannelTypes',  {{}}, ...
         'SNR',           3, ...
         'diagnoise',     0, ...
         'SourceOrient',  {{'fixed'}}, ...
         'loose',         0.2, ...
         'depth',         1, ...
         'weightexp',     0.5, ...
         'weightlimit',   10, ...
         'regnoise',      1, ...
         'magreg',        0.1, ...
         'gradreg',       0.1, ...
         'eegreg',        0.1, ...
         'ecogreg',       0.1, ...
         'seegreg',       0.1, ...
         'fMRI',          [], ...
         'fMRIthresh',    [], ...
         'fMRIoff',       0.1, ...
         'pca',           1), ...
    'sensortypes', 'MEG, MEG MAG, MEG GRAD, EEG', ...
    'output',      1);  % Kernel only: shared

% Process: Snapshot: Sources (one time)
bst_process('CallProcess', 'process_snapshot', sFilesSrcAvg, [], ...
    'target',   8, ...  % Sources (one time)
    'modality', 1, ...  % MEG (All)
    'orient',   3, ...  % top
    'time',     0.035, ...
    'Comment',  'Source maps at 35ms');

% Save and display report
ReportFile = bst_report('Save', sFilesSrcAvg);
bst_report('Open', ReportFile);


function z = cvmgt(x, y, p)
%CVMGT  Conditional merge of two vectors
%
%   Z = CVMGT(X, Y, P) return a vector Z whose elements are X if P is true
%   and Y otherwise.  P, X, and Y should be the same shape except that X
%   and Y may be scalars.  CVMGT stands for conditional vector merge true
%   (an intrinsic function for the Cray fortran compiler).  It implements
%   the C++ statement
%
%     Z = P ? X : Y;

  z = zeros(size(p));
  if isscalar(x)
    z(p) = x;
  else
    z(p) = x(p);
  end
  if isscalar(y)
    z(~p) = y;
  else
    z(~p) = y(~p);
  end
end


%% Copyright (C) 2014-2020, 2022-2023 Colin B. Macdonald
%% Copyright (C) 2017 NVS Abhilash
%% Copyright (C) 2017 Mike Miller
%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy 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 software 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 software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @deftypefn  Command {} sympref @var{cmd}
%% @deftypefnx Command {} sympref @var{cmd} @var{args}
%% @deftypefnx Function {@var{r} =} sympref ()
%% @deftypefnx Function {@var{r} =} sympref (@var{cmd})
%% @deftypefnx Function {@var{r} =} sympref (@var{cmd}, @var{args})
%% Preferences for the Symbolic package.
%%
%% @code{sympref} can set or get various preferences and
%% configurations.  The various choices for @var{cmd} and
%% @var{args} are documented below.
%%
%% Run @strong{diagnostics} on your system:
%% @example
%% @comment doctest: +SKIP
%% sympref diagnose
%%   @print{} ...
%% @end example
%%
%%
%% @strong{Display} of syms:
%%
%% @example
%% @group
%% sympref display
%%   @result{} ans = unicode
%%
%% @end group
%% @group
%% syms x
%% sympref display flat
%% sin(x/2)
%%   @result{} (sym) sin(x/2)
%%
%% sympref display ascii
%% sin(x/2)
%%   @result{} (sym)
%%          /x\
%%       sin|-|
%%          \2/
%%
%% sympref display unicode
%% sin(x/2)
%%   @result{} (sym)
%%          ⎛x⎞
%%       sin⎜─⎟
%%          ⎝2⎠
%%
%% sympref display default
%% @end group
%% @end example
%%
%% By default, a unicode pretty printer is used to display
%% symbolic expressions.  If that doesn't work (e.g., if you
%% see @code{?} characters) then try the @code{ascii} option.
%%
%%
%% @strong{Communication mechanism}:
%%
%% @example
%% @group
%% sympref ipc
%%   @result{} ans = default
%% @end group
%% @end example
%%
%% This default depends on your system.  If you have loaded the
%% @uref{https://gitlab.com/mtmiller/octave-pythonic, Pythonic package},
%% the default will be the @code{native} mechanism.
%% Otherwise, typically the @code{popen2} mechanism will be used,
%% which uses a pipe to communicate with Python.
%% If that doesn't work, try @code{sympref ipc system} which is
%% much slower, as a new Python process is started for each operation.
%%
%% Other options for @code{sympref ipc} include:
%% @itemize
%% @item @code{sympref ipc popen2}: force popen2 choice.
%% @item @code{sympref ipc native}: use the @code{py} interface to
%% interact directly with an embedded Python interpreter, e.g.,
%% provided by the Octave Pythonic package.
%% @item @code{sympref ipc system}: construct a long string of
%% the command and pass it directly to the python interpreter with
%% the @code{system()} command.  This typically assembles a multiline
%% string for the commands, except on Windows where a long one-line
%% string is used.
%% @item @code{sympref ipc systmpfile}: output the python commands
%% to a file in @code{tempdir} and then call that.
%% For debugging, will not be supported long-term.
%% @item @code{sympref ipc sysoneline}: put the python commands all
%% on one line and pass to @code{python -c} using a call to @code{system()}.
%% For debugging, will not be supported long-term.
%% @end itemize
%%
%% Except for @code{native}, all of these communication interfaces
%% depend on the current @strong{Python executable}, which can be queried:
%% @example
%% @comment doctest: +SKIP
%% sympref python
%%   @result{} ans = python
%% @end example
%% Changing this might help if you've installed
%% a local Python interpreter somewhere else on your system.
%% The value can be changed by setting the environment variable
%% @code{PYTHON}, which can be configured in the OS, or it can be
%% set within Octave using:
%% @example
%% @comment doctest: +SKIP
%% setenv PYTHON python3
%% setenv PYTHON $@{HOME@}/.local/bin/python
%% setenv PYTHON C:\Python\python.exe
%% sympref reset
%% @end example
%% If the environment variable is empty or not set, the package
%% uses a default setting (often @code{python}).
%%
%%
%% @strong{Reset}: reset the SymPy communication mechanism.  This can be
%% useful after an error occurs and the connection with Python
%% becomes confused.
%%
%% @example
%% @group
%% sympref reset                              % doctest: +SKIP
%% @end group
%% @end example
%%
%%
%% @strong{Default precision}: control the number of digits used by
%% variable-precision arithmetic (see also the @ref{digits} command).
%%
%% @example
%% @group
%% sympref digits          % get
%%   @result{} ans = 32
%% sympref digits 64       % set
%% sympref digits default
%% @end group
%% @end example
%%
%% Be @strong{quiet} by minimizing startup and diagnostics messages:
%% @example
%% @group
%% sympref quiet
%%   @result{} ans = 0
%% sympref quiet on
%% sympref quiet default
%% @end group
%% @end example
%%
%% Report the @strong{version} number:
%%
%% @example
%% @group
%% sympref version
%%   @result{} 3.1.1+
%% @end group
%% @end example
%%
%% @seealso{sym, syms}
%% @end deftypefn

function varargout = sympref(cmd, arg)

  persistent settings

  if (isempty(settings))
    settings = 42;
    sympref('defaults')
  end

  if (nargin == 0)
    varargout{1} = settings;
    return
  end

  if (isstruct (cmd))
    assert (isequal (sort (fieldnames (cmd)), ...
      sort ({'ipc'; 'display'; 'digits'; 'quiet'})), ...
      'sympref: structure has incorrect field names')
    settings = [];
    sympref ('quiet', cmd.quiet)
    sympref ('display', cmd.display)
    sympref ('digits', cmd.digits)
    sympref ('ipc', cmd.ipc)
    return
  end

  switch lower(cmd)
    case 'defaults'
      settings = [];
      settings.ipc = 'default';
      sympref ('display', 'default')
      sympref ('digits', 'default')
      sympref ('quiet', 'default')

    case 'version'
      assert (nargin == 1)
      varargout{1} = '3.1.1+';

    case 'display'
      if (nargin == 1)
        varargout{1} = settings.display;
      else
        arg = lower (arg);
        if (strcmp (arg, 'default'))
          arg = 'unicode';
          if (ispc () && (~isunix ()))
            % Unicode not working on Windows, Issue #83.
            arg = 'ascii';
          end
        end
        assert(strcmp(arg, 'flat') || strcmp(arg, 'ascii') || ...
               strcmp(arg, 'unicode'))
        settings.display = arg;
      end

    case 'digits'
      if (nargin == 1)
        varargout{1} = settings.digits;
      else
        if (ischar(arg))
          if (strcmpi(arg, 'default'))
            arg = 32;
          else
            arg = str2double(arg);
          end
        end
        arg = int32(arg);
        assert(arg > 0, 'precision must be positive')
        settings.digits = arg;
      end

    case 'snippet'
      warning ('OctSymPy:deprecated', ...
               'Debugging mode "snippet" has been removed');

    case 'quiet'
      if (nargin == 1)
        varargout{1} = settings.quiet;
      else
        if (strcmpi(arg, 'default'))
          settings.quiet = false;
        else
          settings.quiet = tf_from_input(arg);
        end
      end

    case 'python'
      if (nargin ~= 1)
        error('old syntax ''sympref python'' removed; use ''setenv PYTHON'' instead')
      end
      pyexec = getenv('PYTHON');
      if (isempty(pyexec))
        pyexec = defaultpython ();
      end
      varargout{1} = pyexec;

    case 'ipc'
      if (nargin == 1)
        varargout{1} = settings.ipc;
      else
        verbose = ~sympref('quiet');
        sympref('reset')
        settings.ipc = arg;
        switch arg
          case 'default'
            msg = 'Choosing the default [autodetect] communication mechanism';
          case 'native'
            msg = 'Forcing the native Python/C API communication mechanism';
          case 'system'
            msg = 'Forcing the system() communication mechanism';
          case 'popen2'
            msg = 'Forcing the popen2() communication mechanism';
          case 'systmpfile'
            msg = 'Forcing systmpfile ipc: warning: this is for debugging';
          case 'sysoneline'
            msg = 'Forcing sysoneline ipc: warning: this is for debugging';
          otherwise
            msg = '';
            if (~ ischar (arg))
              arg = num2str (arg);
            end
            warning('OctSymPy:sympref:invalidarg', ...
                    'Unsupported IPC mechanism ''%s'': hope you know what you''re doing', ...
                    arg)
        end
        if (verbose)
          disp(msg)
        end
      end

    case 'reset'
      verbose = ~sympref('quiet');
      python_ipc_driver('reset', []);

    %case 'path'
      %pkg_path = fileparts (mfilename ('fullpath'));
      % or
      %pkg_l = pkg ('list');
      %idx = strcmp ('octsympy', cellfun (@(x) x.name, pkg_l, 'UniformOutput', false));
      %if (~ any (idx))
      %  error ('the package %s is not installed', your_pkg);
      %end
      %pkg_path = pkg_l{idx}.dir

    case 'diagnose'
      if (strcmp (lower (sympref ('ipc')), 'default') && ...
          exist ('pyversion') && exist ('pyexec') && exist ('pyeval'))
        % TODO: see note in ipc_native
        assert_pythonic_and_sympy (true)
      else
        assert_have_python_and_sympy (sympref ('python'), true)
      end

    otherwise
      error ('sympref: invalid preference or command ''%s''', lower (cmd));
  end
end

function r = tf_from_input(s)

  if (~ischar(s))
    r = logical(s);
  elseif (strcmpi(s, 'true'))
    r = true;
  elseif (strcmpi(s, 'false'))
    r = false;
  elseif (strcmpi(s, 'on'))
    r = true;
  elseif (strcmpi(s, 'off'))
    r = false;
  elseif (strcmpi(s, '[]'))
    r = false;
  else
    r = str2double(s);
    assert(~isnan(r), 'invalid expression to convert to bool')
    r = logical(r);
  end
end

%!shared sympref_orig
%! sympref_orig = sympref ();

%!test
%! % test quiet, side effect of making following tests a bit less noisy!
%! sympref quiet on
%! a = sympref('quiet');
%! assert(a == 1)

%% Test for correct line numbers in Python exceptions.  These first tests
%% happen with the default ipc---usually popen2.  We don't explicitly test
%% popen2 because test suite should be portable.
%!error <line 1> pycall_sympy__ ('raise ValueError');
%!error <line 1> pycall_sympy__ ('raise ValueError', sym('x'));
%!error <line 1> pycall_sympy__ ('raise ValueError', sym([1 2 3; 4 5 6]));
%!error <line 1> pycall_sympy__ ('raise ValueError', {1; 1; 1});
%!error <line 1> pycall_sympy__ ('raise ValueError', struct('a', 1, 'b', 'word'));
%!error <line 2> pycall_sympy__ ( {'x = 1' 'raise ValueError'} );
%!error <line 3> pycall_sympy__ ( {'x = 1' 'pass' '1/0'} );
%!error <line 3> pycall_sympy__ ( {'a=1' 'b=1' 'raise ValueError' 'c=1' 'd=1'} );

%% Test for correct line error in Python exceptions.
%!error <raise ValueError> pycall_sympy__ ('raise ValueError');
%!error <raise ValueError> pycall_sympy__ ('raise ValueError', sym('x'));
%!error <raise ValueError> pycall_sympy__ ('raise ValueError', sym([1 2 3; 4 5 6]));
%!error <raise ValueError> pycall_sympy__ ('raise ValueError', {1; 1; 1});
%!error <raise ValueError> pycall_sympy__ ('raise ValueError', struct('a', 1, 'b', 'word'));
%!error <raise ValueError> pycall_sympy__ ( {'x = 1' 'raise ValueError'} );
%!error <1/0> pycall_sympy__ ( {'x = 1' 'pass' '1/0'} );
%!error <raise ValueError> pycall_sympy__ ( {'a=1' 'b=1' 'raise ValueError' 'c=1' 'd=1'} );

%!test
%! % system should work on all system, but just runs sysoneline on windows
%! sympref('ipc', 'system');
%! syms x

%!error <line 1> pycall_sympy__ ('raise ValueError')
%!error <line 1> pycall_sympy__ ('raise ValueError', sym('x'))
%!error <line 1> pycall_sympy__ ('raise ValueError', struct('a', 1, 'b', 'word'))

%!error <c=1; raise ValueError> pycall_sympy__ ({'a=1' 'b=1' 'c=1; raise ValueError' 'd=1'});

%!test
%! % sysoneline should work on all systems
%! sympref('ipc', 'sysoneline');
%! syms x

%!error <line 1> pycall_sympy__ ('raise ValueError')
%!error <line 1> pycall_sympy__ ('raise ValueError', struct('a', 1, 'b', 'word'))

%!test
%! sympref('ipc', 'systmpfile');
%! syms x

%!error <line 1> pycall_sympy__ ('raise ValueError')
%!error <line 1> pycall_sympy__ ('raise ValueError', struct('a', 1, 'b', 'word'))

%!test
%! s = warning ('off', 'OctSymPy:sympref:invalidarg');
%! sympref ('ipc', 'bogus');
%! assert (strcmp (sympref ('ipc'), 'bogus'))
%! warning (s)

%!error <invalid ipc mechanism> syms ('x')

%!test
%! sympref('defaults')
%! assert(strcmp(sympref('ipc'), 'default'))
%! sympref('quiet', 'on')

%!test
%! % restore sympref from structure
%! old = sympref ();
%! sympref ('display', 'ascii');
%! sympref ('digits', 64);
%! old = orderfields (old);  % re-ordering the fields should be ok
%! sympref (old);
%! new = sympref ();
%! assert (isequal (old, new))

%!error <incorrect field names>
%! s.a = 'hello';
%! s.b = 'world';
%! sympref (s)

%!test
%! syms x
%! sympref('reset');
%! % restore original sympref settings
%! sympref ('ipc',   sympref_orig.ipc);
%! syms x
%! sympref ('quiet', sympref_orig.quiet);

%!error <invalid preference or command> sympref ('nosuchsetting')
%!error <invalid preference or command> sympref ('nosuchsetting', true)


function outputFilename = publish_mathjax(file, opts, varargin)
    %PUBLISH_MATHJAX  Publish to HTML, and use MathJax to render equations
    %
    % ## Input
    % * __file__ M-file to publish.
    % * __opts__ Structure of options. By default this function uses a custom
    %   XSL stylesheet to publish as HTML with MathJax rendered equations, i.e
    %   `struct('format','html', 'stylesheet','mxdom2mathjax.xsl')`
    %
    % ## Output
    % * __outputFilename__ path to the generated HTML document.
    %
    % ## Options
    % Accepts the same option as the publish function.
    %
    % ## Example
    %
    %     html = publish_mathjax('my_script.m');
    %     web(html, '-browser')
    %
    %     showdemo('my_script')
    %
    % ## References
    % Inspired by a MathWorks Support Team
    % [solution](https://www.mathworks.com/matlabcentral/answers/93851).
    %
    % See also: publish, grabcode
    %

    % path to this directory
    dname = fileparts(mfilename('fullpath'));

    % HTML publish options with custom XSL
    if nargin < 2, opts = struct(); end
    opts.format = 'html';
    opts.stylesheet = fullfile(dname, 'mxdom2mathjax.xsl');

    % publish
    outputFilename = publish(file, opts, varargin{:});

    % copy CSS file to output directory
    outputCSS = fullfile(fileparts(outputFilename), 'publish_custom.css');
    if true || exist(outputCSS, 'file') ~= 2
        copyfile(fullfile(dname, 'publish_custom.css'), outputCSS);
    end
end


% SHOW_EVENTS - Display events in epochs. Events selected by
%                 MAKE_TIMEWARP function can be optionally highlighted.
%                 Each epoch is visualized as a row in the output image with
%                 events marked by colored rectangles.
%
% Usage:
%       >> im = show_events(EEG, 'key1',value1,'key2',value2,...);
%
% Inputs:
%
%   EEG                 - dataset structure.
%
%
% Optional inputs (in 'key', value format):
%
%   'eventThicknessCoef'  - (positive number) adjust the thickness of event
%                           markers in the image. The default value is 1.
%                           Lower values reduce thickness and higher values
%                           increase it. For example, to decrease event
%                           rectangle width by half, set this parameter to
%                           0.5. {default: 1}
%   'eventNames'          - a cell array containing names of events to be
%                           displayed. Order and repetition are ignored.
%                           {default: all events if timeWarp is not provided)
%
%   'timeWarp'            - a structure with latencies (time-warp matrix
%                           for newtimef function) and epochs with correct
%                           sequence created by MAKE_TIMEWARP function.
%                           the subsets {default: false|0)
% Outputs:
%
%   im                    - color (RGB) image showing events of interest in
%                           epochs.
%
% Example:
%
%   % To display all events in data structure EEG
%   >> show_events(EEG);
%
%   % To highlight events selected by MAKE_TIMEWARP function with thin
%   %  event markers
%  >> show_events(EEG, 'eventThicknessCoef', 0.5, 'eventNames', timeWarp.eventSequence,
%   'timeWarp', timeWarp);
%
% Version 1.1
% Author: Nima Bigdely Shamlo, SCCN/INC/UCSD, 2008
% See also: MAKE_TIMEWARP, NEWTIMEF

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

function  im = show_events(EEG, varargin)

%% check inputs
EEG = change_events_to_string(EEG);

inputKeyValues = finputcheck(varargin, ...
   {'eventThicknessCoef'     'real'    [0 Inf]          1; ...
    'eventNames'     'cell'    {}        {}  ; ...
    'timeWarp'        'struct'    []          struct([]); ...
    });

eventThicknessCoef = 0;
eventNames = {};
timeWarp=[];

% place key values into function workspace variables
inputKeyValuesFields = fieldnames(inputKeyValues);
for i=1:length(inputKeyValuesFields)
    eval([inputKeyValuesFields{i} '= inputKeyValues.' inputKeyValuesFields{i} ';']);
end

if length(eventNames) == 0
    if length(timeWarp) == 0
        eventNames = [];
        for i=1:length(EEG.epoch)
            eventNames =  [eventNames EEG.epoch(i).eventtype];
        end
    else
        for i=1:length(timeWarp.eventSequence)
            if ischar(timeWarp.eventSequence{i})
                eventNames = [eventNames timeWarp.eventSequence{i}];
            else % in case it is a cell of strings
                for j=1:length(timeWarp.eventSequence{i})
                    eventNames = [eventNames timeWarp.eventSequence{i}{j}];
                end
            end
        end
        %        eventNames = timeWarp.eventSequence; % if event names is not provided only show timeWarp events
    end
end

if length(timeWarp) == 0
    timeWarp=[];
    timeWarp.latencies = [];
    timeWarp.epochs = 1:length(EEG.epoch);
end
%% set image parameters

imWidth = 300*4;
imHeight = 240*4;
im = double(zeros(imHeight, imWidth, 3));

%% find latencies for events of interest in each epoch

uniqueEventNames = unique_cell_string(eventNames);
for epochNumber = 1:length(EEG.epoch)
    for eventNumber = 1:length(uniqueEventNames)
       ids = find(strcmp(EEG.epoch(epochNumber).eventtype,uniqueEventNames{eventNumber})); % index for events with this type in the current epoch
       latency{epochNumber, eventNumber} = cell2mat(EEG.epoch(epochNumber).eventlatency(ids));
    end
end

%% find a good default value for event marker width based on quantiles
% of inter-event latencies.

intervals = [];
for i=1:size(latency,1)
    intervals = [intervals diff(sort(cell2mat(latency(i,:)),'ascend'))]; %#ok<AGROW>
end

if isempty(intervals)
    eventLineWidth = 0.05*eventThicknessCoef;
else
    eventLineWidth = round(eventThicknessCoef * 0.5 * imWidth * -quantile(-intervals,0.8) /  ((EEG.xmax - EEG.xmin)*1000));
end

%% place colored rectangle block o image to display events
eventColors = lines(length(uniqueEventNames));
for epochNumber = 1:length(EEG.epoch)
    for eventNumber = 1:length(uniqueEventNames)
        for eventInstanceNumber = 1:length(latency{epochNumber, eventNumber})
            startHeight =  max(1,round((epochNumber - 1) * imHeight/ length(EEG.epoch)));
            endHeight = min(imHeight, round((epochNumber) * imHeight/ length(EEG.epoch)));
            startWidth = max(1,round(-eventLineWidth/2 + imWidth * (latency{epochNumber, eventNumber}(eventInstanceNumber) - (EEG.xmin*1000))/ ((EEG.xmax - EEG.xmin)*1000)));
            endWidth =  min(imWidth,startWidth + eventLineWidth);
            colorForEvent =  eventColorBasedOnTypeAndAcceptance(eventColors, eventNumber, epochNumber, latency{epochNumber, eventNumber}(eventInstanceNumber), timeWarp);
            for c = 1:3 % to make sure the highlighted events are not overwritten by other events in the image, we use 'max' and give the brightest color priority
                im(startHeight:endHeight,startWidth:endWidth,c) = max(im(startHeight:endHeight,startWidth:endWidth,c), colorForEvent(c));
            end
        end
    end
end

%% plot image with legend and axis labels

figure;
hold on;
for i=1:length(uniqueEventNames)
    plot([0 0],rand * [0 0],'Color',eventColors(i,:),'linewidth',10);
    uniqueEventNames{i} = strrep(uniqueEventNames{i},'_','-'); % replace _ with - so it is displayed correctly in the legend
end

legend(uniqueEventNames, 'Location', 'NorthWest');

image(round([EEG.xmin*1000 EEG.xmax*1000 ]), [1 length(EEG.epoch)],im);
xlim(round([EEG.xmin*1000 EEG.xmax*1000 ]))
ylim([1 length(EEG.epoch)])
axis normal;
xlabel('Latency', 'fontsize',16);
xlabel('Latency', 'fontsize',16);
ylabel('Epochs', 'fontsize',16);

if nargout == 0  % suppress output if not requested
    clear im ;
end

function color = eventColorBasedOnTypeAndAcceptance(eventColors, eventNumber, epochNumber, eventLatency,timeWarp)
accepted = ismember_bc(epochNumber, timeWarp.epochs);
if ~isempty(timeWarp.latencies)
    matchedEpoch = find(timeWarp.epochs ==  epochNumber);
    accepted = accepted && ~isempty(find(timeWarp.latencies(matchedEpoch,:) == eventLatency, 1));
end

color = eventColors(eventNumber,:);

if ~accepted
    color = color*0.3; % dim the color of unaccepted events.
end

function EEG = change_events_to_string(EEG)
needChange = false;
for i=1:length(EEG.event)
    if ~ischar(EEG.event(i).type)
        EEG.event(i).type = num2str( EEG.event(i).type );
        needChange = true;
    end
end

if needChange
    for e=1:length(EEG.epoch)
        for i=1:length(EEG.epoch(e).eventtype)
            EEG.epoch(e).eventtype(i) = {num2str(cell2mat(EEG.epoch(e).eventtype(i)))};
        end
    end
end


%SETLABTYPE Reset label type of dataset
%
%    A = SETLABTYPE(A,TYPE,LABELS)
%
% The label type of the dataset A is converted to TYPE ('crisp','soft' or
% 'targets'). A conversion of the dataset fields 'nlab', 'lablist' and
% 'targets' is made where necessary. If given, LABELS replaces the labels
% or targets of A.
%
% EXAMPLE
% a = prdataset(rand(10,5)); % create dataset of 10 objects and 5 features
% a = setlabtype(a,'soft',rand(10,1)); % give it random soft labels


function rev = reversePolygon(poly)
%REVERSEPOLYGON Reverse a polygon, by iterating vertices from the end
%
%   POLY2 = reversePolygon(POLY)
%   POLY2 has same vertices as POLY, but in different order. The first
%   vertex of the polygon is still the same.
%
%   Example
%   reversePolygon
%
%   See also
%   polygons2d, reversePolyline
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2009-06-30,    using Matlab 7.7.0.471 (R2008b)
% Copyright 2009 INRA - Cepia Software Platform.

rev = poly([1 end:-1:2], :);


%kMSD 'calculates mean square displacement '
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros MSD.pane file
%
% Parameters:
% InputFile: i1 'Vector input (time along Z)', required: 'First Input data object'
% OutputFile: msd 'MSD', required: 'MSD for each vector series'
% OutputFile: events 'Events', required: 'The valid number of events (i >0)'
% OutputFile: allmsd 'All MSD', required: 'Mean square deviation of all valid positions'
%
% Example: [msd, events, allmsd] = kMSD(i1, {'i1','';'msd','';'events','';'allmsd',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% MSD - calculates mean square displacement
%
%  DESCRIPTION
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1996-2003, Rainer Heintzmann,  All rights reserved.
%

function varargout = kMSD(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,..] = kMSD(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'msd', '__output';'events', '__output';'allmsd', '__output'};
maxval={0,0,0,0};
minval={0,0,0,0};
istoggle=[0,0,0,0];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile','OutputFile','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=3; 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 'msd"  -k'],Inputs,narglist);


function [ML,MU] = munu_m_d
%
%  Deletes the global data that has been generated by 'munu_m_i'.
%
%  Calling sequence:
%
%    munu_m_d
%    [ML,MU] = munu_m_d
%
%  Output:
%
%    ML, MU      LU factors of M
%
%  ML and MU are returned just in case the LU factors of M are needed for some
%  reason after the computation is done, but have been deleted to save memory.
%
%
%  LYAPACK 1.0 (Thilo Penzl, September 1999)

global LP_ML LP_MU LP_N LP_M

if nargout==1
  ML = LP_ML;
  MU = LP_MU;
end

clear global LP_ML LP_MU LP_N LP_M


 function mass = xray_read_atomic_mass(mtype, varargin)
%function mass = xray_read_atomic_mass(mtype)
%|
%| Read atomic mass for a given material type.
%|
%| in
%|	mtype			'aluminum', 'copper', 2, '2', '02-helium', ...
%|				See xray_material_file_name.m
%|		(Optionally mtype can be a cell array of several materials.
%|		If so, kev_in is mandatory and the output will be an array.)
%|
%| out
%|	mass	[M 1]	atomic mass
%|
%| Copyright 2008-04-27, Jeff Fessler, The University of Michigan

% default is to show example
if nargin < 1, ir_usage, end
if nargin == 1 && streq(mtype, 'test'), xray_read_atomic_mass_test, return, end

if isnumeric(mtype) && length(mtype) > 1
	mtype = num2cell(mtype);
end

if iscell(mtype)
	mass = zeros(size(mtype)); % array
	for ll=1:length(mtype)
		mass(ll) = xray_read_atomic_mass(mtype{ll}, varargin{:});
	end
return
end

% defaults
arg.units = '';
arg = vararg_pair(arg, varargin);

% trick: mass file near is near material file, and name parsing
if isnumeric(mtype)
	file = xray_material_file_name(1); % trick to allow z > 92
	zz = mtype; % atomic number
else
	file = xray_material_file_name(mtype);

	% atomic number:
	zz = regexprep(file, '/.*\/', '');
	zz = regexprep(zz, '-.*', '');
	zz = str2num(zz);
end

% atomic mass file
file = regexprep(file, 'element.*', 'atomic-mass/atomic-mass-list');

tmp = load_ascii_skip_header(file); % read uncommented lines
if zz < 1 || zz > length(tmp)
	fail('bad element %d', zz)
end
tmp = tmp(zz,:);
if tmp(1) ~= zz, fail('bug %d', zz), end

mass = tmp(2);

% xray_read_atomic_mass_test()
% example usage
function xray_read_atomic_mass_test
mtypes = {'lead', 2, '02-helium'};
mass = xray_read_atomic_mass(mtypes);

zz = 1:118;
mass = xray_read_atomic_mass(zz);
if im
	plot(zz, zz ./ mass, '-o')
	xlabel 'Z'
	ylabel 'Z/A'
%	ir_savefig fig-z-a
end


function data_num = p01_data_num ( )

%*****************************************************************************80
%
%% P01_DATA_NUM returns the number of data points for problem p01.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 August 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer DATA_NUM, the number of data points.
%
  data_num = 18;

  return
end


classdef Controller < handle
%% CONTROLLER is a template for all user-defined controllers.
%
% controller Properties:
%   type            - Name of the controller
%   state_estimate  - Current estimate of the robot's state
%   prev_ticks      - Previous tick count on the left and right wheels
%
% controller Methods:
%   execute         - Executes the control loop (one iteration).
%   update_odometry - Approximates the location of the robot.
%   uni_to_diff     - Converts from unicycle to differential drive model.
%   deg2rad         - Converts from degrees to radians.

    properties
        %% PROPERTIES Controller memory banks

        type                % Name of the controller
    end % properties

    methods
        %% METHODS

        function obj = Controller(type)
        %% CONTROLLER Constructor
        %   obj = controller() is the default constructor that sets the
        %   name of the controller to 'basic', the state estimate to 0, and
        %   the previous tick count to 0.

            % initialize memory banks
            obj.type = type;
        end
    end

    methods

        function outputs = execute(obj, robot, state_estimate, inputs)
        %% EXECUTE Executes the control loop (one iteration).
        %   [...] = obj.execute(robot, ...) is called by the supervisor once every
        %   iteration. This function should compute the control for one
        %   time step only.
        %
        %   This function accepts a variable number of input and output
        %   arguments that allow the user to define any set of inputs and
        %   outputs for the control loop.
            outputs = [];
        end

        function reset(obj)

        end

    end % methods

end


%GET_BOUNDARY_LAYERS Find boundary layers.
%
%   [ BL ] = GET_BOUNDARY_LAYERS( FEA, IND_BL, HL, NL, AR, ARG )
%   Find boundary layers in FEA struct and return the struct BL
%   with the following fields for connected wall boundaries
%
%       boundaries - list of boundaries in layer
%       svertices  - list of single vertices in layer
%       sedges     - list of single edges in layer (only 3D)
%       gmsh       - gmsh boundary field
%
%   The optional array IND_BL is used to override automatic detection
%   of wall boundaries (boundary condition selection 1 for
%   Navier-Stokes, swirl flow, Brinkman equations, and fluid-structure
%   interation physics modes). If IND_BL is empty layers for all
%   boundaries will be returned.
%
%   The optional numerical arguments HL, NL (default 5), and AR
%   (default 1.2) specifies the layer height, number of cells in
%   layer, and aspect ratios for gmsh output.
%
%   ARG is an optional struct to give parameters for Gmsh boundary
%   layer generation with the fields hmax, hmaxb, and thmax (default 5*pi/3).

% Copyright 2013-2022 Precise Simulation, Ltd.


function [data,grd]=nj_tslice(ncRef,var,iTime,level)
% NJ_TSLICE - Get data and coordinates from CF-compliant dataset at specific time and level
% Usage:
%   [data,grd_temp]=nj_tslice(ncRef,var,[iTime],[level]);
% Inputs:
%   ncRef = OpenDAP Data URL, Local file, or existing 'ncgeodataset' object
%   var - variable to slice
%   iTime = time step to extract data. Use inf or -1 for last time step.
%   level = vertical level (if not supplied, volume data is retrieved). Use
%           inf or -1 for last level.
% Outputs:
%   data = data  - matlab array
%   grd_temp  = structure containing lon,lat,z,time (Matlab datenum)
% Example:
%   uri ='http://geoport.whoi.edu/thredds/dodsC/examples/bora_feb.nc';% NetCDF/OpenDAP/NcML file
%   [data,grd_temp]=nj_tslice(uri,'temp',2, 14); % get level 14 at time step 2
%   [data,grd_temp]=nj_tslice(uri,'temp',2); % get 3D data at time step 2
%   [data,grd_temp]=nj_tslice(uri,'h'); % Retrieve 2D non time dependent array
%
% NCTOOLBOX (https://github.com/nctoolbox/nctoolbox)

if nargin < 2, help(mfilename), return, end
try
  if (isa(ncRef, 'ncgeodataset')) %check for ncgeodataset object
    nc = ncRef;
  else
    % open CF-compliant dataset as ncgeodataset object
    nc = ncgeodataset(ncRef);
  end
  gvar = nc.geovariable(var); %get geovariable object
  switch nargin
    case 2  % return 2D or 3D data (z,lat,lon) for all times (could be huge)
      data = squeeze(gvar.data(:,:,:,:));
      if nargout==2,
        grd_temp = gvar.grid_interop(:,:,:,:);
        grd_temp.z = squeeze(grd_temp.z);
      end
    case 3  % return 2D or 3D data at a specific time
      a=size(gvar);
      if (isinf(iTime) || iTime == -1)
        iTime=a(1);  % assumes time is 1st dimension
      end
      data = squeeze(gvar.data(iTime,:,:,:));
      if nargout==2,
        grd_temp = gvar.grid_interop(iTime,:,:,:);
        grd_temp.z = squeeze(grd_temp.z);
      end
    case 4 % return a single 2D at a specific time and layer
      a=size(gvar);
      if (isinf(iTime) || iTime == -1)
        iTime=a(1);  % assumes time is 1st dimension
      end
      if (isinf(level) || level == -1)
        level=a(2);  % assumes level is 2nd dimension
      end
      data = squeeze(gvar.data(iTime,level,:,:));
      if nargout==2,
        grd_temp = gvar.grid_interop(iTime,level,:,:);
        grd_temp.z = squeeze(grd_temp.z);
      end
  end
  try
      grd.lat = grd_temp.lat;
  end
  try
      grd.lon = grd_temp.lon;
  end
  try
      grd.z = grd_temp.z;
  end
  try
      grd.time = grd_temp.time;
  end
catch ME
  ME.message
end


IN_DIR = 'images/stacked';
OUT_DIR = 'images/detected';
mkdir(OUT_DIR);
N = 88;

for i = 1 : N
    fn = sprintf('%s/%d.jpg', IN_DIR, i);
    I = imread(fn);
    detectEllipses(I);
    saveas(gcf, sprintf('%s/%d.png', OUT_DIR, i));
    close;
end


data       = coder.load('GEN_initData.mat');
N          = data.N;
xDim       = data.dim.x;
uDim       = data.dim.u;

% global variable
global ParNMPCGlobalVariable
globalVariable = {'ParNMPCGlobalVariable',coder.Constant(ParNMPCGlobalVariable)};

cfg = coder.config('lib');
cfg.FilePartitionMethod = 'SingleFile';
cfg.EnableOpenMP = true;
cfg.TargetLang = 'C++';
stackUsageMax = (xDim+uDim)*N/360*200000;
cfg.StackUsageMax = stackUsageMax;
cfg.BuildConfiguration = 'Faster Runs';
cfg.EnableMemcpy  = true;
cfg.GenerateExampleMain = 'GenerateCodeOnly';
cfg.GenCodeOnly = true;
cfg.SupportNonFinite = false;
cfg.CustomInitializer = 'iiwa14_init();';      % init function
clear NMPC_Solve

myCCompiler = mex.getCompilerConfigurations(cfg.TargetLang,'Selected');
if ~strcmp(myCCompiler.Manufacturer,'Microsoft')
        cfg.PostCodeGenCommand = 'buildInfo.addLinkFlags(''-fopenmp'')';
end

codegen  -config cfg Simu_Matlab -globals globalVariable


function matRad_progress(currentIndex, totalNumberOfEvaluations)
% matRad progress bar
%
% call
%   matRad_progress(currentIndex, totalNumberOfEvaluations)
%
% input
%   currentIndex:               current iteration index
%   totalNumberOfEvaluations:   maximum iteration index
%
% output
%   graphical display of progess. make sure there is no other output
%   written during the loop to prevent confusion
%
% References
%   -
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2015 the matRad development team.
%
% This file is part of the matRad project. It is subject to the license
% terms in the LICENSE file found in the top-level directory of this
% distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part
% of the matRad project, including this file, may be copied, modified,
% propagated, or distributed except according to the terms contained in the
% LICENSE file.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% If it's not the first step, erase the stuff printed before
if (currentIndex == 1)
    fprintf('Progress: ');
end

if (currentIndex > 1)
  Length = numel(sprintf('%3.2f %%',(currentIndex-1)/totalNumberOfEvaluations*100));
  fprintf(repmat('\b',1,Length));
end

% Print the progress tool
fprintf('%3.2f %%',currentIndex/totalNumberOfEvaluations*100);

% After the last iteration print a newline command
if (currentIndex == totalNumberOfEvaluations)
    fprintf('\n');
end

end


function [ h, hmin, hmax ] = p04_stepsize ( option )

%*****************************************************************************80
%
%% P04_STEPSIZE returns step sizes for problem 4.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer OPTION, the option index.
%
%    Output, real H, HMIN, HMAX, suggested values for the
%    initial step, the minimum step, and the maximum step.
%
  h =     0.300;
  hmin =  0.001;
  hmax = 25.000;

  return
end


function [ y1, m1, d1, h1, n1, s1, y2, m2, d2, h2, n2, s2 ] = ymdhms_swap ( ...
  y1, m1, d1, h1, n1, s1, y2, m2, d2, h2, n2, s2 )

%*****************************************************************************80
%
%% YMDHMS_SWAP swaps the data defining two YMDHMS dates.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, integer Y1, M1, D1, H1, M1, S1, the first date.
%
%    Input/output, integer Y2, M2, D2, H2, M2, S2, the second date.
%
  tt = y1;
  y1 = y2;
  y2 = tt;

  tt = m1;
  m1 = m2;
  m2 = tt;

  tt = d1;
  d1 = d2;
  d2 = tt;

  tt = h1;
  h1 = h2;
  h2 = tt;

  tt = n1;
  n1 = n2;
  n2 = tt;

  tt = s1;
  s1 = s2;
  s2 = tt;

  return
end


% takes a 3D matrix and returns a cell with length equal to the length of
% the third dimension of the matrix.
function X = lastdim2cell(Y)
X = arrayfun(@(t) Y(:,:,t), 1:size(Y,3), 'uniformoutput', false);
end


function s=xticksi(ah)
%XTIXKSI labels the x-axis of a plot using SI multipliers S=(AH)
%
%  Inputs:  AH       axis handle [default: current axes]
%
% Outputs:  S        optional global SI multiplier (see usage below)
%
% Usage:   (1) plot(...);
%              xticksi;
%
%          (2) plot(...);
%              xlabel(['Frequency (' xticksi 'Hz)']);
%
% The first form will label the tick marks on the x-axis of the current plot
% using SI multipliers where appropriate. This is particularly useful for log
% plots which MATLAB does not label very well.
% The second form will, if possible, use a single SI multiplier for all the tick
% marks; this global multiplier can be incorporated into the axis label as shown.

%	   Copyright (C) Mike Brookes 2009
%      Version: $Id: xticksi.m,v 1.2 2010/01/02 20:02:58 dmb Exp $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~nargin
    ah=gca;
end
if nargout
s=xyzticksi(1,ah);
else
    xyzticksi(1,ah);
end


function[variables] = replaceVariables(obj, variables)
% [variables] = replaceVariables(obj, variables)
%
% Replace all default variables (x\d+) with free variables.
%
% Copyright by Holger Caesar, 2015

for i = 1 : numel(variables),
    oldVariable = variables{i};

    if regexp(oldVariable, 'x\d+'),
        freeVariable = getFreeVariable(obj);
        variables{i} = freeVariable;
    end;
end;


function PlotInterElem(vert,intpt)

scatter3(vert(1,1),vert(1,2),vert(1,3),'k');
hold on

scatter3(vert(2,1),vert(2,2),vert(2,3),'k');
scatter3(vert(3,1),vert(3,2),vert(3,3),'k');
scatter3(vert(4,1),vert(4,2),vert(4,3),'k');

if size(intpt,1) == 3
    scatter3(intpt(1,1),intpt(1,2),intpt(1,3),'r');
    scatter3(intpt(2,1),intpt(2,2),intpt(2,3),'b');
    scatter3(intpt(3,1),intpt(3,2),intpt(3,3),'m');
elseif size(intpt,1) == 4
    scatter3(intpt(1,1),intpt(1,2),intpt(1,3),'k');
    scatter3(intpt(2,1),intpt(2,2),intpt(2,3),'b');
    scatter3(intpt(3,1),intpt(3,2),intpt(3,3),'k');
    scatter3(intpt(4,1),intpt(4,2),intpt(4,3),'y');
end

axis equal

hold off


function y=unique_and_sort(x,sortopts)
% Unique() function that ignores NaNs in arrays and empty values as well as 'NA' in
% cellstrs, and sorts according to sortopts

%For unique() options
persistent old_matlab_2012
if isempty(old_matlab_2012)
    old_matlab_2012=verLessThan('matlab','7.14');
end

%For iscategorical()
persistent old_matlab_2013
if isempty(old_matlab_2013)
    old_matlab_2013=verLessThan('matlab','8.2');
end

%Create unique in original order
if old_matlab_2012
    [y,ia,~]=unique(x);
    [~,ind]=sort(ia); %Trick to get the original order in older matlab versions
    y=y(ind);
else
    y = unique(x,'stable'); %we keep the original order
end

%Clean up uniques
if ~iscell(x)
    if ~old_matlab_2013 && ~iscategorical(y)
        y(isnan(y)) = []; % remove all nans
    end
else
    y(strcmp(y,'NA'))=[]; %remove all 'NA'
    y(strcmp(y,''))=[]; %remove all ''
end

%Apply sorting options
if numel(sortopts)>1 %Custom ordering
    y=sort(y);%Sort first

    sortopts=shiftdim(sortopts);
    %If correct lengt and we have integers and all numbers from 1 to N are there we probably have indices
    if length(sortopts)==length(y) && isnumeric(sortopts) && sum(sort(sortopts)==(1:length(y))')==numel(y)
        disp('ordering given as indices')
        y=y(sortopts);
    else
        disp('ordering given as values')
        try
            %This should work whatever the lengths of either array
            [present,order]=ismember(sortopts,y);
            y=y(order(present));
        catch
            warning('Improper ordering values')
        end
    end

else %Other orderings
    switch sortopts
        case 1
            y=sort(y); %default
        case -1
            y=flipud(sort(y)); %We use flipud instead of the 'descend' option because somehow it isn't supported for cellstr.
    end
    %case 0 does nothing (keep original ordering)
end

end


function engine = var_elim_inf_engine(bnet, varargin)
% VAR_ELIM_INF_ENGINE Variable elimination inference engine
% engine = var_elim_inf_engine(bnet)
%
% For details on variable elimination, see
% - R. Dechter, "Bucket Elimination: A Unifying Framework for Probabilistic Inference", UA1 96, pp. 211-219.
% - Z. Li and B. D'Ambrosio, "Efficient inference in Bayes networks as a combinatorial
%     optimization problem", Intl. J. Approximate Reasoning, 11(1):55-81, 1994
% - R. McEliece and S. M. Aji, "The Generalized Distributive Law", IEEE Trans. Inform. Theory, 46(2), 2000

% This is where we will store the results between enter_evidence and marginal_nodes
engine.evidence = [];

engine = class(engine, 'var_elim_inf_engine', inf_engine(bnet));


function rgb = yellow

% returns a predefined color as [red green blue] values
%
% skin_surface         = [255 213 119]/255;
% outer_skull_surface  = [140  85  85]/255;
% inner_skull_surface  = [202 100 100]/255;
% cortex = [255 213 119]/255;
% black  = [0   0   0  ]/255;
% white  = [255 255 255]/255;
% red    = [255 0   0  ]/255;
% green  = [0   192 0  ]/255;
% blue   = [0   0   255]/255;
% yellow = [255 255 0  ]/255;
% cortex_light = [199 194 169]/255;
% cortex_dark  = [100 97 85]/255;

rgb = [255 255 0  ]/255;


function cMap=wcbp(varargin)

switch nargin
    case 0
        n=250;
    case 1
        n=varargin{1};
end

cPink=[220 000 163];
cBlue=[0 0 204];
cCyan=[0 160 160];

cMap=[255*ones(1,3);...
    120*ones(1,3);...
    cCyan;...
    cBlue;...
    cPink/1.5;...
    cPink;]./255;

[cMap]=resampleColormap(cMap,n);

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


function value = p09_autonomous ( )

%*****************************************************************************80
%
%% P09_AUTONOMOUS reports whether problem P09 is autonomous.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer VALUE, is 1 if the equation is autonomous.
%
  value = 1;

  return
end


function y = nnz(x)
% Octave treats ranges specially to save memory: https://www.gnu.org/software/octave/doc/v4.2.0/Ranges.html
% When applying `nnz` to a range an error occurs. It seems to be solved by linearizing the input (that is,
% applying index `(:)`). That probably turns the range into an actual column vector
y = builtin('nnz', x(:));
end


% Copyright 2019 Jonas Koenemann, Moritz Diehl, University of Freiburg
% Redistribution is permitted under the 3-Clause BSD License terms. Please
% ensure the above copyright notice is visible in any derived work.
%
function startup(in)
  % ocl.utils.startup(workingDirLocation)
  %
  % Startup script for OpenOCL
  % Adds required directories to the path. Sets up a folder for the results
  % of tests and a folder for autogenerated code.
  %
  % inputs:
  %   workingDirLocation - path to location where the working directory
  %                        should be created.

  ocl_dir  = fileparts(which('ocl'));

  if isempty(ocl_dir)
    ocl.utils.error('Can not find OpenOCL. Add root directory of OpenOCL to the path.')
  end

  workspaceLocation = fullfile(ocl_dir, 'Workspace');

  if nargin == 1 && ischar(in)
    workspaceLocation = in;
  elseif nargin == 1
    ocl.utils.error('Invalid argument.')
  end

  % create folders for tests and autogenerated code
  testDir     = fullfile(workspaceLocation,'test');
  exportDir   = fullfile(workspaceLocation,'export');
  [~,~] = mkdir(testDir);
  [~,~] = mkdir(exportDir);

  % set environment variables for directories
  setenv('OPENOCL_PATH', ocl_dir)
  setenv('OPENOCL_TEST', testDir)
  setenv('OPENOCL_EXPORT', exportDir)
  setenv('OPENOCL_WORK', workspaceLocation)

  % setup directories
  addpath(ocl_dir)
  addpath(exportDir)

  addpath(fullfile(ocl_dir,'doc'))

  if ~exist(fullfile(ocl_dir,'Lib','casadi'), 'dir')
    r = mkdir(fullfile(ocl_dir,'Lib','casadi'));
    ocl.utils.assert(r, 'Could not create directory in Lib/casadi');
    casadiFound = false;
  else
    % check if casadi is already installed
    addpath(fullfile(ocl_dir,'Lib'))
    addpath(fullfile(ocl_dir,'Lib','casadi'))
    casadiFound = checkCasadi(fullfile(ocl_dir,'Lib','casadi'));
  end

  % install casadi into Lib folder
  if ~casadiFound

    if ispc && verAtLeast('matlab','9.0')
      % Windows, >=Matlab 2016a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-windows-matlabR2016a-v3.4.5.zip';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    elseif ispc && verAtLeast('matlab','8.4')
      % Windows, >=Matlab 2014b
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-windows-matlabR2014b-v3.4.5.zip';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    elseif ispc && verAtLeast('matlab','8.3')
      % Windows, >=Matlab 2014a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-windows-matlabR2014a-v3.4.5.zip';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    elseif ispc && verAtLeast('matlab','8.1')
      % Windows, >=Matlab 2013a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-windows-matlabR2013a-v3.4.5.zip';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));

    elseif isunix && ~ismac && verAtLeast('matlab','8.4')
      % Linux, >=Matlab 2014b
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-linux-matlabR2014b-v3.4.5.tar.gz';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    elseif isunix && ~ismac && verAtLeast('matlab','8.3')
      % Linux, >=Matlab 2014a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-linux-matlabR2014a-v3.4.5.tar.gz';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));

    elseif ismac && verAtLeast('matlab','8.5')
      % Mac, >=Matlab 2015a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-osx-matlabR2015a-v3.4.5.tar.gz';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    elseif ismac && verAtLeast('matlab','8.4')
      % Mac, >=Matlab 2015a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-osx-matlabR2014b-v3.4.5.tar.gz';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    elseif ismac && verAtLeast('matlab','8.3')
      % Mac, >=Matlab 2015a
      path = 'https://github.com/casadi/casadi/releases/download/3.4.5/';
      filename = 'casadi-osx-matlabR2014a-v3.4.5.tar.gz';
      downloadCasadi(ocl_dir, path, filename, fullfile(ocl_dir,'Lib','casadi'));
    else
      ocl.utils.info(['Could not set up CasADi for you system.', ...
               'You need to install CasADi yourself and add it to your path.'])
    end
    % add Lib and Lib/casadi to path
    addpath(fullfile(ocl_dir,'Lib'))
    addpath(fullfile(ocl_dir,'Lib','casadi'))
  end

  casadiFound = checkCasadiWorking();
  if casadiFound
    ocl.utils.info('CasADi is up and running!')
  else
    ocl.utils.error('Go to https://web.casadi.org/get/ and setup CasADi.');
  end

  ocl.utils.info('OpenOCL startup procedure finished successfully.')

end

function downloadCasadi(ocl_dir, path, filename, dest)

  if exist(fullfile(dest, 'CUSTOM_CASADI'), 'file') > 0
    fprintf(['You chose to your use your custom CasADi installation. If you changed \n', ...
            'your mind delete the CUSTOM_CASADI file in %s\n'], dest);
    return;
  end

  fprintf(2,'\nYour input is required! Please read below:\n')

  confirmation = [ '\n', 'Dear User, if you continue, CasADi will be downloaded from \n', ...
                   path, filename, ' \n', ...
                   'and saved to the Workspace folder. The archive will be extracted \n', ...
                   'to the Lib folder. This will take a few minutes. \n\n', ...
                   'Hit [enter] to continue! \n\n', ...
                   'Advanced users: \n', ...
                   'If you have set-up your own CasADi version and you want to use that, you \n', ...
                   'can type `n` and hit [enter]. We will then perform some basic checks if \n', ...
                   'your version is campatible. We strongly recommend you to let OpenOCL install \n', ...
                   'the required version (if you do not save the path, the CasADi version of OpenOCL \n', ...
                   'will not be on your path at startup, and not conflict with you current CasADi \n', ...
                   'installation): '];
  m = input(confirmation,'s');

  if strcmp(m, 'n') || strcmp(m, 'no')
    try
      ocl.tests.variable;
      fid = fopen(fullfile(dest, 'CUSTOM_CASADI'),'w');
      fclose(fid);
      return;
    catch e
      warning(e.message)
      ocl.utils.error('You did not agree to download CasADi and your version is not compatible. Either run again or set-up a compatible CasADi version manually.');
    end
  end

  archive_destination = fullfile(ocl_dir, 'Workspace', filename);

  if ~exist(archive_destination, 'file')
    ocl.utils.info('Downloading...')
    websave(archive_destination, [path,filename]);
  end
  ocl.utils.info('Extracting...')
  [~,~,ending] = fileparts(archive_destination);
  if strcmp(ending, '.zip')
    unzip(archive_destination, dest)
  else
    untar(archive_destination, dest)
  end
end

function r = checkCasadi(path)

  cur_path = pwd;
  cd(path)

  if ~exist(fullfile(path,'+casadi','SX.m'),'file') > 0
    r = false;
  else
    try
      casadi.SX.sym('x');
      r = true;
    catch e
      cd(cur_path)
      ocl.utils.warning(e.message);
      casadiNotWorkingError();
    end
  end
  cd(cur_path)
end

function r = checkCasadiWorking()
  try
    casadi.SX.sym('x');
    r = true;
  catch e
    ocl.utils.warning(e.message);
    casadiNotWorkingError();
  end
end

function r = verAtLeast(software, version_number)
  r = ~verLessThan(software,version_number);
end

function casadiNotWorkingError
  ocl.utils.error(['Casadi installation not found or it does not ', ...
            'work properly. Try restarting Matlab. Remove all ', ...
            'casadi installations from your path. Run ocl.utils.clean. OpenOCL will ', ...
            'then install the correct casadi version for you.']);
end


classdef TestLineSegmentDetector
    %TestLineSegmentDetector

    properties (Constant)
        im = fullfile(mexopencv.root(),'test','blox.jpg');
    end

    methods (Static)
        function test_1
            img = cv.imread(TestLineSegmentDetector.im, ...
                'Grayscale',true, 'ReduceScale',2);
            lsd = cv.LineSegmentDetector('Refine','Advanced');

            [lines, width, prec, nfa] = lsd.detect(img);
            validateattributes(lines, {'cell'}, {'vector'});
            cellfun(@(v) validateattributes(v, {'numeric'}, ...
                {'vector', 'numel',4, 'real'}), lines);
            validateattributes(width, {'numeric'}, {'vector', 'numel',numel(lines)});
            validateattributes(prec, {'numeric'}, {'vector', 'numel',numel(lines)});
            validateattributes(nfa, {'numeric'}, {'vector', 'numel',numel(lines)});

            out = lsd.drawSegments(img, lines);
            validateattributes(out, {class(img)}, {'3d', 'size',[size(img) 3]});
        end

        function test_2
            img = cv.imread(TestLineSegmentDetector.im, ...
                'Grayscale',true, 'ReduceScale',2);
            lsd1 = cv.LineSegmentDetector('Refine','Standard');
            lsd2 = cv.LineSegmentDetector('Refine','None');
            lines1 = lsd1.detect(img);
            lines2 = lsd2.detect(img);
            [comp,c] = lsd1.compareSegments([size(img,2) size(img,1)], lines1, lines2);
            validateattributes(comp, {class(img)}, {'3d', 'size',[size(img) 3]});
            validateattributes(c, {'numeric'}, {'scalar', 'integer', 'nonnegative'});
        end
    end

end


%kckhueshift 'shifts the hues on a Hue-only (1 band) image '
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros ckhueshift.pane file
%
% Parameters:
% InputFile: i 'Input ', required: 'First Input data object'
% Double: shift 'Shift by', default: 0: 'shift float value'
% OutputFile: o 'Output', required: 'Resulting output data object'
%
% Example: o = kckhueshift(i, {'i','';'shift',0;'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% ckhueshift - shifts the hues on a Hue-only (1 band) image
%
%  DESCRIPTION
% Adds a constant value to each value on the object, correcting for circularity. This will make a "hue shift" on the object.
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
% Expects a 1-band object.
%
%  REFERENCES
% All references for the COLOR toolbox are on the $COLOR/Readme.html file.
%
%  COPYRIGHT
% Copyright (C) 1997 Rafael Santos. Khoros (C) Khoral Research, Inc.
%

function varargout = kckhueshift(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,..] = kckhueshift(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'shift', 0;'o', '__output'};
maxval={0,360,0};
minval={0,-360,0};
istoggle=[0,0,0];
was_set=istoggle * 0;
paramtype={'InputFile','Double','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 'ckhueshift"  '],Inputs,narglist);