function d2img = draw_2Dskeleton_ITOP(db,fileId,coord_pixel)

    db_path = strcat('/home/gyeongsikmoon/workspace/Data/Human_pose_estimation/ITOP/',db,'_view/','ITOP_',db,'_test_depth_map.h5');
    jointNum =  15;
    cubicSz = 2.0;
    imgHeight = 240;
    imgWidth = 320;

    annot_path = strcat('/home/gyeongsikmoon/workspace/Data/Human_pose_estimation/ITOP/',db,'_view/','ITOP_',db,'_test_labels.h5');

    coord_pixel = squeeze(coord_pixel);
    rgb_img = zeros(imgHeight,imgWidth,3);
    refDepths = zeros(1,jointNum);
    line_width = 6;

    gt = h5read(annot_path,'/real_world_coordinates',[1 1 fileId],[3 jointNum 1]);
    for jid = 1:jointNum
        refDepths(1,jid) = gt(3,jid,1);
    end
    refDepth = (min(refDepths(:)) + max(refDepths(:)))/2;

    img = h5read(db_path,'/data',[1 1 fileId],[imgWidth imgHeight 1]);
    img = permute(img,[2,1]);
    img(img==0) = refDepth+cubicSz/2;

    if strcmp(db,'top')
        mask = h5read(annot_path,'/segmentation',[1 1 fileId],[imgWidth imgHeight 1]);
        mask = permute(mask,[2,1]);
        img(mask==-1) = refDepth+cubicSz/2;
    end

    if strcmp(db,'side')
        if 1 <= min(coord_pixel(2,:)-15)
            img(1:round(min(coord_pixel(2,:)))-15,:) = refDepth+cubicSz/2;
        end
        if max(coord_pixel(2,:))+15 <= imgHeight
            img(round(max(coord_pixel(2,:)))+15:imgHeight,:) = refDepth+cubicSz/2;
        end
        if 1 <= min(coord_pixel(1,:)) - 15
            img(:,1:round(min(coord_pixel(1,:)))-15) = refDepth+cubicSz/2;
        end
        if max(coord_pixel(1,:)) + 15 <= imgWidth
            img(:,round(max(coord_pixel(1,:)))+15:imgWidth) = refDepth+cubicSz/2;
        end

        img(img < min(coord_pixel(3,:))-0.15) = refDepth+cubicSz/2;
        img(img > max(coord_pixel(3,:))+0.15) = refDepth+cubicSz/2;
    end

    img(img>refDepth+cubicSz/2) = refDepth + cubicSz/2;
    img(img<refDepth-cubicSz/2) = refDepth - cubicSz/2;
    img = img - refDepth;
    img = img/(cubicSz/2);

    img = img + 1;
    img = img/2;

    rgb_img(:,:,1) = img*255/255;
    rgb_img(:,:,2) = img*240/255;
    rgb_img(:,:,3) = img*204/255;

    f = figure;
    set(f, 'visible', 'off');
    imshow(rgb_img);
    hold on;

    plot([coord_pixel(1,1),coord_pixel(1,2)],[coord_pixel(2,1),coord_pixel(2,2)],'Color',[255/255,178/255,102/255],'LineWidth',line_width) %neck to head

    plot([coord_pixel(1,2),coord_pixel(1,3)],[coord_pixel(2,2),coord_pixel(2,3)],'Color',[255/255,153/255,153/255],'LineWidth',line_width) %neck to r_shoulder
    plot([coord_pixel(1,3),coord_pixel(1,5)],[coord_pixel(2,3),coord_pixel(2,5)],'Color',[255/255,102/255,102/255],'LineWidth',line_width) %r_shoulder to r_elbow
    plot([coord_pixel(1,5),coord_pixel(1,7)],[coord_pixel(2,5),coord_pixel(2,7)],'Color',[255/255,51/255,51/255],'LineWidth',line_width) %r_elbow to r_hand

    plot([coord_pixel(1,2),coord_pixel(1,4)],[coord_pixel(2,2),coord_pixel(2,4)],'Color',[153/255,255/255,153/255],'LineWidth',line_width) %neck to l_shoulder
    plot([coord_pixel(1,4),coord_pixel(1,6)],[coord_pixel(2,4),coord_pixel(2,6)],'Color',[102/255,255/255,102/255],'LineWidth',line_width) %l_shoulder to l_elbow
    plot([coord_pixel(1,6),coord_pixel(1,8)],[coord_pixel(2,6),coord_pixel(2,8)],'Color',[51/255,255/255,51/255],'LineWidth',line_width) %l_elbow to l_hand

    plot([coord_pixel(1,2),coord_pixel(1,9)],[coord_pixel(2,2),coord_pixel(2,9)],'Color',[230/255,230/255,0/255],'LineWidth',line_width) %neck to torso

    plot([coord_pixel(1,9),coord_pixel(1,10)],[coord_pixel(2,9),coord_pixel(2,10)],'Color',[255/255,153/255,255/255],'LineWidth',line_width) %torso to r_hip
    plot([coord_pixel(1,10),coord_pixel(1,12)],[coord_pixel(2,10),coord_pixel(2,12)],'Color',[255/255,102/255,255/255],'LineWidth',line_width) %r_hip to r_knee
    plot([coord_pixel(1,12),coord_pixel(1,14)],[coord_pixel(2,12),coord_pixel(2,14)],'Color',[255/255,51/255,255/255],'LineWidth',line_width) %r_knee to r_foot

    plot([coord_pixel(1,9),coord_pixel(1,11)],[coord_pixel(2,9),coord_pixel(2,11)],'Color',[153/255,204/255,255/255],'LineWidth',line_width) %torso to l_hip
    plot([coord_pixel(1,11),coord_pixel(1,13)],[coord_pixel(2,11),coord_pixel(2,13)],'Color',[102/255,178/255,255/255],'LineWidth',line_width) %l_hip to l_knee
    plot([coord_pixel(1,13),coord_pixel(1,15)],[coord_pixel(2,13),coord_pixel(2,15)],'Color',[51/255,153/255,255/255],'LineWidth',line_width) %l_knee to l_foot

    colorList = [
    255/255 178/255 102/255;

    230/255 230/255 0/255;

    255/255 153/255 153/255;
    153/255 255/255 153/255;

    255/255 102/255 102/255;
    102/255 255/255 102/255;

    255/255 51/255 51/255;
    51/255 255/255 51/255;

    230/255 230/255 0/255;

    255/255 153/255 255/255;
    153/255 204/255 255/255;

    255/255 102/255 255/255;
    102/255 178/255 255/255;

    255/255 51/255 255/255;
    51/255 153/255 255/255];
    scatter(coord_pixel(1,:),coord_pixel(2,:),150,colorList,'filled');

    set(gca,'Units','normalized','Position',[0 0 1 1]);  %# Modify axes size
    set(gcf,'Units','pixels','Position',[200 200 2*imgWidth 2*imgHeight]);  %# Modify figure size

    frame = getframe(gcf);
    framedata = frame.cdata;

    xmin = min(coord_pixel(1,:));
    xmax = max(coord_pixel(1,:));
    ymin = min(coord_pixel(2,:));
    ymax = max(coord_pixel(2,:));

    len = max(xmax-xmin+1,ymax-ymin+1) + 70;
    xcenter = (xmin + xmax)/2;
    ycenter = (ymin + ymax)/2;

    xmin = max(round(xcenter - len/2),1);
    xmax = min(round(xmin + len),imgWidth);
    ymin = max(round(ycenter - len/2),1);
    ymax = min(round(ymin + len),imgHeight);
    framedata = framedata(2*ymin:2*ymax,2*xmin:2*xmax,:);

    hold off;
    close(f);

    d2img = framedata;

end


function [cfg] = ft_topoplotER(cfg, varargin)

% FT_TOPOPLOTER plots the topographic distribution over the head of a 2-dimensional
% data representations such as the event-related potentials or fields, or a power
% or connectivity spectrum.
%
% Use as
%   ft_topoplotER(cfg, timelock)
% or
%   ft_topoplotER(cfg, freq)
%
% The data can be an ERP/ERF produced by FT_TIMELOCKANALYSIS, a power spectrum
% (without time dimension) produced by FT_FREQANALYSIS or a connectivity spectrum
% produced by FT_CONNECTIVITYANALYSIS. Also, the output to FT_FREQSTATISTICS and
% FT_TIMELOCKSTATISTICS can be visualised.
%
% The configuration can have the following parameters
%   cfg.parameter          = field that contains the data to be plotted as color, for example 'avg', 'powspctrm' or 'cohspctrm' (default is automatic)
%   cfg.maskparameter      = field in the data to be used for masking of data. It should have alues between 0 and 1, where 0 corresponds to transparent.
%   cfg.xlim               = limit for 1st dimension in data (e.g., time), can be 'maxmin' or [xmin xmax] (default = 'maxmin')
%   cfg.zlim               = limits for color dimension, 'maxmin', 'maxabs', 'zeromax', 'minzero', or [zmin zmax] (default = 'maxmin')
%   cfg.channel            = Nx1 cell-array with selection of channels (default = 'all'), see FT_CHANNELSELECTION for details
%   cfg.refchannel         = name of reference channel for visualising connectivity, can be 'gui'
%   cfg.baseline           = 'yes','no' or [time1 time2] (default = 'no'), see FT_TIMELOCKBASELINE or FT_FREQBASELINE
%   cfg.baselinetype       = 'absolute' or 'relative' (default = 'absolute')
%   cfg.trials             = 'all' or a selection given as a 1xN vector (default = 'all')
%   cfg.colormap           = string, or Nx3 matrix, see FT_COLORMAP
%   cfg.marker             = 'on', 'labels', 'numbers', 'off'
%   cfg.markersymbol       = channel marker symbol (default = 'o')
%   cfg.markercolor        = channel marker color (default = [0 0 0] (black))
%   cfg.markersize         = channel marker size (default = 2)
%   cfg.markerfontsize     = font size of channel labels (default = 8 pt)
%   cfg.highlight          = 'off', 'on', 'labels', 'numbers'
%   cfg.highlightchannel   =  Nx1 cell-array with selection of channels, or vector containing channel indices see FT_CHANNELSELECTION
%   cfg.highlightsymbol    = highlight marker symbol (default = 'o')
%   cfg.highlightcolor     = highlight marker color (default = [0 0 0] (black))
%   cfg.highlightsize      = highlight marker size (default = 6)
%   cfg.highlightfontsize  = highlight marker size (default = 8)
%   cfg.hotkeys            = enables hotkeys (pageup/pagedown/m) for dynamic zoom and translation (ctrl+) of the color limits
%   cfg.colorbar           = whether to show a colorbar alongside the figure (default = 'no')
%                            'no'                 do not show a colorbar
%                            'yes'                at the default MATLAB location
%                            'North'              inside plot box near top
%                            'South'              inside bottom
%                            'East'               inside right
%                            'West'               inside left
%                            'NorthOutside'       outside plot box near top
%                            'SouthOutside'       outside bottom
%                            'EastOutside'        outside right
%                            'WestOutside'        outside left
%   cfg.colorbartext       =  string indicating the text next to colorbar
%   cfg.interplimits       = limits for interpolation (default = 'head')
%                            'electrodes'         to furthest electrode
%                            'head'               to edge of head
%   cfg.interpolation      = 'linear','cubic','nearest','v4' (default = 'v4') see GRIDDATA
%   cfg.style              = plot style (default = 'both')
%                            'straight'           colormap only
%                            'contour'            contour lines only
%                            'both'               both colormap and contour lines
%                            'fill'               constant color between lines
%                            'blank'               only the head shape
%   cfg.gridscale          = scaling grid size that determines resolution of figure (default = 67)
%   cfg.shading            = 'flat' or 'interp' (default = 'flat')
%   cfg.comment            = 'no', 'auto' or 'xlim' (default = 'auto')
%                            'auto': date, xparam and zparam limits are printed
%                            'xlim': only xparam limits are printed
%   cfg.commentpos         = string or two numbers, position of the comment (default = 'leftbottom')
%                            'lefttop' 'leftbottom' 'middletop' 'middlebottom' 'righttop' 'rightbottom'
%                            'title' to place comment as title
%                            'layout' to place comment as specified for COMNT in layout
%                            [x y] coordinates
%   cfg.interactive        = Interactive plot 'yes' or 'no' (default = 'yes')
%                            In a interactive plot you can select areas and produce a new
%                            interactive plot when a selected area is clicked. Multiple areas
%                            can be selected by holding down the SHIFT key.
%   cfg.directionality     = '', 'inflow' or 'outflow' specifies for
%                            connectivity measures whether the inflow into a
%                            node, or the outflow from a node is plotted. The
%                            (default) behavior of this option depends on the dimord
%                            of the input data (see below).
%   cfg.layout             = specify the channel layout for plotting using one of the supported ways (see below).
%   cfg.interpolatenan     = 'yes' or 'no', whether to interpolate over channels containing NaNs (default = 'yes')
%   cfg.figure             = 'yes' or 'no', whether to open a new figure. You can also specify a figure handle from FIGURE, GCF or SUBPLOT. (default = 'yes')
%
% For the plotting of directional connectivity data the cfg.directionality option
% determines what is plotted. The default value and the supported functionality
% depend on the dimord of the input data. If the input data is of dimord
% 'chan_chan_XXX', the value of directionality determines whether, given the
% reference channel(s), the columns (inflow), or rows (outflow) are selected for
% plotting. In this situation the default is 'inflow'. Note that for undirected
% measures, inflow and outflow should give the same output. If the input data is of
% dimord 'chancmb_XXX', the value of directionality determines whether the rows in
% data.labelcmb are selected. With 'inflow' the rows are selected if the
% refchannel(s) occur in the right column, with 'outflow' the rows are selected if
% the refchannel(s) occur in the left column of the labelcmb-field. Default in this
% case is '', which means that all rows are selected in which the refchannel(s)
% occur. This is to robustly support linearly indexed undirected connectivity
% metrics. In the situation where undirected connectivity measures are linearly
% indexed, specifying 'inflow' or 'outflow' can result in unexpected behavior.
%
% The layout defines how the channels are arranged. You can specify the
% layout in a variety of ways:
%  - you can provide a pre-computed layout structure, see FT_PREPARE_LAYOUT
%  - you can give the name of an ascii layout file with extension *.lay
%  - you can give the name of an electrode file
%  - you can give an electrode definition, i.e. "elec" structure
%  - you can give a gradiometer definition, i.e. "grad" structure
% If you do not specify any of these and the data structure contains an
% electrode or gradiometer structure, that will be used for creating a
% layout. If you want to have more fine-grained control over the layout
% of the subplots, you should create your own layout file.
%
% See also FT_SINGLEPLOTER, FT_MULTIPLOTER, FT_SINGLEPLOTTFR, FT_MULTIPLOTTFR,
% FT_TOPOPLOTTFR, FT_PREPARE_LAYOUT

% Undocumented options:
%
% It is possible to use multiple highlight-selections (e.g.: multiple
% statistical clusters of channels) To do this, all the content of
% the highlight-options (including cfg.highlight) should be placed
% in a cell-array (even if the normal content was already in a
% cell-array). Specific marker settings (e.g. color, size) are defaulted
% when not present.
%
% Example (3 selections):
% cfg.highlight          = {'labels', 'labels', 'numbers'}
% cfg.highlightchannel   = {{'MZF03','MZC01','MRT54'}, [1:5], 'C*'}
% cfg.highlightsymbol    = {'o',[],'+'}        % the empty option will be defaulted
% cfg.highlightcolor     = {'r',[0 0 1]};      % the missing option will be defaulted
% cfg.highlightsize      = [];                 % will be set to default, as will the missing cfg.highlightfontsize
%
% Other options:
% cfg.labeloffset (offset of labels to their marker, default = 0.005)

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DEVELOPERS NOTE: This code is organized in a similar fashion for multiplot/singleplot/topoplot
% and for ER/TFR and should remain consistent over those 6 functions.
% Section 1: general cfg handling that is independent from the data
% Section 2: data handling, this also includes converting bivariate (chan_chan and chancmb) into univariate data
% Section 3: cfg handling that depends on the data
% Section 4: actual plotting
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Section 1: general cfg handling that is independent from the data

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble loadvar varargin
ft_preamble provenance varargin

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% this is needed for the figure title
if isfield(cfg, 'dataname') && ~isempty(cfg.dataname)
  dataname = cfg.dataname;
elseif isfield(cfg, 'inputfile') && ~isempty(cfg.inputfile)
  dataname = cfg.inputfile;
elseif nargin>1
  dataname = arrayfun(@inputname, 2:nargin, 'UniformOutput', false);
else
  dataname = {};
end

% make sure figure window titles are labeled appropriately, pass this onto the actual plotting function
cfg.funcname = mfilename;
cfg.dataname = dataname;

% prepare the layout, this should be done only once
tmpcfg = keepfields(cfg, {'layout', 'channel', 'rows', 'columns', 'commentpos', 'skipcomnt', 'scalepos', 'skipscale', 'projection', 'viewpoint', 'rotate', 'width', 'height', 'elec', 'grad', 'opto', 'linecolor', 'showcallinfo', 'trackcallinfo', 'trackusage', 'trackdatainfo', 'trackmeminfo', 'tracktimeinfo', 'checksize'});
cfg.layout = ft_prepare_layout(tmpcfg, varargin{1});

% call the common function that is shared between ft_topoplotER and ft_topoplotTFR
cfg = topoplot_common(cfg, varargin{:});

% remove this field again, it is only used for figure labels
cfg = removefields(cfg, 'funcname');

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble previous varargin
ft_postamble provenance
ft_postamble savefig

% add a menu to the figure, but only if the current figure does not have subplots
menu_fieldtrip(gcf, cfg, false);

if ~ft_nargout
  % don't return anything
  clear cfg
end


function p = remove_redundant(p);

if isempty(p.F_struc)
    return
end

b = p.F_struc(1+p.K.f:p.K.l+p.K.f,1);
A = -p.F_struc(1+p.K.f:p.K.l+p.K.f,2:end);

redundant = find(((A>0).*A*(p.ub-p.lb) - (b-A*p.lb) <-1e-2));

if length(redundant)>1
    p.InequalityConstraintState(redundant) = inf;
end

if p.options.bmibnb.lpreduce
    b = p.lpcuts(:,1);
    A = -p.lpcuts(:,2:end);
    redundant = find(((A>0).*A*(p.ub-p.lb) - (b-A*p.lb) <-1e-2));
    if length(redundant)>1
        p.lpcuts(redundant,:) = [];
        p.cutState(redundant) = [];
    end
end

if any(p.K.f)
    b = p.F_struc(1:p.K.f,1);
    A = -p.F_struc(1:p.K.f,2:end);
    s1 = ((A>0).*A*(p.ub-p.lb) - (b-A*p.lb) <1e-6);
    s2 = ((-A>0).*(-A)*(p.ub-p.lb) - ((-b)-(-A)*p.lb) <1e-6);
    redundant = find(s1 & s2);
    if length(redundant)>1
        p.EqualityConstraintState(redundant) = inf;
    end
end


function [document, scores] = report_precision_recall(context, experiment, trackers, sequences, varargin)
% report_overlap Generate a report using tracking precision recall methodology
%
% Performs tracking precision-recall analysis and generates a report based on the results.
%
% Input:
% - context (structure): Report context structure.
% - experiment (struct): An experiment structure.
% - trackers (cell): An array of tracker structures.
% - sequences (cell): An array of sequence structures.
% - varargin[UseTags] (boolean): Analyze according to tags (otherwise according to sequences).
% - varargin[HideLegend] (boolean): Hide legend in plots.
%
% Output:
% - document (structure): Resulting document structure.
% - scores (struct): A scores structure.
%

usetags = get_global_variable('report_tags', true);
hidelegend = get_global_variable('report_lagend_hide', false);
resolution = 100;

for i = 1:2:length(varargin)
    switch lower(varargin{i})
        case 'usetags'
            usetags = varargin{i+1};
        case 'resolutuion'
            resolution = varargin{i+1};
        case 'hidelegend'
            hidelegend = varargin{i+1};
        otherwise
            error(['Unknown switch ', varargin{i}, '!']) ;
    end
end

if ~strcmp(experiment.type, 'unsupervised')
   error('Tracking precision-recall analysis only suitable for unsupervised experiments!');
end

document = document_create(context, 'tpr', 'title', 'Tracking precision recall');

trackers_hash = md5hash(strjoin((cellfun(@(x) x.identifier, trackers, 'UniformOutput', false)), '-'), 'Char', 'hex');
parameters_hash = md5hash(sprintf('%d%d', usetags, resolution));

tags = {};

if isempty(experiment.tags)
    usetags = false;
end;

if usetags && isfield(experiment, 'tags')
    tags = union(experiment.tags, {'all'});
    sequences_hash = md5hash(strjoin(tags, '-'), 'Char', 'hex');
else
    sequences_hash = md5hash(strjoin((cellfun(@(x) x.name, sequences, 'UniformOutput', false)), '-'), 'Char', 'hex');
end;

cache_identifier = sprintf('tpr_%s_%s_%s_%s', experiment.name, trackers_hash, sequences_hash, parameters_hash);

result = document_cache(context, cache_identifier, @analyze_precision_recall, experiment, trackers, ...
    sequences, 'Tags', tags, 'Resolution', resolution);

if usetags
    % When using tags we have inserted a separate one for this
    mask = strcmp('tag_all', result.selectors);

    average_curve = result.curves(:, mask);
    average_measures = result.measures(:, mask);

    % Now remove the 'all' tag from results
    tag_curve = result.curves(:, ~mask);
    tag_measures = result.measures(:, ~mask);

    selector_tags = cat(2, result.selectors(~mask), result.selectors(mask));

else

    average_curve = cell(numel(trackers), 1);
    average_measures = zeros(numel(trackers), 3);

    for t = 1:numel(trackers)
        average_curve{t} = mean(cat(3, result.curves{t, :}), 3);
        f = 2 * (average_curve{t}(:, 1) .* average_curve{t}(:, 2)) ./ (average_curve{t}(:, 1) + average_curve{t}(:, 2));
        [average_measures(t, 1), idx] = max(f);
        average_measures(t, 2) = average_curve{t}(idx, 1);
        average_measures(t, 3) = average_curve{t}(idx, 2);
    end;

    tag_curve = result.curves;
    tag_measures = result.measures;

    selector_tags = result.selectors;

end

scores.name = 'TPR';
scores.values = average_measures;
scores.ids = {'f', 'tp', 'tr'};
scores.names = {'F', 'TP', 'TR'};
scores.order = {'descending', 'descending', 'descending'};

tracker_labels = cellfun(@(x) iff(isfield(x.metadata, 'verified') && x.metadata.verified, [x.label, '*'], x.label), trackers, 'UniformOutput', 0);

print_text('Writing tracking precision-recall table ...');

document.section('Experiment %s', experiment.name);

pr_plot(document, sprintf('%s_average', experiment.name), ...
    sprintf('Experiment %s (average)', experiment.name), ...
    trackers, average_curve, hidelegend);

table_data = highlight_best_rows(num2cell(cat(2, tag_measures(:, : , 1), average_measures(:, 1))), repmat({'descending'}, 1, size(tag_measures, 2) + 1));

document.table(table_data, 'columnLabels', selector_tags, 'rowLabels', tracker_labels, 'title', 'Tracking precision-recall overview');

document.subsection('Detailed plots');

for t = 1:size(tag_curve, 2)

    plot_title = sprintf('Tracking precision-recall plot for tag %s in experiment %s', ...
        selector_tags{t}, experiment.name);
    plot_id = sprintf('overlap_%s_%s', experiment.name, selector_tags{t});

    pr_plot(document, plot_id, plot_title, trackers, tag_curve(:, t), ~hidelegend);

end;

document.write();

end

function pr_plot(document, identifier, title, trackers, curves, hidelegend)

    handle = plot_blank('Visible', false, 'Title', 'Overlap', 'Width', 6, 'Height', 6); hold on;

    phandles = zeros(numel(trackers), 1);

    for t = 1:numel(curves)
        phandles(t) = plot(curves{t}(:, 2), curves{t}(:, 1), 'Color', trackers{t}.style.color);
    end;

    labels = cellfun(@(x) x.label, trackers, 'UniformOutput', false);

    if ~hidelegend
        legend(phandles, labels);
    end;

    xlabel('Tracking recall');
    ylabel('Tracking precision');
    xlim([0, 1]);
    ylim([0, 1]);
    hold off;
    document.figure(handle, identifier, title);

    close(handle);
end


% sdae - training a stacked DAE (finetuning)
% Copyright (C) 2011 KyungHyun Cho, Tapani Raiko, Alexander Ilin
%
% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License
% as published by the Free Software Foundation; either version 2
% of the License, or (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
%
function [S] = sdae(S, patches, valid_patches, valid_portion);

if nargin < 3
    early_stop = 0;
    valid_patches = [];
    valid_portion = 0;
else
    early_stop = 1;
    valid_err = -Inf;
    valid_best_err = -Inf;
end

actual_lrate = S.learning.lrate;

n_samples = size(patches, 1);

layers = S.structure.layers;
n_layers = length(layers);

if layers(1) ~= size(patches, 2)
    error('Data is not properly aligned');
end

minibatch_sz = S.learning.minibatch_sz;
n_minibatches = ceil(n_samples / minibatch_sz);

n_epochs = S.iteration.n_epochs;

momentum = S.learning.momentum;
weight_decay = S.learning.weight_decay;

biases_grad = cell(n_layers, 1);
W_grad = cell(n_layers, 1);
biases_grad_old = cell(n_layers, 1);
W_grad_old = cell(n_layers, 1);
for l = 1:n_layers
    biases_grad{l} = zeros(size(S.biases{l}))';
    if l < n_layers
        W_grad{l} = zeros(size(S.W{l}));
    end
    biases_grad_old{l} = zeros(size(S.biases{l}))';
    if l < n_layers
        W_grad_old{l} = zeros(size(S.W{l}));
    end
end

min_recon_error = Inf;
min_recon_error_update_idx = 0;
stopping = 0;

do_normalize = S.do_normalize;
do_normalize_std = S.do_normalize_std;

if S.data.binary == 0
    if do_normalize == 1
        % make it zero-mean
        patches_mean = mean(patches, 1);
        patches = bsxfun(@minus, patches, patches_mean);
    end

    if do_normalize_std ==1
        % make it unit-variance
        patches_std = std(patches, [], 1);
        patches = bsxfun(@rdivide, patches, patches_std);
    end
end

anneal_counter = 0;
actual_lrate0 = actual_lrate;

if S.debug.do_display == 1
    figure(S.debug.display_fid);
end

try
    use_gpu = gpuDeviceCount;
catch errgpu
    use_gpu = false;
    disp(['Could not use CUDA. Error: ' errgpu.identifier])
end

for step=1:n_epochs
    if S.verbose
        fprintf(2, 'Epoch %d/%d: ', step, n_epochs)
    end
    if use_gpu
        % push
        for l = 1:n_layers
            if l < n_layers
                S.W{l} = gpuArray(single(S.W{l}));
            end
            S.biases{l} = gpuArray(single(S.biases{l}));
        end

        if S.adagrad.use
            for l = 1:n_layers
                if l < n_layers
                    S.adagrad.W{l} = gpuArray(single(S.adagrad.W{l}));
                end
                S.adagrad.biases{l} = gpuArray(single(S.adagrad.biases{l}));
            end
        elseif S.adadelta.use
            for l = 1:n_layers
                if l < n_layers
                    S.adadelta.gW{l} = gpuArray(single(S.adadelta.gW{l}));
                    S.adadelta.W{l} = gpuArray(single(S.adadelta.W{l}));
                end
                S.adadelta.gbiases{l} = gpuArray(single(S.adadelta.gbiases{l}));
                S.adadelta.biases{l} = gpuArray(single(S.adadelta.biases{l}));
            end
        end
    end

    for mb=1:n_minibatches
        S.iteration.n_updates = S.iteration.n_updates + 1;

        % p_0
        v0 = patches((mb-1) * minibatch_sz + 1:min(mb * minibatch_sz, n_samples), :);
        mb_sz = size(v0,1);

        if use_gpu > 0
            v0 = gpuArray(single(v0));
        end

        % add error
        v0_clean = v0;

        if S.data.binary == 0 && S.noise.level > 0
            if use_gpu
                v0 = v0 + S.noise.level * gpuArray(randn(size(v0)));
            else
                v0 = v0 + S.noise.level * randn(size(v0));
            end
        end

        if S.noise.drop > 0
            mask = binornd(1, 1 - S.noise.drop, size(v0));
            v0 = v0 .* mask;
            clear mask;
        end

        h0e = cell(n_layers, 1);
        h0e{1} = v0;

        for l = 2:n_layers
            h0e{l} = bsxfun(@plus, h0e{l-1} * S.W{l-1}, S.biases{l}');

            if l < n_layers || S.bottleneck.binary
                h0e{l} = sigmoid(h0e{l}, S.hidden.use_tanh);
            end
        end

        h0d = cell(n_layers, 1);
        h0d{end} = h0e{end};

        for l = n_layers-1:-1:1
            h0d{l} = bsxfun(@plus, h0d{l+1} * S.W{l}', S.biases{l}');
            if l == 1 && S.data.binary
                h0d{l} = sigmoid(h0d{l});
            end
            if l > 1
                h0d{l} = sigmoid(h0d{l}, S.hidden.use_tanh);
            end
        end

        % compute reconstruction error
        hr = sdae_get_hidden(v0_clean, S);
        vr = sdae_get_visible(hr, S);

        if S.data.binary
            rerr = -mean(sum(v0_clean .* log(max(vr, 1e-16)) + (1 - v0_clean) .* log(max(1 - vr, 1e-16)), 2));
        else
            rerr = mean(sum((v0_clean - vr).^2,2));
        end
        if use_gpu > 0
            rerr = gather(rerr);
        end
        S.signals.recon_errors = [S.signals.recon_errors rerr];

        % reset gradients
        for l = 1:n_layers
            biases_grad{l} = 0 * biases_grad{l};
            if l < n_layers
                W_grad{l} = 0 * W_grad{l};
            end
        end

        % backprop
        deltad = cell(n_layers, 1);
        deltad{1} = h0d{1} - v0_clean;
        biases_grad{1} = mean(deltad{1}, 1);

        for l = 2:n_layers
            deltad{l} = deltad{l-1} * S.W{l-1};
            if l < n_layers || S.bottleneck.binary
                deltad{l} = deltad{l} .* dsigmoid(h0d{l}, S.hidden.use_tanh);
            end
            biases_grad{l} = mean(deltad{l}, 1);
            W_grad{l-1} = (deltad{l-1}' * h0d{l}) / (size(v0, 1));
        end

        deltae = cell(n_layers, 1);
        deltae{end} = deltad{end};

        for l = n_layers-1:-1:1
            deltae{l} = deltae{l+1} * S.W{l}';
            if l == 1 && S.data.binary
                deltae{l} = deltae{l} .* dsigmoid(h0e{l});
            end
            if l > 1
                deltae{l} = deltae{l} .* dsigmoid(h0e{l}, S.hidden.use_tanh);
                biases_grad{l} = biases_grad{l} + mean(deltae{l}, 1);
            end
            W_grad{l} = W_grad{l} + (h0e{l}' * deltae{l+1}) / (size(v0, 1));
        end

        % learning rate
        if S.adagrad.use
            % update
            for l = 1:n_layers
                biases_grad_old{l} = (1 - momentum) * biases_grad{l} + momentum * biases_grad_old{l};
                if l < n_layers
                    W_grad_old{l} = (1 - momentum) * W_grad{l} + momentum * W_grad_old{l};
                end
            end

            for l = 1:n_layers
                if l < n_layers
                    S.adagrad.W{l} = S.adagrad.W{l} + W_grad_old{l}.^2;
                end

                S.adagrad.biases{l} = S.adagrad.biases{l} + biases_grad_old{l}.^2';
            end

            for l = 1:n_layers
                S.biases{l} = S.biases{l} - S.learning.lrate * (biases_grad_old{l}' + ...
                    weight_decay * S.biases{l}) ./ sqrt(S.adagrad.biases{l} + S.adagrad.epsilon);
                if l < n_layers
                    S.W{l} = S.W{l} - S.learning.lrate * (W_grad_old{l} + ...
                        weight_decay * S.W{l}) ./ sqrt(S.adagrad.W{l} + S.adagrad.epsilon);
                end
            end

        elseif S.adadelta.use
            % update
            for l = 1:n_layers
                biases_grad_old{l} = (1 - momentum) * biases_grad{l} + momentum * biases_grad_old{l};
                if l < n_layers
                    W_grad_old{l} = (1 - momentum) * W_grad{l} + momentum * W_grad_old{l};
                end
            end

            if S.iteration.n_updates == 1
                adamom = 0;
            else
                adamom = S.adadelta.momentum;
            end

            for l = 1:n_layers
                if l < n_layers
                    S.adadelta.gW{l} = adamom * S.adadelta.gW{l} + (1 - adamom) * W_grad_old{l}.^2;
                end

                S.adadelta.gbiases{l} = adamom * S.adadelta.gbiases{l} + (1 - adamom) * biases_grad_old{l}.^2';
            end

            for l = 1:n_layers
                dbias = -(biases_grad_old{l}' + ...
                    weight_decay * S.biases{l}) .* (sqrt(S.adadelta.biases{l} + S.adadelta.epsilon) ./ ...
                    sqrt(S.adadelta.gbiases{l} + S.adadelta.epsilon));
                S.biases{l} = S.biases{l} + dbias;

                S.adadelta.biases{l} = adamom * S.adadelta.biases{l} + (1 - adamom) * dbias.^2;
                clear dbias;

                if l < n_layers
                    dW = -(W_grad_old{l} + ...
                        weight_decay * S.W{l}) .* (sqrt(S.adadelta.W{l} + S.adadelta.epsilon) ./ ...
                        sqrt(S.adadelta.gW{l} + S.adadelta.epsilon));
                    S.W{l} = S.W{l} + dW;

                    S.adadelta.W{l} = adamom * S.adadelta.W{l} + (1 - adamom) * dW.^2;

                    clear dW;
                end

            end
        else
            if S.learning.lrate_anneal > 0 && (step >= S.learning.lrate_anneal * n_epochs)
                anneal_counter = anneal_counter + 1;
                actual_lrate = actual_lrate0 / anneal_counter;
            else
                if S.learning.lrate0 > 0
                    actual_lrate = S.learning.lrate / (1 + S.iteration.n_updates / S.learning.lrate0);
                else
                    actual_lrate = S.learning.lrate;
                end
                actual_lrate0 = actual_lrate;
            end

            S.signals.lrates = [S.signals.lrates actual_lrate];

            % update
            for l = 1:n_layers
                biases_grad_old{l} = (1 - momentum) * biases_grad{l} + momentum * biases_grad_old{l};
                if l < n_layers
                    W_grad_old{l} = (1 - momentum) * W_grad{l} + momentum * W_grad_old{l};
                end
            end

            for l = 1:n_layers
                S.biases{l} = S.biases{l} - actual_lrate * (biases_grad_old{l}' + weight_decay * S.biases{l});
                if l < n_layers
                    S.W{l} = S.W{l} - actual_lrate * (W_grad_old{l} + weight_decay * S.W{l});
                end
            end
        end

        if S.verbose == 1
            fprintf(2, '.');
        end

        if use_gpu > 0
            clear v0 h0d h0e v0_clean vr hr deltae deltad
        end

        if early_stop
            n_valid = size(valid_patches, 1);
            rndidx = randperm(n_valid);
            if use_gpu > 0
                v0valid = gpuArray(single(valid_patches(rndidx(1:round(n_valid * valid_portion)),:)));
            else
                v0valid = single(valid_patches(rndidx(1:round(n_valid * valid_portion)),:));
            end

            hr = sdae_get_hidden(v0valid, S);
            vr = sdae_get_visible(hr, S);

            if S.data.binary
                rerr = -mean(sum(v0valid .* log(max(vr, 1e-16)) + (1 - v0valid) .* log(max(1 - vr, 1e-16)), 2));
            else
                rerr = mean(sum((v0valid - vr).^2,2));
            end
            if use_gpu > 0
                rerr = gather(rerr);
            end

            S.signals.valid_errors = [S.signals.valid_errors rerr];

            if valid_err == -Inf
                valid_err = rerr;
                valid_best_err = rerr;
            else
                prev_err = valid_err;
                valid_err = 0.99 * valid_err + 0.01 * rerr;

                if step > S.valid_min_epochs && (1.1 * valid_best_err) < valid_err
                    fprintf(2, 'Early-stop! %f, %f\n', valid_err, prev_err);
                    stopping = 1;
                    break;
                end

                if valid_err < valid_best_err
                    valid_best_err = valid_err;
                end
            end
        else
            if S.stop.criterion > 0
                if S.stop.criterion == 1
                    if min_recon_error > S.signals.recon_errors(end)
                        min_recon_error = S.signals.recon_errors(end);
                        min_recon_error_update_idx = S.iteration.n_updates;
                    else
                        if S.iteration.n_updates > min_recon_error_update_idx + S.stop.recon_error.tolerate_count
                            fprintf(2, '\nStopping criterion reached (recon error) %f > %f\n', ...
                                S.signals.recon_errors(end), min_recon_error);
                            stopping = 1;
                            break;
                        end
                    end
                else
                    error ('Unknown stopping criterion %d', S.stop.criterion);
                end
            end
        end

        if length(S.hook.per_update) > 1
            err = S.hook.per_update{1}(S, S.hook.per_update{2});

            if err == -1
                stopping = 1;
                break;
            end
        end

        if S.debug.do_display == 1 && mod(S.iteration.n_updates, S.debug.display_interval) == 0
            S.debug.display_function (S.debug.display_fid, S, v0, v1, h0, h1, W_grad, vbias_grad, hbias_grad);
            drawnow;
        end
    end

    if use_gpu > 0
        % pull
        for l = 1:n_layers
            if l < n_layers
                S.W{l} = gather(S.W{l});
            end
            S.biases{l} = gather(S.biases{l});
        end

        if S.adagrad.use
            for l = 1:n_layers
                if l < n_layers
                    S.adagrad.W{l} = gather(S.adagrad.W{l});
                end
                S.adagrad.biases{l} = gather(S.adagrad.biases{l});
            end
        elseif S.adadelta.use
            for l = 1:n_layers
                if l < n_layers
                    S.adadelta.W{l} = gather(S.adadelta.W{l});
                    S.adadelta.gW{l} = gather(S.adadelta.gW{l});
                end
                S.adadelta.biases{l} = gather(S.adadelta.biases{l});
                S.adadelta.gbiases{l} = gather(S.adadelta.gbiases{l});
            end
        end
    end

    if length(S.hook.per_epoch) > 1
        err = S.hook.per_epoch{1}(S, S.hook.per_epoch{2});

        if err == -1
            stopping = 1;
        end
    end

    if stopping == 1
        break;
    end

    if S.verbose == 1
        fprintf(2, '\n');
    end

    fprintf(2, 'Epoch %d/%d - recon_error: %f\n', step, n_epochs, ...
        S.signals.recon_errors(end));
end

if use_gpu > 0
    % pull
    for l = 1:n_layers
        if l < n_layers
            S.W{l} = gather(S.W{l});
        end
        S.biases{l} = gather(S.biases{l});
    end

    if S.adagrad.use
        for l = 1:n_layers
            if l < n_layers
                S.adagrad.W{l} = gather(S.adagrad.W{l});
            end
            S.adagrad.biases{l} = gather(S.adagrad.biases{l});
        end
    elseif S.adadelta.use
        for l = 1:n_layers
            if l < n_layers
                S.adadelta.W{l} = gather(S.adadelta.W{l});
                S.adadelta.gW{l} = gather(S.adadelta.gW{l});
            end
            S.adadelta.biases{l} = gather(S.adadelta.biases{l});
            S.adadelta.gbiases{l} = gather(S.adadelta.gbiases{l});
        end
    end
end


function colors2 = cluster_orthviews_classes(cl,classes,overlay,myview,domontage, varargin)
% :Usage:
% ::
%
%    colors2 = cluster_orthviews_classes(cl,classes,overlay,myview,domontage, [orthview axis], [colors cell])
%
% Makes montage and cluster orthviews of classes of clusters in different
% colors (hard coded colors right now).
%
% :Inputs:
%
%   **cl:**
%        clusters structure with regions
%
%   **classes:**
%        integers with classes (i.e., networks) to be color-coded on plot
%
%   **overlay:**
%        anatomical underlay image
%
%   **myview:**
%        if entered, shows centers on plot
%
%   **domontage:**
%        if non-zero, make montages of networks
%
%   **[orthview axis]:**
%        Optional; integer for which orthviews axis to use, 1:kk
%
% :Output:
%
%   Cell of colors, in order, for use in other functions
%
% :Examples:
% ::
%
%    classes = c.ClusterSolution.classes;
%    overlay = EXPT.overlay;
%    cluster_orthviews_classes(cl,c.ClusterSolution.classes, EXPT.overlay, 'saggital', 0);
%    cluster_orthviews_classes(cl,c.ClusterSolution.classes, EXPT.overlay, 'axial', 0);
%    cluster_orthviews_classes(cl,c.ClusterSolution.classes, EXPT.overlay, 'coronal', 0);
%    cluster_orthviews_classes(cl,c.ClusterSolution.classes, EXPT.overlay, [], 0);
%
% ..
%    tor wager
%    Colors update, minor improvements, Jan 2010
% ..

whichorth = 1;
if ~isempty(varargin), whichorth = varargin{1}; end

if length(varargin) > 1
    colors2 = varargin{2};
    disp('Using input colors: '); %colors2{:}
else
    % text colors no longer needed -- can handle string colors
    %colors = {'yo' 'bo' 'go' 'ro' 'co' 'mo' 'ko' 'r^' 'g^' 'b^' 'y^' 'c^' 'm^' 'k^'};
    disp('Using default colors. ');
    colors2 = {[1 1 0] [0 0 1] [0 1 0] [1 0 0] [1 .5 0] [0 1 1] [1 0 1] [.5 1 0] [0 .5 1] [0 1 .5] [1 0 .5]};
end

while length(colors2) < max(classes)
    colors2tmp = colors2;
    for jj = 1:length(colors2tmp)
        colors2tmp{jj}(colors2tmp{jj} > .8) = colors2tmp{jj}(colors2tmp{jj} > .8) - .2;
        colors2tmp{jj}(colors2tmp{jj} < .2) = colors2tmp{jj}(colors2tmp{jj} < .2) + .2;
    end
    colors2 = [colors2 colors2tmp];
end
colors2 = colors2(1:max(classes));

% orthviews
cluster_orthviews(cl(classes==1),colors2(1),'overlay',overlay,'solid');

for i = 2:max(classes)
    cluster_orthviews(cl(classes==i),colors2(i),'add','solid', 'handle', whichorth);
end

if ~isempty(myview) && ischar(myview)
    cluster_orthviews_showcenters(cl,myview,overlay,0);
end

if domontage

% montage: build function call
str = ['montage_clusters(overlay,'];
for i = 1:max(classes)
    clc{i} = cl(classes==i);
    str = [str 'clc{' num2str(i) '},'];
end
str = [str '{'];
for i = 1:max(classes)
    %str = [str '''' colors2{i} ''''];  % no longer need solid colors
    str = [str '[' num2str(colors2{i}) '] '];
    %if i ~= max(classes), str = [str ' ']; end
end
str = [str '}, ''nooverlap'');'];
eval(str)
end

return


function [ sicd_meta_current ] = sicd_update_meta_0_5( sicd_meta_0_5 )
%SICD_UPDATE_META_0_5 Update a SICD metadata structure from version 0.5 to
%current version (whatever that may be)
%
% Author: Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

sicd_meta_1_0 = sicd_meta_0_5;

% Add RadarCollection.TxPolarization, now required, but optional prior to version 1.0
if isfield(sicd_meta_0_5, 'RadarCollection') && ...
        ~isfield(sicd_meta_0_5.RadarCollection, 'TxPolarization') && ...
        isfield(sicd_meta_0_5.RadarCollection, 'RcvChannels') && ...
        isfield(sicd_meta_0_5.RadarCollection.RcvChannels, 'ChanParameters')
    if numel(sicd_meta_0_5.RadarCollection.RcvChannels.ChanParameters)==1
        sicd_meta_1_0.RadarCollection.TxPolarization = sicd_meta_0_5.RadarCollection.RcvChannels.ChanParameters.TxRcvPolarization(1);
    else
        sicd_meta_1_0.RadarCollection.TxPolarization = 'SEQUENCE';
        tx_pols = {sicd_meta_0_5.RadarCollection.RcvChannels.ChanParameters.TxRcvPolarization};
        tx_pols = unique(cellfun(@(x) x(1), tx_pols));
        for i = 1:numel(tx_pols)
            sicd_meta_1_0.RadarCollection.TxSequence.TxStep(i).TxPolarization = tx_pols(i);
        end
        % Note: If there are multiple waveforms and multiple polarizations,
        % there is no deconfliction done here.
    end
end

% RadarCollection.Area.Corner was optional in version 0.5, but required in
% version 1.0.  Fortunately, Corner is easily derived from Plane.
if isfield(sicd_meta_0_5, 'RadarCollection') && ...
        isfield(sicd_meta_0_5.RadarCollection, 'Area') && ...
        ~isfield(sicd_meta_0_5.RadarCollection.Area, 'Corner') && ...
        isfield(sicd_meta_0_5.RadarCollection.Area, 'Plane')
    try % If Plane substructure is misformed, this may fail
        plane = sicd_meta_0_5.RadarCollection.Area.Plane; % For concise notation
        ref_pt = [plane.RefPt.ECF.X plane.RefPt.ECF.Y plane.RefPt.ECF.Z];
        x_uvect = [plane.XDir.UVectECF.X plane.XDir.UVectECF.Y plane.XDir.UVectECF.Z];
        y_uvect = [plane.YDir.UVectECF.X plane.YDir.UVectECF.Y plane.YDir.UVectECF.Z];
        x_offsets = [plane.XDir.FirstLine plane.XDir.FirstLine ...
            plane.XDir.NumLines plane.XDir.NumLines];
        y_offsets = [plane.YDir.FirstSample plane.YDir.NumSamples ...
            plane.YDir.NumSamples plane.YDir.FirstSample];
        for i = 1:4
            acp = ref_pt + x_uvect * plane.XDir.LineSpacing * double(x_offsets(i) - plane.RefPt.Line) + ...
                y_uvect * plane.YDir.SampleSpacing * double(y_offsets(i) - plane.RefPt.Sample);
            sicd_meta_1_0.RadarCollection.Area.Corner.ACP(i) = ...
                cell2struct(num2cell(ecf_to_geodetic(acp)),{'Lat','Lon','HAE'});
        end
    end
end

% PolarizationHVAnglePoly no longer a valid field in version 1.0.
if isfield(sicd_meta_0_5, 'RadarCollection') && ...
        isfield(sicd_meta_0_5.RadarCollection, 'PolarizationHVAnglePoly')
    sicd_meta_1_0.RadarCollection = rmfield(sicd_meta_1_0.RadarCollection, 'PolarizationHVAnglePoly');
end

% Antenna.Tx/Rcv/TwoWay.HPBW no longer a valid field in version 1.0.
if isfield(sicd_meta_0_5, 'Antenna')
    if isfield(sicd_meta_0_5.Antenna, 'Tx') && ...
            isfield(sicd_meta_0_5.Antenna.Tx, 'HPBW')
        sicd_meta_1_0.Antenna.Tx = rmfield(sicd_meta_0_5.Antenna.Tx, 'HPBW');
    end
    if isfield(sicd_meta_0_5.Antenna, 'Rcv') && ...
            isfield(sicd_meta_0_5.Antenna.Rcv, 'HPBW')
        sicd_meta_1_0.Antenna.Rcv = rmfield(sicd_meta_0_5.Antenna.Rcv, 'HPBW');
    end
    if isfield(sicd_meta_0_5.Antenna, 'TwoWay') && ...
            isfield(sicd_meta_0_5.Antenna.TwoWay, 'HPBW')
        sicd_meta_1_0.Antenna.TwoWay = rmfield(sicd_meta_0_5.Antenna.TwoWay, 'HPBW');
    end
end

% NoiseLevel got its own substructure between SICD 0.5 and SICD 1.0
if isfield(sicd_meta_0_5, 'Radiometric') && ...
        isfield(sicd_meta_0_5.Radiometric, 'NoisePoly')
    sicd_meta_1_0.Radiometric.NoiseLevel.NoisePoly = ...
            sicd_meta_0_5.Radiometric.NoisePoly;
    sicd_meta_1_0.Radiometric = rmfield(sicd_meta_1_0.Radiometric, 'NoisePoly');
    if isfield(sicd_meta_0_5.Radiometric, 'NoiseLevelType')
        sicd_meta_1_0.Radiometric.NoiseLevel.NoiseLevelType = ...
            sicd_meta_0_5.Radiometric.NoiseLevelType;
    else
        % Even if NoiseLevelType wasn't given, we know that relative noise
        % levels should be 1 at SCP.
        if abs(sicd_meta_0_5.Radiometric.NoisePoly(1)-1)<eps
            sicd_meta_1_0.Radiometric.NoiseLevel.NoiseLevelType = 'RELATIVE';
        else
            sicd_meta_1_0.Radiometric.NoiseLevel.NoiseLevelType = 'ABSOLUTE';
        end
    end
end
if isfield(sicd_meta_0_5, 'Radiometric') && ...
        isfield(sicd_meta_0_5.Radiometric, 'NoiseLevelType')
    sicd_meta_1_0.Radiometric = rmfield(sicd_meta_1_0.Radiometric, 'NoiseLevelType');
end

% MatchInfo
if isfield(sicd_meta_0_5, 'MatchInfo')
    sicd_meta_1_0.MatchInfo = struct(); % Clear this out so we can reconstruct it
    if isfield(sicd_meta_0_5.MatchInfo.Collect, 'MatchType') % MatchType was optional field in 0.5
        types = unique({sicd_meta_0_5.MatchInfo.Collect.MatchType});
    else
        types = {''}; % TypeID (equivalent of MatchType) required in 1.0
    end
    sicd_meta_1_0.MatchInfo.NumMatchTypes = numel(types);
    sicd_meta_1_0.MatchInfo.MatchType = struct();
    for i=1:numel(sicd_meta_1_0.MatchInfo.NumMatchTypes)
        if isfield(sicd_meta_0_5.MatchInfo.Collect, 'MatchType')
            ind = find(strcmp({sicd_meta_0_5.MatchInfo.Collect.MatchType},types{i}));
        else
            ind = 1:numel(sicd_meta_0_5.MatchInfo.Collect);
        end
        sicd_meta_1_0.MatchInfo.MatchType(i).TypeID = strtrim(types{i});
        sicd_meta_1_0.MatchInfo.MatchType(i).NumMatchCollections = ...
            numel(ind) - 1; % 0.5 included current instance as one of the collections
        for j = 1:numel(ind)
            if isfield(sicd_meta_0_5.MatchInfo.Collect(ind(j)), 'Parameter')
                if iscell(sicd_meta_0_5.MatchInfo.Collect(ind(j)).Parameter) % Multiple parameters
                    current_index = find(cellfun(@(x) strcmpi(strtrim(x.name),'CURRENT_INSTANCE'), ...
                        sicd_meta_0_5.MatchInfo.Collect(ind(j)).Parameter),1);
                    if ~isempty(current_index)
                        current_index = str2double(sicd_meta_0_5.MatchInfo.Collect(ind(j)).Parameter{current_index}.value);
                    end
                elseif strcmpi(strtrim(sicd_meta_0_5.MatchInfo.Collect(ind(j)).Parameter.name), 'CURRENT_INSTANCE') % Single parameter
                    current_index = str2double(sicd_meta_0_5.MatchInfo.Collect(ind(j)).Parameter.value);
                else
                    current_index = [];
                end
            end
            if ~isempty(current_index)
                sicd_meta_1_0.MatchInfo.MatchType(i).CurrentIndex = current_index;
            else
                sicd_meta_1_0.MatchInfo.MatchType(i).MatchCollection(j).CoreName = ...
                    sicd_meta_0_5.MatchInfo.Collect(ind(j)).CoreName;
                if isfield(sicd_meta_0_5.MatchInfo.Collect(ind(j)), 'Parameter')
                    sicd_meta_1_0.MatchInfo.MatchType(i).MatchCollection(j).Parameter = ...
                        sicd_meta_0_5.MatchInfo.Collect(ind(j)).Parameter;
                end
            end
        end
    end
end

% Add AzimAng and LayoverAng to SCPCOA
sicd_meta_1_0 = derived_sicd_fields(sicd_meta_1_0);

% We are now updated to version 1.0.  Now do rest of updates.
% sicd_meta_current = sicd_update_meta_1_0(sicd_meta_1_0); % If we needed
% to to more updates past version 1.0, they would go here
sicd_meta_current = sicd_meta_1_0; % No further updates

end

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


function dicomrt_isosurface(inputdose,dose_xmesh,dose_ymesh,dose_zmesh,levels,norm,VOI,voi2plot)
% dicomrt_isosurface(inputdose,dose_xmesh,dose_ymesh,dose_zmesh,levels,norm,VOI,voi2plot)
%
% Show isosurface for 3D dose distributions.
%
% inputdose contains the 3D dose distribution
% inputdose can be an rtplan generated or a monte carlo generated 3D dose distribution or a dose difference.
%
% dose_xmesh,dose_ymesh,dose_zmesh are x-y-z coordinates of the center of the dose-pixel
% levels is a vector containing the values of the % dose difference to be displayed in 3D
% norm is the dose normalization level:
%   1.   norm =0  no normalization is carried out
%   2.       =-1 same as (1) but matrix is treated as dose difference (transparency display)
%   3.       >0  doses are normalized to norm (100%)
% VOI is an OPTIONAL cell array which contain the patients VOIs as read by dicomrt_loadVOI
% voi2plot is an OPTIONAL vector pointing to the number of VOIs to be displayed
%
% Example:
%
% dicomrt_isosurface(A,xmesh,ymesh,zmesh,[100 90],60,A_voi,[1 2 3])
%
% overlay 2 isosurfaces for matrix A at the 100% and 90% levels. Dose is normalised to 60Gy (100%).
% The figure also shows VOIs # 1 2 and 3.
%
% See also dicomrt_loaddose, dicomrt_loadmcdose, dicomrt_contourslice, dicomrt_dosediff
%
% Copyright (C) 2002 Emiliano Spezi (emiliano.spezi@physics.org)

% Check number of argument and set-up some parameters and variables
error(nargchk(6,8,nargin))

% Check case and set-up some parameters and variables
[dose_temp,type_dose,doselabel,PatientPosition]=dicomrt_checkinput(inputdose);
dose=dicomrt_varfilter(dose_temp);

% Check normalization
if norm>0
    dose=dose./norm.*100;
end

% Initialize plot parameters:
color = char('r','g','b','c','m','y','k','w');
line = char('-','--',':','-.');
marker = char('+','o','*','x','s','d','^');
width = [0.5,1.0,1.5,2.0,2.5,3.0];
alphal=[0.1:0.1:1.0];

% Set isolevels display
[contourcolor,doseareas,transl]=dicomrt_setisolevels(norm,dose_temp);

% Fetching legend information
legend_matrix=char(num2str(levels'));

% Rendering 3D dose
handle=figure;
set(handle,'Name',['dicomrt_isosurface: ',inputname(1)]);
grid on;
hold

if exist('VOI')~=1 % No VOI is defined
    if length(levels)==1
        [n,p] = histc(levels,doseareas);
        handle = patch(isosurface(dose_xmesh,dose_ymesh,dose_zmesh,dose,levels));
        isonormals(dose_xmesh,dose_ymesh,dose_zmesh,dose,handle);
        set(handle,'FaceColor',contourcolor(p),'EdgeColor','None','FaceAlpha',0.5);
        view(30,30);
        legend(handle,[int2str(levels)]);
        xlabel('X axis (cm)','Fontsize',12)
        ylabel('Y axis (cm)','Fontsize',12)
        zlabel('Z axis (cm)','Fontsize',12)
    elseif length(levels)~=1
        for i=1:length(levels)
            [n,p] = histc(levels(i),doseareas);
            if p==0
                p=1;
            end
            handle = patch(isosurface(dose_xmesh,dose_ymesh,dose_zmesh,dose,levels(i)));
            isonormals(dose_xmesh,dose_ymesh,dose_zmesh,dose,handle);
            set(handle,'FaceColor',contourcolor(p),'EdgeColor','None','FaceAlpha',transl(p));
        end
        legend(legend_matrix);
        view(30,30);
        xlabel('X axis (cm)','Fontsize',12)
        ylabel('Y axis (cm)','Fontsize',12)
        zlabel('Z axis (cm)','Fontsize',12)
    end
    title(['Isosurface plot for: ',inputname(1)],'interpreter','none','FontSize',16);
elseif exist('VOI')==1 & exist('voi2plot')==1 % VOI was defined
    % Set VOI display parameters
    colorselect =7;
    lineselect =1;
    linewidth =1;
    if length(levels)==1
        [n,p] = histc(levels,doseareas);
        if p==0
            p=1;
        end
        handle = patch(isosurface(dose_xmesh,dose_ymesh,dose_zmesh,dose,levels));
        isonormals(dose_xmesh,dose_ymesh,dose_zmesh,dose,handle);
        set(handle,'FaceColor',contourcolor(p),'EdgeColor','None','FaceAlpha',0.5);
        view(30,30);
        legend(handle,[int2str(levels)]);
        xlabel('X axis (cm)','Fontsize',12)
        ylabel('Y axis (cm)','Fontsize',12)
        zlabel('Z axis (cm)','Fontsize',12)
    elseif length(levels)~=1
        for i=1:length(levels)
            [n,p] = histc(levels(i),doseareas);
            if p==0
                p=1;
            end
            handle = patch(isosurface(dose_xmesh,dose_ymesh,dose_zmesh,dose,levels(i)));
            isonormals(dose_xmesh,dose_ymesh,dose_zmesh,dose,handle);
            set(handle,'FaceColor',contourcolor(p),'EdgeColor','None','FaceAlpha',transl(p));
        end
        legend(legend_matrix);
        view(30,30);
        xlabel('X axis (cm)','Fontsize',12)
        ylabel('Y axis (cm)','Fontsize',12)
        zlabel('Z axis (cm)','Fontsize',12)
    end
    title(['Isosurface plot: ',inputname(1)],'interpreter','none','FontSize',16);
    % Plot VOIs
    dicomrt_rendervoi(VOI,voi2plot,1,1,1);
else
    error('dicomrt_isosurface: VOI or voi2plot is missing. Exit now !');
end


function [] = aps_modis(start_step,end_step)
% [] = aps_modis(start_step,end_step)
% Computes the MODIS delays based on the OSCAR service provied by JPL
%
%     Copyright (C) 2015  Bekaert David - University of Leeds
%     Email: eedpsb@leeds.ac.uk or davidbekaert.com
%
%     This program is free software; you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation; either version 2 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License along
%     with this program; if not, write to the Free Software Foundation, Inc.,
%     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%
% By David Bekaert - University of Leeds
% May 2014
%
% Modifications:
% DB	05/2014 	Start from the MERIS scrip the program the function
% DB    07/2014     Have re-visualization of sounding data when already
%                   processed
% DB    08/2014     Include SAR varying conversion factors
% DB    08/2014     Include option to use MODIS recalibrated data
% DB    09/2014     Check if conversion factors are known before
% DB    04/2015     Fix in case filename grd is not starting with OSCAR_Modis*grd
% DB    02/2016     Include aps_systemcall and suppress filename output.

%% loading the StaMPS variables
curdir = pwd;

if start_step==0
   % get the data from the OSCAR webite (JPL)
   aps_modis_Python
end

if start_step==1
     % Compute the MERIS conversion factors from the sounding data
    fprintf('\n\nStep 1: Compute the spectrometer conversion factors from the sounding data \n')

    % getting parameters from parms_aps file
    sounding_dir = getparm_aps('sounding_dir',1);
    start_date = getparm_aps('sounding_start_date',1);
    end_date = getparm_aps('sounding_end_date',1);
    time_stamp = getparm_aps('sounding_time_stamp',1);
    sounding_ifg_dates = getparm_aps('sounding_ifg_dates',1);
    start_year_str = start_date(1:4);
    end_year_str = end_date(1:4);
    start_str = start_date(5:6);
    end_str = end_date(5:6);
    time_stamp_str = [];
    for k=1:size(time_stamp,1)
        if k>1
            time_stamp_str = [time_stamp_str '_' time_stamp(k,:)];
        else
            time_stamp_str = [time_stamp(k,:)];
        end
    end

     % see if the filename already exist
    if strcmp(sounding_ifg_dates,'y')
        savename = [sounding_dir filesep 'Spectrometer' filesep 'Spectrometer_sensitivity_SAR_dates_1month_' time_stamp_str 'Hr_' num2str(start_year_str) start_str '_' num2str(end_year_str) end_str '.mat'];
    else
        savename = [sounding_dir filesep 'Spectrometer' filesep 'Spectrometer_sensitivity_' time_stamp_str 'Hr_' num2str(start_year_str) start_str '_' num2str(end_year_str) end_str '.mat'];
    end

    if exist(savename,'file')==2
        % check if user wants to visualize or re-run the data
        str = '';
        while strcmpi(str,'y')~=1 && strcmpi(str,'n')~=1
            str = input(['This file already exist, do you want to re-process the data? [y/n] \n'],'s');
        end

        if strcmpi(str,'y')
            rerun_flag =1;
        else
            sounding_spectrometer_sens_display
            rerun_flag =0;
        end
    else
       rerun_flag =1;
    end

    if rerun_flag ==1;
        sounding_spectrometer_sens;
    end
end

if start_step<=2 && end_step >=2
    % SAR delays using MODIS data
    fprintf('\n\nStep 2: Compute MODIS tropospheric delay for individual dates\n')

    % generating a file list of the files to be processed:
    modis_datapath = getparm_aps('modis_datapath',1);
    command_str = 'echo files > modis_batch_file.txt';
    command_str2 = ['ls -d ' modis_datapath filesep '2*' filesep '*.grd >> modis_batch_file.txt'];

    aps_systemcall(command_str);
    aps_systemcall(command_str2);

    % running the MODIS computation on the file list
    aps_modis_SAR('modis_batch_file.txt')
end
if start_step<=3 && end_step >=3
    fprintf('\n\nStep 3: Computes MODIS tropospheric delay for interferograms\n')
    aps_modis_InSAR
end

cd(curdir)


function [img, scale, im_scaled_size] = prepare_img_blob(img, scale, mean_pix, max_size)
%
% 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
%
% Part of the code in this file comes from the Faster R-CNN code and the matlab
% re-implementation of Fast-RCNN (https://github.com/ShaoqingRen/faster_rcnn)
%
% 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]
% ---------------------------------------------------------

if numel(mean_pix) == 1, mean_pix = [mean_pix, mean_pix, mean_pix]; end
assert(numel(mean_pix)==3);

im_height = size(img, 1);
im_width = size(img, 2);
% get the image size of the scaled image
im_scaled_size = prepare_img_blob_size([im_height, im_width], scale, max_size);
scale = min(im_scaled_size);

% scale image
if (scale <= 224)
    img = imresize(img, [im_scaled_size(1), im_scaled_size(2)], 'bilinear');
else
    img = imresize(img, [im_scaled_size(1), im_scaled_size(2)], 'bilinear', 'antialiasing', false);
end

img = single(img); % transform to single precision
img = img(:,:,[3 2 1]); % transform from RGB -> BGR (necessary for Caffe)
% subtruct the mean pixel from the image
img = bsxfun(@minus, img, reshape(mean_pix, [1, 1, 3]));
img = permute(img, [2 1 3]); % permute from [Height x Width x 3] to [Width x Height x 3] (necessary for Caffe)
end


function loser = updategrid(x, minHoleTime, minHoleSize, maxHoleTime, maxHoleSize)
global F
global alive
global snakeSize
global holeCountDown
global lastPos

res = size(F);
loser = 0;
for i = alive
    pixels = getpixels(x(i,:), snakeSize);
    index1 = size(F,1) * lastPos(:,i*2) + lastPos(:,i*2-1);
    index2 = size(F,1) * pixels(:,2) + pixels(:,1);
    F(index1) = 0;

    if any(pixels(:) < 1) || any(pixels(:,1) >= res(1)) || any(pixels(:,2) >= res(2))
        loser = i;
        alive(alive == i) = [];
        F(index1) = i;
        return
    end
    if sum(full(F(index2))) > 1
        alive(alive == i) = [];
        F(index1) = i;
        return
    end

    F(index2) = i;
    if holeCountDown(i,1) ~= 0
        F(index1) = i;
    else
        F(index1) = 0;
        holeCountDown(i,1) = 1;
        holeCountDown(i,2) = holeCountDown(i,2) - 1;
    end
    if holeCountDown(i,2) == 0
        F(index2) = i;
        holeCountDown(i,1) = round(rand() * (maxHoleTime - minHoleTime)) + minHoleTime;
        holeCountDown(i,2) = round(rand() * (maxHoleSize - minHoleSize)) + minHoleSize;
    end
    lastPos(:,i*2-1:i*2) = pixels;
end


%RNA production medium test
%
% Author: Jared Jacobs, jmjacobs@stanford.edu
% Author: Jonathan Karr, jkarr@stanford.edu
% Affiliation: Covert Lab, Department of Bioengineering, Stanford University
% Last updated: 9/10/2010
classdef RNA_Test < TestCase
    properties
        simulation
    end

    methods
        function this = RNA_Test(name)
            this = this@TestCase(name);
        end

        function setUp(this)
            sim = edu.stanford.covert.cell.sim.SimulationFixture.load([], {
                'Metabolism'
                'Transcription'
                'RNAProcessing'
                'RNAModification'
                'tRNAAminoacylation'
                'RNADecay'
                });

            this.simulation = sim;
        end

        function testRnaProduction(this)
            import edu.stanford.covert.util.ConstantUtil;

            %% references
            sim = this.simulation;
            %this.seedSimulation(sim, 10);
            %sim.applyOptions('verbosity', 1);

            g = sim.gene;
            mass = sim.state('Mass');
            m = sim.state('Metabolite');
            rna = sim.state('Rna');
            time = sim.state('Time');
            pm = sim.state('ProteinMonomer');
            pc = sim.state('ProteinComplex');
            transcription = sim.process('Transcription');

            %% constants
            rnaMWs = rna.molecularWeights(rna.aminoacylatedIndexs);

            %% turn off decay
            rna.decayRates(setdiff(1:end, rna.intergenicIndexs)) = 0;

            %% keep track of initial state
            initRNAs = ...
                + rna.counts(rna.matureIndexs, sim.compartment.cytosolIndexs) ...
                + rna.counts(rna.aminoacylatedIndexs, sim.compartment.cytosolIndexs);
            initRNAs(setdiff(1:end, rna.matureMRNAIndexs)) = ...
                initRNAs(setdiff(1:end, rna.matureMRNAIndexs)) + ...
                sum(pc.proteinComplexComposition(setdiff(1:end, g.mRNAIndexs), :, :), 3) * sum(pc.counts(pc.matureIndexs, :) + pc.counts(pc.boundIndexs, :), 2);

            initMonomers = ...
                + pm.counts(pm.matureIndexs, :) ...
                + pm.counts(pm.boundIndexs, :);
            initComplexs = ...
                + pc.counts(pc.matureIndexs, :) ...
                + pc.counts(pc.boundIndexs, :);

            %% simulate
            iterMax = 1000;

            ntps = zeros(4, iterMax);
            if sim.verbosity > 0
                fprintf('%5s %6s %6s %6s %6s\n', 'Iter ', ' ATP  ', ' CTP  ', ' GTP  ', ' UTP  ');
                fprintf('%5s %6s %6s %6s %6s\n', '=====', '======', '======', '======', '======');
            end
            for i = 1:iterMax
                if sim.verbosity > 0 && mod(i, 100) == 1
                    fprintf('%5d %6d %6d %6d %6d\n', i, ...
                        transcription.substrates(transcription.substrateIndexs_ntp(1)), ...
                        transcription.substrates(transcription.substrateIndexs_ntp(2)), ...
                        transcription.substrates(transcription.substrateIndexs_ntp(3)), ...
                        transcription.substrates(transcription.substrateIndexs_ntp(4)));
                end

                %mock protein synthesis
                pm.counts(pm.matureIndexs, :) = ...
                    + pm.counts(pm.matureIndexs, :) ...
                    + pm.randStream.stochasticRound(initMonomers * log(2) / time.cellCycleLength * exp(i * log(2) / time.cellCycleLength));
                pc.counts(pc.matureIndexs, :) = ...
                    + pc.counts(pc.matureIndexs, :) ....
                    + pc.randStream.stochasticRound(initComplexs * log(2) / time.cellCycleLength * exp(i * log(2) / time.cellCycleLength));

                %simulate
                sim.evolveState();

                ntps(:, i) = transcription.substrates(transcription.substrateIndexs_ntp);
            end

            newRNAs = ...
                - initRNAs ...
                + rna.counts(rna.matureIndexs, sim.compartment.cytosolIndexs) ...
                + rna.counts(rna.aminoacylatedIndexs, sim.compartment.cytosolIndexs);
            newRNAs(setdiff(1:end, rna.matureMRNAIndexs)) = ...
                newRNAs(setdiff(1:end, rna.matureMRNAIndexs)) + ...
                sum(pc.proteinComplexComposition(setdiff(1:end, g.mRNAIndexs), :, :), 3) * sum(initComplexs, 2);

            %% assertions

            %NTPs are limiting
            assertIn(min(min(ntps(:, end-100+1:end))), [0 max(2000, min(ntps(:, 1)))]);

            %NTPs are mostly used -- not too many are free
            assertIn(...
                (m.counts(m.ntpIndexs([2 4]), sim.compartment.cytosolIndexs)' * m.molecularWeights(m.ntpIndexs([2 4]))) / ...
                (rna.counts(:, sim.compartment.cytosolIndexs)' * rna.molecularWeights), ...
                [0 0.03]);

            %mature/aminoacylated RNA counts increased
            assertAllEqual(true, newRNAs >= 0);
            assertElementsAlmostEqual(newRNAs' * rnaMWs / ConstantUtil.nAvogadro, ...
                (exp(iterMax * log(2) / time.cellCycleLength) - 1) * ...
                mass.initialFractionNTPsInRNAs * mass.cellInitialDryWeight * mass.dryWeightFractionRNA, ...
                'relative', 2.5e-1, 0);

            assertIn(sum(sum(rna.counts(rna.nascentIndexs, :))), [0 20]);
            assertIn(sum(sum(rna.counts(rna.processedIndexs, :))), [0 40]);
            assertIn(sum(sum(rna.counts(rna.intergenicIndexs, :))), [0 10]);
            assertAllEqual(0, rna.counts(rna.boundIndexs, :));
            assertAllEqual(0, rna.counts(rna.damagedIndexs, :));
            assertAllEqual(0, rna.counts(rna.misfoldedIndexs, :));

            %RNA production matches expectations
            rates = rna.nascentRNAMatureRNAComposition * transcription.computeRNAPolymeraseTUBindingProbabilities();
            rates = rates(:, 1);
            assertIn(corr(rates, newRNAs), [0.50 1]);
            assertIn(180 / pi * acos(rates' * newRNAs / ...
                (sqrt(rates' * rates) * sqrt(newRNAs' * newRNAs))), ...
                [0 60]);
        end

        function testRnaProductionAndDecay(this)
            import edu.stanford.covert.util.ConstantUtil;

            %% references
            sim = this.simulation;
            %sim.applyOptions('verbosity', 1);
            this.seedSimulation(sim, 1000);

            g = sim.gene;
            comp = sim.compartment;
            mass = sim.state('Mass');
            m = sim.state('Metabolite');
            rna = sim.state('Rna');
            time = sim.state('Time');
            pm = sim.state('ProteinMonomer');
            pc = sim.state('ProteinComplex');
            rnaPol = sim.state('RNAPolymerase');
            transcript = sim.state('Transcript');
            transcription = sim.process('Transcription');

            %% keep track of initial state
            initRNAs = ...
                + rna.counts(rna.matureIndexs, comp.cytosolIndexs) ...
                + rna.counts(rna.aminoacylatedIndexs, comp.cytosolIndexs);
            initRNAs(setdiff(1:end, rna.matureMRNAIndexs)) = ...
                initRNAs(setdiff(1:end, rna.matureMRNAIndexs)) + ...
                sum(pc.proteinComplexComposition(setdiff(1:end, g.mRNAIndexs), :, :), 3) * ...
                sum(pc.counts(pc.matureIndexs, :) + pc.counts(pc.boundIndexs, :), 2);
            initMonomers = ...
                + pm.counts(pm.matureIndexs, :) ...
                + pm.counts(pm.boundIndexs, :);
            initComplexs = ...
                + pc.counts(pc.matureIndexs, :) ...
                + pc.counts(pc.boundIndexs, :);

            %% simulate
            iterMax = 30000;

            rnaExp = zeros(size(initRNAs));
            rnaProd = zeros(size(rna.nascentIndexs));
            oldNascentRNAs = transcription.RNAs;
            rnaPolStateOcc = zeros(4, iterMax);
            ntps = zeros(4, iterMax);
            ndps = zeros(4, iterMax);
            nmps = zeros(4, iterMax);
            phosphates = zeros(3, iterMax);
            boundTUs = zeros(numel(rna.nascentIndexs), iterMax);
            rnaDryWt = zeros(1, iterMax);
            transcriptDryWt = zeros(1, iterMax);
            nucDryWt = zeros(1, iterMax);
            if sim.verbosity > 0
                fprintf('%5s %6s %6s %6s %6s\n', 'Iter ', ' ATP  ', ' CTP  ', ' GTP  ', ' UTP  ');
                fprintf('%5s %6s %6s %6s %6s\n', '=====', '======', '======', '======', '======');
            end
            for i = 1:iterMax
                if sim.verbosity > 0 && mod(i, 100) == 1
                    fprintf('%5d %6d %6d %6d %6d\n', i, ...
                        transcription.substrates(transcription.substrateIndexs_ntp(1)), ...
                        transcription.substrates(transcription.substrateIndexs_ntp(2)), ...
                        transcription.substrates(transcription.substrateIndexs_ntp(3)), ...
                        transcription.substrates(transcription.substrateIndexs_ntp(4)));
                end

                %mock protein synthesis
                pm.counts(pm.matureIndexs, :) = ...
                    + pm.counts(pm.matureIndexs, :) ...
                    + pm.randStream.stochasticRound(initMonomers * log(2) / time.cellCycleLength * exp(i * log(2) / time.cellCycleLength));
                pc.counts(pc.matureIndexs, :) = ...
                    + pc.counts(pc.matureIndexs, :) + ...
                    + pc.randStream.stochasticRound(initComplexs * log(2) / time.cellCycleLength * exp(i * log(2) / time.cellCycleLength));

                %simulate
                sim.evolveState();

                %store data
                rnaExp = rnaExp ...
                    + rna.counts(rna.matureIndexs, comp.cytosolIndexs) ...
                    + rna.counts(rna.aminoacylatedIndexs, comp.cytosolIndexs);
                rnaExp(setdiff(1:end, rna.matureMRNAIndexs)) = ...
                    rnaExp(setdiff(1:end, rna.matureMRNAIndexs)) + ...
                    sum(pc.proteinComplexComposition(setdiff(1:end, g.mRNAIndexs), :, :), 3) * sum(initComplexs, 2);
                rnaProd = rnaProd + max(0, transcription.RNAs - oldNascentRNAs);
                oldNascentRNAs = transcription.RNAs;
                rnaPolStateOcc(:, i) = [
                    rnaPol.nActive
                    rnaPol.nSpecificallyBound
                    rnaPol.nNonSpecificallyBound
                    rnaPol.nFree
                    ];
                ntps(:, i) = transcription.substrates(transcription.substrateIndexs_ntp);
                ndps(:, i) = m.counts(m.ndpIndexs, comp.cytosolIndexs);
                nmps(:, i) = m.counts(m.nmpIndexs, comp.cytosolIndexs);
                phosphates(:, i) = m.counts([m.diphosphateIndexs; m.phosphateIndexs; m.hydrogenIndexs], comp.cytosolIndexs);
                boundTUs(:, i) = histc(transcript.boundTranscriptionUnits(rnaPol.states >= rnaPol.activelyTranscribingValue), (1:numel(rna.nascentIndexs))');

                rnaDryWt(:, i) = rna.dryWeight(1);
                transcriptDryWt(:, i) = transcript.dryWeight;
                nucDryWt(:, i) = (...
                    + ntps(:, i)' * m.molecularWeights(m.ntpIndexs) ...
                    + ndps(:, i)' * m.molecularWeights(m.ndpIndexs) ...
                    + nmps(:, i)' * m.molecularWeights(m.nmpIndexs)) / ConstantUtil.nAvogadro;
            end

            %% assertions

            %NTPs are limiting
            assertIn(min(min(ntps(:, end-100+1:end))), [0 exp(log(2) * iterMax / time.cellCycleLength) * min(ntps(:, 1))]);
            assertIn(min(min(ndps(:, end-100+1:end))), [0 exp(log(2) * iterMax / time.cellCycleLength) * min(ndps(:, 1))]);
            assertIn(min(min(nmps(:, end-100+1:end))), [0 exp(log(2) * iterMax / time.cellCycleLength) * min(nmps(:, 1))]);
            assertIn(min(transcriptDryWt(:, end-100+1:end)), [0 2.5 * exp(log(2) * iterMax / time.cellCycleLength) * transcriptDryWt(1)]);

            %NTPs are mostly used -- not too many are free
            assertIn(...
                (m.counts(m.ntpIndexs([2 4]), comp.cytosolIndexs)' * m.molecularWeights(m.ntpIndexs([2 4]))) / ...
                ((rna.dryWeight(1) + transcript.dryWeight) * edu.stanford.covert.util.ConstantUtil.nAvogadro), ...
                [0 0.05]);

            rnas = ...
                + rna.counts(rna.matureIndexs, comp.cytosolIndexs) ...
                + rna.counts(rna.aminoacylatedIndexs, comp.cytosolIndexs);
            rnas(setdiff(1:end, rna.matureMRNAIndexs)) = ...
                rnas(setdiff(1:end, rna.matureMRNAIndexs)) + ...
                sum(pc.proteinComplexComposition(setdiff(1:end, g.mRNAIndexs), :, :), 3) * sum(initComplexs, 2);
            assertElementsAlmostEqual(rnas' * rna.molecularWeights(rna.aminoacylatedIndexs) / edu.stanford.covert.util.ConstantUtil.nAvogadro, ...
                exp(iterMax * log(2) / time.cellCycleLength) * mass.cellInitialDryWeight * mass.dryWeightFractionRNA, ...
                'relative', 2e-1, 0);

            %total NTP incorporation similar to production by metabolism
            assertElementsAlmostEqual(...
                (edu.stanford.covert.util.ComputationUtil.invertCompositionMatrix(rna.nascentRNAMatureRNAComposition) * ...
                (mass.cellInitialDryWeight * mass.dryWeightFractionRNA * edu.stanford.covert.util.ConstantUtil.nAvogadro / ...
                (rna.expression(rna.matureIndexs)' * rna.molecularWeights(rna.matureIndexs)) * rna.expression(rna.matureIndexs) .* ...
                (log(2) / time.cellCycleLength + rna.decayRates(rna.matureIndexs))))' * rna.lengths(rna.nascentIndexs) * ...
                time.cellCycleLength / log(2) * (exp(log(2) / time.cellCycleLength * iterMax)-1), ...
                rnaProd' * rna.lengths(rna.nascentIndexs), ...
                'relative', 0.40);

            %RNA expression matches expectations
            assertIn(corr(rna.expression(rna.matureIndexs), rnaExp), [0.9 1]);
            assertIn(180 / pi * acos(rna.expression(rna.matureIndexs)' * rnaExp / ...
                (sqrt(rna.expression(rna.matureIndexs)' * rna.expression(rna.matureIndexs)) * sqrt(rnaExp' * rnaExp))), ...
                [0 20]);

            %RNA polymerase occupancy matches expectations
            assertElementsAlmostEqual(rnaPol.stateExpectations, ...
                sum(rnaPolStateOcc, 2) / sum(rnaPolStateOcc(:)), ...
                'relative', 0.75, 0.20); %todo: tighten

            %RNAs matured
            assertIn(sum(sum(rna.counts(rna.nascentIndexs, :))), [0 20]);
            assertIn(sum(sum(rna.counts(rna.processedIndexs, :))), [0 30]);
            assertIn(sum(sum(rna.counts(rna.intergenicIndexs, :))), [0 10]);
            assertAllEqual(0, rna.counts(rna.boundIndexs, :));
            assertAllEqual(0, rna.counts(rna.damagedIndexs, :));
            assertAllEqual(0, rna.counts(rna.misfoldedIndexs, :));
        end

        function sim = seedSimulation(~, sim, seed)
            if sim.verbosity > 0
                fprintf('Seed: %d\n', seed)
            end

            sim.applyOptions('seed', seed);
            sim.seedRandStream();

            for i = 1:numel(sim.states)
                o = sim.states{i};
                o.seed = seed;
                o.seedRandStream();
            end

            for i = 1:numel(sim.processes)
                o = sim.processes{i};
                o.seed = seed;
                o.seedRandStream();
            end
        end
    end
end


% fig2: anat averages from paired regressors: sensory/motor correlations
% plots a pair of regressors in a graded double colormap, saves as tiff
% stacks, and also saves anat average plot as tiff file.
% (compare to fig2A_correlation_1reg_with_hist for more details)

clear all; close all; clc

outputDir = GetOutputDataDir;

%% Init load
hfig = figure;
InitializeAppData(hfig);
ResetDisplayParams(hfig);

%% set params
thres_reg_const = 0.5;
% M_reg_thres = {0.5,0.5,0.5};

for setflag = 7
    % reset
    ResetDisplayParams(hfig);

    switch setflag
        case 1 % Phototaxis
%             stimrange = 1;
M_stimrange = GetStimRange('P');
            M_regtypeflag = [1,1,2]; % 0 for VAR, 1 for stim and 2 for motor
            M_reg_name = {'PT','HalfField','PT_SwimLR'};
            M_reg_range = {[3,2],[5,6],[1,3]};
            M_fishrange = {[1:18],[1:7],[1:3,5:18]};
            n_reg = length(M_reg_name);

        case 2 % OMR
%             stimrange = 2;
M_stimrange = GetStimRange('O');
            M_regtypeflag = [1,1,2]; % 1 for stim and 0 for motor
            M_reg_name = {'OMR_FwBw','OMR_LR','OMR_SwimLR'};
            M_reg_range =  {[7,6],[9,8],[1,3]};
            M_fishrange = {[8:18],[8:18],[8:18]};
            n_reg = length(M_reg_name);

        case 3 % Looming
%             stimrange = 5;
M_stimrange = GetStimRange('L');
            M_regtypeflag = [1,2]; % 1 for stim and 0 for motor
            M_reg_name = {'Loom_LR','Loom_SwimLR'};
            M_reg_range =  {[11,12],[1,3]};
            M_fishrange = {[9:15,17:18],[9:15,17:18]};
            n_reg = length(M_reg_name);

        case 4 % Dark Flash (black-white)
%             stimrange = 3;
M_stimrange = GetStimRange('D');
            M_regtypeflag = [1,2]; % 1 for stim and 0 for motor
            M_reg_name = {'DF_BW','DF_SwimLR'};
            M_reg_range =  {[1,4],[1,3]};
            M_fishrange = {[12:15,17:18],[12:15,17:18]};
            n_reg = length(M_reg_name);

%             % from VAR:

        case 5 % ABN
            M_regtypeflag = [0];
            M_stimrange = GetStimRange();%('2');
            M_reg_name = {'ABN_reg0.5_defstimrange_test'};
            M_clus_range = {[12,1]};
            M_fishrange = {[1:12,14:18]};
            n_reg = length(M_reg_name);
        case 6 % Fw
            M_regtypeflag = [0];
            M_stimrange = GetStimRange();%('2');
            M_reg_name = {'Fw_reg0.5_defS'};
            M_clus_range = {[11,4]};
            M_fishrange = {[1:18]};
            n_reg = length(M_reg_name);

        case 7 % left HBO
            M_regtypeflag = [0,0];
            M_stimrange = GetStimRange();%('2');
            M_reg_name = {'HBO-L2_reg0.5_defS','HBO-R2_reg0.5_defS'};
            M_clus_range = {[10,2],[10,3]};
            M_fishrange = {[1:3,5:18],[1:3,5:18]};
            n_reg = length(M_reg_name);
    end
    M_fishrange_im = M_fishrange;

    %% Load fish
    range = 1:18;
    IM_full = cell(n_reg,max(range));
    %%

%     [M_fishrange_im,fishrange_load] = CheckIfLoadFish(M_fishrange,M_ClusterIDs,M_stimrange);
% [cIX_load,gIX_load,M,stim,behavior,M_0] = LoadSingleFishDefault(i_fish,hfig,M_ClusterIDs{i_set},M_stimrange{i_set});
    for i_fish = range
        if ismember(i_fish,cell2mat(M_fishrange))
            ClusterIDs = [1,1];%GetClusterIDs('all');
            stimrange = M_stimrange{i_fish};
            % load fish data
            if isempty(stimrange)
                [cIX_load,gIX_load,M,stim,behavior,M_0] = LoadSingleFishDefault(i_fish,hfig,ClusterIDs);
            else
                [cIX_load,gIX_load,M,stim,behavior,M_0] = LoadSingleFishDefault(i_fish,hfig,ClusterIDs,stimrange);
            end
        end

        %% Load stim/motor
        for i_set = 1:n_reg

            if ~ismember(i_fish,M_fishrange{i_set})
                continue;
            end

            reg_thres = thres_reg_const; %M_reg_thres{i_set};

            % get stim/motor regressors
            if M_regtypeflag(i_set)==0
                ClusterIDs = M_clus_range{i_set};%[12,1];% GetClusterIDs('all');
                [cIX,gIX] = LoadCluster_Direct(i_fish,ClusterIDs(1),ClusterIDs(2));
                M = UpdateIndices_Manual(hfig,cIX,gIX);
                Reg = FindClustermeans(gIX,M);

            elseif M_regtypeflag(i_set)==1
                fishset = getappdata(hfig,'fishset');
                [~,names,regressors] = GetStimRegressor(stim,fishset,i_fish);

                reg_range = M_reg_range{i_set}; % left/right pair
                Reg = regressors(reg_range,:);

            elseif M_regtypeflag(i_set)==2
                isMotorseed = 0;
                setappdata(hfig,'isMotorseed',isMotorseed);
                [~,~,behavior] = UpdateTimeIndex(hfig);
                [~,names,regressors] = GetMotorRegressor(behavior,i_fish);

                reg_range = M_reg_range{i_set}; % left/right pair
                Reg = regressors(reg_range,:);
            end

            % code adapted from 'best regressor regression' code 'AllRegsRegression'

            Corr = corr(Reg',M_0');
            [corr_max,IX_regtype] = max(Corr,[],1);
            cIX = find(corr_max>reg_thres)';
            gIX_offset = IX_regtype(cIX)';
            clrIX = MapXto1Dcolormap(corr_max(cIX),[reg_thres,1],64);

            if isempty(cIX)
                M_fishrange_im{i_set} = setdiff(M_fishrange_im{i_set} ,i_fish);
                continue;
            end

            gIX = clrIX+(gIX_offset-1)*64;
            numK = length(unique(gIX));

            %% make double colormap - ??
            clr1 = [1,0,0];
            clr1_ = [0.7,0.5,0.5];
            clr2 = [0,1,1];
            clr2_ = [0.5,0.7,0.7];
            numC = 64;
            clrmap1 = Make1DColormap([clr1_;clr1],numC);
            clrmap2 = Make1DColormap([clr2_;clr2],numC);
            clrmap = [clrmap1;clrmap2];

            %% make figure
            I = LoadCurrentFishForAnatPlot(hfig,cIX,gIX,clrmap);
            [h,im_full] = DrawCellsOnAnat(I);

            %         % add 2 colorbars
            % %         AddColorbarToAnat(clrmap,cmin,cmax)
            % %         colormap(clrmap1);
            % %         caxis([reg_thres,1])
            % %         colorbar('Location','manual','Position',[0.8,0.7,0.05,0.15],'Units','normalized')
            %         ax = axes('Position',[0.75,0.8,0.05,0.15],'Units','normalized');
            %         DrawCustomColorbar(clrmap1,[reg_thres,1],2,ax);
            %
            %         ax = axes('Position',[0.9,0.8,0.05,0.15],'Units','normalized');
            %         DrawCustomColorbar(clrmap2,[reg_thres,1],2,ax);
            %
            %% save figure
            close(h);
            IM_full{i_set,i_fish} = im_full;

        end
    end

    %% save as tiff stack
    for i_set = 1:n_reg
        range_im = M_fishrange_im{i_set};
        tiffdir = fullfile(outputDir,[M_reg_name{i_set},'_allfish.tiff']);
        IM = IM_full(i_set,range_im);

        SaveImToTiffStack(IM,tiffdir);
    end

    %% [for later] plot from tiff stack
    isPlotfromtiffstack = 0;

    if isPlotfromtiffstack
        IM_full = cell(n_reg,18);
        for i_set = 1:n_reg
            %% get tiff-stack path
            tiffdir = fullfile(outputDir,[M_reg_name{i_set},'_allfish.tiff']);

            %% load

            for i_fish = 1:18
                im = double(imread(tiffdir,i_fish))./255;
                IM_full{i_set,i_fish} = im(317:1236,1:621,:);
            end
        end
    end

    %% make average plots
    % M_k_scale = {1,1.5,1};
    % M_k_contrast = {1.2,1.5,1.2};

    for i_set = 1:n_reg;
        range_im = M_fishrange_im{i_set};%[1:3,5:7];%[1:3,5:18];
        cellarray = IM_full(i_set,range_im);

        % adjust params for visualization
        k_scale = 0.4;%1/1.5;%M_k_scale{i_set};
        k_contrast = 1;%M_k_contrast{i_set};

        [h_anat,im_avr] = AverageAnatPlot(cellarray,k_contrast,k_scale);

        tiffdir = fullfile(outputDir,[M_reg_name{i_set},'_avr.tiff']);
        imwrite(im_avr, tiffdir, 'compression','none','writemode','overwrite');
    end

end


function show_map(calc_type, in2, compare_window_dur)
    % ZMAP script show_map.m. Creates Dialog boxes for Z-map calculation
    % does the calculation and makes displays the map
    % stefan wiemer 11/94
    %
    % make dialog interface and call maxzlta
    %
    % turned into function by Celso G Reyes 2017

    %FIXME (maybe) changing compare_window_dur doesn't change the global version.

    % Input Rubberband
    %
    report_this_filefun();

    % compare_window_dur is shared among the parts of this function
    it=[]

    if in2 ~= 'calma'
        create_the_figure(calc_type)
    else
        do_calma(calc_type)
    end

    function create_the_figure(calc_type)
        %initial values
        ZG=ZmapGlobal.Data; % used by get_zmap_globals
        ZG.compare_window_dur_v3 = years(1.5);
        it = t0b +1;
        figure(mess);
        clf
        set(gca,'visible','off')
        set(gcf,'Units','pixel','NumberTitle','off','Name','Input Parameters');

        set(gcf,'pos',[ ZG.welcome_pos, ZG.welcome_len +[200, -50]]);

        % creates a dialog box to input some parameters
        %
        add_timecut_controls(it)

        if calc_type == "rub" || calc_type == "lta"
            add_compareduration_controls(compare_window_dur)
        end

        uicontrol('Style','Pushbutton',...
            'Position', [.60 .05 .15 .15 ],...
            'Units','normalized',...
            'Callback',@(~,~)close(),...
            'String','Cancel');

        uicontrol('Style','Pushbutton',...
            'Position',[.25 .05 .15 .15 ],...
            'Units','normalized',...
            'callback',@cb_go,...
            'String','Go');

        set(gcf,'visible','on');
        watchoff
    end

    function do_calma(calc_type)
        % check if time are with limits
        %
        if ~exist('it', 'var')
            it = t0b + (teb-t0b)/2;
        end
        if it + compare_window_dur > teb || it < t0b
            errordlg('Time out of limits')
            in2 = 'nocal';
            show_map
        end

        % initial parameter
        winlen_days = floor(compare_window_dur/ZG.bin_dur);
        ti = floor((it -t0b)/days(ZG.bin_dur));
        [len, ncu] = size(cumuall);
        len = len-2;
        var1 = zeros(1,ncu);
        var2 = zeros(1,ncu);
        mean1 = zeros(1,ncu);
        mean2 = zeros(1,ncu);
        as = zeros(1,ncu);

        % loop over all grid points for percent
        %
        %
        switch calc_type
            case 'per'
                [as, strib, stri2] = calc_percent_change();
            case 'rub'
                [as, var1, var2] = calc_rubberband(ncu, ti, winlen_days);
            case 'ast'
                [as, var1, var2] = calc_ast(ncu, ti, len);
            case 'lta'
                [as, var1, var2] = calc_lta(ncu, ti, winlen_days, len, cumuall);
            case 'maz'
                [maxlta, maxlta2, mean1, mean2] = calc_maz(ncu, cumuall, len);
            otherwise
                error('ZMAP:show_map:unknownOperation','not sure which operation to do')
        end

        %normalisation of lap1
        normlap1=nan(length(tmpgri(:,1)),1)
        normlap2=nan(length(tmpgri(:,1)),1)

        lv = logical(ll) ;  % having to do with the grid(?)
        normlap2(lv)= as(:);
        %construct a matrix for the color plot
        valueMap=reshape(normlap2,length(yvect),length(xvect));

        [n1, n2] = size(cumuall);
        s = cumuall(n1,:);
        normlap2(lv)= s(:);
        %construct a matrix for the color plot
        r = reshape(normlap2, length(yvect), length(xvect));
        ZG.tresh_km = max(r(:));
        % find max and min of data for automatic scaling
        %
        ZG.maxc = max(valueMap(:));
        ZG.maxc = fix(max(valueMap(:)))+1;
        ZG.minc = min(valueMap(:));
        ZG.minc = fix(min(valueMap(:)))-1;
        %plot imge
        %
        det = 'nop';
        old = valueMap;
        view_max(valueMap,gx,gy,stri,'nop')

    end

    function add_timecut_controls(default_value)
        uicontrol('Style','edit',...  # was inp2_field
            'Position',[.80 .775 .18 .15],...
            'Units','normalized',...
            'String',num2str(default_value),...
            'callback',@cb_timecut_year);

        text(...  #was txt2
            'Position',[0. 0.9 0 ],...
            'FontWeight','bold',...
            'FontSize',ZmapGlobal.Data.fontsz.m ,...
            'String','Please input time of cut in years (e.g. 86.5):');
    end

    function add_compareduration_controls(compare_window_dur)
        text(...  # was txt3
            'Position',     [0. 0.65 0 ],...
            'FontWeight',   'bold',...
            'FontSize',     ZmapGlobal.Data.fontsz.m ,...
            'String',       'Please input window length in years (e.g. 1.5):');
        uicontrol('Style',  'edit',...
            'Position',     [.80 .575 .18 .15],...
            'Units',        'normalized',...
            'String',       num2str(years(compare_window_dur)),...
            'callback',     @cb_window_duration_edit);
    end

    %% callbacks

    function cb_timecut_year(mysrc,~)
        it = str2double(mysrc.String);
    end

    function cb_window_duration_edit(mysrc,~)
        compare_window_dur = years(str2double(mysrc.String));
    end

    function cb_go(mysrc, myevt)
        watchon;
        drawnow;
        do_calma(calc_type);
    end
end

%% calculation functions

function [as, strib, stri2] = calc_percent_change(cumuall, ti, len)
    for i = ncu:-1:1
        mean1(i) = mean(cumuall(1:ti,i));
        mean2(i) = mean(cumuall(ti:len,i));
    end    %for i

    as = -((mean1-mean2)./mean1)*100;

    strib = 'Change in Percent';
    stri2 = ['ti=' num2str(ti*days(ZG.bin_dur) + t0b)  ];
end

function [as, var1, var2] = calc_rubberband(ncu, ti, winlen_days)
    for i = ncu:-1:1
        mean1(i) = mean(cumuall(1:ti,i));
        mean2(i) = mean(cumuall(ti+1:ti+winlen_days,i));
        var1(i) = cov(cumuall(1:ti,i));
        var2(i) = cov(cumuall(ti+1:ti+winlen_days,i));
    end %  for i ;
    as = (mean1 - mean2)./(sqrt(var1/ti+var2/winlen_days));
end

function [as, var1, var2] = calc_ast(ncu, ti, len)
    for i = ncu:-1:1
        mean1(i) = mean(cumuall(1:ti,i));
        var1(i) = cov(cumuall(1:ti,i));
        mean2(i) = mean(cumuall(ti+1:len,i));
        var2(i) = cov(cumuall(ti+1:len,i));
    end
    as = (mean1 - mean2)./(sqrt(var1/ti+var2/(len-ti)));
end

function [as, var1, var2] = calc_lta(ncu, ti, winlen_days, len, cumuall)
    mean1 = mean([cumuall(1:ti-1,:) ; cumuall(ti+winlen_days+1:len,:)]);
    mean2 = mean(cumuall(ti:ti+winlen_days,:));
    for i = ncu : -1 : 1
        var1(i) = cov([cumuall(1:ti-1,i) ; cumuall(ti+winlen_days+1:len,i)]);
        var2(i) = cov(cumuall(ti:ti+winlen_days,i));
    end     % for i
    as = (mean1 - mean2)./(sqrt(var1/(len-winlen_days)+var2/winlen_days));
end

function [maxlta, maxlta2, mean1, mean2] = calc_maz(ncu, cumuall, len)
            maxlta = zeros(1,ncu);
            maxlta = maxlta -5;
            mean1 = mean(cumuall(1:len,:));
            wai = waitbar(0,'Please wait...');
            set(wai,'Color',[0.8 0.8 0.8], 'NumberTitle','off', 'Name','Percent done');

            for i = ncu:-1:1
                var1(i) = cov(cumuall(1:len,i));
            end

            for ti = 1:step: len - winlen_days
                waitbar(ti/len)
                mean1 = mean(cumuall(1:len,:));
                mean2 = mean(cumuall(ti:ti+winlen_days,:));
                for i = 1:ncu
                    var1(i) = cov(cumuall(1:len,i));
                    var2(i) = cov(cumuall(ti:ti+winlen_days,i));
                end
                as = (mean1 - mean2)./(sqrt(var1/len+var2/winlen_days));
                maxlta2 = [maxlta ;  as ];
                maxlta = max(maxlta2);
            end
            %as = reshape(maxlta,length(gy),length(gx));
            close(wai)
end