% DROSPLOTCHIPDISTANCES Plot the accuracy figures appearing in the paper
% FORMAT
% DESC Plot the accuracy figures appearing in the paper
%
% COPYRIGHT : Antti Honkela, 2009

% SHEFFIELDML

tfnames = drosTF.names;
FONTSIZE = 8;
styles = {'bo-', 'rd--', 'm*--', 'gs--', 'k--'};
t = [20, 100, 250];

rankings = {};
for k=1:length(tfnames),
  tf = tfnames{k};
  nonmutarankings{k} = {indrank.(tf), [], corrrank.(tf)};
  if isfield(mutarank, tf),
    rankings{k} = {indrank.(tf), mutarank.(tf), corrrank.(tf)};
  else
    rankings{k} = nonmutarankings{k};
  end
end

clear accs;
clear pvals;
figure(1);
for k=1:length(tfnames),
  subplot(3, length(tfnames), k); %3*(k-1)+2);
  tf = tfnames{k};

  [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(...
      rankings{k}, ...
      chip_validation.(tf), t, styles, [], drosexp, drosinsitu);
  set(gca, 'FontSize', FONTSIZE);
  title(sprintf('Global ChIP: %s', tfnames{k}));
  xlabel('Top N to consider');
  if k==1,
    ylabel('Relative enrichment (%)');
  end
end

clear accs;
clear pvals;
for k=1:length(tfnames),
  subplot(3, length(tfnames), length(tfnames)+k);
  tf = tfnames{k};

  if isfield(mutant_validation, tf),
    [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(...
	nonmutarankings{k}, ...
	mutant_validation.(tf), t, styles, [], drosexp, drosinsitu);
    set(gca, 'FontSize', FONTSIZE);
    title(sprintf('Global knock-outs: %s', tfnames{k}));
    xlabel('Top N to consider');
    if k==1,
      ylabel('Relative enrichment (%)');
    end
  end
end

subplot(3, length(tfnames), 3*length(tfnames)-[1, 0]);
if exist('INCLUDE_TSNI') && INCLUDE_TSNI,
  bar(rand(5));
else
  bar(rand(length(rankings{1})));
end
hold on
plot(1:2, t(1:2), 'k--');

axis([-10 -9 -10 -9]);
set(gca, 'FontSize', FONTSIZE);
axis off
if exist('INCLUDE_TSNI') && INCLUDE_TSNI,
  legend('Single-target models', 'Multiple-target models', 'TSNI', ...
	 'Knock-outs', 'Correlation', 'Random', 'Location', 'North');
else
  legend('Single-target models', ... %'Multiple-target models', ...
	 'Knock-outs', 'Correlation', 'Random', 'Location', 'North');
end

set(gcf, 'PaperUnits', 'centimeters');
set(gcf, 'PaperSize', [20 20])
set(gcf, 'PaperPosition', [0 0 17.4 18])
hold off

clear accs;
clear pvals;
figure(2);
for k=1:length(tfnames),
  subplot(3, length(tfnames), k); %3*(k-1)+2);
  tf = tfnames{k};

  [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(...
      rankings{k}, ...
      chip_validation.(tf), t, styles, 1, drosexp, drosinsitu);
  set(gca, 'FontSize', FONTSIZE);
  title(sprintf('Focused ChIP: %s', tfnames{k}));
  xlabel('Top N to consider');
  if k==1,
    ylabel('Relative enrichment (%)');
  end
end

clear accs;
clear pvals;
for k=1:length(tfnames),
  subplot(3, length(tfnames), length(tfnames)+k);
  tf = tfnames{k};

  if isfield(mutant_validation, tf),
    [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(...
	nonmutarankings{k}, ...
	mutant_validation.(tf), t, styles, 1, drosexp, drosinsitu);
    set(gca, 'FontSize', FONTSIZE);
    title(sprintf('Focused knock-outs: %s', tfnames{k}));
    xlabel('Top N to consider');
    if k==1,
      ylabel('Relative enrichment (%)');
    end
  end
end

subplot(3, length(tfnames), 3*length(tfnames)-[1, 0]);
if exist('INCLUDE_TSNI') && INCLUDE_TSNI,
  bar(rand(5));
else
  bar(rand(length(rankings{1})));
end
hold on
plot(1:2, 1:2, 'k-.');
plot(1:2, 1:2, 'k--');

axis([-10 -9 -10 -9]);
set(gca, 'FontSize', FONTSIZE);
axis off
if exist('INCLUDE_TSNI') && INCLUDE_TSNI,
  legend('Single-target models', 'Multiple-target models', 'TSNI', ...
	 'Knock-outs', 'Correlation', 'Random', 'Location', 'North');
else
  legend('Single-target models', ... %'Multiple-target models', ...
	 'Knock-outs', 'Correlation', 'Random', 'Location', 'North');
end

set(gcf, 'PaperUnits', 'centimeters');
set(gcf, 'PaperSize', [20 20])
set(gcf, 'PaperPosition', [0 0 17.4 18])
hold off

% figure(3);
% tf = 'twi';

% clear accs;
% clear pvals;

% rankings = {indrank.(tf), ssrank.(tf)};

% subplot(2, 3, 1);
% [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(rankings, ...
%     chip_validation.(tf), t, styles, [], drosexp, drosinsitu);
% set(gca, 'FontSize', FONTSIZE);
% title(sprintf('Global ChIP: %s', tf));
% xlabel('Top N to consider');
% ylabel('Relative enrichment (%)');

% subplot(2, 3, 2);
% [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(rankings, ...
%     mutant_validation.(tf), t, styles, [], drosexp, drosinsitu);
% set(gca, 'FontSize', FONTSIZE);
% title(sprintf('Global knock-outs: %s', tf));
% xlabel('Top N to consider');
% %ylabel('Relative enrichment (%)');

% subplot(2, 3, 4);
% [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(rankings, ...
%     chip_validation.(tf), t, styles, 1, drosexp, drosinsitu);
% set(gca, 'FontSize', FONTSIZE);
% title(sprintf('Focused ChIP: %s', tf));
% xlabel('Top N to consider');
% ylabel('Relative enrichment (%)');

% subplot(2, 3, 5);
% [accs(:, :, k), pvals(:, :, k)] = drosPlotAccuracyBars(rankings, ...
%     mutant_validation.(tf), t, styles, 1, drosexp, drosinsitu);
% set(gca, 'FontSize', FONTSIZE);
% title(sprintf('Focused knock-outs: %s', tf));
% xlabel('Top N to consider');
% %ylabel('Relative enrichment (%)');

% subplot(2, 3, [3,6]);
% bar(rand(2));
% hold on
% plot(1:2, t(1:2), 'k--');
% plot(1:2, 1:2, 'k-.');

% axis([-10 -9 -10 -9]);
% set(gca, 'FontSize', FONTSIZE);
% axis off
% legend('n=12', 'n=7', ...
%        'Random', 'Filtered', 'Location', 'West');

% set(gcf, 'PaperUnits', 'centimeters');
% set(gcf, 'PaperSize', [20 20])
% set(gcf, 'PaperPosition', [0 0 9.65 9.65])
% %set(gcf, 'PaperSize', [20 20])
% %set(gcf, 'PaperPosition', [0 0 8.7 8.7])
% hold off


function result = substr(s, i, j)
%SUBSTR Extracts a substring using s(i:j) when last > 0, or else s(i:end+j).

    if j > 0
        result = s(i:j);
    else
        result = s(i:end+j);
    end
end


function msfun_khepera3(block)

% Copyright (C) 2013, Georgia Tech Research Corporation
% see the LICENSE file included with this software

%%
%% The setup method is used to set up the basic attributes of the
%% S-function such as ports, parameters, etc. Do not add any other
%% calls to the main body of the function.
%%
robot = [];

setup(block);

%% Function: setup ===================================================
%% Abstract:
%%   Set up the basic characteristics of the S-function block such as:
%%   - Input ports
%%   - Output ports
%%   - Dialog parameters
%%   - Options
%%
%%   Required         : Yes
%%   C-Mex counterpart: mdlInitializeSizes
%%
    function setup(block)

        % Register number of ports
        block.NumInputPorts  = 2;
        block.NumOutputPorts = 2;

        % Setup port properties to be inherited or dynamic
        % block.SetPreCompInpPortInfoToDynamic;
        % block.SetPreCompOutPortInfoToDynamic;
        block.SetPreCompPortInfoToDefaults;

        % Override input port properties
        block.InputPort(1).Dimensions        = 1;
        block.InputPort(1).DatatypeID  = 0;  % double
        block.InputPort(1).Complexity  = 'Real';
        block.InputPort(1).DirectFeedthrough = false;

        block.InputPort(2).Dimensions        = 1;
        block.InputPort(2).DatatypeID  = 0;  % double
        block.InputPort(2).Complexity  = 'Real';
        block.InputPort(2).DirectFeedthrough = false;

        block.InputPort(1).SamplingMode = 0;
        block.InputPort(2).SamplingMode = 0;

        % Override output port properties
        block.OutputPort(1).Dimensions       = 9;
        block.OutputPort(1).DatatypeID  = 0; % double
        block.OutputPort(1).Complexity  = 'Real';

        block.OutputPort(2).Dimensions       = 2;
        block.OutputPort(2).DatatypeID  = 0; % double
        block.OutputPort(2).Complexity  = 'Real';

        % Set up the states
        block.NumContStates = 0;
        block.NumDworks = 0;

        % Register parameters
        block.NumDialogPrms     = 3;
        block.DialogPrmsTunable = {'NonTunable', 'NonTunable', 'NonTunable'};

        % Register sample times
        %  [0 offset]            : Continuous sample time
        %  [positive_num offset] : Discrete sample time
        %
        %  [-1, 0]               : Inherited sample time
        %  [-2, 0]               : Variable sample time
        block.SampleTimes = [0.033 0];

        % Specify the block simStateCompliance. The allowed values are:
        %    'UnknownSimState', < The default setting; warn and assume DefaultSimState
        %    'DefaultSimState', < Same sim state as a built-in block
        %    'HasNoSimState',   < No sim state
        %    'CustomSimState',  < Has GetSimState and SetSimState methods
        %    'DisallowSimState' < Error out when saving or restoring the model sim state
        block.SetAccelRunOnTLC(false); % run block in interpreted mode even w/ Acceleration
        block.SimStateCompliance = 'DefaultSimState';

        %% -----------------------------------------------------------------
        %% The MATLAB S-function uses an internal registry for all
        %% block methods. You should register all relevant methods
        %% (optional and required) as illustrated below. You may choose
        %% any suitable name for the methods and implement these methods
        %% as local functions within the same file. See comments
        %% provided for each function for more information.
        %% -----------------------------------------------------------------

        block.RegBlockMethod('PostPropagationSetup',    @DoPostPropSetup);
        block.RegBlockMethod('InitializeConditions', @InitializeConditions);
        block.RegBlockMethod('Start', @Start);
        block.RegBlockMethod('Outputs', @Outputs);     % Required
        block.RegBlockMethod('Update', @Update);
        block.RegBlockMethod('Terminate', @Terminate); % Required

    end %end setup

%%
%% PostPropagationSetup:
%%   Functionality    : Setup work areas and state variables. Can
%%                      also register run-time methods here
%%   Required         : No
%%   C-Mex counterpart: mdlSetWorkWidths
%%
    function DoPostPropSetup(block)

    end

%%
%% InitializeConditions:
%%   Functionality    : Called at the start of simulation and if it is
%%                      present in an enabled subsystem configured to reset
%%                      states, it will be called when the enabled subsystem
%%                      restarts execution to reset the states.
%%   Required         : No
%%   C-MEX counterpart: mdlInitializeConditions
%%
    function InitializeConditions(block)

    end %end InitializeConditions

%%
%% Start:
%%   Functionality    : Called once at start of model execution. If you
%%                      have states that should be initialized once, this
%%                      is the place to do it.
%%   Required         : No
%%   C-MEX counterpart: mdlStart
%%
    function Start(block)

        x_0 = block.DialogPrm(1).Data;
        y_0 = block.DialogPrm(2).Data;
        theta_0 = block.DialogPrm(3).Data;

        customData = getSimulatorBlockUserData(bdroot(block.BlockHandle));
        simulator = customData('simulatorHandle');

        robot = simulator.world.add_robot('Khepera3', 'Supervisor', x_0, y_0, theta_0);

        % store info in custom data;
        customData = containers.Map('UniformValues', false);
        customData('robotHandle') = robot;
        set(block.BlockHandle, 'UserData', customData, 'UserDataPersistent', 'off');

    end %endfunction

%%
%% Outputs:
%%   Functionality    : Called to generate block outputs in
%%                      simulation step
%%   Required         : Yes
%%   C-MEX counterpart: mdlOutputs
%%
    function Outputs(block)

%         customData = get(block.BlockHandle, 'UserData');
%         robot = customData('robotHandle');

        block.OutputPort(1).Data = robot.ir_array.get_range();
        robot.encoders.ticks
        block.OutputPort(2).Data = [robot.encoders.ticks];

    end %end Outputs

%%
%% Update:
%%   Functionality    : Called to update discrete states
%%                      during simulation step
%%   Required         : No
%%   C-MEX counterpart: mdlUpdate
%%
    function Update(block)

%         customData = get(block.BlockHandle, 'UserData');
%         robot = customData('robotHandle');

        vel_r = block.InputPort(1).Data;
        vel_l = block.InputPort(2).Data;

        robot.set_wheel_speeds(vel_r,vel_l);

    end %end Update

%%
%% Terminate:
%%   Functionality    : Called at the end of simulation for cleanup
%%   Required         : Yes
%%   C-MEX counterpart: mdlTerminate
%%
    function Terminate(block)

    end %end Terminate

end


classdef opticheckval
    %OPTICHECKVAL Contains Static Methods for Checking Option Values

    methods(Static)

        function err = checkScalarSet(value,field,set)
            %Scalar in set
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isa(value,'double') || ~any(value==set))
                str = sprintf('\n');
                for i = 1:length(set)
                    str = sprintf('%s %g\n',str,set(i));
                end
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should a double scalar from one of the following supported values:\n%s',field,str);
            end
        end

        function err = checkScalar01(value,field)
            %Scalar 0 or 1
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || (value ~= 0 && value ~=1) || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be an integer scalar with the value 0 or 1',field);
            end
        end

        function err = checkVector01(value,field)
            %Vector 0 or 1
            err =[];
            if(~isnumeric(value) || any((value == 0 | value == 1) ~= 1) || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a vector with the values 0 or 1',field);
            end
        end

        function err = checkScalarGrtZ(value,field)
            %Scalar double > Zero
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || value <= 0 || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a double scalar greater than 0',field);
            end
        end

        function err = checkScalarIntGrtZ(value,field)
            %Scalar integer > zero
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || value < 1 || (round(value) ~= value) || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be an integer scalar greater than 0',field);
            end
        end

        function err = checkScalarNonNeg(value,field)
            %Scalar double >= Zero
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || value < 0 || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar greater or equal to 0',field);
            end
        end

        function err = checkScalarIntNonNeg(value,field)
            %Scalar integer >= zero
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || value < 0 || (round(value) ~= value) || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be an integer scalar greater than 0',field);
            end
        end

        function err = checkScalarDbl(value,field)
            %Scalar double
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar double',field);
            end
        end

        function err = checkScalarBoundLELE(value,field,lb,ub)
            %Scalar double lb <= value <= ub
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || value < lb || value > ub || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar double %g <= value <= %g',field,lb,ub);
            end
        end

        function err = checkScalarBoundLLE(value,field,lb,ub)
            %Scalar double lb < value <= ub
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || value <= lb || value > ub || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar double %g < value <= %g',field,lb,ub);
            end
        end

        function err = checkScalarBoundLEL(value,field,lb,ub)
            %Scalar double lb <= value < ub
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || value < lb || value >= ub || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar double %g <= value < %g',field,lb,ub);
            end
        end

        function err = checkScalarBoundLL(value,field,lb,ub)
            %Scalar double lb < value < ub
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || value <= lb || value >= ub || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar double %g < value < %g',field,lb,ub);
            end
        end

        function err = checkScalarIntBoundLEL(value,field,lb,ub)
            %Scalar integer lb <= value < ub
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || (round(value) ~= value) || value < lb || value >= ub || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar integer %g <= value < %g',field,lb,ub);
            end
        end

        function err = checkScalarIntBoundLELE(value,field,lb,ub)
            %Scalar integer lb <= value <= ub
            err = [];
            if(~isscalar(value) || ~isnumeric(value) || ~isreal(value) || (round(value) ~= value) || value < lb || value > ub || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a scalar integer %g <= value <= %g',field,lb,ub);
            end
        end

        function err = checkVectorIntGrtZ(value,field)
            %Vector of integers > 0
            err = [];
            if(~isnumeric(value) || any(value < 1) || any(round(value) ~= value) || ~any(isa(value,'double')))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be an integer vector with all elements greater than 0',field);
            end
        end

        function err = checkDualCol(value,field)
            %Double matrix with two columns
            err = [];
            if(~isnumeric(value) || ~isreal(value) || size(value,2) ~= 2 || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a double matrix with two columns',field);
            end
        end

        function err = checkDblVec(value,field)
            %Double vector (not sparse)
            err = [];
            if(~isnumeric(value) || ~isreal(value) || ~isa(value,'double') || (size(value,1) > 1 && size(value,2) > 1) || issparse(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a real double dense vector (1D)',field);
            end
        end

        function err = checkDblMat(value,field)
            %Double Matrix or Vector or Scalar
            err = [];
            if(~isnumeric(value) || ~isreal(value) || ~isa(value,'double'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a real double matrix or vector (2D or 1D)',field);
            end
        end

        function err = checkDblVecOrCell(value,field)
            %Double Vector or Cell Array of Double Vectors
            err = [];
            if(~iscell(value)), value = {value}; end
            for i = 1:length(value)
                val = value{i};
                if(~isnumeric(val) || ~isreal(val) || ~isa(val,'double') || (size(val,1) > 1 && size(val,2) > 1) || issparse(val))
                    err = MException('OPTI:SetFieldError','Parameter ''%s'' (cell %d) should be a real double dense vector or scalar (1D)',field,i);
                end
            end
        end

        function err = checkDblVecOrLogVec(value,field)
            %Double Vector or Logical Vectors
            err = [];
            if(islogical(value))
                if(size(value,1) > 1 && size(value,2) > 1)
                    err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a logical vector OR real double dense vector (1D)',field);
                end
            else
                if(~isnumeric(value) || ~isreal(value) || ~isa(value,'double') || (size(value,1) > 1 && size(value,2) > 1) || issparse(value))
                    err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a real double dense vector (1D) or logical vector',field);
                end
            end
        end

        function err = checkDblMatOrCell(value,field)
            %Double Matrix or Cell Array of Double Matrices
            err = [];
            if(~iscell(value)), value = {value}; end
            for i = 1:length(value)
                val = value{i};
                if(~isnumeric(val) || ~isreal(val) || ~isa(val,'double'))
                    err = MException('OPTI:SetFieldError','Parameter ''%s'' (cell %d) should be a real double matrix or vector (2D or 1D)',field,i);
                end
            end
        end

        function err = checkChar(value,field)
            %Char array
            err = [];
            if(~ischar(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a char array (string)',field);
            end
        end

        function err = checkNLOPTAlg(value,field)
            %Char array and valid NLOPT algorithm
            err = [];
            if(~ischar(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a char array (string)',field);
            else
                nloptSolver(value); %will throw an error if not found
            end
        end

        function err = checkOptiSolver(value,field)
            %Char array and valid OPTI solver
            err = [];
            if(~ischar(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a char array (string)',field);
            else
                rub = checkSolver(value,1); %#ok<NASGU>
            end
        end

        function err = checkYesNo(value,field)
            %Char array and yes or no
            err = opticheckval.checkValidString(value,field,{'yes','no'});
        end

        function err = checkYesCrashNo(value,field)
            %Char array and no, or yes will crash
            err = [];
            if(~ischar(value) || ~strcmpi(value,'no'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' must be set as no, otherwise OPTI may crash (sorry!).\n',field);
            end
        end

        function err = checkEnDis(value,field)
            %Char array and enable or disable
            err = opticheckval.checkValidString(value,field,{'enable','disable'});
        end

        function err = checkOnOff(value,field)
            %Char array and on or off
            err = opticheckval.checkValidString(value,field,{'on','off'});
        end

        function err = checkValidString(value,field,valid)
            %Char array and valid string
            err = [];
            if(~ischar(value) || all(strcmpi(value,valid)==0))
                str = sprintf('\n');
                for i = 1:length(valid)
                    str = sprintf('%s ''%s''\n',str,valid{i});
                end
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should a string from the following supported options:\n%s',field,str);
            end
        end

        function err = checkValidStringArr(value,field,valid)
            %Char array and of valid characters
            err = [];
            if(~ischar(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a char array (string)',field);
            else
                if(~iscell(valid)), valid = {valid}; end
                for i = 1:length(value)
                   if(~any(ismember(valid,value(i))))
                       str = sprintf('\n');
                        for j = 1:length(valid)
                            str = sprintf('%s ''%s''\n',str,valid{j});
                        end
                        err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a char array (string) with the following characters only:\n%s',field,str);
                        return;
                    end
                end
            end
        end

        function err = checkStruct(value,field)
            %Structure
            err = [];
            if(~isstruct(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a structure\n',field);
            end
        end

        function err = checkStructFields(value,field,reqfields)
            %Structure with required fields
            err = [];
            if(~isstruct(value))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a structure\n',field);
            else
                flds = fieldnames(value);
                if(~iscell(reqfields)), reqfields = {reqfields}; end
                for i = 1:length(reqfields)
                    if(~any(ismember(flds,reqfields{i})))
                        str = sprintf('\n');
                        for j = 1:length(reqfields)
                            str = sprintf('%s ''%s''\n',str,reqfields{j});
                        end
                        err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a structure with the following fields:\n%s',field,str);
                        return;
                    end
                end
            end
        end

        function err = checkFunHandle(value,field)
            %Function Handle
            err = [];
            if(~isa(value,'function_handle'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a function handle.\n\nFor existing m-file functions, pass as @function_name (not a string, using the ''@'' operator).\n',field);
            end
        end

        function err = checkNumorFHndl(value,field)
            %Function handle or numeric matrix
            err = [];
            if(isnumeric(value))
                if(~isreal(value) || ~isa(value,'double'))
                    err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a real, double, matrix/vector or function handle\n',field);
                end
            elseif(~isa(value,'function_handle'))
                err = MException('OPTI:SetFieldError','Parameter ''%s'' should be a function handle OR real, double, matrix\n',field);
            end
        end

    end

end


function data = spm_chi2_plot(action,arg1,arg2,arg3,arg4)
% Display a plot showing convergence of an optimization routine.
% FORMAT spm_chi2_plot('Init',title,xlabel,ylabel)
% Initialises the plot in the 'Interactive' window.
%
% FORMAT spm_chi2_plot('Set',value)
% Updates the plot.
%
% FORMAT spm_chi2_plot('Clear')
% Clears the 'Interactive' window.
%
%-----------------------------------------------------------------------
% @(#)spm_chi2_plot.m	1.2 John Ashburner 97/09/11

global pb_pointer pb_name ax
%-----------------------------------------------------------------------
if (nargin == 0)
	spm_chi2_plot('Init');
else
	% initialize
	%---------------------------------------------------------------
	if (strcmp(lower(action),'init'))
		if (nargin<4)
			arg3 = 'Iteration #';
			if (nargin<3)
				arg2 = 'Chi-squared';
				if (nargin<2)
					arg1 = 'Optimizing';
				end
			end
		end
		fg = spm_figure('FindWin','Interactive');
		if ~isempty(fg)
			pb_pointer = get(fg,'Pointer');
			pb_name    = get(fg,'Name');
			spm_chi2_plot('Clear');
			set(fg,'Pointer','watch');
			set(fg,'Name',pb_name);
			ax = axes('Position', [0.15 0.1 0.8 0.75],...
				'Box', 'on','Parent',fg);
			lab = get(ax,'Xlabel');
			set(lab,'string',arg3,'FontSize',10);
			lab = get(ax,'Ylabel');
			set(lab,'string',arg2,'FontSize',10);
			lab = get(ax,'Title');
			set(lab,'string',arg1);
			line('Xdata',[], 'Ydata',[],...
				'LineWidth',2,'Tag','Chi2Plot','Parent',ax);
			drawnow;
		end

	% reset
	%---------------------------------------------------------------
	elseif (strcmp(lower(action),'set'))
		if (nargin<2)
			arg1 = 0;
		end
		F = spm_figure('FindWin','Interactive');
		br = findobj(F,'Tag','Chi2Plot');
		if (~isempty(br))
			xd = get(br,'Xdata');
			yd = [get(br,'Ydata') arg1];
			xd = [xd (length(xd)+1)];
			set(br,'Ydata',yd,'Xdata',xd);
			drawnow;
		end

	% clear
	%---------------------------------------------------------------
	elseif (strcmp(lower(action),'clear'))
		fg = spm_figure('FindWin','Interactive');
		spm_figure('Clear',fg);
		set(fg,'Pointer',pb_pointer);
		set(fg,'Name',pb_name);
		drawnow;
	elseif (strcmp(lower(action),'data'))
		F = spm_figure('FindWin','Interactive');
		br = findobj(F,'Tag','Chi2Plot');
		if (~isempty(br))
			data = get(br,'Ydata');
		else
			data = [];
		end
	end
end


%% PRIME_BATCH_LOCAL uses the BATCH command to run the PRIME code locally.
%
%  Discussion:
%
%    The PRIME code is a function, so first we must write a script
%    called PRIME_SCRIPT that runs the function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 April 2010
%
%  Author:
%
%    John Burkardt
%
  clear

  fprintf ( 1, '\n' );
  fprintf ( 1, 'PRIME_BATCH_LOCAL:\n' );
  fprintf ( 1, '  Run PRIME_SCRIPT locally.\n' );
%
%  BATCH sends the script for execution.
%
  my_job = batch ( 'prime_script', ...
    'Configuration', 'local', ...
    'CaptureDiary', true, ...
    'FileDependencies', { 'prime_fun' }, ...
    'matlabpool', 4 );
%
%  WAIT pauses the MATLAB session til the job completes.
%
  wait ( my_job );
%
%  DIARY displays any messages printed during execution.
%
  diary ( my_job );
%
%  LOAD makes the script's workspace available.
%
%  total = total number of primes.
%
  load ( my_job );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Total number of primes = %d\n', total );
%
%  DESTROY cleans up data about the job we no longer need.
%
  destroy ( my_job );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'PRIME_BATCH_LOCAL:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );


function title = p11_title ( )

%*****************************************************************************80
%
%% P11_TITLE returns the title of problem P11.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, the title of the problem.
%
  title = 'Problem 11, Enright and Pryce #C1';

  return
end


function test_suite = test_regression1

%   Run specific demo, save values and compare the results to the expected.
%   Works for both xUnit Test Framework package by Steve Eddins and for
%   the built-in Unit Testing Framework (as of Matlab version 2013b).
%
%   See also
%     TEST_ALL, DEMO_REGRESSION1
%
% Copyright (c) 2011-2012 Ville Tolvanen
% Copyright (c) 2014 Tuomas Sivula

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

  % Check which package to use
  if exist('initTestSuite', 'file')
    initTestSuite_path = which('initTestSuite');
  else
    initTestSuite_path = '';
  end
  if ~isempty(initTestSuite_path) && ...
     exist([initTestSuite_path(1:end-15) 'runtests'], 'file')
    % xUnit package
    initTestSuite;
  else
    % Built-in package
    % Use all functions except the @setup
    tests = localfunctions;
    tests = tests(~cellfun(@(x)strcmp(func2str(x),'setup'),tests));
    test_suite = functiontests(tests);
  end
end

% -------------
%     Tests
% -------------

function testRunDemo(testCase)
  % Run the correspondin demo and save the values. Note this test has to
  % be run at lest once before the other test may succeed.
  rundemo(getName(), { ...
    'K', 'C', 'w', ...
    {'Eft_map', @(x)x(1:50)}, {'Varft_map', @(x)x(1:50)}, ...
    {'Eft_ia', @(x)x(1:50)}, {'Varft_ia', @(x)x(1:50)}, ...
    {'Eft_mc', @(x)x(1:50)}, {'Varft_mc', @(x)x(1:50)} })
end

function testCovarianceMatrices(testCase)
  % Test diagonal with 1e-7 tolerance (because of varying jitterSigma2)
  verifyVarsEqual(testCase, getName(), {'K','C'}, ...
    @(x)diag(x), 'AbsTol', 1e-7)
  % Test non-diagonal elements
  verifyVarsEqual(testCase, getName(), {'K','C'}, ...
    @(x)x(~eye(size(x))), 'AbsTol', eps)
end

function testOptimizedParameter(testCase)
  verifyVarsEqual(testCase, getName(), {'w'}, ...
    'RelTolElement', 0.05)
end

function testPredictedMeanVarianceGrid(testCase)
  verifyVarsEqual(testCase, getName(), ...
    {'Eft_map','Varft_map'}, ...
    'RelTolElement', 0.05, 'RelTolRange', 0.01)
end

function testPredictedMeanVarianceMC(testCase)
  verifyVarsEqual(testCase, getName(), {'Eft_mc'}, ...
    'RelTolElement', 0.1, 'RelTolRange', 0.02)
  verifyVarsEqual(testCase, getName(), {'Varft_mc'}, ...
    'AbsTol', 0.3)
end

function testPredictedMeanVarianceIA(testCase)
  verifyVarsEqual(testCase, getName(), ...
    {'Eft_ia','Varft_ia'}, ...
    'RelTolElement', 0.1, 'RelTolRange', 0.02)
end

% ------------------------
%     Helper functions
% ------------------------

function testCase = setup
  % Helper function to suply empty array into variable testCase as an
  % argument for each test function, if using xUnit package. Not to be
  % used with built-in test framework.
  testCase = [];
end

function name = getName
  % Helperfunction that returns the name of the demo, e.g. 'binomial1'.
  name = mfilename;
  name = name(6:end);
end


%% BASIC COLLISION EVENT (collisionEvent.m) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This class is designed as a child class to a generic "event", used to
% define the characteristics of a collision event.

% Author: James A. Douthwaite

classdef collisionEvent < interactionEvent

%% INITIALISE THE COLLISION EVENT SPECIFIC PARAMETERS
    properties
        % Collision unique properties
    end
%%  CLASS METHODS
    methods
        % CONSTRUCTION METHOD FOR THE COLLISION EVENT
        function obj = collisionEvent(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 collision object

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

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


function sFile = in_fopen_manscan(DataFile)
% IN_FOPEN_MANSCAN: Open a MANSCAN file (continuous recordings)
%
% USAGE:  sFile = in_fopen_manscan(DataFile)

% @=============================================================================
% This software is part of the Brainstorm software:
% http://neuroimage.usc.edu/brainstorm
%
% Copyright (c)2000-2013 Brainstorm by the University of Southern California
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2012

%% ===== READ HEADER =====
% Get text file (.mbi)
MbiFile = strrep(DataFile, '.mb2', '.mbi');
% If doesn't exist: error
if ~exist(MbiFile, 'file')
    ft_error('Cannot open file: missing text file .mbi');
end
% Initialize header
iEpoch = 1;
hdr.epoch(iEpoch).Comment = {};
hdr.epoch(iEpoch).Channel = [];
hdr.Events = [];
curBlock = '';
% Read file line by line
fid = fopen_or_error(MbiFile,'r');
while(1)
    % Reached the end of the file: exit the loop
    if feof(fid)
        break;
    end;
    % Read one line
    buf = fgetl(fid);
    if isempty(buf)
        curBlock = '';
        continue;
    end
    % Split line based on space characters
    splitBuf = str_split(buf, [0 9 32]);
    if isempty(splitBuf)
        continue;
    end
    % Current block
    if ~isempty(curBlock)
        switch curBlock
            case 'event'
                % Ignore MANSCAN auto events
                if any(strcmpi(evtProp, 'Channel'))
                    continue;
                end
                % New event
                iEvt = length(hdr.Events) + 1;
                % Read event name and epoch
                hdr.Events(iEvt).Name   = splitBuf{1};
                hdr.Events(iEvt).iEpoch = iEpoch;
                % Read each property
                for iProp = 2:length(evtProp)
                    if strcmpi(evtProp{iProp}, 'Channel')
                        hdr.Events(iEvt).Name = [hdr.Events(iEvt).Name '_' splitBuf{iProp}];
                    elseif strcmpi(evtType{iProp}, 'String')
                        hdr.Events(iEvt).(evtProp{iProp}) = splitBuf{iProp};
                    else
                        hdr.Events(iEvt).(evtProp{iProp}) = str2num(splitBuf{iProp});
                    end
                end

            case 'channel'
                % New channel
                iChan = length(hdr.epoch(iEpoch).Channel) + 1;
                % Read channel name
                hdr.epoch(iEpoch).Channel(iChan).Name = splitBuf{1};
                % Read each property
                for iProp = 2:length(chanProp)
                    if strcmpi(chanProp{iProp}, 'UnitDisplayToFile')
                        propValue = str2num(splitBuf{iProp});
                    else
                        propValue = splitBuf{iProp};
                    end
                    hdr.epoch(iEpoch).Channel(iChan).(chanProp{iProp}) = propValue;
                end
        end
        % Next line
        continue;
    end
    % Detect keyword
    switch lower(splitBuf{1})
        case 'datatypeid'
            iEpoch = iEpoch + 1;
            hdr.epoch(iEpoch).Comment = {};
            hdr.epoch(iEpoch).Channel = [];
        case 'comment'
            hdr.epoch(iEpoch).Comment{end+1} = strtrim(strrep(buf, splitBuf{1}, ''));
        case 'event'
            curBlock = 'event';
            evtProp = splitBuf;
            evtType = str_split(fgetl(fid), [0 9 32]);
        case 'channel'
            curBlock = 'channel';
            chanProp = splitBuf;
        case 'offsetdisplayexperiment'
            hdr.epoch(iEpoch).OffsetDisplay = str2num(splitBuf{2});
        case 'experimenttime'
            hdr.epoch(iEpoch).ExperimentTime = strtrim(strrep(buf, splitBuf{1}, ''));
        case 'worddatafile'
            % Read channel order
            hdr.epoch(iEpoch).ChannelOrder = str_split(fgetl(fid), [0 9 32]);
            % Read record info
            datainfo = str_split(fgetl(fid), [0 9 32]);
            hdr.epoch(iEpoch).StartData1 = str2num(datainfo{1});
            hdr.epoch(iEpoch).StartData2 = str2num(datainfo{2});
            hdr.epoch(iEpoch).Sweeps     = str2num(datainfo{3});
            hdr.epoch(iEpoch).BinFile    = datainfo{4};
    end
end

%% ===== CREATE BRAINSTORM SFILE STRUCTURE =====
% Initialize returned file structure
sFile = []; %db_template('sfile');
% Add information read from header
sFile.byteorder  = 'l';
sFile.filename   = DataFile;
sFile.format = 'EEG-MANSCAN';
sFile.device = 'MANSCAN';
sFile.channelmat = [];
% Comment: short filename
[tmp__, sFile.comment, tmp__] = fileparts(DataFile);
% Consider that the sampling rate of the file is the sampling rate of the first signal
sFile.prop.sfreq = 256;
sFile.prop.nAvg  = 1;
% No info on bad channels
sFile.channelflag = ones(length(hdr.epoch(iEpoch).ChannelOrder), 1);

%% ===== EPOCHS =====
if (length(hdr.epoch) <= 1)
    sFile.prop.samples = [0, hdr.epoch(1).Sweeps-1];
    sFile.prop.times   = sFile.prop.samples ./ sFile.prop.sfreq;
else
    % Build epochs structure
    for iEpoch = 1:length(hdr.epoch)
        sFile.epochs(iEpoch).label   = sprintf('Epoch #%02d', iEpoch);
        sFile.epochs(iEpoch).samples = [0, hdr.epoch(iEpoch).Sweeps-1];
        sFile.epochs(iEpoch).times   = sFile.epochs(iEpoch).samples ./ sFile.prop.sfreq;
        sFile.epochs(iEpoch).nAvg    = 1;
        sFile.epochs(iEpoch).select  = 1;
        sFile.epochs(iEpoch).bad         = 0;
        sFile.epochs(iEpoch).channelflag = [];

        % Check if all the epochs have the same channel list
        if (iEpoch > 1) && ~isequal(hdr.epoch(iEpoch).ChannelOrder, hdr.epoch(1).ChannelOrder)
            ft_error('Channel list must remain constant across epochs.');
        end
    end
    % Extract global min/max for time and samples indices
    sFile.prop.samples = [min([sFile.epochs.samples]), max([sFile.epochs.samples])];
    sFile.prop.times   = [min([sFile.epochs.times]),   max([sFile.epochs.times])];
end

%% ===== CREATE EMPTY CHANNEL FILE =====
nChannels = length(hdr.epoch(1).ChannelOrder);
ChannelMat.Comment = [sFile.device ' channels'];
%ChannelMat.Channel = repmat(db_template('channeldesc'), [1, nChannels]);
hdr.Gains = [];
% For each channel
for iChan = 1:nChannels
    % Find channel in description list
    chName = hdr.epoch(1).ChannelOrder{iChan};
    iDesc = find(strcmpi({hdr.epoch(1).Channel.Name}, chName));
    sDesc = hdr.epoch(1).Channel(iDesc);
    % Type
    if isfield(sDesc, 'IsEEG') && ~isempty(sDesc.IsEEG)
        if strcmpi(sDesc.IsEEG, 'Yes')
            ChannelMat.Channel(iChan).Type = 'EEG';
        else
            ChannelMat.Channel(iChan).Type = 'Misc';
        end
    elseif isfield(sDesc, 'IsEEG')
        ChannelMat.Channel(iChan).Type = 'EEG REF';
    else
        ChannelMat.Channel(iChan).Type = 'EEG';
    end
    % Create structure
    ChannelMat.Channel(iChan).Name    = chName;
    ChannelMat.Channel(iChan).Loc     = [0; 0; 0];
    ChannelMat.Channel(iChan).Orient  = [];
    ChannelMat.Channel(iChan).Weight  = 1;
    ChannelMat.Channel(iChan).Comment = '';
    % Check that this channel has a gain
    if isempty(hdr.epoch(1).Channel(iDesc).UnitDisplayToFile)
        hdr.Gains(iChan,1) = 1;
    else
        hdr.Gains(iChan,1) = hdr.epoch(1).Channel(iDesc).UnitDisplayToFile;
    end
end
% Return channel structure
sFile.channelmat = ChannelMat;

%% ===== FORMAT EVENTS =====
if ~isempty(hdr.Events)
    % Get all the epochs names
    uniqueEvt = unique({hdr.Events.Name});
    % Create one category for each event
    for iEvt = 1:length(uniqueEvt)
        % Get all the occurrences
        iOcc = find(strcmpi({hdr.Events.Name}, uniqueEvt{iEvt}));
        % Get the samples for all the occurrences
        sample   = [hdr.Events(iOcc).BeginSample];
        duration = [hdr.Events(iOcc).DurationSamples];
        % Extended event = duration is not 1 for all the markers
        if ~all(duration == 1)
            sample = [sample; sample + duration];
        end
        % Create event structure
        sFile.events(iEvt).label   = uniqueEvt{iEvt};
        sFile.events(iEvt).samples = sample;
        sFile.events(iEvt).times   = sample ./ sFile.prop.sfreq;
        sFile.events(iEvt).epochs  = [hdr.Events(iOcc).iEpoch];
        sFile.events(iEvt).select  = 1;
    end
end
% Save file header
sFile.header = hdr;

function splStr = str_split( str, delimiters, isCollapse )
% STR_SPLIT: Split string.
%
% USAGE:  str_split( str, delimiters, isCollapse=1 ) : delimiters in an array of char delimiters
%         str_split( str )             : default are file delimiters ('\' and '/')
%
% INPUT:
%    - str        : String to split
%    - delimiters : String that contains all the characters used to split, default = '/\'
%    - isCollapse : If 1, remove all the empty entries
%
% OUTPUT:
%    - splStr : cell-array of blocks found between separators

% @=============================================================================
% This software is part of the Brainstorm software:
% http://neuroimage.usc.edu/brainstorm
%
% Copyright (c)2000-2013 Brainstorm by the University of Southern California
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2008

% Default delimiters: file delimiters ('\', '/')
if (nargin < 3) || isempty(isCollapse)
    isCollapse = 1;
end
if (nargin < 2) || isempty(delimiters)
    delimiters = '/\';
end
% Empty input
if isempty(str)
    splStr = {};
    return
end

% Find all delimiters in string
iDelim = [];
for i=1:length(delimiters)
    iDelim = [iDelim strfind(str, delimiters(i))];
end
iDelim = unique(iDelim);

% If no delimiter: return the whole string
if isempty(iDelim)
    splStr = {str};
    return
end

% Allocates the split array
splStr = cell(1, length(iDelim)+1);

% First part (before first delimiter)
if (iDelim(1) ~= 1)
    iSplitStr = 1;
    splStr{iSplitStr} = str(1:iDelim(1)-1);
else
    iSplitStr = 0;
end

% Loop over all other delimiters
for i = 2:length(iDelim)
    if (isCollapse  && (iDelim(i) - iDelim(i-1) > 1)) || ...
       (~isCollapse && (iDelim(i) - iDelim(i-1) >= 1))
        iSplitStr = iSplitStr + 1;
        splStr{iSplitStr} = str(iDelim(i-1)+1:iDelim(i)-1);
    end
end

% Last part (after last delimiter)
if (iDelim(end) ~= length(str))
    iSplitStr = iSplitStr + 1;
    splStr{iSplitStr} = str(iDelim(end)+1:end);
end

% Remove all the unused entries
if (iSplitStr < length(splStr))
    splStr(iSplitStr+1:end) = [];
end


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

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

% Last Modified by GUIDE v2.5 10-Oct-2004 00:15:21

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

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

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

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

% Update handles structure
guidata(hObject, handles);

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

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

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

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[filename, pathname] = uigetfile({'*.bmp';'*.jpg';'*.gif';'*.*'}, 'Pick an Image File');
S = imread([pathname,filename]);
axes(handles.axes1);
imshow(S);

handles.S = S;
guidata(hObject, handles);

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

S = handles.S;
axes(handles.axes1);
img_crop = imcrop(S);
axes(handles.axes2);
imshow(img_crop);
handles.img_crop = img_crop;

axes(handles.axes7);
I=S;
Igray = rgb2gray(I);
Ibw = im2bw(Igray,graythresh(Igray));
Iedge = edge(uint8(Ibw));
se = strel('square',2);
Iedge2 = imdilate(Iedge, se);
Ifill= imfill(Iedge2,'holes');
[Ilabel num] = bwlabel(Ifill);
Iprops = regionprops(Ilabel);
Ibox = [Iprops.BoundingBox];
[y,x]=size(Ibox);%
x=x/4;%
Ibox = reshape(Ibox,[4 x]);%

handles.Ibox=Ibox;
imshow(I)

selected_col = get(handles.edit5,'string');
selected_col = evalin('base',selected_col);

selected_ln = get(handles.edit6,'string');
selected_ln = evalin('base',selected_ln);

for cnt = 1:selected_ln * selected_col
    rectangle('position',Ibox(:,cnt),'edgecolor','r');
end
guidata(hObject, handles);
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

img_crop = handles.img_crop;
imgGray = rgb2gray(img_crop);
bw = im2bw(img_crop,graythresh(imgGray));
axes(handles.axes3);
imshow(bw);
bw2 = charcrop(bw);
axes(handles.axes4);
imshow(bw2);
handles.bw2 = bw2;

guidata(hObject, handles);
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

bw2  = handles.bw2;
charvec = figresize(bw2);
axes(handles.axes5);
plotchar(charvec);

handles.charvec = charvec;
guidata(hObject, handles);
% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
net = handles.net ;
charvec = handles.charvec;
%selected_net = get(handles.edit1,'string');

result = sim(net,charvec);
[val, num] = max(result);
set(handles.edit2, 'string',num);
guidata(hObject, handles);

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

% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double
% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

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

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

% Hints: get(hObject,'String') returns contents of edit2 as text
%        str2double(get(hObject,'String')) returns contents of edit2 as a double

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

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

% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[filename, pathname] = uigetfile({'*.bmp';'*.jpg';'*.gif';'*.*'}, 'Pick an Image File');
trimg = imread([pathname,filename]);

selected_col = get(handles.edit5,'string');
selected_col = evalin('base',selected_col);

selected_ln = get(handles.edit6,'string');
selected_ln = evalin('base',selected_ln);

img = preprocess(trimg,selected_col,selected_ln);

for cnt = 1:selected_ln * selected_col;
    bw2 = charcrop(img{cnt});
    charvec = figresize(bw2);
    out(:,cnt) = charvec;
end
P = out(:,1:40);
T = [eye(10) eye(10) eye(10) eye(10)];
%Ptest = out(:,(selected_ln -2)* selected_col :selected_ln * selected_col);

%% Creating and training of the Neural Network
net = createnn(P,T);
handles.net = net;

%% Testing the Neural Network
%[a,b]=max(sim(net,Ptest));
%disp(b);
assignin('base','net',net);
guidata(hObject, handles);
function edit5_Callback(hObject, eventdata, handles)
% hObject    handle to edit5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit5 as text
%        str2double(get(hObject,'String')) returns contents of edit5 as a double

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

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

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

% Hints: get(hObject,'String') returns contents of edit6 as text
%        str2double(get(hObject,'String')) returns contents of edit6 as a double

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

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


function updateLayout(mtexFig)
% resize figure and reorder subfigs

if isempty(mtexFig.children), return;end

% store old units and perform all calculations in pixel
old_units = get(mtexFig.parent,'Units');
set(mtexFig.parent,'Units','pixels');

figSize = get(mtexFig.parent,'Position');
figSize = figSize(3:4) - sum(reshape(mtexFig.figTightInset,2,2),2).';

% compute layout
[mtexFig.ncols,mtexFig.nrows] = calcPartition(mtexFig,figSize);
[mtexFig.axisWidth,mtexFig.axisHeight] = calcAxesSize(mtexFig,figSize);

% align axes according to layout
for i = 1:length(mtexFig.children)

  % compute position in raster
  [col,row] = ind2sub([mtexFig.ncols mtexFig.nrows],i);

  aw = mtexFig.axisWidth + mtexFig.innerPlotSpacing + sum(mtexFig.tightInset([1,3]));
  ah = mtexFig.axisHeight + mtexFig.innerPlotSpacing + sum(mtexFig.tightInset([2,4]));

  axisPos = [mtexFig.figTightInset(1:2),0,0] + ...
  [1 + (col-1)*aw + mtexFig.tightInset(1),...
    1 + figSize(2) - row * ah ...
    + mtexFig.innerPlotSpacing + mtexFig.tightInset(2),...
    mtexFig.axisWidth,mtexFig.axisHeight];
  axisPos(axisPos<0)=0;
  set(mtexFig.children(i),'Units','Pixel','Position',axisPos);

  % position the colorbars
  if numel(mtexFig.cBarAxis) == numel(mtexFig.children)

    resizeColorBar(mtexFig.cBarAxis(i))

  end
end

if length(mtexFig.cBarAxis)==1 && i>1
  pos = get(mtexFig.cBarAxis,'position');

  if pos(4)>pos(3) %Vertical bar

    pos(4) = mtexFig.nrows * mtexFig.axisHeight + ...
      (mtexFig.nrows-1) * (mtexFig.innerPlotSpacing + sum(mtexFig.tightInset([2,4])));
    pos(2) = axisPos(2)+1;
    pos(1) = mtexFig.ncols*(mtexFig.axisWidth + mtexFig.innerPlotSpacing + ...
      sum(mtexFig.tightInset([1,3]))) + mtexFig.outerPlotSpacing;

  else  %Horizontal bar

    pos(3)=mtexFig.ncols*(mtexFig.axisWidth) + ...
      (mtexFig.ncols-1) * (mtexFig.innerPlotSpacing + sum(mtexFig.tightInset([1,3]))); %c_bar width
    pos(2) = mtexFig.outerPlotSpacing + 2*pos(4);%axisPos(2) - 2*pos(4);
    pos(1) = mtexFig.outerPlotSpacing + mtexFig.tightInset(1); %c_bar left

  end
  set(mtexFig.cBarAxis,'position',pos);
end

% revert figure units
set(mtexFig.parent,'Units',old_units);

  function resizeColorBar(cBar)

    pos = get(cBar,'position');
    if pos(4) > pos(3) % vertical
      set(cBar,'position',...
        [axisPos(1)+mtexFig.axisWidth+10,...
        axisPos(2)+1,...
        pos(3),mtexFig.axisHeight-1]);
    else % horizonal
      set(cBar,'position',...
        [axisPos(1),...
        axisPos(2)-mtexFig.tightInset(2) + mtexFig.cBarShift,...
        mtexFig.axisWidth-1,pos(4)]);
    end
  end

function testit

close all
mtexFig = mtexFigure;
mtexFig.gca
rectangle('position',[0,0,1,1])
axis equal  tight
title('asdsa')
xlabel('asd')
mtexFig.nextAxis;
rectangle('position',[0,0,1,1])
axis equal tight
xlabel('asd')

title('asdasd2')
axis(mtexFig.children(1),'off')
axis(mtexFig.children(2),'off')

mtexFig.drawNow

end

end


function move_vline(handle,DoneFcn)
%MOVE_VLINE implements horizontal movement of line.
%
%  Example:
%    plot(sin(0:0.1:pi))
%    h=vline(1);
%    move_vline(h)
%
%Note: This tools strictly requires MOVEX_TEXT, and isn't much good
%      without VLINE by Brandon Kuczenski, available at MATLAB Central.
%<http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=1039&objectType=file>

% Copyright 2004-2010 The MathWorks, Inc.

% This seems to lock the axes position
set(gcf,'Nextplot','Replace')
set(gcf,'DoubleBuffer','on')

h_ax=get(handle,'parent');
h_fig=get(h_ax,'parent');
setappdata(h_fig,'h_vline',handle)
if nargin<2, DoneFcn=[]; end
setappdata(h_fig,'DoneFcn',DoneFcn)
set(handle,'ButtonDownFcn',@DownFcn)

function DownFcn(hObject,eventdata,varargin)
set(gcf,'WindowButtonMotionFcn',@MoveFcn)
set(gcf,'WindowButtonUpFcn',@UpFcn)

function UpFcn(hObject,eventdata,varargin)
set(gcf,'WindowButtonMotionFcn',[])
DoneFcn=getappdata(hObject,'DoneFcn');
if isstr(DoneFcn)
  eval(DoneFcn)
elseif isa(DoneFcn,'function_handle')
  feval(DoneFcn)
end

function MoveFcn(hObject,eventdata,varargin)
h_vline=getappdata(hObject,'h_vline');
h_ax=get(h_vline,'parent');
cp = get(h_ax,'CurrentPoint');
xpos = cp(1);
x_range=get(h_ax,'xlim');
if xpos<x_range(1), xpos=x_range(1); end
if xpos>x_range(2), xpos=x_range(2); end
XData = get(h_vline,'XData');
XData(:)=xpos;
set(h_vline,'xdata',XData)
%update text
text_obj = findobj('Type','Text','Tag','cbar_text');
movex_text(text_obj,xpos)


function view_bvt(lab1,valueMap)
    % plots the maxz LTA values calculated
    % with maxzlta.m or other similar values as a color map
    % needs valueMap, gx, gy, stri
    %
    % define size of the plot etc.
    %

    report_this_filefun();
    ZG=ZmapGlobal.Data;
    ZG.someColor = 'k';

    % Find out if figure already exists
    %
    bmapc=findobj('Type','Figure','-and','Name','b-value cross-section');

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

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

    % Set up the Seismicity Map window Enviroment
    %
    if isempty(bmapc)
        bmapc = figure_w_normalized_uicontrolunits( ...
            'Name','b-value cross-section',...
            'NumberTitle','off', ...
            'backingstore','on',...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));
        % make menu bar

        lab1 = 'b-value';

        uicontrol('Units','normal',...
            'Position',[.0 .93 .08 .06],'String','Print ',...
            'callback',@callbackfun_001)

        uicontrol('Units','normal',...
            'Position',[.0 .75 .08 .06],'String','Close ',...
            'callback',@callbackfun_002)

        uicontrol('Units','normal',...
            'Position',[.0 .85 .08 .06],'String','Info ',...
            'callback',@callbackfun_003)

        uicontrol('Units','normal',...
            'Position',[.92 .80 .08 .05],'String','set ni',...
            'callback',@callbackfun_024)

        set_nia = uicontrol('style','edit','value',ni,'string',num2str(ni));
        set(set_nia, 'Callback', @callbackfun_025);
        set(set_nia,'units','norm','pos',[.94 .85 .06 .05],'min',10,'max',10000);
        nilabel = uicontrol('style','text','units','norm','pos',[.90 .85 .04 .05]);
        set(nilabel,'string','ni:','background',[.7 .7 .7]);

        ZG.tresh_km = max(r(:)); re4 = valueMap;
        nilabel2 = uicontrol('style','text','units','norm','pos',[.60 .92 .25 .06]);
        set(nilabel2,'string','MinRad (in km):','background',color_fbg);
        set_ni2 = uicontrol('style','edit','value',ZG.tresh_km,'string',num2str(ZG.tresh_km),...
            'background','y');
        set(set_ni2, 'Callback', @callbackfun_026)
        set(set_ni2,'units','norm','pos',[.85 .92 .08 .06],'min',0.01,'max',10000);

        uicontrol('Units','normal',...
            'Position',[.95 .93 .05 .05],'String','Go ',...
            'callback',@callbackfun_027)

        create_my_menu();

        colormap(jet)
    end   % This is the end of the figure setup

    % Now lets plot the color-map of the z-value
    %
    figure(bmapc);
    delete(findobj(bmapc,'Type','axes'));
    % delete(sizmap);
    reset(gca);
    cla
    set(gca,'NextPlot','replace')
    watchon;
    set(gca,'visible','off','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold',...
        'FontWeight','bold','LineWidth',1.5,...
        'Box','on','SortMethod','childorder')

    % set values greater ZG.tresh_km = nan
    %
    re4 = valueMap;
    re4(r > ZG.tresh_km) = nan;

    % plot image
    %
    orient portrait
    set(gcf,'PaperPosition', [2. 1 7.0 5.0])

    set(gca,'NextPlot','add')
    pco1 = pcolor(gx,gy,db12);
    axis([ min(gx) max(gx) min(gy) max(gy)])
    set(gca,'NextPlot','add');  shading flat; axis image

    hocm = hot;

    hocm(33,:) = [0.4 0.4 0.4];
    colormap(hocm)
    %brighten(0.7)
    caxis([-0.3 0.3])
    set(gca,'Color',[1.0 1.0 1.0]  )
    set(gca,'visible','on','FontSize',10,...
        'FontWeight','normal','LineWidth',1.5,...
        'Box','on','TickDir','out')
    set(gca,'NextPlot','add')

    % plot overlay
    %
    ploeqc = plot(newa(:,end),-newa(:,7),'.k');
    set(ploeqc,'Tag','eqc_plot','MarkerSize',ZG.ms6,'Marker',ty,'Color',ZG.someColor,'Visible','on')

    if exist('vox', 'var')
        plovo = plot(vox,voy,'*b');
        set(plovo,'MarkerSize',6,'LineWidth',1)
    end

    if exist('maix', 'var')
        pl = plot(maix,maiy,'*k');
        set(pl,'MarkerSize',12,'LineWidth',2)
    end

    if exist('maex', 'var')
        pl = plot(maex,-maey,'*k');
        set(pl,'MarkerSize',8,'LineWidth',2)
    end
    %overlay

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

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

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

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

    %% ui functions
    function create_my_menu()
        add_menu_divider();

    end

    %% callback functions

    function callbackfun_001(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        printdlg;
    end

    function callbackfun_002(mysrc,myevt)

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

        f1=gcf;
        f2=gpf;
        set(f1,'Visible','off');
        close(bmapc);
        if f1~=f2
            figure(map);
        end
    end

    function callbackfun_003(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        helpdlg(help('view_bvt'),'Help for view_bvt')
    end

    function callbackfun_004(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        view_bv2(lab1,valueMap);
    end

    function callbackfun_005(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        h1 = gca;
        ZG=ZmapGlobal.Data;
        ZG.hold_state=false;
        cicros(1);
    end

    function callbackfun_006(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        h1 = gca;
        ZG=ZmapGlobal.Data;
        ZG.hold_state=false;
        cicros(2);
    end

    function callbackfun_007(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        h1 = gca;
        ZG=ZmapGlobal.Data;
        ZG.hold_state=true;
        cicros(0);
    end

    function callbackfun_008(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        h1 = gca;
        ZG=ZmapGlobal.Data;
        ZG.hold_state=false;
        cicros(3);
    end

    function callbackfun_011(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1 ='b-value change';
        valueMap = dbperc;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_012(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='b-value';
        valueMap = old;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_013(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='b-value';
        valueMap = meg;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_014(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='a-value';
        valueMap = avm;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_015(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='error in b';
        valueMap = stanm;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_016(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='difference in b';
        valueMap = old-meg;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_017(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='Mmax';
        valueMap = maxm;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_018(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='dM ';
        valueMap = maxm-magco;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_019(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        def = {'6'};
        m = inputdlg('Magnitude of projected mainshock?','Input',1,def);
        m1 = m{:};
        m = str2num(m1);
        lab1 = 'Tr in yrs. (only smallest values shown)';
        valueMap =(teb - t0b)./(10.^(avm-m*old));
        view_bvt(lab1,valueMap);
    end

    function callbackfun_020(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='Probability';
        valueMap = pro;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_021(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='Mcomp';
        valueMap = old1;
        view_bv2(lab1,valueMap);
    end

    function callbackfun_022(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lab1='Radius in [km]';
        valueMap = r;
        view_bvt(lab1,valueMap);
    end

    function callbackfun_024(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        ni=str2num(set_nia.String);
        num2str(ni);
    end

    function callbackfun_025(mysrc,myevt)

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

    function callbackfun_026(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        ZG.tresh_km=str2double(set_ni2.String);
        set_ni2.String=num2str(ZG.tresh_km);
    end

    function callbackfun_027(mysrc,myevt)

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

        pause(1);
        re4 =valueMap;
        view_bv2(lab1,valueMap);
    end
end


classdef CatalogManager < handle
    % Manage a bunch of catalogs, filtering according to each catalog's associated filter function
    %
    % Usage:
    %   % associate the CatalogManager with a catalog
    %   cm = CatalogManger(someZmapCatalog)
    %
    %   % add a 'live' subsetter that will track the large (M>5) events
    %
    %   cm.AddSubset( 'big_events', @(c)c.Magnitude > 5)
    %
    %   % add another subsetter that will track shallow northen hemisphere events
    %
    %   cm.AddSubset( 'shallow_northern', @(c)c.Depth<5 & c.Latitude>0)
    %
    %
    %   % if you would like ot modify the filter, then use 'ChangeFilter'
    %   %     - using AddSubset would be an error, since it already exists
    %   cm.ChangeFilter(('shallow_northern', @(c)c.Depth<8 & c.Latitude>0)
    %
    %
    %   % to get the subcatalog, use 'GetSubset'
    %   shallow_northern_cat = cm.GetSubset('shallow_northern')
    %
    %   % change the catalog and get some new results...
    %   cm.RawCatalog = someOtherZmapCatalog
    %   shallow_northern_cat = cm.GetSubset('shallow_northern')
    %

    properties
        RawCatalog % this is the catalog that will be filtered
    end

    properties(Access=private)
        Catalogs        containers.Map
    end

    events
        RawCatalogChanged
    end

    methods
        function obj = CatalogManager(catalog)
            obj.RawCatalog = catalog;
        end

        function AddSubset(obj, Tag, filterFcn, ~)
            subcatalog.FilterFcn = filterFcn; % filterFcn returns a logical mask
            subcatalog.Filter = subcatalog.FilterFcn(obj.RawCatalog);
            if ismember(Tag, keys(obj.Catalogs))
                error('%s is already being used. Did you mean to CHANGE the filter instead?',Tag)
            end
            obj.Catalogs(Tag) = subcatalog;
        end

        function catalog = GetSubset(obj, Tag)
            subcatalog = obj.Catalogs(Tag);
            if numel(subcatalog.Filter) ~= obj.RawCatalog.Count
                subcatalog.Filter = subcatalog.FilterFcn(obj.RawCatalog);
            end
            catalog = obj.RawCatalog.subset(subcatalog.Filter);
        end

        function filt = GetFilter(obj, Tag, position)
            % position can be 'first' or 'last' or empty (empty returns all)
            subcatalog = obj.Catalogs(Tag);
            if numel(subcatalog.Filter) ~= obj.RawCatalog.Count
                subcatalog.Filter = subcatalog.FilterFcn(obj.RawCatalog);
            end
            filt = subcatalog.Filter;
            if exist('position','var')
            	p = find(filt, 1, position);
                filt = false(size(filt));
                filt(p) = true;
            end
        end

        function ChangeFilter(obj, Tag, filterFcn)
            subcatalog.FilterFcn = filterFcn; % filterFcn returns a logical mask
            subcatalog.Filter = subcatalog.FilterFcn(obj.RawCatalog);
            obj.Catalogs(Tag) = subcatalog;
        end

        function RemoveSubset(obj, Tag)
            remove(obj.Catalogs,Tag);
        end

        function RecalculateFilter(obj, Tag)
            subcatalog = obj.Catalogs(Tag);
            subcatalog.Filter = subcatalog.FilterFcn(obj.RawCatalog);
            obj.Catalogs(Tag) = subcatalog;
        end

        function recalculateAllFilters(obj)
            for key = keys(obj.Catalogs)
                obj.RecalculateFilter(key{1});
            end
        end

        function disp(obj)
            getIndentedSummary = @(ca,level) "     "+ strrep(summary(ca,level),newline,[newline, '       ']);
            disp('CatalogManger with:')
            disp('  RawCatalog:')
            disp(getIndentedSummary(obj.RawCatalog,'simple'));
            fprintf('\n\nWith Tagged entries:\n')
            for key = keys(obj.Catalogs)
                Tag = key{1};
                c = obj.GetSubset(Tag);
                entry = obj.Catalogs(Tag);
                fprintf("  %-10s : %s  yielding\n","'"+Tag+"'", func2str(entry.FilterFcn));
                disp(getIndentedSummary(c,'simple'));
                fprintf('\n\n');
            end
        end
    end
end


% add relevant paths
hodi = fileparts(which('zmap'));
path_list = [
    {hodi};
    fullfile(hodi, {'src';
    'help';
    'zmapwww';
    'importfilters';
    'resrc';
    });
    split(genpath(fullfile(hodi,'dem'))); %location for DEM data files
    fullfile(hodi, 'resrc', {'features';'sample';'focalmech'});
    fullfile(hodi, 'src',{'afterrate';
    'cgr_utils';
    'as_class';
    'declus';
    'pvals';
    'synthetic';
    'utils';
    'distance2curve';
    fullfile('system_dependent',computer)});
    fullfile(hodi,'src','cgr_utils',{'grids';'gui';'selections'});
    {fullfile(hodi, 'src', 'danijel')};
    fullfile(hodi, 'src', 'danijel', {'calc';
    'ex';
    'focal';
    'gui';
    'plot';
    'probfore'});
    {fullfile(hodi, 'src', 'jochen')};
    fullfile(hodi, 'src', 'jochen', {'auxfun';
    'ex';
    'plot';
    'seisvar';
    'stressinv'});
    fullfile(hodi, 'src', 'jochen', 'seisvar', 'calc');
    {fullfile(hodi, 'src', 'thomas')};
    fullfile(hodi, 'src', 'thomas', {'decluster';
    'etas';
    'slabanalysis';
    'seismicrates';
    });
    fullfile(hodi, 'src','thessa');
    fullfile(hodi, 'src', 'thomas', 'decluster', 'reasen');
    ];
addpath(path_list{:});


function spm_eeg_review(D,flag,inv)
% General review (display) of SPM meeg object
% FORMAT spm_eeg_review(D,flags,inv)
%
% INPUT:
% D      - meeg object
% flag   - switch to any of the displays (optional)
% inv    - which source reconstruction to display (when called from
% spm_eeg_inv_imag_api.m)
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Jean Daunizeau
% $Id: spm_eeg_review.m 7221 2017-11-16 14:25:37Z vladimir $

if nargin == 0
    [D, sts] = spm_select(1, 'mat$', 'Select M/EEG mat file');
    if ~sts, return; end
    D = spm_eeg_load(D);
end

%-- Initialize SPM figure
D.PSD.handles.hfig = spm_figure('GetWin','Graphics');
spm_clf(D.PSD.handles.hfig);
% Get default SPM graphics options --> revert back to defaults
D.PSD.SPMdefaults.col = get(D.PSD.handles.hfig,'colormap');
D.PSD.SPMdefaults.renderer = get(D.PSD.handles.hfig,'renderer');

%-- Create default userdata structure
try
    D.PSD.source.VIZU.current = inv;
end
[D] = PSD_initUD(D);
if ~strcmp(transformtype(D),'time') %
    D.PSD.type = 'epoched';
    D.PSD.trials.current = 1;
    D.PSD.VIZU.type = 2;
end

%-- Create figure uitabs
labels = {'EEG', 'MEG', 'MPLANAR', 'MCOMB', 'OTHER','info','source'};
callbacks = {'spm_eeg_review_callbacks(''visu'',''main'',''eeg'')',...
    'spm_eeg_review_callbacks(''visu'',''main'',''meg'')',...
    'spm_eeg_review_callbacks(''visu'',''main'',''megplanar'')',...
    'spm_eeg_review_callbacks(''visu'',''main'',''megcomb'')',...
    'spm_eeg_review_callbacks(''visu'',''main'',''other'')',...
    'spm_eeg_review_callbacks(''visu'',''main'',''info'')',...
    'spm_eeg_review_callbacks(''visu'',''main'',''source'')'};
try
    [h] = spm_uitab(D.PSD.handles.hfig,labels,callbacks,[],flag);
catch
    [h] = spm_uitab(D.PSD.handles.hfig,labels,callbacks,[],6);
end
D.PSD.handles.tabs = h;

% Add prepare and SAVE buttons
object.type = 'buttons';
object.list = 1;
D = spm_eeg_review_uis(D,object);
set(D.PSD.handles.BUTTONS.pop1,...
    'deletefcn',@back2defaults)

%-- Attach userdata to SPM graphics window
Dtmp = rmfield(D,'PSD');
D.PSD.D0 = Dtmp;
%CP, some how, removing and adding a field in the object doesn't work directly...
set(D.PSD.handles.hfig,...
    'units','normalized',...
    'color',[1 1 1],...
    'userdata',D);

try
    if ismac
        set(D.PSD.handles.hfig,'renderer','zbuffer');
    else
        set(D.PSD.handles.hfig,'renderer','OpenGL');
    end
catch
    set(D.PSD.handles.hfig,'renderer','OpenGL');
end

try
    switch flag
        case 1
            spm_eeg_review_callbacks('visu','main','eeg')
        case 2
            spm_eeg_review_callbacks('visu','main','meg')
        case 3
            spm_eeg_review_callbacks('visu','main','megplanar')
        case 4
            spm_eeg_review_callbacks('visu','main','megcomb')
        case 5
            spm_eeg_review_callbacks('visu','main','other')
        case 6
            spm_eeg_review_callbacks('visu','main','info')
        case 7
            spm_eeg_review_callbacks('visu','main','source')
    end
catch
    % Initilize display on 'info'
    spm_eeg_review_callbacks('visu','main','info')
end

%% Revert graphical properties of SPM figure back to normal
function back2defaults(e1,e2)
hf = spm_figure('FindWin','Graphics');
D = get(hf,'userdata');
try
    set(D.PSD.handles.hfig,'colormap',D.PSD.SPMdefaults.col);
    set(D.PSD.handles.hfig,'renderer',D.PSD.SPMdefaults.renderer);
end

%% initialization of the userdata structure
function [D] = PSD_initUD(D)
% This function initializes the userdata structure.

%-- Check spm_uitable capability (JAVA compatibility) --%
D.PSD.VIZU.uitable = spm_uitable;

%-- Initialize time window basic info --%
D.PSD.VIZU.xlim = [1,min([5e2,nsamples(D)])];
D.PSD.VIZU.info = 4; % show history
D.PSD.VIZU.fromTab = [];

%-- Initialize trials info --%
switch D.type

    %------ before epoching -----%

    case 'continuous'
        D.PSD.type = 'continuous';
        if ntrials(D) && ~isempty(events(D,1))
            Events = events(D);
            Nevents = length(Events);
            for i =1:Nevents
                if isempty(Events(i).duration)
                    Events(i).duration = 0;
                end
                if isempty(Events(i).value)
                    Events(i).value = '0';
                end
                if isempty(Events(i).type)
                    Events(i).type = '0';
                end
                if ~ischar(Events(i).value)
                    Events(i).value = num2str(Events(i).value);
                end
                if ~ischar(Events(i).type)
                    Events(i).type = num2str(Events(i).type);
                end
            end
            %D = events(D,1,Events);
        end
        D.PSD.VIZU.type = 1;

        %------ after epoching -----%

    case 'single'
        D.PSD.type = 'epoched';
        nTrials = D.ntrials;
        D.PSD.trials.TrLabels = cell(nTrials,1);
        bTrials = badtrials(D);
        for i = 1:nTrials
            if any(i==bTrials)
                str = ' (bad)';
            else
                str = ' (not bad)';
            end
            D.PSD.trials.TrLabels{i} = [...
                'Trial ',num2str(i),': ',char(conditions(D,i)) ,str];
        end
        D.PSD.trials.current = 1;
        D.PSD.VIZU.type = 1;
    case {'evoked','grandmean'}
        D.PSD.type = 'epoched';
        nTrials = D.ntrials;
        D.PSD.trials.TrLabels = cell(nTrials,1);
        for i = 1:nTrials
            D.PSD.trials.TrLabels{i} = [...
                'Trial ',num2str(i),' (average of ',...
                num2str(repl(D,i)),' events): ',...
                char(conditions(D,i))];
            D = events(D,i,[]);
        end
        D.PSD.trials.current = 1;
        D.PSD.VIZU.type = 1;
end

%-- Initialize channel info --%
nc = D.nchannels;
D.PSD.EEG.I  = indchantype(D,'EEG');
D.PSD.MEG.I  = sort(indchantype(D,'MEG'));
D.PSD.MEGPLANAR.I  = indchantype(D,'MEGPLANAR');
D.PSD.MEGCOMB.I  = indchantype(D,'MEGCOMB');
D.PSD.other.I = setdiff(1:nc, ...
    [D.PSD.EEG.I(:);D.PSD.MEG.I(:);D.PSD.MEGPLANAR.I(:);D.PSD.MEGCOMB.I(:)]);
%-- Get basic display variables (data range, offset,...)
if ~isempty(D.PSD.EEG.I)
    set(D.PSD.handles.hfig,'userdata',D);
    figure(D.PSD.handles.hfig)
    [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.EEG.I);
    D.PSD.EEG.VIZU = out;
else
    D.PSD.EEG.VIZU = [];
end
if ~isempty(D.PSD.MEG.I)
    set(D.PSD.handles.hfig,'userdata',D);
    figure(D.PSD.handles.hfig)
    [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.MEG.I);
    D.PSD.MEG.VIZU = out;
else
    D.PSD.MEG.VIZU = [];
end
if ~isempty(D.PSD.MEGPLANAR.I)
    set(D.PSD.handles.hfig,'userdata',D);
    figure(D.PSD.handles.hfig)
    [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.MEGPLANAR.I);
    D.PSD.MEGPLANAR.VIZU = out;
else
    D.PSD.MEGPLANAR.VIZU = [];
end
if ~isempty(D.PSD.MEGCOMB.I)
    set(D.PSD.handles.hfig,'userdata',D);
    figure(D.PSD.handles.hfig)
    [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.MEGCOMB.I);
    D.PSD.MEGCOMB.VIZU = out;
else
    D.PSD.MEGCOMB.VIZU = [];
end
if ~isempty(D.PSD.other.I)
    set(D.PSD.handles.hfig,'userdata',D);
    figure(D.PSD.handles.hfig)
    [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.other.I);
    D.PSD.other.VIZU = out;
else
    D.PSD.other.VIZU = [];
end

%-- Initialize inverse field info --%
if isfield(D,'inv') && ~isempty(D.inv)
    isInv = zeros(length(D.inv),1);
    for i=1:length(D.inv)
        if isfield(D.inv{i},'inverse') && ...
                isfield(D.inv{i}, 'method') && ...
                strcmp(D.inv{i}.method,'Imaging')
            isInv(i) = 1;
        end
    end
    isInv = find(isInv);
    Ninv = length(isInv);
    if Ninv>=1
        labels = cell(Ninv,1);
        callbacks = cell(Ninv,1);
        F  = zeros(Ninv,1);
        ID = zeros(Ninv,1);
        pst = [];
        for i=1:Ninv
            if ~isfield(D.inv{isInv(i)},'comment')
                D.inv{isInv(i)}.comment{1} = num2str(i);
            end
            if ~isfield(D.inv{isInv(i)},'date')
                D.inv{isInv(i)}.date(1,:) = '?';
                D.inv{isInv(i)}.date(2,:) = ' ';
            end
            if isfield(D.inv{isInv(i)}.inverse,'R2') ...
                    && isnan(D.inv{isInv(i)}.inverse.R2)
                D.inv{isInv(i)}.inverse.R2 = [];
            end
            if isfield(D.inv{isInv(i)}.inverse, 'ID')
                ID(i) = D.inv{isInv(i)}.inverse.ID;
            else
                ID(i) = nan;
            end
            labels{i} = [D.inv{isInv(i)}.comment{1}];
            callbacks{i} = ['spm_eeg_review_callbacks(''visu'',''inv'',',num2str(i),')'];
            try
                F(i) = D.inv{isInv(i)}.inverse.F;
                pst = [pst;D.inv{isInv(i)}.inverse.pst(:)];
            catch
                continue
            end
        end
        if isempty(pst)
            Ninv = 0;
        else
            pst = unique(pst);
        end
    end
else
    Ninv = 0;
end
if Ninv >= 1
    try
        if D.PSD.source.VIZU.current > Ninv
            D.PSD.source.VIZU.current = 1;
        end
    catch
        D.PSD.source.VIZU.current = 1;
    end
    D.PSD.source.VIZU.isInv = isInv;
    D.PSD.source.VIZU.pst = pst;
    D.PSD.source.VIZU.F = F;
    D.PSD.source.VIZU.ID = ID;
    D.PSD.source.VIZU.labels = labels;
    D.PSD.source.VIZU.callbacks = callbacks;
    D.PSD.source.VIZU.timeCourses = 1;
else
    D.PSD.source.VIZU.current = 0;
    D.PSD.source.VIZU.isInv = [];
    D.PSD.source.VIZU.pst = [];
    D.PSD.source.VIZU.F = [];
    D.PSD.source.VIZU.labels = [];
    D.PSD.source.VIZU.callbacks = [];
    D.PSD.source.VIZU.timeCourses = [];
end


function hsp= gridutil_getSubplots(chans)
%GRIDUTIL_GETSUBPLOTS - Returns the handles of the subplots of a grid plot
% that correspond to given channels
%
%Synposis:
% HSP= gridutil_getSubplots(<CHANS>)
%
%Input:
% CHANS: channel indices, [] means all, default []

if ~exist('chans','var'), chans=[]; end
if ~isempty(chans) && ~iscell(chans),
  chans= {chans};
end

if ~isempty(chans) && ischar(chans{1}) && ...
      strcmp(chans{1},'plus'),
  search_type= '^ERP';   % starting with 'ERP'
  chans= chans(2:end);
else
  search_type= '^ERP$';  % only the word 'ERP'
end

hc= get(gcf, 'children');
isERPplot= zeros(size(hc));

for ih= 1:length(hc),
  ud= get(hc(ih), 'userData');
  if isstruct(ud) && isfield(ud,'type') && ischar(ud.type) && ...
        ~isempty(regexp(ud.type,search_type))
    if isempty(chans) || ~isempty(util_chanind(ud.chan,chans)),
      isERPplot(ih)= 1;
    end
  end
end

hsp= hc(find(isERPplot))';


function nmt_addtopo(cfgplot,erp)
% configures and display topoplot on nutmegtrip viewer
% (not intended for use outside of nutmegtrip plot functions)

global st
figure(st.fig);
if(verLessThan('matlab','8.4')) % necessary to preserve colormap on functional image for Matlab R2014a and earlier
    for ii=1:3
        freezeColors(st.vols{1}.ax{ii}.ax);
    end
end

newway = true
if(newway)
    axes(st.nmt.gui.ax_ts(2,1));
    set(st.nmt.gui.ax_ts(2,1),'Visible');
    cfgplot.interactive = 'no';
    % cfgplot.colorbar = 'yes';  % how can we transfer colorbar over?
    cfgplot.comment = 'no';
    ft_topoplotER(cfgplot,erp);

    set(st.nmt.gui.ax_ts(2,1),'Units','pixels','Position',st.nmt.gui.ax_topo_pos);
    colormap(st.nmt.gui.ax_ts(2,1),jet)

else
    if(isfield(st.nmt.gui,'ax_topo'))
        delete(st.nmt.gui.ax_topo);
    end
    topofig = figure('Visible','off');
    cfgplot.interactive = 'no';
    % cfgplot.colorbar = 'yes';  % how can we transfer colorbar over?
    cfgplot.comment = 'no';
    ft_topoplotER(cfgplot,erp);

    st.nmt.gui.ax_topo = copyobj(gca,st.fig);
    delete(topofig);

    set(st.nmt.gui.ax_topo,'Units','pixels','Position',st.nmt.gui.ax_topo_pos);
    colormap(st.nmt.gui.ax_topo,jet)
end
end


function [H, H_cross]= stimutil_cueArrows(dirs, varargin)

props= {'cross'         0       '!DOUBLE[1]'
       };
props_drawArrow= stimutil_drawArrow;
all_props= opt_catProps(props, props_drawArrow);

if nargin==0,
  H= all_props;
  return
end

opt= opt_proplistToStruct(varargin{:});
opt= opt_setDefaults(opt, props);
opt_checkProplist(opt, all_props);

for dd= 1:length(dirs),
  if dd<length(dirs),
    h_tmp= stimutil_drawArrow(dirs{dd}, opt, 'cross',0);
  else
    h_tmp= stimutil_drawArrow(dirs{dd}, opt);
  end
  H(dd)= h_tmp.arrow;
end

if opt.cross,
  H_cross= h_tmp.cross;
else
  H_cross= [];
end

set([H H_cross], 'Visible','off');


function tagS = MR_image_module_tags_subset
%"MR_image_module_tags_subset"
%   Return a subset of the tags specified in C.7.3.1 in PS3.3
%   of the 2006 DICOM specification required for distinguishing MR series'.
%
%   Tags are returned in a struct array with 3 fields:
%
%   Tag: String containing hex DICOM tag of a field.
%  Type: String describing type of field, with 5 options:
%         '1' Field must exist, data must exist and be valid.
%         '2' Field must exist, data can exist and be valid, or be NULL.
%         '3' Field is optional, if the field exists data can exist and be
%             valid or be NULL.
%         '1C' Field must exist under certain conditions and contain valid
%             data.
%         '2C' Field must exist under certain conditions and can contain
%             valid data or be NULL.
%Children: For sequences, a tagS with the same format as this struct array.
%
%AI 11/20/2020
%
%Usage:
%   tagS = MR_image_module_tags_subset
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

%Initialize the tagS structure.
tagS = struct('tag', {}, 'tagdec', {}, 'type', {}, 'children', {});

%Create an empty tagS template for sequence creation.
template = tagS;

%Add tags based on PS3.3 attribute lists.

%Modality
tagS(end+1) = struct('tag', '00080060', 'tagdec', 524384, 'type', '1', 'children', []);

% Acquisition Time
tagS(end+1) = struct('tag', '00080032', 'tagdec', 524338, 'type', '3', 'children', []);

% b-value for MR scans
tagS(end+1) = struct('tag', '00431039', 'tagdec', 4395065, 'type', '4', 'children', []); % GE
tagS(end+1) = struct('tag', '00189087', 'tagdec', 1609863, 'type', '4', 'children', []); % Philips
tagS(end+1) = struct('tag', '0019100C', 'tagdec', 1642508, 'type', '4', 'children', []); % SIEMENS

% Temporal position ID
tagS(end+1) = struct('tag', '00200100', 'tagdec', 2097408, 'type', '3', 'children', []);

%Trigger time
tagS(end+1) = struct('tag', '00181060', 'tagdec', 1577056, 'type', '2C', 'children', []);

%Number of slices (for GE data)
tagS(end+1) = struct('tag', '0021104F', 'tagdec', 2166863, 'type', '3', 'children', []);

%Instance number
tagS(end+1) = struct('tag', '00200013', 'tagdec', 2097171, 'type', '1', 'children', []);

%Manufacturer
tagS(end+1) = struct('tag', '00080070', 'tagdec', 524400, 'type', '2', 'children', []);


%%train network config
param.caffe_path=fullfile(fileparts(pwd),'matcaffe');
param.solver_netfile=fullfile(fileparts(pwd),'model','solver_PQAN_image.prototxt');
param.fintune_model=fullfile(fileparts(pwd),'pretrain_model','googlenet_bn.caffemodel');
param.test_net_file=fullfile(fileparts(pwd),'model','test_PQAN_image.prototxt');
param.test_batch_size=32;
param.result_save_file='result.txt';
param.save_model_file='ilIDS_VID_model';
param.save_model_name='PQAN_322_iter';
param.test_interval=500;
param.train_maxiter=15000;
param.data_path=fullfile(fileparts(pwd),'generate_data');
param.traindata_filename='train_data_iLID';
param.testdata_filename='test_data_iLID';
param.use_data_split_index=1;
param.data_split_num=1;
param.train_person_num=150;
param.use_gpu=1;
param.gpu_id=0;
%%
for split_index=param.use_data_split_index:param.data_split_num
    if ~exist(strcat(param.save_model_file,num2str(split_index)),'file')
        mkdir(strcat(param.save_model_file,num2str(split_index)));
    end
    load(strcat(param.data_path,param.traindata_filename,num2str(split_index),'/train_data.mat'));
    %% find caffe
    cur_path=pwd;
    cd(param.caffe_path);
    addpath(genpath(param.caffe_path))
    caffe.reset_all;
    caffe.init_log(fullfile(cur_path,'log'));
    addpath(param.caffe_path);
    if param.use_gpu
        caffe.set_mode_gpu;
    else
        caffe.set_mode_cpu;
    end
    cd(cur_path);
    caffe_solver=caffe.get_solver(param.solver_netfile,param.gpu_id);
    net=caffe.get_net(param.test_net_file,'test');
    caffe_solver.use_caffemodel(param.fintune_model);
    input_data_shape=caffe_solver.nets{1}.blobs('data').shape;
    batch_size=input_data_shape(4);
    batch_data=zeros(input_data_shape,'single');
    batch_label=zeros(1,1,1,batch_size,'single');
    batch_sim=ones(1,1,1,1,'single');
    %
    batch_score=ones(1,1,3,batch_size,'single');
    %
    train_x_axis=[];
    train_y_axis=[];
    iter=0;
    while iter<param.train_maxiter
        [batch_data,batch_label]=get_train_minibatch(param,batch_data,batch_label,batch_size,train_data_cam1,train_data_cam2,label_train_cam1,label_train_cam2);
        caffe_solver.nets{1}.blobs('data').set_data(batch_data);
        caffe_solver.nets{1}.blobs('label').set_data(batch_label);
        caffe_solver.nets{1}.blobs('sim').set_data(batch_sim);
        caffe_solver.step(1);
        iter = caffe_solver.iter;
        if mod(iter,10)==0
            soft_loss=caffe_solver.nets{1}.blobs('loss3/loss').get_data;
            acc=caffe_solver.nets{1}.blobs('loss3/top-1').get_data;
            loss=caffe_solver.nets{1}.blobs('triplet_loss').get_data;
            loss1=caffe_solver.nets{1}.blobs('loss1/loss').get_data;
            loss2=caffe_solver.nets{1}.blobs('loss2/loss').get_data;
            contrastive_loss=caffe_solver.nets{1}.blobs('contrastive_loss').get_data;
            train_x_axis=[train_x_axis,iter];
            train_y_axis=[train_y_axis,soft_loss];
            plot(train_x_axis,train_y_axis);
            drawnow;
            fprintf('iter= %d ,softmaxloss= %f ,tripletloss= %f,contrastive_loss=%f.loss1=%f  loss2=%f\n',iter,soft_loss,loss,contrastive_loss,loss1,loss2);
            if soft_loss+loss+contrastive_loss+loss1+loss2 > 80
                fprintf('stop');
            end
        end
        % test in the training stage
        if iter>10000 && mod(iter,param.test_interval)==0
            caffe_solver.nets{1}.save(strcat(param.save_model_file,num2str(split_index),'/',param.save_model_name,'_',num2str(iter),'.caffemodel'));
            net.copy_from(strcat(param.save_model_file,num2str(split_index),'/',param.save_model_name,'_',num2str(iter),'.caffemodel'));
            net.blobs('data').reshape([224 224 3 param.test_batch_size]);
            load(strcat(param.data_path,param.testdata_filename,num2str(split_index),'/test_data.mat'));
            test_script;
        end
        if iter>9900 && mod(iter,100)==0
            caffe_solver.nets{1}.save(strcat(param.save_model_file,num2str(split_index),'/',param.save_model_name,'_',num2str(iter),'.caffemodel'));
        end
    end
%     test_network;
end