function results = OTB_DEEP_settings(seq, res_path, bSaveImage, parameters)

close all

s_frames = seq.s_frames;

% Feature specific parameters
hog_params.cell_size = 4;
hog_params.compressed_dim = 10;

% grayscale_params.colorspace='gray';
% grayscale_params.cell_size = 1;

cn_params.tablename = 'CNnorm';
cn_params.useForGray = false;
cn_params.cell_size = 4;
cn_params.compressed_dim = 3;

ic_params.tablename = 'intensityChannelNorm6';
ic_params.useForColor = false;
ic_params.cell_size = 4;
ic_params.compressed_dim = 3;

cnn_params.nn_name = 'imagenet-vgg-m-2048.mat'; % Name of the network
cnn_params.output_layer = [3 14];               % Which layers to use
cnn_params.downsample_factor = [2 1];           % How much to downsample each output layer
cnn_params.compressed_dim = [16 64];            % Compressed dimensionality of each output layer
cnn_params.input_size_mode = 'adaptive';        % How to choose the sample size
cnn_params.input_size_scale = 1;                % Extra scale factor of the input samples to the network (1 is no scaling)

% Which features to include
params.t_features = {
    struct('getFeature',@get_cnn_layers, 'fparams',cnn_params),...
    ...struct('getFeature',@get_colorspace, 'fparams',grayscale_params),...
    struct('getFeature',@get_fhog,'fparams',hog_params),...
    struct('getFeature',@get_table_feature, 'fparams',cn_params),...
    struct('getFeature',@get_table_feature, 'fparams',ic_params),...
};

% Global feature parameters1s
params.t_global.normalize_power = 2;    % Lp normalization with this p
params.t_global.normalize_size = true;  % Also normalize with respect to the spatial size of the feature
params.t_global.normalize_dim = true;   % Also normalize with respect to the dimensionality of the feature

% Image sample parameters
params.search_area_shape = 'square';    % The shape of the samples
params.search_area_scale = 4.0;         % The scaling of the target size to get the search area
params.min_image_sample_size = 200^2;   % Minimum area of image samples
params.max_image_sample_size = 250^2;   % Maximum area of image samples

% Detection parameters
params.refinement_iterations = 1;       % Number of iterations used to refine the resulting position in a frame
params.newton_iterations = 5;           % The number of Newton iterations used for optimizing the detection score
params.clamp_position = false;          % Clamp the target position to be inside the image

% Learning parameters
params.output_sigma_factor = 1/12;		% Label function sigma
params.learning_rate = 0.012;	 	 	% Learning rate
params.nSamples = 50;                   % Maximum number of stored training samples
params.sample_replace_strategy = 'lowest_prior';    % Which sample to replace when the memory is full
params.lt_size = 0;                     % The size of the long-term memory (where all samples have equal weight)
params.train_gap = 5;                   % The number of intermediate frames with no training (0 corresponds to training every frame)
params.skip_after_frame = 1;            % After which frame number the sparse update scheme should start (1 is directly)
params.use_detection_sample = true;     % Use the sample that was extracted at the detection stage also for learning

% Factorized convolution parameters
params.use_projection_matrix = true;    % Use projection matrix, i.e. use the factorized convolution formulation
params.update_projection_matrix = true; % Whether the projection matrix should be optimized or not
params.proj_init_method = 'pca';        % Method for initializing the projection matrix
params.projection_reg = 2e-7;	 	 	% Regularization paremeter of the projection matrix

% Generative sample space model parameters
params.use_sample_merge = true;                 % Use the generative sample space model to merge samples
params.sample_update_criteria = 'Merge';        % Strategy for updating the samples
params.weight_update_criteria = 'WeightedAdd';  % Strategy for updating the distance matrix
params.neglect_higher_frequency = false;        % Neglect hiigher frequency components in the distance comparison for speed

% Conjugate Gradient parameters
params.CG_iter = 5;                     % The number of Conjugate Gradient iterations in each update after the first frame
params.init_CG_iter = 10*20;            % The total number of Conjugate Gradient iterations used in the first frame
params.init_GN_iter = 10;               % The number of Gauss-Newton iterations used in the first frame (only if the projection matrix is updated)
params.CG_use_FR = false;               % Use the Fletcher-Reeves (true) or Polak-Ribiere (false) formula in the Conjugate Gradient
params.CG_standard_alpha = true;        % Use the standard formula for computing the step length in Conjugate Gradient
params.CG_forgetting_rate = 75;	 	 	% Forgetting rate of the last conjugate direction
params.precond_data_param = 0.7;	 	% Weight of the data term in the preconditioner
params.precond_reg_param = 0.1;	 	% Weight of the regularization term in the preconditioner
params.precond_proj_param = 30;	 	 	% Weight of the projection matrix part in the preconditioner

% Regularization window parameters
params.use_reg_window = true;           % Use spatial regularization or not
params.reg_window_min = 1e-4;			% The minimum value of the regularization window
params.reg_window_edge = 10e-3;         % The impact of the spatial regularization
params.reg_window_power = 2;            % The degree of the polynomial to use (e.g. 2 is a quadratic window)
params.reg_sparsity_threshold = 0.12;   % A relative threshold of which DFT coefficients that should be set to zero

% Interpolation parameters
params.interpolation_method = 'bicubic';    % The kind of interpolation kernel
params.interpolation_bicubic_a = -0.75;     % The parameter for the bicubic interpolation kernel
params.interpolation_centering = true;      % Center the kernel at the feature sample
params.interpolation_windowing = false;     % Do additional windowing on the Fourier coefficients of the kernel

% Scale parameters for the translation model
% Only used if: params.use_scale_filter = false
params.number_of_scales = 7;            % Number of scales to run the detector
params.scale_step = 1.01;               % The scale factor

% Scale filter parameters
% Only used if: params.use_scale_filter = true
params.use_scale_filter = false;            % Use the fDSST scale filter or not (for speed)
% params.scale_sigma_factor = 1/16;         % Scale label function sigma
% params.scale_learning_rate = 0.025;       % Scale filter learning rate
% params.number_of_scales_filter = 17;    % Number of scales
% params.number_of_interp_scales = 33;    % Number of interpolated scales
% params.scale_model_factor = 1.0;        % Scaling of the scale model
% params.scale_step_filter = 1.02;        % The scale factor for the scale filter
% params.scale_model_max_area = 32*16;    % Maximume area for the scale sample patch
% params.scale_feature = 'HOG4';          % Features for the scale filter (only HOG4 supported)
% params.s_num_compressed_dim = 'MAX';    % Number of compressed feature dimensions in the scale filter
% params.lambda = 1e-2;                   % Scale filter regularization
% params.do_poly_interp = true;           % Do 2nd order polynomial interpolation to obtain more accurate scale

% Other parameters
params.visualization = 0;               % Visualiza tracking and detection scores
params.debug = 0;                       % Do full debug visualization

% Initialize
params.init_sz = [seq.init_rect(1,4), seq.init_rect(1,3)];
params.init_pos = [seq.init_rect(1,2), seq.init_rect(1,1)] + (params.init_sz - 1)/2;
params.s_frames = s_frames;

% Run tracker
results = tracker(params);


function rx = mrRx(vol,ref,varargin)
%
% rx = mrRx([vol],[referenceVol],[options]):
%
% A GUI to create, edit, and save 4 x 4 transformations to apply
% to volume matrices. Can be used to coregister a volume to a
% reference volume, evaluate motion and motion correction, and
% perform motion correction.
%
% vol: a 2D or 3D matrix (4D support may come later).
%
% referenceVol: Another volume, which is not transformed,
% to which the first volume may be compared.
%
% The reference volume need not be the same size as the
% transformed volume. But, it will be assumed they're at
% the same resolution, unless the 'volRes' or 'refRes' options
% are applied.
%
% Both vol and referenceVol can be supplied as strings specifying
% paths to volume files. Can load volumes in any of the formats
% supported by loadVolume (type help loadVolume for a list). This
% includes vAnatomy .dat, analyze .img, I-files, DICOM, and others.
%
% If invoked without input arguments, just opens the control
% window, from which transformed and reference volumes
% can be loaded with dialogs.
%
% Returns rx,a struct with info about the UI state, similar to a view.
% The key field in rx is rx.xform, which specifies a 4x4 affine
% transformation matrix to transform coordinates in the rx to coordinates
% in the volume. That is:
%   volCoords = rx.xform * rxCoords;
% though these transformations can be properly accessed with the functions
% rx2vol and vol2rx.
%
% Options:
% rxRes, [1 x 3 matrix]: specify the size of voxels in the prescription, in
%                 mm, as a 1x3 vector.
% volRes, [1 x 3 matrix]: specify the size of voxels in the prescribed volume,
%                  in mm, as a 1x3 vector.
% refRes, [1 x 3 matrix]: specify the size of voxels in the reference volume,
%                  in mm, as a 1x3 vector.
% rxDims, [1 x 3 matrix]: specify the dims (# of voxels -- rows cols slices)
%                  for the prescription.
% rxSizeMM, [1 x 3 matrix]: specify the total size of the prescription in mm.
%                   This is overridden if rxDims is specified.
%
% Note these parameters can be used to specify vol
% and ref as being at different resolutions, and the
% prescription at a third resolution.
%
% 02/17/05 ras.
if notDefined('vol')
    vol = [];
elseif ischar(vol)
    [vol volVoxelSize] = loadVolume(vol); %,'reorient');
	varargin = [varargin {'volRes' volVoxelSize}];
end

if notDefined('ref')
    ref = [];
elseif ischar(ref)
    ref = loadVolume(ref); %,'reorient');
end

% initialize the rx struct
rx = rxInit(vol, ref, varargin);

% open the main control figure:
rx = rxOpenControlFig(rx);

if ~isempty(vol)
    rx = rxOpenInterpFig(rx);
end

if ~isempty(ref)
    rx = rxOpenRefFig(rx);
end

% add rx as user data in control fig
set(rx.ui.controlFig,'UserData',rx);

rxRefresh(rx,1);

return


%
% Score a MotorProgram
%   log-probability score as in Equation 1 in the main text
%
% Input
%  M: motor program
%  libclass: object of type LibraryClass
%
%  By default, it includes all components of the log-score.
%  To choose only specific components, you can use this syntax:
%    'token',true,'type',true,'image',true,'stat',true
%
%     For the token, type, and image model respectively set to true or
%       false. 'stat' is only needed for alphabet model, which is not
%       included here and should not be used.
%
%  Output
%   score : score
%   out : struct that breaks down the score by component
%
function [score,out] = scoreMP(M,libclass,varargin)

    % should we include type and/or token-level variables?
    assert(isa(libclass,'Library'));
    n = length(varargin);
    if mod(n,2)~=0
       error('the number of optional arguments must be even');
    end

    defaultinc = (n == 0 || (n==2 && strcmp(varargin{1},'strokes')));
    inc_stat = false;
    if defaultinc
        inc_image = true;
        inc_token = true;
        inc_type = true;
    else % specified in the arguments
        inc_image = nan;
        inc_token = nan;
        inc_type = nan;
    end
    list_sid = 1:M.ns;
    for i=1:2:n-1
       switch varargin{i}
           case 'strokes'
               list_sid = varargin{i+1};
               assert(isnumeric(list_sid));
           case 'token'
               inc_token = varargin{i+1};
               assert(islogical(inc_token));
           case 'type'
               inc_type = varargin{i+1};
               assert(islogical(inc_type));
           case 'image'
               inc_image = varargin{i+1};
               assert(islogical(inc_image));
           case 'stat'
               inc_stat = varargin{i+1};
               assert(islogical(inc_stat));
           otherwise
               error('invalid input parameters to scoreMP');
       end
    end

    % check that we have specified all the terms to include/exclude
    if ~defaultinc
        if any(isnan([inc_image inc_token inc_type]))
           error('score terms not fully specified');
        end
    end
    PM = M.parameters;
    out = struct;

    % check that we have relations instantiated
    if inc_token || inc_type
        assert(M.has_relations(list_sid));
    end

    % type-level score for number of strokes
    if inc_type
        out.number = CPD.score_number(libclass,M.ns);
    end

    out.S = cell(M.ns,1);
    for i=list_sid
       MS = M.S{i};
       out.S{i} = struct;

       % type-level scores
       if inc_type
           out.S{i}.sequence = CPD.score_sequence(libclass,M.ns,MS.ids);
           out.S{i}.scales_type = CPD.score_invscale_type(libclass,MS.invscales_type,MS.ids);
           out.S{i}.relation = CPD.score_relation_type(libclass,MS.R);
           if ~isempty(MS.shapes_type)
              out.S{i}.shape_type = CPD.score_shape_type(libclass,MS.shapes_type,MS.ids);
           end
       end

       % token-level scores
       if inc_token
           if isempty(MS.shapes_type)
               out.S{i}.shape_marginalize = CPD.score_shape_marginalize(libclass,MS.shapes_token,MS.ids);
           else
               out.S{i}.shape_token = CPD.score_shape_token(libclass,MS.shapes_token,MS.shapes_type);
           end
           out.S{i}.scales_token = CPD.score_invscale_token(libclass,MS.invscales_token,MS.invscales_type);
           out.S{i}.position = CPD.score_position(libclass,MS.pos_token,MS.R,M.S(1:i-1));
           if strcmp(MS.R.type,'mid')
               if isempty(MS.R.eval_spot_type)
                   out.S{i}.relation_token = CPD.score_relation_token_approx_marginalize(libclass,MS.R.eval_spot_token);
               else
                   out.S{i}.relation_token = CPD.score_relation_token(libclass,MS.R.eval_spot_token,MS.R.eval_spot_type);
               end
           end
       end

    end

    % token-level image variables
    if inc_token
        out.image_blur = CPD.score_image_blur(M.blur_sigma,PM);
        out.image_noise = CPD.score_image_noise(M.epsilon,PM);
        out.A = CPD.score_affine(libclass,M.A);
    end

    % include the stat penalty term
    if inc_stat
        error('This term should not be used in the score.');
        out.stat = CPD.score_stat(libclass,M);
    end

    % score the image
    if inc_image
        out.image = CPD.score_image(M.I,M.pimg);
    end

    score = sumfields(out);
    if isnan(score)
       assert(false);
    end
end

function total = sumfields(S)
%
% Add up all the scalar, numeric fields
% in a structure S. Recursively call
% on cell arrays of fields
%
    if isempty(S)
       total = 0;
       return
    end
    assert(isstruct(S));
    total = 0;
    fds = fieldnames(S);
    for i=1:length(fds)
       field = S.(fds{i});
       if ~isempty(field)

          if isnumeric(field) % if number
              total = total + sum(field(:));

          elseif iscell(field) % if cell, call recursively
              for j=1:length(field)
                total = total + sumfields(field{j});
              end

          else
              error('invalid field type');
          end

       end
    end
end


function newdata=struct2jdata(data,varargin)
%
% newdata=struct2jdata(data,opt,...)
%
% convert a JData object (in the form of a struct array) into an array
%
% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
%
% input:
%      data: a struct array. If data contains JData keywords in the first
%            level children, these fields are parsed and regrouped into a
%            data object (arrays, trees, graphs etc) based on JData
%            specification. The JData keywords are
%               "_ArrayType_", "_ArraySize_", "_ArrayData_"
%               "_ArrayIsSparse_", "_ArrayIsComplex_"
%      opt: (optional) a list of 'Param',value pairs for additional options
%           The supported options include
%               'Recursive', if set to 1, will apply the conversion to
%                            every child; 0 to disable
%
% output:
%      newdata: the covnerted data if the input data does contain a JData
%               structure; otherwise, the same as the input.
%
% examples:
%      obj=struct('_ArrayType_','double','_ArraySize_',[2 3],
%                 '_ArrayIsSparse_',1 ,'_ArrayData_',null);
%      ubjdata=struct2jdata(obj);
%
% license:
%     BSD License, see LICENSE_BSD.txt files for details
%
% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%

fn=fieldnames(data);
newdata=data;
len=length(data);
if(jsonopt('Recursive',0,varargin{:})==1)
  for i=1:length(fn) % depth-first
    for j=1:len
        if(isstruct(getfield(data(j),fn{i})))
            newdata(j)=setfield(newdata(j),fn{i},jstruct2array(getfield(data(j),fn{i})));
        end
    end
  end
end
if strncmpi('x0x5F_ArrayType_',fn,16) && strncmpi('x0x5F_ArrayData_',fn,16)
  newdata=cell(len,1);
  for j=1:len
    ndata=cast(data(j).x0x5F_ArrayData_,data(j).x0x5F_ArrayType_);
    iscpx=0;
    if strncmpi('x0x5F_ArrayIsComplex_',fn,21)
        if(data(j).x0x5F_ArrayIsComplex_)
           iscpx=1;
        end
    end
    if strncmpi('x0x5F_ArrayIsSparse_',fn,20)
        if(data(j).x0x5F_ArrayIsSparse_)
            if strncmpi('x0x5F_ArraySize_',fn,16)
                dim=double(data(j).x0x5F_ArraySize_);
                if(iscpx && size(ndata,2)==4-any(dim==1))
                    ndata(:,end-1)=complex(ndata(:,end-1),ndata(:,end));
                end
                if isempty(ndata)
                    % All-zeros sparse
                    ndata=sparse(dim(1),prod(dim(2:end)));
                elseif dim(1)==1
                    % Sparse row vector
                    ndata=sparse(1,ndata(:,1),ndata(:,2),dim(1),prod(dim(2:end)));
                elseif dim(2)==1
                    % Sparse column vector
                    ndata=sparse(ndata(:,1),1,ndata(:,2),dim(1),prod(dim(2:end)));
                else
                    % Generic sparse array.
                    ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3),dim(1),prod(dim(2:end)));
                end
            else
                if(iscpx && size(ndata,2)==4)
                    ndata(:,3)=complex(ndata(:,3),ndata(:,4));
                end
                ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3));
            end
        end
    elseif strncmpi('x0x5F_ArraySize_',fn,16)
        if(iscpx && size(ndata,2)==2)
             ndata=complex(ndata(:,1),ndata(:,2));
        end
        ndata=reshape(ndata(:),data(j).x0x5F_ArraySize_);
    end
    newdata{j}=ndata;
  end
  if(len==1)
      newdata=newdata{1};
  end
end


function [TrainData, TestData, TrainLabel, TestLabel] = createData_CDPLSA()

    % load source domain 1
    A = csvread('CD_PLSA/data/Train1.data');
    TrainX1 = spconvert(A);
    C = textread('CD_PLSA/data/Train1.label');
    TrainY1 = C';
    % load source domain 2
    A = csvread('CD_PLSA/data/Train2.data');
    TrainX2 = spconvert(A);
    C = textread('CD_PLSA/data/Train2.label');
    TrainY2 = C';
    % load source domain 3
    A = csvread('CD_PLSA/data/Train3.data');
    TrainX3 = spconvert(A);
    C = textread('CD_PLSA/data/Train3.label');
    TrainY3 = C';

    % load target domain
    A = csvread('CD_PLSA/data/Test.data');
    TestX = spconvert(A);
    C = textread('CD_PLSA/data/Test.label');
    TestY = C';

    TrainData{1,1} = TrainX1;
    TrainLabel{1,1} = TrainY1;
    TrainData{1,2} = TrainX2;
    TrainLabel{1,2} = TrainY2;
    TrainData{1,3} = TrainX3;
    TrainLabel{1,3} = TrainY3;
    TestData{1,1} = TestX;
    TestLabel{1,1} = TestY;
    save inputData.mat TrainData TrainLabel TestData TestLabel
    clear TrainX1 TrainX2 TrainX3 TrainY1 TrainY2 TrainY3 TestX TestY
end


function obj = updateSurfc(obj, dataIndex)

    if strcmpi(obj.State.Plot(dataIndex).Class, 'surface')
        surfaceIndex = dataIndex;
        updateSurfOnly(obj, surfaceIndex)
    elseif strcmpi(obj.State.Plot(dataIndex).Class, 'contour')
        contourIndex = dataIndex;
        updateContourOnly(obj, contourIndex)
    end

end

function updateContourOnly(obj, contourIndex)

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

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

    %-AXIS DATA STRUCTURE-%
    axisData = get(obj.State.Plot(contourIndex).AssociatedAxis);

    %-CONTOUR DATA STRUCTURE- %
    contourData = get(obj.State.Plot(contourIndex).Handle);
    surfData = get(obj.State.Plot(contourIndex-1).Handle);
    figureData = get(obj.State.Figure.Handle);

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

    %-associate scene-%
    obj.data{contourIndex}.scene = sprintf('scene%d', xsource);

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

    %-scatter3d type for contour projection-%
    obj.data{contourIndex}.type = 'scatter3d';
    obj.data{contourIndex}.mode = 'lines';

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

    %-get colormap-%
    cMap = figureData.Colormap;
    fac = 1/(length(cMap)-1);
    colorScale = {};

    for c = 1: length(cMap)
        colorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))};
    end

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

    %-get plot data-%
    contourMatrix = contourData.ContourMatrix;

    xData = [];
    yData = [];
    zData = [];
    cData = [];

    zmin = axisData.ZLim(1);
    len = size(contourMatrix, 2);
    n = 1;

    while (n < len)

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

        %-get plot data-%
        m = contourMatrix(2, n);
        zlevel = contourMatrix(1, n);

        xData = [xData, contourMatrix(1, n+1:n+m), NaN];
        yData = [yData, contourMatrix(2, n+1:n+m), NaN];
        zData = [zData, zmin * ones(1, m), NaN];

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

        %-get edge color-%
        if isnumeric(contourData.LineColor)
            cData = sprintf('rgb(%f,%f,%f)', 255*contourData.LineColor);

        elseif strcmpi(contourData.LineColor, 'interp')
            cData = zData;
            obj.data{contourIndex}.line.colorscale = colorScale;

        elseif strcmpi(contourData.LineColor, 'flat')
            [err, r] = min(abs(surfData.ZData - zlevel));
            [~, c] = min(err);
            r = r(c);

            cData = [cData, surfData.ZData(r, c) * ones(1, m), NaN];
            obj.data{contourIndex}.line.colorscale = colorScale;

        elseif strcmpi(contourData.LineColor, 'none')
            cData = 'rgba(0,0,0,0)';

        end

        n = n + m + 1;

    end

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

    %-set data on scatter3d-%
    obj.data{contourIndex}.x = xData;
    obj.data{contourIndex}.y = yData;
    obj.data{contourIndex}.z = zData;

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

    %-set edge color-%
    obj.data{contourIndex}.line.color = cData;

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

    %-line style-%

    obj.data{contourIndex}.line.width = 2*contourData.LineWidth;

    switch contourData.LineStyle
        case '-'
            obj.data{contourIndex}.line.dash = 'solid';
        case '--'
            obj.data{contourIndex}.line.dash = 'dash';
        case '-.'
            obj.data{contourIndex}.line.dash = 'dashdot';
        case ':'
            obj.data{contourIndex}.line.dash = 'dot';
    end

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

    %-surface name-%
    obj.data{contourIndex}.name = contourData.DisplayName;

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

    %-surface showscale-%
    obj.data{contourIndex}.showscale = false;

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

    %-surface visible-%
    obj.data{contourIndex}.visible = strcmp(contourData.Visible,'on');

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

function updateSurfOnly(obj, surfaceIndex)

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

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

    %-SURFACE DATA STRUCTURE- %
    meshData = get(obj.State.Plot(surfaceIndex).Handle);
    figureData = get(obj.State.Figure.Handle);

    %-AXIS STRUCTURE-%
    axisData = get(ancestor(meshData.Parent,'axes'));

    %-SCENE DATA-%
    eval( sprintf('scene = obj.layout.scene%d;', xsource) );

    %-GET CONTOUR INDEX-%
    obj.PlotOptions.nPlots = obj.PlotOptions.nPlots + 1;
    contourIndex = obj.PlotOptions.nPlots;
    obj.PlotOptions.contourIndex(surfaceIndex) = contourIndex;

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

    %-associate scene-%
    obj.data{surfaceIndex}.scene = sprintf('scene%d', xsource);
    obj.data{contourIndex}.scene = sprintf('scene%d', xsource);

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

    %-surface type for face color-%
    obj.data{surfaceIndex}.type = 'surface';

    %-scatter3d type for contour mesh lines-%
    obj.data{contourIndex}.type = 'scatter3d';
    obj.data{contourIndex}.mode = 'lines';

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

    %-get plot data-%
    xData = meshData.XData;
    yData = meshData.YData;
    zData = meshData.ZData;

    if isvector(xData)
        [xData, yData] = meshgrid(xData, yData);
    end

    %-reformat data to mesh-%
    xDataSurface = xData;
    yDataSurface = yData;
    zDataSurface = zData;

    xDataContourDir1 = [xDataSurface; NaN(1, size(xDataSurface, 2))];
    yDataContourDir1 = [yDataSurface; NaN(1, size(yDataSurface, 2))];
    zDataContourDir1 = [zDataSurface; NaN(1, size(zDataSurface, 2))];

    xDataContourDir2 = xDataContourDir1(1:end-1,:)';
    yDataContourDir2 = yDataContourDir1(1:end-1,:)';
    zDataContourDir2 = zDataContourDir1(1:end-1,:)';

    xDataContourDir2 = [xDataContourDir2; NaN(1, size(xDataContourDir2, 2))];
    yDataContourDir2 = [yDataContourDir2; NaN(1, size(yDataContourDir2, 2))];
    zDataContourDir2 = [zDataContourDir2; NaN(1, size(zDataContourDir2, 2))];

    xDataContour = [xDataContourDir1(:); xDataContourDir2(:)];
    yDataContour = [yDataContourDir1(:); yDataContourDir2(:)];
    zDataContour = [zDataContourDir1(:); zDataContourDir2(:)];

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

    %-set data on surface-%
    obj.data{surfaceIndex}.x = xDataSurface;
    obj.data{surfaceIndex}.y = yDataSurface;
    obj.data{surfaceIndex}.z = zDataSurface;

    %- setting grid mesh by default -%
    % x-direction
    xData = xData(1, :);
    obj.data{surfaceIndex}.contours.x.start = xData(1);
    obj.data{surfaceIndex}.contours.x.end = xData(end);
    obj.data{surfaceIndex}.contours.x.size = mean(diff(xData));
    obj.data{surfaceIndex}.contours.x.show = true;

    % y-direction
    yData = yData(:, 1);
    obj.data{surfaceIndex}.contours.y.start = yData(1);
    obj.data{surfaceIndex}.contours.y.end = yData(end);
    obj.data{surfaceIndex}.contours.y.size = mean(diff(yData));;
    obj.data{surfaceIndex}.contours.y.show = true;

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

    %-set data on scatter3d-%
    obj.data{contourIndex}.x = xDataContour(:);
    obj.data{contourIndex}.y = yDataContour(:);
    obj.data{contourIndex}.z = zDataContour(:);

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

    %-COLORING-%

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

    %-get colormap-%
    cMap = figureData.Colormap;
    fac = 1/(length(cMap)-1);
    colorScale = {};

    for c = 1: length(cMap)
        colorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))};
    end

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

    %-get edge color-%
    if isnumeric(meshData.EdgeColor)
        cDataContour = sprintf('rgb(%f,%f,%f)', 255*meshData.EdgeColor);

    elseif strcmpi(meshData.EdgeColor, 'interp')
        cDataContour = zDataContour(:);
        obj.data{contourIndex}.line.colorscale = colorScale;
        obj.data{surfaceIndex}.contours.x.colorscale = cDataContour;
        obj.data{surfaceIndex}.contours.y.colorscale = cDataContour;

        obj.data{surfaceIndex}.contours.x.show = false;
        obj.data{surfaceIndex}.contours.y.show = false;

    elseif strcmpi(meshData.EdgeColor, 'flat')
        cData = meshData.CData;

        if size(cData, 3) ~= 1
            cMap = unique( reshape(cData, ...
                [size(cData,1)*size(cData,2), size(cData,3)]), 'rows' );
            cData = rgb2ind(cData, cMap);

            edgeColorScale = {};
            fac = 1/(length(cMap)-1);

            for c = 1: length(cMap)
                edgeColorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))};
            end

            obj.data{surfaceIndex}.line.cmin = 0;
            obj.data{surfaceIndex}.line.cmax = 255;
            obj.data{contourIndex}.line.colorscale = edgeColorScale;
        else
            obj.data{contourIndex}.line.cmin = axisData.CLim(1);
            obj.data{contourIndex}.line.cmax = axisData.CLim(2);
            obj.data{contourIndex}.line.colorscale = colorScale;
        end

        cDataContourDir1 = [cData; NaN(1, size(cData, 2))];
        cDataContourDir2 = cDataContourDir1(1:end-1,:)';
        cDataContourDir2 = [cDataContourDir2; NaN(1, size(cDataContourDir2, 2))];
        cDataContour = [cDataContourDir1(:); cDataContourDir2(:)];

        obj.data{surfaceIndex}.contours.x.show = false;
        obj.data{surfaceIndex}.contours.y.show = false;

    elseif strcmpi(meshData.EdgeColor, 'none')
        cDataContour = 'rgba(0,0,0,0)';

    end

    %-set edge color-%
    obj.data{contourIndex}.line.color = cDataContour;
    obj.data{surfaceIndex}.contours.x.color = cDataContour;
    obj.data{surfaceIndex}.contours.y.color = cDataContour;

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

    %-get face color-%
    faceColor = meshData.FaceColor;

    if isnumeric(faceColor)

        if all(faceColor == [1, 1, 1])
            faceColor = [0.96, 0.96, 0.96];
        end

        for n = 1:size(zDataSurface, 2)
            for m = 1:size(zDataSurface, 1)
                cDataSurface(m, n, :) = faceColor;
            end
        end

        [cDataSurface, cMapSurface] = rgb2ind(cDataSurface, 256);
        cDataSurface = double(cDataSurface) + axisData.CLim(1);

        for c = 1: size(cMapSurface, 1)
            colorScale{c} = { (c-1)*fac , sprintf('rgba(%f,%f,%f, 1)', cMapSurface(c, :))};
        end

        obj.data{surfaceIndex}.cmin = axisData.CLim(1);
        obj.data{surfaceIndex}.cmax = axisData.CLim(2);

    elseif strcmpi(faceColor, 'interp')
        cDataSurface = zDataSurface;

        if surfaceIndex > xsource
            cData = [];

            for idx = xsource:surfaceIndex
                cData = [cData; obj.data{idx}.z];
            end

            cMin = min(cData(:));
            cMax = max(cData(:));

            for idx = xsource:surfaceIndex
                obj.data{idx}.cmin = cMin;
                obj.data{idx}.cmax = cMax;
            end
        end

    elseif strcmpi(faceColor, 'flat')
        cData = meshData.CData;

        if size(cData, 3) ~= 1
            cMap = unique( reshape(cData, ...
                [size(cData,1)*size(cData,2), size(cData,3)]), 'rows' );
            cDataSurface = rgb2ind(cData, cMap);

            colorScale = {};
            fac = 1/(length(cMap)-1);

            for c = 1: length(cMap)
                colorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))};
            end
        else
            cDataSurface = cData;
        end

    end

    %-set face color-%
    obj.data{surfaceIndex}.colorscale = colorScale;
    obj.data{surfaceIndex}.surfacecolor = cDataSurface;

    %-lighting settings-%

    if isnumeric(meshData.FaceColor) && all(meshData.FaceColor == [1, 1, 1])
        obj.data{surfaceIndex}.lighting.diffuse = 0.5;
        obj.data{surfaceIndex}.lighting.ambient = 0.725;
    else
        % obj.data{surfaceIndex}.lighting.diffuse = 1.0;
        % obj.data{surfaceIndex}.lighting.ambient = 0.9;
    end

    if meshData.FaceAlpha ~= 1
        obj.data{surfaceIndex}.lighting.diffuse = 0.5;
        obj.data{surfaceIndex}.lighting.ambient = 0.725 + (1-meshData.FaceAlpha);
    end

    if obj.PlotlyDefaults.IsLight
        obj.data{surfaceIndex}.lighting.diffuse = 1.0;
        obj.data{surfaceIndex}.lighting.ambient = 0.3;
    end

    %-opacity-%
    obj.data{surfaceIndex}.opacity = meshData.FaceAlpha;

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

    %-line style-%
    obj.data{contourIndex}.line.width = 3*meshData.LineWidth;

    if strcmpi(meshData.LineStyle, '-')
        obj.data{contourIndex}.line.dash = 'solid';
    else
        obj.data{contourIndex}.line.dash = 'dot';
        obj.data{surfaceIndex}.contours.x.show = false;
        obj.data{surfaceIndex}.contours.y.show = false;
    end

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

    %-SCENE CONFIGUTATION-%

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

    %-aspect ratio-%
    asr = obj.PlotOptions.AspectRatio;

    if ~isempty(asr)
        if ischar(asr)
            scene.aspectmode = asr;
        elseif isvector(ar) && length(asr) == 3
            xar = asr(1);
            yar = asr(2);
            zar = asr(3);
        end
    else

        %-define as default-%
        xar = max(xData(:));
        yar = max(yData(:));
        xyar = max([xar, yar]);
        zar = 0.7*xyar;
    end

    scene.aspectratio.x = 1.15*xyar;
    scene.aspectratio.y = 1.0*xyar;
    scene.aspectratio.z = zar;

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

    %-camera eye-%
    ey = obj.PlotOptions.CameraEye;

    if ~isempty(ey)
        if isvector(ey) && length(ey) == 3
            scene.camera.eye.x = ey(1);
            scene.camera.eye.y = ey(2);
            scene.camera.eye.z = ey(3);
        end
    else

        %-define as default-%
        xey = - xyar; if xey>0 xfac = 0.1; else xfac = -0.1; end
        yey = - xyar; if yey>0 yfac = -0.5; else yfac = 0.5; end
        if zar>0 zfac = 0.1; else zfac = -0.1; end

        scene.camera.eye.x = xey + xfac*xey;
        scene.camera.eye.y = yey + yfac*yey;
        scene.camera.eye.z = zar + zfac*zar;
    end

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

    %-scene axis configuration-%

    scene.xaxis.range = axisData.XLim;
    scene.yaxis.range = axisData.YLim;
    scene.zaxis.range = axisData.ZLim;

    scene.xaxis.tickvals = axisData.XTick;
    scene.xaxis.ticktext = axisData.XTickLabel;

    scene.yaxis.tickvals = axisData.YTick;
    scene.yaxis.ticktext = axisData.YTickLabel;

    scene.zaxis.tickvals = axisData.ZTick;
    scene.zaxis.ticktext = axisData.ZTickLabel;

    scene.xaxis.zeroline = false;
    scene.yaxis.zeroline = false;
    scene.zaxis.zeroline = false;

    scene.xaxis.showline = true;
    scene.yaxis.showline = true;
    scene.zaxis.showline = true;

    scene.xaxis.tickcolor = 'rgba(0,0,0,1)';
    scene.yaxis.tickcolor = 'rgba(0,0,0,1)';
    scene.zaxis.tickcolor = 'rgba(0,0,0,1)';

    scene.xaxis.ticklabelposition = 'outside';
    scene.yaxis.ticklabelposition = 'outside';
    scene.zaxis.ticklabelposition = 'outside';

    scene.xaxis.title = axisData.XLabel.String;
    scene.yaxis.title = axisData.YLabel.String;
    scene.zaxis.title = axisData.ZLabel.String;

    scene.xaxis.tickfont.size = axisData.FontSize;
    scene.yaxis.tickfont.size = axisData.FontSize;
    scene.zaxis.tickfont.size = axisData.FontSize;

    scene.xaxis.tickfont.family = matlab2plotlyfont(axisData.FontName);
    scene.yaxis.tickfont.family = matlab2plotlyfont(axisData.FontName);
    scene.zaxis.tickfont.family = matlab2plotlyfont(axisData.FontName);

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

    %-SET SCENE TO LAYOUT-%
    obj.layout = setfield(obj.layout, sprintf('scene%d', xsource), scene);

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

    %-surface name-%
    obj.data{surfaceIndex}.name = meshData.DisplayName;
    obj.data{contourIndex}.name = meshData.DisplayName;

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

    %-surface showscale-%
    obj.data{surfaceIndex}.showscale = false;
    obj.data{contourIndex}.showscale = false;

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

    %-surface visible-%
    obj.data{surfaceIndex}.visible = strcmp(meshData.Visible,'on');
    obj.data{contourIndex}.visible = strcmp(meshData.Visible,'on');

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

    leg = get(meshData.Annotation);
    legInfo = get(leg.LegendInformation);

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

    obj.data{surfaceIndex}.showlegend = showleg;

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


% superline() - dashed (moving) line between two points
%
% Usage:
%   >> [handles] = superline( X, Y, color, linewidth, offset, middle );
%
% Inputs:
%   X          - abscices of the points (2 abscices for the 2 points)
%   Y          - ordinates of the points (2 ordinates for the 2 points)
%   color      - color of the line (default black)
%   linewidth  - thickness of the line (same as line 'linewidth' property, default:1)
%   offset     - change the offset of the dash (in between 0 and 1) (default:0)
%   middle     - put a small line at the middle
%
% Outputs:
%   handles    - handles of all the objects composing the line

% arno@salk.edu, Arnaud Delorme, CNL / Salk Institute, 2001

% This program is free software; you can redistribute it and/or
% modify it.
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

function h = superline(X, Y, color, thickness, offset, middle);

if nargin < 2
	error('Not enough arguments. Type help superline');
	return;
end;
if nargin < 3
	color = 'k';
end;
if nargin < 4
	thickness = 1;
end;
if nargin < 5
	offset = 0;
end;
if nargin < 6
	middle = 0;
end;

% ratio X/Y
% ---------
if abs(Y(1) - Y(2)) == 0
	ratioXY = 1;
else
	ratioXY = abs(X(1) - X(2))/abs(Y(1) - Y(2));
end;

PADSTRIPE  = 0.8;
SIZESTRIPE = 0.2;
%PADSTRIPE  = 0.18;
%SIZESTRIPE = 0.09;

% original line vector
% --------------------
if ratioXY >= 0.05
	slope = (Y(2)-Y(1)) / (X(2)-X(1));
	slopenormalize = [1 slope]/sqrt(slope^2+1); % (1,slope) are the coordinate of the non unitary vector
else
	slopenormalize = sign(Y(2)-Y(1))*[0 1];
end;
% reverse vector if necessary
if X(1) > X(2)
	slopenormalize = - slopenormalize;
end;
vectpad    = slopenormalize*PADSTRIPE*abs(complex(X(1), Y(1)) - complex(X(2), Y(2)));
vectstripe = slopenormalize*SIZESTRIPE*abs(complex(X(1), Y(1)) - complex(X(2), Y(2)));
nblines    = 1/(PADSTRIPE+SIZESTRIPE);

% draw the discontinuous line
% ---------------------------
cont = 1;
compter = 1;
firstpass = 1;
posx1 = X(1);
posy1 = Y(1);
offsetshifted = mod( 0.5 + offset + SIZESTRIPE/2,1);

while cont == 1
	if firstpass == 1
		if offsetshifted/nblines < SIZESTRIPE
			posx1 = posx1 + vectstripe(1)*(offsetshifted/nblines)/SIZESTRIPE;
			posy1 = posy1 + vectstripe(2)*(offsetshifted/nblines)/SIZESTRIPE;
			posx2 = posx1 + vectpad(1);
			posy2 = posy1 + vectpad(2);
		else
			posx2 = posx1 + vectstripe(1)*(offsetshifted/nblines-SIZESTRIPE)/SIZESTRIPE; %consider the offset from 0 to 1
			posy2 = posy1 + vectstripe(2)*(offsetshifted/nblines-SIZESTRIPE)/SIZESTRIPE; %consider the offset from 0 to 1
		end;
		firstpass = 0;
		%posy1
		%posy2
	else
		posx2 = posx1 + vectpad(1);
		posy2 = posy1 + vectpad(2);
		%posy1
		%posy2
	end;
	%fprintf(['Abscice1 ' num2str(X(1)) '  Abscice2 ' num2str(X(1)) '  equal ' num2str(X(1) == X(2)) '\n']);
	if ratioXY < 0.1
		if Y(1) > Y(2)
			if posy2 <= Y(2)
				posx2 = X(2);
				posy2 = Y(2);
				cont = 0;
			end;
		else
			if posy2 >= Y(2)
				posx2 = X(2);
				posy2 = Y(2);
				cont = 0;
			end;
		end;
	else
		if X(1) > X(2)
			if posx2 <= X(2)
				posx2 = X(2);
				posy2 = Y(2);
				cont = 0;
			end;
		else
			if posx2 >= X(2)
				posx2 = X(2);
				posy2 = Y(2);
				cont = 0;
			end;
		end;
	end;
	h(compter) = line([posx1 posx2], [posy1 posy2]);
	set(h(compter), 'color', color);
	set(h(compter), 'linewidth', thickness);
	posx1 = posx2+vectstripe(1);
	posy1 = posy2+vectstripe(2);
	compter = compter +1;
	if ratioXY < 0.1
		if Y(1) > Y(2)
			if posy1 <= Y(2)
				cont = 0;
			end;
		else
			if posy1 >= Y(2)
				cont = 0;
			end;
		end;
	else
		if X(1) > X(2)
			if posx1 <= X(2)
				cont = 0;
			end;
		else
			if posx1 >= X(2)
				cont = 0;
			end;
		end;
	end;
end;

%patch(patchccordinatesX, patchccordinatesY, [0 0 0 0], color);

if middle
	hold on; h = plot((X(1)+X(2))/2, (Y(1)+Y(2))/2, '*k', 'markersize', thickness/2);
end;

return

% tests
figure;
for i=9:31
	fprintf('******************************* %d \n', mod(i/10, 1));
	superline( [ 0+i 1+i ] , [ 10 20 ], 'b', 5, mod(i/10, 1),1);
end;


function this = plot_design_matrix(this)
% plots the design matrix scaled for display
%
%   Y = MrGlm()
%   Y.plot_design_matrix()
%
% This is a method of class MrGlm.
%
% IN
%
% OUT
%
% EXAMPLE
%   plot_design_matrix
%
%   See also MrGlm

% Author:   Saskia Bollmann & Lars Kasper
% Created:  2018-05-08
% Copyright (C) 2018 Institute for Biomedical Engineering
%                    University of Zurich and ETH Zurich
%
% This file is part of the TAPAS UniQC Toolbox, which is released
% under the terms of the GNU General Public License (GPL), version 3.
% You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version).
% For further details, see the file COPYING or
%  <http://www.gnu.org/licenses/>.
%

figure;
imagesc(this.designMatrix);
colormap gray;
title('design matrix');

end


function [h,Coord,Color,height] = som_dendrogram(Z,varargin)

%SOM_DENDROGRAM Visualize a dendrogram.
%
% [h,Coord,Color,height] = som_dendrogram(Z, [[argID,] value, ...])
%
%  Z = som_linkage(sM);
%  som_dendrogram(Z);
%  som_dendrogram(Z,sM);
%  som_dendrogram(Z,'coord',co);
%
%  Input and output arguments ([]'s are optional):
%   h        (vector) handle to the arc lines
%   Z        (matrix) size n-1 x 1, the hierarchical cluster matrix
%                     returned by functions like LINKAGE and SOM_LINKAGE
%                     n is the number of original data samples.
%   [argID,  (string) See below. The values which are unambiguous can
%    value]  (varies) be given without the preceeding argID.
%   Coord    (matrix) size 2*n-1 x {1,2}, the coordinates of the
%                     original data samples and cluster nodes used
%                     in the visualization
%   Color    (matrix) size 2*n-1 x 3, the colors of ...
%   height   (vector) size 2*n-1 x 1, the heights of ...
%
% Here are the valid argument IDs and corresponding values. The values
% which are unambiguous (marked with '*') can be given without the
% preceeding argID.
%   'data'  *(struct) map or data struct: many other optional
%                     arguments require this
%            (matrix) data matrix
%   'coord'  (matrix) size n x 1 or n x 2, the coordinates of
%                     the original data samples either in 1D or 2D
%            (matrix) size 2*n-1 x {1,2}, the coordinates of both
%                     original data samples and each cluster
%           *(string) 'SOM', 'pca#', 'sammon#', or 'cca#': the coordinates
%                     are calculated using the given data and the
%                     required projection algorithm. The '#' at the
%                     end of projection algorithms refers to the
%                     desired output dimension and can be either 1 or 2
%                     (2 by default). In case of 'SOM', the unit
%                     coordinates (given by SOM_VIS_COORDS) are used.
%   'color'  (matrix) size n x 3, the color of the original data samples
%            (matrix) size 2*n-1 x 3, the colors of both original
%                     data samples and each cluster
%            (string) color specification, e.g. 'r.', used for each node
%   'height' (vector) size n-1 x 1, the heights used for each cluster
%            (vector) size 2*n-1 x 1, the heights used for both original
%                     data samples and each cluster
%           *(string) 'order', the order of combination determines height
%                     'depth', the depth at which the combination
%                     happens determines height
%   'linecolor' (string) color specification for the arc color, 'k' by default
%               (vector) size 1 x 3
%
% See also SOM_LINKAGE, DENDROGRAM.

% Copyright (c) 2000 by Juha Vesanto
% Contributed to SOM Toolbox on June 16th, 2000 by Juha Vesanto
% http://www.cis.hut.fi/projects/somtoolbox/

% Version 2.0beta juuso 160600

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% read the arguments

% Z
nd = size(Z,1)+1;
nc = size(Z,1);

% varargin
Coordtype = 'natural'; Coord = []; codim = 1;
Colortype = 'none'; Color = [];
height = [zeros(nd,1); Z(:,3)];
M = [];
linecol = 'k';

i=1;
while i<=length(varargin),
  argok = 1;
  if ischar(varargin{i}),
    switch varargin{i},
     case 'data', i = i + 1; M = varargin{i};
     case 'coord',
      i=i+1;
      if isnumeric(varargin{i}), Coord = varargin{i}; Coordtype = 'given';
      else
	if strcmp(varargin{i},'SOM'), Coordtype = 'SOM';
	else Coordtype = 'projection'; Coord = varargin{i};
	end
      end
     case 'color',
      i=i+1;
      if isempty(varargin{i}), Colortype = 'none';
      elseif ischar(varargin{i}), Colortype = 'colorspec'; Color = varargin{i};
      else Colortype = 'given'; Color = varargin{i};
      end
     case 'height', i=i+1; height = varargin{i};
     case 'linecolor', i=i+1; linecol = varargin{i};
     case 'SOM',
      Coordtype = 'SOM';
     case {'pca','pca1','pca2','sammon','sammon1','sammon2','cca','cca1','cca2'},
      Coordtype = 'projection'; Coord = varargin{i};
     case {'order','depth'}, height = varargin{i};
    end
  elseif isstruct(varargin{i}), M = varargin{i};
  else
    argok = 0;
  end
  if ~argok,
    disp(['(som_dendrogram) Ignoring invalid argument #' num2str(i+1)]);
  end
  i = i+1;
end

switch Coordtype,
 case 'SOM',
  if isempty(M) | ~any(strcmp(M.type,{'som_map','som_topol'})) ,
    error('Cannot determine SOM coordinates without a SOM.');
  end
  if strcmp(M.type,'som_map'), M = M.topol; end
 case 'projection',
  if isempty(M), error('Cannot do projection without the data.'); end
  if isstruct(M),
    if strcmp(M.type,'som_data'), M = M.data;
    elseif strcmp(M.type,'som_map'), M = M.codebook;
    end
  end
  if size(M,1) ~= nd,
    error('Given data must be equal in length to the number of original data samples.')
  end
 case 'given',
  if size(Coord,1) ~= nd & size(Coord,1) ~= nd+nc,
    error('Size of given coordinate matrix does not match the cluster hierarchy.');
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% initialization

% Coordinates
switch Coordtype,
 case 'natural', o = leavesorder(Z)'; [dummy,Coord] = sort(o); codim = 1;
 case 'SOM', Coord = som_vis_coords(M.lattice,M.msize); codim = 2;
 case 'projection',
  switch Coord,
   case {'pca','pca2'},       Coord = pcaproj(M,2);   codim = 2;
   case 'pca1',               Coord = pcaproj(M,1);   codim = 1;
   case {'cca','cca2'},       Coord = cca(M,2,20);    codim = 2;
   case 'cca1',               Coord = cca(M,1,20);    codim = 1;
   case {'sammon','sammon2'}, Coord = sammon(M,2,50); codim = 2;
   case 'sammon1',            Coord = sammon(M,1,50); codim = 1;
  end
 case 'given', codim = min(size(Coord,2),2); % nill
end

if size(Coord,1) == nd,
  Coord = [Coord; zeros(nc,size(Coord,2))];
  for i=(nd+1):(nd+nc),
    leaves = leafnodes(Z,i,nd);
    if any(leaves), Coord(i,:) = mean(Coord(leaves,:),1); else Coord(i,:) = Inf; end
  end
end

% Colors
switch Colortype,
 case 'colorspec', % nill
 case 'none', Color = '';
 case 'given',
  if size(Color,1) == nd,
    Color = [Color; zeros(nc,3)];
    for i=(nd+1):(nd+nc),
      leaves = leafnodes(Z,i,nd);
      if any(leaves), Color(i,:) = mean(Color(leaves,:),1);
      else Color(i,:) = 0.8;
      end
    end
  end
end

% height
if ischar(height),
  switch height,
   case 'order', height = [zeros(nd,1); [1:nc]'];
   case 'depth', height = nodedepth(Z); height = max(height) - height;
  end
else
  if length(height)==nc, height = [zeros(nd,1); height]; end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% draw

% the arcs
lfrom = []; lto = [];
for i=1:nd+nc,
  if i<=nd, ch = [];
  elseif ~isfinite(Z(i-nd,3)), ch = [];
  else ch = Z(i-nd,1:2)';
  end
  if any(ch),
    lfrom = [lfrom; i*ones(length(ch),1)];
    lto = [lto; ch];
  end
end

% the coordinates of the arcs
if codim == 1,
  Lx = [Coord(lfrom), Coord(lto), Coord(lto)];
  Ly = [height(lfrom), height(lfrom), height(lto)];
  Lz = [];
else
  Lx = [Coord(lfrom,1), Coord(lto,1), Coord(lto,1)];
  Ly = [Coord(lfrom,2), Coord(lto,2), Coord(lto,2)];
  Lz = [height(lfrom), height(lfrom), height(lto)];
end

washold = ishold;
if ~washold, cla; end

% plot the lines
if isempty(Lz),
  h = line(Lx',Ly','color',linecol);
else
  h = line(Lx',Ly',Lz','color',linecol);
  if ~washold, view(3); end
  rotate3d on
end

% plot the nodes
hold on
switch Colortype,
 case 'none', % nill
 case 'colorspec',
  if codim == 1, plot(Coord,height,Color);
  else plot3(Coord(:,1), Coord(:,2), height, Color);
  end
 case 'given',
  som_grid('rect',[nd+nc 1],'line','none','Coord',[Coord, height],...
	   'Markersize',10,'Markercolor',Color);
end
if ~washold, hold off, end

return;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% subfunctions

function depth = nodedepth(Z)

  nd = size(Z,1)+1;
  nc = size(Z,1);
  depth = zeros(nd+nc,1);
  ch = nc+nd-1;
  while any(ch),
    c  = ch(1); ch = ch(2:end);
    if c>nd & isfinite(Z(c-nd,3)),
      chc = Z(c-nd,1:2);
      depth(chc) = depth(c) + 1;
      ch = [ch, chc];
    end
  end
  return;

function inds = leafnodes(Z,i,nd)

  inds = [];
  ch = i;
  while any(ch),
    c  = ch(1); ch = ch(2:end);
    if c>nd & isfinite(Z(c-nd,3)), ch = [ch, Z(c-nd,1:2)]; end
    if c<=nd, inds(end+1) = c; end
  end
  return;

function order = leavesorder(Z)

  nd = size(Z,1)+1;
  order = 2*nd-1;
  nonleaves = 1;
  while any(nonleaves),
    j = nonleaves(1);
    ch = Z(order(j)-nd,1:2);
    if j==1, oleft = []; else oleft = order(1:(j-1)); end
    if j==length(order), oright = []; else oright = order((j+1):length(order)); end
    order = [oleft, ch, oright];
    nonleaves = find(order>nd);
  end
  return;


%%% show_2dvideo(2dmatrix,int,int)
%
function show_2dvideo(M,m,n)
  for i = 1 : size(M,2)
    I = reshape(M(:,i),m,n);
    imshow(I,[],'InitialMagnification','fit');
    %imshow(I,'InitialMagnification','fit');
    disp(i);
    pause(0.01);
  end
end


function test_suite = test_dim_find()
% tests for cosmo_dim_find
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_dim_find_basics()
    prefixes='sf';
    for dim=1:2
        if dim==1
            transposer=@transpose;
        else
            transposer=@(x)x;
        end

        prefix=prefixes(dim);
        attr_name=[prefix 'a'];
        dim_name=[prefix 'dim'];

        dim_labels={'i','j','k'};

        ds=cosmo_synthetic_dataset();
        if dim==1
            ds=cosmo_dim_transpose(ds,{'i','j','k'},1);
        end

        combis=cell2mat(cosmo_cartprod(repmat({[false,true]},3,1)));

        for j=1:size(combis,1);
            msk=combis(j,:);

            use_string_name=sum(msk)==1 && msk(2);

            if use_string_name
                name=dim_labels{msk};
            else
                name=dim_labels(msk);
            end

            [d,i,an,dn,vs]=cosmo_dim_find(ds,name,false);

            if ~any(msk)
                assertEqual({d,i,an,dn,vs},{[],[],[],[],[]});

            else
                assertEqual(d,dim);
                assertEqual(i,transposer(find(msk)'));
                assertEqual(an,attr_name);
                assertEqual(dn,dim_name);

                values=ds.a.(dim_name).values;

                if use_string_name
                    assertEqual(vs,values{msk});
                else
                    assertEqual(vs,values(transposer(msk)));
                end
            end
        end
    end

function test_dim_find_exceptions()
    aet=@(varargin)assertExceptionThrown(@()...
                cosmo_dim_find(varargin{:}),'');

    ds=cosmo_synthetic_dataset();

    ds=cosmo_dim_transpose(ds,'i',1);
    aet(ds,{'i','j'});
    assertEqual(cosmo_dim_find(ds,{'i','j'},false),[]);
    aet(ds,{'foo'});
    assertEqual(cosmo_dim_find(ds,{'foo'},false),[]);
    aet(ds,'foo');
    aet(ds,[]);
    assertEqual(cosmo_dim_find(ds,'foo',false),[]);
    ds=cosmo_dim_transpose(ds,'i',2);
    cosmo_dim_find(ds,'i');
    ds.a.fdim.labels{1}='k';
    aet(ds,'k',true);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% IR Tools
% April 2018
%
% This file is part of the IR Tools package and is distributed under the
% 3-Clause BSD License. A separate license file should be provided as
% part of the package.
%
% Copyright 2018 Silvia Gazzola, University of Bath, Per Christian Hansen,
% Technical University of Denmark and James G. Nagy, Emory University.
%
% Contact: s.gazzola@bath.ac.uk, pcha@dtu.dk, jnagy@emory.edu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Installating
%   IRtools_setup       - Set up search paths to IRtools
%
% Example scripts:
%   EXblur_cgls_hybrid  - Example script, speckle deblurring problem
%   EXdiffusion_rrgmres - Example script, inverse diffusion problem
%   EXinvinterp2_cgls   - Example script, inverse interpolation problem
%   EXnmr_cgls_mrnsd    - Example script, 2D NMR relaxometry
%   EXsparsity          - Example script, deblurring without and with sparsity
%
% Iterative methods:
%   IRart              - Algebraic Reconstruction Technique
%   IRcgls             - Conjugate Gradient algorithm for Least Squares problems
%   IRconstr_ls        - Least squares solver with box and energy constraints
%   IRell1             - Least squares solver with 1-norm penalization term
%   IRenrich           - Enriched CGLS method
%   IRfista            - FISTA algorithm for constrained least squares problems
%   IRget              - Get options for IR Tools functions
%   IRhtv              - Least squares solver with heuristic total variation penalization
%   IRhybrid_fgmres    - Hybrid version of FGMRES for enforcing 1-norm penalization
%   IRhybrid_gmres     - Hybrid version of GMRES algorithm for square systems
%   IRhybrid_lsqr      - Hybrid version of LSQR algorithm
%   IRirn              - Least squares solver with 1-norm penalization term
%   IRmrnsd            - Modified Residual Norm Steepest Descent method
%   IRnnfcgls          - Modified flexible CGLS for nonnegatively constrained LS problems
%   IRrestart          - Restarted Krylov subspace methods
%   IRrrgmres          - Range Restricted GMRES for square systems
%   IRset              - Set options for IR Tools functions
%   IRsirt             - Simuletaneous Iterative Reconstruction Technique
%
% Operators (functions) for some test problems:
%   OPdiffusion        - The forward computation and its adjoint for PRdiffusion
%   OPinvinterp2       - The forward computation and its adjoint for PRinvinterp2
%   OPnmr              - The forward computation and its adjoint for PRnmr
%
% Test problems and associated functions:
%   PRblur             - Generates data for use in image deblurring problems
%   PRblurdefocus      - Image deblurring problem with a defocus point spread function
%   PRblurgauss        - Image deblurring problem with a Gaussian point spread function
%   PRblurmotion       - Image deblurring problem with linear motion blur
%   PRblurrotation     - Image deblurring problem with rotational motion blur
%   PRblurshake        - Image deblurring problem with random camera motion (shaking)
%   PRblurspeckle      - Image deblurring problem with a speckle point spread function
%   PRdiffusion        - Generates data for use in an inverse diffusion problems
%   PRget              - Get options for IR Tools test problems
%   PRinvinterp2       - Generates data for use in 2D inverse interpolation problems
%   PRnmr              - Generates data for 2D NMR relaxometry problems
%   PRnoise            - Add noise of a specified distribution and level
%   PRseismic          - Generates data for seismic travel-time tomography problems
%   PRset              - Set options for IR Tools test problems
%   PRshowb            - Show the right-hand side b (the data) in IR Tools
%   PRshowx            - Show the solution x in IR Tools
%   PRspherical        - Generates data for spherical means tomography problems
%   PRtomo             - Generates data for X-ray tomographic reconstruction problems


%% Test the niSelect function
%
% We identify a small region of a white matter mask.  We can use this
% region to limit the computation that we do for tracking and LiFE
%
% RL/BW Vistasoft Team, 2016

%% Go get a white matter mask from the Remote Data client

rdt = RdtClient('vistasoft');
rdt.crp('/vistadata/diffusion/sampleData/dti40/bin');

% This is all of the artifacts
a = rdt.listArtifacts('print',true);

% Write the white matter mask out in the local directory
dFolder = fullfile(vistaRootPath,'local');
fname = rdt.readArtifact(a(7),'destinationFolder',dFolder);

%% Have a look
nii = niftiRead(fname);
montageAll = niftiView(nii);

%% Select out a cube

p.keepLR = 20:30; p.keepPA = 20:30; p.keepIS = 40:50;
niiCube = niftiSelect(nii,p);
montage = niftiView(niiCube);

%% Make an overlay from the
montageOverlay(:,:,1) = montage(:,:);
montageOverlay(:,:,2) = montageAll;
montageOverlay(:,:,3) = montageAll;
mrvNewGraphWin; imagesc(montageOverlay); axis image

%%


function [boxes blobIndIm blobBoxes hierarchy priority] = Image2HierarchicalGrouping(im, sigma, k, minSize, colourType, functionHandles)
% function [boxes blobIndIm blobBoxes hierarchy] = Image2HierarchicalGrouping
%                              (im, sigma, k, minSize, colourType, functionHandles)
%
% Creates hierarchical grouping from an image
%
% im:                   Image
% sigma (= 0.8):        Smoothing for initial segmentation (Felzenszwalb 2004)
% k (= 100):            Threshold for initial segmentation
% minSize (= 100):      Minimum size of segments for initial segmentation
% colourType:           ColourType in which to do grouping (see Image2ColourSpace)
% functionHandles:      Similarity functions which are called. Function
%                       creates as many hierarchies as there are functionHandles
%
% boxes:                N x 4 array with boxes of all hierarchical groupings
% blobIndIm:            Index image with the initial segmentation
% blobBoxes:            Boxes belonging to the indices in blobIndIm
% hierarchy:            M x 1 cell array with hierarchies. M =
%                       length(functionHandles)
%
%     Jasper Uijlings - 2013

% Change colour space
[colourIm imageToSegment] = Image2ColourSpace(im, colourType);

% Get initial segmentation, boxes, and neighbouring blobs
[blobIndIm blobBoxes neighbours] = mexFelzenSegmentIndex(imageToSegment, sigma, k, minSize);
numBlobs = size(blobBoxes,1);

% Skip hierarchical grouping if segmentation results in single region only
if numBlobs == 1
    warning('Oversegmentation results in a single region only');
    boxes = blobBoxes;
    hierarchy = [];
    priority = 1; % priority is legacy
    return;
end

%%% Calculate histograms and sizes as prerequisite for grouping procedure

% Get colour histogram
[colourHist blobSizes] = BlobStructColourHist(blobIndIm, colourIm);

% Get texture histogram
textureHist = BlobStructTextureHist(blobIndIm, colourIm);
% textureHist = BlobStructTextureHistLBP(blobIndIm, colourIm);

% Allocate memory for complete hierarchy.
blobStruct.colourHist = zeros(size(colourHist,2), numBlobs * 2 - 1);
blobStruct.textureHist = zeros(size(textureHist,2), numBlobs * 2 - 1);
blobStruct.size = zeros(numBlobs * 2 -1, 1);
blobStruct.boxes = zeros(numBlobs * 2 - 1, 4);

% Insert calculated histograms, sizes, and boxes
blobStruct.colourHist(:,1:numBlobs) = colourHist';
blobStruct.textureHist(:,1:numBlobs) = textureHist';
blobStruct.size(1:numBlobs) = blobSizes ./ 3;
blobStruct.boxes(1:numBlobs,:) = blobBoxes;

blobStruct.imSize = size(im,1) * size(im,2);

%%% If you want to use original blobs in similarity functions, uncomment
%%% these lines.
% blobStruct.blobs = cell(numBlobs * 2 - 1, 1);
% initialBlobs = SegmentIndices2Blobs(blobIndIm, blobBoxes);
% blobStruct.blobs(1:numBlobs) = initialBlobs;

% Loop over all merging strategies. Perform them one by one.
boxes = cell(1, length(functionHandles)+1);
priority = cell(1, length(functionHandles) + 1);
hierarchy = cell(1, length(functionHandles));
for i=1:length(functionHandles)
    [boxes{i} hierarchy{i} blobStructT mergeThreshold] = BlobStruct2HierarchicalGrouping(blobStruct, neighbours, numBlobs, functionHandles{i});
    boxes{i} = boxes{i}(numBlobs+1:end,:);
    priority{i} = (size(boxes{i}, 1):-1:1)';
end

% Also save the initial boxes
i = i+1;
boxes{i} = blobBoxes;
priority{i} = ones(size(boxes{i}, 1), 1) * (size(boxes{1}, 1)+1);

% Concatenate boxes and priorities resulting from the different merging
% strategies
boxes = cat(1, boxes{:});
priority = cat(1, priority{:});
[priority ids] = sort(priority, 'ascend');
boxes = boxes(ids,:);


% Copyright 2011 Zdenek Kalal
%
% This file is part of TLD.
%
% TLD 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.
%
% TLD 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 TLD.  If not, see <http://www.gnu.org/licenses/>.

function tld = tldLearning(tld,I)

bb    = tld.bb(:,I); % current bounding box
img   = tld.img{I}; % current image

% Check consistency -------------------------------------------------------

pPatt  = tldGetPattern(img,bb,tld.model.patchsize); % get current patch
[pConf1,~,pIsin] = tldNN(pPatt,tld); % measure similarity to model

if pConf1 < 0.5, disp('Fast change.'); tld.valid(I) = 0; return; end % too fast change of appearance
if var(pPatt) < tld.var, disp('Low variance.'); tld.valid(I) = 0; return; end % too low variance of the patch
if pIsin(3) == 1, disp('In negative data.'); tld.valid(I) = 0; return; end % patch is in negative data

% Update ------------------------------------------------------------------

% generate positive data
overlap  = bb_overlap(bb,tld.grid); % measure overlap of the current bounding box with the bounding boxes on the grid
[pX,pEx] = tldGeneratePositiveData(tld,overlap,img,tld.p_par_update); % generate positive examples from all bounding boxes that are highly overlappipng with current bounding box
pY       = ones(1,size(pX,2)); % labels of the positive patches

% generate negative data
idx      = overlap < tld.n_par.overlap & tld.tmp.conf >= 1; % get indexes of negative bounding boxes on the grid (bounding boxes on the grid that are far from current bounding box and which confidence was larger than 0)
overlap  = bb_overlap(bb,tld.dt{I}.bb); % measure overlap of the current bounding box with detections
nEx      = tld.dt{I}.patch(:,overlap < tld.n_par.overlap); % get negative patches that are far from current bounding box

fern(2,[pX tld.tmp.patt(:,idx)],[pY zeros(1,sum(idx))],tld.model.thr_fern,2); % update the Ensemble Classifier (reuses the computation made by detector)
tld = tldTrainNN(pEx,nEx,tld); % update nearest neighbour


% Test suite for run_CNMF_patches
% Use 'run(TestRunCNMFPatches)' to run the whole suite.
classdef TestRunCNMFPatches < matlab.unittest.TestCase

    properties
        dataset   % generate dataset to test with
        datasize  % dataset size
        patches   % patches coordinates
    end

    properties (ClassSetupParameter)
        sizY = struct('data2d', [128, 128, 500], ...
                      'data2d_small', [25, 25, 500], ...
                      'data3d', [128, 128, 7, 100]);
        memory_mapped = struct('memmapped', true, 'inRAM', false);
    end

    properties (MethodSetupParameter)
        patch_size = struct('default', {[]}, 'small', 25);
    end

    properties (TestParameter)
        cluster_pixels = struct('cluster_on', true, 'cluster_off', false);
    end

    methods (TestClassSetup)
        function createDataset(testCase, sizY, memory_mapped)
            rng(1)  % fix random generator seed for reproducibility
            Y = randn(sizY);
            if memory_mapped
                Yr = reshape(Y, [], sizY(end));
                F_dark = min(Yr(:));
                filename = [tempname, '.mat'];
                save(filename, 'Yr', 'Y', 'F_dark', 'sizY', '-v7.3');
                Y = matfile(filename, 'Writable', false);
            end
            testCase.datasize = sizY;
            testCase.dataset = Y;
        end
    end

    methods (TestClassTeardown)
        function cleanDataset(testCase)
            % clear create file, if any
            if isa(testCase.dataset, 'matlab.io.MatFile')
                delete(testCase.dataset.Properties.Source);
            end
        end
    end

    methods (TestMethodSetup)
        function createPatches(testCase, patch_size)
            if isempty(patch_size)
                testCase.patches = [];
            else
                data_ndims = length(testCase.datasize(1:end-1));
                psize = [patch_size, patch_size, 5];
                psize = psize(1:data_ndims);
                testCase.patches = construct_patches( ...
                    testCase.datasize(1:end-1), psize);
            end
        end
    end

    methods (Test)
        function testRunning(testCase, cluster_pixels)
            % simply test that nothing crashes
            options = struct('cluster_pixels', cluster_pixels);
            run_CNMF_patches( ...
                testCase.dataset, 7, testCase.patches, [], [], options);
        end
    end
end


%% custom input
addpath('./CustomLayers/','./utils/')
% clear all % 如果更换模型，需重置静态函数(影响性能)，否则可以不用清理
cfg_file = 'cfg/yolov4-tiny.cfg';
weight_file = 'weights/yolov4-tiny.weights';
throushold = 0.1;
NMS = 0.4;

%% import all classes
fid = fopen('coco.names','r');
names = textscan(fid, '%s', 'Delimiter',{'   '});
fclose(fid);classesNames = categorical(names{1});
RGB = randi(255,length(classesNames),3);

%% 摄像头视频流识别
cap = webcam();
player = vision.DeployableVideoPlayer();
image = cap.snapshot();
step(player, image);

while player.isOpen()
    image = cap.snapshot();
    t1 = tic;
    outFeatures = yolov3v4Predict(cfg_file,weight_file,image);% M*(5+nc) ,为[x,y,w,h,Pobj,p1,p2,...,pn]
    fprintf('预测耗时：%.2f 秒\n',toc(t1));% yolov4大概0.4秒，yolov3大概0.2秒，yolov3-tiny大概0.06秒,yolov4-tiny大概0.07秒,yolov3-tiny-prn大概0.06秒

    %% 阈值过滤+NMS处理
    scores = outFeatures(:,5);
    outFeatures = outFeatures(scores>throushold,:);

    allBBoxes = outFeatures(:,1:4);
    allScores = outFeatures(:,5);
    [maxScores,indxs] = max(outFeatures(:,6:end),[],2);
    allScores = allScores.*maxScores;
    allLabels = classesNames(indxs);

    % NMS非极大值抑制
    if ~isempty(allBBoxes)
        [bboxes,scores,labels] = selectStrongestBboxMulticlass(allBBoxes,allScores,allLabels,...
            'RatioType','Min','OverlapThreshold',NMS);
        annotations = string(labels) + ": " + string(scores);
        [~,ids] = ismember(labels,classesNames);
        colors = RGB(ids,:);
        image = insertObjectAnnotation(image,...
            'rectangle',bboxes,cellstr(annotations),...
            'Color',colors,...
            'LineWidth',3);
    end
    step(player,image);
end
release(player);


function [pck,nseg] = eval_plot_pck(isMatchAll, pidxs, verbose, pslidx)

if (nargin < 2)
    pidxs = 1:14;
end

if (nargin < 3)
    verbose = true;
end

if (nargin < 4)
    pslidx = -1;
end

nMatchAll = 0;
nSegAll = 0;
pck = zeros(1,15);
nseg = zeros(1,15);
idxsAll = [];
for pidx = pidxs
    idxs = find(~isnan(isMatchAll(:,pidx)));
    idxsAll = union(idxsAll,idxs);
    nSeg = sum(~isnan(isMatchAll(:,pidx)));
    nMatch = sum(isMatchAll(:,pidx) == 1);
    nMatchAll = nMatchAll + nMatch;
    nSegAll = nSegAll + nSeg;
    pck(pidx) = nMatch/nSeg*100;
    nseg(pidx) = nSeg;
    if (verbose)
        %fprintf('pidx %d: %f; seg: %d %d\n',pidx,nMatch/nSeg,nMatch,nSeg);
    end

end

pck(end) = nMatchAll/nSegAll*100;
nseg(end) = nSegAll;

if pslidx == -1
    if (verbose)
        fprintf('total: %f; seg: %d %d\n',nMatchAll/nSegAll, nMatchAll, nSegAll);
        fprintf(' Head & Shoulder & Elbow & Wrist & Hip & Knee  & Ankle & UBody & Total & # images \\\n');
        if (length(pidxs) == 14)
            fprintf('&%1.1f  & %1.1f  & %1.1f  & %1.1f  & %1.1f  & %1.1f & %1.1f & %1.1f & %1.1f & %d\\\n',(pck(7)+pck(8))/2,(pck(11)+pck(12))/2,(pck(10)+pck(13))/2,(pck(9)+pck(14))/2,(pck(3)+pck(4))/2,(pck(2)+pck(5))/2,(pck(1)+pck(6))/2,mean(pck(9:14)),pck(15),length(idxsAll));
        elseif (length(pidxs) == 6)
            fprintf('& - & %1.1f & %1.1f & %1.1f  & -  & -  & - & %1.1f & %1.1f & %d\\\n',(pck(11)+pck(12))/2,(pck(10)+pck(13))/2,(pck(9)+pck(14))/2, mean(pck(9:14)), pck(15),length(idxsAll));
        end
    end
else
    if (verbose)
%         fprintf('total: %f; seg: %d %d\n',nMatchAll/nSegAll, nMatchAll, nSegAll);
%         fprintf('Poselet & Torso & Upper & Lower & Upper & Fore- & Head  & Total & Total \\\n');
%         fprintf('        &       & Leg   & Leg&  & Arm   & arm   &       & PCP   & images\\\n');
        if (length(pidxs) == 10)
            fprintf('%s & &%1.1f  & %1.1f  & %1.1f  & %1.1f  & %1.1f  & %1.1f & %1.1f & %d\\\n',padZeros(num2str(pslidx),4),pck(5),(pck(2)+pck(3))/2,(pck(1)+pck(4))/2,(pck(8)+pck(9))/2,(pck(7)+pck(10))/2,pck(6),pck(11),length(idxsAll));
        elseif (length(pidxs) == 5)
            fprintf('&%1.1f  & - & - & %1.1f  & %1.1f  & -  & %1.1f & %d\\\n',pck(5),(pck(8)+pck(9))/2,(pck(7)+pck(10))/2, pck(11),length(idxsAll));
        elseif (length(pidxs) == 4)
            fprintf('& - & - & - & %1.1f  & %1.1f  & -  & %1.1f & %d\\\n',(pck(8)+pck(9))/2,(pck(7)+pck(10))/2, pck(11),length(idxsAll));
        end
    end
end

pck = [(pck(7)+pck(8))/2,(pck(11)+pck(12))/2,(pck(10)+pck(13))/2,(pck(9)+pck(14))/2,(pck(3)+pck(4))/2,(pck(2)+pck(5))/2,(pck(1)+pck(6))/2,mean(pck(9:14)),pck(15)];


function sconfounds = spm_cfg_eeg_spatial_confounds
% configuration file for reading montage files
%__________________________________________________________________________
% Copyright (C) 2014-2016 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak
% $Id: spm_cfg_eeg_spatial_confounds.m 6926 2016-11-09 22:13:19Z guillaume $

D = cfg_files;
D.tag = 'D';
D.name = 'File Name';
D.filter = 'mat';
D.num = [1 1];
D.help = {'Select the EEG mat file.'};

timewin         = cfg_entry;
timewin.tag     = 'timewin';
timewin.name    = 'Time window';
timewin.strtype = 'r';
timewin.num     = [1 2];
timewin.val     = {[-Inf Inf]};
timewin.help    = {'Time window (ms)'};

condlabel = cfg_entry;
condlabel.tag = 'conditions';
condlabel.name = 'Condition label';
condlabel.strtype = 's';
condlabel.help = {''};

conditions = cfg_repeat;
conditions.tag = 'condrepeat';
conditions.name = 'Conditions';
conditions.help = {'Specify the labels of the conditions to include in the SVD.'};
conditions.num  = [0 Inf];
conditions.values  = {condlabel};
conditions.val = {};

ncomp = cfg_entry;
ncomp.tag = 'ncomp';
ncomp.name = 'Number of components';
ncomp.strtype = 'n';
ncomp.num = [1 1];
ncomp.help = {'Number of confound components to keep.'};

threshold = cfg_entry;
threshold.tag = 'threshold';
threshold.name = 'Threshold';
threshold.strtype = 'r';
threshold.val = {NaN};
threshold.num = [1 1];
threshold.help = {'Threshold for data amplitude after correction.',...
    'If defined this overrides number of components.'};

svd = cfg_branch;
svd.tag = 'svd';
svd.name = 'SVD';
svd.val = {timewin, conditions, threshold, ncomp};
svd.help = {'Define confounds from SVD of artefact samples.'};

conffile = cfg_files;
conffile.tag = 'conffile';
conffile.name = 'File name';
conffile.filter = 'mat';
conffile.num = [1 1];
conffile.help = {'Select the EEG mat file.'};

spmeeg = cfg_branch;
spmeeg.tag = 'spmeeg';
spmeeg.name = 'SPM M/EEG dataset';
spmeeg.val = {conffile};
spmeeg.help = {'Load confounds defined in a different dataset.'};

conffile = cfg_files;
conffile.tag = 'conffile';
conffile.name = 'BESA confounds file';
conffile.filter = '.*.bsa';
conffile.num = [1 1];
conffile.help = {'Select the EEG mat file.'};

besa = cfg_branch;
besa.tag = 'besa';
besa.name = 'BESA';
besa.val = {conffile};
besa.help = {'Load confounds defined in BESA from a .bsa file.'};

eyes = cfg_const;
eyes.tag = 'eyes';
eyes.name = 'Eyes';
eyes.val  = {1};
eyes.help = {'Defined confounds based on standard locations for the eyes',...
    'This is a very crude method, a data-driven method is preferable'};

clr = cfg_const;
clr.tag = 'clear';
clr.name = 'Clear';
clr.val  = {1};
clr.help = {'Clear previously defined spatial confounds.'};

mode = cfg_repeat;
mode.tag = 'mode';
mode.name = 'Mode';
mode.values = {svd, spmeeg, besa, eyes, clr};
mode.help = {'Select methods for defining spatial confounds.'};

sconfounds = cfg_exbranch;
sconfounds.tag = 'sconfounds';
sconfounds.name = 'Define spatial confounds';
sconfounds.val = {D, mode};
sconfounds.help = {'Define spatial confounds for topography-based correction of artefacts.'};
sconfounds.prog = @eeg_sconfounds;
sconfounds.vout = @vout_eeg_sconfounds;
sconfounds.modality = {'EEG'};

function out = eeg_sconfounds(job)

D = char(job.D{1});

for i = 1:numel(job.mode)
    mode = job.mode{i};
    S = [];
    S.D = D;
    S.mode = char(fieldnames(mode));
    switch S.mode
        case 'svd'
            if ~isnan(mode.svd.threshold)
                S.threshold = mode.svd.threshold;
            else
                S.ncomp = mode.svd.ncomp;
            end
            S.timewin = mode.svd.timewin;
        case {'besa', 'spmeeg'}
            S.conffile = char(mode.(S.mode).conffile);
        otherwise
            % do nothing
    end

    D = spm_eeg_spatial_confounds(S);
end

out.D = {fullfile(D)};

function dep = vout_eeg_sconfounds(job)
% Output is always in field "D", no matter how job is structured
dep = cfg_dep;
dep.sname = 'Dataset with spatial confounds';
% reference field "D" from output
dep.src_output = substruct('.','D');
% this can be entered into any evaluated input
dep.tgt_spec   = cfg_findspec({{'filter','mat'}});


function [ icpPoseNew ] = poseSparsification_yq( savePoseName, saveIndexName, icpPose, expDis )
%POSESPARCIFICATION Summary of this function goes here
%   Detailed explanation goes here

    % YQ dataset, data preparation
    % same for park dataset

    keepIndex = [1];
    icpPoseNew(1,:) = icpPose(1,:); % for plotting

    cnt = 1;
    for i = 2:length(icpPose)
        pose1 = [icpPose(i,4), icpPose(i,8)];
        pose2 = [icpPose(keepIndex(cnt),4), icpPose(keepIndex(cnt),8)];
        dis = norm(pose1 - pose2);

        if dis > expDis
            cnt = cnt + 1;
            keepIndex(cnt,:) = i;
            icpPoseNew(cnt,:) = icpPose(i,:);
        end
    end

    keepIndex = keepIndex - 1; % from zero

    length(keepIndex)

    % save the index to the file
    dlmwrite(saveIndexName, keepIndex, 'delimiter', '\t');

    dlmwrite(savePoseName, icpPoseNew, 'delimiter', '\t');

end


function relm_PaintSet(vRelm_LTest, vRelm_RTest)

figure

nLen = length(vRelm_LTest);
for nCnt = 1:nLen
  H = subplot(nLen, 2, (nCnt*2)-1);
  relm_PaintCumPlot(vRelm_LTest(nCnt), 'Log-Likelihood', H);
  H = subplot(nLen, 2, (nCnt*2));
  relm_PaintCumPlot(vRelm_RTest(nCnt), 'Log-Likelihood Ratio', H);
end


function opt = TSEMO_options
% Copyright (c) by Eric Bradford, Artur M. Schweidtmann and Alexei Lapkin, 2017-13-12.

% Description: Create TSEMO options structure.
opt.maxeval = 35;                   % Maximum number of function evaluations

for i = 1:3                         % this is only valid for up to 3 objectives. Number needs to be increased for more than 3.
opt.GP(i).nSpectralpoints = 4000;   % Number of spectral sampling points for objective i
opt.GP(i).matern = 1;               % Matern type 1 / 3 / 5 / inf for objective i
opt.GP(i).fun_eval = 200;           % Function evaluations by direct algorithm per input dimension for objective i
end

opt.pop = 100;                      % Genetic algorithm population size
opt.Generation = 100;               % Genetic algorithm number of generations
opt.NoOfBachSequential = 1;         % Batch size
end


function [data] = ft_nirs_transform_ODs(cfg, data)

% FT_NIRS_TRANSFORM_ODs computes the transformation from optical densities (OD)
% to chromophore concentrations such as (de-)oxygenated  hemoglobin, or the
% other way around.
%
% Use as either
%   [data]      = ft_nirs_transform_ODs(cfg, data)
%
% The configuration "cfg" is a structure containing information about
% target of the transformation. The configuration should contain
%   cfg.channel            = Nx1 cell-array with selection of channels
%                            (default = 'nirs'), see FT_CHANNELSELECTION for
%                            more details
%   cfg.target             = Mx1 cell-array, can be 'O2Hb' (oxygenated hemo-
%                            globin), 'HHb' de-oxygenated hemoglobin') or
%                            'tHb' (total hemoglobin), or a combination of
%                            those (default: {'O2Hb', 'HHb'})
%
% Optional configuration settings are
%   cfg.age                = scalar, age of the subject (necessary to
%                            automatically select the appropriate DPF, or
%   cfg.dpf                = scalar, differential path length factor
%   cfg.dpffile            = string, location to a lookup table for the
%                            relation between participant age and DPF
%
% Note that the DPF might be different across channels, and is usually
% stored in the optode structure contained in the data.
%
% The function returns data transformed to the specified chromophore
% concentrations that were requested.
%
% To facilitate data-handling and distributed computing you can use
%   cfg.inputfile   =  ...
% If you specify this option the input data will be read from a *.mat
% file on disk. This mat files should contain only a single variable named 'data',
% corresponding to the input structure.
%
% See also FT_NIRS_PREPARE_ODTRANSFORMATION, FT_APPLY_MONTAGE

% Options to be implemented:
%   cfg.opto          = structure with optode definition or filename, see FT_READ_SENS
%   cfg.siunits       = yes/no, ensure that SI units are used consistently
%   cfg.logarithm     = string, can be 'natural' or 'base10' (default = 'base10')
%   cfg.inverse       = string, whether the multiplicative inverse should be take
%
% Note that HomER uses the inverse, natural logarithm. The inverse is taken
% after the ln transform.

% You are using the FieldTrip NIRS toolbox developed and maintained by
% Artinis Medical Systems (http://www.artinis.com). For more information
% on FieldTrip, see http://www.fieldtriptoolbox.org
%
% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
% International License. To view a copy of this license, visit
% http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to
% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%
% Creative Commons Attribution-ShareAlike 4.0 International License:
% -----------------------------------
% You are free to:
%
%     Share - copy and redistribute the material in any medium or format
%     Adapt - remix, transform, and build upon the material
%     for any purpose, even commercially.
%
%     The licensor cannot revoke these freedoms as long as you follow the
%     license terms.
%
% Under the following terms:
%
%     Attribution - You must give appropriate credit, provide a link to
%                    the license, and indicate if changes were made. You
%                    may do so in any reasonable manner, but not in any way
%                    that suggests the licensor endorses you or your use.
%
%     ShareAlike - If you remix, transform, or build upon the material,
%                   you must distribute your contributions under the same
%                   license as the original.
%
%     No additional restrictions - You may not apply legal terms or
%                                   technological measures that legally
%                                   restrict others from doing anything the
%                                   license permits.
%
% -----------------------------------
%
% This toolbox is not to be used for medical or clinical purposes.
%
% Copyright (c) 2015-2016 by Artinis Medical Systems.
% Contact: askforinfo@artinis.com
%
% Main programmer: Jörn M. Horschig
% $Id$

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

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

ft_preamble debug

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  % do not continue function execution in case the outputfile is present and the user indicated to keep it
  return
end

data = ft_checkdata(data, 'datatype', 'raw', 'feedback', 'yes');

% set the defaults
cfg.channel = ft_getopt(cfg, 'channel', 'nirs');
cfg.target  = ft_getopt(cfg, 'target', {'O2Hb', 'HHb'});

% determine the NIRS channels
cfg.channel = ft_channelselection(cfg.channel, data);

% make a copy of the data
origdata = data;

% keep only the NIRS channels
data = ft_selectdata(cfg, data);

% also keep the non-NIRS channels
tmpcfg = cfg;
tmpcfg.channel = setdiff(origdata.label, cfg.channel);
dataextra = ft_selectdata(tmpcfg, origdata);

target = cfg.target;
if ~iscell(target)
  target     = {target};
end

computetHb  = any(ismember(target, 'tHb'));
computeHHb  = any(ismember(target, 'HHb'));
computeO2Hb = any(ismember(target, 'O2Hb'));

% cfg-handling is done inside here
[montage, cfg] = ft_nirs_prepare_ODtransformation(cfg, data);

% save montage in the cfg
cfg.montage = montage;

% apply the (combined) montages
dataout = ft_apply_montage(data, montage, 'keepunused', 'yes');

if computetHb
  % total hemoglobin is the sum of oxygenated and deoxygenated hemoglobin
  tmpcfg = [];
  tmpcfg.channel = '*[O2Hb]';
  dataO2Hb = ft_selectdata(tmpcfg, dataout);
  dataO2Hb.label = strrep(dataO2Hb.label, 'O2Hb', 'tHb');

  tmpcfg = [];
  tmpcfg.channel = '*[HHb]';
  dataHHb = ft_selectdata(tmpcfg, dataout);
  dataHHb.label = strrep(dataHHb.label, 'HHb', 'tHb');

  tmpcfg = [];
  tmpcfg.operation = 'add';
  tmpcfg.parameter = 'trial';
  dataTotal = ft_math(tmpcfg, dataO2Hb, dataHHb);

  if ~computeHHb && ~computeO2Hb
    % replace dataout
    dataout.label = dataTotal.label;
    dataout.trial = dataTotal.trial;
  else
    % concat to dataout
    dataout.label = vertcat(dataout.label, dataTotal.label);
    dataout.trial = cellfun(@vertcat, dataout.trial, dataTotal.trial, 'UniformOutput', false);
  end
end

% remove O2 or H if not desired
tmpcfg = [];
tmpcfg.channel = [];
if computetHb
  tmpcfg.channel = horzcat(tmpcfg.channel, {'*tHb]'});
end
if computeHHb
  tmpcfg.channel =  horzcat(tmpcfg.channel, {'*HHb]'});
end
if computeO2Hb
  tmpcfg.channel =  horzcat(tmpcfg.channel, {'*O2Hb]'});
end

dataout = ft_selectdata(tmpcfg, dataout);

if length(dataextra.label)>0
  % append the extra data
  data = ft_appenddata([], dataout, dataextra);
else
  data = dataout;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug

ft_postamble previous    data
ft_postamble provenance  data
ft_postamble history     data


function scrollplotdemo

% Created by Steven Lord, slord@mathworks.com
% Uploaded to MATLAB Central
% http://www.mathworks.com/matlabcentral
% 7 May 2002
%
% Permission is granted to adapt this code for your own use.
% However, if it is reposted this message must be intact.

% Generate and plot data
x=0:1e-2:2*pi;
y=sin(x);
dx=2;
%% dx is the width of the axis 'window'
a=gca;
p=plot(x,y);

% Set appropriate axis limits and settings
set(gcf,'doublebuffer','on');
%% This avoids flickering when updating the axis
set(a,'xlim',[0 dx]);
set(a,'ylim',[min(y) max(y)]);

% Generate constants for use in uicontrol initialization
pos=get(a,'position');
Newpos=[pos(1) pos(2)-0.1 pos(3) 0.05];
%% This will create a slider which is just underneath the axis
%% but still leaves room for the axis labels above the slider
xmax=max(x);
S=['set(gca,''xlim'',get(gcbo,''value'')+[0 ' num2str(dx) '])'];
%% Setting up callback string to modify XLim of axis (gca)
%% based on the position of the slider (gcbo)

% Creating Uicontrol
h=uicontrol('style','slider',...
    'units','normalized','position',Newpos,...
    'callback',S,'min',0,'max',xmax-dx);


function [ params ] = setEdgeBoxesParamsFromConfig( config)

%%Loading Default Parameters here
%(1) main parameters
%   .name           - [] target filename (if specified return is 1)
%   .alpha          - [.65] step size of sliding window search
%   .beta           - [.75] nms threshold for object proposals
%   .minScore       - [.01] min score of boxes to detect
%   .maxBoxes       - [1e4] max number of boxes to detect

config.params.name=[];
if isfield(config.params, 'alpha')
	config.params.alpha=[config.params.alpha];
end
if isfield(config.params, 'beta')
	config.params.beta=[config.params.beta];
end
if isfield(config.params, 'minScore')
	config.params.minScore=[config.params.minScore];
end
if isfield(config.params, 'maxBoxes')
	config.params.maxBoxes=[config.params.maxBoxes];
end

%(2)  additional parameters, safe to ignore and leave at default vals

%   .edgeMinMag     - [.1] increase to trade off accuracy for speed
%   .edgeMergeThr   - [.5] increase to trade off accuracy for speed
%   .clusterMinMag  - [.5] increase to trade off accuracy for speed
%   .maxAspectRatio - [3] max aspect ratio of boxes
%   .minBoxArea     - [1000] minimum area of boxes
%   .gamma          - [2] affinity sensitivity, see equation 1 in paper
%   .kappa          - [1.5] scale sensitivity, see equation 3 in paper

if isfield(config.params, 'edgeMinMag')
	config.params.edgeMinMag = [config.params.edgeMinMag];
end
if isfield(config.params, 'edgeMergeThr')
	config.params.edgeMergeThr = [config.params.edgeMergeThr];
end
if isfield(config.params, 'clusterMinMag')
	config.params.clusterMinMag  = [config.params.clusterMinMag];
end
if isfield(config.params, 'maxAspectRatio')
	config.params.maxAspectRatio = [config.params.maxAspectRatio];
end
if isfield(config.params, 'minBoxArea')
	config.params.minBoxArea= [config.params.minBoxArea] ;
end
if isfield(config.params, 'gamma')
	config.params.gamma=[config.params.gamma];
end
if isfield(config.params, 'kappa')
	config.params.kappa=[config.params.kappa];
end

params = config.params;

end


function mesh_write_fs_curv(p)

% mesh_write_fs_curv - Save mesh CData to FreeSurfer curvature file
%
% USEAGE: mesh_write_fs_curv(p)
%
% Write a binary curvature file for each mesh in p.mesh.data.
% If any cells of p.mesh.data.meshtype are empty, they are skipped.
%
% This function outputs an *.curv curvature file from the
% vertex scalar data contained in p.mesh.data.Cdata - if it
% contains a timeseries, the output values are taken from
% the column specified in p.mesh.samplePoint.
%
% All output is handled by fs_write_curv.
%
% See the FreeSurfer website at http://surfer.nmr.mgh.harvard.edu/
% for more information.
%

% $Revision: 1.1 $ $Date: 2009-04-28 22:13:58 $

% Licence:  GNU GPL, no implied or express warranties
% History:  10/2002, Darren.Weber_at_radiology.ucsf.edu
%           01/2003, Darren.Weber_at_radiology.ucsf.edu
%                    now using fs_write_surf and fs_write_wfile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fprintf('\nMESH_WRITE_FS_CURV...\n');

if ~exist('p','var'),
    error('...no input p struct.\n');
elseif isempty(p),
    error('...input p struct is empty.\n');
elseif isempty(p.mesh.data),
    error('...input p struct has no mesh data.\n');
end

[path,name,ext] = fileparts(strcat(p.mesh.path,filesep,p.mesh.file));
file = fullfile(path,[name ext]);

fprintf('...writing FreeSurfer curvatures to:\n\t%s\n',path);

tic;

Meshes = p.mesh.data.meshtype;

[path,name,ext] = fileparts(file);

for i=1:size(Meshes,2),

    if Meshes{i},

        % check for mesh Cdata
        if size(p.mesh.data.Cdata,2) >= i,
            if ~isempty(p.mesh.data.Cdata{1}),
                if size(p.mesh.data.Cdata{i},2) > 1,
                    % Obtain the Cdata at the selected time point
                    curv = p.mesh.data.Cdata{i}(:,p.mesh.samplePoint);
                else
                    curv = p.mesh.data.Cdata{i};
                end

                Nfaces = size(p.mesh.data.faces{i},1);

                outputExt = [ext,'.curv'];
                outputName = strcat(name,'.',Meshes{i});
                outputFile = fullfile(path,[outputName outputExt]);

                fprintf('...writing curvature: %s\n',[outputName outputExt]);
                fs_write_curv(outputFile,curv,Nfaces);
            else
                msg = sprintf('\np.mesh.data.Cdata{%d} is empty\n',i);
                warning(msg);
            end
        else
            msg = sprintf('\nno p.mesh.data.Cdata{%d}\n',i);
            warning(msg);
        end
    end
end

t=toc; fprintf('...done (%5.2f sec).\n\n',t);

return