% Copyright (C) 2017-2018 Titus Cieslewski, RPG, University of Zurich,
%   Switzerland
%   You can contact the author at <titus at ifi dot uzh dot ch>
% Copyright (C) 2017-2018 Siddharth Choudhary, College of Computing,
%   Georgia Institute of Technology, Atlanta, GA, USA
% Copyright (C) 2017-2018 Davide Scaramuzza, RPG, University of Zurich,
%   Switzerland
%
% This file is part of dslam_open.
%
% dslam_open 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.
%
% dslam_open 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 dslam_open. If not, see <http://www.gnu.org/licenses/>.

function runSimulationAndSave(robot_vo_data, decentr_stream, ...
    dvpr_train_path, distributed_mapper_location, dpath, params, data_type)
%% Prepare empty decentralized state.
decentr_state = initDecentrState(robot_vo_data);
%% Assign netvlad cluster centers
% set dvpr_train_path to folder containing a bunch of features
decentr_state = assignClusterCenters(...
    decentr_state, dvpr_train_path, params);

%% Play!
figure(1);
tic;
netvlad_match_stats = zeros(numel(decentr_stream), 4);
data_increments = cell(numel(decentr_stream), 1);
accuracy_measurements = {};
opt_handle = initOptHandle(params.num_robots);
dgs_stats = {};
% Start ATE eval 5 seconds into the dataset to avoid meaningless aligns.
last_accur_eval = 5;
for step_i = 1:numel(decentr_stream)
%for step_i = 1:500
    real_time = toc
    if (real_time < decentr_stream{step_i}.time)
        pause(decentr_stream{step_i}.time - real_time);
    end
    [decentr_state, data_increments{step_i}, ...
        netvlad_match_stats(step_i, :), opt_handle, dgs_stats_i] = ...
        stepDecentrState(decentr_state, decentr_stream{step_i}, params, ...
        distributed_mapper_location, opt_handle);
    dgs_stats = [dgs_stats; dgs_stats_i];

    if (mod(step_i, params.num_robots) == 0)
        plotDecentrState(decentr_state);
        pause(0.0001);
    end

    if ((decentr_stream{step_i}.time - last_accur_eval) > 1)
        last_accur_eval = decentr_stream{step_i}.time;
        [accuracy_measurement, decentr_state] = ...
            evalAccuracy(decentr_state, opt_handle, ...
            decentr_stream{step_i}.time);
        accuracy_measurements = [accuracy_measurements; ...
            accuracy_measurement];
    end
    disp([num2str(step_i) ' out of ' num2str(numel(decentr_stream))]);
end
data_increment_times = cellfun(@(x) x.time, decentr_stream);
% Wrap optimization, unless optimization is nop.
vo_end_state = decentr_state;
[decentr_state, dgs_stats_i, final_increments, ...
    final_increment_times, opt_handle, final_accuracy_measurements] = ...
    wrapUpOptimization(...
    decentr_state, opt_handle, ...
    distributed_mapper_location, params, decentr_stream{end}.time);

dgs_stats = [dgs_stats; dgs_stats_i];
data_increments = [data_increments; final_increments];
data_increment_times = [data_increment_times; final_increment_times];
accuracy_measurements = [...
    accuracy_measurements; final_accuracy_measurements];
plotDecentrState(decentr_state);
%% Save stats
%dlmwrite(...
%    [dpath 'netvlad_match_stats_' ...
%    num2str(cell2mat(struct2cell(params))') '.txt'], ...
%    netvlad_match_stats, ' ');
if strcmp(data_type, 'stata')
    save(...
        regexprep([dpath 'run_data_' ...
        num2str(cell2mat(struct2cell(params))') '.mat'], '\s+', ' '), ...
        'decentr_state', 'data_increments', 'data_increment_times', ...
        'accuracy_measurements', 'dgs_stats', 'vo_end_state', '-v7.3');
else
    save(...
        [dpath 'run_data_' ...
        num2str(cell2mat(struct2cell(params))') '.mat'], ...
        'decentr_state', 'data_increments', 'data_increment_times', ...
        'accuracy_measurements', 'dgs_stats', '-v7.3');

end


function eventLog = ma_executeSetState(setStateEvent, initialState, eventNum, celBodyData)
%ma_executeSetState Summary of this function goes here
%   Detailed explanation goes here

    event = setStateEvent;

    if(strcmpi(event.subType,'setState'))
        eventLog = [event.epoch, ...
                    event.rVect(1), event.rVect(2), event.rVect(3), ...
                    event.vVect(1), event.vVect(2), event.vVect(3), ...
                    event.centralBody.id, ...
                    event.dryMass, event.fuelOxMass, event.monoMass, event.xenonMass, ...
                    eventNum];
    elseif(strcmpi(event.subType,'estLaunch'))
        eventLog = ma_executeLaunch(initialState, event.launch, celBodyData);

        eventLog(:,8) = event.centralBody.id;
        eventLog(:,9) = event.dryMass;
        eventLog(:,10) = event.fuelOxMass;
        eventLog(:,11) = event.monoMass;
        eventLog(:,12) = event.xenonMass;
        eventLog(:,13) = eventNum;

%         if(isempty(initialState))
%             eventLog(:,8) = event.centralBody.id;
%             eventLog(:,9) = event.dryMass;
%             eventLog(:,10) = event.fuelOxMass;
%             eventLog(:,11) = event.monoMass;
%             eventLog(:,12) = event.xenonMass;
%             eventLog(:,13) = eventNum;
%         else
%             eventLog(:,8) = initialState(8);
%             eventLog(:,9) = initialState(9);
%             eventLog(:,10) = initialState(10);
%             eventLog(:,11) = initialState(11);
%             eventLog(:,12) = initialState(12);
%             eventLog(:,13) = eventNum;
%         end
    end
end


%Saving data into ASPAR type 5 format

report_this_filefun(mfilename('fullpath'));

str = [];
[newmatfile] = ['t1.sum'];
[ newpath] = [hodi '/aspar/'];

newt3 = [];
do = [ ' cd ' newpath ];
eval(do)

% lets add the mainshock as the fisrt and largest event...
l = newt2.Date > maepi(1,3);
newt3 =  newt2(l,1:9);
newt3 = [maepi(1,1:9) ; newt3 ];
lam = (newt3(:,2)-floor(newt3(:,2)))*100*6/10;
lom = (newt3(:,1)-floor(newt3(:,1)))*100*6/10;

s = [floor(newt3(:,3:5))  newt3(:,8:9) floor(newt3(:,2)) lam floor(abs((newt3(:,1))))  lom  newt3(:,7) newt3(:,6)];

fid = fopen([newpath newmatfile],'w') ;;
fprintf(fid,'%5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %7.3f %5.0f %7.3f %7.3f %7.3f\n',s');
fclose(fid);
clear s
return


function [ap, prec, recall] = pascal_eval(cls, ds, testset, year, suffix)
% Score detections using the PASCAL development kit.
%   [ap, prec, recall] = pascal_eval(cls, ds, testset, suffix)
%
% Return values
%   ap        Average precision score
%   prec      Precision at each detection sorted from high to low confidence
%   recall    Recall at each detection sorted from high to low confidence
%
% Arguments
%   cls       Object class to evaluate
%   ds        Detection windows returned by pascal_test.m
%   testset   Test set to evaluate against (e.g., 'val', 'test')
%   year      Test set year to use  (e.g., '2007', '2011')
%   suffix    Results are saved to a file named:
%             [cls '_pr_' testset '_' suffix]

% AUTORIGHTS
% -------------------------------------------------------
% Copyright (C) 2011-2012 Ross Girshick
% Copyright (C) 2008, 2009, 2010 Pedro Felzenszwalb, Ross Girshick
%
% This file is part of the voc-releaseX code
% (http://people.cs.uchicago.edu/~rbg/latent/)
% and is available under the terms of an MIT-like license
% provided in COPYING. Please retain this notice and
% COPYING if you use this file (or a portion of it) in
% your project.
% -------------------------------------------------------

conf = voc_config('pascal.year', year, ...
                  'eval.test_set', testset);
cachedir = conf.paths.model_dir;
VOCopts  = conf.pascal.VOCopts;

ids = textread(sprintf(VOCopts.imgsetpath, testset), '%s');

% write out detections in PASCAL format and score
fid = fopen(sprintf(VOCopts.detrespath, 'comp3', cls), 'w');
for i = 1:length(ids);
  bbox = ds{i};
  for j = 1:size(bbox,1)
    fprintf(fid, '%s %f %d %d %d %d\n', ids{i}, bbox(j,end), bbox(j,1:4));
  end
end
fclose(fid);

recall = [];
prec = [];
ap = 0;

do_eval = (str2num(year) <= 2007) | ~strcmp(testset, 'test');
if do_eval
  if str2num(year) == 2006
    [recall, prec, ap] = VOCpr(VOCopts, 'comp3', cls, true);
  else
    % Bug in VOCevaldet requires that tic has been called first
    tic;
    [recall, prec, ap] = VOCevaldet(VOCopts, 'comp3', cls, true);
  end

  % force plot limits
  ylim([0 1]);
  xlim([0 1]);

  print(gcf, '-djpeg', '-r0', [cachedir cls '_pr_' testset '_' suffix '.jpg']);
end

% save results
save([cachedir cls '_pr_' testset '_' suffix], 'recall', 'prec', 'ap');


classdef prtOutlierRemovalNonFinite < prtOutlierRemoval
    % prtOutlierRemovalNonFinite  Removes missing data from a prtDataSet
    %
    %   OutRemove = prtOutlierRemovalNonFinite creates a pre-processing
    %   object that removes all missing data as outliers. Missing data are
    %   respresented as NaN's in the original data set.
    %
    %   A prtOutlierRemovalNonFinite object also inherits all properties and
    %   functions from the prtOutlierRemoval class.  For more information
    %   on how to control the behaviour of outlier removal objects, see the
    %   help for prtOutlierRemoval.
    %
    %   Example:
    %
    %   dataSet = prtDataGenUnimodal;               % Load a data Set
    %   outlier = prtDataSetClass([NaN NaN; inf inf],[1;1]);     % Create and insert
    %   dataSet = catObservations(dataSet,outlier); % an Outlier
    %
    %   % Create the prtOutlierRemoval object
    %   nonFiniteRemove = prtOutlierRemovalNonFinite('runMode','removeObservation');
    %
    %   nonFiniteRemove = nonFiniteRemove.train(dataSet);    % Train and run
    %   dataSetNew = nonFiniteRemove.run(dataSet);
    %
    %   See Also:  prtOutlierRemoval,
    %   prtOutlierRemovalMissingData ,prtOutlierRemovalNstd

    properties (SetAccess=private)
        % Required by prtAction
        name = 'Non Finite Data Outlier Removal';  % NonFinite Data Outlier Removal
        nameAbbreviation = 'NonFiniteDataRemove'   % NonFiniteDataRemove
    end

    methods

        % Allow for string, value pairs
        function Obj = prtOutlierRemovalNonFinite(varargin)

            %Need to check this with the string - setting the string in
            %prtOutlierRemoval should change this value...
            Obj.isCrossValidateValid = true;

            Obj = prtUtilAssignStringValuePairs(Obj,varargin{:});
        end
    end

    methods (Access = protected, Hidden = true)

        function Obj = trainAction(Obj,~)
            %Nothing to do
        end

        function outlierIndices = calculateOutlierIndices(Obj,DataSet) %#ok<MANU> This is OK - don't make it static.
            outlierIndices = ~isfinite(DataSet.getObservations);
        end

    end

end


function model2xls(model, fileName, compSymbols, compNames)
% Writes a model to and Excel spreadsheet.
%
% USAGE:
%
%    model2xls(model, fileName, compSymbols, compNames)
%
% INPUT:
%    model:          A COBRA model struct
%    fileName:       filename with an xsl extension.
%
% OPTIONAL INPUT:
%
%    compSymbols:    Symbols of compartments used in metabolite ids
%    compNames:      Names of the compartments identified by the symbols
%
% EXAMPLE:
%
%                   'Reaction List' tab headers (case sensitive):
%
%                     * Required:
%
%                       * 'Abbreviation':      HEX1
%                       * 'Reaction':          `1 atp[c] + 1 glc-D[c] --> 1 adp[c] + 1 g6p[c] + 1 h[c]`
%                       * 'GPR':               (3098.3) or (80201.1) or (2645.3) or ...
%                     * Optional:
%
%                       * 'Description':       Hexokinase
%                       * 'Subsystem':         Glycolysis
%                       * 'Reversible':        0 (false) or 1 (true)
%                       * 'Lower bound':       0
%                       * 'Upper bound':       1000
%                       * 'Objective':         0/1
%                       * 'Confidence Score':  0,1,2,3,4
%                       * 'EC Number':         2.7.1.1;2.7.1.2
%                       * 'KEGG ID':           R000001
%                       * 'Notes':             Reaction also associated with EC 2.7.1.2
%                       * 'References':        PMID:2043117;PMID:7150652,...
%
%                   'Metabolite List' tab: Required headers (case sensitive): (needs to be complete list of metabolites,
%                   i.e., if a metabolite appears in multiple compartments it has to be represented in multiple rows.
%                   Abbreviations need to overlap with use in Reaction List
%
%                     * Required
%
%                       * 'Abbreviation':      glc-D or glc-D[c]
%                     * Optional:
%
%                       * 'Charged formula' or formula:   C6H12O6
%                       * 'Charge':                       0
%                       * 'Compartment':                  cytosol
%                       * 'Description':                  D-glucose
%                       * 'KEGG ID':                      C00031
%                       * 'PubChem ID':                   5793
%                       * 'ChEBI ID':                     4167
%                       * 'InChI string':                 InChI=1/C6H12O6/c7-1-2-3(8)4(9)5(10)6(11)12-2/h2-11H,1H2/t2-,3-,4+,5-,6?/m1/s1
%                       * 'SMILES':                       OC[C@H]1OC(O)[C@H](O)[C@@H](O)[C@@H]1O
%                       * 'HMDB ID':                      HMDB00122
%
% NOTE:
%
%    Optional inputs may be required for input on unix machines.
%
% .. Authors:
%        - extracted from writeCbModel
%        - Thomas Pfau June 2017

if ~exist('compSymbols','var')
    if isfield(model,'comps') && isfield(model,'compNames')
        compSymbols = model.comps;
        compNames = model.compNames;
    else
        [compSymbols,compNames] = getDefaultCompartments();
    end
end

%Set up xlwrite in case its not set up.
setupxlwrite();

ReactionXlsFields = {'Abbreviation','Description','Reaction','GPR','Lower bound','Upper bound',...
    'Objective','Confidence Score','Subsystem','Notes','EC Number','References','KEGG ID'};
ReactionModelFields = {'rxns','rxnNames','formulas','grRules','lb','ub',...
    'c','rxnConfidenceScore','subSystems','rxnNotes','rxnECNumbers','rxnReferences','rxnKEGGID'};
if isfield(model,'rules')
    model = creategrRulesField(model);
end
if isfield(model,'osenseStr')
    %Only do something if minimisation is requested. Assume that osenseStr
    %is valid.
    if strcmpi(model.osenseStr,'min')
        model.c = model.c*-1;
    end
end

%Explicit handling of subSystems:
if isfield(model,'subSystems')
    cellBool = cellfun(@(x) iscell(x), model.subSystems);
    if all(cellBool)
        %Merge the subSystems with separating ';'
        model.subSystems = cellfun(@(x) strjoin(x,';'),model.subSystems,'UniformOutput',0);
    end
end

model.formulas = printRxnFormula(model,'printFlag',0);
actualFieldNames = fieldnames(model);
usedFields = ismember(ReactionModelFields,actualFieldNames);
ExcelFields = ReactionXlsFields(usedFields);
modelFields = ReactionModelFields(usedFields);
tmpData = cell(numel(model.rxns) + 1,sum(usedFields));
tmpData(1,:) = ExcelFields;
for i = 1:numel(ExcelFields)
    modelField = model.(modelFields{i});
    if isnumeric(modelField)

        for j = 2:length(modelField)+1
            tmpData{j,i} = num2str(modelField(j-1));
        end
        %tmpData(2:end,i) = mat2str(modelField);
    else
        modelField = cellfun(@chopForExcel, modelField,'UniformOutput',0);
        tmpData(2:end,i) = modelField;
    end
end

xlwrite(fileName,tmpData,'Reaction List');

MetaboliteXlsFields = {'Abbreviation','Description','Charged formula','Charge','Compartment','KEGG ID',...
    'PubChem ID','ChEBI ID','InChi string','SMILES','HMDB ID'};
MetaboliteModelFields = {'mets','metNames','metFormulas','metCharges','metCompartments','metKEGGID',...
    'metPubChemID','metChEBIID','metInChIString','metSmiles','metHMDBID'};
%detemine compartments
[tokens tmp_met_struct] = regexp(model.mets,'(?<met>.+)\[(?<comp>.+)\]$','tokens','names'); % add the third type for parsing the string such as "M_10fthf5glu_c"
%if we have any compartment, we will use unknown as compartment ID for
%metabolites without compartment.
if any(cellfun(@isempty, tmp_met_struct))
    unknownComp = 'u';
    unknownCompName = 'Unknown';
else
    unknownComp = 'c';
    unknownCompName = 'Cytosol';
end
if ~any(ismember(compSymbols,unknownComp))
    compSymbols{end+1} = unknownComp;
    compNames{end+1} = unknownCompName;
end

model.metCompartments = cell(size(model.mets));

for i = 1:numel(tmp_met_struct)
    if isempty(tmp_met_struct{i})
        model.mets{i} = [model.mets{i} '[' unknownComp ']'];
        model.metCompartments{i} = compNames(ismember(compSymbols,unknownComp));
    else
        model.metCompartments{i} = compNames(ismember(compSymbols,tmp_met_struct{i}.comp));
    end
end
actualFieldNames = fieldnames(model);
usedFields = ismember(MetaboliteModelFields,actualFieldNames);
ExcelFields = MetaboliteXlsFields(usedFields);
modelFields = MetaboliteModelFields(usedFields);
tmpData = cell(numel(model.mets) + 1,sum(usedFields));
tmpData(1,:) = ExcelFields;
for i = 1:numel(ExcelFields)
    modelField = model.(modelFields{i});
    if isnumeric(modelField)
        tmpData(2:end,i) = num2cell(modelField);
    else
        modelField = cellfun(@chopForExcel, modelField,'UniformOutput',0);
        tmpData(2:end,i) = modelField;
    end
end

xlwrite(fileName,tmpData,'Metabolite List');

end

%% Chop strings for excel output
function strOut = chopForExcel(str)

if (length(str) > 5000)
    strOut = str(1:5000);
    fprintf('String longer than 5000 characters - truncated for Excel output\n%s\n',str);
else
    strOut = str;
end
end


function unfreezeColors(h)
% unfreezeColors  Restore colors of a plot to original indexed color. (v2.3)
%
%   Useful if you want to apply a new colormap to plots whose
%       colors were previously frozen with freezeColors.
%
%   Usage:
%       unfreezeColors          unfreezes all objects in current axis,
%       unfreezeColors(axh)     same, but works on axis axh. axh can be vector.
%       unfreezeColors(figh)    same, but for all objects in figure figh.
%
%       Has no effect on objects on which freezeColors was not already called.
%				(Note: if colorbars were frozen using cbfreeze, use cbfreeze('off') to
%       unfreeze them. See freezeColors for information on cbfreeze.)
%
%
%   See also freezeColors, freezeColors_pub.html, cbfreeze.
%
%
%   John Iversen (iversen@nsi.edu) 3/23/05
%

%   Changes:
%   JRI 9/1/06 now restores any object with frozen CData;
%              can unfreeze an entire figure at once.
%   JRI 4/7/10 Change documentation for colorbars

% Free for all uses, but please retain the following:
%
%   Original Author:
%   John Iversen, 2005-10
%   john_iversen@post.harvard.edu

error(nargchk(0,1,nargin,'struct'))

appdatacode = 'JRI__freezeColorsData';

%default: operate on gca
if nargin < 1,
    h = gca;
end

if ~ishandle(h),
     error('JRI:unfreezeColors:invalidHandle',...
            'The argument must be a valid graphics handle to a figure or axis')
end

%if h is a figure, loop on its axes
if strcmp(get(h,'type'),'figure'),
    h = get(h,'children');
end

for h1 = h', %loop on axes

    %process all children, acting only on those with saved CData
    %   ( in appdata JRI__freezeColorsData)
    ch = findobj(h1);

    for hh = ch',

        %some object handles may be invalidated when their parent changes
        %   (e.g. restoring colors of a scattergroup unfortunately changes
        %   the handles of all its children). So, first check to make sure
        %   it's a valid handle
        if ishandle(hh)
            if isappdata(hh,appdatacode),
                ad = getappdata(hh,appdatacode);
                %get oroginal cdata
                %patches have to be handled separately (see note in freezeColors)
                if ~strcmp(get(hh,'type'),'patch'),
                    cdata = get(hh,'CData');
                else
                    cdata = get(hh,'faceVertexCData');
                    cdata = permute(cdata,[1 3 2]);
                end
                indexed = ad{1};
                scalemode = ad{2};

                %size consistency check
                if all(size(indexed) == size(cdata(:,:,1))),
                    %ok, restore indexed cdata
                    if ~strcmp(get(hh,'type'),'patch'),
                        set(hh,'CData',indexed);
                    else
                        set(hh,'faceVertexCData',indexed);
                    end
                    %restore cdatamapping, if needed
                    g = get(hh);
                    if isfield(g,'CDataMapping'),
                        set(hh,'CDataMapping',scalemode);
                    end
                    %clear appdata
                    rmappdata(hh,appdatacode)
                else
                    warning('JRI:unfreezeColors:internalCdataInconsistency',...
                        ['Could not restore indexed data: it is the wrong size. ' ...
                        'Were the axis contents changed since the call to freezeColors?'])
                end

            end %test if has our appdata
        end %test ishandle

    end %loop on children

end %loop on axes


function [ipinfo,tt]=hostipinfo(m,t)
%HOSTIPINFO get host name and internet connection information
%  Usage:    hostname   = hostipinfo;        % computer name
%            ip_address = hostipinfo('i');   % IP address
%
%  Inputs:   m  mode input selects the information to output (see below)
%            t  optional output from an "ipconfig -all" command
%
%  Outputs:  ipinfo   cell array with one row per IP connection. The number
%                     of columns is detemined by the m input (see below).
%                     If only a single output value is selected by the m input, then
%                     ipinfo will be a string rather than a cell array.
%            tt       output from the "ipconfig -all" command
%
%  The "m" input selects whch IP connections to supply information about
%  (rows of IPINFO) and what information to supply (columns of IPINFO).
%
%  Row selection: A   include all connections
%                 L   Local Internet Connection [default if m non-empty]
%                 B   Bluetooth Connection
%                 P   PPP connection (e.g. a VPn connection)
%
%  Col selection: h   hostname (same for all connections) [default if m is empty]
%                 c   Connection type code: L=local, B=bluetooth, P=PPP or ?=other
%                 t   Connection type (e.g. "Ethernet" or "PPP")
%                 n   Connection name (e.g. "Local Area Connection")
%                 m   MAC address (e.g. "00-53-45-00-00-00"
%                 i   IP address (e.g. "192.168.1.1") [default if m non-empty]

%      Copyright (C) Mike Brookes 2012
%      Version: $Id: hostipinfo.m 1443 2012-02-22 09:10:03Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargin<2
    t=evalc('!ipconfig -all');
    if nargin<1
        m='';
    end
end
tt=t;
if ~numel(m)
    m='Lh';
end
host=regexp(t,'Host Name[ .]*:\s*([\w-]*)','tokens','once'); % get host name
if ~numel(m)
    ipinfo=host{1};
else
    [iad,ad]=regexp(t,'\n(\w*) adapter ([ \w]*):','start','tokens'); % get adapters
    [iadx,adx]=regexp(t,'\n(\w* adapter [ \w]*):','start','tokens'); % get entire adapter names
    [imac,mac]=regexp(t,'Physical Address[ .]*:\s*(\S*)','start','tokens'); % get MAC addresses
    [iip,ip]=regexp(t,'IP Address[ .]*:\s*(\S*)','start','tokens'); % get IP addresses
    nad=numel(iad);  % number of adapters listed in ipconfig
    iad(nad+1)=length(t); % add an extra fake adapter at the end of the list
    fty='hctnmi'; % possible output fields
    nfty=numel(fty);    % number of fields
    ipinfo=cell(nad,nfty); % cell array to store the fields for each adapter
    nr=nad;
    aty='LBP';   % types of adapter
    naty=numel(aty);
    assx={'Ethernet adapter Local Area Connection'; 'Ethernet adapter Bluetooth Network Connection' ; 'PPP adapter '};
    for i=1:nad
        ipinfo{i,1}=host{1};
        ipinfo(i,3:4)=ad{i};
        ix=find((imac>iad(i)) & (imac<iad(i+1)),1);
        if numel(ix)
            ipinfo{i,5}=mac{ix}{1};
        else
            ipinfo{i,5}='';
        end
        ix=find((iip>iad(i)) & (iip<iad(i+1)),1);
        if numel(ix)
            ipinfo{i,6}=ip{ix}{1};
        else
            ipinfo{i,6}='';
        end
        jx=cell(length(assx),1);
        for j=1:length(assx)
            jx{j}=strfind(adx{i}{1},assx{j});    % compare adapter strings with adapter types
        end
        jx=find(~cellfun('isempty',jx));
        if numel(jx)
            ipinfo{i,2}=aty(jx);
        else
            ipinfo{i,2}='?';
        end
    end
    % Select the requested adapters from the rows of ipinfo{}
    if ~any(m=='A')
        ix=(1:naty)*(aty(ones(numel(m),1),:)'==m(ones(naty,1),:));
        ix=ix(ix>0);
        nr=numel(ix);
        if ~nr
            ix=1;  % default to 'L' = Local Internet
        end
        jx=ix;      % jx will hold first match
        for i=1:numel(ix)
            a=strmatch(aty(ix(i)),ipinfo(:,2));
            if numel(a)
                jx(i)=a(1);
            else
                jx(i)=0;
            end
        end
        jx=jx(jx>0);
        ipinfo=ipinfo(jx,:);
    end
    % Select the requested fields from the columns of ipinfo{}
    ix=(1:nfty)*(fty(ones(numel(m),1),:)'==m(ones(nfty,1),:));
    ix=ix(ix>0);
    nc=numel(ix);
    if ~nc
        ix=6;  % default to 'i' = IP address
    end
    ipinfo=ipinfo(:,ix);
    if nr<2 && nc<2
        ipinfo=ipinfo{1};  % just output a string if only one element requested
    end
end


function magnifier
% MAGNIFIER - Pixel Magnification for any graphic.
%
% The figure window created by the MAGNIFIER command will display a
% magnification of pixels of the area under the mouse.  To use it,
% click in the MAGNIFIER window, and drag the mouse to the area of
% interest.

% Written by Eric Ludlam <eludlam@mathworks.com>
% Copyright 2002 The MathWorks Inc

  ad.f=figure('renderer','painters','menubar','none',...
              'busyaction','cancel','doublebuffer','off','tag','magnifier',...
              'name','Magnifier','numbertitle','off');
  ad.a=axes('parent',ad.f);

  f=getframe(ad.f, [ get(ad.f,'currentpoint') 100 100 ] );
  ad.i = image(f.cdata,'parent',ad.a,'erasemode','none');
  set(ad.a, 'color','none','xticklabel',[],'yticklabel',[],'box','on',...
             'position',[.05 .05 .9 .9],'layer','bottom');

  title('Click and drag to magnify');
  set(ad.f,'windowbuttondownfcn',@magnifybuttondown);
  set(ad.f,'windowbuttonupfcn',@magnifybuttonup);

  set(ad.f ,'handlevisibility','callback');
  setappdata(ad.f,'magnifier',ad);

function magnifymotion(a,b)

  global inmotion;

  if isempty(inmotion)

    inmotion = 1;

    ad=getappdata(a,'magnifier');
    cp = get(ad.f,'currentpoint');

    f = getframe(ad.f, [ cp-50 100 100 ]);

    set(ad.i,'cdata',f.cdata);

    inmotion = [];

  end

function magnifybuttondown(a,b)
% Button down function in the magnifier

  ad=getappdata(a,'magnifier');
  ad.down = 1;
  set(ad.f,'windowbuttonmotionfcn',@magnifymotion)
  setappdata(ad.f,'magnifier',ad);

function magnifybuttonup(a,b)

  ad=getappdata(a,'magnifier');
  ad.down=0;
  set(ad.f,'windowbuttonmotionfcn',[])
  setappdata(ad.f,'magnifier',ad);


function [scans,dt] = er_getScanGroup(vw,scan)
% [scans,dt] = er_getScanGroup(view,scan);
%
% Gets the group of scans assigned as a group to the
% current scan; if no group of scans is assigned, prompts
% to assign it.
%
% See: er_groupScans.
%
% ras 04/07/04: wrote it.
global dataTYPES;

cdt = vw.curDataType;

if ieNotDefined('scan')
    scan = viewGet(vw, 'curScan');
end

% check if there's a scan group assigned to this scan
if ~isfield(dataTYPES(cdt).scanParams(scan),'scanGroup') || ...
        isempty(dataTYPES(cdt).scanParams(scan).scanGroup)
    er_groupScans(vw);
end

% parse the groupScans text into a data type series
% and a set of scans (e.g. 'Original: 1 2 3'):
txt = dataTYPES(cdt).scanParams(scan).scanGroup;
%colon = findstr(':',txt); %findstr is obsolete, using strfind instead
colon = strfind(txt,':');
dtName = txt(1:colon-1);
scans = str2num(txt(colon+2:end));
dt = cellfind({dataTYPES.name}, dtName);

return


function rx = rx3ViewToggle(rx, nToggles, views);
% Toggle between the interpolated and reference slices for the 3 view axes
% in the interpolated 3-view figure.
%
%  rx = rx3ViewToggle(rx, [nToggles=3], [views=1:3]);
%
%
% ras, 05/05/2009.
if ~exist('rx', 'var') | isempty(rx)
    cfig = findobj('Tag','rxControlFig');
    rx = get(cfig,'UserData');
end

if notDefined('nToggles')
    % # of times to alternate b/w interp and ref images
    nToggles = 3;
end

if notDefined('views')
    % which of the 3 view windows to toggle
    views = 1:3;
end

%% get position from UI controls
for i = 1:3
    loc(i) = str2num( get(rx.ui.interpLoc(i), 'String') );
end

for ori = views
    % get interpolated image
    interp = rxInterpSlice(rx, loc(ori), ori);

    % get reference image
    switch ori
        case 1, ref = squeeze( rx.ref(loc(ori),:,:) );
        case 2, ref = squeeze( rx.ref(:,loc(ori),:) );
        case 3, ref = rx.ref(:,:,loc(ori));
    end

    % adjust contrast, brightness, etc.
    [interp ref] = rxGetComparisonImages(rx, interp, ref);

    if ishandle(rx.ui.interp3ViewAxes(ori))
        axes(rx.ui.interp3ViewAxes(ori))
    else
        figure('Name', ['mrRx: ' mfilename]);
    end

    rng = [min(interp(:)) max(interp(:))];

    % get cur axis limits and keep them, in case user has zoomed image
    x = get(gca, 'xlim');
    y = get(gca, 'ylim');

    for n = 1:nToggles
        imshow(ref, rng);
        xlim(x); ylim(y);
        pause(0.15);
        imshow(interp, rng);
        xlim(x); ylim(y);
        pause(0.15);
    end

    % if n toggles is 0, just switch the view to the reference image
    if nToggles < 1,
        imshow(ref, rng);
        xlim(x); ylim(y);
    end
end

return


function transition_net_multi(varargin)

opts.expDir = fullfile('../data','DCFNet-net-7') ;
opts = vl_argparse(opts, varargin);

modelPath = dir(fullfile(opts.expDir, 'net-epoch-*0.mat'));
modelPath = sort({modelPath.name});

[~,out_name,~] = fileparts(opts.expDir);

for i = 1:numel(modelPath)
    load(fullfile(opts.expDir, modelPath{i}));
    net = dagnn.DagNN.loadobj(net) ;
    net = deployDCFNet(net);
    if ~exist('../model_multi', 'dir')
        mkdir('../model_multi');
    end
    save(fullfile('../model_multi', [out_name num2str(i, 'epoch_%d.mat')]), 'net') ;
end
end


function update_visualization_func = show_video(img_files, video_path, resize_image)
%SHOW_VIDEO
%   Visualizes a tracker in an interactive figure, given a cell array of
%   image file names, their path, and whether to resize the images to
%   half size or not.
%
%   This function returns an UPDATE_VISUALIZATION function handle, that
%   can be called with a frame number and a bounding box [x, y, width,
%   height], as soon as the results for a new frame have been calculated.
%   This way, your results are shown in real-time, but they are also
%   remembered so you can navigate and inspect the video afterwards.
%   Press 'Esc' to send a stop signal (returned by UPDATE_VISUALIZATION).
%
%   Joao F. Henriques, 2014
%   http://www.isr.uc.pt/~henriques/
%
%   revised by: Yang Li, August, 2014
%   http://ihpdep.github.io

	%store one instance per frame
	num_frames = numel(img_files);
	boxes = cell(num_frames,1);

	%create window
	[fig_h, axes_h, unused, scroll] = videofig(num_frames, @redraw, [], [], @on_key_press);  %#ok, unused outputs
	set(fig_h, 'Number','off', 'Name', ['Tracker - ' video_path])
	axis off;

	%image and rectangle handles start empty, they are initialized later
	im_h = [];
	rect_h = [];

	update_visualization_func = @update_visualization;
	stop_tracker = false;

	function stop = update_visualization(frame, box)
		%store the tracker instance for one frame, and show it. returns
		%true if processing should stop (user pressed 'Esc').
		boxes{frame} = box;
		scroll(frame);
		stop = stop_tracker;
	end

	function redraw(frame)
		%render main image
		im = imread([video_path img_files{frame}]);
% 		if size(im,3) > 1,
% 			im = rgb2gray(im);
% 		end
		if resize_image,
			im = imresize(im, 0.5);
		end

		if isempty(im_h),  %create image
			im_h = imshow(im, 'Border','tight', 'InitialMag',200, 'Parent',axes_h);
		else  %just update it
			set(im_h, 'CData', im)
		end

		%render target bounding box for this frame
		if isempty(rect_h),  %create it for the first time
			rect_h = rectangle('Position',[0,0,1,1], 'EdgeColor','g', 'Parent',axes_h);
		end
		if ~isempty(boxes{frame}),
			set(rect_h, 'Visible', 'on', 'Position', boxes{frame});
		else
			set(rect_h, 'Visible', 'off');
		end
	end

	function on_key_press(key)
		if strcmp(key, 'escape'),  %stop on 'Esc'
			stop_tracker = true;
		end
	end

end


function [ids,fullfilenames] = GenerateListOfFilesTBA(ext,datadir,recursive)
%
%[ids,fullfilenames] = GenerateListOfFilesTBA(ext, datadir, recursive)
%
%   OBJECTIVE:
%       This function takes the extension ext and finds all relevant
%       files within the working directory and the subfolders of the
%       working directory. Works with records that are stored with a
%       filename in the format '####.ext'
%
%   INPUT:  ext       - string variable of the extension of filetype
%           	        example: 'mat' 'qrs'
%           datadir   - string variable representing the name of the
%           	        directory of the data
%           recursive -
%
%   OUTPUT: ids          - vector of identifiers (doubles) listing all records
%           fulfilenames - full file name for each record(strings)
%
%	REPO:
%       https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox
%   ORIGINAL SOURCE AND AUTHORS:
%       Main script written by Adriana N. Vest
%       Dependent scripts written by various authors
%       (see functions for details)
%	COPYRIGHT (C) 2016
%   LICENSE:
%       This software is offered freely and without warranty under
%       the GNU (v3 or later) public license. See license file for
%       more information
%

% Check for folders inside the data directory so that a decision can be
% made about whether to include subfolders or not

if strcmp(computer,'GLNXA64')
    if recursive
    	[~, sysout] = system(['ls ' datadir filesep '*.',ext]);
    else
        [~, sysout] = system(['ls ' datadir filesep '*.',ext]);
        % ANV modified this line to work in linux for MIT NSR files on box
        % May need to revisit
    end
    allfiles = strsplit(sysout);
elseif strcmp(computer,'MACI64') || strcmp(computer,'PCWIN64')
    allfiles1 = [];
    if recursive
        allfiles1 = dir(fullfile(datadir, '*', filesep, ['*.' ext]));
    end
	allfiles2 = dir(fullfile(datadir, ['*.' ext]));
    allfiles = [allfiles1;allfiles2];
else
    error('no files or records found');
end

% Initialize arrays to store data
ids = cell(length(allfiles), 1); % Create ids vector to store subject identifiers
fullfilenames = cell(length(ids),1); % Create cell array to store filenames

for i = 1:length(fullfilenames)
    try
        if strcmp(computer,'GLNXA64')
            filename = dir(allfiles{i});
            fullfilenames{i} = [allfiles{i}];

            filename = filename.name;
            filename = strrep(filename, ['.' ext], '');
            ids{i} = filename;
        elseif strcmp(computer,'MACI64')
            fullfilenames{i} = [allfiles(i).folder filesep allfiles(i).name];
            filename = allfiles(i).name;
            filename = strrep(filename, ['.' ext], '');
            ids{i} = filename;
        elseif strcmp(computer,'PCWIN64')
            fullfilenames{i} = [datadir filesep allfiles(i).name];
            filename = allfiles(i).name;
            filename = strrep(filename, ['.' ext], '');
            ids{i} = filename;
        end
    catch

    end
end

if strcmp(computer,'GLNXA64')
	%idx_rem = find((isempty(ids))); %% This line isn't working on Linux
    emptyCells = cellfun(@isempty,ids);
    idx_rem = find(emptyCells);
    ids(idx_rem) = [];
	fullfilenames(idx_rem) = [];
end

if isnumeric(ids{1})
    for k = 1:length(ids)
        ids{k} = num2str(ids{k});
    end
end


%% AMPL Install for OPTI Toolbox
% Supplied binaries are built from Netlib's AMPL Solver Library Interface

%   Copyright (C) 2011 Jonathan Currie (I2C2)

% This file will help you compile AMPL Solver Library (ASL) for use with
% MATLAB.

% My build platform:
% - Windows 8 x64
% - Visual Studio 2012

% 1) Get AMPL Solver Library
% The generic NL reader for AMPL is available free from Netlib
% (http://www.netlib.org/ampl/solvers/). You will need to download all .c
% and .h as well as .hd files. Note this is not the AMPL engine
% (www.ampl.com) which is a commerical product, but code to allow people to
% connect their solvers to AMPL. Alternatively send a blank email to
% "netlib@netlib.org" with "send all from ampl/solvers" as the subject to
% retrieve all files.

% 2) Compile ASL
% The easiest way to compile ASL is to use the Visual Studio Project
% Builder included with OPTI. Use the following commands, substituting the
% required path on your computer:

% %% Visual Studio Builder Commands
% path = 'full path to ASL here'; %e.g. 'C:\Solvers\ASL'
% sdir = path;
% name = 'libasl';
% opts = [];
% opts.exPP = {'Arith_Kind_ASL=1','Sscanf=sscanf','Printf=printf','Sprintf=sprintf',...
%              'Fprintf=fprintf','snprintf=_snprintf','NO_STDIO1','_CRT_SECURE_NO_WARNINGS','_CRT_NONSTDC_NO_DEPRECATE'};
% opts.exclude = {'arithchk.c','atof.c','b_search.c','dtoa.c','fpinit.c','funcadd.c',...
%                 'funcadd0.c','funcaddk.c','funcaddr.c','obj_adj0.c','sjac0dim.c',...
%                 'sprintf.c','sscanf.c','printf.c','mpec_adj0.c'};
% opts.charset = 'MultiByte';
% VS_WriteProj(sdir,name,[],opts)
% %%

% Once complete, you will have a directory called ASL\libasl. Open the
% Visual Studio 2012 project file, then complete the following steps:
%   a) Rename arith.h0 to arith.h, and uncomment the define "IEEE_8087"
%   b) Rename stdio1.h0 to stdio1.h
%   c) Under project properties change the character set to "Use
%   Multi-Byte Character Set" (both Win32 and x64 as required).
%   d) Comment out the line "exit(n)" in mainexit.c (this stops MATLAB
%   crashing on an ASL error) [line 62]
%   e) To prevent Matlab crashing on a bad NL file comment all code under
%   the if(n_con < 0 || ...) statement on line 260 in jac0dim.c. Add return
%   NULL; so instead of exiting, our MEX file can determine this as a bad file.
%   f) Comment line 900 in asl.h (extern int Sprintf(char*, ....)
%   g) Comment line 36 in jac0dim.c (extern int Sscanf(char*, ...)
%   h) Comment line 56 in stderr.c (AllocConsole();)
%   i) Build a Win32 or x64 Release to compile the code.
%   j) Copy the generated .lib file to the following folder:
%
%   OPTI/Utilities/File IO/Source/lib/win32 or win64
%
%   Also copy all header files to the include directory as per the above
%   path.

% 3) MEX Interface
% The Read MEX Interface is a simple MEX interface I wrote to use the AMPL
% File IO and Eval routines.

% 4) Compile the MEX File
% The code below will automatically include all required libraries and
% directories to build the MEX file. Once you have completed all
% the above steps, simply run this file to compile! You MUST BE in
% the base directory of OPTI!

clear asl

% Get Arch Dependent Library Path
libdir = opti_GetLibPath();

fprintf('\n------------------------------------------------\n');
fprintf('AMPL MEX FILE INSTALL\n\n');

post = [' -IInclude -L' libdir ' -llibasl -DNO_STDIO1 -output asl'];

%CD to Source Directory
cdir = cd;
cd 'Utilities/File IO/Source';

%Compile & Move
pre = 'mex -v -largeArrayDims amplmex.c';
try
    eval([pre post])
     movefile(['asl.' mexext],'../','f')
    fprintf('Done!\n');
catch ME
    cd(cdir);
    error('opti:ampl','Error Compiling AMPL!\n%s',ME.message);
end
cd(cdir);
fprintf('------------------------------------------------\n');


%GET Get datafile parameter fields
%
%   [VALUE1,VALUE2,...] = GET(A,FIELD1,FIELD2,...)
%
% INPUT
%   A       Datafile
%   FIELDx  Field names (strings)
%
% OUTPUT
%   VALUEx  Field values
%
% SEE ALSO (PRTools Guide)
% PRDATAFILE, SET


function value = p00_param_default ( test )

%*****************************************************************************80
%
%% P00_PARAM_DEFAULT defaults the parameters of any test problem.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer TEST, the test problem index.
%
%    Output, integer VALUE, the number of problem parameters.
%
  if ( test == 1 )
    value = 0;
  elseif ( test == 2 )
    value = 0;
  elseif ( test == 3 )
    value = 0;
  elseif ( test == 4 )
    value = 0;
  elseif ( test == 5 )
    value = 0;
  elseif ( test == 6 )
    value = 0;
  elseif ( test == 7 )
    value = 0;
  elseif ( test == 8 )
    value = 0;
  elseif ( test == 9 )
    value = 0;
  elseif ( test == 10 )
    value = 0;
  elseif ( test == 11 )
    value = 0;
  elseif ( test == 12 )
    value = 0;
  elseif ( test == 13 )
    value = 0;
  elseif ( test == 14 )
    value = 0;
  elseif ( test == 15 )
    value = p15_param ( 'DEFAULT' );
  elseif ( test == 16 )
    value = p16_param ( 'DEFAULT' );
  elseif ( test == 17 )
    value = p17_param ( 'DEFAULT' );
  elseif ( test == 18 )
    value = p18_param ( 'DEFAULT' );
  elseif ( test == 19 )
    value = p19_param ( 'DEFAULT' );
  elseif ( test == 20 )
    value = p20_param ( 'DEFAULT' );
  elseif ( test == 21 )
    value = 0;
  elseif ( test == 22 )
    value = 0;
  elseif ( test == 23 )
    value = 0;
  elseif ( test == 24 )
    value = 0;
  elseif ( test == 25 )
    value = 0;
  elseif ( test == 26 )
    value = p26_param ( 'DEFAULT' );
  elseif ( test == 27 )
    value = 0;
  elseif ( test == 28 )
    value = 0;
  elseif ( test == 29 )
    value = 0;
  elseif ( test == 30 )
    value = 0;
  elseif ( test == 31 )
    value = p31_param ( 'DEFAULT' );
  elseif ( test == 32 )
    value = p32_param ( 'DEFAULT' );
  elseif ( test == 33 )
    value = p33_param ( 'DEFAULT' );
  elseif ( test == 34 )
    value = p34_param ( 'DEFAULT' );
  elseif ( test == 35 )
    value = p35_param ( 'DEFAULT' );
  elseif ( test == 36 )
    value = 0;
  elseif ( test == 37 )
    value = p37_param ( 'DEFAULT' );
  elseif ( test == 38 )
    value = p38_param ( 'DEFAULT' );
  elseif ( test == 39 )
    value = p39_param ( 'DEFAULT' );
  elseif ( test == 40 )
    value = p40_param ( 'DEFAULT' );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_PARAM_DEFAULT - Fatal error!\n' );
    fprintf ( 1, '  Illegal problem index TEST = %d\n', test );
    error ( 'P00_PARAM_DEFAULT - Fatal error!' );
  end

  return
end


function r = eq(p,q)
% this function compares the equality condition of x, y, and z values of the structures that I use in
% the FVtool.
%
% SYNOPSIS:
%
%
% PARAMETERS:
%
%
% RETURNS:
%
%
% EXAMPLE:
%
% SEE ALSO:
%

% Copyright (c) 2012-2016 Ali Akbar Eftekhari
% See the license file

if (isa(p, 'CellVariable')&&isa(q, 'CellVariable'))
    r=p;
    r.value = p.value==q.value;
elseif isa(p, 'CellVariable')
    r=p;
    r.value = p.value==q;
else
    r=q;
    r.value = p==q.value;
end


function a = ne( x, y )

b = newcnstr( evalin( 'caller', 'cvx_problem', '[]' ), x, y, '~=' );
if nargout, a = b; end

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function [scanFileNameC,doseFileNameC,maskFileNameC] = ...
    export_scan_dose_struct_from_planC(exportFormat,...
    scanNumV,doseNumV,structNameC,outdDir,planC)
% function [scanFileNameC,doseFileNameC,maskFileNameC] = ...
%     export_scan_dose_struct_from_planC(exportFormat,...
%     scanNumV,doseNumV,structNameC,outNrrdDir,planC)
%
% exportFormat: nii or nrrd
% scanNumV: indices of scans in planC to export
% doseNumV: indices of doses in planC to export
% structNameC: cell array of structure names to export
% outDir: directory to export to
% planC:
%
% APA, 9/13/2021

indexS = planC{end};
reorientFlag = 1;
dataType = [];

scanFileNameC = {};
doseFileNameC = {};
maskFileNameC = {};

% scan
for iScan = 1:length(scanNumV)
    scanNum = scanNumV(iScan);
    scanFileNameC = scan2imageOut(planC,scanNum,outdDir,reorientFlag,exportFormat,dataType);
end

% dose
for iDose = 1:length(doseNumV)
    doseNum = doseNumV(iDose);
    scanNum = getDoseAssociatedScan(doseNum,planC);
    doseFileNameC = dose2imageOut(planC, doseNum, scanNum, outdDir,reorientFlag,exportFormat);
end

% structure
maskFileNameC = mask2imageOut(planC,scanNum,structNameC,outdDir,reorientFlag,exportFormat);


function Z = mldivide(X,Y)
%MLDIVIDE Slash left division for tensors.
%
%   MLDIVIDE(A,B) is called for the syntax 'A \ B' when A is a scalar and B
%   is a tensor.
%
%   Example
%   X = tenrand([4 3 2],5);
%   3 \ X
%
%   See also TENSOR, TENSOR/LDIVIDE.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

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

if isscalar(X)
    Z = tenfun(@ldivide,X,Y);
    return;
end

error('MLDIVIDE only supports the scalar case for tensors');


%  sabs smooth approximation of abs
%
%  ::
%
%
%  Args:
%
%  Returns:
%     :
%
%  Note:
%
%  Example:
%
%     See also:
%


%% BASIC WAYPOINT EVENT (waypointEvent.m) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This class is designed as a child class to a generic "event", used to
% define the characteristics of a 'waypoint achieved' event.

% Author: James A. Douthwaite

classdef waypointEvent < interactionEvent

%% INITIALISE THE WAYPOINT EVENT SPECIFIC PARAMETERS
    properties
        % Waypoint unique properties
    end
%%  CLASS METHODS
    methods
        % CONSTRUCTION METHOD FOR THE WAYPOINT EVENT
        function obj = waypointEvent(time,objectA,objectB,summaryInfo,enum)
            % INPUTS:
            % time          - Detection time (s)
            % objectA       - Class for the reference object
            % objectIDB     - Class for the second object
            % summaryInfo   - Event description string
            % enum          - Provided alternative enum (nullified?)
            % OUTPUTS:
            % obj           - The waypoint event object

            % INITIALISE THE GENERIC EVENT SUPERCLASS
            obj = obj@interactionEvent(time,'WAYPOINT',objectA,objectB,summaryInfo);

            % ASSIGN AN EVENT NUMERATION
%             if ~exist('enum','var') || ~isa(enum,'uint8')
            if nargin < 5 || ~isa(enum,'uint8')
                obj.type = eventType.waypoint;
            else
                obj.type = enum;
            end
        end
    end
end


function PlotRegMean(ops1,ops)

figure('position', [900 50 900 900])
ax = ceil(sqrt(numel(ops1)));
for i = 1:length(ops1)
    subplot(ax,ax,i)
    imagesc(ops1{i}.mimg)
    colormap('gray')
    title(sprintf('Plane %d', i))
end
annotation('textbox', [0 .96 1 .03], 'String', ...
    sprintf('Registration for mouse %s, date %s', ops.mouse_name, ops.date), ...
    'Interpreter', 'none', 'FontWeight', 'bold', 'LineStyle', 'none', ...
    'HorizontalAlignment', 'center');
drawnow


function arrivalObj = antelope(dbname, subset_expr)
% LOAD_ARRIVALS Load arrivals from a CSS3.0 database
% Modifed by Glenn Thompson 2017-11-28 to include some fields from assoc table
% if present, necessary to support hankelq code
ARRIVAL_TABLE_PRESENT = antelope.dbtable_present(dbname, 'arrival');
ASSOC_TABLE_PRESENT = antelope.dbtable_present(dbname, 'assoc');
ORIGIN_TABLE_PRESENT = antelope.dbtable_present(dbname, 'origin');
    if ~ARRIVAL_TABLE_PRESENT
        fprintf('No arrival table belonging to %s\n',dbname);
        return
    end

    fprintf('Loading arrivals from %s\n',dbname);

    % Open database
    db = dbopen(dbname,'r');
    disp('- database opened');

    % Apply subset expression
    db = dblookup_table(db,'arrival');
    disp('- arrival table opened');
    if exist('subset_expr','var')
        db = dbsubset(db,subset_expr);
        disp('- subsetted database')
    end

    nrows = dbnrecs(db);
    if nrows > 0

        % Sort by arrival time
        db = dbsort(db,'time');
        disp('- sorted arrival table')

        seaz =[]; deltim=[]; delta=[]; orid=[]; evid=[]; timeres=[]; otime=[]; depth=[];
        fprintf('- reading %d rows\n',nrows);
        [sta,chan,time,amp,signal2noise,iphase, arid] = dbgetv(db,'sta','chan','time','amp','snr','iphase','arid');

        % Join with assoc table if present
        if ASSOC_TABLE_PRESENT
            db2 = dblookup_table( db , 'assoc');
            db = dbjoin(db, db2);

            % Get the values
            [sta,chan,time,amp,signal2noise,iphase, arid, seaz, deltim, delta, orid, timeres] = ...
                dbgetv(db,'sta','chan','time','amp','snr','iphase','arid', ...
                'seaz', 'deltim', 'delta', 'orid', 'timeres');

            % Join with origin table if present
            if ORIGIN_TABLE_PRESENT
                db3 = dblookup_table( db , 'origin');
                db = dbjoin(db, db3);
                [evid,otime,depth] = dbgetv(db,'evid','time','depth');
            end
        end

        % Create arrival object
        disp('- creating arrival object')
        arrivalObj = Arrival(cellstr(sta), cellstr(chan), epoch2datenum(time), cellstr(iphase), ...
            'amp', amp, 'signal2noise', signal2noise, 'arid', arid, 'seaz', seaz, ...
            'deltim', deltim, 'delta', delta, 'otime', otime, 'orid', orid, ...
            'evid', evid, 'timeres', timeres, 'depth', depth);

        % Close database link
        dbclose(db);
        disp('- database closed')

        disp('- complete!')
    else
        fprintf('No arrivals found matching request\n');
    end

end


%% (Internal) Get names of annotations from annotation structure
%
%   [AnnNames, all_annotations] = getAnnNames(aux_struct)
%
% Arguments:
%
%      + aux_struct:
%
%      + retries: times to check the existence
%
% Output:
%
%      + AnnNames:
%
%      + all_annotations:
%
% Example:
%
%
% See also ECGtask_QRS_detection
%
% Author: Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar
% Version: 0.1 beta
% Last update: 14/5/2014
% Birthdate  : 21/4/2015
% Copyright 2008-2015
%
function [AnnNames, all_annotations] = getAnnNames(aux_struct)

    AnnNames = [];

    for fname = rowvec(fieldnames(aux_struct))
        if( isfield(aux_struct.(fname{1}), 'time') )
            AnnNames = [AnnNames; cellstr(fname{1}) cellstr('time')];
        end
        if( isfield(aux_struct.(fname{1}), 'qrs') )
            AnnNames = [AnnNames; cellstr(fname{1}) cellstr('qrs')];
        end
    end

    cant_anns = size(AnnNames,1);

    all_annotations = cell(cant_anns,1);
    for ii = 1:cant_anns
        all_annotations{ii} = aux_struct.(AnnNames{ii,1}).(AnnNames{ii,2});
    end


function imdb = dtd_get_database(dtdDir, varargin)
opts.seed = 1 ;
opts.joint = 0;
opts = vl_argparse(opts, varargin) ;

rng(opts.seed) ;

imdb.imageDir = fullfile(dtdDir, 'images') ;
imdb.maskDir = fullfile(dtdDir, 'mask') ;

cats = dir(imdb.imageDir) ;
cats = cats([cats.isdir] & ~ismember({cats.name}, {'.','..'})) ;
imdb.classes.name = {cats.name} ;
imdb.images.id = [] ;
imdb.sets = {'train', 'val', 'test'} ;

for c=1:numel(cats)
  ims = dir(fullfile(imdb.imageDir, imdb.classes.name{c}, '*.jpg'));
  imdb.images.name{c} = cellfun(@(S) fullfile(imdb.classes.name{c}, S), ...
    {ims.name}, 'Uniform', 0);
  imdb.images.label{c} = c * ones(1,numel(ims)) ;
  if numel(ims) ~= 120, error('DTD folder appears inconsistent') ; end
end
imdb.images.name = horzcat(imdb.images.name{:}) ;
imdb.images.label = horzcat(imdb.images.label{:}) ;
imdb.images.id = 1:numel(imdb.images.name) ;

for s = 1:3
  list = textread(fullfile(dtdDir, 'labels', ...
    sprintf('%s%d.txt', imdb.sets{s}, opts.seed)),'%s') ;
  ok = ismember(imdb.images.name, list) ;
  imdb.images.set(find(ok)) = s ;
end
if any(~ismember(imdb.images.set, 1:3)), error('DTD appears inconsistent') ; end

imdb.segments = imdb.images ;
imdb.segments.imageId = imdb.images.id ;
imdb.segments.mask = strrep(imdb.images.name, 'image', 'mask') ;

imdb.meta.classes = imdb.classes.name ;
imdb.meta.inUse = true(1, numel(imdb.meta.classes)) ;
imdb.segments.difficult = false(1, numel(imdb.segments.id)) ;

if (opts.joint)
    annoPath = fullfile(dtdDir, 'labels', 'labels_joint_anno.txt');
    imdb.images.label = -1 * ones(numel(imdb.meta.classes), numel(imdb.images.name));
    fid = fopen(annoPath);
    if (fid > 0)
        lines = textscan(fid, '%s', 'Delimiter', '\n');
        lines = lines{1};
        for ii = 1 : numel(lines)
            parts = strsplit(lines{ii}, ' ');
            parts = parts(1: end - 1);
            imName = parts{1};
            parts = parts{2 : end};
            keyAttr = imName(1 : find(imName == '/') - 1);
            imId = strcmp(imdb.images.name, imName);
            imdb.images.label(ismember(imdb.meta.classes, parts), imId) = 1;
            imdb.images.label(ismember(imdb.meta.classes, keyAttr), imId) = 1;
        end
    end
    imdb.segments.label = imdb.images.label;
end


function fdparain(gobut)
    % Creates the input window for the parameters of the factal dimension calculation.
    %
    %
    % turned into function by Celso G Reyes 2017

    ZG=ZmapGlobal.Data; % used by get_zmap_globals
    figure_w_normalized_uicontrolunits('Units','pixel','pos',[200 400 550 200 ],'Name','Parameters','visible','off',...
        'NumberTitle','off','Color',ZG.color_bg,'NextPlot','new'); % was color_fbg
    axis off;

    input1 = uicontrol('Style','popupmenu','Position',[.75 .75 .23 .09],...
        'Units','normalized','String','Automatic Range|Manual Fixed Range|Manual',...
        'Value',1, 'Callback', @callbackfun_001);

    input2 = uicontrol('Style','edit','Position',[.34 .43 .10 .09],...
        'Units','normalized','String',num2str(radm), 'enable', 'off',...
        'Value',1, 'Callback', @callbackfun_002);

    input3 = uicontrol('Style','edit','Position',[.75 .43 .10 .09],...
        'Units','normalized','String',num2str(rasm), 'enable', 'off',...
        'Value',1, 'Callback', @callbackfun_003);

    tx1 = text('Position',[0 .85 0 ], ...
        'FontSize',ZmapGlobal.Data.fontsz.m , 'FontWeight','bold' , 'String',' Distance Range within which D is computed: ');

    tx2 = text('Position',[0 .45 0], ...
        'FontSize',ZmapGlobal.Data.fontsz.m , 'FontWeight','bold' , 'String','Minimum value: ', 'color', 'w');

    tx3 = text('Position',[.52 .45 0], ...
        'FontSize',ZmapGlobal.Data.fontsz.m , 'FontWeight','bold' , 'String','Maximum value: ', 'color', 'w');

    tx4 = text('Position',[.41 .45 0], ...
        'FontSize',ZmapGlobal.Data.fontsz.m , 'FontWeight','bold' , 'String','km', 'color', 'w');

    tx5 = text('Position',[.94 .45 0], ...
        'FontSize',ZmapGlobal.Data.fontsz.m , 'FontWeight','bold' , 'String','km', 'color', 'w');

    close_button=uicontrol('Style','Pushbutton',...
        'Position',[.60 .05 .20 .15 ],...
        'Units','normalized', 'Callback', @callbackfun_004,'String','Cancel');

    switch (gobut)

        case 1   %Defined in timeplot.m, dorand.m,

            go_button=uicontrol('Style','Pushbutton',...
                'Position',[.20 .05 .20 .15 ],...
                'Units','normalized',...
                'callback',@callbackfun_005,...
                'String','Go');

        case 2  %defined in fdtimin.m

            go_button=uicontrol('Style','Pushbutton',...
                'Position',[.20 .05 .20 .15 ],...
                'Units','normalized',...
                'callback',@callbackfun_006,...
                'String','Go');

        case 3  %defined in Dcross.m

            go_button=uicontrol('Style','Pushbutton',...
                'Position',[.20 .05 .20 .15 ],...
                'Units','normalized',...
                'callback',@callbackfun_007,...
                'String','Go');

    end  %switch(gobut)

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

    function callbackfun_001(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        range=(get(input1,'Value'));
        input1.Value=range;
        actrange(range);
    end

    function callbackfun_002(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        radm=str2double(input2.String);
        input2.String= num2str(radm);
    end

    function callbackfun_003(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        rasm=str2double(input3.String);
        input3.String= num2str(rasm);
    end

    function callbackfun_004(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;

    end

    function callbackfun_005(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;

        org = [2];
        startfd(2);
    end

    function callbackfun_006(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;

        fdtime;
    end

    function callbackfun_007(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;

        Dcross('ca');
    end

end


function [view,OK] = editROIFields(view,n)
% Edit the fields in a region of interest
%
%  [view,OK] = editROIFields(view,n)
%
% You can set the name and color of an ROI
% ARW 040104 : Added uisetcolor option, ability to use [R G B] color format
% RAS, DR, 2007: several new options, including size report and
% save options.
% ras, 01/24/07: records date created, last modified.
% ras, 10/08/07: for the 'save ROI' checkbox, the code now determines
% whether to default to checked or unchecked based on whether the ROI
% is already saved, as well as its name. E.g., if the file has already
% been saved, or it's named 'ROI1', it leaves it unchecked by default.
colorList = {'yellow','magenta','cyan','red','green','blue','white','kblack','user'};

colorChar = char(colorList)';
colorChar = colorChar(1,:);

if ~exist('n','var'), n = view.selectedROI; end
if n==0
    myErrorDlg('Sorry,  you need to load an ROI first.')
end

ROI = view.ROIs(n);
if (ischar(ROI.color))

    colorNum = findstr(ROI.color,colorChar);
    switch lower(ROI.color)
        case 'yellow',  colorRGB=[1 1 0];
        case 'magenta', colorRGB=[1 0 1];
        case 'cyan',    colorRGB=[0 1 1];
        case 'red',     colorRGB=[1 0 0];
        case 'green',   colorRGB=[0 1 0];
        case 'blue',    colorRGB=[0 0 1];
        case 'white',   colorRGB=[1 1 1];
        case 'k',       colorRGB=[0 0 0];
        otherwise
            colorRGB=[0 0 0];
    end
else
    colorNum=8; colorRGB=ROI.color;
end

if ~isfield(ROI, 'created'), ROI.created = datestr(now); end
if ~isfield(ROI, 'modified'), ROI.modified = datestr(now); end
if ~isfield(ROI, 'comments'), ROI.comments = ''; end

dlg(1).string = 'ROI name:';
dlg(1).fieldName = 'name';
dlg(1).style = 'edit';
dlg(1).value = ROI.name;

dlg(2).string = 'Color:';
dlg(2).fieldName = 'color';
dlg(2).list = colorList;
dlg(2).choice = colorNum;
dlg(2).style = 'popupmenu';
if ischar(ROI.color), dlg(2).value = colorList{colorNum};
else                  dlg(2).value = 'user';
end

dlg(end+1).string = 'Comments on ROI:';
dlg(end).fieldName = 'comments';
dlg(end).style = 'edit3';
dlg(end).value = ROI.comments;

dlg(end+1).string = 'Date Created:';
dlg(end).fieldName = 'created';
dlg(end).style = 'text';
dlg(end).value = ROI.created;

dlg(end+1).string = 'Last Modified:';
dlg(end).fieldName = 'modified';
dlg(end).style = 'text';
dlg(end).value = datestr(now);

% ras 01/07: let's also report the ROI size where it's not too hard
if ismember(view.viewType, {'Inplane' 'Volume' 'Gray'})
    dlg(end+1).string = 'ROI Size';
    dlg(end).fieldName = 'roiSize';
    dlg(end).style = 'text';
    nVoxels = size(ROI.coords, 2);
    roiVolume = nVoxels .* prod(viewGet(view, 'voxelSize'))';
    if isequal(view.viewType, 'Inplane')
        % get anatomical and functional sizes
		if nVoxels > 0
			funcVoxels=roiSubCoords(view, ROI.coords);
			nFuncVoxels = size(funcVoxels,2);
			str = strvcat([num2str(nVoxels) ' anatomical voxels'], ...
				[num2str(nFuncVoxels) ' functional voxels'], ...
				sprintf('%3.1fmm^3', roiVolume));
		else
			str = 'No voxels';
		end
        dlg(end).value = str;
    else
        % functionals are resampled to match anat, only one size
        dlg(end).value = sprintf('%i voxels, %3.1fmm^3', nVoxels, roiVolume);
    end
end

if isequal(view.viewType, 'Inplane') & nVoxels > 0
    % another nicety: report which slices the ROI may be found in
    dlg(end+1).string = 'Slices containing ROI';
    dlg(end).fieldName = 'roiSlices';
    dlg(end).style = 'text';
    dlg(end).value = num2str( unique(ROI.coords(3,:)) );
end

%% add checkbox to save the modified ROI:
% default to checked if the ROI has not been saved, unchecked if it has
roiIsSaved = check4File( fullfile(roiDir(view), ROI.name) );
tempRoi = strncmp(ROI.name, 'ROI', 3); % ROI1, ROI2, etc... don't want to save
saveFlag = ( ~roiIsSaved & ~tempRoi );

dlg(end+1).string = 'Save this ROI when done';
dlg(end).fieldName = 'save';
dlg(end).style = 'checkbox';
dlg(end).value = saveFlag;

if ismember(view.viewType, {'Volume' 'Gray'})
    dlg(end+1).string = 'If saving, save in local / shared directory?';
    dlg(end).fieldName = 'local';
    dlg(end).style = 'popup';
    dlg(end).list = {'local' 'shared'};
    dlg(end).value = 2;
end

resp = generalDialog(dlg,'Edit ROI Fields');

% If user selects 'OK', change the parameters.  Otherwise the
% user isn't happy with these settings so bail out.
if ~isempty(resp)
    ROI = mergeStructures(ROI, resp);
    if (strcmp(ROI.color,'user'))
        ROI.color = uisetcolor(colorRGB);
    else
        ROI.color = ROI.color(1);
    end

    % enforce proper ROI fields
    ROI = rmfield(ROI, 'save');
    ROI = roiCheck(ROI);

    if ismember(view.viewType, {'Volume' 'Gray'})   % get local flag from resp
        local = isequal(resp.local, 'local');
    else
        local = 1; % Inplane/Flat: always save locally
    end

    if resp.save==1
        saveROI(view, ROI, local);
    end

    for f = fieldnames(ROI)'
        view.ROIs(n).(f{1}) = ROI.(f{1});
    end

    OK = 1;
else
    OK = 0;
end

return


%   AUTHORSHIP
%   Primary Developer: Stephen Meehan <swmeehan@stanford.edu>
%   Math Lead & Secondary Developer:  Connor Meehan <connor.gw.meehan@gmail.com>
%   Bioinformatics Lead:  Wayne Moore <wmoore@stanford.edu>
%   Provided by the Herzenberg Lab at Stanford University
%   License: BSD 3 clause
%

% this wrapper around MatLab internal map is meant for
% polymorphic function signature compatability with other
% classdef and JAVA class in CytoGenie AutoGate
classdef Map < handle

    properties(Constant)
        PROP_ID='nextId';
    end

    properties
        propertyFile;
    end

    properties(SetAccess=private)
        map;
    end

    methods(Static)
        function SetOnOffBoolean(props, prop, value)
            if strcmp('on', value)
                props.set(prop, 'true');
            else
                props.set(prop, 'false');
            end
        end

        function SetBoolean(props, prop, value)
            if value
                props.set(prop, 'true');
            else
                props.set(prop, 'false');
            end
        end

        function this=Global(closeIfTrueOrMap)
            persistent singleton;
            if nargin>0 && islogical(closeIfTrueOrMap) && closeIfTrueOrMap
                clear singleton;
                singleton=[];
                disp('Resetting global Map');
                this=[];
            else
                if nargin==1
                    try
                        priorMap=closeIfTrueOrMap;
                        %test method compatibility
                        priorMap.size
                        prop='IsBasicMap';
                        if ~priorMap.has(prop)
                            priorMap.set(prop, 'false')
                            priorMap.get(prop, 'true')
                            priorMap.remove(prop);
                        else
                            priorMap.get(prop, 'true')
                        end
                        singleton=priorMap;
                        this=singleton;
                        return;
                    catch ex
                        ex.getReport
                    end
                end
                if isempty(singleton)
                    singleton=Map;
                    singleton.highDef=Gui.hasPcHighDefinitionAProblem(2000, 2500, false);
                    Map.SetHighDef(singleton, singleton.highDef);
                end
                this=singleton;
            end
        end

        function path=Path
            path=Map.Global.contentFolder;
        end

        function nums=GetNumbers(props, name)
            nums=props.get(name, []);
            if ~isempty(nums)
                nums=str2num(nums);
            else
                nums=[];
            end
        end

        function SetStruct(this, id, structure)
            names=fieldnames(structure)';
            N=length(names);
            for i=1:N
                name=names{i};
                value=getfield(structure, name);
                this.set([id '.' name], value);
            end
        end
    end

    methods
        function this=Map(keysOrFileName, values)
            if nargin<2
                values={};
                if nargin<1
                    keysOrFileName=[];
                end
            end
            if ~isempty(values)
                this.map=containers.Map(keysOrFileName, values);
            elseif ~isempty(keysOrFileName) && ischar(keysOrFileName)
                this.propertyFile=keysOrFileName;
                this.load;
            else
                this.map=containers.Map;
            end
        end

        function cnt=size(this)
            cnt=this.map.length;
        end

        function reset(this)
            this.clear;
        end

        function clear(this)
            remove(this.map, this.map.keys);
        end

        function priorValue=remove(this, name)
            priorValue=this.get(name);
            remove(this.map, name);
        end

        function value=getIdentified(this, id, name)
            value=this.get([id '.' name]);
        end

        function set(this, name, value)
            this.map(name)=value;
        end

        function prior=put(this, name, value)
            prior=this.get(name);
            this.map(name)=value;
        end

        %for value char compatibility with outside map classes
        function setBoolean(this, name, isTrue)
            if isTrue
                isTrue='true';
            else
                isTrue='false';
            end
            this.map(name)=isTrue;
        end

        % for value char compatibility with outside map classes
        function setNumeric(this, name, num)
            this.map(name)=num2str(num);
        end

        function isTrue=is(this, name, defaultIsTrue)
            if this.map.isKey(name)
                value=this.map(name);
                if ischar(value)
                    value=strcmpi('yes', value) || strcmpi('true', value);
                end
                isTrue=value;
            else
                if nargin<3
                    isTrue=false;
                else
                    isTrue=defaultIsTrue;
                end
            end
        end

        function value=get(this, name, defaultValue)
            if this.map.isKey(name)
                value=this.map(name);
            else
                if nargin<3
                    value=[];
                else
                    value=defaultValue;
                end
            end
        end

        function value=getNumeric(this, property, defaultValue)
            value=this.get(property);
            if isempty(value)
                if nargin>2
                    value=defaultValue;
                else
                    value=0;
                end
            else
                if isa(value,'char')
                    value=str2double(value);
                    if isnan(value)
                        if nargin>2
                            value=defaultValue;
                        else
                            value=0;
                        end
                    end
                elseif ~isnumeric(value) || any(isnan(value))
                    if nargin>2
                        value=defaultValue;
                    else
                        value=0;
                    end
                end
            end
        end

        function ok=has(this, name)
            ok=this.map.isKey(name);
        end

        function ok=containsKey(this, name)
            ok=this.map.isKey(name);
        end

        function save(this, propertyFile)
            if nargin>1
                this.propertyFile=propertyFile;
            end
            if ~isempty(this.propertyFile)
                basicMap=this;
                save(this.propertyFile, 'basicMap');
            end
        end

        function load(this, propertyFile)
            if nargin>1
                this.propertyFile=propertyFile;
            end
            if ~isempty(this.propertyFile) && exist(this.propertyFile, 'file')
                load(this.propertyFile, 'basicMap');
                this.map=basicMap.map;
            end
        end

        function k=keys(this)
            k=this.map.keys;
        end

        function this=addAll(this, that, keys)
            if nargin<3
                it=that.map.keySet.iterator;
                while(it.hasNext)
                    name=it.next;
                    this.set(name, that.props{that.map.get(name)});
                end
            else
                N=length(keys);
                for i=1:N
                    if that.has(keys{i})
                        this.set(keys{i}, that.get(keys{i}));
                    end
                end
            end
        end

        function idx=indexOf(this, name, value)
            idx=-1;
            N=this.countIfMultipleElse0(name);
            if N==0 && this.has(name)
                v=this.get(name);
                if strcmp(v, value)
                    idx=1;
                end
            else
                for i=1:N
                    v=this.get([name '.' num2str(i)]);
                    if strcmp(v, value)
                        idx=i;
                        break;
                    end
                end
            end
        end

        function wasMissing=addIfMissing(this, name, value)
            idx=this.indexOf(name,value);
            if idx<=0
                wasMissing=true;
                this.add(name,value);
            else
                wasMissing=false;
            end
        end

        function wasMissing=putIfMising(this, name, value)
            if ~this.has(name)
                wasMissing=true;
                this.put(name,value);
            else
                wasMissing=false;
            end
        end

        function debug(this)
            k=this.map.keys;
            N=length(k);
            for i=1:N
                name=k{i};
                v=this.get(name);
                if ischar(v)
                    fprintf('%s=%s\n', name, v);
                elseif isnumeric(v)
                    fprintf('%s=%d\n', name, v);
                else
                    ss=class(v);
                    fprintf('%s=[%s object]\n', name,  ss);
                end
            end
        end

        function add(this, name, value)
            name2=this.increment(name);
            this.set(name2, value);
        end

        function setAll(this, name, values)
            this.remove(name);
            N=length(values);
            for i=1:N
                this.add(name,values{i});
            end
        end

        function c=getAll(this, name)
            N=this.countIfMultipleElse0(name);
            if N==0 && this.has(name)
                c{1}=this.get(name);
            else
                c=cell(1,N);
                for i=1:N
                    c{i}=this.get([name '.' num2str(i)]);
                end
            end
        end

        function name2=increment(this, name)
            N=this.countIfMultipleElse0(name)+1;
            if N==1 && this.has(name)
                N=N+1;
                value=this.get(name);
                this.remove(name);
                this.set([name '.1'], value);
            end
            name2=[name '.' num2str(N)];
            this.set([name '.count'], num2str(N));
        end

        function N=countIfMultipleElse0(this, name)
            N=0;
            if ischar(name)
                num=this.get([name '.count']);
                if ~isempty(num)
                    N=str2num(num);
                end
            end
        end

        function id=newId(this)
            id=num2str(this.getNumeric(Map.PROP_ID, 0)+1);
            this.set(Map.PROP_ID, id);
            this.set([id '.createdWhen'], char(datetime));
            this.save;
        end
    end
end


%% backup the current results before merging
neuron_bk = neuron.copy();
ctr = neuron.estCenter();
K = size(neuron.A,2);   %neuron numbers
ind_del = false(K, 1);
Coor = neuron.get_contours();
[img, col0, AA] = neuron.overlapA([], 0.1);  % overlap neurons
color_all = zeros(K,3);
col = col0;
for m=1:3
color_all(:,m) = mod(col,2);
col = floor(col/2);
end

%% UI CONTROL
IDs = [];
fig_merge = figure('position', [10, 300, 1400, 500], 'papersize', [14, 5]);
ax_all = axes('position', [0.005 0.1, 0.4, 0.8]);
axes(ax_all);
imagesc(img, 'parent', ax_all);  hold on;
axis equal off tight;
pb_select = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [0.05, 0.01, 0.1, 0.08], ...
    'string', 'add neurons', 'fontweight', 'bold', ...
    'fontsize', 16,     'callback', 'cnmfe_manual_merge_pick_neuron;');
pb_zoom = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [0.16, 0.01, 0.1, 0.08], ...
    'string', 'zoom out', 'fontweight', 'bold', ...
    'fontsize', 16,     'callback', 'axes(ax_all); cla; imagesc(img); axis tight;');
pb_finish = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [0.27, 0.01, 0.1, 0.08], ...
    'string', 'FINISH', 'fontweight', 'bold', ...
    'fontsize', 16,     'callback', 'neuron.delete(ind_del); close(gcf); ');

ax_selected = axes('position', [0.41, 0.6, 0.15, 0.35]);
ax_trace = axes('position', [0.6, 0.55, 0.35, 0.4]);
ax_merged = axes('position', [0.41, 0.05, 0.15, 0.35]);
ax_merged_trace = axes('position', [0.6, 0.05, 0.35, 0.4]);

%%
pb_remove = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [.41, 0.5, 0.08, 0.08], ...
    'string', 'remove', 'fontweight', 'bold', ...
    'fontsize', 16, ...
    'callback', 'cnmfe_manual_merge_remove_neuron;');
pb_merge = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [.49, 0.5, 0.08, 0.08], ...
    'string', 'merge', 'fontweight', 'bold', ...
    'fontsize', 16, ...
    'callback', 'cnmfe_manual_merge_merge_neurons;');
pb_reverse = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [.41, 0.42, 0.08, 0.08], ...
    'string', 'cancel', 'fontweight', 'bold', ...
    'fontsize', 16, ...
    'callback', 'cnmfe_manual_merge_cancel;');
pb_reverse = uicontrol(fig_merge, 'style', 'pushbutton', ...
    'unit', 'normalized',  'position', [.49, 0.42, 0.08, 0.08], ...
    'string', 'NEW', 'fontweight', 'bold', ...
    'fontsize', 16, ...
    'callback', 'IDs=[]; axes(ax_selected); cla; axes(ax_trace); cla; ');


function cvx_pushobj( dir, x )

global cvx___
try
    np = length(cvx___.problems);
    pstr = cvx___.problems(np);
catch
    cvx_throw( 'No CVX model is present.' );
end

%
% Check problem
%

if ~isinf( pstr.direction )
    if isnan( pstr.direction )
        cvx_throw( 'Objective functions cannot be added to sets.' );
    else
        cvx_throw( 'An objective has already been supplied for this problem.' );
    end
end

%
% Check direction
%

if ~ischar( dir ) || size( dir, 1 ) ~= 1,
    cvx_throw( 'The second argument must be a string.' );
end

%
% Check objective expression
%

persistent remap_min remap_max
if isempty( remap_max ),
    remap_min = cvx_remap( { { 'constant' } ; { 'l_convex' } ; { 'convex' } } );
    remap_max = cvx_remap( { { 'constant' } ; { 'l_concave' } ; { 'concave' } } );
end
if ~isa( x, 'cvx' ) && ~isnumeric( x ),
    cvx_throw( 'Cannot accept an objective of type ''%s''.', class( arg ) );
elseif ~isreal( x ),
    cvx_throw( 'Expressions in objective functions must be real.' );
elseif isempty( x ),
    warning( 'CVX:EmptyObjective', 'Empty objective.' );
end
cx = cvx_classify( x );
switch dir,
    case { 'minimize', 'minimise' },
        vx = remap_min( :, cx );
        dir = +1;
    case { 'maximize', 'maximise' },
        vx = remap_max( :, cx );
        dir = -1;
    otherwise,
        cvx_throw( 'Invalid objective type: %s', dir );
end
avx = all( vx, 2 );
if ~any( avx ),
    vx = any( vx, 1 );
    if all( vx ),
        cvx_throw( 'Cannot combine logarithmic and linear objectives.' );
    else
        cvx_dcp_error( type, 'unary', cvx_fastref( x, ~vx ) );
    end
end

%
% Store the objective
%

isgeo = avx(2) & ( ~avx(1) | pstr.gp );
if isgeo,
    x = log( x );
    dir = 2 * dir;
end
if np > 1,
    bx = cvx_sparsify( cvx_basis( x ), [], 'magnitude' );
    x = cvx( size( x ), bx );
end
if isgeo,
    x = exp( x );
end
pstr.objective = x;
pstr.direction = dir;
cp = pstr.checkpoint(4);
if cp > 1,
    x = find( any( cvx_basis( x ), 2 ), 2, 'first' );
    if any( x > 1 & x < cp ),
        pstr.checkpoint(4) = x(1+(x(1)==1)) - 1;
    end
end
cvx___.problems( end ) = pstr;

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


function unicycle_test ( )

%*****************************************************************************80
%
%% UNICYCLE_TEST tests the UNICYCLE library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 June 2012
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'UNICYCLE_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the UNICYCLE library.\n' );

  unicycle_test01 ( );
  unicycle_test02 ( );
  unicycle_test03 ( );
  unicycle_test04 ( );
  unicycle_test05 ( );
  unicycle_test06 ( );
  unicycle_test07 ( );
  unicycle_test08 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'UNICYCLE_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function out=imag(x)

precision=x(1).precision;
out_rval=cell(size(x));
out_ival=cell(size(x));

for ii=1:numel(x)
 [temp,out_rval{ii}]=getVals(x,ii);
 out_ival{ii}='0';
end % for ii=1:max(ex,
out=class(struct('rval',out_rval,...
                 'ival',out_ival,...
                 'precision',precision),'mp');


function [AuuCondensed,AuxCondensed,AxxCondensed] = OCP_Auu_Aux_Axx_Condensed(lambda,mu,u,x,z,p) %#codegen
    [AuuCondensed,AuxCondensed,AxxCondensed] = OCP_GEN_Auu_Aux_Axx_Condensed(lambda,mu,u,x,z,p);
end