 function ir_stem_spectrum(x, y, varargin)
%function ir_stem_spectrum(x, y, varargin)
%|
%| default spectrum style for engn 100

arg.thresh = 0;
arg.color = [0 0.5 0];
arg = vararg_pair(arg, varargin);

k = y > max(y(:)) * arg.thresh;

stem(x(k), y(k), ...
	'color', arg.color, ...
	'linewidth', 3.0, ...
	'marker', 'none')
ylabelf('amplitude')


function M1 = glassbrain_avi(fps,len,clusters)
% :Usage:
% ::
%
%    M = glassbrain_avi(fps,len,clusters)
%
% works with cluster_surf.m
% assumes a gray brain where no activation, or creates one
%
% SEE ALSO cluster_surf_movie.m, which works well too.
%
% ..
%    tor wager
% ..

dofadein = 0;
dozionimg = 0;
if isempty(clusters), doclustersurf = 0;, else, doclustersurf = 1;,end

if dozionimg
% ---------------------------------------
% Special Script
% ---------------------------------------
hh = open('Brook Zion 2.jpg');
hh = hh.Brook_Zion_2;
for i = 1:3, hh2(:,:,i) = flipud(hh(:,:,i));,end
hh = hh2;
f1 = figure('Color',[0 0 .7]); image(-size(hh,2)./2,-size(hh,1)./2,hh); hold on; axis image; axis auto
set(gca,'Color',[0 0 1],'YDir','Normal'); axis off
Ps = which('surf_single_subj_T1_gray.mat'); %'c:\tor_scripts\3DheadUtility\surf_single_subj_T1_gray.mat';
load(Ps)
 h = patch('Faces',faces,'Vertices',vertices,'FaceColor',[.5 .5 .5], ...
  'EdgeColor','none','SpecularStrength',.2,'FaceAlpha',0.01,'SpecularExponent',200);

%camzoom(3)
camzoom(1.2)
drawnow

 O = struct('name','glassZion.avi','fps',5,'length',10,'timeres',1, 'H',h, ...
    'azOffset',0,'elOffset',0,'zoom',2,'add2movie',[],'closemovie',1);

    finalTrans = .5;
    O.timecourse{1} = [0:(finalTrans/(O.fps*O.length)):finalTrans] + .01;

    M2 = make3Davi(O);  % close this one
    O.name = 'glassZion_act.avi'; O.closemovie = 0;
    camzoom(1/3); set(h,'FaceAlpha',.01);
    M1 = make3Davi(O);  % leave this one open

    axis vis3d

% ---------------------------------------
% First part: transparent brain fade-in
% ---------------------------------------
elseif dofadein
    f1 = figure('Color','w'); h = addbrain;
    view(0,90); axis off;

    set(h,'Tag','cluster1');

    O = struct('name','glassbrainX.avi','fps',fps,'length',len(1),'timeres',1, 'H',h, ...
    'azOffset',0,'elOffset',0,'zoom',1,'add2movie',[],'closemovie',0);

    finalTrans = .5;
    O.timecourse{1} = [0:(finalTrans/(O.fps*O.length)):finalTrans];
    M1 = make3Davi(O);

else

    f1 = gcf;
    h3 = get(gca,'Children');for i = 1:length(h3),h4=get(h3(i));if isfield(h4,'FaceVertexCData'),h5 = h3(i);,end,end
    h = h5; %gco;
    tmp = get(h,'FaceVertexCData'); if size(tmp,2) ~= 3 | ~(size(tmp,1) > 5000), error('Make surface object current object'),end

    O = struct('name','glassbrainX.avi','fps',fps,'length',len(1),'timeres',1, 'H',h, ...
    'azOffset',0,'elOffset',0,'zoom',1,'add2movie',[],'closemovie',0);
    M1 = avifile('glassbrainX.avi','Quality',75,'Compression','none','Fps',O.fps);

end

% ---------------------------------------
% Second part: change cluster surface
% ---------------------------------------
if doclustersurf
    cl = cat(2,clusters.Z); refZ = [0 max(cl) min(cl(cl < 0)) 0];,

    %for j = 1:length(clusters)
    %      clusters(j).origZ = clusters(j).Z;
    %  end
    %cluster_surf(clusters,h,refZ,10,{[1 0 0]},'colorscale','heatmap');

    cluster_surf(clusters,h,10,{[1 0 0]},'colorscale','heatmap');
    figure(f1)
end

% ---------------------------------------
% Second part: cluster activations
% ---------------------------------------
axis vis3d
mov = avifile('glassbrainX_act1.avi','Quality',75,'Compression','none','Fps',O.fps);

% add frames

tmp = get(h,'FaceVertexCData');
t1 = find(~(all(tmp == .5,2)));
ind = 1;

for i = [10:-1:1 1:10 10:-1:1 1:10]

    if ind > 10, ff = get(h,'FaceAlpha'); set(h,'FaceAlpha',min(1,ff+.1));, end
    fprintf(1,'%3.0f . ',i)
    M1 = get_frame(M1,i,tmp,h,t1);
    mov = addframe(mov,gca);
    ind = ind + 1;

end

mov = close(mov);

% ---------------------------------------
% Third part: tip down
% ---------------------------------------
[az,el] = view; ind = 1;
ii = repmat([10:-1:1 1:10 10:-1:1 1:10 10:-1:1 1:10],1,10);

mov = avifile('glassbrainX_act2.avi','Quality',75,'Compression','none','Fps',O.fps);

for i = 5:5:90

    view(az-2*i,el - i)

    fprintf(1,'%3.0f . ',i)
    M1 = get_frame(M1,ii(ind),tmp,h,t1);
    mov = addframe(mov,gca);

    ind = ind + 1;
    lightFollowView
end

mov = close(mov);

% ---------------------------------------
% Fourth part: spin
% ---------------------------------------
[az,el] = view; ind = 1;
ii = repmat([10:-1:1 1:10 10:-1:1 1:10 10:-1:1 1:10],1,10);

mov = avifile('glassbrainX_act3.avi','Quality',75,'Compression','none','Fps',O.fps);

for i = 0:10:360

    if i < 70
        view(az-i,el+i./2)
    elseif i == 70
        [dummy,el] = view;
        view(az-i,el)
    else
        view(az-i,el);
    end

    fprintf(1,'%3.0f . ',i)
    M1 = get_frame(M1,ii(ind),tmp,h,t1);
    mov = addframe(mov,gca);

    ind = ind + 1;
    lightFollowView
end

mov = close(mov);

M1 = close(M1);

return

% ---------------------------------------
% Alternative: Random blobs
% ---------------------------------------
n = noisevector(size(tmp,1),[1:-.1:0],1);
gray = .5 * ones(size(tmp));
set(h,'FaceVertexCData',gray);
t2 = gray;

ind = 1;
ni = find(n > 1);
 bins = round(1:length(ni)./30:length(ni));
 cols = rand(length(bins),3);
cols(:,3) = 0;

for i = 1:length(bins)-1
    whh{ind} = ni(ni > bins(i) & ni < bins(i+1)) ;
    t2(whh{ind},:) = repmat(cols(ind,:),length(whh{ind}),1);
    ind = ind+1;
end
set(h,'FaceVertexCData',t2);

function M1 = get_frame(M1,i,tmp,h,t1)

    fprintf(1,'%3.0f . ',i)
    t2 = tmp; t2(t1,:) = 2.5 .* t2(t1,:) ./ (i .^ .7); % scale down

    t2(t1,:) = t2(t1,:) + .05 * randn(length(t2(t1,1)),3); % add a little noise
        t2(t2 > 1) = 1;
        t2(t1,3) = 0;        % no blue

    t2(sum(t2,2) < .2,:) = .5;                  % replace low values with gray
    set(h,'FaceVertexCData',t2);
    drawnow

    H = gca;
    %mov = addframe(mov,H);
    M1 = addframe(M1,H);

 return


function Z = zstream(action,D)
% Compress/decompress stream of bytes using Deflate/Inflate
% FORMAT Z = zstream('C',D)
% D        - data stream to compress (converted to uint8 if needed)
% Z        - compressed data stream (uint8 vector)
% FORMAT D = zstream('D',Z)
% Z        - data stream to decompress (uint8 vector)
% D        - decompressed data stream (uint8 vector)
%__________________________________________________________________________
%
% This C-MEX file relies on:
% * miniz, by Rich Geldreich
%   http://code.google.com/p/miniz/
% Fallback Java implementation is adapted from:
% * dzip/dunzip, by Michael Kleder
%   http://www.mathworks.com/matlabcentral/fileexchange/8899
%__________________________________________________________________________
% Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging

% Guillaume Flandin
% $Id: zstream.m 6417 2015-04-21 16:03:44Z guillaume $

if exist('OCTAVE_VERSION','builtin')
    error('zstream.c not compiled - see Makefile');
end

switch upper(action)
    case 'C'
        D = typecast(D(:),'uint8');
        f = java.io.ByteArrayOutputStream();
        g = java.util.zip.DeflaterOutputStream(f);
        g.write(D);
        g.close;
        Z = typecast(f.toByteArray,'uint8');
        f.close;

    case 'D'
        import com.mathworks.mlwidgets.io.InterruptibleStreamCopier
        a   = java.io.ByteArrayInputStream(D);
        b   = java.util.zip.InflaterInputStream(a);
        isc = InterruptibleStreamCopier.getInterruptibleStreamCopier;
        c   = java.io.ByteArrayOutputStream;
        isc.copyStream(b,c);
        Z   = c.toByteArray;

    otherwise
        error('Unknown action "%s".',action);
end


% Copyright 2011 Zdenek Kalal
%
% This file is part of TLD.
%
% TLD 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.
%
% TLD 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 TLD.  If not, see <http://www.gnu.org/licenses/>.

function bb = bb_click(tld,img)
% Create

if isfield(tld,'handle')
     h = get(gca,'Children'); delete(h(1:end-1));
    set(tld.handle,'cdata',img);
else
    imshow(img);
end
text(10,10,'Define bounding box and double click inside.','color','white');
h = imrect;
p = wait(h);
bb = [p(1); p(2);p(1)+p(3); p(2)+p(4)];
% [c,r,p] = impixel(img);
% if length(c) ~= 2,
%     bb = [];
%     return;
% end
% bb = [c(1); r(1); c(2); r(2)];


function [TorF, vstr, rdate] = have_feature_pdipmopf()
%HAVE_FEATURE_PDIPMOPF  Detect availability/version info for PDIPMOPF
%
%   Feature detection function implementing 'pdipmopf' tag for HAVE_FEATURE
%   to detect availability/version of PDIPMOPF, a primal-dual interior point
%   method optimal power flow (OPF) solver included in TSPOPF.
%   (https://www.pserc.cornell.edu/tspopf)
%
%   See also HAVE_FEATURE, PDIPMOPF.

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

if have_feature('matlab') && exist('pdipmopf', 'file') == 3;
    TorF = 1;
    v = pdipmopfver('all');
    vstr = v.Version;
    rdate = v.Date;
else
    TorF = 0;
    vstr = '';
    rdate = '';
end


%CREATE TEMPLATES
%Letter
A=imread('letters_numbers\A.bmp');B=imread('letters_numbers\B.bmp');
C=imread('letters_numbers\C.bmp');D=imread('letters_numbers\D.bmp');
E=imread('letters_numbers\E.bmp');F=imread('letters_numbers\F.bmp');
G=imread('letters_numbers\G.bmp');H=imread('letters_numbers\H.bmp');
I=imread('letters_numbers\I.bmp');J=imread('letters_numbers\J.bmp');
K=imread('letters_numbers\K.bmp');L=imread('letters_numbers\L.bmp');
M=imread('letters_numbers\M.bmp');N=imread('letters_numbers\N.bmp');
O=imread('letters_numbers\O.bmp');P=imread('letters_numbers\P.bmp');
Q=imread('letters_numbers\Q.bmp');R=imread('letters_numbers\R.bmp');
S=imread('letters_numbers\S.bmp');T=imread('letters_numbers\T.bmp');
U=imread('letters_numbers\U.bmp');V=imread('letters_numbers\V.bmp');
W=imread('letters_numbers\W.bmp');X=imread('letters_numbers\X.bmp');
Y=imread('letters_numbers\Y.bmp');Z=imread('letters_numbers\Z.bmp');
%Number
one=imread('letters_numbers\1.bmp');  two=imread('letters_numbers\2.bmp');
three=imread('letters_numbers\3.bmp');four=imread('letters_numbers\4.bmp');
five=imread('letters_numbers\5.bmp'); six=imread('letters_numbers\6.bmp');
seven=imread('letters_numbers\7.bmp');eight=imread('letters_numbers\8.bmp');
nine=imread('letters_numbers\9.bmp'); zero=imread('letters_numbers\0.bmp');
%*-*-*-*-*-*-*-*-*-*-*-
letter=[A B C D E F G H I J K L M...
    N O P Q R S T U V W X Y Z];
number=[one two three four five...
    six seven eight nine zero];
character=[letter number];
templates=mat2cell(character,42,[24 24 24 24 24 24 24 ...
    24 24 24 24 24 24 24 ...
    24 24 24 24 24 24 24 ...
    24 24 24 24 24 24 24 ...
    24 24 24 24 24 24 24 24]);
save ('templates','templates')
clear all


function savestack(img, fname, varargin)
% Save a 3D image into a file or a series of files.
%
%   savestack(IMG, FNAME)
%   Saves the 3D image given in IMG into the file(s) given by FNAME.
%   IMG should be either a 3D array of grayscale or intensity values, or a
%   4D array of color values (coded as uint8).
%   FNAME is either a single file name, or a file name pattern that is used
%   to save the stack into a file series.
%
%   If file name contains '??', '##' or '%0xd' (x being an integer), then
%   the image is saved into a series of files, with increasing indices.
%
%   savestack(IMG, MAP, FNAME)
%   Saves a grayscale image together with a colormap. IMG should be a uint8
%   or uint16 image, and MAP should be a valid Matlab colormap (N-by-3
%   array coded as double, between 0 and 1)
%
%   savestack(..., FNAME, INDICES)
%   Also specifies number associated with each slice. Can be useful when
%   exporting a portion of a 3D stack, after a crop or a downsampling in Z
%   direction.
%
%   savestack(..., OPTIONS)
%   Uses options to write each slice. See imwrite to details.
%
%   savestack(..., VERBOSITY)
%   Also specifies verbosity. VERBOSITY can be either 'verbose' or 'quiet'.
%
%
%   Examples:
%     savestack(img, 'imgBundle.tif');        % save as stack
%     savestack(img, 'imgBundle???.tif');     % save as image series
%     savestack(img, 'imgBundle###.tif');     % save as image series
%     savestack(img, 'imgBundle%03d.tif');    % save as image series
%
%
%   See also:
%     readstack, imwrite
%

%   ---------
%   author: David Legland, david.legland@inra.fr
%   INRA - Cepia Software Platform
%   created the 10/09/2003.
%   http://www.pfl-cepia.inra.fr/index.php?page=slicer

%   HISTORY
%   17/02/2004 change indices of slices, to start at -00 and not at -01
%   18/10/2004 adapt to save in other formats than tif, and keeping
%       possibility to specify options
%   02/01/2005 correct bug: if save a bundle TIF on existing file,
%       remove previous file.
%   01/06/2006 allow wildcard '###', ensure more portability with
%       windows, add verbosity options
%   28/11/2008 update doc, remove unused variable 'slice'
%   30/10/2019 uses TIFF lib to accelerate write time

%% Default values

% default verbosity is true
verbose = true;

%% Process input arguments

% check number of input arguments: at least two, at most five
if nargin < 1 || nargin > 5
    error('savestack requires at least two arguments, and at most 5');
end

% image size
dim = size(img);

% check if colormap is specified
map = [];
if isnumeric(fname)
    map = fname;
    if nargin < 3
        error('Should specify file name as third input');
    end
    fname = varargin{1};
    varargin(1) = [];
end

% check for verbosity options
if ~isempty(varargin)
    var = varargin{end};
    if ischar(var)
       if strcmp(var, 'quiet') || strcmp(var, 'silent')
            verbose = false;
            varargin = varargin{1:end-1};
       end
    end
end

% check image number of dimensions
nd = length(dim);
if nd == 3
    isGrayscale = true;
    sliceIndices = 0:dim(3)-1;

elseif nd == 4
    if ~isempty(map)
        error('Can not save a 4D image array with map');
    end
    isGrayscale = false;
    sliceIndices = 0:dim(4)-1;
end

% determine optional slice indices (default: 0 -> dim(3))
if ~isempty(varargin) && isnumeric(varargin{1})
    disp('use specified slice indices');
    sliceIndices = varargin{1};
    varargin(1) = [];
end

%% Compute file name pattern

% replace wildcard '??' or '???' by wildcard '%02d' or '%03d'
pos = strfind(fname, '?');
npos = length(pos);
if npos > 0
    fname = strrep(fname, repmat('?', [1 npos]), ['%0' num2str(npos) 'd']);
end

% replace wildcard '##' or '###' by wildcard '%02d' or '%03d'
pos = strfind(fname, '#');
npos = length(pos);
if npos > 0
    fname = strrep(fname, repmat('#', [1 npos]), ['%0' num2str(npos) 'd']);
end

% binary flag indicating if the stack shouldbe save as a single file, or as
% a collection of 2D slices.
saveAsStack = ~contains(fname, '%0');

%% Save image file(s)

if saveAsStack
    % save one file containing all slices of image
    if verbose
        disp('save a stack');
    end

    % setup TIFF tags shared by all images
    tagStruct.ImageWidth = size(img, 2);
    tagStruct.ImageLength = size(img, 1);
    if isa(img, 'uint8')
        tagStruct.BitsPerSample = 8;
    elseif isa(img, 'uint16')
        tagStruct.BitsPerSample = 16;
    else
        error(['Can not manage data with class: ' class(img)]);
    end
    if isGrayscale
        tagStruct.SamplesPerPixel = 1;
        tagStruct.Photometric = Tiff.Photometric.MinIsBlack;

        % eventually update Tag structure to understand color map
        if ~isempty(map)
            tagStruct.Photometric = Tiff.Photometric.Palette;
            tagStruct.ColorMap = map;
        end
    else
        tagStruct.SamplesPerPixel = 3;
        tagStruct.Photometric = Tiff.Photometric.RGB;
    end
    tagStruct.Compression = Tiff.Compression.PackBits;
    tagStruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
    tagStruct.Software = 'MATLAB_MatImage';

    % create a TIFF file, and setup necessary tags
    t = Tiff(fname, 'w');
    setTag(t, tagStruct);

    if isGrayscale
        % save a grayscale stack

        % write first slice
        write(t, img(:,:,1));

        % append other slices
        for i = 2:dim(3)
            writeDirectory(t);
            setTag(t, tagStruct);
            write(t, img(:,:,i));
        end

    else
        % save a color stack

        % write first slice
        write(t, img(:,:,:,1));

        % append other slices
        for i = 2:dim(4)
            writeDirectory(t);
            setTag(t, tagStruct);
            write(t, img(:,:,:,i));
        end
    end

    close(t);

else
    % save a series of file, one file per slice of images
    if verbose
        disp('save slices');
    end

    % indentify the position of output file name that will contain indices
    pos = strfind(fname, '%0');
    pos = pos(end);

    % extract different parts of the file name
    basename = fname(1:pos-1);
    endname = fname(pos+4:end);

    % string format to compute image name
    % -> basename + indSlice + endName
    format = ['%s%0' fname(pos+2) 'd%s'];

    % save each slice of the image (gray-scale->3D or color->4D)
    if isGrayscale
        if isempty(map)
            % save grayscale slice images
            for i = 1:dim(3)
                index = sliceIndices(i);
                fileName = sprintf(format, basename, index, endname);
                imwrite(img(:,:,i), fileName, ...
                    'WriteMode', 'overwrite', varargin{:});
            end

        else
            % save grayscale slice images with colormap
            for i = 1:dim(3)
                index = sliceIndices(i);
                fileName = sprintf(format, basename, index, endname);
                imwrite(img(:,:,i), map, fileName, ...
                    'WriteMode', 'overwrite', varargin{:});
            end

        end
    else
        % save color slice images
        for i = 1:dim(4)
            index = sliceIndices(i);
            fileName = sprintf(format, basename, index, endname);
            imwrite(img(:,:,:,i), fileName, ...
                'WriteMode', 'overwrite', varargin{:});
        end
    end
end


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


%     NeuroSLAM System Copyright (C) 2018-2019
%     NeuroSLAM: A Brain inspired SLAM System for 3D Environments
%
%     Fangwen Yu (www.yufangwen.com), Jianga Shang, Youjian Hu, Michael Milford(www.michaelmilford.com)
%
%     The NeuroSLAM V1.0 (MATLAB) was developed based on the OpenRatSLAM (David et al. 2013).
%     The RatSLAM V0.3 (MATLAB) developed by David Ball, Michael Milford and Gordon Wyeth in 2008.
%
%     Reference:
%     Ball, David, Scott Heath, Janet Wiles, Gordon Wyeth, Peter Corke, and Michael Milford.
%     "OpenRatSLAM: an open source brain-based SLAM system." Autonomous Robots 34, no. 3 (2013): 149-176.
%
%     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/>.

[filename,pathname,fileindex] = uigetfile('*.*','Please open a video file');
dname = uigetdir('c:/','Save images to');
dname = [dname '\'];
video_info = VideoReader([pathname filename]);

LEN = 50000;
nfmt = ['%0.' num2str(length(num2str(LEN))) 'd'];
ffmt = 'png';%file format

videoFReader = vision.VideoFileReader([pathname filename]);

Frames = 0;
% Frames = 41443;
while ~isDone(videoFReader)
    Frames = Frames+1;
    disp(['Processing ' num2str(Frames) ' frame']);
    video_image = step(videoFReader);
    resizeImage = imresize (video_image, [270, 480]);
    imwrite(resizeImage,strcat(dname,num2str(Frames,nfmt),['.' ffmt]),ffmt); %save each frame
end
disp('Finised');


function kbrDisplay(model, spacing)

% KBRDISPLAY Display parameters of the KBR model.
% FORMAT
% DESC displays the parameters of the kernel based regression
% model and the model type to the console.
% ARG model : the model to display.
%
% FORMAT does the same as above, but indents the display according
% to the amount specified.
% ARG model : the model to display.
% ARG spacing : how many spaces to indent the display of the model by.
%
% SEEALSO : kbrCreate, modelDisplay
%
% COPYRIGHT : Neil D. Lawrence, 2007

% MLTOOLS

if nargin > 1
  spacing = repmat(32, 1, spacing);
else
  spacing = [];
end
spacing = char(spacing);
fprintf(spacing);
fprintf('Kernel based regression model:\n')
fprintf(spacing);
fprintf('Kernel type:\n')
kernDisplay(model.kern, length(spacing)+2)


% The COBRAToolbox: testFindRxnsFromMets.m
%
% Purpose:
%     - Tests the functionality of findRxnFromMets with all available
%     parameters
%
% Authors:
%     - Original file: Thomas Pfau Jan 2018
%

% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testFindRxnsFromMets'));
cd(fileDir);

% load model
model = getDistributedModel('ecoli_core_model.mat');

% First, find all reactions involved with 3pg
singleTestMet = model.mets{3};
involvedReacs = {'Biomass_Ecoli_core_w_GAM';'PGK';'PGM'};
consuming = involvedReacs;
producing = involvedReacs(2:3);
reacs = findRxnsFromMets(model,singleTestMet);
assert(isempty(setxor(involvedReacs,reacs)));
reacs = findRxnsFromMets(model,singleTestMet,'consumersOnly',true);
assert(isempty(setxor(consuming,reacs)));
reacs = findRxnsFromMets(model,singleTestMet,'producersOnly',true);
assert(isempty(setxor(producing,reacs)));

% now, we change the bounds of PGK to not function in the forward direction
modelChanged = changeRxnBounds(model,'PGK',0,'l');
modelChanged = changeRxnBounds(modelChanged,'PGM',0,'u');
reacs = findRxnsFromMets(modelChanged,singleTestMet,'producersOnly',true);
assert(isempty(reacs));

% now, test the same with consumers and the PGM reaction, only biomass is
% left.
modelChanged = changeRxnBounds(model,'PGM',0,'l');
modelChanged = changeRxnBounds(modelChanged,'PGK',0,'u');
reacs = findRxnsFromMets(modelChanged,singleTestMet,'consumersOnly',true);
assert(isempty(setxor(involvedReacs(1),reacs)));

% lets test 2 metabolites (2pg and 3pg)
dualTestMet = model.mets(2:3);
involvedReacs = {'Biomass_Ecoli_core_w_GAM';'ENO';'PGM';'PGK'};
consuming = involvedReacs;
producing = involvedReacs(2:4);
reacs = findRxnsFromMets(model,dualTestMet);
assert(isempty(setxor(involvedReacs,reacs)));
reacs = findRxnsFromMets(model,dualTestMet,'consumersOnly',true);
assert(isempty(setxor(consuming,reacs)));
reacs = findRxnsFromMets(model,dualTestMet,'producersOnly',true);
assert(isempty(setxor(producing,reacs)));

% test printout.
% build comparison text
res = printRxnFormula(model,'PGM');
compText = res{1}; % this is sufficient;

% create diary
diaryFile = 'RxnsFromMetTest';
diary(diaryFile)
reacs = findRxnsFromMets(model,dualTestMet,'containsAll',true,'printFlag',1);
assert(isempty(setxor({'PGM'},reacs)));
diary off
text = importdata(diaryFile);
assert(~isempty(strfind(strrep(text,'\n',''),compText)));
%cleanup
delete(diaryFile);

% test implicit printOut is silent, if no output is created
diary(diaryFile)
[reacs,forms] = findRxnsFromMets(model,dualTestMet,'containsAll',true);
diary off;
text = importdata(diaryFile);
% ITs not found in the output
assert(isempty(strfind(text,compText)));
% but is equal to printRxnFormula
assert(isequal(forms,res))
%cleanup
delete(diaryFile);

% change the directory
cd(currentDir)


function [fun,lb,ub,nlcon,cl,cu,xtype] = GetBARON(B)
%Build BARON arguments from SymBuilder Object
%
%   Called By SYMBUILDER Class

%   Copyright (C) 2012 Jonathan Currie (I2C2)

%Check object is built
if(~IsBuilt(B))
    error('Please build the object using Draft() or Build()');
end

%Check we have an objective (no good without!)
if(B.noObjs == 0)
    error('You can only get BARON arguments when you have specified an objective!');
elseif(B.noObjs > 1)
    error('You can only get BARON arguments with a single objective');
end

%Clear existing functions from memory
clear symb_grad symb_hess symb_nlcon symb_nljac symb_obj

%Objective
fun = GetAllObj(B);
%Bounds
lb = B.lb;
ub = B.ub;
%Nonlinear Constraints
opts.preallocate = false;
[nlcon,cl,cu] = GetAllCon(B,opts);
%Integer Constraints
xtype = B.xtype;


function test_bug2093

% WALLTIME 00:40:00
% MEM 3gb
% DEPENDENCY ft_read_header ft_read_data ft_read_event read_nex_header read_nex_data read_plexon_nex

% Compares output of same test NEX file from ft_read_header,
% ft_read_data, and ft_read_event using old (master branch) and new
% (nexhandling branch) versions of the FieldTrip code

testnexfile = dccnpath('/home/common/matlab/fieldtrip/data/test/original/lfp/plexon/p213parall.nex');
testmatfile = dccnpath('/home/common/matlab/fieldtrip/data/test/bug2093.mat');

%% first get output of old code
% if ~exist(testmatfile, 'file')
%   % run only once, this is to be done using FT version older than 9/9/2016,
%   % last commit before changes:  c8de94a3e13df7d10737381f1070a0d467c9bfbb
%   old.hdr = ft_read_header(testnexfile);
%   old.dat = ft_read_data(testnexfile);
%   old.evt = ft_read_event(testnexfile);
%
%   save(testmatfile, 'old')
% else
  % all future test executions with newer FT code
  load(testmatfile)
% end

%% then get output of new code
% new.hdr = ft_read_header(testnexfile);
% new.dat = ft_read_data(testnexfile);
new.evt = ft_read_event(testnexfile);

%% then compare the 2
% make sure the old header and data are identical, since I haven't changed them yet
% assert(isequal(old.hdr,new.hdr))
% assert(isequaln(old.dat,new.dat)) % data padded with NaNs should still be equal

%% make sure all old events are still present, despite adding more
assert(isequal(fieldnames(old.evt), fieldnames(new.evt)))
fnames = fieldnames(old.evt);
oldcell = cell(1,numel(fnames));
newcell = cell(1,numel(fnames));
mtnew = false(numel(new.evt),numel(fnames));
for fieldn = 1:numel(fnames)
  if ischar(old.evt(1).(fnames{fieldn})) && ...
      ischar(new.evt(1).(fnames{fieldn}))
    oldcell{fieldn} = {old.evt.(fnames{fieldn})}';
    newcell{fieldn} = {new.evt.(fnames{fieldn})}';
  else
    oldcell{fieldn} = vertcat(old.evt.(fnames{fieldn}));
    newcell{fieldn} = vertcat(new.evt.(fnames{fieldn}));
  end
  assert(isequal(class(oldcell{fieldn}), class(newcell{fieldn})))

  if ~isequal(size(oldcell{fieldn},1), numel(old.evt))
    error('This strategy won''t work.')
  end
  if ~isequal(size(newcell{fieldn},1), numel(new.evt))
    for evn = 1:numel(new.evt)
      mtnew(evn,fieldn) = isempty(new.evt(evn).(fnames{fieldn}));
    end
    if ~isequal(size(newcell{fieldn},1), sum(~mtnew(:,fieldn)))
      error('Empty fields don''t account for difference in event #s.')
    end
  end
end

oldevttable = struct2table(old.evt);
% Empty values in numeric variables cause the column to be represented as a
% cell-array when the structure is converted to a table, which is not
% supported by ismember.  The empty values should only be in the new event
% types I added support for, so they can be safely excluded from the table
% when verifying that all old event rows are contained in the new event
% data.
newrows = ~any(mtnew,2);
newevttable = table; %#ok<*AGROW>
for fieldn = 1:numel(fnames)
  if isequal(size(newcell{fieldn},1), numel(newrows))
    newevttable = [newevttable table(newcell{fieldn}(newrows,:), ...
      'VariableNames',fnames(fieldn))];
  elseif isequal(size(newcell{fieldn},1), sum(newrows))
    newevttable = [newevttable table(newcell{fieldn}, ...
      'VariableNames',fnames(fieldn))];
  else
    error('There may be different empty cells in different event fields.')
  end
end

assert(all(ismember(oldevttable,newevttable)))
disp('All old events found in new event output.')


function [] = ResumeExperiment( jobID, taskID, Niter )
%INPUT
%  jobID : integer/name of job
%  taskID : integer/name of task
%  Niter  : # iterations of MCMC

resumeBPHMM( {jobID, taskID}, {'Niter', Niter}, {'jobID', jobID, 'taskID', taskID} );


function res = arg_nogui(varargin)
% Like arg(), but not displayed by GUIs.
% Spec = arg_nogui(Names,Default,Range,Help,Options...)
%
% This type of function argument specifier behaves like arg(), except that it will not be displayed
% in GUIs that are generated for the function. This is mainly used for optional arguments that have
% a format that is too complex to be meaningfully edited by the user (e.g. a large matrix, or a
% long cell array), or undocumented or possibly confusing (e.g. some functions have special internal
% or reserved arguments).
%
% In:
%   Names : The name(s) of the argument. At least one must be specified, and if multiple are
%           specified, they must be passed in a cell array.
%           * The first name specified is the argument's "code" name, as it should appear in the
%             function's code (= the name under which arg_define() returns it to the function).
%           * The second name, if specified, is the "Human-readable" name, which is exposed in the
%             GUIs (if omitted, the code name is displayed). For consistency with other MATLAB
%             functions it should be in CamelCase.
%           * Further specified names are aliases for the argument (e.g., for backwards
%             compatibility with older function syntaxes/parameter names).
%
%   Default : Optionally the default value of the argument; can be any data structure (default: []).
%
%   Range : Optionally a range of admissible values (default: []).
%           * If empty, no range is enforced.
%           * If a cell array, each cell is considered one of the allowed values.
%           * If a 2-element numeric vector, the two values are considered the numeric range of the
%             data (inclusive).
%
%   Help : The help text for this argument, optional. (default: '').
%
%   Options... : Optional name-value pairs to denote additional properties, same as in arg().
%
% Out:
%   Spec : A cell array, that, when called as feval(Spec{1},reptype,Spec{2}{:}), yields a
%          specification of the argument, for use by arg_define.
%
% Examples:
%   function myfunction(varargin)
%   arg_define(varargin, ...
%       arg('arg1',10,[],'Some argument.'), ...
%       arg_nogui('arg_hidden',1001,[],'Hidden argument. This one will not be displayed in a GUI; reserved for special purposes.'));
%
% See also:
%   arg, arg_norep, arg_sub, arg_subswitch, arg_subtoggle, arg_define
%
%                                Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                2010-09-24

% Copyright (C) Christian Kothe, SCCN, 2010, christian@sccn.ucsd.edu
%
% 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 should have received a copy of the GNU General Public License along with this program; if not,
% write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
% USA

if nargin == 1
    res = {'expand_arg',[varargin {[],[],[],'displayable',false}]};
elseif nargin >= 4
    res = {'expand_arg',[varargin(1:4) {'displayable',false} varargin(5:end)]};
elseif nargin == 2
    res = {'expand_arg',[varargin {[],[],'displayable',false}]};
else
    res = {'expand_arg',[varargin {[],'displayable',false}]};
end


function view3d(arg,arg2)

% view3d  Interactively rotate, zoom and pan the view of a 3-D plot
% --------------------------------------------------------------------
%
% VIEW3D ROT turns on mouse-based 3-D rotation
% VIEW3D ZOOM turns on mouse-based 3-D zoom and pan
% VIEW3D OFF turns it off
%
% VIEW3D(FIG,...) works on the figure FIG
%
% Double click to restore the original view
%
% hit "z" key over the figure to switch from ROT to ZOOM
% hit "r" key over the figure to switch from ZOOM to ROT
%
% in ROT mode:
% press and hold left mouse button to rotate about screen xy axis
% press and hold middle mouse button to rotate about screen z axis
% in ZOOM mode:
% press and hold left mouse button to zoom in and out
% press and hold middle mouse button to move the plot
%
% --------------------------------------------------------------------
% inspired from rotate3d by The MathWorks, Inc.
%
% Torsten Vogel 09.04.1999
% tv.volke@bmw.de
% tested under Matlab 5.2
% --------------------------------------------------------------------

% ---------------------------------------------- inputs --------------
if nargin == 0
   error('not enough inputs')
elseif nargin == 1
   if ishandle(arg)
      error('not enough inputs')
      return
   else
      switch(lower(arg))
      case 'rot'
         viewact(gcf,'rot')
      case 'zoom'
         viewact(gcf,'zoom')
      case 'off'
         viewact(gcf,'off')
      case 'down'
         view3dDownFcn
      case 'up'
         view3dUpFcn
      case 'keypress'
         view3dkeypressFcn
      case 'view_xy' % rotate via screen xy axis
         view3dxyFcn
      case 'view_z'  % rotate via screen z axis
         view3dzFcn
      case 'view_zoom' % zoom in and out
         view3dzoomFcn
      case 'view_pan'  % move the plot
         view3dpanFcn
      otherwise
         error('misspelled command argument')
      end
   end
elseif nargin==2
   if ~ishandle(arg)
      error('bad figure handle')
   end
   switch(lower(arg2))
   case 'rot'
      viewact(arg,'rot')
   case 'zoom'
      viewact(arg,'zoom')
   case 'off'
      viewact(arg,'off')
   otherwise
      error('misspelled command argument')
   end
end

% ---------------------------------------------- activation ----------
function viewact(fig,what)

% de-/activates view3d for the given figure

view3dObj = findobj(allchild(fig),'Tag','view3dObj');

if strcmp(what,'rot')
   if isempty(view3dObj)
      view3dObj = makeview3dObj(fig); %the small text box at the lower left corner
   end
   vdata = get(view3dObj,'UserData');
   vdata.what = 'rot';
   set(view3dObj,'UserData',vdata);
elseif strcmp(what,'zoom')
   if isempty(view3dObj)
      view3dObj = makeview3dObj(fig); %the small text box at the lower left corner
   end
   vdata = get(view3dObj,'UserData');
   vdata.what = 'zoom';
   set(view3dObj,'UserData',vdata);
elseif strcmp(what,'off')
   if isempty(view3dObj)
      return
   end
   vdata = get(view3dObj,'UserData');
   uirestore(vdata.uistate);
   set(fig,'KeyPressFcn',vdata.oldkeypressfcn)
   delete(view3dObj);
end

% ---------------------------------------------- view3dDownFcn -------
function view3dDownFcn

view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
mouseclick = get(gcf,'SelectionType');
if isempty(view3dObj)
   return
end
vdata = get(view3dObj,'UserData');
vdata.oldunits = get(gcf,'Units');
set(gcf,'Units','pixels');
vdata.old_pt = get(0,'PointerLocation');
%  ----------------- store or restore previous view
ViewData = get(get(gca,'zlabel'),'UserData');
if isempty(ViewData)
   ViewData = manageViewData('get_from_axes');
   set(get(gca,'zlabel'),'UserData',ViewData)
end
if strcmp(mouseclick,'open')
   manageViewData('set_axes',ViewData);
   set(gcf,'Units',vdata.oldunits)
   return
end
%  ----------------- display text box
fig_color = get(gcf,'Color');
c = sum([.3 .6 .1].*fig_color);
set(vdata.textbox,'BackgroundColor',fig_color);
if(c > .5)
   set(vdata.textbox,'ForegroundColor',[0 0 0]);
else
   set(vdata.textbox,'ForegroundColor',[1 1 1]);
end
%  ----------------- what to do?
if strcmp(vdata.what,'rot')
   if strcmp(mouseclick,'normal')
      set(vdata.textbox,'string','Screen XY Rotation');
      set(gcf,'WindowButtonMotionFcn','view3d(''view_xy'')');
      set(gcf,'Pointer','custom','pointershapecdata',pointershapes('rot'));
   elseif strcmp(mouseclick,'extend')
      set(vdata.textbox,'string','Screen Z Rotation');
      set(gcf,'WindowButtonMotionFcn','view3d(''view_z'')');
      set(gcf,'Pointer','custom','pointershapecdata',pointershapes('rot'));
   end
else
   if strcmp(mouseclick,'normal')
      set(vdata.textbox,'string','Zoom');
      set(gcf,'WindowButtonMotionFcn','view3d(''view_zoom'')');
      set(gcf,'Pointer','custom','pointershapecdata',pointershapes('zoom'));
   elseif strcmp(mouseclick,'extend')
      set(vdata.textbox,'string','Pan');
      set(gcf,'WindowButtonMotionFcn','view3d(''view_pan'')');
      set(gcf,'Pointer','custom','pointershapecdata',pointershapes('pan'));
   end
end
set(view3dObj,'UserData',vdata)
set(vdata.textbox,'visi','on')

% ---------------------------------------------- view3dUpFcn ---------
function view3dUpFcn

view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
if isempty(view3dObj)
   return
end
vdata = get(view3dObj,'UserData');
set(gcf,'WindowButtonMotionFcn','','Units',vdata.oldunits,'pointer','arrow')
set(view3dObj,'visi','off')

% ---------------------------------------------- view3dkeypressFcn ---
function view3dkeypressFcn

view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
if isempty(view3dObj)
   return
end
vdata = get(view3dObj,'UserData');
currchar = lower(get(gcf,'currentchar'));
if strcmp(currchar,'r')
   vdata.what = 'rot';
elseif strcmp(currchar,'z')
   vdata.what = 'zoom';
end
set(view3dObj,'UserData',vdata)

% ---------------------------------------------- view3dxyFcn ---------
function view3dxyFcn

view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
vdata = get(view3dObj,'UserData');
new_pt = get(0,'PointerLocation');
old_pt = vdata.old_pt;
dx = (new_pt(1) - old_pt(1))*.5;
dy = (new_pt(2) - old_pt(2))*.5;
direction = [0 0 1];
coordsys  = 'camera';
pos  = get(gca,'cameraposition' );
targ = get(gca,'cameratarget'   );
dar  = get(gca,'dataaspectratio');
up   = get(gca,'cameraupvector' );
[newPos newUp] = camrotate(pos,targ,dar,up,-dx,-dy,coordsys,direction);
set(gca,'cameraposition', newPos, 'cameraupvector', newUp);
vdata.old_pt = new_pt;
set(view3dObj,'UserData',vdata)

% ---------------------------------------------- view3dzFcn ----------
function view3dzFcn

view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
vdata = get(view3dObj,'UserData');
new_pt = get(0,'PointerLocation');
old_pt = vdata.old_pt;
dy = (new_pt(2) - old_pt(2))*.5;
camroll(gca,-dy)
vdata.old_pt = new_pt;
set(view3dObj,'UserData',vdata)

% ---------------------------------------------- view3dzoomFcn -------
function view3dzoomFcn
view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
vdata = get(view3dObj,'UserData');
new_pt = get(0,'PointerLocation');
old_pt = vdata.old_pt;
dy = (new_pt(2) - old_pt(2))/abs(old_pt(2));
camzoom(gca,1-dy)
vdata.old_pt = new_pt;
set(view3dObj,'UserData',vdata)

% ---------------------------------------------- view3dpanFcn --------
function view3dpanFcn

view3dObj  = findobj(allchild(gcf),'Tag','view3dObj');
vdata = get(view3dObj,'UserData');
new_pt = get(0,'PointerLocation');
old_pt = vdata.old_pt;
dx = (new_pt(1) - old_pt(1))/old_pt(1)*4;
dy = (new_pt(2) - old_pt(2))/old_pt(2)*4;
campan(gca,-dx,-dy,'camera')
vdata.old_pt = new_pt;
set(view3dObj,'UserData',vdata)

% ---------------------------------------------- make view3dObj ------
function view3dObj = makeview3dObj(fig)

% save the previous state of the figure window
vdata.uistate  = uisuspend(fig);
% the data structure
vdata.what     = [];
vdata.olp_pt   = [];
vdata.textbox  = [];
vdata.oldunits = [];
vdata.oldkeypressfcn = get(fig,'KeyPressFcn');
% view3dObj
view3dObj = uicontrol('style','text','parent',fig,'Units','Pixels',...
                      'Position',[2 2 130 20],'Visible','off', ...
                      'HandleVisibility','off','tag','view3dObj');
vdata.textbox  = view3dObj;
% store current view
ViewData = manageViewData('get_from_axes');
set(get(gca,'zlabel'),'UserData',ViewData);
% functions
set(fig,'WindowButtonDownFcn','view3d(''down'')');
set(fig,'WindowButtonUpFcn','view3d(''up'')');
set(fig,'WindowButtonMotionFcn','');
set(fig,'ButtonDownFcn','');
set(fig,'KeyPressFcn','view3d(''keypress'')');

set(view3dObj,'UserData',vdata);
% ---------------------------------------------- manage ViewData -----
function ViewData = manageViewData(how,data)

if nargin == 1 ; data = [];end
props = {
   'DataAspectRatio'
   'DataAspectRatioMode'
   'CameraPosition'
   'CameraPositionMode'
   'CameraTarget'
   'CameraTargetMode'
   'CameraUpVector'
   'CameraUpVectorMode'
   'CameraViewAngle'
   'CameraViewAngleMode'
   'PlotBoxAspectRatio'
   'PlotBoxAspectRatioMode'
   'Units'
   'Position'
   'View'
   'Projection'
};
if strcmp(how,'get_from_axes')
   ViewData = get(gca,props);
elseif strcmp(how,'get_stored')
   ViewData = get(get(gca,'zlabel'),'UserData');
elseif strcmp(how,'set_axes')
   set(gca,props,data)
   ViewData = [];
end
% -------------------------------------------------------------------------
% get some pointer shapes
function shape = pointershapes(arg)

if strcmp(arg,'zoom')
% -- zoom
shape=[ 2   2   2   2   2   2   2   2   2   2 NaN NaN NaN NaN NaN NaN  ;
        2   1   1   1   1   1   1   1   1   2 NaN NaN NaN NaN NaN NaN  ;
        2   1   2   2   2   2   2   2   2   2 NaN NaN NaN NaN NaN NaN  ;
        2   1   2   1   1   1   1   1   1   2 NaN NaN NaN NaN NaN NaN  ;
        2   1   2   1   1   1   1   1   2 NaN NaN NaN NaN NaN NaN NaN  ;
        2   1   2   1   1   1   1   2 NaN NaN NaN NaN NaN NaN NaN NaN  ;
        2   1   2   1   1   1   1   1   2 NaN NaN NaN   2   2   2   2  ;
        2   1   2   1   1   2   1   1   1   2 NaN   2   1   2   1   2  ;
        2   1   2   1   2 NaN   2   1   1   1   2   1   1   2   1   2  ;
        2   2   2   2 NaN NaN NaN   2   1   1   1   1   1   2   1   2  ;
      NaN NaN NaN NaN NaN NaN NaN NaN   2   1   1   1   1   2   1   2  ;
      NaN NaN NaN NaN NaN NaN NaN   2   1   1   1   1   1   2   1   2  ;
      NaN NaN NaN NaN NaN NaN   2   1   1   1   1   1   1   2   1   2  ;
      NaN NaN NaN NaN NaN NaN   2   2   2   2   2   2   2   2   1   2  ;
      NaN NaN NaN NaN NaN NaN   2   1   1   1   1   1   1   1   1   2  ;
      NaN NaN NaN NaN NaN NaN   2   2   2   2   2   2   2   2   2   2  ];
elseif strcmp(arg,'pan')
% -- pan
shape=[ NaN NaN NaN NaN NaN NaN NaN   2   2 NaN NaN NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN NaN   2   1   1   2 NaN NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN   2   1   1   1   1   2 NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN   1   1   1   1   1   1 NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN NaN   2   1   1   2 NaN NaN NaN NaN NaN NaN ;
        NaN NaN   2   1 NaN NaN   2   1   1   2 NaN NaN   1   2 NaN NaN ;
        NaN   2   1   1   2   2   2   1   1   2   2   2   1   1   2 NaN ;
          2   1   1   1   1   1   1   1   1   1   1   1   1   1   1   2 ;
          2   1   1   1   1   1   1   1   1   1   1   1   1   1   1   2 ;
        NaN   2   1   1   2   2   2   1   1   2   2   2   1   1   2 NaN ;
        NaN NaN   2   1 NaN NaN   2   1   1   2 NaN NaN   1   2 NaN NaN ;
        NaN NaN NaN NaN NaN NaN   2   1   1   2 NaN NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN   1   1   1   1   1   1 NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN   2   1   1   1   1   2 NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN NaN   2   1   1   2 NaN NaN NaN NaN NaN NaN ;
        NaN NaN NaN NaN NaN NaN NaN   2   2 NaN NaN NaN NaN NaN NaN NaN ];
elseif strcmp(arg,'rot')
% -- rot
shape=[ NaN NaN NaN   2   2   2   2   2 NaN   2   2 NaN NaN NaN NaN NaN ;
        NaN NaN NaN   1   1   1   1   1   2   1   1   2 NaN NaN NaN NaN ;
        NaN NaN NaN   2   1   1   1   1   2   1   1   1   2 NaN NaN NaN ;
        NaN NaN   2   1   1   1   1   1   2   2   1   1   1   2 NaN NaN ;
        NaN   2   1   1   1   2   1   1   2 NaN NaN   2   1   1   2 NaN ;
        NaN   2   1   1   2 NaN   2   1   2 NaN NaN   2   1   1   2 NaN ;
          2   1   1   2 NaN NaN NaN NaN NaN NaN NaN NaN   2   1   1   2 ;
          2   1   1   2 NaN NaN NaN NaN NaN NaN NaN NaN   2   1   1   2 ;
          2   1   1   2 NaN NaN NaN NaN NaN NaN NaN NaN   2   1   1   2 ;
          2   1   1   2 NaN NaN NaN NaN NaN NaN NaN NaN   2   1   1   2 ;
        NaN   2   1   1   2 NaN NaN   2   1   2 NaN   2   1   1   2 NaN ;
        NaN   2   1   1   2 NaN NaN   2   1   1   2   1   1   1   2 NaN ;
        NaN NaN   2   1   1   1   2   2   1   1   1   1   1   2 NaN NaN ;
        NaN NaN NaN   2   1   1   1   2   1   1   1   1   2 NaN NaN NaN ;
        NaN NaN NaN NaN   2   1   1   2   1   1   1   1   1 NaN NaN NaN ;
        NaN NaN NaN NaN NaN   2   2 NaN   2   2   2   2   2 NaN NaN NaN ];

end


function [ readerobj ] = open_rs_reader( filename )
%OPEN_RS_READER Intiates a reader object for RADARSAT-2 or RCM product.xml file
%
% Written by: Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

%% Read and process XML metadata
xp=javax.xml.xpath.XPathFactory.newInstance.newXPath();
domnode=xmlread(filename);
symmetry=[0 0 0];
% Because RS2/RCM XML uses a default namespace, we have to use a local-name
% query, rather than the much simpler traditional XPath query that assumes
% no namespace.  See isrs2.m for more details.
collector_name=char(xp.evaluate(['/*[local-name()=''product'']'...
    '/*[local-name()=''sourceAttributes'']'...
    '/*[local-name()=''satellite'']'], domnode));
if strcmpi(collector_name, 'RADARSAT-2')
    ia_str = 'imageAttributes';
    ipdf_str=['/*[local-name()=''product'']'...
        '/*[local-name()=''imageAttributes'']'...
        '/*[local-name()=''fullResolutionImageData'']'];
    beta_lut_str=['/*[local-name()=''product'']'...
        '/*[local-name()=''imageAttributes'']'...
        '/*[local-name()=''lookupTable''][@incidenceAngleCorrection="Beta Nought"]'];
    beta_lut_str = fullfile(fileparts(filename), char(xp.evaluate(beta_lut_str, domnode)));
    noise_str = ''; % No separate noise file for RS2
elseif strncmpi(collector_name, 'RCM', 3)
    ia_str = 'imageReferenceAttributes';
    ipdf_str=['/*[local-name()=''product'']'...
        '/*[local-name()=''sceneAttributes'']'...
        '/*[local-name()=''imageAttributes'']'...
        '/*[local-name()=''ipdf'']'];
    beta_lut_str=['/*[local-name()=''product'']'...
        '/*[local-name()=''imageReferenceAttributes'']'...
        '/*[local-name()=''lookupTableFileName''][@sarCalibrationType="Beta Nought"]'];
    beta_lut_str = fullfile(fileparts(filename), 'calibration', char(xp.evaluate(beta_lut_str, domnode)));
    noise_str=['/*[local-name()=''product'']'...
        '/*[local-name()=''imageReferenceAttributes'']'...
        '/*[local-name()=''noiseLevelFileName'']'];
    noise_str = fullfile(fileparts(filename), 'calibration', char(xp.evaluate(noise_str, domnode)));
end
lineOrder=char(xp.evaluate(['/*[local-name()=''product'']'...
    '/*[local-name()=''' ia_str ''']'...
    '/*[local-name()=''rasterAttributes'']'...
    '/*[local-name()=''lineTimeOrdering'']'],...
    domnode));
lookdir=upper(char(xp.evaluate(['/*[local-name()=''product'']'...
    '/*[local-name()=''sourceAttributes'']'...
    '/*[local-name()=''radarParameters'']'...
    '/*[local-name()=''antennaPointing'']'],...
    domnode)));
sampleOrder=char(xp.evaluate(['/*[local-name()=''product'']'...
    '/*[local-name()=''' ia_str ''']'...
    '/*[local-name()=''rasterAttributes'']'...
    '/*[local-name()=''pixelTimeOrdering'']'],...
    domnode));
symmetry(1)=xor(strcmp(lineOrder,'Decreasing'),lookdir(1)=='L');
symmetry(2)=strcmp(sampleOrder,'Decreasing');
if exist(beta_lut_str, 'file')
    betanode={xmlread(beta_lut_str)};
else
    betanode = {};
end
if exist(noise_str, 'file')
    try % Simulated RCM datasets have misformed noise XML
        betanode = {betanode{:} xmlread(noise_str)};
    end
end
meta=meta2sicd_rs_xml(domnode,betanode{:});

%% Get all files from a polarimetric collect
num_files=str2double(xp.evaluate(['count(' ipdf_str ')'],domnode));
readerobj={};
for i=1:num_files
    basepathname=fileparts(filename);
    datafilename=char(xp.evaluate([ipdf_str '[' num2str(i) ']'],domnode));
    % If format is needed, do this:
    % format=char(xp.evaluate(['/*[local-name()=''product'']'...
    %                          '/*[local-name()=''' ia_str ''']'...
    %                          '/*[local-name()=''productFormat'']']),...
    %                         domnode);
    % Return individual reader objects for each polarimetric channel
    if exist(fullfile(basepathname,datafilename),'file')
        readerobj{end+1}=open_tiff_reader_noxml(fullfile(basepathname,datafilename),symmetry);
        meta{i}.native.tiff=readerobj{end}.get_meta();
        readerobj{end}.get_meta = @() meta{i};
    end
end
end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function [lfp, spike, stm, bhv] = spass2fieldtrip(dirname, varargin)

% SPASS2FIELDTRIP reads data from a set of SPASS data files and converts
% the contents into data structures that FieldTrip understands. Note that
% dependent on the SPASS data it might be required to change some
% hard-coded parameters inside this function.
%
% Use as
%   [lfp, spike, stm, bhv] = spass2fieldtrip(dirname)
% Optionally you can specify the sample rate as key-value pairs
%  'fsample_ana' - default 1000
%  'fsample_swa' - default 32000
%
% The specified directory should contain the SPASS files, and the files should have
% the same name as the directory.
%
% The swa and sti input file are combined into the spike output structure.
% For the rest of the data it is trivial how the input and output relate.
%
% For example, if you specify
%   [lfp, spike, bhv, stm] = spass2fieldtrip('jeb012a02')
% then the following files should exist:
%   'jeb012a02/jeb012a02.ana'
%   'jeb012a02/jeb012a02.swa'
%   'jeb012a02/jeb012a02.spi'
%   'jeb012a02/jeb012a02.stm'
%   'jeb012a02/jeb012a02.bhv'
%
% Subsequently you can analyze the data in FieldTrip, or write the spike
% waveforms to a nex file for offline sorting using
%   ft_write_spike('jeb012a02_ch1.nex', spike, 'dataformat', 'plexon_nex', 'chanindx', 1)
%   ft_write_spike('jeb012a02_ch2.nex', spike, 'dataformat', 'plexon_nex', 'chanindx', 2)
%   ft_write_spike('jeb012a02_ch3.nex', spike, 'dataformat', 'plexon_nex', 'chanindx', 3)
%
% See also NUTMEG2FIELDTRIP, LORETA2FIELDTRIP, FIELDTRIP2SPSS

% Copyright (C) 2007, Robert Oostenveld
%
% $Id$

fsample_ana = ft_getopt(varargin, 'fsample_ana', 1000);
fsample_swa = ft_getopt(varargin, 'fsample_swa', 32000);

anafile = fullfile(dirname, [dirname '.ana']);
swafile = fullfile(dirname, [dirname '.swa']);
spifile = fullfile(dirname, [dirname '.spi']);
stmfile = fullfile(dirname, [dirname '.stm']);
bhvfile = fullfile(dirname, [dirname '.bhv']);

if ~exist(anafile, 'file'), ft_error('the file "%s" does not exist', anafile); end
if ~exist(swafile, 'file'), ft_error('the file "%s" does not exist', swafile); end
if ~exist(spifile, 'file'), ft_error('the file "%s" does not exist', spifile); end
if ~exist(stmfile, 'file'), ft_error('the file "%s" does not exist', stmfile); end
if ~exist(bhvfile, 'file'), ft_error('the file "%s" does not exist', bhvfile); end

% read the data
fprintf('reading %s\n', anafile); ana = read_labview_dtlg(anafile, 'int16');
fprintf('reading %s\n', swafile); swa = read_labview_dtlg(swafile, 'int16');
fprintf('reading %s\n', spifile); spi = read_labview_dtlg(spifile, 'int32');
fprintf('reading %s\n', stmfile); stm = read_labview_dtlg(stmfile, 'int32');
fprintf('reading %s\n', bhvfile); bhv = read_labview_dtlg(bhvfile, 'int32');

% determine the number of trials
ntrials = numel(bhv.data{1});

nchans = numel(ana.data)./ntrials;
ana.data = reshape(ana.data, [nchans, ntrials]);

% prepare the continuous LFP data
lfp         = [];
lfp.trial   = {};
lfp.time    = {};
lfp.label   = {};
lfp.fsample = fsample_ana;
for i=1:ntrials
  tmp = cell2mat(ana.data(:,i)')';
  lfp.trial{i} = tmp;
  lfp.time{i}  = ((1:size(tmp,2))-1)/fsample_ana;
  nsamples(i)  = length(lfp.time{i});
end
for i=1:size(ana.data,1)
  lfp.label{i,1} = sprintf('chan%d', i);
end

% the data is trial based, try to estimate the time between subsequent
% trials, or better: the time between subsequent stimuli
isi = 10^ceil(log10(max(nsamples)+1));

nchans = numel(swa.data)./ntrials;
swa.data = reshape(swa.data, [nchans, ntrials]);
spi.data = reshape(spi.data, [nchans, ntrials]);

% prepare the spike data
spike           = [];
spike.label     = {};
spike.waveform  = {}; % 1xnchans cell-array, each element contains a matrix (Nsamples X Nspikes), can be empty
spike.timestamp = {}; % 1xnchans cell-array, each element contains a vector (1 X Nspikes)
spike.unit      = {}; % 1xnchans cell-array, each element contains a vector (1 X Nspikes)
for i=1:size(swa.data,1)
  spike.label{i} = sprintf('chan%d', i);
end

nspikes = zeros(nchans, ntrials);
for i=1:nchans
  for j=1:ntrials
    nspikes(i,j) = length(swa.data{i,j});
  end
end

% reinsert the inter-trial intervals, this links both the LFP and the spike
% timestamps to a common continuous timeaxis
for j=1:nchans
  for i=1:ntrials
    spi.data{j,i} = spi.data{j,i} + (i-1)*(fsample_swa./fsample_ana)*isi;
  end
end

% convert the spike timestamps and waveforms to a FieldTrip-compatible format
for i=1:nchans
  spike.waveform{i}  = cell2mat(swa.data(i,:));
  spike.timestamp{i} = cell2mat(spi.data(i,:)')';
  spike.unit{i}      = ones(size(spike.timestamp{i}));  % since unsorted
end

% prepare the other output
stm = stm.data{1}(:);
bhv = bhv.data{1}(:);

% remember where the lfp trials are on the imaginary continuous timeaxis,
% this links both the LFP and the spike timestamps to a common continuous
% timeaxis
trl = zeros(ntrials, 3);
for i=1:ntrials
  begsample = (i-1)*isi+1;
  endsample = begsample+nsamples(i)-1;
  offset    = 0;
  trl(i,:) = [begsample endsample offset];
end

% store the header information
lfp.hdr.FirstTimeStamp = 0;
lfp.hdr.TimeStampPerSample = fsample_swa./fsample_ana;


function [engine, loglik] = enter_evidence(engine, evidence, varargin)
% ENTER_EVIDENCE Add the specified evidence to the network (jtree_unrolled_dbn)
% [engine, loglik] = enter_evidence(engine, evidence, ...)
%
% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
%
% The following optional arguments can be specified in the form of name/value pairs:
% [default value in brackets]
%
% maximize - if 1, does max-product instead of sum-product [0]
% filter   - if 1, does filtering (not supported), else smoothing [0]
%
% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)

maximize = 0;
filter = 0;

% parse optional params
args = varargin;
nargs = length(args);
if nargs > 0
  for i=1:2:nargs
    switch args{i},
     case 'maximize', maximize = args{i+1};
     case 'filter',  filter = args{i+1};
     otherwise,
      error(['invalid argument name ' args{i}]);
    end
  end
end

if filter
  error('jtree_unrolled_dbn does not support filtering')
end

if size(evidence,2) ~= engine.nslices
  error(['engine was created assuming there are ' num2str(engine.nslices) ...
	 ' slices, but evidence has ' num2str(size(evidence,2))])
end

[engine.unrolled_engine, loglik] = enter_evidence(engine.unrolled_engine, evidence, 'maximize', maximize);


function map = readCbMap(fileName)
% readCbMap reads in a map from a textfile and returns a map struct
%
% map = readCbMap(fileName)
%
%INPUT
% fileName is the text file exported from BiGG database
%
%OUTPUT
% map                   Map structure
%   molPosition             the positions of the metabolite nodes
%   molIndex                index for molecule node(same as connection index)
%   molName                 full name of metabiolites
%   molAbbreviation         The abbreviation formetabolites(labels)
%   molLabelPos             The positions to display the metabolite's labels
%   molPrime                Y if metabolite is primary and N if not
%   rxnPosition             the positions of the reaction nodes
%   rxnLabelPosition        the positions of the reaction nodes' labels if the
%                           node is a midpoint
%   rxnIndex                the index of reaction nodes used in connection
%   connection              the node connection matrix
%   connectionAbb           the reaction abbreviations assigned to each
%                           segment
%   connectionName          the name of reactions
%   connectionReversibile   1 if reaction is reversible and 0 otherwise
%

% The general format of the import file in 9 cols
if nargin < 1
    [fileName,filePath] = uigetfile({'*.txt'});
else
    filePath = '';
    if isempty(regexp(fileName,'.txt$', 'once'))
        fileName = strcat(fileName,'.txt');
    end
end

format = '%s %n %s %f %f %f %f %n %s';
fid = fopen(strcat(filePath,fileName));
molecules = textscan(fid, format,'delimiter', '\t','HeaderLines',1);
fclose(fid);

molAbb = molecules{1,1};
molComp = molecules{1,2};
molPrim = molecules{1,3};
molLabelx = molecules{1,4};
molLabely = molecules{1,5};
molPosx = molecules{1,6};
molPosy = molecules{1,7};
molName = molecules{1,9};
molId = molecules{1,8};
% s = size(molLabelx);            %lenght of a general column
% i = 1;

% while i<= s(1)
%     if strcmp(molAbb(i),'Reactions Nodes')
%         rxnN = i;               % number of molecules
%     elseif strcmp(molAbb(i),'Reactions')
%         rxnEnd = i;
%     elseif strcmp(molAbb(i),'Texts')
%         textBeg = i;
%     end
%     i= i+1;
% end

rxnN = (strmatch('Reactions Nodes',molAbb));
rxnEnd = strmatch('Reactions',molAbb,'exact');
textBeg = strmatch('Texts',molAbb);

indexMols = (1:(rxnN-1));
indexRxnNodes = ((rxnN+1):(rxnEnd-1));
indexRxnNames = ((rxnEnd+1):(textBeg-1));
indexTexts = ((textBeg+1):length(molAbb));

rxnNum = (rxnEnd-rxnN-1);       % number of rxn nodes
connectionNum = textBeg-rxnEnd;    % number of connections: connectionNum

% set up the position matrix for molecules
molPos(:,1) = molPosx(indexMols);
molPos(:,2) = molPosy(indexMols);

% set up the position matrix for molecules' labels
molLabelPos = [molLabelx(indexMols) molLabely(indexMols)];

% set up the position matrix for reactions
%rxnPos = [molLabelx(indexRxnNodes) molLabely(indexRxnNodes)];
%Updated BiGG to output files in a less disorganized fashion
rxnPos = [molPosx(indexRxnNodes) molPosy(indexRxnNodes)];

% set up the position matrix for reactions' labels
%rxnLabelPos = [molPosx(indexRxnNodes) molPosy(indexRxnNodes)];
%Updated BiGG to output files in a less disorganized fashion
rxnLabelPos = [molLabelx(indexRxnNodes) molLabely(indexRxnNodes)];

% reaction ids
rxnId = molId(indexRxnNodes);

% set up the connection matrix
node = [molLabelx(indexRxnNames) molLabely(indexRxnNames)];

% set up the reversibility for each connection
r = zeros(connectionNum,1);
r(strmatch('Reversible',molPrim(indexRxnNames),'exact'))=1;

rxnAbb = molAbb(indexRxnNames);
rxnName = molName(indexRxnNames);

%% Handling other shapes and texts
shapeIDs = [strmatch('Circle',molAbb); strmatch('Rect',molAbb); strmatch('Line',molAbb)];
indexShapes = logical(sparse(length(molAbb),1));
indexShapes(shapeIDs) = 1;
map.shapeType = molAbb(indexShapes);
map.shapePos = [molLabelx(indexShapes) molLabely(indexShapes)];
map.shapeSize = [molPosx(indexShapes) molPosy(indexShapes)];
for i=1:length(shapeIDs)
    str = molName(shapeIDs(i));
    [colorStr, str] = strtok(str,':');
    [c1,c2] = strtok(colorStr,'/');
    [c2,c3] = strtok(c2,'/');
    c3 = regexprep(c3,'\/','');
    if isnan(str2double(c3))
        c3 = 0;
    end
    [thickness, style] = strtok(str,'@');
    thickness = regexprep(thickness,'(\w*):','');
    style = regexprep(style,'\@','');
    map.shapeStyle(i,1) = style;
    map.shapeThickness(i,1) = str2num(thickness{1,1});
    map.shapeColor(i,1:3) = [str2double(c1{1,1}) str2double(c2{1,1}) str2double(c3{1,1})];
end
indexShapes(1:textBeg) = 1;
map.text = molName(~indexShapes);
map.textFont = molAbb(~indexShapes);
map.textPos = [molLabelx(~indexShapes) molLabely(~indexShapes)];
map.textSize = molPosx(~indexShapes);

map.molPosition = molPos';
map.molIndex = molId(1:(rxnN-1));
map.molName = molName(1:(rxnN-1));
map.molAbbreviation = molAbb(1:(rxnN-1));
map.molLabelPos = molLabelPos;
map.molPrime = molPrim(1:(rxnN-1));
map.molCompartment = molComp(1:(rxnN-1));
map.rxnPosition = rxnPos';
map.rxnLabelPosition = rxnLabelPos';
map.rxnIndex = rxnId;
map.connection = node;
map.connectionAbb = rxnAbb;
map.connectionName = rxnName;
map.connectionReversible = r;
end


function [varargout] = opm_fil(filename, hdr, begsample, endsample, chanindx)

% OPM_FIL reads header, data and events from OPM MEG recordings that are done at the FIL (UCL, London).
%
% Use as
%   hdr = opm_fil(filename);
%   dat = opm_fil(filename, hdr, begsample, endsample, chanindx);
%   evt = opm_fil(filename, hdr);
%
% See https://github.com/tierneytim/OPM for technical details.
%
% See also FT_FILETYPE, FT_READ_HEADER, FT_READ_DATA, FT_READ_EVENT, QUALISYS_TSV, MOTION_C3D, EVENTS_TSV

% Copyright (C) 2020, 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$

needhdr = (nargin==1);
needevt = (nargin==2);
needdat = (nargin==5);

% It is permitted to pass any of the files that comprise the dataset
% figure out which files comprise the dataset
[p, f, x] = fileparts(filename);
assert(isfile(filename), sprintf('file "%s" not found', filename));

channelsfile  = fullfile(p, 'channels.tsv');
coordsysfile  = fullfile(p, 'coordsystem.json');
datafile      = fullfile(p, 'meg.bin');
headerfile    = fullfile(p, 'meg.json');
positionsfile = fullfile(p, 'positions.tsv');

precision = 'double';
switch precision
  case 'single'
    samplesize = 4;
  case 'double'
    samplesize = 8;
end

if needhdr
  %% read the header

  fid = fopen(headerfile, 'rt');
  header = jsondecode(fread(fid, [1 inf], 'char=>char'));
  fclose(fid);

  channels  = readtable(channelsfile, 'Delimiter', 'tab', 'FileType', 'text');

  % this one is optional
  if exist(coordsysfile, 'file')
    fid = fopen(coordsysfile, 'rt');
    coordsys = jsondecode(fread(fid, [1 inf], 'char=>char'));
    fclose(fid);
  else
    coordsys = [];
  end

  % this one is optional
  if exist(positionsfile, 'file')
    positions = readtable(positionsfile, 'Delimiter', 'tab', 'FileType', 'text');
  else
    positions = [];
  end

  d = dir(datafile);

  hdr.label       = channels.name;
  hdr.nChans      = size(channels, 1);
  hdr.nSamples    = d.bytes/(size(channels, 1) * samplesize);
  hdr.nSamplesPre = 0; % continuous data
  hdr.nTrials     = 1; % continuous data
  hdr.Fs          = header.SamplingFrequency;
  hdr.chantype    = channels.type;
  hdr.chanunit    = repmat({'unknown'}, size(hdr.label));

  % keep the original header details
  hdr.orig.header     = header;
  hdr.orig.coordsys   = coordsys;
  hdr.orig.positions  = positions;
  hdr.orig.channels   = channels;

  if ~isempty(positions)
    % FIXME construct a grad structure
    hdr.grad.label = positions.name;
    hdr.grad.coilpos = [positions.Px positions.Py positions.Pz];
    hdr.grad.coilori = [positions.Ox positions.Oy positions.Oz];
    hdr.grad.type = 'meg';
    if ~isempty(coordsys)
      hdr.grad.unit = coordsys.MEGCoordinateUnits;
      hdr.grad.coordsys = coordsys.MEGCoordinateSystem;
    end
  end

  % return the header details
  varargout = {hdr};

elseif needdat
  %% read the data, note that it is big endian

  fid = fopen(datafile, 'rb');
  fseek(fid, begsample*samplesize*hdr.nChans, 'bof');
  dat = fread(fid,[hdr.nChans, (endsample-begsample+1)], precision, 0, 'b');
  fclose(fid);

  % take the selection of channels
  dat = dat(chanindx,:);

  % return the data
  varargout = {dat};

elseif needevt
  %% read the events

  % FIXME this does not yet allow the user to override the defaults for ft_read_event, such as detectflank
  event = read_trigger(filename, 'header', hdr, 'dataformat', 'opm_fil', 'chanindx', find(strcmpi(hdr.chantype, 'TRIG')));

  % return the events
  varargout = {event};

end


%kPrintMapVal 'PrintMapVal Object Menuform'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros PrintMapVal.pane file
%
% Parameters:
% Integer: printmapvalWidth 'Width of Display (number of cells across)', default: 7: 'width of printmapval display'
% Integer: printmapvalHeight 'Height of Display (number of cells down) ', default: 9: 'height of printmapval display'
% InputFile: printmapvalFilename 'Input File', required: 'input file'
%
% Example: kPrintMapVal(printmapvalFilename, {'printmapvalWidth',7;'printmapvalHeight',9;'printmapvalFilename',''})
%
% Khoros helpfile follows below:
% .begin tagged
%
% .item "The PrintMapVal Visual Object"
% A printmapval object provides a mechanism with wich to roam around in an image
% and print the values of the map columns indexed by the pixel under the pointer.
% It is only useful with data objects having a map segment.  It is made up of one
% or more (width x height) sets of label objects;  typically, there will be three
% such sets, one each for the Red, Green, and Blue map columns of the colormap.
% The background of each label is the color defined by the values of the map
% columns at that pixel, and the value displayed is the value of the corresponding
% map column.
%
% .item "Width of Display"
% Specifies the number of map column values that should be
% displayed in the horizontal direction on the printmapval display.
%
% .item "Height of Display"
% Specifies the number of map column values that should be
% displayed in the vertical direction on the printmapval display.
%
% .item "Show Color"
% Indicates whether or not the color of the pixel under the
% pointer should be displayed as the background color for the label object in
% which the map values are displayed.  When set to FALSE, the background will be
% white.
%
% .item "Update Mode"
% Indicates whether the printmapval display is to be updated
% continuously as the pointer moves across the image, or not until the button
% is clicked at a particular location in the image.
%
% .item "Display Policy"
% Indicates whether the printmapval object is to display
% the values from the colormap that is being used to display the data object
% (ie, the RGB values that may have been converted and/or normalized), or
% the values from the actual map segment of the data object being visualized
% (ie, the map values before they are converted and/or normalized for use
% in defining the colors that appear on the screen).
%
% .item "Input File"
% The file containing the data object for which the map values are to be
% displayed.
% .end tagged

function varargout = kPrintMapVal(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,..] = kPrintMapVal(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'printmapvalWidth', 7;'printmapvalHeight', 9;'printmapvalFilename', '__input'};
maxval={2,2,0};
minval={2,2,0};
istoggle=[0,0,0];
was_set=istoggle * 0;
paramtype={'Integer','Integer','InputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=0; 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(0);
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
callKhoros([w 'PrintMapVal" '],Inputs,narglist);


%kvnopen 'Opening by N times (with respect to Minkowski addition) the structuring element'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros vnopen.pane file
%
% Parameters:
% InputFile: i 'Input Image ', required: 'input image'
% InputFile: str 'Struct Element', required: 'Structuring Element'
% Integer: n 'Size of Structure El.', default: 5: 'size of structure element'
% OutputFile: o 'Output Image ', required: 'resulting output image'
%
% Example: o = kvnopen({i, str}, {'i','';'str','';'n',5;'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% vnopen - Opening by N times (with respect to Minkowski addition) the structuring element
%
%  DESCRIPTION
% .I vnopen
% will do N successive openings by the same structuring element.
%
% The output image data type will be the same as that of the highest data type
% of the input image.
%
%
%
%  EXAMPLES
% vnopen -i feath.xv -str b.str -n 5 -o outimage.xv
%
% Will do 5 successive openings (vnopen) of the input image "feath.xv" by the structuring element "b.str" and the resulting image will be written to  "outimage.xv".
%
%  "SEE ALSO"
% vcast1(1)
%
%  RESTRICTIONS
% .I vnopen
% can be defined for all data types supported by Khoros, but at the moment it has been implemented just for the bit and unsigned char types.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993-1997 Junior Barrera, Roberto Lotufo.  All rights reserved.
%

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


function [mov ok aviPath] = aviSave(M, aviPath, fps, varargin);
% Export a 3D matrix to an AVI file.
%
% USAGE:
%	[mov ok aviPath] = aviSave(M, [aviPath], [fps], [options]);
%
% INPUTS:
% M: image matrix. Can either be a 3D matrix, in which every slice is a
% frame of the movie (converted to uint8), or a 4D M x N x 3 x frames matrix,
% in which each 3D subvolume is a truecolor ([R G B] slice) image.
%
% aviPath: save path for the .avi file. Will append .avi if it's not there.
% [pops up a dialog if omitted.]
%
% fps: frames per second for the movie. [Default 6]
%
% Options include:
%	'compression': select a compression for the movie. [Defaults based on
%	computer type: 'Indeo5' for windows OS, 'none' otherwise.]
%
%	'cmap': colormap for converting 3D matrices to color.
%
%	'description': descriptive name for the AVI file (will be saved as
%	metadata.)
%
%	other options found in HELP MOVIE2AVI will be supported here.
%
% OUTPUTS:
%	mov: matlab movie structure of the movie.
%
%	ok: flag indicating whether the save was successful.
%
%	aviPath: save path (useful in case a dialog is brought up.)
%
% ras, 07/18/2008.
if notDefined('M'),		error('Need image matrix.');		end
if notDefined('fps'),	fps = 6;							end
if notDefined('aviPath')
	aviPath = mrvSelectFile('w', 'avi', 'Save .AVI file as...');
end

%% default params
quality = 100;
description = aviPath;
keyframe = fps;
if ispc
	compression = 'Indeo3';
	cmap = gray(236);  % max allowed by compressor
else
	compression = 'None';
	cmap = gray(256);
end

%% parse options
for ii = 1:2:length(varargin)
	switch lower(varargin{ii})
		case 'compression', compression = varargin{ii+1};
		case 'description', description = varargin{ii+1};
		case {'cmap' 'colormap'}, cmap = varargin{ii+1};
		case 'quality', quality = varargin{ii+1};
		case 'keyframe', keyframe = varargin{ii+1};
	end
end

%% make the movie structure
if ndims(M)<=3
	nFrames = size(M, 3);

	% enforce uint8 data type
	nCmap = size(cmap, 1);
	if min(M(:)) < 1 | max(M(:)) > nCmap | any(mod(M(:), 1) ~= 0)
		warning('Matrix not uint8: rescaling to be uint8');
		M = uint8( rescale2(M, [], [0 nCmap-1]) );
	end

elseif ndims(M)==4
	if size(M, 3) ~= 3
		error('For 4-D matrices, third dimension must be [R G B] slices.');
	end
	nFrames = size(M, 4);

else
	error('Inappropriate movie size.');

end

for f = 1:nFrames
	if ndims(M) <= 3
		mov(f) = im2frame(M(:,:,f), cmap);
	else
		mov(f) = im2frame(M(:,:,:,f));
	end
end

%% export to AVI
% enfore .avi extension
[p f ext] = fileparts(aviPath);
if ~isequal( lower(ext), '.avi' )
	aviPath = fullfile(p, [f '.avi']);
end

% export
try
	movie2avi(mov, aviPath, 'FPS', fps, 'Compression', compression, ...
		  'Quality', quality, 'Videoname', description, 'Keyframe', keyframe);
	ok = 1;
	fprintf('[%s]: Saved movie as %s.\n', mfilename, aviPath);
catch
	disp(lasterr);
	ok = 0;
end

return


function env_load_dependencies(dependency_dir,autocompile)
% Execute dependency loaders in the given directory tree.
% env_load_dependencies(Directory)
%
% This function recognizes 3 types of dependency loader scripts in the dependencies (sub-)folders.
%  1. Scripts called env_exec.m. Each such script is executed by env_load_dependencies.
%
%  2. Scripts called env_add.m. Each such function is executed, and if the 'ans' variable is true
%     after executing the script (it is set to true before running the script), and no exception
%     had occured, the containing directory is added using addpath.
%
%  3. Scripts called env_compile.m. The presence of such a file indicates to the loader function
%     that any mex or Java source files in the given directory should be automatically compiled.
%     Additional compiler inputs (such as defines, libraries and include directories), if any, may
%     be declared as Name=value; statements in the file itself; These will be passed as named arguments
%     to hlp_trycompile (examples can be found throughout the existing dependencies).
%     A special parameter is Skip, which can be set to false on platforms on which the compilation
%     shall be skipped (perhaps because it is known to fail).
%
% In:
%   Directory : directory tree with dependencies to be loaded; by default, searches for a directory
%               named 'dependencies', relative to the current path or the path of this file.
%
%   Compile : whether to act on env_compile.m files (default: true)
%
% Example:
%   % load the dependencies in the C:\mydependencies folder.
%   env_load_dependencies('C:\mydependencies')
%
% Notes:
%   If you intend to compile your toolbox using the MATLAB compiler, you cannot have empty .m files.
%   Therefore, your env_add etc. files must contain at least a space character to satisfy the compiler.
%
% See also:
%   env_startup
%
%                                Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                2011-03-06

if ~exist('dependency_dir','var')
    % other possible directories where the dependencies could be located:
    possible_dirs = {pwd,fileparts(mfilename('fullpath'))};
    while ~exist('dependency_dir','var')
        % for each of the possible directories...
        for d=1:length(possible_dirs)
            % check whether it contains a 'dependencies' directory
            curdir = possible_dirs{d};
            if exist([curdir filesep 'dependencies'],'dir')
                dependency_dir = [curdir filesep 'dependencies'];
                break;
            end
            % otherwise peel off the last directory
            fsp = find(curdir==filesep,1,'last');
            if ~isempty(fsp)
                possible_dirs{d} = curdir(1:fsp-1); end
        end
        if cellfun('isempty',possible_dirs)
            error('Did not find a directory called ''dependencies''. Please specify it.'); end
    end
else
    if ~ischar(dependency_dir)
        error('The given dependency directory must be a string.'); end
    if ~exist(dependency_dir,'dir')
        error('The given dependency directory (%s) does not exist.',dependency_dir); end
end

if ~exist('autocompile','var')
    autocompile = true; end

if autocompile
    % check if compilation is suppressed on this platform
    try
        fname = [hlp_homedir filesep '.bcilab' filesep 'bcilab-dont-compile'];
        fid = fopen(fname,'r');
        platforms = fgetl(fid);
        fclose(fid);
        if strfind(platforms,[hlp_hostname ';'])
            autocompile = false; end
    catch
    end
end

load_dependencies(genpath(dependency_dir),autocompile);

% now, make sure that the build-* directories are included after their ancestor directories...
if ~isdeployed
    % get current path order
    added_paths = strsplit(path,pathsep)';
    added_paths = sort(added_paths); %#ok<TRSRT>
    added_paths = added_paths(cellfun(@(s)strncmp(dependency_dir,s,length(dependency_dir)),added_paths));

    super_dirs = {}; % this is a cell array of super directories with build dirs that may have to be moved
    sub_dirs = [];   % this is an array of indices (into added_paths) of sub-directories that need
                     % to be moved in front of the respective super dirs (indexed the same)
    % we start from the end so that we don't have to change indices
    for p=length(added_paths):-1:1
        try
            cur = added_paths{p};
            k = strfind(cur,[filesep 'build-']);
            if ~isempty(k)
                % if this is a build directory, add to the potential-move list
                super_dirs{end+1} = cur(1:k(end)-1); %#ok<AGROW>
                sub_dirs(end+1) = p; %#ok<AGROW>
            end
            % check if this is one of the super dirs
            match = strcmp(cur,super_dirs);
            if any(match)
                % move all the respective sub-dirs to right before this position
                indices = sub_dirs(match);
                added_paths = vertcat(added_paths(1:p-1),added_paths(indices),added_paths(setdiff(p:end,indices)));
                super_dirs = super_dirs(~match);
                sub_dirs = sub_dirs(~match);
            end
        catch
            warning('bcilab:dependency_glitch','Glitch during mex/build path reordering.');
            super_dirs = {};
            sub_dirs = [];
        end
    end

    % rebuild path
    if ~isempty(added_paths)
        rmpath(added_paths{:});
        addpath(added_paths{:});
    end
end

% from the given path list, add all paths that contain an active env_add.m
% file (active: either empty or runs without exceptions and ans is not being
% set to false), and execute all env_exec.m files
function load_dependencies(pathlist,autocompile)
compile_problems = {};
paths = sort(strsplit(pathlist,pathsep));
for px = paths(end:-1:1)
    p = px{1};
    if exist([p filesep 'env_add.m'],'file')
        % env_add file: check if "active"
        [dummy,isactive] = evalc('runscript([p filesep ''env_add.m''])');  %#ok<ASGLU>
        % immediately add all java .jar packages
        dirinfos = dir([p filesep '*.jar']);
        for m={dirinfos.name}
            if isdeployed
                warning off MATLAB:javaclasspath:jarAlreadySpecified; end
            evalc('javaaddpath([p filesep m{1}]);');
        end
    else
        isactive = false;
    end
    % env_exec file: run it
    if exist([p filesep 'env_exec.m'],'file')
        runscript([p filesep 'env_exec.m']); end
    % env_compile file: invoke compilation, if necessary
    if autocompile && exist([p filesep 'env_compile.m'],'file')
        settings = get_settings([p filesep 'env_compile.m']);
        % the Skip field determines whether the current platform should be skipped
        if isfield(settings,'Skip')
            docompile = ~settings.Skip;
        else
            docompile = true;
        end
        if ~isequal(settings,false) && docompile
            if ~hlp_trycompile('Directory',p, 'Style','eager', settings);
                compile_problems{end+1} = p; end %#ok<AGROW>
        end
    end
    if isactive
        % finally add to MATLAB & Java path
        if ~isdeployed
            addpath(p); end
        % also add java files here (note: this may clear global variables)
        if ~isempty(dir([p filesep '*.class']))
            if isdeployed
                warning off MATLAB:javaclasspath:jarAlreadySpecified; end
            javaaddpath(p);
        end
    end
end

% handle compilation errors gracefully
if ~isempty(compile_problems) && ~isdeployed
    disp('There were compiling problems for the dependencies in:');
    for k=1:length(compile_problems)
        disp(['  ' compile_problems{k}]); end
    fprintf('\n');
    disp('This means that the affected features of BCILAB will be disabled.');
    if ispc
        disp('These issues are usually resolved by installing a (free) Microsoft Visual Studio Express version that is between five years to a half year older than your MATLAB release.');
        disp('If you install a new compiler, you might have to type "mex -setup" in the MATLAB command line, before MATLAB recognizes it.');
    elseif ismac
        disp('These issues are usually resolved by installing the Xcode application that comes with your OS (with all install options to include gcc compiler support).');
    elseif isunix
        disp('These issues are usually resolved by a installing a version of the gcc compiler package that is between three years to a half year older than your MATLAB release.');
    end
    yn = lower(input('Should BCILAB try to recompile in the future (or skip recompilation if not)? [y/n]','s'));
    if any(strcmp(yn,{'y','n','yes','no'}))
        if yn(1) == 'n'
            if ~exist([hlp_homedir filesep '.bcilab'],'dir')
                if ~mkdir(hlp_homedir,'.bcilab');
                    disp('Cannot create directory .bcilab in your home folder.'); end
            end
            fname = [hlp_homedir filesep '.bcilab' filesep 'bcilab-dont-compile'];
            disp(['BCILAB will add/update a file called ' fname ' which contains the names of computers on which you chose to disable compilation.']);
            fid = fopen(fname,'a');
            if fid ~= -1
                try
                    fwrite(fid,[hlp_hostname ';']);
                    fclose(fid);
                catch
                    try fclose(fid); catch,end
                    disp('There were permission problems while accessing this file. Did not update it.');
                end
            else
                disp('The file name appears to be invalid on your platform; did not update it.');
            end
        end
    else
        disp('Please type ''y'' or ''n'' next time.');
    end
    fprintf('\n');
end

% run the given script (in its own scope...)
% and return the result of the last line
function ans = runscript(filename__)
try
    ans = 1; %#ok<NOANS>
    fprintf('Loading %s...\n',fileparts(filename__));
    run_script(filename__); % Note: This function is equivalent to run(), but works in deployed mode,
                            %       too. If the code fails here, you probably don't have this
                            %       function in your path. You may retrieve it (it's in the 'misc'
                            %       directory of BCILAB), or replace it here by run().
catch e
    disp(['Error running dependency loader ' filename__ '; reason: ' e.message]);
    disp('The dependency will likely not be fully operational.');
    ans = 0; %#ok<NOANS>
end

% run the given settings script (in its own scope...)
% and return the collected defined variables (or false)
function settings = get_settings(filename__)
try
    evalc('run_script(filename__)');
    infos = whos();
    settings = struct();
    for n = {infos.name}
        settings.(n{1}) = eval(n{1}); end
catch
	disp(['The settings script ' filename__ ' contains an error.']);
    settings = false;
end

% Split a string according to some delimiter(s). Not as fast as hlp_split (and doesn't fuse
% delimiters), but doesn't need bsxfun().
function strings = strsplit(string, splitter)
ix = strfind(string, splitter);
strings = cell(1,numel(ix)+1);
ix = [0 ix numel(string)+1];
for k = 2 : numel(ix)
    strings{k-1} = string(ix(k-1)+1:ix(k)-1); end
strings = strings(~cellfun('isempty',strings));


function v = vectorize(m)

v = m(:);


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


function a = ne( x, y )

%   Disciplined convex/geometric programming information for NE (~=):
%      Not-equal constraints violate both the DCP and DGP rulesets. Thus
%      not-equal expressions may only appear in CVX models when both
%      sides are constant.

evalin( 'caller', 'cvx_verify' );
b = cvx_pushcnstr( x, y, '~=' );
if nargout, a = b; end

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