classdef ShapeTransformer < handle
    %SHAPETRANSFORMER  Base class for shape transformation algorithms
    %
    % See also: cv.ShapeTransformer.ShapeTransformer,
    %  cv.ShapeContextDistanceExtractor, tpaps
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    properties (Dependent, Hidden)
        % The regularization parameter for relaxing the exact interpolation
        % requirements of the TPS algorithm.
        % Beta value of the regularization parameter, default 0
        % (only applicable for ThinPlateSplineShapeTransformer)
        RegularizationParameter
        % default true
        % (only applicable for AffineTransformer)
        FullAffine
    end

    %% Constructor/destructor
    methods
        function this = ShapeTransformer(transformerType, varargin)
            %SHAPETRANSFORMER  Constructor
            %
            %     obj = cv.ShapeTransformer(transformerType)
            %     obj = cv.ShapeTransformer(transformerType, 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __transformerType__ an algorithm that defines the aligning
            %   transformation. One of:
            %   * __ThinPlateSplineShapeTransformer__ Definition of the
            %     transformation occupied in the paper [Bookstein89].
            %   * __AffineTransformer__ Wrapper class for the OpenCV Affine
            %     Transformation algorithm. See cv.estimateRigidTransform,
            %     cv.warpAffine, and cv.transform
            %
            % ## Options
            % The following are options for the various algorithms:
            %
            % ### `ThinPlateSplineShapeTransformer`
            % * __RegularizationParameter__ The regularization parameter for
            %   relaxing the exact interpolation requirements of the TPS
            %   algorithm. default 0
            %
            % ### `AffineTransformer`
            % * __FullAffine__ see cv.estimateRigidTransform, default true
            %
            % ## References
            % [Bookstein89]:
            % > "Principal Warps: Thin-Plate Splines and Decomposition of
            % > Deformations", by F.L. Bookstein (PAMI 1989)
            %
            % See also: cv.ShapeTransformer.estimateTransformation
            %
            this.id = ShapeTransformer_(0, 'new', transformerType, varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.ShapeTransformer
            %
            if isempty(this.id), return; end
            ShapeTransformer_(this.id, 'delete');
        end
    end

    %% ShapeTransformer
    methods
        function estimateTransformation(this, transformingShape, targetShape, matches)
            %ESTIMATETRANSFORMATION  Estimate the transformation parameters of the current transformer algorithm, based on point matches
            %
            %     obj.estimateTransformation(transformingShape, targetShape, matches)
            %
            % ## Input
            % * __transformingShape__ Contour defining first shape. A numeric
            %   Nx2/Nx1x2/1xNx2 array or a cell-array of 2D points
            %   `{[x,y], ...}`
            % * __targetShape__ Contour defining second shape (target). Same
            %   format as `transformingShape`.
            % * __matches__ Standard vector of matches between points.
            %
            % See also: cv.ShapeTransformer.applyTransformation,
            %  cv.ShapeTransformer.warpImage
            %
            ShapeTransformer_(this.id, 'estimateTransformation', transformingShape, targetShape, matches);
        end

        function [cost, output] = applyTransformation(this, input)
            %APPLYTRANSFORMATION  Apply a transformation, given a pre-estimated transformation parameters
            %
            %     [cost, output] = obj.applyTransformation(input)
            %
            % ## Input
            % * __input__ Contour (set of points) to apply the transformation.
            %
            % ## Output
            % * __cost__ Transformation cost.
            % * __output__ Output contour.
            %
            % See also: cv.ShapeTransformer.estimateTransformation
            %
            [cost, output] = ShapeTransformer_(this.id, 'applyTransformation', input);
        end

        function output = warpImage(this, transformingImage, varargin)
            %WARPIMAGE  Apply a transformation, given a pre-estimated transformation parameters, to an Image
            %
            %     output = obj.warpImage(transformingImage)
            %     output = obj.warpImage(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __transformingImage__ Input image.
            %
            % ## Output
            % * __output__ Output image.
            %
            % ## Options
            % * __Interpolation__ Image interpolation method. default 'Linear'
            % * __BorderType__ border style. default 'Constant'
            % * __BorderValue__ border value. default 0
            %
            % See cv.remap or cv.warpAffine for options description.
            %
            % See also: cv.ShapeTransformer.estimateTransformation
            %
            output = ShapeTransformer_(this.id, 'warpImage', transformingImage, varargin{:});
        end
    end

    %% Algorithm
    methods
        function clear(this)
            %CLEAR  Clears the algorithm state
            %
            %     obj.clear()
            %
            % See also: cv.ShapeTransformer.empty, cv.ShapeTransformer.load
            %
            ShapeTransformer_(this.id, 'clear');
        end

        function b = empty(this)
            %EMPTY  Returns true if the algorithm is empty
            %
            %     b = obj.empty()
            %
            % ## Output
            % * __b__ Returns true if the detector object is empty (e.g in the
            %   very beginning or after unsuccessful read).
            %
            % See also: cv.ShapeTransformer.clear, cv.ShapeTransformer.load
            %
            b = ShapeTransformer_(this.id, 'empty');
        end

        function save(this, filename)
            %SAVE  Saves the algorithm parameters to a file
            %
            %     obj.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in the specified
            % XML or YAML file.
            %
            % See also: cv.ShapeTransformer.load
            %
            ShapeTransformer_(this.id, 'save', filename);
        end

        function load(this, fname_or_str, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     obj.load(fname)
            %     obj.load(str, 'FromString',true)
            %     obj.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from the specified XML or
            % YAML file (either from disk or serialized string). The previous
            % algorithm state is discarded.
            %
            % See also: cv.ShapeTransformer.save
            %
            ShapeTransformer_(this.id, 'load', fname_or_str, varargin{:});
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = obj.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.ShapeTransformer.save, cv.ShapeTransformer.load
            %
            name = ShapeTransformer_(this.id, 'getDefaultName');
        end
    end

    %% Getters/Setters
    methods
        function value = get.RegularizationParameter(this)
            value = ShapeTransformer_(this.id, 'get', 'RegularizationParameter');
        end
        function set.RegularizationParameter(this, value)
            ShapeTransformer_(this.id, 'set', 'RegularizationParameter', value);
        end

        function value = get.FullAffine(this)
            value = ShapeTransformer_(this.id, 'get', 'FullAffine');
        end
        function set.FullAffine(this, value)
            ShapeTransformer_(this.id, 'set', 'FullAffine', value);
        end
    end

end


function box_overlaps=get_gt_overlap_box(reg2sp, sp, instimg)
if(all(instimg==0)) box_overlaps=zeros(0,size(reg2sp,2)); return; end
boxes=get_region_boxes(sp, reg2sp);
instimg=double(instimg);
insts=unique(instimg(instimg~=0));
gt_boxes=zeros(numel(insts),4);
for i=1:numel(insts)
    [I,J]=find(instimg==insts(i));
    I=I(:); J=J(:);
    gt_boxes(i,:)=[min(J) min(I) max(J) max(I)];
end
boxes(:,3:4)=boxes(:,3:4)-boxes(:,1:2)+1;
gt_boxes(:,3:4)=gt_boxes(:,3:4)-gt_boxes(:,1:2)+1;
int=rectint(boxes, gt_boxes);
uni=bsxfun(@plus, prod(boxes(:,3:4),2), prod(gt_boxes(:,3:4),2)')-int;
box_overlaps=int./(uni+double(uni~=0));
box_overlaps=box_overlaps';


function [exponents,base]=getexponentbase(p,x)
%GETEXPONENTBASE Internal function used in SOS programs

if isempty(p)
    exponents=[];
    base=[];
else
    p_vars = getvariables(p);
    x_vars = getvariables(x);

    base = getbase(p);

    monom_table = yalmip('monomtable');
    exponents = monom_table(p_vars,x_vars);
    if any(base(:,1))%base(1)~=0
        exponents = [spalloc(1,size(exponents,2),0);exponents];
    else
        base = base(:,2:end);
    end
end


function [ x, know ] = p00_sol ( problem, m, know )

%*****************************************************************************80
%
%% P00_SOL returns known solutions for a problem specified by index.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the problem index.
%
%    Input, integer M, the order of the problem.
%
%    Input/output, integer KNOW.
%    On input, KNOW is 0, or the index of the previously returned solution.
%    On output, KNOW is 0 if there are no more solutions, or it is the
%    index of the next solution.
%
%    Output, real X(M), the solution.
%
  if ( problem == 1 )
    [ x, know ] = p01_sol ( m, know );
  elseif ( problem == 2 )
    [ x, know ] = p02_sol ( m, know );
  elseif ( problem == 3 )
    [ x, know ] = p03_sol ( m, know );
  elseif ( problem == 4 )
    [ x, know ] = p04_sol ( m, know );
  elseif ( problem == 5 )
    [ x, know ] = p05_sol ( m, know );
  elseif ( problem == 6 )
    [ x, know ] = p06_sol ( m, know );
  elseif ( problem == 7 )
    [ x, know ] = p07_sol ( m, know );
  elseif ( problem == 8 )
    [ x, know ] = p08_sol ( m, know );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_SOL - Fatal error!\n' );
    fprintf ( 1, '  Problem index out of bounds.\n' );
    error ( 'P00_SOL - Fatal error!' );
  end

  return
end


function pos = findhashsorted(x,searchfor)

if numel(x) < 1000
    % Short enough use built-in despite being sorted...
    pos = find(x == searchfor);
else
    % Long enough to warrant a bisection search, JITs fine
    if searchfor>x(end)
        pos = [];
        return
    elseif searchfor < x(1)
        pos = [];
        return
    elseif searchfor == x(1)
        pos = 1;
        return
    elseif searchfor == x(end)
        pos = numel(x);
        return
    end
    low=1;
    high=numel(x);
    pos=[];
    d=numel(x);
    while high-low > 1
        mid = floor((low+high)/2);
        val = x(mid);
        if val > searchfor
            high = mid;
        elseif val < searchfor
            low = mid;
        else
            pos = mid;
            break
        end
    end
end


% SetValueOfAssignment Sets the value of a variable assignment in a factor.
%
%   F = SetValueOfAssignment(F, A, v) sets the value of a variable assignment,
%   A, in factor F to v. The order of the variables in A are assumed to be the
%   same as the order in F.var.
%
%   F = SetValueOfAssignment(F, A, v, VO) sets the value of a variable
%   assignment, A, in factor F to v. The order of the variables in A are given
%   by the vector VO.
%
%   Note that SetValueOfAssignment *does not modify* the factor F that is
%   passed into the function, but instead returns a modified factor with the
%   new value(s) for the specified assignment(s). This is why we have to
%   reassign F to the result of SetValueOfAssignment in the code snippets
%   shown above.
%
%   See also GetValueOfAssignment.m and SampleFactors.m
%
% Copyright (C) Daphne Koller, Stanford University, 2012

function F = SetValueOfAssignment(F, A, v, VO)

if (nargin == 3),
    indx = AssignmentToIndex(A, F.card);
else
    map = zeros(length(F.var), 1);
    for i = 1:length(F.var),
        map(i) = find(VO == F.var(i));
    end;
    indx = AssignmentToIndex(A(map), F.card);
end;

F.val(indx) = v;

end


classdef TestGroupRectanglesMeanShift
    %TestGroupRectanglesMeanShift

    methods (Static)
        function test_cell
            rcts = {[ 0, 1,10,10], ...
                    [ 1, 1,11,11], ...
                    [10,10,20,20], ...
                    [12,12,21,21], ...
                    [30,40,10,20]};
            weights = ones(size(rcts));
            scales = ones(size(rcts));
            [rslts,w] = cv.groupRectangles_meanshift(rcts, weights, scales);
            if ~isempty(rslts)
                validateattributes(rslts, {'cell'}, {'vector'});
                cellfun(@(r) validateattributes(r, {'numeric'}, ...
                    {'vector', 'integer', 'numel',4}), rslts);
                validateattributes(w, {'numeric'}, ...
                    {'vector', 'numel',numel(rslts)});
            end
        end

        function test_error_argnum
            try
                cv.groupRectangles_meanshift();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function varargout = WFT(varargin)
% Function:             Windowed Fourier transform (interface)
% Initially Developed:  Dr Qian Kemao (16 May 2009)
% Last modified:        Dr Qian Kemao (17 May 2009)
% Version:              1.0
% Copyrights:           All rights reserved.
% Contact:              mkmqian@ntu.edu.sg (Dr Qian Kemao)

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

% Last Modified by GUIDE v2.5 20-May-2009 08:55:16

% Begin initialization code - DO NOT EDIT

%sturcture of g:
%f:                 original data
%filtered:          filtered version of f
%wrapped:           wrapped phase
%unwrapped:         unwrapped phase
%PathMap:           unwrapping path
%g.wx:              wx from wfr
%g.wy:              wy from wfr
%g.r:               r from wfr
%g.phase:           phase from wfr
%g.FringeType:      1~4
%g.AlgorithmType:   'wff' or 'wfr'
%g.a:               background intensity

gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @WFT_OpeningFcn, ...
                   'gui_OutputFcn',  @WFT_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 pushbutton_CallWFTKernel is made visible.
function WFT_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 pushbutton_CallWFTKernel (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes pushbutton_CallWFTKernel wait for user response (see UIRESUME)
% uiwait(handles.figure_WFT);

% --- Outputs from this function are returned to the command line.
function varargout = WFT_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 pushbutton_LoadMat.
function pushbutton_LoadMat_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_LoadMat (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname, filterindex] = uigetfile( ...
        '*.mat',  'MATLAB data (*.mat)','Pick a file');
if filterindex~=0
    load (strcat(pathname,filename));
    g.filtered=g.f;
    g.unwrapped=[];
    g.PathMap=[];
    imagesc(angle(g.f))
    colormap gray;
    save result g;
end

% --- Executes on button press in pushbutton_ReadfII.
function pushbutton_ReadfII_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ReadfII (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname, filterindex] = uigetfile( ...
        {'*.jpg;*.bmp;*.tif;', 'Image files (*.jpg, *.bmp, *.tif)'; ...
        '*.jpg',  'jpg (*.jpg)'; ...
        '*.bmp','bmp (*.bmp)'; ...
        '*.tif','tif (*.tif)'}, ...
        'Pick a file');
if filterindex~=0
    g.wrapped=double(imread(strcat(pathname,filename)));
    g.wrapped=g.wrapped(:,:,1);
    valmax=max(max(g.wrapped));
    valmin=min(min(g.wrapped));
    g.wrapped=(g.wrapped-valmin)/(valmax-valmin)*2*pi-pi;
    g.f=exp(sqrt(-1)*g.wrapped);
    g.filtered=g.f;
    g.unwrapped=[];
    g.PathMap=[];
    g.FringeType=2;
    imagesc(angle(g.f))
    colormap gray;
    save result g;
end

% --- Executes on button press in pushbutton_ReadfIII.
function pushbutton_ReadfIII_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ReadfIII (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname, filterindex] = uigetfile( ...
        {'*.jpg;*.bmp;*.tif;', 'Image files (*.jpg, *.bmp, *.tif)'; ...
        '*.jpg',  'jpg (*.jpg)'; ...
        '*.bmp','bmp (*.bmp)'; ...
        '*.tif','tif (*.tif)'}, ...
        'Pick a file');
if filterindex~=0
    g.f=double(imread(strcat(pathname,filename)));
    g.f=g.f(:,:,1);
    g.a=mean2(g.f);
    g.f=g.f-g.a;
    g.filtered=g.f;
    g.unwrapped=[];
    g.PathMap=[];
    g.FringeType=3;
    imagesc(g.f)
    colormap gray;
    save result g;
end

% --- Executes on button press in pushbutton_ReadfIV.
function pushbutton_ReadfIV_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ReadfIV (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname, filterindex] = uigetfile( ...
        {'*.jpg;*.bmp;*.tif;', 'Image files (*.jpg, *.bmp, *.tif)'; ...
        '*.jpg',  'jpg (*.jpg)'; ...
        '*.bmp','bmp (*.bmp)'; ...
        '*.tif','tif (*.tif)'}, ...
        'Pick a file');
if filterindex~=0
    g.f=double(imread(strcat(pathname,filename)));
    g.f=g.f(:,:,1);
    g.a=mean2(g.f);
    g.f=g.f-g.a;
    g.filtered=g.f;
    g.unwrapped=[];
    g.PathMap=[];
    g.FringeType=4;
    imagesc(g.f)
    colormap gray;
    save result g;
end

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

% --- Executes on button press in pushbutton_qg.
function pushbutton_qg_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_qg (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result;
[g.unwrapped g.PathMap]=unwrapping_qg_trim(g.filtered);
imagesc(g.unwrapped)
save result g;

% --- Executes on button press in pushbutton_ViewOriginalPhase.
function pushbutton_ViewOriginalPhase_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewOriginalPhase (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result;
imagesc(angle(g.f));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.f)
    imwritescale(angle(g.f),'OriginalPhase.jpg');
end

% --- Executes on button press in pushbutton_ViewOriginalAmplitude.
function pushbutton_ViewOriginalAmplitude_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewOriginalAmplitude (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result;
imagesc(abs(g.f));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.f)
    imwritescale(abs(g.f),'OriginalAmplitude.jpg');
end

% --- Executes on button press in pushbutton_ViewFilteredPhase.
function pushbutton_ViewFilteredPhase_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewFilteredPhase (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(angle(g.filtered));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.filtered)
    imwritescale(angle(g.filtered),'FilteredPhase.jpg');
end

% --- Executes on button press in pushbutton_ViewFilteredAmplitude.
function pushbutton_ViewFilteredAmplitude_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewFilteredAmplitude (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(abs(g.filtered));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.filtered)
    imwritescale(abs(g.filtered),'FilteredAmplitude.jpg');
end

% --- Executes on button press in pushbutton_ViewUnwrappedPhase.
function pushbutton_ViewUnwrappedPhase_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewUnwrappedPhase (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(g.unwrapped);
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.unwrapped)
    imwritescale(g.unwrapped,'UnwrappedPhase.jpg');
end

% --- Executes on button press in pushbutton_ViewUnwrappingPath.
function pushbutton_ViewUnwrappingPath_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewUnwrappingPath (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(g.PathMap);
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.PathMap)
    imwritescale(g.PathMap,'UnwrappingPath.jpg');
end

% --- Executes on button press in pushbutton_ViewOriginalFringePattern.
function pushbutton_ViewOriginalFringePattern_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewOriginalFringePattern (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(real(g.f));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.f)
    imwritescale(real(g.f),'OriginalFringePattern.jpg');
end

% --- Executes on button press in pushbutton_ViewRealPartOfFilteredResult.
function pushbutton_ViewRealPartOfFilteredResult_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewRealPartOfFilteredResult (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(real(g.filtered));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.filtered)
    imwritescale(real(g.filtered),'RealPartOfFilteredResult.jpg');
end

% --- Executes on button press in pushbutton_ViewCosineOfFilteredPhase.
function pushbutton_ViewCosineOfFilteredPhase_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_ViewCosineOfFilteredPhase (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
load result
imagesc(cos(angle(g.filtered)));
H=findobj('Tag','checkbox_SaveOption');
val=get(H,'Value');
if val==1 & ~isempty(g.filtered)
    imwritescale(cos(angle(g.filtered)),'CosineOfFilteredPhase.jpg');
end

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

% Hint: get(hObject,'Value') returns toggle state of checkbox_SaveOption

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

% Hint: get(hObject,'Value') returns toggle state of checkbox_ViewColor

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

% Hint: get(hObject,'Value') returns toggle state of checkbox_ViewInColor
if get(hObject,'Value')==1
    colormap('default');
else
    colormap(gray);
end


function inspect_bug3157

% WALLTIME 00:10:00
% MEM 1gb
% DEPENDENCY

%%
ctf151      = ft_read_sens(dccnpath('/home/common/matlab/fieldtrip/data/test/original/meg/ctf151/Subject01.ds'));
neuromag122 = ft_read_sens(dccnpath('/home/common/matlab/fieldtrip/data/test/original/meg/neuromag122/jg_single_01raw.fif'));
neuromag306 = ft_read_sens(dccnpath('/home/common/matlab/fieldtrip/data/test/original/meg/neuromag306/raw.fif'), 'senstype', 'meg');

%%

rx = 30;
ry = 30;
rz = 30;

fake = [];
fake.unit = 'mm';
fake.coilpos = [
  10  0 0
  -10 -0 0
  ];
fake.coilpos = ft_warp_apply(rotate([rx ry rz]), fake.coilpos);
fake.coilori = [
  0 0 1
  0 0 1
  ];
fake.coilori = ft_warp_apply(rotate([rx ry rz]), fake.coilori);
fake.label = {
  '1'
  };
fake.tra = [
  1 -1
  ];

figure
ft_plot_sens(fake, 'coil', false, 'unit', 'mm', 'coilsize', 40, 'coilshape', 'square');
ft_plot_sens(fake, 'coil', true,  'unit', 'mm', 'coilsize', 0);
grid on

%%

figure
ft_plot_sens(ctf151, 'coil', false, 'unit', 'mm', 'coilsize', 15, 'coilshape', 'circle', 'chantype', 'meggrad');

%%

figure
ft_plot_sens(neuromag122, 'coil', false, 'unit', 'mm', 'coilsize', 35, 'coilshape', 'square', 'chantype', 'megplanar');

%%

figure
ft_plot_sens(neuromag306, 'coil', false, 'unit', 'mm', 'coilsize', 30, 'coilshape', 'square', 'chantype', 'megplanar');

%%

figure
ft_plot_sens(neuromag306, 'coil', false, 'unit', 'mm', 'coilsize', 30, 'coilshape', 'square', 'chantype', 'megplanar', 'facecolor', 'b', 'facealpha', 0.1);


function [verticeslist_org] = reorganize_verticeslist (mesh_total, A, mesh_outer, perim, verticeslist,step)

% --- Step 1: iterative reorganization of the vertices' list
% (each vertex must appear in the right order so that they can be
% subsequently linked together one by one).
% This uses mesh_vertex_nearest (D. Weber) and is based on the assumption
% that verticeslist are relatively regularly situated on a circle.

% NOTE: sometimes this function can return a small loop instead of the full
% perimeter and it's mandatory to check that with e.g. the size (number of
% vertices of the perimeter. Just starting the reorglist
% with another start_vertex usually overcomes that problem.
start_vertex=1;
reorglist=[];
while ( size (reorglist,2) ~= (size(verticeslist,2)+1) )

    if start_vertex>=size(verticeslist,2);
        step = step +1;
        [verticeslist]=SearchProjectionOnPial(mesh_total,mesh_outer,perim,step);
        start_vertex = 1;
    end

    reorglist=verticeslist(start_vertex);
    remaininglist=verticeslist;
    remaininglist(start_vertex)=[];

    % search the nearest vertex for the first vertex of the list (start_vertex)
    [nextindex,nextvalue]=mesh_vertex_nearest(mesh_total.vertices(remaininglist,:),mesh_total.vertices(verticeslist(start_vertex),:));
    clear nextvalue;

    % create the reorglist (reorganized list)
    reorglist=[reorglist remaininglist(nextindex)];

    % delete this vertex from the list of vertices (i.e. from the pool of
    % vertices to be reorganized)
    remaininglist(nextindex)=[];

    % repeat that one more time so that we are sufficiently far from the
    % start_vertex to add it to the pool of vertices to be reorganized.
    % Then continue iteratively until we close the loop by finding the start_vertex.
    [nextindex,nextvalue]=mesh_vertex_nearest(mesh_total.vertices(remaininglist,:),mesh_total.vertices(reorglist(2),:));
    clear nextvalue;
    reorglist=[reorglist remaininglist(nextindex)];
    remaininglist(nextindex)=[];

    % add the start_vertex
    remaininglist= [remaininglist verticeslist(start_vertex)];

    % continue to reorganize until start_vertex
    for z= 3: size(verticeslist,2)
        [nextindex,nextvalue]=mesh_vertex_nearest(mesh_total.vertices(remaininglist,:),mesh_total.vertices(reorglist(z),:));
        clear nextvalue;
        reorglist=[reorglist remaininglist(nextindex)];
        if remaininglist(nextindex) == verticeslist(start_vertex), break, end
            remaininglist(nextindex)=[];
    end
    start_vertex=start_vertex+1;
end

verticeslist_org = reorglist;
clear remaininglist;
clear nextindex;
clear nextvalue;


function pref = determineDiscretization(N, lengthDom, pref)
%DETERMINEDISCRETIZATION    Determine discretization for a CHEBOP object.
%
%   PREFOUT = DETERMINEDISCRETIZATION(N, LENGTHDOM, PREFIN) choses the
%   correct discretization PREFOUT.DISCRETIZATION to be used when solving
%   problems (BVP/EIGS/EXPM), modeled by a CHEBOP N.
%
% See also CHEBOP/CLEARPERIODICBC, CHEBOP/SOLVEBVP, CHEBOP/EIGS.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

% Case 1. A string was passed:
if ( isa(pref.discretization, 'char') )

    % Case 1.1. Determine the discretization if the user wants a discretization
    % using values:
    if ( strcmpi(pref.discretization, 'values') )
        % The default for the periodic case if TRIGCOLLOC. But, since TRIGCOLLOC
        % does not support breakpoints, it will be used only if there are no
        % breakpoints.
        if ( isa(N.bc, 'char') && strcmpi(N.bc, 'periodic') && lengthDom < 3 )
            pref.discretization = @trigcolloc;
        % Otherwise (i.e. periodic + breakpoints or other boundary
        % conditions), use CHEBCOLLOC2:
        else
            pref.discretization = @chebcolloc2;
        end

    % Case 1.2. Determine the discretization if the user wants a discretization
    % using coefficients:
    elseif ( strcmpi(pref.discretization, 'coeffs') )
        % Same here with TRIGSPEC and breakpoints:
        if ( isa(N.bc, 'char') && strcmpi(N.bc, 'periodic') && lengthDom < 3 )
            pref.discretization = @trigspec;
        else
            pref.discretization = @ultraS;
        end
    % Error:
    else
        error('CHEBFUN:CHEBOP:solvebvp:determineDiscretization', ...
        'PREF.DISCRETIZATION should be VALUES or COEFFS.\n')
    end

% Case 2. A function handle referring to a class was passed:
else
    % If TRIGCOLLOC or TRIGSPEC were chosen and there are breakpoints, we need
    % to throw an error:
    if ( ( isequal(pref.discretization, @trigcolloc) || ...
            isequal(pref.discretization, @trigspec) ) && lengthDom > 2 )
        error('CHEBFUN:CHEBOP:solvebvp:breakpointsInDomain', ...
        ['Problems with periodic boundary conditions where breakpoints \n', ...
        'are present cannot be solved with the TRIGCOLLOC/TRIGSPEC class.\n' ...
        'Please change the discretization to CHEBCOLLOC1/2 or ULTRAS.'])
    end
end

end


function dimensions=getPathwayDimensions(pathway)
% getPathwayDimensions
%   Retrieves the dimensions of metabolic network in a pathway structure.
%   Returns the position of the upper left corner, width and height.
%
%   pathway         pathway structure representing the pathway to be drawn
%
%   dimension       a 1x4 vector with x and y for the upper left corner,
%                   height and width
%
%   Usage: dimensions=getPathwayDimensions(pathway)

right=0;
left=inf;
top=inf;
bottom=0;

%Loops through the compartments to find the right and bottom border and the
%position of the upper left corner
for i=1:length(pathway.listOfCompartments)
    if pathway.listOfCompartments(1,i).x<left
        left=pathway.listOfCompartments(1,i).x;
    end
    if pathway.listOfCompartments(1,i).y<top
        top=pathway.listOfCompartments(1,i).y;
    end
    if (pathway.listOfCompartments(1,i).x+pathway.listOfCompartments(1,i).w)>right
        right=pathway.listOfCompartments(1,i).x+pathway.listOfCompartments(1,i).w;
    end
    if (pathway.listOfCompartments(1,i).y+pathway.listOfCompartments(1,i).h)>bottom
        bottom=pathway.listOfCompartments(1,i).y+pathway.listOfCompartments(1,i).h;
    end
end

%Loops through the species to find the object furthest to the right, left,
%top and bottom
for i=1:length(pathway.listOfSpecies)
    if pathway.listOfSpecies(1,i).x<left
        left=pathway.listOfSpecies(1,i).x;
    end
    if pathway.listOfSpecies(1,i).y<top
        top=pathway.listOfSpecies(1,i).y;
    end
    if (pathway.listOfSpecies(1,i).x+pathway.listOfSpecies(1,i).w)>right
        right=pathway.listOfSpecies(1,i).x+pathway.listOfSpecies(1,i).w;
    end
    if (pathway.listOfSpecies(1,i).y+pathway.listOfSpecies(1,i).h)>bottom
        bottom=pathway.listOfSpecies(1,i).y+pathway.listOfSpecies(1,i).h;
    end
end

dimensions=[left,top,right-left,bottom-top];
end


%for subplots

function p=plots1(x,y,z,img)

H1=abs(img);
colormap(hot)
subplot(x,y,z);
image(5*100*H1/max(max(H1)));%4 for B-727r;

if z==2
    title('ISAR images using Harmonic Wavelets');
end
if z==4
    ylabel('Range')
end
if z==8
    xlabel('Doppler')
end


% Map spike timestamps to some larger time vector
%
% This function return indices of ts that correspond to spikes values.
% The idea is that ts a long signal and spikes are found within it.
% One application is for example to match spikes to LFP signal.
%
%  USAGE
%   spkInd = general.spikes2time(spikes, ts)
%   spikes      Vector of spike timestamps. Units of spikes should be the
%               same as units of ts.
%   ts          Time signal. Vector or matrix. If matrix is provided,
%               the first column is taken as ts.
%   spkInd      Vector of indices in ts that correspond to spike values.
%
function spkInd = spikes2time(spikes, ts)
    if size(ts, 1) > 1 && size(ts, 2) > 1
        ts = ts(:, 1);
    else
        ts = ts(:);
    end
    % make sure it is a column
    spikes = spikes(:);

    spkInd = knnsearch(ts, spikes);
end


function status=sdephaseplot3(t,y,flag,w)
%SDEPHASEPLOT3  3-D phase space SDE output function.
%   When the function SDEPHASEPLOT3 is passed to an SDE solver as the
%   'OutputFUN' property, i.e., OPTIONS = SDESET('OutputFUN',@SDEPHASEPLOT3),
%   the solver calls SDEPHASEPLOT3(T,Y,'') after every timestep. The
%   SDEPHASEPLOT3 function plots the first three components of the solution, Y,
%   as they are computed, adapting the axis limits of the plot dynamically. To
%   plot particular components of the solution, specify their indices via the
%   'OutputYSelect' SDE options property. The first specified component is
%   plotted with respect to the X-axis, the second component with respect to the
%   Y-axis, and the third component with respect to the Z-axis.
%
%   At the start of integration, the solver calls SDEPHASEPLOT3(TSPAN,Y0,'init')
%   to initialize the output function. After each integration step to new time,
%   T, and solution vector, Y, the solver calls STATUS = SDEPHASEPLOT3(T,Y,'').
%   If the solver's 'Refine' property is greater than one (see SDESET), T is a
%   column vector of new output times and Y is an array of corresponding column
%   vectors. The STATUS return value is 1 if the figure window and plot axis are
%   still open and 0 otherwise. When the integration is complete, the solver
%   calls SDEPHASEPLOT3([],[],'done').
%
%   If fewer than three components of the solution, Y, are specified, one or two
%   components of the integrated Wiener increments, W, can be plotted versus Y
%   solution components or three integrated Wiener increment components can be
%   plotted. Set the 'OutputWSelect' SDE options property to 'yes' or to a
%   vector of indices to pass the integrated Wiener increments to SDEPHASEPLOT3
%   as a fourth argument, SDEPHASEPLOT3(T,Y,'',W). If the 'OutputWSelect'
%   property is set to 'yes' or a non-empty vector of indices the solver calls
%   SDEPHASEPLOT3(TSPAN,Y0,'init',W0) to initialize the output function at the
%   start of integration and SDEPHASEPLOT3([],[],'done',[]) when the integration
%   is complete.
%
%   See also:
%       SDEPLOT, SDEPHASEPLOT2, SDEIMGPLOT, SDEPRINT, SDESET, SDEGET, SDE_EULER,
%       SDE_MILSTEIN, SDE_BM, SDE_GBM, SDE_OU, ODEPHAS3

%   SDEPHASEPLOT3 is based on an updating of Matlab's ODEPHAS3,
%   version 1.27.4.10

%   Andrew D. Horchler, horchler @ gmail . com, 5-11-13
%   Revision: 1.2, 5-13-13

persistent FIG_HANDLE AX_HANDLE;
status = 1;         % Figure widow still open and and plot axis still present
isW = (nargin > 3); % Have integrated Wiener increments been passed
if nargin < 3
    flag = '';
end

switch flag
    case 'init'
        % Initialize persitent handle variables
        FIG_HANDLE = figure(gcf);
        AX_HANDLE = gca;

        % Set units to pixels to get width of axis, set back to default
        units = get(AX_HANDLE,'Units');
        set(AX_HANDLE,'Units','Pixels');
        pos = get(AX_HANDLE,'OuterPosition');
        set(AX_HANDLE,'Units',units);

        % Number of time samples to expect
        LEN_TSPAN = length(t);

        % Use figure axis width and TSPAN length determine redraw chunk
        chunk = min(ceil(LEN_TSPAN/pos(3)),LEN_TSPAN);

        % Number of solution variables, Y (cannot change)
        N = length(y);

        % Initialize UserData and Y
        ud = [];
        ud.y(3,chunk) = 0;
        ud.i = 1;

        if N >= 3
            ud.y(:,1) = y(1:3);
        elseif isW
            % Number of integrated Wiener increment variables, W (cannot change)
            D = length(w);

            if D+N >= 3
                if N == 2
                    ud.y(:,1) = [y(1:2);w(1)];
                elseif N == 1
                    ud.y(:,1) = [y(1);w(1:2)];
                else
                    ud.y(:,1) = w(1:3);
                end
            else
                error('SDETools:sdephaseplot3:TooFewInputsW',...
            	     ['Output function requires at least three solution '...
                      'components from Y or W.']);
            end
        else
            error('SDETools:sdephaseplot3:TooFewInputs',...
            	 ['Output function requires at least three solution '...
                  'components from Y.']);
        end

        % Plot initial data
        ud.lines = plot3(ud.y(1),ud.y(2),ud.y(3),'-');

        % Plot start and end markers, turn on grid
        nextplot = get(AX_HANDLE,'NextPlot');
        set(AX_HANDLE,'NextPlot','add');
        plot3(ud.y(1),ud.y(2),ud.y(3),'g.');
        ud.marker = plot3(ud.y(1),ud.y(2),ud.y(3),'r.');
        set(AX_HANDLE,'NextPlot',nextplot,'DrawMode','fast');
        grid on;

        % Store UserData and draw
        set(FIG_HANDLE,'UserData',ud);
        drawnow;
    case ''
        if isempty(FIG_HANDLE) || isempty(AX_HANDLE)
            if isW
                error('SDETools:sdephaseplot3:NotCalledWithInitW',...
                     ['Output function has not been initialized. Use syntax '...
                      'OutputFUN(TSPAN,Y0,''init'',W0).']);
            else
                error('SDETools:sdephaseplot3:NotCalledWithInit',...
                     ['Output function has not been initialized. Use syntax '...
                      'OutputFUN(TSPAN,Y0,''init'').']);

            end
        end

        % If figure is open
        if ishghandle(FIG_HANDLE) && ishghandle(AX_HANDLE)
            % Get UserData
            ud = get(FIG_HANDLE,'UserData');
            lt = length(t);
            N = size(y,1);
            lY = size(ud.y,2);

            % Update UserData
            oldi = ud.i;
            newi = oldi+lt;
            if newi > lY
                % Set line data
                XYZData = get(ud.lines,{'XData','YData','ZData'});
                set(ud.lines,{'XData','YData','ZData'},...
                             {[XYZData{1} ud.y(1,:)],...
                              [XYZData{2} ud.y(2,:)],...
                              [XYZData{3} ud.y(3,:)]});

                % Set marker point
                set(ud.marker,{'XData','YData','ZData'},...
                              {ud.y(1,end),ud.y(2,end),ud.y(3,end)});

                % Reset UserData
                ud.y(:,lY) = 0;
                oldi = 0;
                newi = lt;
            end

            % Append new data to UserData
            if N >= 3
                ud.y(:,oldi+1:newi) = y(1:3,:);
            elseif N == 2
                ud.y(:,oldi+1:newi) = [y(1:2,:);w(1,:)];
            elseif N == 1
                ud.y(:,oldi+1:newi) = [y(1,:);w(1:2,:)];
            else
                ud.y(:,oldi+1:newi) = w(1:3,:);
            end
            ud.i = newi;

            % Store updated UserData and draw if redraw chunk was full
            set(FIG_HANDLE,'UserData',ud);
            if oldi == 0
                drawnow;
            end
        else
            status = 0;
        end
    case 'done'
        % Rename and delete persistent handles
        hf = FIG_HANDLE;
        FIG_HANDLE = [];
        ha = AX_HANDLE;
        AX_HANDLE = [];

        % If figure is open
        if ~isempty(hf) && ishghandle(hf) && ~isempty(ha) && ishghandle(ha)
            % Get non-zero UserData
            ud = get(hf,'UserData');
            ud.y = ud.y(:,1:ud.i);

            % Set any remaining line data
            XYZData = get(ud.lines,{'XData','YData','ZData'});
            set(ud.lines,{'XData','YData','ZData'},...
                         {[XYZData{1} ud.y(1,:)],...
                          [XYZData{2} ud.y(2,:)],...
                          [XYZData{3} ud.y(3,:)]});

            % Set final marker point
            set(ud.marker,{'XData','YData','ZData'},...
                          {ud.y(1,end),ud.y(2,end),ud.y(3,end)});

            % Delete UserData
            set(hf,'UserData',[]);

            % Refresh or draw
            if ishold(ha)
                drawnow;
            else
                refresh;
            end
        else
            status = 0;
        end
    otherwise
        error('SDETools:sdephaseplot3:InvalidFlag',...
              'Invalid status flag passed to output function.');
end


function out = cfg_example_run_sum(job)
% Example function that returns the sum of an vector given in job.a in out.
% The output is referenced as out(1), this is defined in
% cfg_example_vout_sum.
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: cfg_example_run_sum.m 1716 2008-05-23 08:18:45Z volkmar $

rev = '$Rev: 1716 $'; %#ok

out = sum(job.a);


classdef MeshMerger < handle

    properties (Access = private)
        nodesA
        nodesB
        allNodes
        mergedNodes
        mergedMesh
    end

    properties (Access = private)
        meshA
        meshB
        isMergedNodeA
        isMergedNodeB
    end

    methods (Access = public)

        function obj = MeshMerger(cParams)
            obj.init(cParams)
            obj.computeNodesA();
            obj.computeNodesB();
            obj.computeAllNodes();
        end

        function m = compute(obj)
            obj.computeMergedNodes();
            obj.computeMergedMesh();
            m = obj.computeCanonicalMergedMesh();
        end

        function rNodes = computeRemainingNodes(obj)
            aNodes  = obj.allNodes;
            remainingA = true(obj.meshA.nnodes,1);
            remainingB = ~obj.isMergedNodeB;
            remaining  = [remainingA,remainingB];
            rNodes   = aNodes(remaining);
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.meshA = cParams.meshA;
            obj.meshB = cParams.meshB;
            obj.isMergedNodeA = cParams.isMergedNodeA;
            obj.isMergedNodeB = cParams.isMergedNodeB;
        end

        function computeNodesA(obj)
            npnod = obj.meshA.nnodes;
            nodes = (1:npnod)';
            obj.nodesA = nodes;
        end

        function computeNodesB(obj)
            npnodA = obj.meshA.nnodes;
            npnodB = obj.meshB.nnodes;
            nodes = (1:npnodB)' + npnodA;
            obj.nodesB = nodes;
        end

        function computeAllNodes(obj)
            nA = obj.nodesA;
            nB = obj.nodesB;
            nodes = [nA;nB];
            obj.allNodes = nodes;
        end

        function computeMergedNodes(obj)
            nA   = obj.nodesA;
            nB   = obj.nodesB;
            isMa = obj.isMergedNodeA;
            isMb = obj.isMergedNodeB;
            mNodesA          = nA;
            mNodesB(isMb,1)  = nA(isMa);
            mNodesB(~isMb,1) = nB(~isMb);
            nodes = [mNodesA;mNodesB];
            obj.mergedNodes = nodes;
        end

       function computeMergedMesh(obj)
            s.connec = obj.computeMergedConnec();
            s.coord  = obj.computeMergedCoord();
            m = Mesh(s);
            obj.mergedMesh = m;
        end

        function mConnec = computeMergedConnec(obj)
            aConnec = obj.computeAllConnec();
            s.oldNodes = obj.allNodes;
            s.newNodes = obj.mergedNodes;
            c = ConnecRenumbering(s);
            mConnec = c.renumber(aConnec);
        end

        function connec = computeAllConnec(obj)
            npnodA  = obj.meshA.nnodes;
            connecA = obj.meshA.connec;
            connecB = obj.meshB.connec + npnodA;
            connec = [connecA;connecB];
        end

        function mCoord = computeMergedCoord(obj)
            coordA = obj.meshA.coord;
            coordB = obj.meshB.coord;
            mCoord = [coordA;coordB];
        end

        function m = computeCanonicalMergedMesh(obj)
            s.remainingNodes = obj.computeRemainingNodes();
            s.mesh           = obj.mergedMesh;
            c = CannonicalMeshComputer(s);
            m = c.compute();
        end

    end

end


function [ ALL_HYPS, CAN_POOL ] = groundTruthHypothesisNewFunc( gnd, omap, gc, cn, rotImg, typenum, bufName)
%GROUNDTRUTHHYPOTHESISNEWFUNC Summary of this function goes here
%   Detailed explanation goes here
global config;
%% compute the checking direction on omap
% [candiSetXYZ, ~] = icosahedron2sphere(6);
[candiSetXYZ, ~] = getUniformVector( 6 );
[ohei, owid, ~] = size(omap);
candiSetUV = uv2coords(xyz2uvN(candiSetXYZ), owid, ohei);
candiInd = sub2ind([ohei owid], candiSetUV(:,2), candiSetUV(:,1));
% convert gc to omap
gndGC = zeros(ohei, owid, 3);
gndGC(:,:,1) = max(gc(:,:,5),gc(:,:,6));
gndGC(:,:,2) = max(gc(:,:,1),gc(:,:,3));
gndGC(:,:,3) = max(gc(:,:,2),gc(:,:,4));
normGndGC = sum(gndGC(candiInd))+sum(gndGC(candiInd+1*ohei*owid))+sum(gndGC(candiInd+2*ohei*owid));
% omap
gndOmap = omap;
gndOmap(gndOmap>0) = 1;
normGndOmap = sum(gndOmap, 3);
gndOmap = gndOmap./(repmat(normGndOmap+0.0001, [1 1 3]));
normGndOmap = sum(gndOmap(candiInd))+sum(gndOmap(candiInd+1*ohei*owid))+sum(gndOmap(candiInd+2*ohei*owid));
numPoint = size(candiSetXYZ,1);

% merge
gndMerge = zeros(ohei, owid, 3);
gndMerge(1:ohei/2,:,:) = gndOmap(1:ohei/2,:,:);
gndMerge(ohei/2+1:ohei, :, :) = gndGC(ohei/2+1:ohei, :, :);
normMegMap = sum(gndMerge(candiInd))+sum(gndMerge(candiInd+1*ohei*owid))+sum(gndMerge(candiInd+2*ohei*owid));

% optimal merge
gndOptim = zeros(ohei, owid, 3);
gndOptim(1:685,:,:) = gndOmap(1:685,:,:);
gndOptim(686:ohei, :, :) = gndGC(686:ohei, :, :);
normOptMap = sum(gndOptim(candiInd))+sum(gndOptim(candiInd+1*ohei*owid))+sum(gndOptim(candiInd+2*ohei*owid));

%%
room = gnd(1);
% compute room hyp omap feature
hypVp = false(numPoint,3);
align = room.align;
valid1 = insideCone(align([6;5;8;7],:), candiSetXYZ, 0);
valid2 = insideCone(align([7;8;4;3],:), candiSetXYZ, 0);
valid3 = insideCone(align([6;7;3;2],:), candiSetXYZ, 0);
valid4 = insideCone(align([3;4;1;2],:), candiSetXYZ, 0);
valid5 = insideCone(align([5;6;2;1],:), candiSetXYZ, 0);
valid6 = insideCone(align([8;5;1;4],:), candiSetXYZ, 0);
hypVp(valid1,1) = true; hypVp(valid4,1) = true;
hypVp(valid2,2) = true; hypVp(valid5,2) = true;
hypVp(valid3,3) = true; hypVp(valid6,3) = true;
response = sum(gndOmap(candiInd(hypVp(:,1))+0*ohei*owid)) ...
         + sum(gndOmap(candiInd(hypVp(:,2))+1*ohei*owid)) ...
         + sum(gndOmap(candiInd(hypVp(:,3))+2*ohei*owid));
room.omapScr = response/normGndOmap;
response = sum(gndGC(candiInd(hypVp(:,1))+0*ohei*owid)) ...
         + sum(gndGC(candiInd(hypVp(:,2))+1*ohei*owid)) ...
         + sum(gndGC(candiInd(hypVp(:,3))+2*ohei*owid));
room.gcScr = response/normGndGC;
response = sum(gndMerge(candiInd(hypVp(:,1))+0*ohei*owid)) ...
         + sum(gndMerge(candiInd(hypVp(:,2))+1*ohei*owid)) ...
         + sum(gndMerge(candiInd(hypVp(:,3))+2*ohei*owid));
room.mgScr = response/normMegMap;
response = sum(gndOptim(candiInd(hypVp(:,1))+0*ohei*owid)) ...
         + sum(gndOptim(candiInd(hypVp(:,2))+1*ohei*owid)) ...
         + sum(gndOptim(candiInd(hypVp(:,3))+2*ohei*owid));
room.opScr = response/normOptMap;

%%
% load('./object_classifier/objectclassifier.mat');
load(config.classifierName);
objects = gnd(2:end);
[ scores, valid ] = objectClassifier(room, objects, B);
obj_xyz = zeros(length(objects),6);
for i = 1:length(objects)
    obj_xyz(i,:) = [objects(i).align(1,:) objects(i).align(7,:)];
end
sel_hyps.objects = objects;
sel_hyps.scores = scores;
sel_hyps.valid = valid;
sel_hyps.obj_xyz = obj_xyz;

CAN_POOL{1}.sel_hyps = sel_hyps;
CAN_POOL{1}.room = room;

sel_hyps = repmat(struct('fixed',false,'selID',[]), typenum, 1);
for i = 1:length(objects)
    if objects(i).objtype>12
        continue;
    end
    sel_hyps(objects(i).objtype).fixed = true;
    sel_hyps(objects(i).objtype).selID = [sel_hyps(objects(i).objtype).selID i];
end
ALL_HYPS(1).sel_hyps = sel_hyps;

[objfea, roomfea, anglesid] = compObjHypsFeature( rotImg, omap, gc, cn, CAN_POOL{1}, typenum, bufName );
CAN_POOL{1}.sel_hyps.objfea = objfea;
CAN_POOL{1}.room.roomfea = roomfea;
CAN_POOL{1}.sel_hyps.anglesid = anglesid;

[ sceneImgFea ] = compSceneHypsFeatureA( ALL_HYPS, CAN_POOL{1}.sel_hyps, CAN_POOL{1}.room, omap, gc, cn );
ALL_HYPS(1).sceneImgFea = sceneImgFea;

end


function peak_out=pss_sss_foe(peak,capbuf,fc,sampling_carrier_twist,tdd_flag)

% Use (only) the PSS and SSS to calculate the frequency offset.

% Copyright 2012 Evrytania LLC (http://www.evrytania.com)
%
% Written by James Peroulas <james@evrytania.com>
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU Affero General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Affero General Public License for more details.
%
% You should have received a copy of the GNU Affero General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

% fc*k_factor is the receiver's actual RX center frequency.
if sampling_carrier_twist==1
    k_factor=(fc-peak.freq)/fc;
    k_factor_vec = (fc-peak.freq+(3:-2:-3).*1e3)./fc;
% else
%     k_factor=1;
else
    k_factor = peak.k_factor;
    k_factor_vec = k_factor.*ones(1, 4);
end

if tdd_flag == 1
    [peak.freq, k_factor_idx] = refine_fo(capbuf, peak.cp_type, peak.n_id_2, peak.freq, 1920000, peak.frame_start, k_factor_vec);
    k_factor = k_factor_vec(k_factor_idx);
end

%%%%%%
% Calculate the frequency offset
%%%%%%
% Find the location of the first SSS where we can take a DFT.
if (strcmpi(peak.cp_type,'normal'))
    if tdd_flag==1
        pss_sss_dist=round((3*(128+9)+1)*k_factor); % TDD
        first_sss_dft_location=peak.frame_start+(1920-128)*k_factor; % TDD
    else
        pss_sss_dist=round((128+9)*k_factor); % FDD
        first_sss_dft_location=peak.frame_start+(960-128-9-128)*k_factor; % FDD
    end
elseif (strcmpi(peak.cp_type,'extended'))
    if tdd_flag==1
        pss_sss_dist=round(3*(128+32)*k_factor); %TDD
        first_sss_dft_location=peak.frame_start+(1920-128)*k_factor; %TDD
    else
        pss_sss_dist=round((128+32)*k_factor); %FDD
        first_sss_dft_location=peak.frame_start+(960-128-32-128)*k_factor; %FDD
    end
else
  error('Check code...');
end
first_sss_dft_location=wrap(first_sss_dft_location,0.5,9600*2+0.5);
if (first_sss_dft_location-9600*k_factor>0.5)
%if (first_sss_dft_location>=9601)
  first_sss_dft_location=first_sss_dft_location-9600*k_factor;
  sn=10;
else
  sn=0;
end
sss_dft_loc_set=first_sss_dft_location:9600*k_factor:length(capbuf)-127-pss_sss_dist-100;
n_sss=length(sss_dft_loc_set);

h_raw_fo_pss=NaN(n_sss,62);
sss_raw_fo=NaN(n_sss,62);
%M1=0;
%M2=0;
sn=(1-(sn/10))*10;
M=0;
for k=1:n_sss
  sn=(1-(sn/10))*10;
  sss_dft_location=round(sss_dft_loc_set(k));

  % Find where to take the pss dft
  pss_dft_location=sss_dft_location+pss_sss_dist;
  %if (pss_dft_location+127>length(capbuf))
  %  break;
  %end

  % Find the PSS and use it to estimate the channel.
  dft_in_pss=fshift(capbuf(pss_dft_location:pss_dft_location+127),-peak.freq,fs_lte/16);
  % TOC
  %disp('toc diabled');
  dft_in_pss=[dft_in_pss(3:end) dft_in_pss(1:2)];
  dft_out_pss=dft(dft_in_pss);
  h_raw_fo_pss(k,:)=[dft_out_pss(end-30:end) dft_out_pss(2:32)];
  h_raw_fo_pss(k,:)=h_raw_fo_pss(k,:).*conj(pss(peak.n_id_2));

  % Smoothening... Basic...
  for t=1:62
    %arm_length=min([6 t-1 62-t]);
    lt=max([1 t-6]);
    rt=min([62 t+6]);
    % Growing matrix...
    %h_sm(k,t)=mean(h_raw_fo_pss(k,t-arm_length:t+arm_length));
    h_sm(k,t)=mean(h_raw_fo_pss(k,lt:rt));
  end
  %h_sm(k,:)=1;

  % Estimate noise power.
  % Growing matrix...
  pss_np(k)=sigpower(h_sm(k,:)-h_raw_fo_pss(k,:));

  %M2=M2+sum(conj(h_sm(k,:)).*h_raw_fo_pss(k,:))/pss_np(k);

  % Calculate the SSS in the frequency domain
  dft_in_sss=fshift(capbuf(sss_dft_location:sss_dft_location+127),-peak.freq,fs_lte/16)*exp(j*pi*-peak.freq/(fs_lte/16/2)*-pss_sss_dist);
  % TOC
  %disp('toc diabled');
  dft_in_sss=[dft_in_sss(3:end) dft_in_sss(1:2)];
  dft_out_sss=dft(dft_in_sss);
  sss_raw_fo(k,:)=[dft_out_sss(end-30:end) dft_out_sss(2:32)];
  sss_raw_fo(k,:)=sss_raw_fo(k,:).*conj(sss(peak.n_id_1,peak.n_id_2,sn));

  %M1=M1+sum(conj(h_sm(k,:)).*sss_raw_fo(k,:))/pss_np(k);
  M=M+sum(conj(sss_raw_fo(k,:)).*h_raw_fo_pss(k,:).*absx2(h_sm(k,:))./(2*absx2(h_sm(k,:))*pss_np(k)+pss_np(k)^2));
end
%f_off_est=peak.freq+angle(conj(M1)*M2)/(2*pi)/(1/(fs_lte/16)*pss_sss_dist);
f_off_est=peak.freq+angle(M)/(2*pi)/(1/(fs_lte/16)*pss_sss_dist);

peak_out=peak;
peak_out.freq_fine=f_off_est;


% BWBLKSLV Solves block sparse upper-triangular system.
%    y = bwblkslv(L,b) yields the same result as
%              y(L.perm,:) = L.L'\b
%    However, BWBLKSLV is faster than the built-in operator "\",
%    because it uses dense linear algebra and loop-unrolling on
%    supernodes.
%
%    Typical use, with X sparse m x m positive definite and b is m x n:
%            L = sparchol(symbchol(X),X);
%            y = bwblkslv(L,fwblkslv(L,b));
%    Then y solves X*y=b.
%
% See also symbchol, fwblkslv, mldivide, mrdivide

function y = bwblkslv(L,b) %#ok

 %
 %   This file is part of CholTool 1.00
 %   Copyright (C) 1998 Jos F. Sturm
 %   CRL, McMaster University, Canada.
 %   Supported by the Netherlands Organization for Scientific Research (NWO).
 %
 %   This program is free software; you can redistribute it and/or modify
 %   it under the terms of the GNU General Public License as published by
 %   the Free Software Foundation; either version 2 of the License, or
 %   (at your option) any later version.
 %
 %   This program is distributed in the hope that it will be useful,
 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 %   GNU General Public License for more details.
 %
 %   You should have received a copy of the GNU General Public License
 %   along with this program; if not, write to the Free Software
 %   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 %

error('At OS prompt, type "make" to create cholTool mex-files.')


function [Ain, Cin, b_in, f_in, center, res] = greedyROI(Y, K, params, ROI_list)
% component initialization using a greedy algorithm to identify neurons in 2d or 3d calcium imaging movies
%
% Usage:     [Ain, Cin, bin, fin, center, res] = greedyROI2d(data, K, params)
%
% Input:
% Y          d1 x d2 x (d3 x) T movie, raw data, each column is a vectorized movie
% K          number of neurons to extract (if K is a vector then the algorithm is run multiple times with different parameters)
% params     tuning parameter for fine-tuning the shape (optional)
%            params.nIter: number of iterations for shape tuning (default 5)
%            params.gSig: variance of Gaussian kernel to use (default 5) If params.gSig is a cell, then the algorithm is run with multiple times with different parameters
%            params.gSiz: size of kernel (default 2*gSiz+1)
%            params.nb: rank of background component (default 1)
%            params.save_memory: flag for processing data in chunks to save memory (default 0)
%            params.windowSiz: size of spatial window when computing the median (default 32 x 32)
%            params.chunkSiz: number of timesteps to be processed simultaneously if on save_memory mode (default: 100)
%            params.med_app: number of timesteps to be interleaved for fast (approximate) median calculation (default: 1, no approximation)
%            params.rolling_sum: flag for using rolling sum to detect new components (default: True)
%            params.rolling_length: length of rolling window (default: 100)
% ROI_list   Kn x 2 (or 3) matrix with user specified centroids. If this are present, then the algorithm only finds components around these centroids

%Output:
% Ain        (d) x K matrix, location of each neuron
% Cin        T x K matrix, calcium activity of each neuron
% center     K x 2 (or 3) matrix, inferred center of each neuron
% bin        (d) X nb matrix, initialization of spatial background
% fin        nb X T matrix, initalization of temporal background
% res        d1 x d2 x (d3 x) T movie, residual
%
% Author: Yuanjun Gao with modifications from Eftychios A. Pnevmatikakis and Weijian Yang

use_sum = false;
if nargin < 4 || isempty(ROI_list)
    user_ROIs = 0;
else
    user_ROIs = 1;
    K = size(ROI_list,1);
end

dimY = ndims(Y) - 1;  % dimensionality of imaged data (2d or 3d)
sizY = size(Y);
T = sizY(end);        % # of timesteps
dx = sizY(1:dimY);    % # of voxels in each axis
d = prod(dx);         % total # of voxels

if ~exist('K', 'var'),  %find K neurons
    K = 30;
    warning(['number of neurons are not specified, set to be the default value', num2str(K)]);
end

if ~exist('params', 'var') params = []; end

if ~isfield(params, 'gSig') || isempty(params.gSig);
    if dimY == 2; params.gSig = [5, 5]; else params.gSig = [5,5,5]; end
elseif length(params.gSig) == 1, params.gSig = params.gSig + zeros(1,dimY);
    if dimY == 3; params.gSig(3) = params.gSig(3)/2; end
end

if ~isfield(params, 'gSiz') || isempty(params.gSiz);
    if ~iscell(params.gSig)
        params.gSiz = ceil(2*params.gSig + 1);
    else
        for j = 1:length(params.gSig)
            params.gSiz{j,1} = 2*params.gSig{j}+1; %cellfun(@times,params.gSig{j},num2cell(ones(size(params.gSig{j}))*2));
        end
    end
elseif length(params.gSiz) == 1, params.gSiz = params.gSiz + zeros(1,dimY);
    if dimY == 3; params.gSiz(3) = ceil(params.gSiz(3)/2); end
end

if isfield(params,'ssub');
    if ~iscell(params.gSig); params.gSig(1:2) = params.gSig(1:2)/params.ssub; params.gSiz(1:2) = ceil(params.gSiz(1:2)/params.ssub);
    else
        for j = 1:length(params.gSig)
            params.gSig{j,1} = params.gSig{j}/params.ssub; %cellfun(@times,params.gSig{j},num2cell(ones(size(params.gSig{j}))/params.ssub));
            params.gSiz{j,1} = params.gSiz{j}/params.ssub; %cellfun(@times,params.gSiz{j},num2cell(ones(size(params.gSiz{j}))/params.ssub));
        end
    end
end

if ~isfield(params,'nb'), nb = 1; else nb = params.nb; end

if ~isfield(params, 'nIter'), nIter = 5;
else nIter = params.nIter; end

if ~isfield(params, 'save_memory'), save_memory = 0;
else save_memory = params.save_memory; end

if ~isfield(params, 'chunkSiz'), chunkSiz = 100; else chunkSiz = params.chunkSiz; end
if ~isfield(params, 'windowSiz'), windowSiz = 32; else windowSiz = params.windowSiz; end
if ~isfield(params, 'med_app'), med_app = 1; else med_app = params.med_app; end

if ~isfield(params,'rem_prct') || isempty(params.rem_prct); params.rem_prct = 20; end

Tint = 1:med_app:T;
% if save_memory
%     med = zeros(M,N);
%     for ii = 1:ceil(M/windowSiz)
%         intx = (ii-1)*windowSiz+1:min(ii*windowSiz,M);
%         for jj = 1:ceil(N/windowSiz)
%             inty = (jj-1)*windowSiz+1:min(jj*windowSiz,N);
%             med(intx,inty) = median(data(intx,inty,Tint),3);
%         end
%     end
% else
%if dimY == 2; med = median(Y(:,:,Tint), 3); else med = median(Y(:,:,:,Tint), 4); end
if dimY == 2; med = prctile(Y(:,:,Tint),params.rem_prct, 3); else med = prctile(Y(:,:,:,Tint),params.rem_prct,4); end

% end

Y = bsxfun(@minus, Y, med);
if iscell(params.gSig); params.gSig = cell2mat(params.gSig); params.gSiz = cell2mat(params.gSiz); end
if length(K) > 1  % order size of components to be found in descending order
    [~,ord] = sort(sum(params.gSig,2),'descend');
    K = K(ord);
    params.gSig = params.gSig(ord,:);
    params.gSiz = params.gSiz(ord,:);
end

if ~iscell(params.gSiz)
    Ain = spalloc(d,sum(K),K(:)'*ceil(params.gSiz(:,1).^2)); %zeros(M*N,sum(K));
else
    Ain = sparse(d,sum(K));
end
Cin = zeros(sum(K),T);
center = zeros(sum(K),dimY);

for r = 1:length(K)
    gSig = params.gSig(r,:);
    gSiz = params.gSiz(r,:);

    gHalf = floor(gSiz / 2); %half size of the kernel, used to calculate margin
    gSiz = 2 * gHalf + 1; %actual size

    Atemp = spalloc(d,K(r),K(r)*ceil(prod(gSiz))); %zeros(M, N, K(r));
    %basis = spalloc(M*N,K,K*prod(gSiz));
    trace = zeros(T, K(r));
    centers = zeros(K(r), dimY);

    %scan the whole image (only need to do this at the first iteration)
    rho = imblur(Y, gSig, gSiz, dimY, save_memory, chunkSiz); %covariance of data and basis

    if ~params.rolling_sum
        v = sum(rho.^2, dimY+1); %variance explained
    else
        % running maximum
        avg_fil = ones(1,params.rolling_length)/params.rolling_length;
        rho_s = filter(avg_fil,1,rho.^2,[],dimY+1);
        v = max(rho_s,[],dimY+1);
    end

    for k = 1:K(r),
        if user_ROIs
            iHat = ROI_list(k,:);
        else
            [~, ind] = max(v(:));
            %[iHat, jHat] = ind2sub([M, N], ind);
            iHat = zeros(1,dimY);
            if dimY == 2; [iHat(1),iHat(2)] = ind2sub(dx,ind); else [iHat(1),iHat(2),iHat(3)] = ind2sub(dx,ind); end
        end
        centers(k,:) = round(iHat);

        %iSig = [max(iHat - gHalf(1), 1), min(iHat + gHalf(1), M)]; iSigLen = iSig(2) - iSig(1) + 1;
        %jSig = [max(jHat - gHalf(2), 1), min(jHat + gHalf(2), N)]; jSigLen = jSig(2) - jSig(1) + 1;
        iSig = [max(iHat - gHalf,1)', min(iHat + gHalf,dx)']; iSigLen = iSig(:,2) - iSig(:,1) + 1;

        %fine tune the shape
        if dimY == 2
            dataTemp = Y(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2), :);
            traceTemp = squeeze(rho(iHat(1), iHat(2), :));
        else
            dataTemp = Y(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2), iSig(3,1):iSig(3,2), :);
            traceTemp = squeeze(rho(iHat(1), iHat(2), iHat(3), :));
        end
        [coef, score] = finetune(dataTemp, traceTemp, nIter);

        dataSig = bsxfun(@times, coef, reshape(score, [ones(1,dimY),T]));
        %[xSig,ySig] = meshgrid(iSig(1):iSig(2),jSig(1):jSig(2));
        basis = zeros(dx);
        if dimY == 2;  basis(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2)) = coef; else  basis(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2), iSig(3,1):iSig(3,2)) = coef; end
        Atemp(:,k) = basis(:);
        %basis(sub2ind([M,N],xSig(:),ySig(:)),k) = coef(:);

        trace(:, k) = score';

        if dimY == 2;
            Y(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2), :) = Y(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2), :) - dataSig; %update residual
        else
            Y(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2), iSig(3,1):iSig(3,2), :) = Y(iSig(1,1):iSig(1,2), iSig(2,1):iSig(2,2),  iSig(3,1):iSig(3,2),:) - dataSig;
        end

        if mod(k,10) == 0; fprintf('found %i out of %i neurons..\n', k,K(r)); end

        %get next basis;
        if k < K(r)
            %iMod = [max(iHat - 2 * gHalf(1), 1), min(iHat + 2 * gHalf(1), M)]; iModLen = iMod(2) - iMod(1) + 1;%patches to modify
            %jMod = [max(jHat - 2 * gHalf(2), 1), min(jHat + 2 * gHalf(2), N)]; jModLen = jMod(2) - jMod(1) + 1;
            iMod = [max(iHat - 2*gHalf,1)', min(iHat + 2*gHalf,dx)']; iModLen = iMod(:,2) - iMod(:,1) + 1;
            %iLag = iSig - iMod(1) + 1; %relative location of iSig in the small patch
            %jLag = jSig - jMod(1) + 1;
            iLag = iSig - repmat(iMod(:,1),1,2) + 1;
            %dataTemp = zeros(iModLen, jModLen);
            dataTemp = zeros(iModLen(:)');
            %dataTemp(iLag(1):iLag(2), jLag(1):jLag(2)) = reshape(coef, [iSigLen, jSigLen]);
            if dimY == 2
                dataTemp(iLag(1,1):iLag(1,2), iLag(2,1):iLag(2,2)) = reshape(coef, iSigLen(:)');
            else
                dataTemp(iLag(1,1):iLag(1,2), iLag(2,1):iLag(2,2), iLag(3,1):iLag(3,2)) = reshape(coef, iSigLen(:)');
            end
            dataTemp = imblur(dataTemp, gSig, gSiz, dimY, 0, chunkSiz);
            rhoTemp = bsxfun(@times, dataTemp, reshape(score, [ones(1,dimY),T]));
            if dimY == 2
                rhoTemp = rho(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2), :)  - rhoTemp;
                rho(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2), :)  = rhoTemp;
                if ~params.rolling_sum
                    v(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2)) = sum(rhoTemp.^2, 3);
                else
                    rho_filt = filter(avg_fil,1,rhoTemp.^2,[],3);
                    v(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2)) = max(rho_filt,[],3);
                end
            else
                rhoTemp = rho(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2), iMod(3,1):iMod(3,2), :)  - rhoTemp;
                rho(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2), iMod(3,1):iMod(3,2), :)  = rhoTemp;
                if ~params.rolling_sum
                    v(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2), iMod(3,1):iMod(3,2)) = sum(rhoTemp.^2, 4);
                else
                    rho_filt = filter(avg_fil,1,rhoTemp.^2,[],4);
                    v(iMod(1,1):iMod(1,2), iMod(2,1):iMod(2,2), iMod(3,1):iMod(3,2)) = max(rho_filt,[],4);
                end
            end
        end
    end
    Ain(:,sum(K(1:r-1))+1:sum(K(1:r))) = Atemp; %sparse(reshape(basis,d,K(r)));
    Cin(sum(K(1:r-1))+1:sum(K(1:r)),:) = trace';
    center(sum(K(1:r-1))+1:sum(K(1:r)),:) = centers;
end
res = reshape(Y,d,T) + repmat(med(:),1,T);

%% clear data matrix from local memory (avoid out-of-memory? see greedyROI_corr.m)
clear Y

%[b_in,f_in] = nnmf(max(res,0),nb);
%[b_in,f_in] = nnsvd(max(res,0),nb);
f_in = [mean(res);rand(nb-1,T)];

for nmfiter = 1:100
    b_in = max((res*f_in')/(f_in*f_in'),0);
    f_in = max((b_in'*b_in)\(b_in'*res),0);
end

function [ain,cin] = finetune(data,cin,nIter)

    %rank-1 semi-NMF to fine tune the inferred components
    %
    %Input:
    %data   d1 x d2 x (d3 x) T matrix, small patch containing one neuron
    %trace  initial value for trace
    %nIter  number of coordinate descent steps
    %
    %Output:
    %basis  d1 x d2 (x d3) matrix, result of the fine-tuned neuron shape
    %trace  1 x T matrix, result of the neuron

    if ~exist('nIter', 'var'), nIter = 1; end
    data = reshape(data,prod(iSigLen),T);
    for iter = 1:nIter
        %nc = norm(cin)^2;
        ain = max(data*cin,0)/norm(cin);
        an = norm(ain);
        if an > 0
            ain = ain/an;
        else
            fprintf('found degenerate component!\n')

            %break
        end
        cin = data'*ain;
    end
    ain = reshape(ain,iSigLen(:)');
    cin = cin(:)';
end

function data = imblur(data, sig, siz, nDimBlur, save_memory, chunkSiz)
%Gaussian blur for high dimensional data
%Input:
%data       original data
%sig        std of gaussian kernel
%siz        size of kernel
%nDimBlur   number of dims to blur (default: ndims(data) - 1)
%
%Output:
%data       result after the Gaussian blur

if ~exist('nDimBlur', 'var'), nDimBlur = ndims(data) - 1;
else nDimBlur = min(nDimBlur, ndims(data)); end

if length(sig) == 1, sig = sig * ones(1,nDimBlur); end
assert(nDimBlur == length(sig));

if length(siz) == 1, siz = siz * ones(1,nDimBlur); end
assert(nDimBlur == length(siz));

for i = 1:nDimBlur,
    if sig(i) > 0,
        x = -floor(siz(i) / 2):floor(siz(i) / 2);
        H = exp(-(x.^2/ (2 * sig(i)^2)));
        H = H' / norm(H(:));
        if nDimBlur > 1,
            indH = 1:nDimBlur; indH(i) = 1; indH(1) = i;
            H = permute(H, indH);
        end
        if save_memory
            L = size(data,ndims(data));
            for ci = 1:ceil(L/chunkSiz)
                int = (ci-1)*chunkSiz+1:min(ci*chunkSiz,L);
                data(:,:,int) = imfilter(data(:,:,int), H, 'same', 0);
            end
        else
            data = imfilter(data, H, 'same', 0);
        end
    end
end
end

end


function obj = t3_hand_eye_func_new(in1,in2,in3)
coefs_tq1_1 = in2(1);
coefs_tq1_2 = in2(4);
coefs_tq1_3 = in2(7);
coefs_tq1_4 = in2(10);
coefs_tq1_5 = in2(13);
coefs_tq1_6 = in2(16);
coefs_tq1_7 = in2(19);
coefs_tq1_8 = in2(22);
coefs_tq1_9 = in2(25);
coefs_tq2_1 = in2(2);
coefs_tq2_2 = in2(5);
coefs_tq2_3 = in2(8);
coefs_tq2_4 = in2(11);
coefs_tq2_5 = in2(14);
coefs_tq2_6 = in2(17);
coefs_tq2_7 = in2(20);
coefs_tq2_8 = in2(23);
coefs_tq2_9 = in2(26);
coefs_tq3_1 = in2(3);
coefs_tq3_2 = in2(6);
coefs_tq3_3 = in2(9);
coefs_tq3_4 = in2(12);
coefs_tq3_5 = in2(15);
coefs_tq3_6 = in2(18);
coefs_tq3_7 = in2(21);
coefs_tq3_8 = in2(24);
coefs_tq3_9 = in2(27);
coefs_tq1_10 = in2(28);
coefs_tq1_11 = in2(31);
coefs_tq2_10 = in2(29);
coefs_tq2_11 = in2(32);
coefs_tq3_10 = in2(30);
coefs_tq3_11 = in2(33);
pinvG3_1 = in1(3);
pinvG3_2 = in1(6);
pinvG3_3 = in1(9);
q0 = in3(1,:);
q1 = in3(2,:);
q2 = in3(3,:);
q3 = in3(4,:);
obj = q0.^2.*(coefs_tq1_1.*pinvG3_1+coefs_tq2_1.*pinvG3_2+coefs_tq3_1.*pinvG3_3)+q1.^2.*(coefs_tq1_5.*pinvG3_1+coefs_tq2_5.*pinvG3_2+coefs_tq3_5.*pinvG3_3)+q2.^2.*(coefs_tq1_8.*pinvG3_1+coefs_tq2_8.*pinvG3_2+coefs_tq3_8.*pinvG3_3)+q3.^2.*(coefs_tq1_10.*pinvG3_1+coefs_tq2_10.*pinvG3_2+coefs_tq3_10.*pinvG3_3)+coefs_tq1_11.*pinvG3_1+coefs_tq2_11.*pinvG3_2+coefs_tq3_11.*pinvG3_3+q0.*q1.*(coefs_tq1_2.*pinvG3_1+coefs_tq2_2.*pinvG3_2+coefs_tq3_2.*pinvG3_3)+q0.*q2.*(coefs_tq1_3.*pinvG3_1+coefs_tq2_3.*pinvG3_2+coefs_tq3_3.*pinvG3_3)+q0.*q3.*(coefs_tq1_4.*pinvG3_1+coefs_tq2_4.*pinvG3_2+coefs_tq3_4.*pinvG3_3)+q1.*q2.*(coefs_tq1_6.*pinvG3_1+coefs_tq2_6.*pinvG3_2+coefs_tq3_6.*pinvG3_3)+q1.*q3.*(coefs_tq1_7.*pinvG3_1+coefs_tq2_7.*pinvG3_2+coefs_tq3_7.*pinvG3_3)+q2.*q3.*(coefs_tq1_9.*pinvG3_1+coefs_tq2_9.*pinvG3_2+coefs_tq3_9.*pinvG3_3);


function [train_users, dev_users] = get_balanced_fold(DISFA_dir, users, au, prop_test, offset)

    % This is for loading the labels
    for i=1:numel(users)
        input_train_label_files{i} = [DISFA_dir, '/ActionUnit_Labels/', users{i}, '/', users{i}];
    end

    % Extracting the labels
    labels_train = extract_au_labels(input_train_label_files, au);

    counts = zeros(numel(users),1);
    for k=1:numel(users)
        counts(k) = sum(labels_train((k-1)*4844+1:k*4844));
    end

    [sorted, inds] = sort(counts);

    dev_users = users(inds(offset:round(1/prop_test):end));
    train_users = setdiff(users, dev_users);

    count_dev = 0;
    count_train = 0;
    for k=1:numel(users)
        if(any(strcmp(dev_users, users{k})))
            count_dev = count_dev + counts(k);
        else
            count_train = count_train + counts(k);
        end

    end
end


function [positionSLR,marksSLR,ind,messages]=SLR2(marks,messages)
% post processing rule for delineation
%
% [positionSLR,marksSLR,ind,messages]=SLR2(marks,messages)
%
% INPUT:
% marks: structure with a matrix of annotations in samples; in each field
%        each matrix of annotations has one line per beat and 10 colunms
%        corresponding respectively to P onset, P peak, P end, QRS onset, QRS
%        main peak, QRS end, T onset, T peak, T prima, T end
% messages.setup.SLR.freq: sampling frequency of the recording.
% messages.setup.SLR.QRSlimit: admited diference between marks of the same beat in ms (optional)
%           by default QRSlimit= 250 ms.
% messages.setup.SLR.k: number of neighbours to consider in SLR rule (optional)
%    by default k=3
% messages.setup.SLR.delta: neighbourhood to consider in SLR rule in ms (optional)
%    by default delta = [4 nan 4 12 nan 10 12 nan nan 12] ms for 10 marks
%    or  delta = [4 nan nan 4 nan 12  nan nan nan nan 10 12 nan nan 12] ms for 15 marks
% messages.setup.wavedet.refrper: minimum time between two admisible beats, by default 257ms
% messages.setup.SLR.tolerance = time in ms to define each individual QRS wave, by default 10ms
%
% OUTPUT:
%positionSLR: struture with multilead based on marks obtained by SLR rule
% marksSLR: matrix multilead based on marks obtained by SLR rule
% ind: indexes of the initial column vectors for each set, corresponding to the sincronized beats
%      each line of ind corresponds to a beat and each column to a set
%      if a beat is absent of a set
% messages.errors: errors during the processing
% messages.errors_desc:errors description
% messages.status: sucess of the procesing (1) ou fail (0)
% messages.status: parameters considered
% Last update: 27JAN2012
positionSLR=[];
marksSLR=[];
ind=[];
if nargin<2
    messages.errors= 'Fatal error in SLR.';
    messages.errors_desc= 'Inputs marks and messages.setup.SLR.freq required';
    messages.status=0;
    return
else
    if size(marks{1},2)~=10 && size(marks{1},2)~=15
        messages.errors= 'Fatal error in SLR.';
        messages.errors_desc= 'Input marks should include 10 or 15 marks.';
        messages.status=0;
        return
    end
    if ~isfield(messages,'setup') || ((~isfield(messages.setup,'SLR') ||...
            (~isfield(messages.setup.SLR,'freq') && ~isfield(messages.setup.SLR,'fa')))  &&...
            (~isfield(messages.setup.wavedet,'wavedet') || ( isfield(messages.setup.wavedet,'wavedet') &&...
            ~isfield(messages.setup.wavedet,'freq')))) %
        messages.errors= 'Fatal error in SLR.';
        messages.errors_desc= 'Inputs messages.setup.SLR.freq required';
        messages.status=0;
        return
    else
        try
            fa=messages.setup.SLR.freq;
        catch me
            me.message = 'Not exist messages.setup.SLR.freq';
            try
                fa=messages.setup.SLR.fa;
            catch me
                me.message = 'Not exist messages.setup.SLR.fa';
                fa= messages.setup.wavedet.freq;
            end
        end
    end
end
messages.status=1;
if ~isfield(messages,'errors')
    messages.errors=[];
end
if ~isfield(messages,'errors_desc')
    messages.errors_desc=[];
end
if ~isfield(messages,'warnings')
    messages.warnings=[];
end
if ~isfield(messages,'status')
    messages.status=1;
end
if ~isfield(messages.setup.SLR,'k')
    messages.setup.SLR.k=min(3,size(marks{1},1)-1);
end
if ~isfield(messages.setup.SLR,'QRSlimit')
    messages.setup.SLR.QRSlimit=250;
end
if ~isfield(messages.setup.SLR,'delta')
    if size(marks{1},2)==10
        messages.setup.SLR.delta = [4 nan 4 12 nan 10 12 nan nan 12];
    elseif size(marks{1},2)==15
        messages.setup.SLR.delta = [4 nan nan 4 nan 12  nan nan nan nan 10 12 nan nan 12];
    end
end

QRSlimit= messages.setup.SLR.QRSlimit*fa/1000;
delta= messages.setup.SLR.delta*fa/1000;
k= messages.setup.SLR.k;
if isempty(k) || ~isnumeric(k) || isnan(k)
    k=min(3,size(marks{1},1)-1);
    messages.setup.SLR.k=k;
end
if isempty(QRSlimit) || ~isnumeric(QRSlimit) || isnan(QRSlimit)
    messages.setup.SLR.QRSlimit=250;
    QRSlimit=messages.setup.SLR.QRSlimit*fa/1000;
end
if isempty(delta) | size(delta)~=size(marks{1},2) %#ok<OR2>
    if size(marks{1},2)==10
        messages.setup.SLR.delta = [4 nan 4 12 nan 10 12 nan nan 12];
    elseif size(marks{1},2)==15
        messages.setup.SLR.delta = [4 nan nan 4 nan 12  nan nan nan nan 10 12 nan nan 12];
    end
    delta= messages.setup.SLR.delta*fa/1000;
end

if ~isfield(messages.setup.SLR,'refrper')
    if isfield(messages.setup,'wavedet') && isfield(messages.setup.wavedet,'refrper')
        messages.setup.SLR.refrper=messages.setup.wavedet.refrper*fa/1000;
    else
        messages.setup.SLR.refrper=275*fa/1000;
    end
end
if ~isfield(messages.setup.SLR,'tolerance')
    messages.setup.SLR.tolerance=10*fa/1000;
end

if isstruct(marks)
    leads = fieldnames(marks);
    messages.setup.SLR.nleads=length(leads);
else
   messages.setup.SLR.nleads = size(marks,2);
end

if length(delta)==10
    messages.setup.SLR.marks_desc={'(','P',')','(','QRS',')','(','T','T''',')'};
    peaks=[2 5 8 9];
    onsets=[1 4 6];
    ends=[3 6 10];
    refmark=5;
elseif length(delta)==15
    messages.setup.SLR.marks_desc={'(','P','P''',')','QRS_first_peak','(','Q','R','S','R''',')','(','T','T''',')'};
    peaks=[2 3 8 13 14];
    onsets=[1 6 12];
    ends=[4 11 15];
    refmark=[8 9 7 10];%RUTE % porque la onda R puede ni existir en una derivacion especifica!
end
nmarks=length(delta);
beats=0;
refmark_n=refmark;

for g=1:messages.setup.SLR.nleads
    if isstruct(marks)
        f = getfield(marks, char(leads(g)));  %#ok<GFLD>
    else
        f = marks{g};
    end
    if length(f)> size(beats,1)
        beats((size(beats,1)+1):length(f),1:g)=zeros(length((size(beats,1)+1):length(f)),g);
    end
    for n=1:size(f,1)
        refmark(n)=refmark_n(find(~isnan(f(n,refmark_n)),1,'first')); %#ok<AGROW>
        beats(n,g)=f(n,refmark(n));  %#ok<AGROW>
    end
end

beats(beats==0)=NaN;
[ind,messages1]=sincronizabeats(beats,QRSlimit);
if messages1.status == 0
    return;
end
ind(sum(~isnan(ind),2)<k+1,:) = [];

beats=NaN*ones(size(ind));
for g=1:size(ind,2)
    if isstruct(marks)
        f = getfield(marks, char(leads(g)));  %#ok<GFLD>
    else
        f = marks{g};
    end
    beats(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),5);
end
ind(find(diff(nanmedian(beats,2)) < messages.setup.SLR.refrper)+1,:) = [];

nbeats=size(ind,1);
marksSLR=NaN.*ones(nbeats,nmarks);
marksSLR_lead=NaN.*ones(nbeats,nmarks);
for mark=peaks
    beats=NaN*ones(size(ind));
    for g=1:size(ind,2)
        if isstruct(marks)
            f = getfield(marks, char(leads(g)));  %#ok<GFLD>
        else
            f = marks{g};
        end
        beats(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark);
    end
    marksSLR(:,mark)=nanmedian(beats,2);
end

if  nmarks==15;
    mark=7:10;
    QRS{1}=NaN*ones(size(ind));
    QRS{2}=QRS{1};
    QRS{3}=QRS{1};
    QRS{4}=QRS{1};
    for g=1:size(ind,2)
        if isstruct(marks)
            f = getfield(marks, char(leads(g)));  %#ok<GFLD>
        else
            f = marks{g};
        end
        QRS{1}(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark(1));  %#ok<AGROW>
        QRS{2}(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark(2)); %#ok<AGROW>
        QRS{3}(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark(3)); %#ok<AGROW>
        QRS{4}(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark(4)); %#ok<AGROW>
    end
    for beat=1:nbeats
        AA=[QRS{1}(beat,:);QRS{2}(beat,:);QRS{3}(beat,:);QRS{4}(beat,:)];
        %look for small R waves that should go with Q waves
        %RS that is an inverted QR or RSR' that is an inverted QRS
        ii=find(AA(2,:)-nanmedian(AA(2,:))<-messages.setup.SLR.tolerance);
        QRS{1}(beat,ii)=QRS{2}(beat,ii); %#ok<AGROW>
        QRS{2}(beat,ii)=QRS{3}(beat,ii); %#ok<AGROW>
        QRS{3}(beat,ii)=QRS{4}(beat,ii); %#ok<AGROW>
        QRS{4}(beat,ii)=NaN; %#ok<AGROW>
        AA=[QRS{1}(beat,:);QRS{2}(beat,:);QRS{3}(beat,:);QRS{4}(beat,:)];
        %look for Q waves that should go with R waves
        %QS complexes or QR that is an inverted RS
        ii=find(AA(1,:)-nanmedian(AA(1,:))>messages.setup.SLR.tolerance);
        QRS{4}(beat,ii)=QRS{3}(beat,ii); %#ok<AGROW>
        QRS{3}(beat,ii)=QRS{2}(beat,ii); %#ok<AGROW>
        QRS{2}(beat,ii)=QRS{1}(beat,ii); %#ok<AGROW>
        QRS{1}(beat,ii)=NaN; %#ok<AGROW>
        AA=[QRS{1}(beat,:);QRS{2}(beat,:);QRS{3}(beat,:);QRS{4}(beat,:)];
        %look for R' waves that should go with S waves
        ii=find(AA(4,:)-nanmedian(AA(4,:))<-messages.setup.SLR.tolerance);
        QRS{1}(beat,ii)=QRS{2}(beat,ii); %#ok<AGROW>
        QRS{2}(beat,ii)=QRS{3}(beat,ii); %#ok<AGROW>
        QRS{3}(beat,ii)=QRS{4}(beat,ii); %#ok<AGROW>
        QRS{4}(beat,ii)=NaN;  %#ok<AGROW>
        AA=[QRS{1}(beat,:);QRS{2}(beat,:);QRS{3}(beat,:);QRS{4}(beat,:)];
        marksSLR(beat,mark)=nanmedian(AA,2)';
    end
end
if size(marksSLR,2) == 15
    positionSLR.P = marksSLR(:,2);
    positionSLR.Pprima = marksSLR(:,3);
    positionSLR.qrs = marksSLR(:,8);
    positionSLR.QRSon = marksSLR(:,6);
    positionSLR.Q = marksSLR(:,7);
    positionSLR.R = marksSLR(:,8);
    positionSLR.S = marksSLR(:,9);
    positionSLR.Rprima = marksSLR(:,10);
    positionSLR.T = marksSLR(:,13);
    positionSLR.Tprima = marksSLR(:,14);
else
    positionSLR.P = marksSLR(:,2);
    positionSLR.qrs = marksSLR(:,5);
    positionSLR.T = marksSLR(:,8);
    positionSLR.Tprima = marksSLR(:,9);
end
for mark=onsets, %onsets
    beats=NaN.*ones(nbeats,nmarks);
    for g=1:size(ind,2)
        if isstruct(marks)
            f = getfield(marks, char(leads(g))); %#ok<GFLD>
        else
            f = marks{g};
        end
        beats(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark);
    end
    aux= sum(~isnan(beats),2);
    for beat=1:nbeats
        if aux(beat)>k, % if the mark was found in more than k of the leads
            kk = beats(beat,:);
            kk(isnan(kk))=[];
            [kk kki] =sort(kk); % sorted the mark found in the leads in beat
            while (length(kk)>k && kk(k+1)>(kk(1)+delta(mark))), %eliminate the first mark until kk satisfy the rule or length(kk)<k
                kk(1)=[];
                kki(1)=[];
            end
            %if length(kk)<k there is not a multilead mark
            if length(kk)==k
                marksSLR(beat,mark)=nan;
            else
                marksSLR(beat,mark)=kk(1);
                marksSLR_lead(beat,mark)=kki(1);
            end
        else
            marksSLR(beat,mark)=nan;
        end
    end
end
positionSLR.Pon = marksSLR(:,onsets(1));
positionSLR.QRSon = marksSLR(:,onsets(2));
positionSLR.Ton = marksSLR(:,onsets(3));
positionSLR.Pon_lead = marksSLR_lead(:,onsets(1));
positionSLR.QRSon_lead = marksSLR_lead(:,onsets(2));
positionSLR.Ton_lead = marksSLR_lead(:,onsets(3));

for mark=ends, % ends
    beats=NaN.*ones(nbeats,nmarks);
    for g=1:size(ind,2)
        if isstruct(marks)
            f = getfield(marks, char(leads(g))); %#ok<GFLD>
        else
            f = marks{g};
        end
        beats(~isnan(ind(:,g)),g)=f(ind(~isnan(ind(:,g)),g),mark);
    end
    aux= sum(~isnan(beats),2);
    for beat=1:nbeats
        if aux(beat)>k, %
            kk = beats(beat,:);
            kk(isnan(kk))=[];
            [kk kki] =sort(kk,'descend');
           % kk =flipud(sort(kk)')';
            while (length(kk)>k && kk(k+1)<(kk(1)-delta(mark))),
                kk(1)=[];
                kki(1)=[];
            end
            if length(kk)==k
                marksSLR(beat,mark)=nan;
            else
                marksSLR(beat,mark)=kk(1);
                marksSLR_lead(beat,mark)=kki(1);
            end
        else
            marksSLR(beat,mark)=nan;
        end
    end
end
positionSLR.Poff = marksSLR(:,ends(1));
positionSLR.QRSoff = marksSLR(:,ends(2));
positionSLR.Toff = marksSLR(:,ends(3));
positionSLR.Poff_lead = marksSLR_lead(:,ends(1));
positionSLR.QRSoff_lead = marksSLR_lead(:,ends(2));
positionSLR.Toff_lead = marksSLR_lead(:,ends(3));


classdef AddDeltaVAction < AbstractEventAction
    %AddDeltaVAction Summary of this class goes here
    %   Detailed explanation goes here

    properties
        deltaVVect(3,1) double = [0;0;0]; %store as km/s
        frame(1,1) DeltaVFrameEnum = DeltaVFrameEnum.Inertial;
        useDeltaMass(1,1) logical = false;

        optVar AbstractOptimizationVariable
    end

    methods
        function obj = AddDeltaVAction(deltaVVect, frame, useDeltaMass)
            if(nargin > 0)
                obj.deltaVVect = deltaVVect;
                obj.frame = frame;
                obj.useDeltaMass = useDeltaMass;
            end

            obj.id = rand();
        end

        function newStateLogEntry = executeAction(obj, stateLogEntry)
            newStateLogEntry = stateLogEntry;

            if(obj.frame == DeltaVFrameEnum.Inertial)
                dvKmsVect = obj.deltaVVect;

            elseif(obj.frame == DeltaVFrameEnum.OrbitNtw)
                dVVectECI = getNTW2ECIdvVect(obj.deltaVVect, newStateLogEntry.position, newStateLogEntry.velocity);
                dvKmsVect = dVVectECI;

            else
                error('Unknown reference frame found while executing action AddDeltaVAction.');
            end

            newStateLogEntry.velocity = newStateLogEntry.velocity + dvKmsVect;

            if(obj.useDeltaMass)
                [tankMDots, totalThrust, tankStates] = AddDeltaVAction.getTankMDotsAndTotalThrustForStateLogEntry(newStateLogEntry);

                if(abs(sum(tankMDots)) > 0)
                    tankMDotsKgS = tankMDots * 1000;
                    totalMDotKgS = sum(tankMDotsKgS);
                    totalThrustN = totalThrust * 1000;
                    effIsp = totalThrustN / (getG0() * abs(totalMDotKgS)); %sec

                    dvVectMag = norm(dvKmsVect);
                    m0 = newStateLogEntry.getTotalVehicleMass();
                    m1 = revRocketEqn(m0, effIsp, dvVectMag);
                    deltaMassMT = m0 - m1;

                    deltaMassPerTankMT = deltaMassMT * (abs(tankMDots) / abs(sum(tankMDots)));

                    for(i=1:length(tankStates))
                        tankStates(i).setTankMass(tankStates(i).getTankMass() - deltaMassPerTankMT(i));
                    end
                end
            end
        end

        function initAction(obj, initialStateLogEntry)
            %none
        end

        function name = getName(obj)
            name = sprintf('Add Delta-V ([%0.3f %0.3f %0.3f] m/s %s)', obj.deltaVVect(1)*1000, obj.deltaVVect(2)*1000, obj.deltaVVect(3)*1000, obj.frame.nameStr);
        end

        function tf = usesStage(obj, stage)
            tf = false;
        end

        function tf = usesEngine(obj, engine)
            tf = false;
        end

        function tf = usesTank(obj, tank)
            tf = false;
        end

        function tf = usesEngineToTankConn(obj, engineToTank)
            tf = false;
        end

        function tf = usesStopwatch(obj, stopwatch)
            tf = false;
        end

        function tf = usesExtremum(obj, extremum)
            tf = false;
        end

        function tf = usesTankToTankConn(obj, tankToTank)
            tf = false;
        end

        function [tf, vars] = hasActiveOptimVar(obj)
            tf = false;
            vars = AbstractOptimizationVariable.empty(0,1);

            if(not(isempty(obj.optVar)))
                tf = any(obj.optVar.getUseTfForVariable());
                vars(end+1) = obj.optVar;
            end
        end

        function data = getUploadDvToKspData(obj, stateLogEntry)
            time = stateLogEntry.time;
            rVect = stateLogEntry.position;
            vVect = stateLogEntry.velocity;

            if(obj.frame == DeltaVFrameEnum.Inertial)
                deltaVNTW = 1000*getNTWdvVect(obj.deltaVVect, rVect(:), vVect(:));

            elseif(obj.frame == DeltaVFrameEnum.OrbitNtw)
                deltaVNTW = 1000*obj.deltaVVect;

            else
                error('Unknown reference frame found while executing action AddDeltaVAction.');
            end

            data(1) = 0;
            data(2) = time;
            data(3) = deltaVNTW(1);
            data(4) = deltaVNTW(2);
            data(5) = deltaVNTW(3);
        end
    end

    methods(Static)
        function addActionTf = openEditActionUI(action, lv)
%             addActionTf = lvd_AddDeltaVActionGUI(action, lv.lvdData);

            output = AppDesignerGUIOutput({false});
            lvd_AddDeltaVActionGUI_App(action, lv.lvdData, output);
            addActionTf = output.output{1};
        end

        function [tankMDots, totalThrust, tankStates] = getTankMDotsAndTotalThrustForStateLogEntry(newStateLogEntry)
            tankStates = newStateLogEntry.getAllActiveTankStates();
            tankStatesMasses = [tankStates.tankMass];
            stageStates = newStateLogEntry.stageStates;
            lvState = newStateLogEntry.lvState;
            ut = newStateLogEntry.time;
            rVect = newStateLogEntry.position;
            vVect = newStateLogEntry.velocity;
            bodyInfo = newStateLogEntry.centralBody;
            steeringModel = newStateLogEntry.steeringModel;

            altitude = newStateLogEntry.altitude;
            pressure = getPressureAtAltitude(bodyInfo, altitude);
            throttle = 1.0;

            powerStorageStates = newStateLogEntry.getAllActivePwrStorageStates();
            storageSoCs = NaN(size(powerStorageStates));
            for(j=1:length(powerStorageStates)) %#ok<*NO4LP>
                storageSoCs(j) = powerStorageStates(j).getStateOfCharge();
            end

            attState = LaunchVehicleAttitudeState();
            attState.dcm = steeringModel.getBody2InertialDcmAtTime(ut, rVect, vVect, bodyInfo);

            [tankMDots, totalThrust, ~, ~] = newStateLogEntry.getTankMassFlowRatesDueToEngines(tankStates, tankStatesMasses, stageStates, throttle, lvState, pressure, ut, rVect, vVect, bodyInfo, steeringModel, storageSoCs, powerStorageStates, attState);
        end
    end
end


function [tri, x] = remove_vertex_from_tri(tri, x, idx)
% REMOVE_VERTEX_FROM_TRI  Remove vertices from a triangular mesh
%
% This function removes vertices from a mesh and all triangles they are
% part of. It also relabels vertex indices accordingly.
%
% [TRI2, X2] = remove_vertex_from_tri(TRI, X, IDX)
%
%   TRI is a 3-column matrix. Each row represents the indices of the three
%   vertices that form a triangle. TRI as a whole represents the closed
%   surface.
%
%   X is a 3-column matrix. Each row represents the Cartesian coordinates
%   of a vertex on the surface, indexed by TRI values.
%
%   IDX is a vector of vertex indices.
%
%   TRI2 and X2 are the matrices that describe the mesh after the vertices
%   have been removed.
%
% See also: addpoint2tri.

% Author: Ramon Casero <rcasero@gmail.com>
% Copyright © 2013 University of Oxford
% Version: 0.1.0
%
% University of Oxford means the Chancellor, Masters and Scholars of
% the University of Oxford, having an administrative office at
% Wellington Square, Oxford OX1 2JD, UK.
%
% This file is part of Gerardus.
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details. The offer of this
% program under the terms of the License is subject to the License
% being interpreted in accordance with English Law and subject to any
% action against the University of Oxford being under the jurisdiction
% of the English Courts.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see
% <http://www.gnu.org/licenses/>.

% check arguments
narginchk(3, 3);
nargoutchk(0, 2);

% map between node indices map(10) = 6 means that vertex 10 will be renamed
% as 6
map = 1:size(x, 1);

% remove duplicates
idx = unique(idx);

% number of indices
N = length(idx);

% loop every index to remove
for I = 1:N

    % if we remove one vertex, all vertices after it decrease their index
    map(idx(I):end) = map(idx(I):end) - 1;

end

% find triangles connected to the vertex that are going to be removed
[I, J] = find(ismember(tri, idx));

% remove triangles
tri(I, :) = [];

% remove vertices
x(idx, :) = [];

% rename vertices in triangles
tri = map(tri);


function [xyQ,stateindex] = ExtractQ_XY_2D_POTTS(state,x,y,Q)

display('Extracting Q_[X, Y] values')
xyQ=cell(1,Q);
stateindex=xyQ;
for q = 1:Q
    stateindex{1,q}=find(state(:,:)==q);
    xyQ{1,q}=[];
    for count=1:prod(size(stateindex{1,q}))
        ElementRnCn(count,:)=FindRC_2D_QPOTTS(stateindex{1,q}(count),state);
        xyQ{1,q}=[xyQ{1,q};...
            x(ElementRnCn(count,1),ElementRnCn(count,2)) y(ElementRnCn(count,1),ElementRnCn(count,2))];
    end
end

github-repos/MATLAB/Sable-mcbench-benchmarks/mcbench-benchmarks-ba13b2f0296ef49491b95e3f984c7c41fccdb6d8/34784-monte-carlo-simulation-of-two-dimensional-grain-growth-code-version-no-1-basic/Monte Carlo Simulation Q-state Potts model 2D square-lattice - microstructure/ExtractQ_XY_2D_POTTS.m