function loadlibltfat(varargin)
global libltfat_intptrstr;

definput.keyvals.lib='libltfat.so';
definput.flags.phase={'load','reload','recompile'};
definput.flags.comptarget={'fulloptim','release','debug'};
definput.flags.verbosity={'quiet','verbose'};
definput.flags.corcpp={'c','cpp'};
definput.keyvals.compiler = [];

[flags,kv,lib]=ltfatarghelper({'lib'},definput,varargin);

[~,libname]=fileparts(lib);
currdir = fileparts(mfilename('fullpath'));
libltfatpath = [currdir, filesep, '..', filesep,'..',filesep,'..',filesep,'..',filesep];
libpath = [libltfatpath, filesep,'build',filesep,lib];
iscompiled = exist(libpath,'file');

makecmd = ['make -C ',libltfatpath];
if ~iscompiled || flags.do_recompile
    [status,result] = system([makecmd, ' clean']);
    if status ~=0, error(result);  end

    makecmd = [makecmd, ' MODULE=libltfat'];
    makecmd = [makecmd, ' munit -j12'];
    makecmd = [makecmd, ' MATLABROOT=', matlabroot];
    makecmd = [makecmd, sprintf(' COMPTARGET=%s',flags.comptarget)];

    if flags.do_cpp
        makecmd = [makecmd, ' USECPP=1'];
    end

    if kv.compiler
        makecmd = [makecmd, sprintf(' CC=%s',kv.compiler)];
    end

    if flags.do_verbose
        disp(makecmd);
        system(makecmd);
    else
        [status,result] = system(makecmd);
        if status ~=0, error(result);  end
    end
end

if libisloaded(libname)
    if flags.do_reload || flags.do_recompile
        unloadlibrary(libname);
    else
        error('%s: libltfat is already loaded. Use ''reload'' to force reload.',upper(mfilename));
    end
end

warning('off');
headerpath = [libltfatpath,'build',filesep,'ltfat.h'];
loadlibrary(libpath,headerpath,'mfilename','libltfatprotofile.m');
warning('on');

intbitsize = 8*calllib('libltfat','ltfat_int_size');
libltfat_intptrstr = sprintf('int%dPtr',intbitsize);


function out = true( in )
%TRUE for initialization of nested cell arrays
%
% (c) Thomas Kuestner
% ---------------------------------------------------------------------

out = cellfun(@(x) true(x), in.data{2,1}, 'UniformOutput', false);
out = reconFlatCellMatrix(out, in.data{1,1});
out = TRAFO(out,in.meta);

end


function r = uplus(p)
% MEAS/UPLUS  Implement +p for meas.

% make a meas called r
r = meas();

% give it the right entries
r.value = p.value;
r.error = p.error;


function image_db = load_image_dataset(varargin)
%
% This file is part of the code that implements the following paper:
% Title      : "LocNet: Improving Localization Accuracy for Object Detection"
% Authors    : Spyros Gidaris, Nikos Komodakis
% Institution: Universite Paris Est, Ecole des Ponts ParisTech
% ArXiv link : http://arxiv.org/abs/1511.07763
% code       : https://github.com/gidariss/LocNet
%
% AUTORIGHTS
% --------------------------------------------------------
% Copyright (c) 2016 Spyros Gidaris
%
% Title     : "LocNet: Improving Localization Accuracy for Object Detection"
% ArXiv link: http://arxiv.org/abs/1511.07763
% Licensed under The MIT License [see LICENSE for details]
% ---------------------------------------------------------

% ************************** OPTIONS *************************************
ip = inputParser;
ip.addParamValue('dataset', 'pascal');
ip.addParamValue('image_set', {})
ip.addParamValue('voc_year',  {})
ip.addParamValue('proposals_method', {});
ip.addParamValue('use_flips', false, @islogical);

ip.parse(varargin{:});
opts = ip.Results;

voc_year         = opts.voc_year;
image_set        = opts.image_set;
proposals_method = opts.proposals_method;
use_flips        = opts.use_flips;

voc_path  = [pwd, '/datasets/VOC%s/'];
coco_path = [pwd, '/datasets/MSCOCO/'];

if ~iscell(proposals_method), proposals_method = {proposals_method}; end
if ~iscell(voc_year), voc_year = {voc_year}; end
if ~iscell(image_set), image_set = {image_set}; end

assert(ischar(voc_year{1}));

num_sets = length(image_set);
assert(length(image_set) == length(voc_year));
image_db.all_regions = {};
for i = 1:num_sets
    % add the paths to the images and the grount truth bounding boxes in
    % the image_db structure
    switch opts.dataset
        case 'pascal'
            image_db_this = load_pascal_dataset(...
                voc_year{i}, image_set{i}, voc_path);
        case 'mscoco'
            image_db_this = load_mscoco_dataset(...
                voc_year{i}, image_set{i}, coco_path );
    end
    % add the bounding box proposals in the image_db structure
    if ~isempty(proposals_method)
        assert(ischar(proposals_method{1}));
        image_db.all_regions = [image_db.all_regions(:); ...
            load_box_proposals(image_db_this, proposals_method)];
    end
    image_db_all(i) = image_db_this;
end
image_db_all = image_db_all(:);
image_db.all_bbox_gt = vertcat(image_db_all.all_bbox_gt);
image_db.image_paths = vertcat(image_db_all.image_paths);
image_db.image_sizes = single(vertcat(image_db_all.image_sizes));

proposals_suffix = '';
if ~isempty(proposals_method)
    for p = 1:length(proposals_method)
        proposals_suffix = [proposals_suffix, proposals_method{p}, '_'];
    end
    proposals_suffix = proposals_suffix(1:end-1);
end

switch opts.dataset
    case 'pascal', image_set_name_all = 'voc_';
    case 'mscoco', image_set_name_all = 'coco_';
end

for i = 1:num_sets
    image_set_name_all = [image_set_name_all, voc_year{i}, '_' image_set{i},'_'];
end
image_set_name_all = image_set_name_all(1:end-1);

image_db.image_set_name = image_set_name_all;
image_db.proposals_suffix = proposals_suffix;

% add flipped versions of the images
if use_flips, image_db = add_flip_data(image_db); end

switch opts.dataset
    case 'pascal'
        voc_path_year = sprintf(voc_path, '2007');
        VOCopts  = initVOCOpts(voc_path_year,'2007');
        classes = VOCopts.classes;
    case 'mscoco'
        save_file_categories = fullfile(coco_path,'annotations','categoties.mat');
        ld = load(save_file_categories,'category_names','cat_ids','catIdsToIndex');
        classes = ld.category_names;
end

image_db.classes = classes;

end

function image_db = load_pascal_dataset(voc_year, image_set, voc_path)
image_db = struct;
voc_path_dataset = sprintf(voc_path, voc_year);
assert(exist(voc_path_dataset,'dir')>0);
voc_path_devkit = fullfile(voc_path_dataset,'VOCdevkit');
assert(exist(voc_path_devkit,'dir')>0);

[image_db.image_paths, image_db.image_set_name] = get_image_paths_from_voc( voc_path_devkit, image_set, voc_year );
image_db.all_bbox_gt = get_grount_truth_bboxes_from_voc(voc_path_devkit, image_set, voc_year, true, voc_path_dataset);
image_db.image_sizes = get_img_size(image_db.image_paths);
end

function image_db = load_mscoco_dataset(coco_year, image_set, data_dir )
image_db = struct;

suffix = sprintf('%s%s',image_set,coco_year);
image_db.image_set_name = sprintf('coco_%s_%s',coco_year,image_set);
save_file_bbox_gt = fullfile(data_dir,'annotations',sprintf('all_bbox_gt_%s.mat',suffix));

save_file_image_names = fullfile(data_dir,'images',sprintf('all_image_names_%s.mat',suffix));
ld = load(save_file_image_names, 'image_names', 'image_sizes');
image_names          = ld.image_names;
image_db.image_paths = strcat(sprintf('%s/images/%s/', data_dir, suffix), image_names);
image_db.image_sizes = ld.image_sizes;

if (exist(save_file_bbox_gt,'file') > 0)
    ld = load(save_file_bbox_gt, 'all_bbox_gt');
    image_db.all_bbox_gt = ld.all_bbox_gt;
else
    image_db.all_bbox_gt = cell(length(image_db.image_paths),1);
    for i = 1:length(image_db.all_bbox_gt)
        image_db.all_bbox_gt{i} = zeros(0,6,'single');
    end
end

end

function image_sizes = get_img_size(image_paths)
num_imgs    = numel(image_paths);
image_sizes = zeros(num_imgs,2);

for img_idx = 1:num_imgs
    im_info                = imfinfo(image_paths{img_idx});
    image_sizes(img_idx,1) = im_info.Height;
    image_sizes(img_idx,2) = im_info.Width;
end
end

function image_db = add_flip_data(image_db)
num_imgs          = numel(image_db.image_paths);
image_paths_new   = cell(num_imgs,1);

there_are_regions = isfield(image_db, 'all_regions') && ~isempty(image_db.all_regions);
there_are_bbox_gt  = isfield(image_db, 'all_bbox_gt')  && ~isempty(image_db.all_bbox_gt);
there_are_feature_paths = isfield(image_db, 'feature_paths')  && ~isempty(image_db.feature_paths);

if there_are_regions,   all_regions_new = image_db.all_regions; end
if there_are_bbox_gt,   all_bbox_gt_new = image_db.all_bbox_gt; end
if there_are_feature_paths, feature_paths_new = cell(num_imgs,1); end

for img_idx = 1:num_imgs
    [img_dir, img_name, img_ext]  = fileparts(image_db.image_paths{img_idx});
    image_paths_new{img_idx} = [img_dir, filesep, img_name, '_flip', img_ext];

    if there_are_feature_paths
        [feat_dir, feat_name, feat_ext]  = fileparts(image_db.feature_paths{img_idx});
        feature_paths_new{img_idx} = [feat_dir, filesep, feat_name, '_flip', feat_ext];
    end

    img_weight = image_db.image_sizes(img_idx,2);
    if there_are_regions
        all_regions_new{img_idx}(:,[1,3]) = img_weight + 1 - all_regions_new{img_idx}(:,[3,1]);
    end
    if there_are_bbox_gt
        all_bbox_gt_new{img_idx}(:,[1,3]) = img_weight + 1 - all_bbox_gt_new{img_idx}(:,[3,1]);
    end
end

image_db.image_paths = cat(1, image_db.image_paths, image_paths_new);
image_db.image_sizes = cat(1, image_db.image_sizes,  image_db.image_sizes);

if there_are_bbox_gt, image_db.all_bbox_gt = cat(1, image_db.all_bbox_gt, all_bbox_gt_new); end
if there_are_regions, image_db.all_regions = cat(1, image_db.all_regions, all_regions_new); end
if there_are_feature_paths, image_db.feature_paths = cat(1,image_db.feature_paths, feature_paths_new); end
end


% Initialization code for running Garmin serial
% input model for xPC

Ts=1/75; % sample time in seconds


%% numOrder
% Below is a demonstration of the features of the |numOrder| function

%%
clear; close all; clc;

%% Syntax
% |[m]=numOrder(A);|

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


% -----------------------------------------------------------
% file: compile_mex.m
% -----------------------------------------------------------
% authors: Sebastien Bougleux and Évariste Daller
% institution: Normandie Univ, CNRS - ENSICAEN - UNICAEN, GREYC UMR 6072
% -----------------------------------------------------------
% Execute this file in matlab to compile matlab functions for LSAP and LSAPE
% -----------------------------------------------------------
% This file is part of LSAPE.
% LSAPE is free software: you can redistribute it and/or modify
% it under the terms of the CeCILL-C License. See README for more
% details.
% -----------------------------------------------------------

disp('Compiling tools for LSAP and LSAPE ...');
files =  { 'hungarianLSAP.cpp', ...
       	   'hungarianLSAPE.cpp', ...
           'greedyLSAP.cpp'
};

str = 'mex -O -I../include ';
flags = ' ';%' -std=c++11';

for i=1:length(files)
    eval([str files{i} flags ' ']);
end


classdef (Sealed) DMDicomLibrary < DMDicomLibraryInterface
    % DMDICOMLIBRARY DicoMat implementation of DMDicomLibraryInterface for
    % reading Dicom data.
    %
    %
    %     Licence
    %     -------
    %     Part of DicoMat. https://github.com/tomdoel/dicomat
    %     Author: Tom Doel, 2013.  www.tomdoel.com
    %     Distributed under the BSD 3-Clause license. Please see the file LICENSE for details.
    %

    methods
        function isDicom = isdicom(obj, fileName)
            % Tests whether a file is in DICOM format

            isDicom = DMisdicom(fileName);
        end

        function metaheader = dicominfo(obj, varargin)
            % Reads the metaheader data from a Dicom file

            metaheader = DMdicominfo(varargin{:});
        end

        function imageData = dicomread(obj, fileName_or_metaHeader)
            % Reads the image data from a Dicom file

            imageData = DMdicomread(fileName_or_metaHeader);
        end

    end

    methods (Access = private)
        function obj = DMDicomLibrary
        end
    end

    methods (Static)
        function singleObj = getLibrary
            persistent singleton
            if isempty(singleton) || ~isvalid(singleton)
                singleton = DMDicomLibrary;
            end
            singleObj = singleton;
        end
    end
end


function tree = copy(tree,subuid,uid)
% XMLTREE/COPY Copy Method (copy a subtree in another branch)
% FORMAT tree = copy(tree,subuid,uid)
%
% tree      - XMLTree object
% subuid    - UID of the subtree to copy
% uid       - UID of the element where the subtree must be duplicated
%__________________________________________________________________________
%
% Copy a subtree to another branch.
% The tree parameter must be in input AND in output.
%__________________________________________________________________________
% Copyright (C) 2002-2015  http://www.artefact.tk/

% Guillaume Flandin
% $Id: copy.m 6480 2015-06-13 01:08:30Z guillaume $

%error(nargchk(2,3,nargin));

if nargin == 2
    uid = parent(tree,subuid);
end

l = length(tree);
tree = sub_copy(tree,subuid,uid);
tree.tree{uid}.contents = [tree.tree{uid}.contents l+1];

% to have the copy next to the original and not at the end?
%  contents = get(tree,parent,'contents');
%  i = find(contents==uid);
%  tree = set(tree,parent,'contents',[contents(1:i) l+1 contents(i+1:end)]);

%==========================================================================
function tree = sub_copy(tree,uid,p)

    l = length(tree);
    tree.tree{l+1} = tree.tree{uid};
    tree.tree{l+1}.uid = l+1;
    tree.tree{l+1}.parent = p;
    tree.tree{l+1}.contents = [];
    if isfield(tree.tree{uid},'contents')
        contents = get(tree,uid,'contents');
        m = length(tree);
        for i=1:length(contents)
            tree.tree{l+1}.contents = [tree.tree{l+1}.contents m+1];
            tree = sub_copy(tree,contents(i),l+1);
            m = length(tree);
        end
    end


function o2 = canlab_results_fmridisplay(input_activation, varargin)
% :Usage:
% ::
%
%    canlab_results_fmridisplay(input_activation, [optional inputs])
%
% purpose:  This function display fmri results.
%
% :Input:
%
%   **input_activation:**
%        nii, img,
%
%        This image has the blobs you want to
%        display. You can also enter a cl "clusters" structure or
%        "region" object.
%
%        you can also get a thresholded image like the examples used here
%        from a number of places - by thresholding your results in SPM
%        and using "write filtered" to save the image, by creating masks
%        from meta-analysis or anatomical atlases, or by using
%        mediation_brain_results, robust_results_threshold,
%        robust_results_batch_script, threshold_imgs, or object
%        oriented tools including fmri_data and statistic_image objects.
%
% :Optional Inputs:
%
%   **'noblobs':**
%        do not display blobs
%
%   **'outline':**
%        display blob outlines
%
%   **'nooutline':**
%        do not display blob outlines (default)
%
%   **'addmontages':**
%        when entering existing fmridisplay obj, add new montages
%
%   **'noremove':**
%        do not remove current blobs when adding new ones
%
%   **'nofigure':**
%        do not create a new figure (for selected montage sets only)
%
%   **'outlinecolor:**
%        followed by new outline color
%
%   **'splitcolor':**
%        followed by 4-cell new split colormap colors (help fmridisplay or edit code for defaults as example)
%
%   **'montagetype':**
%
%        'full'            Axial, coronal, and saggital slices, 4 cortical surfaces
%        'compact'         Midline saggital and two rows of axial slices [the default]
%        'compact2'        A single row showing midline saggital and axial slices
%        'multirow'        A series of 'compact2' displays in one figure for comparing different images/maps side by side
%        'regioncenters'   A series of separate axes, each focused on one region
%
%        'full' for full montages of axial and sagg slices.
%
%        'full hcp' for full montage, but with surfaces and volumes from
%        HCP data
%
%        'compact' [default] for single-figure parasagittal and axials slices.
%
%        'compact2': like 'compact', but fewer axial slices.
%
%        'multirow': followed by number of rows
%           e.g., o2 = canlab_results_fmridisplay([], 'multirow', 2);
%
%        {'blobcenters', 'regioncenters'}: Slices for the center of each blob/region
%        Note: this creates a new figure, tagged
%        'fmridisplay_regioncenters', and is not compatible with 'nofigure'
%
%   **'noverbose':**
%        suppress verbose output, good for scripts/publish to html, etc.
%
%   **'overlay':**
%        specify anatomical image for montage (not surfaces), followed by
%        image name
%        e.g., o2 = canlab_results_fmridisplay([], 'overlay', 'icbm152_2009_symmetric_for_underlay.img')';
%
%         The default brain for overlays is based on Keuken et al. 2014
%         For legacy SPM8 single subject, enter as arguments:
%         'overlay', which('SPM8_colin27T1_seg.img')
%
% Other inputs to addblobs (fmridisplay method) are allowed, e.g., 'cmaprange', [-2 2], 'trans'
%
% See help fmridisplay
% e.g., 'color', [1 0 0]
%
% You can also input an existing fmridisplay object, and it will use the
% one you have created rather than setting up the canonical slices.
%
% Try "brighten(.4) to make the images brighter.
%
% :Example Script:
% ::
%
%    input_activation = 'Pick_Atlas_PAL_large.nii';
%
%    % set up the anatomical overlay and display blobs
%    % (see the code of this function and help fmridisplay for more examples)
%
%    o2 = canlab_results_fmridisplay(input_activation);
%
%    %% ========== remove those blobs and change the color ==========
%
%    cl = mask2clusters(input_activation);
%    removeblobs(o2);
%    o2 = addblobs(o2, cl, 'color', [0 0 1]);
%
%    %% ========== OR
%
%    r = region(input_activation);
%    o2 = removeblobs(o2);
%    o2 = addblobs(o2, r, 'color', [1 0 0]);
%
%    %% ========== Create empty fmridisplay object on which to add blobs:
%    o2 = canlab_results_fmridisplay
%    o2 = canlab_results_fmridisplay([], 'compact2', 'noverbose');
%
%    %% ========== If you want to start over with a new fmridisplay object,
%    % make sure to clear o2, because it uses lots of memory
%
%    % This image should be on your path in the "canlab_canonical_brains" subfolder:
%
%    input_activation = 'pain-emotion_2s_z_val_FDR_05.img';
%    clear o2
%    close all
%    o2 = canlab_results_fmridisplay(input_activation);
%
%    %% ========== save PNGs of your images to insert into powerpoint, etc.
%    % for your paper/presentation
%
%    scn_export_papersetup(400);
%    saveas(gcf, 'results_images/pain_meta_fmridisplay_example_sagittal.png');
%
%    scn_export_papersetup(350);
%    saveas(gcf, 'results_images/pain_meta_fmridisplay_example_sagittal.png');
%
%    Change colors, removing old blobs and replacing with new ones:
%    o2 = canlab_results_fmridisplay(d, o2, 'cmaprange', [.3 .45], 'splitcolor', {[0 0 1] [.3 0 .8] [.9 0 .5] [1 1 0]}, 'outlinecolor', [.5 0 .5]);
%
% ..
%    Tor Wager
%    1/27/2012
% ..

if ~which('fmridisplay.m')
    disp('fmridisplay is not on path.  it is in canlab tools, which must be on your path!')
    return
end

if nargin == 0
    o2 = canlab_results_fmridisplay(region(), 'noblobs', 'nooutline');
    return
end

if ischar(input_activation)

    if strcmp(input_activation, 'compact') || strcmp(input_activation, 'compact2') || strcmp(input_activation, 'full') ...
            || strcmp(input_activation, 'multirow') || strcmp(input_activation, 'coronal') || strcmp(input_activation, 'sagittal')

        % Entered no data map; intention is not to plot blobs, just create underlay
        varargin{end + 1} = 'noblobs';
        varargin{end + 1} = 'nooutline';
        varargin{end + 1} = input_activation; % so code below finds it later
        % do nothing else for now - this is not an input image

    else
        % assume it is an input image

        cl = region(fmri_data(input_activation));  % mask2clusters(input_activation);

    end

elseif isstruct(input_activation) || isa(input_activation, 'region')
    cl = input_activation;
    if ~isa(input_activation, 'region'), cl = cluster2region(cl); end

elseif isa(input_activation, 'image_vector')
    cl = region(input_activation);

elseif isempty(input_activation)
    % do nothing for now

else
    error('I don''t recognize the format of input_activation.  It should be a thresholded mask, clusters, or region object');
end

% process input arguments
% --------------------------------------------
doblobs = true;
dooutline = false;
doaddmontages = false;
doremove = true;
outlinecolor = [0 0 0];
splitcolor = {[0 0 1] [0 .8 .8] [1 .4 .5] [1 1 0]}; % {[0 0 1] [.3 .6 .9] [.8 .3 0] [1 1 0]};  % more straight orange to yellow: {[0 0 1] [0 1 1] [1 .5 0] [1 1 0]}
montagetype = 'compact';
doverbose = true;
%overlay='SPM8_colin27T1_seg.img';
overlay = 'keuken_2014_enhanced_for_underlay.img';
dofigure = true;

wh = strcmp(varargin, 'overlay');
if any(wh), wh = find(wh); overlay = varargin{wh(1) + 1};  varargin([wh wh+1]) = []; end

wh = strcmp(varargin, 'noblobs');
if any(wh), doblobs = false; varargin(wh) = []; end

wh = strcmp(varargin, 'nooutline');
if any(wh), dooutline = false; varargin(wh) = []; end

wh = strcmp(varargin, 'outline');
if any(wh), dooutline = true; varargin(wh) = []; end

wh = strcmp(varargin, 'addmontages');
if any(wh), doaddmontages = true; varargin(wh) = []; end

wh = strcmp(varargin, 'outlinecolor');
if any(wh), wh = find(wh); outlinecolor = varargin{wh(1) + 1}; end

wh = strcmp(varargin, 'splitcolor');
if any(wh), wh = find(wh); splitcolor = varargin{wh(1) + 1}; end

wh = strcmp(varargin, 'noremove');
if any(wh), doremove = false; varargin(wh) = []; end

wh = strcmp(varargin, 'full');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'multirow');
if any(wh), montagetype = varargin{find(wh)};
    nrows = varargin{find(wh) + 1};
    varargin{find(wh) + 1} = [];
        varargin(wh) = [];
end

wh = strcmp(varargin, 'blobcenters');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'regioncenters');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'full hcp');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'compact');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'compact2');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'coronal');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'saggital');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'allslices');
if any(wh), montagetype = varargin{find(wh)}; varargin(wh) = []; end

wh = strcmp(varargin, 'noverbose');
if any(wh), doverbose = false; end

wh = strcmp(varargin, 'nofigure');
if any(wh), dofigure = false; varargin(wh) = []; end

wh = false(1, length(varargin));
for i = 1:length(varargin)
    wh(i) = isa(varargin{i}, 'fmridisplay');
    if wh(i), o2 = varargin{wh}; end
end
varargin(wh) = [];

xyz = [-20 -10 -6 -2 0 2 6 10 20]';
xyz(:, 2:3) = 0;

if isempty(input_activation)
    % we will skip the blobs, but process other optional input args
    doblobs = false;
    dooutline = false;
end

if ~exist('o2', 'var')

    % set up fmridisplay
    % --------------------------------------------
    % you only need to do this once
    % then you can add montages, add and remove blobs, add and remove points (for
    % meta-analysis), etc.

    if doverbose

        disp('Setting up fmridisplay objects');
        % disp('This takes a lot of memory, and can hang if you have too little.');

    end

    [opath, ofname, oext] = fileparts(overlay);
    if isempty(opath)
        % check for file in matlab path
        o2 = fmridisplay('overlay', which(overlay));
    else
        % complete path specified
        o2 = fmridisplay('overlay',overlay);
    end

    % You can customize these and run them from the command line

    switch montagetype

        case {'blobcenters', 'regioncenters'}
            %Make a series of montages at center of each region and add blobs to that:

            if ~exist('cl', 'var'), error('Must enter region object to use blobcenters option.'); end

            xyz = cat(1, cl.mm_center);

            %           onerowstr = [];
            %           if length(cl) < 20, onerowstr = 'onerow'; end

            orientation = 'axial';

            % Make a grid - determine subplots
            nr = floor(sqrt(length(cl)));
            nc = ceil(length(cl) ./ nr);

            [~, axh] = create_figure('fmridisplay_regioncenters', nr, nc, false, true);

            set(axh,'Visible','off'); % turn off axis grid for all axes

            for i = 1:length(cl)

                %axh(i) = subplot(nr, nc, i);
                %axes(axh(i))

                if i == 1
                    [o2, dat] = montage(o2, orientation, 'wh_slice', xyz(i, :), 'onerow', 'existing_axes', axh(i), 'existing_figure', 'noverbose');
                else
                    o2 = montage(o2, 'volume_data', dat, orientation, 'wh_slice', xyz(i, :), 'onerow', 'existing_axes', axh(i), 'existing_figure', 'noverbose');
                end

            end

            wh_montages = 1:length(cl);

        case 'compact'
            % The default

            % saggital
            axh1 = axes('Position', [-0.02 0.4 .17 .17]);
            [o2, dat] = montage(o2, 'saggital', 'wh_slice', [-4 0 0], 'onerow', 'noverbose', 'existing_axes', axh1);
            text(50, -50, 'left');
            drawnow

            axh2 = axes('Position', [-0.02 0.6 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'saggital', 'wh_slice', [4 0 0], 'onerow', 'noverbose', 'existing_axes', axh2);
            text(50, -50, 'right');
            drawnow

            % sagg center
            axh3 = axes('Position', [.08 0.5 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'saggital', 'wh_slice', [0 0 0], 'onerow', 'noverbose', 'existing_axes', axh3);
            drawnow;
            o2.montage{3}.slice_mm_coords;

            % axial bottom
            axh4 = axes('Position', [.10 0.4 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 12, 'noverbose', 'existing_axes', axh4);

            % axial top
            axh5 = axes('Position', [.12 0.54 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-46 50], 'onerow', 'spacing', 12, 'noverbose', 'existing_axes', axh5);

            wh_montages = [1 2 4 5];

            % Lines
            axes(o2.montage{3}.axis_handles)
            locs = [o2.montage{4}.slice_mm_coords; o2.montage{5}.slice_mm_coords];
            for i = 1:length(locs)
                %draw_vertical_line(locs(i));
                hh(i) = plot( [-105 65], [locs(i) locs(i)], 'b', 'LineWidth', 1);
            end

            % brighten(.5)
            sz = get(0, 'screensize');
            set(gcf, 'Color', 'w', 'Position', [sz(3).*.1 sz(4).*.9 sz(3).*.6 sz(4).*.6]);

        case 'multirow'

            % Notes: for some reason, at least in Matlab 2017a, when you
            % use the existing figure the slices scale with the fig
            % position in size. When using montage to create a new figure,
            % they don't seem to do this. could be enlarge_axes, or ???

            if dofigure
                slices_fig_h = figure('Color', 'w');
            end

            ss = get(0, 'ScreenSize');
            myheightdivisor = 1.5; % 3/nrows;  % controls figure aspect ratio
            set(gcf, 'Position', [round(ss(3)/20) round(ss(4)*.5) round(ss(3)*.9) round(ss(4)/myheightdivisor) ])

            %shiftvals = [0:.17:nrows]; % more than we need, but works
            %shiftvals = [0:.24:nrows]; % more than we need, but works
            shiftvals = repmat([0:.24:.75], 1, ceil(nrows/4));  % repeat positions every 4, for adding new figures

            for i = 1:nrows

                % Can only put 4 on one figure, so create additional
                % figures as needed
                if i > 4 && rem(i, 4) == 1

                    figure('Color', 'w');
                    set(gcf, 'Position', [round(i*ss(3)/20) round(ss(4)*.5) round(ss(3)*.9) round(ss(4)/myheightdivisor) ])

                end

                % saggital
                axh = axes('Position', [-0.02 .75-shiftvals(i) .17 .17]);  % [-0.02 0.15+shiftvals(i) .17 .17]);
                axh(2) = axes('Position', [.022 .854-shiftvals(i) .17 .17]);

                if i == 1
                    [o2, dat] = montage(o2, 'saggital', 'slice_range', [-2 2], 'spacing', 4, 'onerow', 'noverbose', 'existing_axes', axh);

                else
                    o2 = montage(o2, 'volume_data', dat, 'saggital', 'slice_range', [-2 2], 'spacing', 4, 'onerow', 'noverbose', 'existing_axes', axh);

                end
                drawnow

                % axial
                axh = axes('Position', [.022 0.8-shiftvals(i) .17 .17]);   % [.015 0.15+shiftvals(i) .17 .17]);
                o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-32 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);
                drawnow

            end

        case 'full'
            % saggital
            [o2, dat] = montage(o2, 'saggital', 'wh_slice', xyz, 'onerow', 'noverbose');
            shift_axes(-0.02, -0.04);

            % coronal
            axh = axes('Position', [-0.02 0.37 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'coronal', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            % axial
            axh = axes('Position', [-0.02 0.19 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            axh = axes('Position', [-0.02 0.01 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-44 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            allaxh = findobj(gcf, 'Type', 'axes');
            disp(length(allaxh));
            for i = 1:(length(allaxh)-36)
                pos1 = get(allaxh(i), 'Position');
                pos1(1) = pos1(1) - 0.03;
                set(allaxh(i), 'Position', pos1);
            end

            % surface
            o2 = surface(o2, 'axes', [0.1 0.74 .25 .25], 'direction', 'hires left', 'orientation', 'medial');
            o2 = surface(o2, 'axes', [0.3 0.74 .25 .25], 'direction', 'hires right', 'orientation', 'medial');
            o2 = surface(o2, 'axes', [0.5 0.74 .25 .25], 'direction', 'hires left', 'orientation', 'lateral');
            o2 = surface(o2, 'axes', [0.7 0.74 .25 .25], 'direction', 'hires right', 'orientation', 'lateral');

            wh_montages = [1 2 3 4];
            wh_surfaces = [1 2 3 4];

        case 'compact2'  % creates a new figure
            %subplot(2, 1, 1);
            [o2, dat] = montage(o2, 'axial', 'slice_range', [-32 50], 'onerow', 'spacing', 8, 'noverbose');

            % shift all axes down and right
            allaxh = o2.montage{1}.axis_handles;
            for i = 1:length(allaxh)
                pos1 = get(allaxh(i), 'Position');
                pos1(2) = pos1(2) - 0.08;
                pos1(1) = pos1(1) + 0.03;

                % enlarge a bit
                pos1(3:4) = pos1(3:4) + .02;

                set(allaxh(i), 'Position', pos1);
            end

            enlarge_axes(gcf, 1);
            %axh = axes('Position', [0.0 0.08 .15 1]);
            axh = axes('Position', [-0.02 .75-.3 .17 .17]);  % [-0.02 0.15+shiftvals(i) .17 .17]);
            axh(2) = axes('Position', [.022 .854-.3 .17 .17]);

            %o2 = montage(o2, 'saggital', 'wh_slice', [0 0 0], 'existing_axes', axh, 'noverbose');
            o2 = montage(o2, 'volume_data', dat, 'saggital', 'slice_range', [-2 2], 'spacing', 4, 'onerow', 'noverbose', 'existing_axes', axh);

            %ss = get(0, 'ScreenSize');
            %set(gcf, 'Position', [round(ss(3)/12) round(ss(4)*.9) round(ss(3)*.8) round(ss(4)/5.5) ]) % this line messes p the
            %images, makes it too big an overlapping
            wh_montages = [1 2];

            brighten(.4)

        case 'coronal'
            % coronal
            o2 = montage(o2, 'coronal', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose');
             wh_montages = 1;

        case  'saggital'
            o2 = montage(o2, 'saggital', 'wh_slice', xyz, 'onerow', 'noverbose');

             wh_montages = 1;

        case 'allslices'

            [o2, dat] = montage(o2, 'saggital', 'wh_slice', xyz, 'onerow', 'noverbose');
            shift_axes(-0.02, -0.04);

            axh = axes('Position', [-0.02 0.37 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'coronal', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            % axial
            axh = axes('Position', [-0.02 0.19 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            wh_montages = [1 2 3];

        case 'full hcp'
            % saggital
            [o2, dat] = montage(o2, 'saggital', 'wh_slice', xyz, 'onerow', 'noverbose');
            shift_axes(-0.02, -0.04);

            % coronal
            axh = axes('Position', [-0.02 0.37 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'coronal', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            % axial
            axh = axes('Position', [-0.02 0.19 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            axh = axes('Position', [-0.02 0.01 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-44 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            allaxh = findobj(gcf, 'Type', 'axes');
            disp(length(allaxh));
            for i = 1:(length(allaxh)-36)
                pos1 = get(allaxh(i), 'Position');
                pos1(1) = pos1(1) - 0.03;
                set(allaxh(i), 'Position', pos1);
            end

            % surface
            o2 = surface(o2, 'axes', [0.1 0.74 .25 .25], 'direction', 'surface left', 'orientation', 'medial');
            o2 = surface(o2, 'axes', [0.3 0.74 .25 .25], 'direction', 'surface right', 'orientation', 'medial');
            o2 = surface(o2, 'axes', [0.5 0.74 .25 .25], 'direction', 'surface left', 'orientation', 'lateral');
            o2 = surface(o2, 'axes', [0.7 0.74 .25 .25], 'direction', 'surface right', 'orientation', 'lateral');

            wh_montages = [1 2 3 4];
            wh_surfaces = [1:8];

        otherwise error('illegal montage type. choose full or compact.');
    end

    % wh_montages = [1 2];

else
    if doverbose, disp('Using existing fmridisplay object'); end

    % Other inputs will be passed into addblobs
    existingmons = length(o2.montage);
    existingsurs = length(o2.surface);

    if doaddmontages
        % use same o2, but add montages
        switch montagetype
            case 'full'
            % saggital
            [o2, dat] = montage(o2, 'saggital', 'wh_slice', xyz, 'onerow', 'noverbose');
            shift_axes(-0.02, -0.04);

            % coronal
            axh = axes('Position', [-0.02 0.37 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'coronal', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            % axial
            axh = axes('Position', [-0.02 0.19 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            axh = axes('Position', [-0.02 0.01 .17 .17]);
            o2 = montage(o2, 'volume_data', dat, 'axial', 'slice_range', [-44 50], 'onerow', 'spacing', 8, 'noverbose', 'existing_axes', axh);

            allaxh = findobj(gcf, 'Type', 'axes');
            disp(length(allaxh));
            for i = 1:(length(allaxh)-36)
                pos1 = get(allaxh(i), 'Position');
                pos1(1) = pos1(1) - 0.03;
                set(allaxh(i), 'Position', pos1);
            end

            % surface
            o2 = surface(o2, 'axes', [0.1 0.74 .25 .25], 'direction', 'hires left', 'orientation', 'medial');
            o2 = surface(o2, 'axes', [0.3 0.74 .25 .25], 'direction', 'hires right', 'orientation', 'medial');
            o2 = surface(o2, 'axes', [0.5 0.74 .25 .25], 'direction', 'hires left', 'orientation', 'lateral');
            o2 = surface(o2, 'axes', [0.7 0.74 .25 .25], 'direction', 'hires right', 'orientation', 'lateral');

            wh_surfaces = existingsurs + [1 2 3 4];

            case 'compact'
                [o2, dat] = montage(o2, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 6, 'noverbose');
                axh = axes('Position', [0.05 0.4 .1 .5]);
                o2 = montage(o2, 'volume_data', dat, 'saggital', 'wh_slice', [0 0 0], 'existing_axes', axh, 'noverbose');

            case 'compact2'
                [o2, dat] = montage(o2, 'axial', 'slice_range', [-40 50], 'onerow', 'spacing', 8, 'noverbose');
                enlarge_axes(gcf, 1);
                axh = axes('Position', [-0.03 0.15 .2 1]);
                o2 = montage(o2, 'volume_data', dat, 'saggital', 'wh_slice', [0 0 0], 'existing_axes', axh, 'noverbose');

                % shift all axes down and right
                shift_axes(+0.03, -0.10);

                %ss = get(0, 'ScreenSize');
                %set(gcf, 'Position', [round(ss(3)/12) round(ss(4)*.9) round(ss(3)*.8) round(ss(4)/5.5) ])

            otherwise error('illegal montage type. choose full or compact when adding to existing montage set.')
        end

        wh_montages = existingmons + [1 2];

    else
        if doremove
            o2 = removeblobs(o2);
        end

        wh_montages = 1:existingmons;
        wh_surfaces = 1:existingsurs;

    end

end

% Now we can add blobs
% --------------------------------------------

% they are added to all montages by default, but you can specify selected
% montages if you want to as well.

% it's easy to remove them as well:
% o2 = removeblobs(o2);

if doblobs
    if exist('wh_surfaces', 'var')
        o2 = addblobs(o2, cl, 'splitcolor', splitcolor, 'wh_montages', wh_montages, 'wh_surfaces', wh_surfaces, 'nolegend', varargin{:});
    else
        o2 = addblobs(o2, cl, 'splitcolor', splitcolor, 'wh_montages', wh_montages, varargin{:});
    end
end

if dooutline
    o2 = addblobs(o2, cl, 'color', outlinecolor, 'outline', 'wh_montages', wh_montages, 'no_surface');
end

% ------------------------------------------------------
% INLINE FUNCTIONS
% ------------------------------------------------------

    function shift_axes(x_offset, y_offset)

        % usage:   function shift_axes(-0.03, -0.18);
        % purpose: To shift axes according of the habdles.
        %
        % input:   Function parameters are (x, y) offset relative to current position

        % shift all axes according to offset values
        allaxh = findobj(gcf, 'Type', 'axes');
        for i = 1:length(allaxh)
            pos1 = get(allaxh(i), 'Position');
            pos1(2) = pos1(2) + y_offset;
            pos1(1) = pos1(1) + x_offset;
            set(allaxh(i), 'Position', pos1);
        end
    end % shift_axes

end  % function


% The COBRAToolbox: testEfmBackboneExtraction.m
%
% Purpose:
%     - test extraction of backbone from a given set of EFMs
%
% Authors:
%     - Created initial test script: Chaitra Sarathy 2 Dec 19
%     - Updates to header docs: Chaitra Sarathy 19 Dec 19

solvers = prepareTest('requiredToolboxes', {'statistics_toolbox'});

global CBTDIR

% save the current path and initialize the test
currentDir = cd(fileparts(which(mfilename)));

% determine the test path for references
testPath = pwd;

% Load reference data
load([testPath filesep 'testData_efmBackboneExtraction.mat']);

% This is a function with two required inputs:
% Case 1: Test whether efmBackboneExtraction gives the expected output when using 2 input and 2 output arguments
[selectedRxns,  rxnDistribution] = efmBackboneExtraction(testEFMRxns, percentage);
assert(isequal(selectedRxns, selectedRxns_ref));
assert(isequal(rxnDistribution,rxnDistribution_ref));

% Case 2: Test whether efmBackboneExtraction throws an error when using 1 input argument only
assert(verifyCobraFunctionError('efmBackboneExtraction', 'inputs', {testEFMRxns}, 'outputArgCount', 1));

% Case 3: Test whether efmBackboneExtraction throws an error when using NO input arguments
assert(verifyCobraFunctionError('efmBackboneExtraction', 'inputs', {}, 'outputArgCount', 1));


function [refinedModel,summary] = performDataDrivenRefinement(model, microbeID, biomassReaction, database, inputDataFolder,summary)
% This function is part of the DEMETER pipeline and performs data-driven
% refinement of a genome-scale reconstruction based on available
% species-specific experimental data.
%
% USAGE
%      [model,summary] = performDataDrivenRefinement(model, microbeID, biomassReaction, database, inputDataFolder,summary)
%
% INPUTS
% model             COBRA model structure to refine
% microbeID         ID of the reconstructed microbe that serves as the
%                   reconstruction name and to identify it in input tables
% inputDataFolder   Folder with input tables with experimental data and
%                   databases that inform the refinement process
% summary           Structure with information on performed refinement
%
% OUTPUT
% refinedModel      Refined COBRA model structure
% summary           Structure with information on performed refinement
%
% .. Authors:
%       - Almut Heinken and Stefania Magnusdottir, 2016-2021

%% Fermentation pathways
% Based on the fermentation pathway data for the microbe (table prepared above),
% add and remove reactions as defined in the following script.
% Perform fermentation pathway gap fill:
[model, addedRxns, removedRxns] = fermentationPathwayGapfill(model, microbeID, database, inputDataFolder);
summary.('addedRxns_fermentation') = addedRxns;
summary.('removedRxns_fermentation') = removedRxns;
%% Carbon sources
% Based on the carbon source data for the microbe (table prepared above), add
% and remove reactions as defined in the following script.
% Perform carbon source pathway gap fill:
[model, addedRxns, removedRxns] = carbonSourceGapfill(model, microbeID, database, inputDataFolder);
summary.('addedRxns_carbonSources') = addedRxns;
summary.('removedRxns_carbonSources') = removedRxns;
%% Putrefaction pathways
[model,putrefactionRxnsAdded]=putrefactionPathwaysGapfilling(model,microbeID,database);
summary.('putrefactionRxnsAdded') = putrefactionRxnsAdded;
%% Known secretion products
[model,secretionRxnsAdded] = secretionProductGapfill(model,microbeID,database,inputDataFolder);
summary.('secretionRxnsAdded') = secretionRxnsAdded;
%% Known consumed metabolites
[model,uptakeRxnsAdded] = uptakeMetaboliteGapfill(model,microbeID,database, inputDataFolder);
summary.('uptakeRxnsAdded') = uptakeRxnsAdded;

%% test pathways to make sure they work

model = rebuildModel(model,database,biomassReaction);

FNs = {};
% Carbon sources
[TruePositives, FalseNegatives] = testCarbonSources(model, microbeID, biomassReaction, database, inputDataFolder);
FNs=union(FNs,FalseNegatives);

% Metabolite uptake
[TruePositives, FalseNegatives] = testMetaboliteUptake(model, microbeID, biomassReaction, database, inputDataFolder);
FNs=union(FNs,FalseNegatives);

%% gapfill if there are any false negatives
osenseStr='min';

dataDrivenGapfill={};
if ~isempty(FNs)
    for j=1:length(FNs)
        metExch=['EX_' database.metabolites{find(strcmp(database.metabolites(:,2),FNs{j})),1} '(e)'];
        % find reactions that could be gap-filled to enable flux
        % seems to try to fix exchanges that are not part of the model,
        % leading it to crash:
        %         Objective reactions not found in model!
        %
        % Error in runGapfillingFunctions (line 41)
        % model = changeObjective(model, objectiveFunction);
     %   add exchange reaction
     if isempty(find(strcmp(model.rxns,metExch)))
         met = [database.metabolites{find(strcmp(database.metabolites(:,2),FNs{j}))} '(e)'];
         model = addExchangeRxn(model,met,-1,1000);
     end
     [model,gapfilledRxns] = runGapfillingFunctions(model,metExch,biomassReaction,osenseStr,database);
     dataDrivenGapfill=union(dataDrivenGapfill,gapfilledRxns);
     %  end
    end
    if ~isempty(dataDrivenGapfill)
        summary.('DataDrivenGapfill')=dataDrivenGapfill;
    end
end

% Fermentation products
[TruePositives, FalseNegatives] = testFermentationProducts(model, microbeID, biomassReaction, database, inputDataFolder);
FNs=union(FNs,FalseNegatives);

% Putrefaction pathways
[TruePositives, FalseNegatives] = testPutrefactionPathways(model, microbeID, biomassReaction, database);
FNs=union(FNs,FalseNegatives);

% Secretion products
[TruePositives, FalseNegatives] = testSecretionProducts(model, microbeID, biomassReaction, database, inputDataFolder);
FNs=union(FNs,FalseNegatives);

% gapfill if there are any false negatives
osenseStr='max';

if ~isempty(FNs)
    for j=1:length(FNs)
        metInd=find(strcmp(database.metabolites(:,2),FNs{j}));
        if length(metInd)>1
            metInd=metInd(1);
        end
        metExch=['EX_' database.metabolites{metInd,1} '(e)'];
        if isempty(find(ismember(model.rxns,metExch)))
            % reaction ID itself provided
            metExch = FNs{j};
        end
        % find reactions that could be gap-filled to enable flux
        try
        [model,condGF,targetGF,relaxGF] = runGapfillingFunctions(model,metExch,biomassReaction,osenseStr,database);
        catch
        end
        summary.('conditionSpecificGapfill') = union(summary.('conditionSpecificGapfill'),condGF);
        summary.('targetedGapfill') = union(summary.('targetedGapfill'),targetGF);
        summary.('relaxFBAGapfill') = union(summary.('relaxFBAGapfill'),relaxGF);
    end
end

%% change back to biomass reaction
refinedModel=changeObjective(model,biomassReaction);

end


function showfigs()
%
% The function showfigs() generates a "slide show" of all open figures,
% bringing each open figure to the fore in turn and then pausing until the
% user issues a command by pressing a key.  Key commands are as follows:
%
% - Press Enter, down-arrow, or spacebar to advance to the next figure
% (next higher figure number).  If the current figure is the last (highest
% figure number), the slide show returns to figure 1.
%
% - Press the up-arrow key to return to the previous figure (next lower
% figure number).  If the current figure is figure 1, the slide show cycles
% back to the last figure (highest figure number).
%
% - Press a numeric key to display the figure whose handle has that value.
% If the user presses 0 (zero), the figure having a handle value of 10 is
% displayed.  If there is no figure corresponding to the key that was
% pressed, showfigs() writes an error message to the command window,
% generates a beep, and then continues running.
%
% - Press the Delete key to close the current figure window.  showfigs()
% decrements the figure handle number (wrapping around from 1 to the
% highest figure number if necessary) until a handle number corresponding
% to a figure that is still open is found, and will then display that
% figure.  (If all figures have been deleted, an error message is displayed
% and showfigs() terminates).
%
% - Press the End key to display the last figure (highest figure number,
% not counting any figures that have been deleted).
%
% - Press the Home key to display the first figure (lowest figure number,
% not counting any figures that have been deleted).
%
% - Press Escape or "q" to terminate the slide show.
%
% If the user presses a key that does not correspond to any showfigs()
% command, showfigs() writes an error message to the command window,
% generates a beep, and then terminates.
%
% Author: Dr. Phillip M. Feldman
%
% Note: I'd like to acknowledge many helpful suggestions from Jen Dobson of
% the MathWorks.
%
% Revision History
%
% Version 1.4, 18 Jun 2009: Modified so that pressing an invalid key does
% not eliminate the callback function (which had the effect of terminating
% the slideshow).  Added code to handle right and left arrows.
%
% Version 1.3, 7 May 2009: Streamlined code that handles numeric keys.
% Added support for "0" key (brings up figure having handle==10).  Added
% error messages.  Added sound feedback to alert user when an invalid key
% has been pressed.
%
% Version 1.2, 7 May 2009: Fixed bug (code that processes numeric keys was
% assuming that handle numbers start with 1 and are consecutive, which is
% not always true).
%
% Version 1.1, 6 May 2009: Modified code to check for deleted figures using
% ishandle() function.
%
% Version 1.0, 5 May 2009: Initial version.

global handles current;

% Find all objects of type axes:
handles= findobj(0, '-depth',1, 'type','figure');

if isempty(handles)
   fprintf(2,'There are no figures to display.\n');
   return
end

% Sort handles so that figures will be displayed in order:
handles= sort(handles);

% Place first figure on top:
figure(handles(1));
current= 1;

% Define callback function to process key presses:
set(handles(1), 'KeyPressFcn',@key_press_handler);

end % function showfigs()

function key_press_handler(source,event)
% keyPressFcn automatically takes in two inputs:
% - source is the object that was active when the keypress occurred
% - event stores the data for the key pressed

global handles current;

% Bring in the handles structure in to the function
handle= guidata(source);

% Remove callback for current figure:
set(handles(current), 'KeyPressFcn',[]);

k= event.Key; % k is the key that is pressed

% The user can press the Escape key or "q" to end the slide show.  Since we
% have already removed the callback, there is nothing more to be done:

if strcmp(k,'escape') | strcmp(k,'q'), return; end

if strcmp(k,'return') | strcmp(k,'downarrow') ...
   | strcmp(k,'rightarrow') | strcmp(k,'space')
   for i= 1 : length(handles)
      current= current + 1;
      if current > length(handles), current= 1; end
      if ishandle(handles(current)), break; end
   end

elseif strcmp(k,'uparrow') | strcmp(k,'leftarrow')
   for i= 1 : length(handles)
      current= current - 1;
      if current < 1, current= length(handles); end
      if ishandle(handles(current)), break; end
   end

elseif strcmp(k,'end')
   for current= length(handles) : -1 : 1
      if ishandle(handles(current)), break; end
   end

elseif strcmp(k,'home')
   for current= 1 : length(handles)
      if ishandle(handles(current)), break; end
   end

% If the user pressed a numeric key, try to activate the figure having the
% corresponding handle number:

elseif strfind('1234567890',k)
   i= str2num(k);
   if i == 0, i= 10; end
   if ishandle(i)
      current= find(handles==i);
   else
      fprintf(2,'There is no figure having handle==%d.\n', i);
      % Play a sound to alert user that an invalid key was pressed:
      play_sound(3);
   end

elseif strcmp(k,'delete')
   close(handles(current));
   for i= 1 : length(handles)
      current= current - 1;
      if current < 1, current= length(handles); end
      if ishandle(handles(current)), break; end
   end
   if ~ishandle(handles(current))
      fprintf(2,'All figures have been deleted.\n');
      return
   end

else
   fprintf('showfigs() does not know how to handle the "%s" key.\n', k);
   play_sound(3);
end

if current > length(handles)
   fprintf(2,'The is no figure number %d.\n', current);
   play_sound(3);
   return
end

% Allow time to update:
pause(0.01);

% Make specified figure visible and raise it above all other figures:
figure(handles(current));

% Define callback function to process key presses:
set(handles(current), 'KeyPressFcn',@key_press_handler);

end % function key_press_handler(source,event)


function varargout = ProgramPerhitunganSel(varargin)
% PROGRAMPERHITUNGANSEL M-file for ProgramPerhitunganSel.fig
%      PROGRAMPERHITUNGANSEL, by itself, creates a new PROGRAMPERHITUNGANSEL or raises the existing
%      singleton*.
%
%      H = PROGRAMPERHITUNGANSEL returns the handle to a new PROGRAMPERHITUNGANSEL or the handle to
%      the existing singleton*.
%
%      PROGRAMPERHITUNGANSEL('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in PROGRAMPERHITUNGANSEL.M with the given input arguments.
%
%      PROGRAMPERHITUNGANSEL('Property','Value',...) creates a new PROGRAMPERHITUNGANSEL or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before ProgramPerhitunganSel_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to ProgramPerhitunganSel_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help ProgramPerhitunganSel

% Last Modified by GUIDE v2.5 06-Jul-2012 06:01:29

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @ProgramPerhitunganSel_OpeningFcn, ...
    'gui_OutputFcn',  @ProgramPerhitunganSel_OutputFcn, ...
    'gui_LayoutFcn',  [] , ...
    'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before ProgramPerhitunganSel is made visible.
function ProgramPerhitunganSel_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to ProgramPerhitunganSel (see VARARGIN)

% Choose default command line output for ProgramPerhitunganSel
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes ProgramPerhitunganSel wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = ProgramPerhitunganSel_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --------------------------------------------------------------------
function Program_Menu_Callback(hObject, eventdata, handles)
% hObject    handle to Program_Menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------
function Info_Menu_Callback(hObject, eventdata, handles)
% hObject    handle to Info_Menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------
function Program_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Program_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
guidata(infogram);

% --------------------------------------------------------------------
function Perancang_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Perancang_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
guidata(Biodata);

% --------------------------------------------------------------------
function Automatic_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Automatic_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
guidata(Otomatis);
close(ProgramPerhitunganSel);

% --------------------------------------------------------------------
function Step_by_step_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Step_by_step_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
guidata(HitungSeltotal);
close(ProgramPerhitunganSel);

% --------------------------------------------------------------------
function Exit_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Exit_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close;

% --------------------------------------------------------------------
function Parasit_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Parasit_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
guidata(Parasit);

% --- Executes during object creation, after setting all properties.
function axes6_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axes6
axes(hObject);
imshow('halutama.jpg');

% --------------------------------------------------------------------
function Malaria_Menu_Item_Callback(hObject, eventdata, handles)
% hObject    handle to Malaria_Menu_Item (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
guidata(Malaria);


function erase_string(str)
% Backspaces the number of chars of the length of str

    fprintf(1, repmat('\b', 1, length(str)));
end


function zD = cvx_newcnstr( zb, iseq, need_dual )

global cvx___
try
    pstr = cvx___.problems(end);
catch
    cvx_throw( 'No CVX model is present.' );
end
if isa( zb, 'cvx' ),
    zb = cvx_basis( zb );
end
[nN,mN] = size( zb );
isr = isreal( zb );
if ~isr,
    mN = 2 * mN;
    zb = reshape( [ real(zb) ; imag(zb) ], nN, mN );
end
if ~iseq,
    ndim = cvx_pushnneg( mN );
    zb(ndim(end),1) = 0;
    zb = zb + sparse( ndim, 1:mN, -1 );
end
cvx___.equalities{end+1} = zb;
cvx___.inequality(end+1) = ~iseq;
mO = cvx___.n_equality;
cvx___.n_equality = mO + mN;
cp = pstr.checkpoint(4);
if cp > 1,
    x = find( any( zb, 2 ), 2, 'first' );
    if any( x > 1 & x <= cp ),
        cvx___.problems(end).checkpoint(4) = x(1+(x(1)==1)) - 1;
    end
end
if nargout
    if nargin == 3 && need_dual
        zD = sparse( mO + 1 : mO + mN, 1 : mN, 1 );
        if ~isr, zD = zD(:,1:2:end) + 1j * zD(:,2:2:end); end
    else
        zD = [];
    end
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.


function cnn_epoch_evaluate(work_info, opts, imdb, net_config, work_info_epoch)

if ~work_info.ref.run_eva
    return;
end

if opts.use_dummy_gt
    return;
end

eva_param=opts.eva_param;
class_info=eva_param.class_info;

eva_result_epoch=work_info_epoch.ref.eva_result;
valid_task_flags=work_info_epoch.ref.valid_task_flags;

seg_eva_result_imgs_coarse=work_info_epoch.ref.seg_eva_result_imgs_coarse;
if ~isempty(valid_task_flags)
    seg_eva_result_imgs_coarse=seg_eva_result_imgs_coarse(valid_task_flags);
end
assert(~isempty(seg_eva_result_imgs_coarse));
seg_eva_result_ds_coarse=gen_predict_result(seg_eva_result_imgs_coarse, class_info);

eva_result_epoch.seg_accuracy_global_coarse=seg_eva_result_ds_coarse.accuracy_global;
eva_result_epoch.seg_accuracy_per_class_coarse=seg_eva_result_ds_coarse.accuracy_per_class;
eva_result_epoch.seg_inter_union_score_per_class_coarse=seg_eva_result_ds_coarse.inter_union_score_per_class;
eva_result_epoch.exclude_class_idxes_coarse=seg_eva_result_ds_coarse.exclude_class_idxes;

seg_eva_result_imgs=work_info_epoch.ref.seg_eva_result_imgs;
if ~isempty(valid_task_flags)
    seg_eva_result_imgs=seg_eva_result_imgs(valid_task_flags);
end
assert(~isempty(seg_eva_result_imgs));
seg_eva_result_ds=gen_predict_result(seg_eva_result_imgs, class_info);

eva_result_epoch.seg_accuracy_global=seg_eva_result_ds.accuracy_global;
eva_result_epoch.seg_accuracy_per_class=seg_eva_result_ds.accuracy_per_class;
eva_result_epoch.seg_inter_union_score_per_class=seg_eva_result_ds.inter_union_score_per_class;
eva_result_epoch.exclude_class_idxes=seg_eva_result_ds.exclude_class_idxes;

seg_eva_result_ds_densecrf=[];
if eva_param.eva_densecrf_postprocess

    seg_eva_result_imgs_densecrf=work_info_epoch.ref.seg_eva_result_imgs_densecrf;
    if ~isempty(valid_task_flags)
        seg_eva_result_imgs_densecrf=seg_eva_result_imgs_densecrf(valid_task_flags);
    end
    assert(~isempty(seg_eva_result_imgs_densecrf));
    seg_eva_result_ds_densecrf=gen_predict_result(seg_eva_result_imgs_densecrf, class_info);

    eva_result_epoch.seg_accuracy_global_densecrf=seg_eva_result_ds_densecrf.accuracy_global;
    eva_result_epoch.seg_accuracy_per_class_densecrf=seg_eva_result_ds_densecrf.accuracy_per_class;
    eva_result_epoch.seg_inter_union_score_per_class_densecrf=seg_eva_result_ds_densecrf.inter_union_score_per_class;
    eva_result_epoch.exclude_class_idxes_densecrf=seg_eva_result_ds_densecrf.exclude_class_idxes;
end

eva_names=cell(0, 1);
eva_names_disp=cell(0, 1);

% eva_names{end+1, 1}='seg_accuracy_global_coarse';
% eva_names_disp{end+1, 1}='seg accuracy global (coarse)';

% eva_names{end+1, 1}='seg_accuracy_per_class_coarse';
% eva_names_disp{end+1, 1}='seg accuracy perclass (coarse)';

eva_names{end+1, 1}='seg_inter_union_score_per_class_coarse';
eva_names_disp{end+1, 1}='IoU (coarse)';

eva_names{end+1, 1}='seg_accuracy_global';
eva_names_disp{end+1, 1}='accuracy global';

eva_names{end+1, 1}='seg_accuracy_per_class';
eva_names_disp{end+1, 1}='accuracy perclass';

eva_names{end+1, 1}='seg_inter_union_score_per_class';
eva_names_disp{end+1, 1}='IoU';

eva_result_epoch.eva_names=cat(1, eva_result_epoch.eva_names, eva_names);
eva_result_epoch.eva_names_disp=cat(1, eva_result_epoch.eva_names_disp, eva_names_disp);

work_info_epoch.ref.eva_result=eva_result_epoch;

fprintf('\n\n------------------------------------------------------------\n');

fprintf('\n\nevaluate result (coarse):\n');
disp(seg_eva_result_ds_coarse);

fprintf('\n\n------------------------------------------------------------\n');
disp_eva_result(seg_eva_result_ds, class_info)

fprintf('\n\nevaluate result:\n');
disp(seg_eva_result_ds);

if ~isempty(seg_eva_result_ds_densecrf)
    fprintf('\n\n------------------------------------------------------------\n');
    disp_eva_result(seg_eva_result_ds_densecrf, class_info)

    fprintf('\n\nevaluate result (densecrf):\n');
    disp(seg_eva_result_ds_densecrf);

end

end

function disp_eva_result(pixel_result, class_info)

fprintf('\n\nCategory result:\n');
class_num=class_info.class_num;
class_label_values=class_info.class_label_values;

for c_idx=1:class_num

	one_label_value=class_label_values(c_idx);
    class_name=class_info.class_names{c_idx};

    one_iou=pixel_result.inter_union_score_classes(c_idx);
    one_acc=pixel_result.accuracy_classes(c_idx);

    fprintf('class_idx:%d, label_vale:%d, class_name:%s, pixel_acc:%.4f, IoU:%.4f\n', c_idx, one_label_value, class_name, one_acc, one_iou);
end

end

function pixel_result=gen_predict_result(pixel_results, class_info)

    exclude_class_idxes=class_info.void_class_idxes;
    class_num=class_info.class_num;
    img_num=length(pixel_results);

    pixel_con_mat=zeros(class_num, class_num);

    for img_idx_idx=1:img_num
        one_pixel_result=pixel_results{img_idx_idx};
        pixel_con_mat=pixel_con_mat+one_pixel_result.confusion_mat;
    end

    pixel_result=seg_eva_gen_result_from_con_mat(pixel_con_mat, exclude_class_idxes);

    predict_result=[];
    predict_result.class_num=class_num;
    predict_result.pixel_result=pixel_result;
    predict_result.exclude_class_idxes=exclude_class_idxes;

end


% EEG_FINDBOUNDARIES - return indices of boundary events
%
% Usage:
%   >> boundaryIndices = eeg_findboundaries(INEEG);
%   >> boundaryIndices = eeg_findboundaries(INEEG.event);
%
% Inputs:
%   INEEG         - input EEG dataset structure. Used to check if event
%                   types are string or numerical.
%
% Outputs:
%   boundaryIndices - indices of boundary events
%
% Author: Arnaud Delorme, 2022
%
% see also: EEGLAB

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

function boundaries = eeg_findboundaries(EEG)

    if nargin < 1
        help eeg_findboundaries;
        return
    end

    boundaries = [];
    if isempty(EEG)
        return;
    end

    if isfield(EEG, 'event') && isfield(EEG, 'setname')
        tmpevent = EEG.event;
    else
        tmpevent = EEG;
    end

    if ~isfield(tmpevent, 'type')
        return;
    end

    % type of boundary event
    eeglab_options;
    if ischar(tmpevent(1).type)
        boundaries = strmatch('boundary', { tmpevent.type });
    elseif option_boundary99
        boundaries = find([ tmpevent.type ] == -99);
    else
        boundaries = [];
    end


function [net_config, exp_info]=cnn_load_model(input_path)

  % input_path can be a cached model file, or a folder which contains the
  % model file and the file name follow the pattern: net-config*.mat

  net_config=[];
  exp_info=[];

  fprintf('check model: %s \n', input_path);
  if ~my_check_file(input_path)
    return;
  end

  if exist(input_path, 'dir')

      model_dir=input_path;
      net_config_file=fullfile(model_dir, 'net-config*.mat');
      net_config_file=my_findfile_by_pattern(net_config_file);

      info_file=fullfile(model_dir, 'exp-info*.mat');
      info_file=my_findfile_by_pattern(info_file);

  else

      net_config_file=input_path;
      info_file=[];

  end

  if isempty(net_config_file)
      return;
  end
  net_config=load(net_config_file);
  net_config=net_config.net_config;
  process_dagnn_load(net_config);
  fprintf('model loaded from: %s\n', net_config_file);

  if ~isempty(info_file)
    exp_info=load(info_file) ;
    exp_info=exp_info.exp_info;
    fprintf('exp_info loaded from: %s\n', info_file);
  end

end

function dag_net=fix_dagnn_name(dag_net)

check_file_names={'inputs'; 'outputs'; 'params'};

for l_idx=1:length(dag_net.layers)
    for f_idx=1:length(check_file_names)
        one_field_name=check_file_names{f_idx};
        one_v=dag_net.layers(l_idx).(one_field_name);
        if size(one_v, 1)>1
            dag_net.layers(l_idx).(one_field_name)=one_v';
        end
    end
end

end

function group_info=fix_layer_name(group_info)

  % for legacy model

    if ~isempty(group_info.net_info)
      net_info=group_info.net_info;
        for l_idx=1:length(net_info.ref.layers)
            tmp_layer=net_info.ref.layers{l_idx};
            if isfield(tmp_layer, 'custom_type')
              if strcmp(tmp_layer.custom_type, 'unary_softmaxloss')
                  tmp_layer.custom_type='dense_softmaxloss';
                  net_info.ref.layers{l_idx}=tmp_layer;
              end
            end
        end
    end
end

function process_dagnn_load(net_config)

assert(isa(net_config, 'ref_obj'));

for group_idx=1:length(net_config.ref.group_infos)
    group_info=net_config.ref.group_infos{group_idx};

    group_info=fix_layer_name(group_info);

    if check_group_dag_net(group_info)
        fprintf('processing dag_net for loading, group_idx:%d, group_name: %s\n', group_info.group_idx, group_info.name);
        group_info.dag_net=fix_dagnn_name(group_info.dag_net);
        group_info.dag_net = dagnn.DagNN.loadobj(group_info.dag_net) ;
        net_config.ref.group_infos{group_idx}=group_info;
    end
end

end

function use_dagnn=check_group_dag_net(group_info)

    use_dagnn=isfield(group_info, 'dag_net') && ~isempty(group_info.dag_net);
    if isfield(group_info, 'use_dagnn') && group_info.use_dagnn
        assert(use_dagnn==group_info.use_dagnn);
    end

end

function result=my_findfile_by_pattern(net_config_file)

  result=[];

  file_info=dir(net_config_file);
  if isempty(file_info)
      return
  end
  file_info=file_info(1);
  onedir=fileparts(net_config_file);
  result=fullfile(onedir, file_info.name);

end


function x=uplus(x)


function convnfft_install
% function convnfft_install
% Installation by building the C-mex file needed for convnfft
%
% Author: Bruno Luong <brunoluong@yahoo.com>
% History
%  Original: 16/Sept/2009

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

% invoke MEX compilation tool
mex(mexopts{:},'inplaceprod.c');


% forcecol.m
% function to force a vector to be a single column
%
% Brian Birge
% Rev 1.0
% 7/1/98

function[out]=forcecol(in)
len=prod(size(in));
out=reshape(in,[len,1]);


function [metabolite_structure,errorFlag] = sanityCheckMetIds(metabolite_structure,removeErrors)
% perform basic sanity checks

if ~exist('removeErrors', 'var')
    removeErrors = 0;
end

errorFlag = '';
Mets = fieldnames(metabolite_structure);
cnt = 1;
for i = 1 : length(Mets)
    % charge must be numeric
    if ~isnumeric(metabolite_structure.(Mets{i}).charge)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).charge;
        errorFlag{cnt,3} = 'charge is not numeric';
        cnt = 1 + cnt;
    end
    % avgmolweight must be numeric
    if  isfield(metabolite_structure.(Mets{i}),'avgmolweight')&& ~isnumeric(metabolite_structure.(Mets{i}).avgmolweight)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).avgmolweight;
        errorFlag{cnt,3} = 'avgmolweight is not numeric';
        cnt = 1 + cnt;

        if removeErrors
            % remove error
            metabolite_structure.(Mets{i}).avgmolweight = NaN;
            metabolite_structure.(Mets{i}).avgmolweight_source = [];
        end
    end
    % monoisotopicweight must be numeric
    if isfield(metabolite_structure.(Mets{i}),'monoisotopicweight')&& ~isnumeric(metabolite_structure.(Mets{i}).monoisotopicweight)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).monoisotopicweight;
        errorFlag{cnt,3} = 'monoisotopicweight is not numeric';
        cnt = 1 + cnt;
        if removeErrors
            % remove error
            metabolite_structure.(Mets{i}).monoisotopicweight = NaN;
            metabolite_structure.(Mets{i}).monoisotopicweight_source = [];
        end
    end
    % pubChemId must be numeric
    if isfield(metabolite_structure.(Mets{i}),'pubChemId')&&  ~isnumeric(metabolite_structure.(Mets{i}).pubChemId)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).pubChemId;
        errorFlag{cnt,3} = 'pubChemId is not numeric';
        cnt = 1 + cnt;

        if removeErrors
            % remove error
            metabolite_structure.(Mets{i}).pubChemId = NaN;
            metabolite_structure.(Mets{i}).pubChemId_source = [];
        end
    end
    % cheBIId must be numeric
    if isfield(metabolite_structure.(Mets{i}),'cheBIId')&&   ~isnumeric(metabolite_structure.(Mets{i}).cheBIId)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).cheBIId;
        errorFlag{cnt,3} = 'cheBIId is not numeric';
        cnt = 1 + cnt;

        if removeErrors
            % remove error
            metabolite_structure.(Mets{i}).cheBIId = NaN;
            metabolite_structure.(Mets{i}).cheBIId_source = [];
        end
    end
    % chemspider must be numeric
    if isfield(metabolite_structure.(Mets{i}),'chemspider')&& ~isnumeric(metabolite_structure.(Mets{i}).chemspider)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).chemspider;
        errorFlag{cnt,3} = 'chemspider is not numeric';
        cnt = 1 + cnt;

        if removeErrors
            % remove error
            metabolite_structure.(Mets{i}).chemspider = NaN;
            metabolite_structure.(Mets{i}).chemspider_source = [];
        end
    end
    % metlin must be numeric
    if isfield(metabolite_structure.(Mets{i}),'metlin')&& ~isnumeric(metabolite_structure.(Mets{i}).metlin)
        errorFlag{cnt,1} = Mets{i};
        errorFlag{cnt,2} = metabolite_structure.(Mets{i}).metlin;
        errorFlag{cnt,3} = 'metlin is not numeric';
        cnt = 1 + cnt;

        if removeErrors
            % remove error
            metabolite_structure.(Mets{i}).metlin = NaN;
            metabolite_structure.(Mets{i}).metlin_source = [];
        end
    end
    % keggId must start with C,D, or G
    if  isfield(metabolite_structure.(Mets{i}),'keggId') &&  isempty(find(isnan(metabolite_structure.(Mets{i}).keggId),1))
        if isnumeric(metabolite_structure.(Mets{i}).keggId) || isempty(regexp(metabolite_structure.(Mets{i}).keggId,'^C')) && isempty(regexp(metabolite_structure.(Mets{i}).keggId,'^D')) ...
                && isempty(regexp(metabolite_structure.(Mets{i}).keggId,'^G'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).keggId;
            errorFlag{cnt,3} = 'keggId does not start with C,D, or G';
            cnt = 1 + cnt;

            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).keggId = NaN;
                metabolite_structure.(Mets{i}).keggId_source = [];
            end
        end
    end
    % hmdb must start with HMDB
    if  isfield(metabolite_structure.(Mets{i}),'hmdb')&&  isempty(find(isnan(metabolite_structure.(Mets{i}).hmdb),1))
        if isnumeric(metabolite_structure.(Mets{i}).hmdb) || isempty(regexp(metabolite_structure.(Mets{i}).hmdb,'^HMDB'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).hmdb;
            errorFlag{cnt,3} = 'hmdb does not start with HMDB';
            cnt = 1 + cnt;

            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).hmdb = NaN;
                metabolite_structure.(Mets{i}).hmdb_source = [];
            end
        end
    end
    % reconMap3 must be equal to VMHId
    %     if isnumeric(metabolite_structure.(Mets{i}).reconMap3) || isempty(strmatch(metabolite_structure.(Mets{i}).VMHId,metabolite_structure.(Mets{i}).reconMap3,'exact')) && ...
    %             ~isempty(find(isnan(metabolite_structure.(Mets{i}).reconMap3)))
    %         errorFlag{cnt,1} = Mets{i};
    %         errorFlag{cnt,2} = metabolite_structure.(Mets{i}).reconMap3;
    %         errorFlag{cnt,3} = 'reconMap3 is not equal to VMHId';
    %         cnt = 1 + cnt;
    %     end

    % food_db must start with FDB
    if isfield(metabolite_structure.(Mets{i}),'food_db')&&   isempty(find(isnan(metabolite_structure.(Mets{i}).food_db),1))
        if isnumeric(metabolite_structure.(Mets{i}).food_db) ||isempty(regexp(metabolite_structure.(Mets{i}).food_db,'^FDB'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).food_db;
            errorFlag{cnt,3} = 'food_db does not start with FDB';
            cnt = 1 + cnt;

            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).food_db = NaN;
                metabolite_structure.(Mets{i}).food_db_source = [];
            end
        end
    end
    % metanetx must start with MNXM
    if isfield(metabolite_structure.(Mets{i}),'metanetx')&&  isempty(find(isnan(metabolite_structure.(Mets{i}).metanetx),1))
        if isnumeric(metabolite_structure.(Mets{i}).metanetx) ||isempty(regexp(metabolite_structure.(Mets{i}).metanetx,'^MNXM'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).metanetx;
            errorFlag{cnt,3} = 'metanetx does not start with MNXM';
            cnt = 1 + cnt;

            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).metanetx = NaN;
                metabolite_structure.(Mets{i}).metanetx_source = [];
            end
        end
    end
    % epa_id must start with DTX
    if  isfield(metabolite_structure.(Mets{i}),'epa_id')&&  isempty(find(isnan(metabolite_structure.(Mets{i}).epa_id),1))
        if isnumeric(metabolite_structure.(Mets{i}).epa_id) ||isempty(regexp(metabolite_structure.(Mets{i}).epa_id,'^DTX'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).epa_id;
            errorFlag{cnt,3} = 'epa_id does not start with DTX';
            cnt = 1 + cnt;

            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).epa_id = NaN;
                metabolite_structure.(Mets{i}).epa_id_source = [];
            end
        end
    end
    % seed must start with cpd
    if  isfield(metabolite_structure.(Mets{i}),'seed')&&  isempty(find(isnan(metabolite_structure.(Mets{i}).seed),1))
        if isnumeric(metabolite_structure.(Mets{i}).seed) ||isempty(regexp(metabolite_structure.(Mets{i}).seed,'^cpd'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).seed;
            errorFlag{cnt,3} = 'seed does not start with cpd';
            cnt = 1 + cnt;
            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).seed = NaN;
                metabolite_structure.(Mets{i}).seed_source = [];
            end
        end
    end
    % casRegistry must contain 2 -
    if isfield(metabolite_structure.(Mets{i}),'casRegistry')&& isempty(find(isnan(metabolite_structure.(Mets{i}).casRegistry),1))
        if isnumeric(metabolite_structure.(Mets{i}).casRegistry) ||isempty(regexp(metabolite_structure.(Mets{i}).casRegistry,'\d*-\d*-\d*'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).casRegistry;
            errorFlag{cnt,3} = 'casRegistry does not follow \d*-\d*-\d*';
            cnt = 1 + cnt;
            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).casRegistry = NaN;
                metabolite_structure.(Mets{i}).casRegistry_source = [];
            end
        end
    end
    % inchiKey must contain 2 -
    if  isfield(metabolite_structure.(Mets{i}),'inchiKey')&&  isempty(find(isnan(metabolite_structure.(Mets{i}).inchiKey),1))
        if isnumeric(metabolite_structure.(Mets{i}).inchiKey) ||isempty(regexp(metabolite_structure.(Mets{i}).inchiKey,'[A-Z]+-[A-Z]+-[A-Z]'))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).inchiKey;
            errorFlag{cnt,3} = 'inchiKey does not follow [A-Z]+-[A-Z]+-[A-Z]+';
            cnt = 1 + cnt;
            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).inchiKey = NaN;
                metabolite_structure.(Mets{i}).inchiKey_source = [];
            end
        end
    end
    % inchiString must start with InChI=
    if isfield(metabolite_structure.(Mets{i}),'inchiString')&& isempty(find(isnan(metabolite_structure.(Mets{i}).inchiString),1))
        if isnumeric(metabolite_structure.(Mets{i}).inchiString) ||isempty(regexp(metabolite_structure.(Mets{i}).inchiString,'^InChI='))
            errorFlag{cnt,1} = Mets{i};
            errorFlag{cnt,2} = metabolite_structure.(Mets{i}).inchiString;
            errorFlag{cnt,3} = 'inchiString does not follow ^InChI=';
            cnt = 1 + cnt;
            if removeErrors
                % remove error
                metabolite_structure.(Mets{i}).inchiString = NaN;
                metabolite_structure.(Mets{i}).inchiString_source = NaN;
            end
        end
    end
end


function bnet = bnet_from_engine(engine)
% BNET_FROM_ENGINE Return the bnet structure stored inside the engine (smoother_engine)
% bnet = bnet_from_engine(engine)

bnet = bnet_from_engine(engine.tbn_engine);


function selIdx = hierarchicalSelect(st)

selID = 567; % Cerebrum, default to start

[boxList, idList] = makeBoxList(st, selID);

ud.idList = idList; ud.st = st;

% make figure
f = figure; set(f, 'KeyPressFcn', @doOK);

% selector box
ud.hBox = uicontrol(f, 'Style', 'listbox', 'String', boxList, ...
    'Callback', @updateSel, 'Value', find(idList==selID),...
    'Units', 'normalized', 'Position', [0.1 0.2 0.8 0.7],...
    'KeyPressFcn', @doOK);

titleStr = boxList{idList==selID}; titleStr = titleStr(find(titleStr~=' ', 1):end);
ud.hSelTitle = uicontrol(f, 'Style', 'text', ...
    'String', sprintf('Selected: %s', titleStr), ...
    'Units', 'normalized', 'Position', [0.1 0.9 0.8 0.1]);

ud.hCancel = uicontrol(f, 'Style', 'pushbutton', ...
    'String', 'Cancel', 'Callback', @doCancel, ...
    'Units', 'normalized', 'Position', [0.1 0.1 0.2 0.1]);

ud.hOK = uicontrol(f, 'Style', 'pushbutton', ...
    'String', 'OK', 'Callback', @doOK, ...
    'Units', 'normalized', 'Position', [0.3 0.1 0.2 0.1]);

set(f, 'UserData', ud);
drawnow;

% AP: internal matlab command didn't work for Mac users, removed
% try
%     c = matlab.ui.internal.dialog.DialogUtils.disableAllWindowsSafely();
%     uiwait(f);
%     delete(c);
% catch
%     if ishghandle(f)
%         delete(f)
%     end
% end
uiwait(f);

if ishghandle(f)
    ud = get(f, 'UserData');
    idList = ud.idList;

    if ud.hBox.Value>1
        selID = idList(get(ud.hBox, 'Value'));

        selIdx = find(st.id==selID);
    else
        selIdx = [];
    end
    delete(f)
    drawnow;
else
    selIdx = [];
end

end

function [boxList, idList] = makeBoxList(st, selID)

idList = selID;
while idList(end)~=997 % root
    idList(end+1) = st.parent_structure_id(st.id==idList(end));
end
idList = idList(end:-1:1); % this is the tree of parents down to the selected one

% make the parent string representation
for q = 1:numel(idList)
    boxList{q} = sprintf('%s%s (%s)', repmat('  ', 1, q-1), ...
        st.acronym{st.id==idList(q)}, ...
        st.safe_name{st.id==idList(q)});
end
np = numel(idList);

% now add children
idList = [idList st.id(st.parent_structure_id==selID)'];

% make the parent string representation
for q = np+1:numel(idList)
    boxList{q} = sprintf('%s%s (%s)', repmat('  ', 1, np), ...
        st.acronym{st.id==idList(q)}, ...
        st.safe_name{st.id==idList(q)});
end

end

function updateSel(src, ~)

f = get(src, 'Parent');
ud = get(f, 'UserData');
st = ud.st; idList = ud.idList;

selID = idList(get(src, 'Value'));

[boxList, idList] = makeBoxList(st, selID);

ud.idList = idList;
set(f, 'UserData', ud);
set(src, 'String', boxList, 'Value', find(idList==selID));

titleStr = boxList{idList==selID}; titleStr = titleStr(find(titleStr~=' ', 1):end);
set(ud.hSelTitle, 'String', sprintf('Selected: %s', titleStr));

end

% OK callback
function doOK(~, ~)
    uiresume(gcbf);
end

% Cancel callback
function doCancel(~, ~)
ud = get(gcbf, 'UserData');
ud.hBox.Value = 1;
uiresume(gcbf);
end


function bz_PreprocessExtracellEphysSession(basepath)

if ~exist('basepath','var')
    basepath = cd;
elseif isempty(basepath)
    basepath = cd;
end

%% Assuming one already did bz_SetAnimalMetadata
bz_RunSessionMetadata(basepath);

%% making an xml if needed
basename = bz_BasenameFromBasepath(basepath);
txmlname = fullfile(basepath,[basename '.xml']);
d = dir(txmlname);
load(fullfile(basepath,[basename '.SessionMetadata.mat']))
if isempty(d);%if no basename.xml already
    if isempty(SessionMetadata.ExtracellEphys.ParametersDivergentFromAnimalMetadata)%if not different from animal xml, copy the animal xml here
        ax = fullfile(SessionMetadata.AnimalMetadata.AnimalBasepath,[SessionMetadata.AnimalMetadata.AnimalName, '.xml']);
        if exist(ax,'file')
            copyfile(ax,txmlname);
        end
    end
end
d = dir(txmlname);
if isempty(d);%if no basename.xml already
    bz_MakeXML(basepath)
end

%%
disp('Concatenating .dat files')
bz_ConcatenateDats(basepath);
disp('Converting .dat to .lfp')
bz_LFPFromDat(basepath);


%--- help for mdd/mhm ---
%
%mdd/mhm is a function.
%    log_mhm = mhm(obj, mhm_tau, opts)
%


function [f, g] = gradFuncWrapper(x, func, grad, varargin)

% GRADFUNCWRAPPER Wrapper function to enable use of Carl Rasmussen's minimze function.

% OPTIMI

func = str2func(func);
grad = str2func(grad);
f = func(x', varargin{:});

if nargout > 1
  g = grad(x', varargin{:})';
end


% Following code bakes a birthday cake for someone special to whom you
% wanna surprise on his/her birthday with a cake in MATLAB ;)
%
% This is a chocolate flavored cake decorated with cheries on top ......
% yyuummmyy :) :)
%
% Lighted birthday candle has been put up on cake; Think of a wish and blow
% off candle by clicking on flame (yellowish in colour)... and here comes
% the celebration with birthday song.. :) :) .. Wish you a very very happy
% birthday..
%
% While running code, make sure that PC speakers are ON
%
% Cake prepared by Amol G. Mahurkar
%
% Birthday_gift.m Revisions
%
% Version 1.2   04/25/2013  A/V sync
%
% Version 1.1	12/19/2011
%
% Version 1.0	10/28/2011
%
% Please suggest some extra features you think should be in this birthday gift
%

%%
function Birthday_gift()

clc; clear; close all;

instruc = ['Happy Birthday !!!!',char(10),char(10),...
    'Here is a birthday cake for someone special,',char(10),char(10),...
    'Make sure that PC speakers are ON',char(10),char(10),...
    'This cake has following features:',char(10),...
    '1. Chocolate flavored... and yummy :) :) ',char(10),...
    '2. Decorated with cheries :) :)',char(10),...
    '3. Lighted birthday candle on top of it',char(10),char(10),...
    'Think of a wish, and',char(10),...
    'Blow off candle by clicking on flame (yellowish in colour, obviously)',char(10),...
    'Enjoy your birthday cake!!!',char(10),char(10),...
    'And ya, wish you a very happy birthday'];

if(~strcmp('Ok',questdlg(instruc,'Surprise !!!!!','Ok','Cancel','Ok')))
    quit;
end

global bday_name;
global your_name;
temp = inputdlg({'Birthday boy/girl name:','Best Wishes from:'});
bday_name = temp{1};
your_name = temp{2};
clear temp;
%% Base

n = 20;
theta = (0:n)/n*2*pi;
sintheta = sin(theta); sintheta(n+1) = 0;
m = 11;
r = ones(1,m)';
x1 = r * cos(theta);
y1 = r * sintheta;
z1 = (0:m-1)'/(m-1) * ones(1,n+1);

r = [1 1 linspace(0.8,0,9)]';
x2 = r * cos(theta);
y2 = r * sintheta;
z2 = ones(11,21);

%% Cherry

theta = (-n:2:n)/n*pi;
phi = (-n:2:n)'/n*pi/2;
cosphi = cos(phi); cosphi(1) = 0; cosphi(n+1) = 0;
sintheta = sin(theta); sintheta(1) = 0; sintheta(n+1) = 0;
x3 = 0.1.*cosphi*cos(theta);
y3 = 0.1.*cosphi*sintheta;
z3 = 0.1.*sin(phi)*ones(1,n+1);

%% Candle

x4=0.05.*ones(m,1)*cos(theta) + 0.5;
y4=0.05.*ones(m,1)*sintheta + 0.5;
z4 = (0:m-1)'/(m-1) * ones(1,n+1) + 0.5;

r11=linspace(0.05,0,10);
r11=[0.05 r11];
r11=r11';
x5=r11*cos(theta) + 0.5;
y5=r11*sintheta + 0.5;
z5 = linspace(1.5,1.8,11)' * ones(1,n+1);

%% Flame

theta = (-n:2:n)/n*pi;
phi = (-n:2:n)'/n*pi/2;
cosphi = cos(phi); cosphi(1) = 0; cosphi(n+1) = 0;
sintheta = sin(theta); sintheta(1) = 0; sintheta(n+1) = 0;
x6 = 0.04.*cosphi*cos(theta) + 0.5;
y6 = 0.04.*cosphi*sintheta + 0.5;
z6 = (linspace(1.7,2,21)')*ones(1,n+1);

%% Cake

[figure1, axes1] = figureset();
cake_w_flame(x1,x2,x3,x4,x5,x6,y1,y2,y3,y4,y5,y6,z1,z2,z3,z4,z5,z6,figure1,axes1,1);

again = 1;
while(again)
[xin yin] = ginput(1);
if(xin < 0.5 && xin > -1 && yin < 0.6 && yin > -1)
    again = 0;
    load('bday_song_8bit_11025.mat');
%     sound(song,11025,8);
    obj = audioplayer(song, 11025, 8);
    play(obj);
    close(figure1)
    [figure1, axes1] = figureset();
    cake_w_flame(x1,x2,x3,x4,x5,x6,y1,y2,y3,y4,y5,y6,z1,z2,z3,z4,z5,z6,figure1,axes1,0);
    eatmore = 'Wanna eat more ??  Use rotate tool or/and zoom in/out tool for it';
    msgbox(eatmore);
else
    while(~strcmp(questdlg('Blow off candle','Click on candle to blow it off','Ok','No'),'Ok'))
    end
    again = 1;
end
end

function [figure1, axes1] = figureset()

figure1 = figure('NumberTitle','off','Name','Wish you a very very happy birthday');

axes1 = axes('Visible','off','Parent',figure1,'PlotBoxAspectRatio',[1 1 1],...
    'DataAspectRatio',[1 1 1],'CameraViewAngle',10);
% 10.7508094342063
view(axes1,[-72.5 30]);
hold(axes1,'all');

oldRootUnits=get(0,'Units');
set(0,'Units','Pixels');
pos=get(0,'ScreenSize');
set(0,'Units',oldRootUnits);
maxPos=[-3 27 pos(3)+8 pos(4)-22];
oldUnits=get(figure1,'Units');
oldActivePositionProperty=get(figure1,'ActivePositionProperty');
set(figure1,'Units','Pixels','ActivePositionProperty','outerposition');
set(figure1,'Position',maxPos,'OuterPosition',maxPos);
set(figure1,'Units',oldUnits,'ActivePositionProperty',oldActivePositionProperty);

%% Cake w/wo flame
function cake_w_flame(x1,x2,x3,x4,x5,x6,y1,y2,y3,y4,y5,y6,z1,z2,z3,z4,z5,z6,~,axes1,flame)

global bday_name;
global your_name;

surf(x1,y1,z1,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[0.200000002980232 0 0]);
surf(x2,y2,z2,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[0.600000023841858 0.200000002980232 0]);

text('Parent',axes1,'String','Happy Birthday','Position',[-0.57 0.18 1.5],...
    'FontSize',28,...
    'FontName','Monotype Corsiva','Color',[1 0 0]);
text('Parent',axes1,'String',bday_name,'Position',[-0.3 -0.1 1.2],...
    'FontSize',28,...
    'FontName','Monotype Corsiva','Color',[1 0 0]);
text('Parent',axes1,'String',['Best Wishes from ',your_name],'Position',[-1.5 -1.5 1.5],...
    'FontSize',28,...
    'FontName','Monotype Corsiva','Color',[1 0 0]);
surf(x3+0,y3+0.8,z3+1.1,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[1 0 0]);
surf(x3+0,y3-0.8,z3+1.1,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[1 0 0]);
surf(x3+0.8,y3+0,z3+1.1,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[1 0 0]);

surf(x3-0.8,y3+0,z3+1.1,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[1 0 0]);
surf(x4,y4,z4,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[0.925490200519562 0.839215695858002 0.839215695858002]);
surf(x5,y5,z5,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[0.925490200519562 0.839215695858002 0.839215695858002]);
if(flame==1)
surf(x6,y6,z6,'Parent',axes1,'FaceLighting','phong',...
    'LineStyle','none',...
    'FaceColor',[1 1 0]);
end
light('Parent',axes1,'Style','local',...
    'Position',[-10.162701816704 -0.924193626363743 14.9951905283833]);

if(flame==0)
for i=1:110
view(axes1,[-10*i 20+0.2727*i])
pause(0.205)     %0.15
end
end
% EOF


function iq = acquireIqVector(mxa_ip)

% MATLAB/MXA example 7
% Getting IQ data using the MXA driver and plot display

% Version: 1.0
% Date: Sep 11, 2006
% 2006 Agilent Technologies, Inc.

% TCPIP parameters
mxa_port = 5025;

% MXA Interface creation and connection opening
mxa_if = tcpip(mxa_ip,mxa_port);
mxa = icdevice('agilent_mxa.mdd', mxa_if);
connect(mxa,'object')

% Get IQ data
iq = invoke(mxa,'getIQ');

% Close the MXA connection and clean up
disconnect(mxa);
delete(mxa);
clear mxa;


function favar = initializeFavarResults(opts)
% INITIALIZESTRCIDENT this function initalizes a strcident struct to store
% the results based on the already existing fields on the settings objet
arguments
    opts (1,1) bear.settings.BASEsettings
end

favar.FAVAR     = false;
favar.HDplot    = false;
favar.IRFplot   = false;
favar.FEVDplot  = false;

if isprop(opts, 'favar') && isa(opts.favar, 'bear.settings.favar.FAVARsettings') && opts.favar.FAVAR
    favar = initalizeFavar(opts.favar);
end
end

function favar = initalizeFavar(favarOpt)

p = properties(favarOpt);
for i = 1 : length(p)

    favar.(p{i}) = favarOpt.(p{i});

end

end


function test_suite = test_moxunit_util_strjoin
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_strjoin_basics
    aeq=@(a,varargin)assertEqual(moxunit_util_strjoin(varargin{:}),a);

    aeq('a b cc',{'a','b','cc'});
    aeq('a>#<b>#<cc',{'a','b','cc'}, '>#<');
    aeq(sprintf('a\tb\tcc'),{'a','b','cc'}, '\t');
    aeq('a\b\cc',{'a','b','cc'}, '\\');
    aeq('a+b=cc',{'a','b','cc'}, {'+','='});

function test_strjoin_exceptions
    aet=@(varargin)assertExceptionThrown(@()...
                        moxunit_util_strjoin(varargin{:}),'');

    % first argument must be cell with strings
    aet('a');
    aet(struct)
    aet(2);
    aet([]);
    aet({2});

    % second argument must be string or cell with strings
    aet({'a','b','c'},2);
    aet({'a','b','c'},struct);
    aet({'a','b','c'},[]);
    aet({'a','b','c'},[]);
    aet({'a','b','c'},{'x'});
    aet({'a','b','c'},{1,2});