function obj = updateRectangle(obj, rectIndex)

%----RECTANGLE FIELDS----%

% x - [DONE]
% y - [DONE]
% mode - [DONE]
% name - [DONE]
% text - [NOT SUPPORTED IN MATLAB]
% error_y - [HANDLED BY ERRORBAR]
% error_x - [HANDLED BY ERRORBAR]
% line.color - [DONE]
% line.width - [DONE]
% line.dash - [DONE]
% line.opacity - [NOT SUPPORTED IN MATLAB]
% line.smoothing - [NOT SUPPORTED IN MATLAB]
% line.shape - [NOT SUPPORTED IN MATLAB]
% connectgaps - [NOT SUPPORTED IN MATLAB]
% fill - [HANDLED BY RECTANGLE]
% fillcolor - [HANDLED BY RECTANGLE]
% opacity - [NOT SUPPORTED IN MATLAB]
% textfont - [NOT SUPPORTED IN MATLAB]
% textposition - [NOT SUPPORTED IN MATLAB]
% xaxis [DONE]
% yaxis [DONE]
% showlegend [DONE]
% stream - [HANDLED BY PLOTLYSTREAM]
% visible [DONE]
% type [DONE]

%-AXIS INDEX-%
axIndex = obj.getAxisIndex(obj.State.Plot(rectIndex).AssociatedAxis);

%-RECTANGLE DATA STRUCTURE- %
rect_data = get(obj.State.Plot(rectIndex).Handle);

%-CHECK FOR MULTIPLE AXES-%
[xsource, ysource] = findSourceAxis(obj,axIndex);

%-AXIS DATA-%
eval(['xaxis = obj.layout.xaxis' num2str(xsource) ';']);
eval(['yaxis = obj.layout.yaxis' num2str(ysource) ';']);

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

%-rectangle xaxis-%
obj.data{rectIndex}.xaxis = ['x' num2str(xsource)];

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

%-rectangle yaxis-%
obj.data{rectIndex}.yaxis = ['y' num2str(ysource)];

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

%-rectangle type-%
obj.data{rectIndex}.type = 'scatter';

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

%-rectangle x-%
obj.data{rectIndex}.x = [rect_data.Position(1) rect_data.Position(1) ...
    rect_data.Position(1) + rect_data.Position(3) ...
    rect_data.Position(1) + rect_data.Position(3) ...
    rect_data.Position(1)];

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

%-rectangle y-%
obj.data{rectIndex}.y = [rect_data.Position(2) rect_data.Position(2) + rect_data.Position(4) ...
    rect_data.Position(2) + rect_data.Position(4) ...
    rect_data.Position(2) ...
    rect_data.Position(2)];

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

%-rectangle name-%
obj.data{rectIndex}.name = rect_data.DisplayName;

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

%-rectangle mode-%
obj.data{rectIndex}.mode = 'lines';

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

%-rectangle fill-%
obj.data{rectIndex}.visible = strcmp(rect_data.Visible,'on');

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

%-rectangle fill-%
obj.data{rectIndex}.fill = 'tonexty';

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

%-rectangle line-%
obj.data{rectIndex}.line = extractPatchLine(rect_data);

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

%-rectangle fillcolor-%
fill = extractPatchFace(rect_data);
obj.data{rectIndex}.fillcolor = fill.color;

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

%-rectangle showlegend-%
leg = get(rect_data.Annotation);
legInfo = get(leg.LegendInformation);

switch legInfo.IconDisplayStyle
    case 'on'
        showleg = true;
    case 'off'
        showleg = false;
end

obj.data{rectIndex}.showlegend = showleg;

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

end


classdef prtDataSetClassReshape < prtDataSetClass & prtDataInterfaceReshape
    % An helper class that interfaces from prtDataSetClass and prtDataInterfaceReshape
    %
    % There are no additional methods. This just combines prtDataSetClass and the
    % mixin prtDataInterfaceReshape
    %
    %  Example:
    %     ds = prtDataSetClassReshape(randn(20,100), [], 'observationSize',[10 10]);
    %
    %     size(ds.getObservations(1))
    %     size(ds.getObservations)
    %     size(ds.getObservationsAsMat(1))
    %     size(ds.getObservationsAsMat)
    %     size(ds.getObservationsAsMat([1 3]))
    %     size(ds.getObservationsAsCell([1 3]))
    %     size(ds.getObservationsAsCell())
    %     cell2mat(cellfun(@size,ds.getObservationsAsCell([1 3]),'uniformOutput',false))
    methods
        function self = prtDataSetClassReshape(varargin)
            self = self@prtDataSetClass(varargin{:});
        end
    end
end


classdef EulerAnglesDataClass < TimeSeriesDataBaseClass

    %% Public 'read-only' properties
    properties (SetAccess = private)
        FileNameAppendage = '_EulerAngles.csv';
        Phi = [];
        Theta = [];
        Psi = [];
    end

    %% Public methods
    methods (Access = public)
        function obj = EulerAnglesDataClass(varargin)
            fileNamePrefix = varargin{1};
            for i = 2:2:nargin
                if  strcmp(varargin{i}, 'SampleRate'), obj.SampleRate = varargin{i+1};
                else error('Invalid argument.');
                end
            end
            data = obj.ImportCSVnumeric(fileNamePrefix);
            obj.Phi = data(:,2);
            obj.Theta = data(:,3);
            obj.Psi = data(:,4);
            obj.SampleRate = obj.SampleRate;    % call set method to create time vector
        end
        function fig = Plot(obj)
            if(obj.NumPackets == 0)
                error('No data to plot.');
            else
                if(isempty(obj.Time))
                    time = 1:obj.NumPackets;
                else
                    time = obj.Time;
                end
                fig = figure('Name', obj.CreateFigName());
                hold on;
                plot(time, obj.Phi, 'r');
                plot(time, obj.Theta, 'g');
                plot(time, obj.Psi, 'b');
                title('Euler angles');
                xlabel(obj.TimeAxis);
                ylabel('Angle (degrees)');
                legend('\phi', '\theta', '\psi');
                hold off;
            end
        end
    end
end


function pass = test_printTree(~)
%%TEST_PRINTTREE    Do TREEVAR computations, check that print and printTree works.

%% Basic computation:
u = treeVar();
v = cos(u);
w = sin(u);
t = v + w;

%% Call both static and non-static versions of the method
pass(1) = doesNotCrash(@() treeVar.printTree(t.tree));
pass(2) = doesNotCrash(@() print(t));
%% Introducing differentiation
u = treeVar();
myfun = @(u) 2 + diff(u,2);
t = myfun(u);
pass(3) = doesNotCrash(@() treeVar.printTree(t.tree));
pass(4) = doesNotCrash(@() print(t));
end

function pass = doesNotCrash(fn)
try
    fn();
    pass = true;
catch ME %#ok<NASGU>
    pass = false;
end
end


function option_num = p20_option_num ( )

%*****************************************************************************80
%
%% P20_OPTION_NUM returns the number of options for problem 20.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer OPTION_NUM, the number of options.
%
  option_num = 1;

  return
end


%--- help for abstvar/setOptions ---
%
%  INTERNAL FUNCTION: Sets options for the VAR
%
%  ::
%
%     var_obj = set_inputs(var_obj,varargin);
%
%  Args:
%     var_obj (var object): VAR object
%     varargin: Options to set. Must come in pairs
%
%        - **'data'**: Data for the VAR. Can be either a struct or ts object
%        - **'prior'**: Prior to use if BVAR. Available priors are
%
%           - minnesota
%           - jeffrey
%           - nw
%           - normal-wishart
%           - inw
%           - sz
%
%        - **'linear_restrictions'**: Linear restrictions. For the format, see XXXXXXXXX
%
%  Returns:
%     :
%
%        - var_obj (var object): New VAR with the given inputs updated.
%
%
%    Other functions named setOptions
%
%       AbstractPortfolio/setOptions    PortfolioCVaR/setOptions
%       Portfolio/setOptions            PortfolioMAD/setOptions
%


%SETUSER Set the user field of a dataset
%
%   A = SETUSER(A,S,FIELD)
%
% INPUT
%   A      Dataset
%   S      Variable to be stored in the user field
%   FIELD  Desired field, default 'USER'.
%
% OUTPUT
%   A      Updated dataset
%
% DESCRIPTION
% Set or reset the subfield FIELD of the user field of A by S.
%
% Note the the USER field of datasets was originally intended for a user
% defined description of datasets. Later its usage was extended to a field
% for storing general information on datasets. For that reason 'old'
% datasets without a structure in the user field are transformed such that
% this information is stored in a subfield USER in the user field. It can
% be retrieved by GETUSER(A,'USER').
%
% Note also that for reasons of backward compatibility the parameter order
% of the SETUSER command differs from similar Matlab commands like
% SETFIELD: first field content, then field name.


function printMetricsExt(metrics, metricsInfo, dispHeader,dispMetrics,padChar)
% print metrics
%
% ...
%

% default names
if nargin==1
    metricsInfo.names.long = {'IDF1', 'IDP', 'IDR',    'Recall','Precision','False Alarm Rate', ...
        'GT Tracks','Mostly Tracked','Partially Tracked','Mostly Lost', ...
        'False Positives', 'False Negatives', 'ID Switches', 'Fragmentations', ...
        'MOTA','MOTP', 'MOTA Log'};

    metricsInfo.names.short = {'IDF1', 'IDP', 'IDR',    'Rcll','Prcn','FAR', ...
        'GT','MT','PT','ML', ...
        'FP', 'FN', 'IDs', 'FM', ...
        'MOTA','MOTP', 'MOTAL'};

    metricsInfo.widths.long = [5 4 4   6 9 16 9 14 17 11 15 15 11 14 5 5 8];
    metricsInfo.widths.short = [5 4 4  5 5 5 4 4 4 4 6 6 5 5 5 5 5];

    metricsInfo.format.long = {'.1f','.1f','.1f', ...
        '.1f','.1f','.2f', ...
        'i','i','i','i', ...
        'i','i','i','i', ...
        '.1f','.1f','.1f'};

    metricsInfo.format.short=metricsInfo.format.long;
end

namesToDisplay=metricsInfo.names.long;
widthsToDisplay=metricsInfo.widths.long;
formatToDisplay=metricsInfo.format.long;

namesToDisplay=metricsInfo.names.short;
widthsToDisplay=metricsInfo.widths.short;
formatToDisplay=metricsInfo.format.short;

if nargin<3, dispHeader=1; end
if nargin<4
    dispMetrics=1:length(metrics);
end
if nargin<5
    padChar={' ',' ','|',' ',' ','| ','',' ',' ','|','',' ',' ','| ',' ',' ',' ',' '};
end

if dispHeader
    for m=dispMetrics
        printString=sprintf('fprintf(''%%%is%s'',char(namesToDisplay(m)))',widthsToDisplay(m),char(padChar(m)));
        eval(printString)
    end
    fprintf('\n');
end

for m=dispMetrics
    printString=sprintf('fprintf(''%%%i%s%s'',metrics(m))',widthsToDisplay(m),char(formatToDisplay(m)),char(padChar(m)));
    eval(printString)
end

% if standard, new line
if nargin<4
    fprintf('\n');
end


function get_voc12train_truncation_stats(cls, visualize, debug)

if nargin < 2
    visualize = 0;
    debug = 0;
end
if nargin < 3
    debug = 0;
end

setup_path;

% LOAD CAD MODELS
CADPathName = fullfile(PASCAL3D_DIR, 'CAD', [cls '.mat']);
cad = load(CADPathName);
cad = cad.(cls);

%image_dir = '/orions3-zfs/projects/rqi/Dataset/VOC12/VOCdevkit/VOC2012/JPEGImages/';
image_dir = fullfile(PASCAL3D_DIR, 'Images', [cls '_pascal']);
ids = textread(sprintf(VOCopts.imgsetpath, 'train'), '%s');

% LOGGINGS
azimuths = [];
elevations = [];
thetas = [];
distances = [];
gt_bboxes = [];
cad_bboxes = [];
gt_bboxes_draw  = [];
cad_bboxes_draw = [];
area_ratios = []; % gt bbox / cad bbox

for i = 1:numel(ids)
    if mod(i,100) == 0
        fprintf('%s: %d/%d\n', cls, i, numel(ids));
    end

    % Load annotation for the i'th image
    filename = fullfile(PASCAL3D_DIR, 'Annotations', sprintf('%s_pascal/%s.mat', cls, ids{i}));
    if ~exist(filename,'file')
        continue;
    end
    anno = load(filename);
    objects = anno.record.objects;
    for k = 1:length(objects)
        obj = objects(k);
        % Proceed only when the object is of cls
        if strcmp(obj.class,cls)
            bbox = obj.bbox;
            bbox_draw = [bbox(1) bbox(2) bbox(3)-bbox(1) bbox(4)-bbox(2)];
            im = imread(fullfile(image_dir, [ids{i} '.jpg']));
            % Show original image
            if debug
                imshow(im);
                hold on;
                rectangle('Position', bbox_draw, 'EdgeColor', 'g');
            end
            % Show annotated anchor points
            if debug && isfield(obj, 'anchors') == 1 && isempty(obj.anchors) == 0
                names = fieldnames(obj.anchors);
                for j = 1:numel(names)
                    if obj.anchors.(names{j}).status == 1
                        if isempty(obj.anchors.(names{j}).location) == 0
                            x = obj.anchors.(names{j}).location(1);
                            y = obj.anchors.(names{j}).location(2);
                            plot(x, y, 'ro');
                        else
                            fprintf('anchor point %s is missing!\n', names{j});
                        end
                    end
                end
            end
            % show overlay of the CAD model
            if isfield(obj, 'cad_index') == 1 && isempty(obj.cad_index) == 0 && ...
                    isfield(obj, 'viewpoint') == 1 && isfield(obj.viewpoint, 'azimuth') == 1
                vertices = cad(obj.cad_index).vertices;
                faces = cad(obj.cad_index).faces;
                x2d = project_3d(vertices, obj);
                if isempty(x2d) == 0

                    if debug
                        patch('vertices', x2d ,'faces', faces, ...
                        'FaceColor', 'blue', 'FaceAlpha', 0.2, 'EdgeColor', 'none');
                    end

                    % Find bbox for the CAD model
                    bbox_cad = [min(x2d(:,1)),min(x2d(:,2)),max(x2d(:,1)),max(x2d(:,2))];
                    bbox_cad_draw = [bbox_cad(1), bbox_cad(2), bbox_cad(3)-bbox_cad(1), bbox_cad(4)-bbox_cad(2)];

                    area_ratio = bbox_draw(3)*bbox_draw(4)/(bbox_cad_draw(3)*bbox_cad_draw(4));
                    if debug
                        rectangle('Position', bbox_cad_draw, 'EdgeColor','r');
                        fprintf('Approx. visible ratio: %f\n', area_ratio);
                        hold off;
                    end

                    azimuths = [azimuths obj.viewpoint.azimuth];
                    area_ratios = [area_ratios area_ratio];
                    gt_bboxes = [gt_bboxes; bbox];
                    cad_bboxes = [cad_bboxes; bbox_cad];
                    gt_bboxes_draw = [gt_bboxes_draw; bbox_draw];
                    cad_bboxes_draw = [cad_bboxes_draw; bbox_cad_draw];
                end

            end
            if debug
                fprintf('press button to continue...\n');
                pause();
                close all;
            end
        end
    end
end

widths = cad_bboxes(:,3) - cad_bboxes(:,1);
heights = cad_bboxes(:,4) - cad_bboxes(:,2);
r = zeros(length(azimuths), 4);
gt_cad_bboxes_diff = gt_bboxes - cad_bboxes;
r(:,1) = gt_cad_bboxes_diff(:,1) ./ widths;
r(:,3) = gt_cad_bboxes_diff(:,3) ./ widths;
r(:,2) = gt_cad_bboxes_diff(:,2) ./ heights;
r(:,4) = gt_cad_bboxes_diff(:,4) ./ heights;
left = r(:,1); top = r(:,2);
right = r(:,3); bottom = r(:,4);
mkdir(g_truncation_statistics_folder);
save(fullfile(g_truncation_statistics_folder, [cls '_truncation_stats']), 'left', 'top', 'right', 'bottom');

if visualize
    % Show relation between azimuth and area_ratios
    vnum = 8;
    azimuth_interval = [0 (360/(vnum*2)):(360/vnum):360-(360/(vnum*2))];
    ratios_by_view = zeros(vnum,1);
    for i = 1:length(azimuths)
        azimuths(i) = find_interval(azimuths(i), azimuth_interval);
    end
    for v = 1:vnum
        [tmp, index] = find(azimuths == v);
        ratios_by_view(v) = median(area_ratios(index));
    end
    figure, subplot(1,2,1), bar(ratios_by_view);
    subplot(1,2,2), scatter(azimuths, area_ratios);

    % Show hist of ratios of gt_cad_bboxes_diff/[width,height]
    figure, subplot(2,2,1), hist(left), title('left');
    subplot(2,2,2), hist(top), title('right');
    subplot(2,2,3), hist(right), title('top');
    subplot(2,2,4), hist(bottom), title('bottom');
end

function ind = find_interval(azimuth, a)
for i = 1:numel(a)
    if azimuth < a(i)
        break;
    end
end
ind = i;
if azimuth > a(end)
    ind = 1;
end


function [output] = getCompareBinsOfFluxes(xglc, model, samplo, samphi, metabolites)
% Compares the bins of fluxes between `samplo` and `samphi`,
% calls `compareBinsOfFluxes(xglc, model, sammin, sammax, metabolites).
% `samplo` and `samphi` each contain samples in `x.points`
%
% USAGE:
%
%    [output] = getCompareBinsOfFluxes(xglc, model, samplo, samphi, metabolites)
%
% INPUTS:
%    xglc:           sugar distribution
%    model:          model structure
%    samplo:         samples containing bins of fluxes
%    samphi:         samples containing bins of fluxes
%
% OPTIONAL INPUT:
%    metabolites:    list of metabolites
%
% OUTPUT:
%    output:         result of comparison
%
% .. Author: - Wing Choi 3/7/08

output = 0;

if (nargin < 4)
    disp '[output] = getCompareBinsOfFluxes(xglc,model,samplo,samphi,metabolites)'
    return;
end

if (nargin < 5)
    metabolites = [];
end

if (isempty(xglc))
    % random glucose
    %xglc = rand(64,1);
    %xglc = xglc/sum(xglc);
    %xglc = idv2cdv(6)*xglc;

    glucose = rand(8,1);
    glucose = glucose/sum(glucose);
    %glc = idv2cdv(6)*glc;

    % glc 1-6 = carbon 1-6
    % glc 7 = carbon 1+2 (really 5 and 6)
    % glc 8 = unlabeled
    % glc 9 = fully labeled
    glc = zeros(64,9);
    glc(1+1,1) = 1;
    glc(2+1,2) = 1;
    glc(4+1,3) = 1;
    glc(8+1,4) = 1;
    glc(16+1,5) = 1;
    glc(32+1,6) = 1;
    glc(32+16+1,7) = 1;
    glc(0+1,8) = 1;
    glc(63+1,9) = 1;

    xGlc = zeros(64,1);
    for i = 1:8
        xGlc = xGlc + glucose(i)*glc(:,i);
    end

    xglc = idv2cdv(6)*xGlc;

end

% specify the #fluxes and #bins to work with.
bins = [ 100 40 ; 125 32 ; 200 20 ; 250 16 ; 300 13 ; 400 10 ; 1000 4 ];

for i = 1:7
    nflux = bins(i,1);
    nbins = bins(i,2);
    ol = getBinsOfFluxes(samplo,nflux,nbins);
    ou = getBinsOfFluxes(samphi,nflux,nbins);
    ome = compareBinsOfFluxes(xglc,model,ol,ou,metabolites);
    name = sprintf('n%d',nbins);
    output.data(i,1:length(ome.totalz)) = ome.totalz';
    output.atotalz(i,1) = mean(ome.totalz);
    output.std(i,1) = std(ome.totalz);
end

% get the single bin of 4000 run for compare.
sl.samps(1,1).points = samplo.points(:,1:4000);
su.samps(1,1).points = samphi.points(:,1:4000);
ome = compareBinsOfFluxes(xglc,model,sl,su,metabolites);
output.data(8,1) = ome.totalz(1,1);
output.atotalz(8,1) = ome.totalz(1,1);
output.std(8,1) = 0;
%[totalz,zscore,mdvs] = compareMultSamp(xGlc,x,samps);

%[totalz] = compareTwoSamp(xGlc,x,samp1,samp2,metabolite);

return
end


function varargout = histGUI(varargin)
% HISTGUI M-file for histGUI.fig
%      HISTGUI, by itself, creates a new HISTGUI or raises the existing
%      singleton*.
%
%      H = HISTGUI returns the handle to a new HISTGUI or the handle to
%      the existing singleton*.
%
%      HISTGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in HISTGUI.M with the given input arguments.
%
%      HISTGUI('Property','Value',...) creates a new HISTGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before histGUI_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to histGUI_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 histGUI

% Last Modified by GUIDE v2.5 27-Mar-2004 20:18:45

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @histGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @histGUI_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 histGUI is made visible.
function histGUI_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 histGUI (see VARARGIN)

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

% Set the figure background color
set(hObject,'Color',[0.6 1 1]);

% Set the initial number of bins
handles.nbins = 11;

% Update handles structure
guidata(hObject, handles);

% --- Outputs from this function are returned to the command line.
function varargout = histGUI_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 NBins_Callback(hObject, eventdata, handles)
% hObject    handle to NBins (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get number of bins, round to integer, and update field
nbins = str2num(get(hObject,'String'));
nbins = round(nbins);
if nbins < 1
   nbins = 1;
end
set (handles.NBins,'String',int2str(nbins));

% Save in handles structure
handles.nbins = nbins;
guidata(gcbf, handles);

% Re-display data, if available
if handles.nbins > 0 & ~isempty(handles.x)

   % Create histogram
   hist(handles.x,handles.nbins);

end

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end

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

% Get file name
[filename,path] = uigetfile('*.dat','Load Data File');
if filename ~= 0

   % Read data
   x = textread([path filename],'%f');

   % Save in handles structure
   handles.x = x;
   guidata(gcbf, handles);

   % Create histogram
   hist(handles.x,handles.nbins);

   % Set axis labels
   xlabel('\bfValue');
   ylabel('\bfCount');

   % Calculate statistics
   ave = mean(x);
   med = median(x);
   sd  = std(x);
   n   = length(x);

   % Update fields
   set (handles.MeanData,'String',sprintf('%7.2f',ave));
   set (handles.MedianData,'String',sprintf('%7.2f',med));
   set (handles.StdDevData,'String',sprintf('%7.2f',sd));
   set (handles.TitleString,'String',['Histogram (N = ' int2str(n) ')']);

end

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

close(gcbf);

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


function [ts] = PL2TsBySource( filename, source, channelInSource, unit )
% PL2TsBySource( filename, source, channelInSource, unit ): read spike timestamps from a .pl2 file
%
% ts = PL2TsBySource( filename, source, channelInSource, unit );
% ts = PL2TsBySource( filename, 'SPK', 1, 2 );
% ts = PL2TsBySource( filename, 7, 1, 3 );
%
% INPUT:
%   filename - if empty string, will use File Open dialog
%   source - source name or source numeric id
%   channel -  1-based channel number within source
%           To print the list of spike channels, use these commands:
%
%           pl2 = PL2GetFileIndex(filename);
%           PL2Print(pl2.SpikeChannels);
%
%   unit  - unit number (0 - unsorted, 1-255 sorted units)
%
% OUTPUT:
%   ts - array of timestamps (in seconds)

n = 0;
ts = [];

if nargin ~= 4
    error 'expected 4 input arguments';
end

filename = internalPL2ResolveFilename(filename);
pl2 = PL2GetFileIndex(filename);
channelNumber = internalPL2ResolveChannelBySource(pl2.SpikeChannels, source, channelInSource);
ts = Pl2Ts(filename, channelNumber, unit);

end


function Y=reshape(varargin)
%RESHAPE (overloaded)

Y = varargin{1};
% simple hack to figure out new sizes
temp = reshape(ones(size(Y.basis,1),1),varargin{2:end});
Y.conicinfo = [0 0];
Y.dim = size(temp);
Y = clean(Y);


function view_rccross_a2(lab1,valueMap)
    % view_rccross_a2 plots ratechanges and p values calculated
    % derived with rc_cross_a2.m or other similar values as a color map.
    % needs valueMap, gx, gy
    %
    % define size of the plot etc.

    report_this_filefun();

    myFigName='RC-Cross-section';
    myFigFinder=@() findobj('Type','Figure','-and','Name',myFigName);

    % This is the info window text
    %
    ttlStr='The b and p -Value Map Window                 ';
    hlpStr1zmap= ...
        ['                                                '
        ' This window displays b-values and p-values     '
        ' using a color code.                            '
        ' Some of the menu-bar options are               '
        ' described below:                               '
        '                                                '
        ' Threshold: You can set the maximum size that   '
        '   a volume is allowed to have in order to be   '
        '   displayed in the map. Therefore, areas with  '
        '   a low seismicity rate are not displayed.     '
        '   edit the size (in km) and click the mouse    '
        '   outside the edit window.                     '
        'FixAx: You can chose the minimum and maximum    '
        '        values of the color-legend used.        '
        'Polygon: You can select earthquakes in a        '
        ' polygon either by entering the coordinates or  '
        ' defining the corners with the mouse            '];
    hlpStr2zmap= ...
        ['                                                '
        'Circle: Select earthquakes in a circular volume:'
        '      Ni, the number of selected earthquakes can'
        '      be edited in the upper right corner of the'
        '      window.                                   '
        ' Refresh Window: Redraws the figure, erases     '
        '       selected events.                         '

        ' zoom: Selecting Axis -> zoom on allows you to  '
        '       zoom into a region. Click and drag with  '
        '       the left mouse button. type <help zoom>  '
        '       for details.                             '
        ' Aspect: select one of the aspect ratio options '
        ' Text: You can select text items by clicking.The'
        '       selected text can be rotated, moved, you '
        '       can change the font size etc.            '
        '       Double click on text allows editing it.  '
        '                                                '
        '                                                '];

    % Set up the Seismicity Map window Enviroment
    %

    % Find out if figure already exists
    %
    hRccross=myFigFinder();

    if isempty(hRccross)
        hRccross = figure_w_normalized_uicontrolunits( ...
            'Name',myFigName,...
            'NumberTitle','off', ...
            'NextPlot','new', ...
            'backingstore','on',...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));

        %lab1 = 'p-value:';
        create_my_menu();

        %valueMap = pvalg;
        ZG.tresh_km = nan; re4 = valueMap;

        colormap(jet)
        ZG.tresh_km = nan; minpe = nan; Mmin = nan; minsd = nan;
    end   % This is the end of the figure setup.

    % Now lets plot the color-map!
    %
    figure(hRccross);
    delete(findobj(hOmoricross,'Type','axes'))
    %delete(sizmap)
    ax=gca;
    reset(ax) % automatically sets NextPlot to replace
    watchon;
    set(ax,'visible','off','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold',...
        'FontWeight','bold','LineWidth',1.5,...
        'Box','on','SortMethod','childorder')

    rect = [0.18,  0.10, 0.7, 0.75];
    rect1 = rect;

    % find max and min of data for automatic scaling
    ZG.maxc = max(valueMap(:));
    ZG.maxc = fix(ZG.maxc)+1;
    ZG.minc = min(valueMap(:));
    ZG.minc = fix(ZG.minc)-1;

    re4 = valueMap;

    % plot image
    orient landscape

    %Plots re4, which contains the filtered values.
    axes('position',rect)
    set(gca,'NextPlot','add')
    pco1 = pcolor(gx,gy,re4);

    axis([ min(gx) max(gx) min(gy) max(gy)])
    axis image
    set(gca,'NextPlot','add')
    shading(ZG.shading_style);

    % make the scaling for the recurrence time map reasonable
    if lab1(1) =='T'
        re = valueMap(~isnan(valueMap));
        caxis([min(re) 5*min(re)]);
    end

    fix_caxis.ApplyIfFrozen(gca);

    title([name ';  '   num2str(t0b) ' to ' num2str(teb) ],'FontSize',ZmapGlobal.Data.fontsz.s,...
        'Color','r','FontWeight','bold')

    xlabel('Distance [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)
    ylabel('Depth [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)

    % plot overlay
    %
    set(gca,'NextPlot','add')
    zmap_update_displays();
    globalcatalog=ZG.primeCatalog;
    ploeq = plot(globalcatalog.X, globalcatalog.Y,'k.');
    set(ploeq,'Tag','eq_plot','MarkerSize',ZG.ms6,'Marker',ty,'Color',ZG.someColor,'Visible','on')

    set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold',...
        'FontWeight','bold','LineWidth',1.5,...
        'Box','on','TickDir','out')
    h1 = gca;
    hzma = gca;

    % Create a colorbar
    %
    h5 = colorbar('horiz');
    set(h5,'Pos',[0.35 0.05 0.4 0.02],...
        'FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s,'TickDir','out')

    rect = [0.00,  0.0, 1 1];
    axes('position',rect)
    axis('off')
    %  Text Object Creation
    txt1 = text(...
        'Units','normalized',...
        'Position',[ 0.33 0.06 0 ],...
        'HorizontalAlignment','right',...
        'FontSize',ZmapGlobal.Data.fontsz.s,....
        'FontWeight','bold',...
        'String',lab1);

    % Make the figure visible
    %
    set(gca,'FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold',...
        'FontWeight','bold','LineWidth',1.5,...
        'Box','on','TickDir','out')
    figure(hRccross);
    axes(h1)
    watchoff(hRccross)

    %% ui functions
    function create_my_menu()
        add_menu_divider();
        add_symbol_menu('eq_plot');

        options = uimenu('Label',' Analyze ');
        uimenu(options,'Label','Refresh ','MenuSelectedFcn',@callbackfun_001)
        uimenu(options,'Label','Select EQ in Circle - Constant R',...
            'MenuSelectedFcn',@callbackfun_002)
        uimenu(options,'Label','Select EQ with const. number',...
            'MenuSelectedFcn',@callbackfun_003)

        op1 = uimenu('Label',' Maps ');

        %Menu for adjusting several parameters.
        adjmenu =  uimenu(op1,'Label','Adjust Map Display Parameters'),...
            uimenu(adjmenu,'Label','Adjust Mmin cut',...
            'MenuSelectedFcn', @(~,~)cb_viewagain('mag') )
        uimenu(adjmenu,'Label','Adjust Rmax cut',...
            'MenuSelectedFcn', @(~,~)cb_viewagain('rmax') )
        uimenu(adjmenu,'Label','Adjust goodness of fit cut',...
            'MenuSelectedFcn', @(~,~)cb_viewagain('gofi') )
        uimenu(adjmenu,'Label','Adjust p-value st. dev. cut',...
            'MenuSelectedFcn', @(~,~)cb_viewagain('pstdc') )

        uimenu(op1,'Label','Relative rate change (bootstrap)',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('Sigma') )
        uimenu(op1,'Label','Model',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('Model') )
        uimenu(op1,'Label','KS-Test',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('Rejection') )
        uimenu(op1,'Label','KS-Test Statistic',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('KS distance') )
        uimenu(op1,'Label','KS-Test p-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('KS-Test p-value') )
        uimenu(op1,'Label','RMS of fit',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('RMS') )
        uimenu(op1,'Label','Resolution Map (Number of events)',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('Number of events') )
        uimenu(op1,'Label','Resolution Map (Radii)',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('Radius / [km]') )
        uimenu(op1,'Label','p-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('p-value') )
        uimenu(op1,'Label','p-value standard deviation',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('p-valstd') )
        uimenu(op1,'Label','c-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('c-value') )
        uimenu(op1,'Label','c-value standard deviation',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('c-valuestd') )
        uimenu(op1,'Label','k-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('k-value') )
        uimenu(op1,'Label','k-value standard deviation',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('k-valuestd') )
        uimenu(op1,'Label','p2-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('p2-value') )
        uimenu(op1,'Label','p-value standard deviation',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('p2-valuestd') )
        uimenu(op1,'Label','c2-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('c2-value') )
        uimenu(op1,'Label','c2-value standard deviation',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('c2-valuestd') )
        uimenu(op1,'Label','k2-value',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('k2-value') )
        uimenu(op1,'Label','k2-value standard deviation',...
            'MenuSelectedFcn', @(~,~)cb_viewagainOtherdata('k2-valuestd') )

        add_display_menu(1);
    end

    %% callback functions

    function callbackfun_001(mysrc,myevt)
        view_rccross_a2(lab1,valueMap);
    end

    function callbackfun_002(mysrc,myevt)
        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        h1 = gca;
        met = 'ra';
        ZG=ZmapGlobal.Data;
        ZG.hold_state=false;
        plot_circbootfit_a2;
        watchoff(hRccross);
    end

    function callbackfun_003(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        h1 = gca;
        ZG=ZmapGlobal.Data;
        ZG.hold_state2=true;
        ZG=ZmapGlobal.Data;
        ZG.hold_state=true;
        plot_constnrbootfit_a2;
        watchoff(hRccross);
    end

    function cb_viewagain(asel)
        % set asel, adju2, then view
        ZG=ZmapGlobal.Data;
        adju2;
        view_rccross_a2(lab1,ZG.valueMap);
    end

    function cb_viewagainOtherdata(label)
        % set asel, adju2, then view
        ZG=ZmapGlobal.Data;
        switch label
            case 'Sigma'
                valueMap=mRelchange; %8
            case 'Model'
                valueMap=mMod; %9
            case 'Rejection'
                valueMap=mKstestH; %10
            case 'KS distance'
                valueMap=mKsstat; %11
            case 'KS-Test p-value'
                valueMap=mKsp; %12
            case 'RMS'
                valueMap=mRMS; %13
            case 'Number of events'
                valueMap=mNumevents; %14
            case 'Radius / [km]'
                valueMap=vRadiusRes; %15
            case 'p-value'
                valueMap=mPval;
            case 'p-valstd'
                valueMap=mPvalstd;
            case 'c-value'
                valueMap=mCval;
            case 'c-valstd'
                valueMap=mCvalstd;
            case 'k-value'
                valueMap=mKval;
            case 'k-valstd'
                valueMap=mKvalstd;
            case 'p2-value'
                valueMap=mPval2;
            case 'p2-valstd'
                valueMap=mPvalstd2;
            case 'c2-value'
                valueMap=mCval2;
            case 'c2-valstd'
                valueMap=mCvalstd2;
            case 'k2-value'
                valueMap=mKval2;
            case 'k2-valstd'
                valueMap=mKvalstd2;
            otherwise
                error('unknown choice');
        end
        ZG.valueMap=valueMap;
        view_rccross_a2(label,ZG.valueMap);
    end

end


%-Abstract
%
%   ZZMICE_DP converts an numeric input to double precision format.
%
%-Disclaimer
%
%   THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
%   CALIFORNIA  INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
%   GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
%   ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
%   PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED
%   "AS-IS" TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING
%   ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR
%   A PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
%   SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
%   SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
%
%   IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY,
%   OR NASA BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING,
%   BUT NOT LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF
%   ANY KIND, INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY
%   AND LOST PROFITS, REGARDLESS OF WHETHER CALTECH, JPL, OR
%   NASA BE ADVISED, HAVE REASON TO KNOW, OR, IN FACT, SHALL
%   KNOW OF THE POSSIBILITY.
%
%   RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE
%   OF THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO
%   INDEMNIFY CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING
%   FROM THE ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
%
%-I/O
%
%   Given:
%
%      x   an input numeric to convert to double precision
%
%   the call:
%
%      y = zzmice_dp(x)
%
%   returns:
%
%      y   the double precision representation of 'x'
%
%-Examples
%
%   None.
%
%-Particulars
%
%   This routine exists to support the NAIF MATLAB-CSPICE interface.
%
%-Required Reading
%
%   MICE.REQ
%
%-Version
%
%   -Mice Version 1.1.0, 27-JUL-2009, EDW (JPL)
%
%      Added value check on 'nargin'. Incorrect input argument type/form
%      error tag changed from "MICE(BADVAL)" to "MICE(BADARG)."
%
%   -Mice Version 1.0.1, 30-DEC-2008, EDW (JPL)
%
%      Function ensures all input values as finite.
%
%      Corrected misspellings.
%
%   -Mice Version 1.0.0, 30-JAN-2006, EDW (JPL)
%
%-Index_Entries
%
%   None.
%
%-&

function [y] = zzmice_dp(x)

   if( ~isequal(nargin,1) )

      error( 'MICE(USAGE): _y_ = zzmice_dp( _x_ )' )

   end

   if( isnumeric(x) && all( isfinite( x(:) ) ) )

     y = double(x);

   else

      error( ['MICE(BADARG): Improper type of input ' ...
              'argument passed to function. Value ' ...
              'or values expected as finite double precision.'] )

   end


function test_partial_basis_1d(N, M, K)

if nargin < 1
    N = 2048;
end

if nargin < 2
    M = floor(N/8);
end

if nargin < 3
    K = floor(M/5);
end

% prepare demo signal
X = spx.data.synthetic.SparseSignalGenerator()

end


function [vertices, landmarks_fitted, fit_params] = read_face_recon(reconstruction_dir)
    vertices = import_vertices_keypoints([reconstruction_dir, '/vertices.txt']);
    landmarks_fitted = import_vertices_keypoints([reconstruction_dir, '/landmarks_fitted.txt']);
    landmarks_fitted = [landmarks_fitted(59:end, :); landmarks_fitted(1, :); ...
        landmarks_fitted(51:58, :); landmarks_fitted(2:50, :)]; % reorder
    fit_params = import_params([reconstruction_dir, '/fit_params.txt']);
end

function vertices = import_vertices_keypoints(filename)
dataLines = [1, Inf];
opts = delimitedTextImportOptions("NumVariables", 3);
opts.DataLines = dataLines;
opts.Delimiter = ",";
opts.VariableNames = ["VarName1", "VarName2", "VarName3"];
opts.VariableTypes = ["double", "double", "double"];
opts.ExtraColumnsRule = "ignore";
opts.EmptyLineRule = "read";
vertices = readtable(filename, opts);
vertices = table2array(vertices);
end

function params = import_params(filename, dataLines)
if nargin < 2
    dataLines = [1, Inf];
end
opts = delimitedTextImportOptions("NumVariables", 1);
opts.DataLines = dataLines;
opts.Delimiter = ",";
opts.VariableNames = "VarName1";
opts.VariableTypes = "double";
opts.ExtraColumnsRule = "ignore";
opts.EmptyLineRule = "read";
params = readtable(filename, opts);
params = table2array(params);
end


%----UPDATE AXIS DATA/LAYOUT----%

function obj = updateAxisMultipleYAxes(obj,axIndex,yaxIndex)

    %-STANDARDIZE UNITS-%
    axisUnits = get(obj.State.Axis(axIndex).Handle,'Units');
    set(obj.State.Axis(axIndex).Handle,'Units','normalized')

    try
        fontUnits = get(obj.State.Axis(axIndex).Handle,'FontUnits');
        set(obj.State.Axis(axIndex).Handle,'FontUnits','points')
    catch
        % TODO
    end

    %-AXIS DATA STRUCTURE-%
    axisData = get(obj.State.Axis(axIndex).Handle);

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

    %-xaxis-%
    xaxis = extractAxisData(obj,axisData, 'X');

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

    %-yaxis-%
    [yaxis, yAxisLim] = extractAxisDataMultipleYAxes(obj, axisData, yaxIndex);

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

    %-getting and setting postion data-%

    xo = axisData.Position(1);
    yo = axisData.Position(2);
    w = axisData.Position(3);
    h = axisData.Position(4);

    if obj.PlotOptions.AxisEqual
        wh = min(axisData.Position(3:4));
        w = wh;
        h = wh;
    end

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

    %-xaxis domain-%
    xaxis.domain = min([xo xo + w],1);
    scene.domain.x = min([xo xo + w],1);

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

    %-yaxis domain-%
    yaxis.domain = min([yo yo + h],1);
    scene.domain.y = min([yo yo + h],1);

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

    [xsource, ysource, xoverlay, yoverlay] = findSourceAxis(obj, axIndex, yaxIndex);

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

    %-xaxis anchor-%
    xaxis.anchor = ['y' num2str(ysource)];

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

    %-yaxis anchor-%
    yaxis.anchor = ['x' num2str(xsource)];

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

    %-xaxis overlaying-%
    if xoverlay
        xaxis.overlaying = ['x' num2str(xoverlay)];
    end

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

    %-yaxis overlaying-%
    if yoverlay
        yaxis.overlaying = ['y' num2str(yoverlay)];
    end

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

    % update the layout field (do not overwrite source)
    if xsource == axIndex
        obj.layout = setfield(obj.layout,['xaxis' num2str(xsource)],xaxis);
    end

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

    % update the layout field (do not overwrite source)
    obj.layout = setfield(obj.layout,['yaxis' num2str(ysource)],yaxis);

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

    %-REVERT UNITS-%
    set(obj.State.Axis(axIndex).Handle,'Units',axisUnits);

    try
        set(obj.State.Axis(axIndex).Handle,'FontUnits',fontUnits);
    catch
        % TODO
    end

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

    %-do y-axes visibles-%
    obj.PlotOptions.nPlots = obj.PlotOptions.nPlots + 1;
    plotIndex = obj.PlotOptions.nPlots;

    obj.data{plotIndex}.type = 'scatter';
    obj.data{plotIndex}.xaxis = ['x' num2str(xsource)];
    obj.data{plotIndex}.yaxis = ['y' num2str(ysource)];

    %-------------------------------------------------------------------------%
end


function [] = generateMetaboReport(modelProperties,reportDir,orgNames)
% This function generates
F = fieldnames(modelProperties);

for i = 1 : length(F)
    clear html
    fid=fopen('reportTemplate.html');
    tline = fgetl(fid);
    cnt =1;
    while ischar(tline)
        disp(tline)
        tline = fgetl(fid);
        disp(tline)
        % replace space holders in template html file
        if ~isnumeric(tline)
            if ~exist('orgNames','var')
                ModelName = regexprep(F{i},'_', ' ');
            else
                if strcmp(F{i},orgNames{i})
                    ModelName = regexprep(F{i},'_', ' ');
                else
                    ModelName = regexprep(orgNames{i},'_', ' ');
                end
            end
            tline= regexprep(tline,'###ModelName',ModelName);
            % Basic information
            tline= regexprep(tline,'###OverallScore',num2str(round(modelProperties.(F{i}).modelProp2.Scores.Overall,2)));
            tline= regexprep(tline,'###NumMets',num2str(modelProperties.(F{i}).modelProp2.m));
            tag = '###ListNumMets'; list = modelProperties.(F{i}).modelProp2.Details.metabolites; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRxns',num2str(modelProperties.(F{i}).modelProp2.n));
            tag = '###ListNumRxns'; list = modelProperties.(F{i}).modelProp2.Details.reactions; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);
            tline= regexprep(tline,'###NumGenes',num2str(modelProperties.(F{i}).modelProp2.genes));
            tline= regexprep(tline,'###NumComp',num2str(modelProperties.(F{i}).modelProp2.compartments));
            tline= regexprep(tline,'###MetCov',num2str(round(modelProperties.(F{i}).modelProp2.metCov,2)));
            % Metabolic information
            tline= regexprep(tline,'###NumMUnique',num2str(modelProperties.(F{i}).modelProp2.metUnique));
            tag = '###ListMetUnique'; list = modelProperties.(F{i}).modelProp2.Details.metabolites_unique; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetNoCharge',num2str(modelProperties.(F{i}).modelProp2.MissingMetCharge));

            tline= regexprep(tline,'###NumMetNoForm',num2str(modelProperties.(F{i}).modelProp2.MissingMetFormulae));
            tag = '###ListNumMetNoForm'; list = modelProperties.(F{i}).modelProp2.Details.MissingMetFormulae; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###MedComp',num2str(modelProperties.(F{i}).modelProp2.MediumMets));
            tag = '###ListMedComp'; list = modelProperties.(F{i}).modelProp2.Details.MediumMets; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            % Reaction information
            tline= regexprep(tline,'###NumMetRxns',num2str(modelProperties.(F{i}).modelProp2.MetabolicRxns));
            tag = '###ListNumMetRxns'; list = modelProperties.(F{i}).modelProp2.Details.MetabolicRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumTransRxns',num2str(modelProperties.(F{i}).modelProp2.TransportRxns));
            tag = '###ListNumTransRxns'; list = modelProperties.(F{i}).modelProp2.Details.TransportRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumExRxns',num2str(modelProperties.(F{i}).modelProp2.ExchangeRxns));
            tag = '###ListNumExRxns'; list = modelProperties.(F{i}).modelProp2.Details.ExchangeRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumDmRxns',num2str(modelProperties.(F{i}).modelProp2.DemandRxns));
            tag = '###ListNumDmRxns'; list = modelProperties.(F{i}).modelProp2.Details.DemandRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumSinkRxns',num2str(modelProperties.(F{i}).modelProp2.SinkRxns));
            tag = '###ListNumSinkRxns'; list = modelProperties.(F{i}).modelProp2.Details.SinkRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumBmRxns',num2str(modelProperties.(F{i}).modelProp2.BiomassRxns));
            tag = '###ListNumBmRxns'; list = modelProperties.(F{i}).modelProp2.Details.BiomassRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            % GPR information
            tline= regexprep(tline,'###NumRxnWoGpr',num2str(round(modelProperties.(F{i}).modelProp2.RxnsWithoutGpr,2)));
            tag = '###ListNumRxnWoGpr'; list = modelProperties.(F{i}).modelProp2.Details.RxnsWithoutGpr; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumTRxnWoGpr',num2str(round(modelProperties.(F{i}).modelProp2.TRxnsWithoutGpr,2)));
            tag = '###ListNumTRxnWoGpr'; list = modelProperties.(F{i}).modelProp2.Details.TRxnsWithoutGpr; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            % Network topology
            tline= regexprep(tline,'###NumBlockedR',num2str(round(modelProperties.(F{i}).modelProp2.BlockedRxns,2)));
            tag = '###ListNumBlockedR'; list = modelProperties.(F{i}).modelProp2.Details.BlockedRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumDeadM',num2str(round(modelProperties.(F{i}).modelProp2.DeadendsMets,2)));
            tag = '###ListNumDeadM'; list = modelProperties.(F{i}).modelProp2.Details.DeadendsMets; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumStoichCycleRxns',num2str(round(modelProperties.(F{i}).modelProp2.StoichCycleRxns,2)));
            tag = '###ListNumStoichCycleRxns'; list = modelProperties.(F{i}).modelProp2.Details.StoichCycleRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            % Matrix Conditioning
            tline= regexprep(tline,'###NumMinMaxCoeff',num2str(round(modelProperties.(F{i}).modelProp2.maxminCoeff,2)));
            tag = '###ListNumMinMaxCoeff'; list = modelProperties.(F{i}).modelProp2.Details.maxminCoeff; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRank',num2str(round(modelProperties.(F{i}).modelProp2.Rank,2)));

            % Consistency
            tline= regexprep(tline,'###NumConsRxns',num2str(round(modelProperties.(F{i}).modelProp2.ConsRxns,2)));
            tag = '###ListNumConsRxns'; list = modelProperties.(F{i}).modelProp2.Details.InconsRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumBalRxns',num2str(round(modelProperties.(F{i}).modelProp2.BalancedMassRxns,2)));
            tag = '###ListNumBalRxns'; list = modelProperties.(F{i}).modelProp2.Details.UnBalancedMassRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumChargeRxns',num2str(round(modelProperties.(F{i}).modelProp2.BalancedChargeRxns,2)));
            tag = '###ListNumChargeRxns'; list = modelProperties.(F{i}).modelProp2.Details.UnBalancedChargeRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetConnec',num2str(round(modelProperties.(F{i}).modelProp2.MetConn,2)));
            tag = '###ListNumMetConnec'; list = modelProperties.(F{i}).modelProp2.Details.MetConn; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumUnboundR',num2str(round(modelProperties.(F{i}).modelProp2.UnboundedFlux,2)));
            tag = '###ListNumUnboundR'; list = modelProperties.(F{i}).modelProp2.Details.UnboundedFluxRxns; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###ScoreConsistency',num2str(round(modelProperties.(F{i}).modelProp2.Scores.Consistency,2)));

            % Annotation - Metabolites
            tline= regexprep(tline,'###NumMAnnoAny',num2str(round(modelProperties.(F{i}).modelProp2.MetWAnno,2)));
            tag = '###ListNumMAnnoAny'; list = modelProperties.(F{i}).modelProp2.Details.metWOAnno; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetPubCh',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetPubChemID,2)));
            tag = '###ListNumMetPubCh'; list = modelProperties.(F{i}).modelProp2.Details.missingmetPubChemID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetKegg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetKEGGID,2)));
            tag = '###ListNumMetKegg'; list = modelProperties.(F{i}).modelProp2.Details.missingmetKEGGID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetSeed',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetSEEDID,2)));
            tag = '###ListNumMetSeed'; list = modelProperties.(F{i}).modelProp2.Details.missingmetSEEDID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetIKey',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetInchiKey,2)));
            tag = '###ListNumMetIKey'; list = modelProperties.(F{i}).modelProp2.Details.missingmetInchiKey; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetIString',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetInchiString,2)));
            tag = '###ListNumMetIString'; list = modelProperties.(F{i}).modelProp2.Details.missingmetInchiString; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetChebi',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetChEBIID,2)));
            tag = '###ListNumMetChebi'; list = modelProperties.(F{i}).modelProp2.Details.missingmetChEBIID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetHmdb',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetHMDBID,2)));
            tag = '###ListNumMetHmdb'; list = modelProperties.(F{i}).modelProp2.Details.missingmetHMDBID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetReac',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetReactomeID,2)));
            tag = '###ListNumMetReac'; list = modelProperties.(F{i}).modelProp2.Details.missingmetReactomeID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetMetNetX',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetMetaNetXID,2)));
            tag = '###ListNumMetMetNetX'; list = modelProperties.(F{i}).modelProp2.Details.missingmetMetaNetXID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetBigg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetBiGGID,2)));
            tag = '###ListNumMetBigg'; list = modelProperties.(F{i}).modelProp2.Details.missingmetBiGGID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetBioc',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetmetBioCycID,2)));
            tag = '###ListNumMetBioc'; list = modelProperties.(F{i}).modelProp2.Details.missingmetBioCycID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            % Annotation - Metabolites - Conformity
            tline= regexprep(tline,'###NumMetCPubCh',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetPubChemID,2)));
            tag = '###ListNumMetCPubCh'; list = modelProperties.(F{i}).modelProp2.Details.missingmetPubChemID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCKegg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetKEGGID,2)));
            tag = '###ListNumMetCKegg'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetKEGGID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCSeed',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetSEEDID,2)));
            tag = '###ListNumMetCSeed'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetSEEDID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCIKey',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetInchiKey,2)));
            tag = '###ListNumMetCIKey'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetInchiKey; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCIString',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetInchiString,2)));
            tag = '###ListNumMetCIString'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetInchiString; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCChebi',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetChEBIID,2)));
            tag = '###ListNumMetCChebi'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetChEBIID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCHmdb',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetHMDBID,2)));
            tag = '###ListNumMetCHmdb'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetHMDBID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCReac',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetReactomeID,2)));
            tag = '###ListNumMetCReac'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetReactomeID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCMetNetX',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetMetaNetXID,2)));
            tag = '###ListNumMetCMetNetX'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetMetaNetXID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCBigg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetBiGGID,2)));
            tag = '###ListNumMetCBigg'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetBiGGID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetCBioc',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetConfmetBioCycID,2)));
            tag = '###ListNumMetCBioc'; list = modelProperties.(F{i}).modelProp2.Details.AnnoMetNonConfmetBioCycID; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###ScoreAnnotationMetabolites',num2str(round(modelProperties.(F{i}).modelProp2.Scores.AnnotationMetabolites,2)));

            % Reaction Annotation
            tline= regexprep(tline,'###NumRAnnoAny',num2str(round(modelProperties.(F{i}).modelProp2.rxnWAnno,2)));
            tag = '###ListNumRAnnoAny'; list = modelProperties.(F{i}).modelProp2.Details.rxnWOAnno; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRRhea',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnRheaID,2)));
            tag = '###ListNumRRhea'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnRheaID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRRhea',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnRheaID,2)));
            tag = '###ListNumCRRhea'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnRheaID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRKegg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnKEGGID,2)));
            tag = '###ListNumRKegg'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnKEGGID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRKegg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnKEGGID,2)));
            tag = '###ListNumCRKegg'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnKEGGID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRSeed',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnSEEDID,2)));
            tag = '###ListNumRSeed'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnSEEDID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRSeed',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnSEEDID,2)));
            tag = '###ListNumCRSeed'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnSEEDID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRMetX',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnMetaNetXID,2)));
            tag = '###ListNumRMetX'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnMetaNetXID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRMetX',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnMetaNetXID,2)));
            tag = '###ListNumCRMetX'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnMetaNetXID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRBigg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnBiGGID,2)));
            tag = '###ListNumRBigg'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnBiGGID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRBigg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnBiGGID,2)));
            tag = '###ListNumCRBigg'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnBiGGID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRReac',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnReactomeID,2)));
            tag = '###ListNumRReac'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnReactomeID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRReac',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnReactomeID,2)));
            tag = '###ListNumCRReac'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnReactomeID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRBren',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnBRENDAID,2)));
            tag = '###ListNumRBren'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnBRENDAID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRBren',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnBRENDAID,2)));
            tag = '###ListNumCRBren'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnBRENDAID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRBioc',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnBioCycID,2)));
            tag = '###ListNumRBioc'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnBioCycID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCRBioc',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnBioCycID,2)));
            tag = '###ListNumCRBioc'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnBioCycID; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumREcn',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnrxnECNumbers,2)));
            tag = '###ListNumREcn'; list = modelProperties.(F{i}).modelProp2.Details.missingrxnECNumbers; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCREcn',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnConfrxnECNumbers,2)));
            tag = '###ListNumCREcn'; list = modelProperties.(F{i}).modelProp2.Details.AnnoRxnNonConfrxnECNumbers; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###ScoreAnnotationReactions',num2str(round(modelProperties.(F{i}).modelProp2.Scores.AnnotationReactions,2)));

            % Gene Annotation

            tline= regexprep(tline,'###NumGAnnoAny',num2str(round(modelProperties.(F{i}).modelProp2.geneWAnno,2)));
            tag = '###ListNumGAnnoAny'; list = modelProperties.(F{i}).modelProp2.Details.geneWOAnno; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGRefSeq',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneRefSeqID,2)));
            tag = '###ListNumGRefSeq'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneRefSeqID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGUniProt',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneUniprotID,2)));
            tag = '###ListNumGUniProt'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneUniprotID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGEcoGene',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneEcoGeneID,2)));
            tag = '###ListNumGEcoGene'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneEcoGeneID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGKegg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneKEGGID,2)));
            tag = '###ListNumGKegg'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneKEGGID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGNCBIG',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneEntrezID,2)));
            tag = '###ListNumGNCBIG'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneEntrezID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGNCBIP',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneNCBIProteinID,2)));
            tag = '###ListNumGNCBIP'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneNCBIProteinID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGCCDS',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneCCDSID,2)));
            tag = '###ListNumGCCDS'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneCCDSID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGHPRD',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneHPRDID,2)));
            tag = '###ListNumGHPRD'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneHPRDID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGASAP',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGenegeneASAPID,2)));
            tag = '###ListNumGASAP'; list = modelProperties.(F{i}).modelProp2.Details.missinggeneASAPID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGRefSeq',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneRefSeqID,2)));
            tag = '###ListNumCGRefSeq'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneRefSeqID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGUniProt',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneUniprotID,2)));
            tag = '###ListNumCGUniProt'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneUniprotID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGEcoGene',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneEcoGeneID,2)));
            tag = '###ListNumCGEcoGene'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneEcoGeneID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGKegg',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneKEGGID,2)));
            tag = '###ListNumCGKegg'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneKEGGID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGNCBIG',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneEntrezID,2)));
            tag = '###ListNumCGNCBIG'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneEntrezID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGNCBIP',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneNCBIProteinID,2)));
            tag = '###ListNumCGNCBIP'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneNCBIProteinID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGCCDS',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneCCDSID,2)));
            tag = '###ListNumCGCCDS'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneCCDSID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGHPRD',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneHPRDID,2)));
            tag = '###ListNumCGHPRD'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneHPRDID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumCGASAP',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneConfgeneASAPID,2)));
            tag = '###ListNumCGASAP'; list = modelProperties.(F{i}).modelProp2.Details.AnnoGeneNonConfgeneASAPID; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###ScoreAnnotationGenes',num2str(round(modelProperties.(F{i}).modelProp2.Scores.AnnotationGenes,2)));

            % SBO Annotation
            tline= regexprep(tline,'###NumMSBOAny',num2str(round(modelProperties.(F{i}).modelProp2.metWSBO,2)));
            tag = '###ListNumMSBOAny'; list = modelProperties.(F{i}).modelProp2.Details.metWOSBO; type = 'met';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumMetSBO247',num2str(round(modelProperties.(F{i}).modelProp2.AnnoMetSBO0000247,2)));

            tline= regexprep(tline,'###NumRSBOAny',num2str(round(modelProperties.(F{i}).modelProp2.rxnWSBO,2)));
            tag = '###ListNumRSBOAny'; list = modelProperties.(F{i}).modelProp2.Details.rxnWOSBO; type = 'rxn';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumRSBO176',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000176,2)));
            tline= regexprep(tline,'###NumRSBO176',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000176,2)));
            tline= regexprep(tline,'###NumRSBO185',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000185,2)));
            tline= regexprep(tline,'###NumRSBO627',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000627,2)));
            tline= regexprep(tline,'###NumRSBO628',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000628,2)));
            tline= regexprep(tline,'###NumRSBO632',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000632,2)));
            tline= regexprep(tline,'###NumRSBO629',num2str(round(modelProperties.(F{i}).modelProp2.AnnoRxnSBO0000629,2)));

            tline= regexprep(tline,'###NumGSBOAny',num2str(round(modelProperties.(F{i}).modelProp2.geneWSBO,2)));
            tag = '###ListNumGSBOAny'; list = modelProperties.(F{i}).modelProp2.Details.geneWOSBO; type = 'none';
            tline = writeListItem(tline,tag,list,type);

            tline= regexprep(tline,'###NumGSBO243',num2str(round(modelProperties.(F{i}).modelProp2.AnnoGeneSBO0000243,2)));

            tline= regexprep(tline,'###ScoreAnnotationSBO',num2str(round(modelProperties.(F{i}).modelProp2.Scores.AnnotationSBO,2)));

        end
        html{cnt} = tline;
        cnt = cnt + 1;
    end
    fclose(fid);
    html = html';
    ModelName = regexprep(ModelName,' ','_');
    fid =fopen([reportDir filesep 'modelreport_' ModelName '.html'], 'w');

    for j = 1 : length(html)-1
        fprintf(fid,strcat(html{j},'\n'));
    end

    fclose(fid);
end

function tlineOut = writeListItem(tline,tag,list,type)
%type = 'rxn';
%type = 'met';
if  regexp(tline,tag)
    %  tline= regexprep(tline,'###ListMedComp',num2str(modelProperties.(F{i}).modelProp2.MediumMets+2));
    tlineOut = '';
    for k = 1 : length(list)
        m = list{k};
        if strcmp(type,'rxn')
            tlineOut = strcat(tlineOut,'<li class="list-group-item"> <a href = https://vmh.life/#reaction/',m,' target = "_blank">',m,'</a>','</li>','\n');
        elseif strcmp(type,'met')
            if contains(m,'[')
                mpart = split(m,'[');
                mpart = mpart{1};
            else
                mpart = m;
            end
            tlineOut = strcat(tlineOut,'<li class="list-group-item"> <a href = https://vmh.life/#metabolite/',mpart,' target = "_blank">',m,'</a>','</li>','\n');
        elseif strcmp(type,'none')
            tlineOut = strcat(tlineOut,'<li class="list-group-item">',m,'</li>','\n');
        end
    end
else
    tlineOut = tline;
end


function mv = mrViewVoxelData(ui, roi);
%
% mv = mrViewTimeCourse(<ui>, <roi=selected ROI>);
%
% Plot a multi voxel UI for the selected ROI in a mrViewer UI.
%
% roi can be specified as an index into the mrViewer ROIs, a name
% of the ROI, or a loaded struct. ui defaults to the current viewer.
%
% ras, 07/06.
if notDefined('ui'), ui = mrViewGet; end
if notDefined('roi'),    roi = ui.rois(ui.settings.roi);    end

if ischar(roi)
    roi = ui.rois(cellfind({ui.rois.name}, roi));

elseif isnumeric(roi)
    roi = ui.rois(roi);

end

% this version is for mrVista 2, so we need a loaded mrSESSION.mat file,
% globals and all that (see sessionGUI_viewTimeCourse):
mrGlobals2;

% check if an event-related scan group is assigned.
% If so, use that; otherwise use the GUI selected scans.
scans = GUI.settings.scan;
dt = GUI.settings.dataType;
if isfield(dataTYPES(dt).scanParams(scans(1)), 'scanGroup') & ...
        ~isempty(dataTYPES(dt).scanParams(scans(1)).scanGroup)
    [scans dt] = er_getScanGroup(INPLANE{1});
end

roi = roiParse(roi);
roi.viewType = 'Inplane'; % always in this space, even if it was
                          % loaded from Volume/Gray

mv = multiVoxelUI(INPLANE{1}, roi, scans, dt);

if ~checkfields(GUI, 'controls', 'tcui')
    GUI.controls.tcui = [];
end
GUI.controls.tcui(end+1) = mv.ui.fig;

return


function rec = VOCreadrecxml(path)

x=VOCreadxml(path);
x=x.annotation;

rec.folder=x.folder;
rec.filename=x.filename;
rec.source.database=x.source.database;
rec.source.annotation=x.source.annotation;
rec.source.image=x.source.image;

rec.size.width=str2double(x.size.width);
rec.size.height=str2double(x.size.height);
rec.size.depth=str2double(x.size.depth);

rec.segmented=strcmp(x.segmented,'1');

rec.imgname=[x.folder '/JPEGImages/' x.filename];
rec.imgsize=str2double({x.size.width x.size.height x.size.depth});
rec.database=rec.source.database;

for i=1:length(x.object)
    rec.objects(i)=xmlobjtopas(x.object(i));
end

function p = xmlobjtopas(o)

p.class=o.name;

if isfield(o,'pose')
    if strcmp(o.pose,'Unspecified')
        p.view='';
    else
        p.view=o.pose;
    end
else
    p.view='';
end

if isfield(o,'truncated')
    p.truncated=strcmp(o.truncated,'1');
else
    p.truncated=false;
end

if isfield(o,'occluded')
    p.occluded=strcmp(o.occluded,'1');
else
    p.occluded=false;
end

if isfield(o,'difficult')
    p.difficult=strcmp(o.difficult,'1');
else
    p.difficult=false;
end

p.label=['PAS' p.class p.view];
if p.truncated
    p.label=[p.label 'Trunc'];
end
if p.occluded
    p.label=[p.label 'Occ'];
end
if p.difficult
    p.label=[p.label 'Diff'];
end

p.orglabel=p.label;

p.bbox=str2double({o.bndbox.xmin o.bndbox.ymin o.bndbox.xmax o.bndbox.ymax});

p.bndbox.xmin=str2double(o.bndbox.xmin);
p.bndbox.ymin=str2double(o.bndbox.ymin);
p.bndbox.xmax=str2double(o.bndbox.xmax);
p.bndbox.ymax=str2double(o.bndbox.ymax);

if isfield(o,'polygon')
    %warning('polygon unimplemented');
    p.polygon=[];
else
    p.polygon=[];
end

if isfield(o,'mask')
    warning('mask unimplemented');
    p.mask=[];
else
    p.mask=[];
end

if isfield(o,'part')&&~isempty(o.part)
    p.hasparts=true;
    for i=1:length(o.part)
        p.part(i)=xmlobjtopas(o.part(i));
    end
else
    p.hasparts=false;
    p.part=[];
end

if isfield(o,'actions')
    p.hasactions=true;
    fn=fieldnames(o.actions);
    for i=1:numel(fn)
        p.actions.(fn{i})=strcmp(o.actions.(fn{i}),'1');
    end
else
    p.hasactions=false;
    p.actions=[];
end


function [dt,t1] = dtiLoadDt6(fname, applyBrainMask)
%Load a dt6 (tensor) data file.
%
%  [dt,t1] = dtiLoadDt6(fname, [applyBrainMask=true]);
%
% Optionally, you can also load the T1 data file and apply a brain mask.
%
% The six entries are the diffusion tensor values, derived from the raw
% data.  The raw data can be in many different directions.  The diffusion
% tensor is a 3x3, symmetric, positive-definite matrix, D.  The six
% independent entries in the matrix are stored in a vector: (Dxx Dyy Dzz
% Dxy Dxz Dyz)
%
% The project-style dt6- contain no data, just pointers to data files.  The
% directory architecture of the data should be:
%
%
% HISTORY:
%  2007.10.29 RFD: wrote it, pulling parts from dtiLoadDT6. The dt6 loading
%  was a mess. Hopefully it is better now.
%
% (c) Stanford VISTA Team

%% Initialize the variables
dt = [];   % This is the main dt structure.
t1 = [];
if(~exist('fname','var') || isempty(fname))
    fname = [pwd filesep];
end
if(isdir(fname))
    [f,p] = uigetfile({'*.mat'}, 'Select a dt6 file...',fname);
    if(isequal(f,0)), disp('Load dt6 canceled.'); return; end
    fname = fullfile(p,f);
end
if(~exist('applyBrainMask','var') || isempty(applyBrainMask))
    applyBrainMask = true;
end

%% Load the dt6 information.
%  This information describes things like where the data files are.
[dt6Struct, dt.dataFile, defaultPath, dataDir] = dtiLoadDt6Info(fname);
[p,n] = fileparts(dataDir);
dt.subName = n;
[p,n] = fileparts(p);
if(~isempty(n))
    dt.subName = [n '_' dt.subName];
    [p,n] = fileparts(p);
    if(~isempty(n))
        dt.subName = [n '_' dt.subName];
    end
end

% Decide whether we will output the T1 data
if(nargout>1)
    loadT1 = true;
    t1.talairachScale = [];
else
    loadT1 = false;
end

%% Read the data
% We support both new NIFTI-based dt6 files and the old dt6 file format.
if(isfield(dt6Struct,'files'))   % Test whether new dt6 stye
    %
    % New project-style dt6- contains no data, just pointers to data files.
    %
    [dt.dt6, dt.xformToAcpc, dt.mmPerVoxel] = dtiLoadTensorsFromNifti(dt6Struct.files.tensors);
    dt.adcUnits = '';

    clear ni;
    ni = niftiRead(dt6Struct.files.b0);
    ni.data(isnan(ni.data)) = 0;
    dt.b0 = ni.data;

    clear ni;
    ni = niftiRead(dt6Struct.files.brainMask);
    dt.brainMask = ni.data;

    if(loadT1 && isfield(dt6Struct.files,'t1'))
        t1Fname = dt6Struct.files.t1;
        if(exist(t1Fname,'file'))
            ni = niftiRead(t1Fname);
            t1.img = ni.data;
            t1.xformToAcpc = ni.qto_xyz;
            t1.mmPerVoxel = ni.pixdim(1:3);
        else
            % try another level up
            t1Fname = dt6Struct.files.t1;
            if(exist(t1Fname,'file'))
                ni = niftiRead(t1Fname);
                t1.img = ni.data;
                t1.xformToAcpc = ni.qto_xyz;
                t1.mmPerVoxel = ni.pixdim(1:3);
            else
                disp(['Couldn''t load t1 file "' t1Fname '".']);
            end
        end
        % look for a t1 brain mask in there too
        t1MaskName = fullfile(fileparts(t1Fname),'t1_mask.nii.gz');
		if(~exist(t1MaskName,'file'))
		  t1MaskName = fullfile(fileparts(t1Fname),'t1_brain_mask.nii.gz');
		end
        if(exist(t1MaskName,'file'))
            ni = niftiRead(t1MaskName);
            t1.brainMask = ni.data;
            t1.brainMaskXform = ni.qto_xyz;
        end
    end
    dt.files = dt6Struct.files;
else
    %
    % It's an old dt6 file- the data are already loaded, but we need to
    % check things and pack the relevant structs.
    %
    if(~isfield(dt6Struct, 'xformToAcPc')), dt.xformToAcpc = eye(4);
    else dt.xformToAcpc = dt6Struct.xformToAcPc; end
    dt.dt6 = dt6Struct.dt6;
    dt.mmPerVoxel = dt6Struct.mmPerVox;

    dt6Struct.b0(isnan(dt6Struct.b0)) = 0;
    dt.b0 = dt6Struct.b0;

    if(isfield(dt6Struct,'brainMask'))
        dt.brainMask = dt6Struct.brainMask;
    elseif(isfield(dt6Struct,'dtBrainMask'))
        dt.brainMask = dt6Struct.dtBrainMask;
    else
        dt.brainMask = [];
    end

    if(isfield(dt6Struct, 'adcUnits'))
        dt.adcUnits = dt6Struct.adcUnits;
    else
        dt.adcUnits = '';
    end

    if(loadT1 && isfield(dt6Struct,'anat'))
        t1.img = double(dt6Struct.anat.img);
        t1.xformToAcpc = dt6Struct.anat.xformToAcPc;
        t1.mmPerVoxel = dt6Struct.anat.mmPerVox;
        if(isfield(dt6Struct.anat, 'brainMask'))
            t1.brainMask = dt6Struct.anat.brainMask;
            t1.brainMaskXform = dt6Struct.anat.xformToAcPc;
        end

        if(isfield(dt6Struct.anat, 'talScale'))
            t1.talairachScale = dt6Struct.anat.talScale;
        end
    end
    dt.files = [];
end

%% Set up the T1 data
if(loadT1 && isempty(t1.talairachScale) && isfield(t1,'brainMask') && ~isempty(t1.brainMask))
    % Approximate Talairach scales using brain mask
    disp('Computing Talairach scales from brain mask...');
    t1.talairachScale = mrAnatGetTalairachScalesFromMask(t1.brainMask, t1.brainMaskXform);
end

%% NaN's take forever on Pentium 4 CPUs!
% (eg. http://www.psychology.nottingham.ac.uk/staff/cr1/simd.html)
dt.dt6(isnan(dt.dt6)) = 0;

%% Apply the brain mask, if it exists
if(applyBrainMask && ~isempty(dt.brainMask))
    for ii=1:6
        tmp = dt.dt6(:,:,:,ii);
        tmp(~dt.brainMask) = 0;
        dt.dt6(:,:,:,ii) = tmp;
    end
end
if(isempty(dt.brainMask))
    dt.brainMask = dt.dt6(:,:,:,1)>0;
end

%% Convert adc units to our standard micrometers^2 / millisecond
if(isempty(dt.adcUnits))
    [dt.adcUnits,dt.adcScale,stdUnitStr] = dtiGuessDiffusivityUnits(dt.dt6);
    if(dt.adcScale~=1)
        dt.dt6 = dt.dt6*dt.adcScale;
    end
    dt.adcUnits = stdUnitStr;
end

%% Apply a spatial transformation
if(isfield(dt6Struct,'xformVAnatToAcpc'))
    dt.xformVAnatToAcpc = dt6Struct.xformVAnatToAcpc;
elseif(isfield(dt6Struct,'xformToMrVista') && exist('t1','var') && ~isempty(t1))
    % try to use an old vanatXform
    warning('mrDiffusion:deprecated','Using old xformToMrVista field- you may want to recompute this using Xform->Compute mrVista xform');
    dt.xformVAnatToAcpc = t1.xformToAcpc*dt6Struct.xformToMrVista;
end
if(loadT1 && isfield(dt6Struct,'t1NormParams'))
    t1.t1NormParams = dt6Struct.t1NormParams;
end

%% Set the default bounding box
dt.bb = sort(mrAnatXformCoords(dt.xformToAcpc, [1 1 1; size(dt.brainMask)]));
if(any(dt.mmPerVoxel<1))
    dt.renderMm = dt.mmPerVoxel;
else
    dt.renderMm = [1 1 1];
end

return;