%%***************************************************************
%% linsysolve: solve linear system to get dy, and direction
%%             corresponding to unrestricted variables.
%%
%% [xx,coeff,L,resnrm] = linsysolve(schur,UU,Afree,EE,rhs);
%%
%% child functions: symqmr.m, mybicgstable.m, linsysolvefun.m
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%***************************************************************

   function [xx,coeff,L,resnrm] = linsysolve(par,schur,UU,Afree,EE,rhs);

    global solve_ok existspcholsymb exist_analytic_term
    global nnzmat nnzmatold matfct_options matfct_options_old use_LU
    global Lsymb msg diagR diagRold

    spdensity  = par.spdensity;
    printlevel = par.printlevel;
    iter       = par.iter;
    err        = max([par.relgap,par.pinfeas,par.dinfeas]);

    m = length(schur);
    if (iter==1);
       use_LU = 0; matfct_options_old = '';
       diagR = ones(m,1);
    end
    if isempty(nnzmatold); nnzmatold = 0; end
    diagRold = diagR;
%%
%% schur = schur + rho*diagschur + lam*AAt
%%
    diagschur = abs(full(diag(schur)));
    if (par.ublksize)
       minrho = 1e-15;
    else
       minrho = 1e-17;
    end
    const = 1e-2;
    ratio = max(diagR)/min(diagR);
    if (par.depconstr) | (ratio > 1e10) | (iter < 5)
       %% important: do not perturb beyond certain threshold
       %% since it will adversely affect prim_infeas of fp43
       %%
       rho = max(minrho,min(1e-10,const*norm(par.rp)/(1+norm(diagschur.*par.dy))));
       if (exist_analytic_term); rho = 0; end
       pertdiag = rho*max(1e-8,diagschur);
       mexschurfun(schur,pertdiag);
       %%if (printlevel>2); fprintf(' %2.1e',rho); end
    end
    if (par.depconstr) | (par.ZpATynorm > 1e10) | (par.ublksize) | (iter < 10)
       %% Note: do not add this perturbation even if ratio is large.
       %% It adversely affects hinf15.
       %%
       lam = 0.1*min(1e-14,const*norm(par.rp)/(1+norm(par.AAt*par.dy)));
       if (exist_analytic_term); lam = 0; end
       mexschurfun(schur,lam*par.AAt);
       %%if (printlevel>2); fprintf(' *%2.1e ',lam); end
    end
    if (max(diagschur)/min(diagschur) > 1e14) & (par.blkdim(2) == 0) ...
       & (iter > 10)
       tol = 1e-8;
       idx = find(diagschur < tol); len = length(idx);
       pertdiagschur = zeros(m,1);
       if (len > 0 & len < 5) & (norm(rhs(idx)) < tol)
          pertdiagschur(idx) = 1*ones(length(idx),1);
          mexschurfun(schur,pertdiagschur);
          if (printlevel>2); fprintf('#'); end
       end
    end
%%
%% assemble coefficient matrix
%%
    len = size(Afree,2);
    if ~isempty(EE)
       EE(:,[1 2]) = len + EE(:,[1 2]); %% adjust for ublk
    end
    EE = [(1:len)' (1:len)' zeros(len,1); EE];
    if isempty(EE)
       coeff.mat22 = [];
    else
       coeff.mat22 = spconvert(EE);
    end
    if (size(Afree,2) | size(UU,2))
       coeff.mat12 = [Afree, UU];
    else
       coeff.mat12 = [];
    end
    coeff.mat11 = schur; %% important to use perturbed schur matrix
    ncolU = size(coeff.mat12,2);
%%
%% pad rhs with zero vector
%% decide which solution methods to use
%%
    rhs = [rhs; zeros(m+ncolU-length(rhs),1)];
    if (ncolU > 300); use_LU = 1; end
%%
%% Cholesky factorization
%%
    L = []; resnrm = norm(rhs); xx = inf*ones(m,1);
    if (~use_LU)
       solve_ok = 1;  solvesys = 1;
       nnzmat = mexnnz(coeff.mat11);
       nnzmatdiff = (nnzmat ~= nnzmatold);
       if (nnzmat > spdensity*m^2) | (m < 500)
          matfct_options = 'chol';
       else
          if (par.matlabversion >= 7.3) %% & (par.computer == 64)
             matfct_options = 'spchol';
	  else
             matfct_options = 'myspchol';
          end
       end
       if (printlevel>2); fprintf(' %s ',matfct_options); end
       if strcmp(matfct_options,'chol')
          if issparse(schur); schur = full(schur); end;
          if (iter<=5); %% to fix strange anonmaly in Matlab
             mexschurfun(schur,1e-20,2);
          end
          L.matfct_options = 'chol';
          L.perm = [1:m];
          [L.R,indef] = chol(schur);
          diagR = diag(L.R).^2;
          if (indef)
             diagR = diagRold;
 	     solve_ok = -2; solvesys = 0;
             msg = 'linsysolve: Schur complement matrix not pos. def.';
             if (printlevel); fprintf('\n  %s',msg); end
          end
       elseif strcmp(matfct_options,'spchol')
          if ~issparse(schur); schur = sparse(schur); end;
          L.matfct_options = 'spchol';
          [L.R,indef,L.perm] = chol(schur,'vector');
          L.Rt = L.R';
          diagR = full(diag(L.R)).^2;
          if (indef)
             diagR = diagRold;
 	     solve_ok = -2; solvesys = 0;
             msg = 'linsysolve: Schur complement matrix not pos. def.';
             if (printlevel); fprintf('\n  %s',msg); end
          end
       elseif strcmp(matfct_options,'myspchol')
          if ~issparse(schur), schur = sparse(schur); end;
          if (nnzmatdiff | ~strcmp(matfct_options,matfct_options_old))
             [Lsymb,flag] = symbcholfun(schur,par.cachesize);
             if (flag)
                solve_ok = -2;  solvesys = 0;
                existspcholsymb = 0;
                msg = 'linsysolve: symbolic factorization fails';
                if (printlevel); fprintf('\n  %s',msg); end
                use_LU = 1;
             else
                existspcholsymb = 1;
             end
          end
          if (existspcholsymb)
             L = sparcholfun(Lsymb,schur);
             L.matfct_options  = 'myspchol';
             L.d(find(L.skip)) = 1e20;
             if any(L.skip) & (ncolU)
                solve_ok = -3; solvesys = 0;
                existspcholsymb = 0;
                use_LU = 1;
                if (printlevel)
                   fprintf('\n  L.skip exists but ncolU > 0.');
                   fprintf('\n  switch to LU factor.');
                end
             end
          end
       end
       if (solvesys)
          if (ncolU)
             tmp = coeff.mat12'*linsysolvefun(L,coeff.mat12)-coeff.mat22;
	     if issparse(tmp); tmp = full(tmp); end
             tmp = 0.5*(tmp + tmp');
             [L.Ml,L.Mu,L.Mp] = lu(tmp);
             tol = 1e-16;
             condest = max(abs(diag(L.Mu)))/min(abs(diag(L.Mu)));
             idx = find(abs(diag(L.Mu)) < tol);
             if ~isempty(idx) | (condest > 1e18);
                solvesys = 0; solve_ok = -4;
                use_LU = 1;
                msg = 'SMW too ill-conditioned, switch to LU factor';
                if (printlevel); fprintf('\n  %s.',msg); end
             end
          end
          [xx,resnrm,solve_ok] = symqmr(coeff,rhs,L,[],[],printlevel);
          if (solve_ok <= 0.3) & (printlevel)
             fprintf('\n  warning: symqmr failed: %3.1f ',solve_ok);
          end
       end
       if (solve_ok <= 0.3)
          tol = 1e-10;
          if (m < 7e3 & strcmp(matfct_options,'chol') & (err > tol)) ...
             | (m < 2e5 & strcmp(matfct_options,'spchol') & (err > tol)) ...
             | (m < 2e5 & strcmp(matfct_options,'myspchol') & (err > tol))
             use_LU = 1;
             if (printlevel); fprintf('\n  switch to LU factor.'); end
          end
       end
    end
%%
%% LU factorization
%%
    if (use_LU)
       nnzmat = mexnnz(coeff.mat11)+mexnnz(coeff.mat12);
       nnzmatdiff = (nnzmat ~= nnzmatold);
       solve_ok = 1; solvesys = 1;
       if ~isempty(coeff.mat22)
          raugmat = [coeff.mat11, coeff.mat12; coeff.mat12', coeff.mat22];
       else
          raugmat = coeff.mat11;
       end
       if (nnzmat > spdensity*m^2) | (m+ncolU < 500)
          matfct_options = 'lu';
       else
          matfct_options = 'splu';
       end
       if (printlevel>2); fprintf(' %s ',matfct_options); end
       if strcmp(matfct_options,'lu')
          if issparse(raugmat); raugmat = full(raugmat); end
          [L.l,L.u,L.p] = lu(raugmat);
          L.matfct_options = 'lu';
          L.p = sparse(L.p);
          idx = find(abs(diag(L.u)) < 1e-30);
          if ~isempty(idx)
             msg = 'linsysolve: matrix is singular';
             if (printlevel); fprintf('\n  %s',msg); end
             solvesys = 0;
          end
          [ii,jj] = find(L.p); [dummy,idx] = sort(ii); L.perm = jj(idx);
       end
       if strcmp(matfct_options,'splu')
          if ~issparse(raugmat); raugmat = sparse(raugmat); end
          L.perm = [1:length(raugmat)];
          L.matfct_options = 'splu';
          L.symmatrix = 1;
          [L.l,L.u,L.p,L.q] = lu(raugmat);
          [ii,jj] = find(L.p); L.p = ii;
          [ii,jj] = find(L.q); L.q = ii;
       end
       if (solvesys)
          [xx,resnrm,solve_ok] = mybicgstab(coeff,rhs,L,[],[],printlevel);
          if (solve_ok<=0) & (printlevel)
             fprintf('\n  warning: bicgstab fails: %3.1f,',solve_ok);
          end
       end
    end
    if (printlevel>2); fprintf('%2.0d ',length(resnrm)-1); end
%%
    nnzmatold = nnzmat; matfct_options_old = matfct_options;
%%***************************************************************


function [mCatDecluster, mCatAfter, vCluster, vCl, vMainCluster] = calc_decluster_ver1(mCatalog,nMethod)
% function [mCatDecluster, mCatAfter, vCluster, vCl, vMainCluster] = calc_decluster_ver1(mCatalog,nMethod)
% ----------------------------------------------------------------------------------------------------------
%
% Function to decluster earthquake catalog using the windowing technique in space and time by
% Knopoff & Gardner, GJR astr. Soc, 28, 311-313, 1972
% Gardner & Knopoff, BSSA, 64,5, 1363-1367, 1974
% using different windows
%
% Incoming variables
% mCatalog : Incoming earthquake catalog (ZMAP format)
% nMethod  : Window length for declustering (see calc_windows.m)
%            1: Gardener & Knopoff, 1974
%            2: Gruenthal pers. communication
%            3: Urhammer, 1986
%
% Outgoing variables:
% mCatDecluster : Declustered earthquake catalog
% mCatAfter     : Catalog of aftershocks (foreshocks)
% vCluster      : Vector indicating only aftershocks/foreshocls in cluster using a cluster number
% vCl           : Vector indicating all events in clusters using a cluster number
% vMainCluster  : Vector indicating mainshocks of clusters using a cluster number
%
% J. Woessner, woessner@seismo.ifg.ethz.ch
% last update: 31.07.02

%% Added:
% 31.07.02 Correction for problem of mainshocks with a cluster number as aftershocks belong to two sequences
% 31.07.02 Corrected fMaxClusterMag(nMagCount) to fMaxClusterMag, since counting variable not needed

%%% Remember: Improve zero length cluster problem, no waitbars yet, time difference mainshock-original event not implemented
%% This is the version before calc_decluster.m

%% Initialize Vectors and Matrices
mCatDecluster = [];
mCatAfter = [];
vCluster = zeros(length(mCatalog),1); % Initialize all events as mainshock
vCl = zeros(length(mCatalog),1); % Initialize all events as mainshock
vSel = zeros(length(mCatalog),1); % Initialize all events as mainshock
vMainCluster = zeros(length(mCatalog),1); % Initialize

[nXSize, nYsize] = size(mCatalog);
if nXSize == 0
    disp('Load new catalog');
    return
end

vDecDate = mCatalog(:,3);
nCount = 0;    % Variable of cluster number

fMagThreshold = min(mCatalog(:,6)); % Set Threshold to minimum magnitude of catalog
for nEvent=1:length(mCatalog(:,6))
    %nEvent
    if vCluster(nEvent) == 0
        fMagnitude(nEvent) = mCatalog(nEvent, 6);
        if fMagnitude(nEvent) >= fMagThreshold
            %% Define first aftershock zone and determine magnitude of strongest aftershock
            fMag = fMagnitude(nEvent);
            [fSpace, fTime] = calc_windows(fMagnitude(nEvent), nMethod);
            fSpaceDeg = km2deg(fSpace);
            %% This first if is for events with no location given
            if isnan(mCatalog(nEvent,1))
                %vSel = (vDecDate(:,1)-vDecDate(nEvent,1) >= 0) & (vDecDate(:,1)-vDecDate(nEvent,1) <= fTime  & vCluster(nEvent) == 0);
                vSel = (mCatalog(:,3) == mCatalog(nEvent,3));
            else
                vSel = (abs(mCatalog(:,1) - mCatalog(nEvent,1)) <= fSpaceDeg) & (abs(mCatalog(:,2) - mCatalog(nEvent,2)) <= fSpaceDeg)...
                    & (vDecDate(:,1)-vDecDate(nEvent,1) >= 0) & (vDecDate(:,1)-vDecDate(nEvent,1) <= fTime & vCluster(nEvent) == 0);
            end
            mTmp = mCatalog(vSel,:);
            %nMagCount = 1; % Variable to determine max. magnitude in a cluster
            if length(mTmp(:,1)) == 1  % Only one event thus no cluster
                fMaxClusterMag = fMag;
            else
                fMaxClusterMag = max(mTmp(:,6));
                % Search for event with bigger magnitude in cluster and resize windows if necessary
                while fMaxClusterMag-fMag > 0
                    [fSpace, fTime] = calc_windows(fMaxClusterMag, nMethod);
                    fSpaceDeg = km2deg(fSpace);
                    vSel = (abs(mCatalog(:,1) - mCatalog(nEvent,1)) <= fSpaceDeg) &...
                        (abs(mCatalog(:,2) - mCatalog(nEvent,2)) <= fSpaceDeg)...
                        & (vDecDate(:,1)-vDecDate(nEvent,1) >= 0) & (vDecDate(:,1)-vDecDate(nEvent,1) <= fTime & vSel == 1);
                    mTmp = mCatalog(vSel,:);
                    if isempty(mTmp) % no events in aftershock zone
                        break;
                    end
                    fMag = fMaxClusterMag;
                    %nMagCount = nMagCount+1;
                    fMaxClusterMag = max(mTmp(:,6));
                    if fMaxClusterMag - fMag == 0 % no bigger event in aftershock zone
                        break;
                    end
                end  % End of while
                nCount = nCount + 1; % Set cluster number
            end % End of if
            % Define final aftershock zone if different from original one
            if fMaxClusterMag > fMagnitude(nEvent)
                [fSpace, fTime] = calc_windows(fMaxClusterMag, nMethod);
                fSpaceDeg = km2deg(fSpace);
                % Select events with the Event having the number nEvent, since it is a foreshock (time condition)
                vSel = (abs(mCatalog(:,1) - mCatalog(nEvent,1)) <= fSpaceDeg) & (abs(mCatalog(:,2) - mCatalog(nEvent,2)) <= fSpaceDeg)...
                    & (vDecDate(:,1)-vDecDate(nEvent,1) >= 0) & (vDecDate(:,1)-vDecDate(nEvent,1) <= fTime & vCluster(nEvent) == 0);
            end
            [vIndice]=find(vSel); % Vector of indices with Clusters
            vTmpCluster(vIndice,:) = nCount;
            length(vTmpCluster(vIndice,:));
            nI=1; % Variable counting the length of the cluster
            % Select the right numbers for the cluster using the indice vector vIndice
            % First: Insert cluster number after check for length
            % Second: Check if it's a mainshock
            % Third: Keep the former cluster indice;
            while nI <= length(vIndice)
                if (~isempty(vTmpCluster(vIndice(nI))) & length(vTmpCluster(vIndice,:)) > 1 & vCluster(vIndice(nI)) == 0)
                    vCluster(vIndice(nI)) = vTmpCluster(vIndice(nI));
                    %vEventnr(vIndice,:) = nEvent;
                elseif  (~isempty(vTmpCluster(vIndice(nI)))  &&  length(vTmpCluster(vIndice,:)) == 1  &&  vCluster(vIndice(nI)) == 0)
                    vCluster(vIndice(nI)) = 0;
                else
                    vCluster(vIndice(nI)) = vCluster(vIndice(nI));
                end
                nI=nI+1;
            end %End of while nI
            %%% Check if the Cluster is not just one event which can happen in case of keeping the former
            %%% cluster number in preceeding while-Loop
            vSelSingle = (vCluster == nCount);
            [vIndiceSingle] = find(vSelSingle);
            %vTmpSingle(vIndiceSingle,:);
            if length(vIndiceSingle) == 1
                nCount
                vIndiceSingle
                vCluster(vIndiceSingle)=0; % Set the event as mainsock
                nCount = nCount-1; % Correct the cluster number down by one
            end
        end % End of if checking magnitude threshold fMagThreshold
    end % End of if chekcing if vCluster == 0
end % End of FOR over mCatalog
%nCount
%% vCL Cluster vector with mainshocks in it; vCluster is now modified to get rid of mainshocks
vCl = vCluster;

%% Matrix with cluster indice, magnitude and time
mTmpCat = [vCluster mCatalog(:,6) mCatalog(:,3)];
%% Delete largest event from cluster series and add to mainshock catalog
for nCevent = 1:nCount
    %nCevent
    vSel4 = (mTmpCat(:,1) == nCevent); % Select cluster
    mTmpCat2 = mCatalog(vSel4,:);
    fTmpMaxMag = max(mTmpCat2(:,6)); % Select max magnitude of cluster
    vSelMag = (mTmpCat2(:,6) == fTmpMaxMag);
    [nMag] = find(vSelMag);
    if length(nMag) == 1
        vSel5 = (mTmpCat(:,1) == nCevent & mTmpCat(:,2) == fTmpMaxMag); % Select the event
        [vIndiceMag] = find(vSel5); % Find indice
        vCluster(vIndiceMag) = 0;  % Set cluster value to zero, so it is a mainshock
        vMainCluster(vIndiceMag) = nCevent; % Set mainshock vector to cluster number
    elseif isempty(nMag)
        disp('Nothing in ')
        nCevent
    else
        vSel = (mTmpCat(:,1) == nCevent & mTmpCat(:,2) == fTmpMaxMag);
        mTmpCat3 = mCatalog(vSel,:);
        [vIndiceMag] = min(find(vSel)); % Find minimum indice of event with max magnitude in cluster
        vCluster(vIndiceMag) = 0;  % Set cluster value to zero, so it is a mainshock
        vMainCluster(vIndiceMag) = nCevent;  % Set mainshock vector to cluster number
    end
end % End of For nCevent

%% Create a catalog of aftershocks (mCatAfter) and of declustered catalog (mCatDecluster)
vSel = (vCluster(:,1) > 0);
mCatDecluster=mCatalog(~vSel,:);
mCatAfter = mCatalog(vSel,:);


clear
close all

plotx2east

load martensite_single_grain

[grains,ebsd('indexed').grainId] =...
    calcGrains(ebsd('indexed'),'angle',3*degree);

cond_grains = ismember(grains.id,unique(ebsd(ids_of_interest).grainId));

%%
job = parentGrainReconstructor(ebsd,grains) % define job
job.useBoundaryOrientations = true;
clearvars grains ebsd

job.p2c = orientation.KurdjumovSachs(job.p2c.CS,job.p2c.SS);
job.calcParent2Child('quantile',0.6,'c2c'); % get representative OR

%%
job.calcHyperGraph3('threshold',5*degree,'c2c','mergeSimilar','mergethreshold',8*degree,'keepGraph')

numIters = [3 10 50];
grainId = 1844;

%%

for k = 1:length(numIters);
    if k == 1
    job.clusterHyperGraph3('numIter',numIters(k),...
        'inflationPower',1,'merged','mergethreshold',8*degree,'keepGraph')
        graphplotfunc(job,cond_grains,grainId,k,numIters)
    else
    job.clusterHyperGraph3('numIter',numIters(k) - numIters(k-1),...
        'inflationPower',1,'merged','mergethreshold',8*degree,'keepGraph')
        graphplotfunc(job,cond_grains,grainId,k,numIters)
    end
end

for k = 1:length(numIters);
    if k == 1
    job.clusterHyperGraph3('numIter',numIters(k),...
        'inflationPower',1.05,'merged','mergethreshold',8*degree,'keepGraph')
        graphplotfunc(job,cond_grains,grainId,k,numIters)
    else
    job.clusterHyperGraph3('numIter',numIters(k) - numIters(k-1),...
        'inflationPower',1.05,'merged','mergethreshold',8*degree,'keepGraph')
        graphplotfunc(job,cond_grains,grainId,k,numIters)
    end
end

%%
function graphplotfunc(job,cond_grains,grainId,k,numIters)
p2c = orientation.NishiyamaWassermann(job.p2c.CS,job.p2c.SS);
p2c = p2c.project2FundamentalRegion(job.p2c);

pOri = variants(p2c, job.grains.meanOrientation, job.votes.parentId(:,1));

nextAxis
plot(job.grains(cond_grains),...
    pOri(cond_grains))
lims = job.ebsd.extent;
xlim([lims(1) lims(2)])
ylim([lims(3) lims(4)])

text(lims(1)+5,lims(4)-10, [num2str(numIters(k)) ' iterations'],...
    'HorizontalAlignment','left',...
    'FontSize',20, 'FontWeight','bold','BackgroundColor', 'white')

end


% IMAGE
% See also
%
% Display:
%   clusterMontage    - Used for visualization of clusters of images and videos.
%   im                - Function for displaying grayscale images.
%   filmStrip         - Used to display R stacks of T images as a "filmstrip".
%   makeGif           - Writes a matlab movie to an animated GIF.
%   montage2          - Used to display collections of images and videos.
%   movieToImages     - Creates a stack of images from a matlab movie M.
%   playMovie         - Shows/makes an/several movie(s) from an image sequence.
%
% Histograms:
%   assignToBins      - Quantizes A according to values in edges.
%   histc2            - Multidimensional histogram count with weighted values.
%   histcImWin        - Calculates local histograms at every point in an image I.
%   histcImLoc        - Creates a series of locally position dependent histograms.
%   histMontage       - Used to display multiple 1D histograms.
%
% Generalized correlation:
%   normxcorrn        - Normalized n-dimensional cross-correlation.
%   xcorrn            - n-dimensional cross-correlation.  Generalized version of xcorr2.
%   xeucn             - n-dimensional euclidean distance between each window in A and template T.
%
% Image deformation:
%   imagesAlign       - Fast and robust estimation of homography relating two images.
%   imNormalize       - Various ways to normalize a (multidimensional) image.
%   imShrink          - Used to shrink a multidimensional array I by integer amount.
%   imtransform2      - Applies a linear or nonlinear transformation to an image I.
%   jitterImage       - Creates multiple, slightly jittered versions of an image.
%   opticalFlow       - Coarse-to-fine optical flow using Lucas&Kanade or Horn&Schunck.
%   textureMap        - Maps texture in I according to rsDst and csDst.
%
% Generalized nonmaximal suppression:
%   nonMaxSupr        - Applies nonmaximal suppression on an image of arbitrary dimension.
%   nonMaxSuprList    - Applies nonmaximal suppression to a list.
%   nonMaxSuprWin     - Nonmaximal suppression of values outside of a given window.
%
% Seq files:
%   seqIo             - Utilities for reading and writing seq files.
%   seqReaderPlugin   - Plugin for seqIo and videoIO to allow reading of seq files.
%   seqWriterPlugin   - Plugin for seqIo and videoIO to allow writing of seq files.
%   seqPlayer         - Simple GUI to play seq files.
%
% Behavior annotation for seq files:
%   behaviorAnnotator - Caltech Behavior Annotator.
%   behaviorData      - Retrieve and manipulate behavior annotation of a video.
%
% Binary mask creation:
%   maskCircle        - Creates an image of a 'pie slice' of a circle.
%   maskEllipse       - Creates a binary image of an ellipse.
%   maskGaussians     - Divides a volume into softly overlapping gaussian windows.
%   maskSphere        - Creates an 'image' of a n-dimensional hypersphere.
%
% Linear filtering:
%   convnFast         - Fast convolution, replacement for both conv2 and convn.
%   gaussSmooth       - Applies Gaussian smoothing to a (multidimensional) image.
%   localSum          - Fast routine for box filtering.
%
% Miscellaneous:
%   imMlGauss         - Calculates max likelihood params of Gaussian that gave rise to image G.
%   imrectLite        - A 'lite' version of imrect [OBSOLETE: use imrectRot].
%   imRectRot         - Create a draggable, resizable, rotatable rectangle or ellipse.
%   imwrite2          - Similar to imwrite, except follows a strict naming convention.
%   kernelTracker     - Kernel Tracker from Comaniciu, Ramesh and Meer PAMI 2003.


classdef PlaneStressTransformer < handle

    properties (Access = protected)
        psTensor
    end

    methods (Access = public,Static)

        function psTensor = transform(Tensor)
            factory       = PlaneStressTransformerFactory();
            planeStresser = factory.create(Tensor);
            psTensor      = planeStresser.getTensor();
        end

    end

    methods (Access = private)

        function t = getTensor(obj)
            t = obj.psTensor;
        end

    end

    methods (Access = protected,Abstract)
        createPlaneStressTensor(obj)
    end

end


function gf=gfobs_L1L5(obsr,obsb,lam)

pi=sdobs(obsr,obsb,1)*lam(1);
pj=sdobs(obsr,obsb,3)*lam(3);

if pi==0||pj==0
    gf=0;
else
    gf=pi-pj;
end

return


function [FrEn,avLL] = evalfreeenergy_ehmm(T,Gamma,Xi,ehmm,residuals,XX,todo)
% Computes the Free Energy of an HMM depending on observation model
%
% INPUT
% T            length of series
% Gamma        probability of states conditioned on data
% Xi           joint probability of past and future states conditioned on data
% ehmm          bsmm structure
% residuals    in case we train on residuals, the value of those.
%
% OUTPUT
% FrEn         the variational free energy, separated in different terms:
%                   element 1: Gamma Entropy
%                   element 2: data negative loglikelihood
%                   element 3: Gamma negative loglikelihood
%                   element 4: KL for initial and transition probabilities
%                   elements 5-: KL for the state parameters
% avLL         log likelihood of the observed data, per trial
%
% Author: Diego Vidaurre, OHBA, University of Oxford

if nargin<7, todo = ones(1,5); end

K = ehmm.K;

if nargin>=6, Tres = size(residuals,1);
else, Tres = sum(T) - length(T)*ehmm.train.maxorder;
end
setstateoptions;
ltpi = sum(regressed)/2 * log(2*pi);
np = size(XX,2); ndim = size(residuals,2);

% Entropy of Gamma
Entr = [];
if todo(1)==1
    Entr = GammaEntropy_ehmm(Gamma,Xi,T);
end

% loglikelihood of Gamma
avLLGamma = [];
if todo(3)==1
    avLLGamma = GammaavLL_ehmm(ehmm,Xi);
end

% P and Pi KL
KLdivTran = [];
if todo(4)==1
    KLdivTran = KLtransition_ehmm(ehmm);
end

% state KL
KLdiv = [];
if todo(5)==1

    OmegaKL = 0;
    for n = 1:ndim
        if ~regressed(n), continue; end
        OmegaKL = OmegaKL + gamma_kl(ehmm.Omega.Gam_shape,ehmm.prior.Omega.Gam_shape, ...
            ehmm.Omega.Gam_rate(n),ehmm.prior.Omega.Gam_rate(n));
    end
    KLdiv = [KLdiv OmegaKL];

    WKL = 0;
    Sind_all = [repmat(Sind(:,n),K,1) == 1; false(np,1)];
    for n = 1:ndim
        prior_prec = [];
        for k = 1:K
            hs = ehmm.state(k);
            pr = ehmm.state(k).prior;
            if ~regressed(n), continue; end
            if ~train.zeromean, prior_prec = hs.prior.Mean.iS(n); end
            if train.order > 0
                ndim_n = sum(S(:,n));
                alphaterm = repmat( (hs.alpha.Gam_shape ./  hs.alpha.Gam_rate), ndim_n, 1);
                if ndim==1
                    prior_prec = [prior_prec; alphaterm(:)] ;
                else
                    sigmaterm = repmat(hs.sigma.Gam_shape(S(:,n),n) ./ ...
                        hs.sigma.Gam_rate(S(:,n),n), length(orders), 1);
                    prior_prec = [prior_prec; sigmaterm .* alphaterm(:)] ;
                end
            end
        end
        prior_var = diag(1 ./ prior_prec);
        WKL = WKL + gauss_kl(ehmm.state_shared(n).Mu_W(Sind_all),zeros(np*K,1), ...
            ehmm.state_shared(n).S_W(Sind_all,Sind_all), prior_var);
    end
    KLdiv = [KLdiv WKL];

    sigmaKL = 0; alphaKL = 0;
    for k = 1:K+1
        if isempty(train.prior) && ~isempty(orders) && ~train.uniqueAR && ndim>1
            for n1 = 1:ndim
                for n2 = 1:ndim
                    if (train.symmetricprior && n2<n1) || S(n1,n2)==0, continue; end
                    sigmaKL = sigmaKL + gamma_kl(hs.sigma.Gam_shape(n1,n2),pr.sigma.Gam_shape(n1,n2), ...
                        hs.sigma.Gam_rate(n1,n2),pr.sigma.Gam_rate(n1,n2));
                end
            end
        end
        if isempty(train.prior) &&  ~isempty(orders)
            for i = 1:length(orders)
                alphaKL = alphaKL + gamma_kl(hs.alpha.Gam_shape,pr.alpha.Gam_shape, ...
                    hs.alpha.Gam_rate(i),pr.alpha.Gam_rate(i));
            end
        end
    end
    KLdiv = [KLdiv sigmaKL alphaKL];

end

% data log likelihood
savLL = [];
if todo(2)==1

    Gamma = [Gamma prod(1-Gamma,2) ];
    Gamma = rdiv(Gamma,sum(Gamma,2));

    avLL = zeros(Tres,1);

    ldetWishB = 0;
    PsiWish_alphasum = 0;
    for n = 1:ndim
        if ~regressed(n), continue; end
        ldetWishB = ldetWishB+0.5*log(ehmm.Omega.Gam_rate(n));
        PsiWish_alphasum = PsiWish_alphasum+0.5*psi(ehmm.Omega.Gam_shape);
    end
    C = ehmm.Omega.Gam_shape ./ ehmm.Omega.Gam_rate;
    avLL = avLL + (-ltpi-ldetWishB+PsiWish_alphasum);

    for k = 1:K+1

        % error
        meand = XX * ehmm.state(n).W.Mu_W(:,regressed);
        d = residuals(:,regressed) - meand;
        Cd = bsxfun(@times, C(regressed), d)';
        dist = zeros(Tres,1);
        for n = 1:sum(regressed)
            dist = dist - 0.5 * (d(:,n).*Cd(n,:)');
        end

        % Covariance of the distance
        NormWishtrace = zeros(Tres,1);
%         if ndim == 1
%             NormWishtrace = NormWishtrace + 0.5 * C * ...
%                 sum( (XX * ehmm.state(k).W.S_W) .* XX, 2);
%         else
%             for n = 1:ndim
%                 if ~regressed(n), continue; end
%                 NormWishtrace = NormWishtrace + 0.5 * C(n) * ...
%                     sum( (XX(:,Sind(:,n)) * ...
%                     permute(ehmm.state(k).W.S_W(n,Sind(:,n),Sind(:,n)),[2 3 1])) ...
%                     .* XX(:,Sind(:,n)), 2);
%             end
%         end

        avLL = avLL + Gamma(:,k) .* (dist - NormWishtrace);

    end
    savLL = sum(avLL);
end

FrEn = [-Entr -savLL -avLLGamma +KLdivTran +KLdiv];

% fprintf(' %.10g + %.10g + %.10g + %.10g + %.10g + %.10g =  %.10g \n',...
%     sum(-Entr) ,sum(-(-ltpi-ldetWishB+PsiWish_alphasum)*Tres) , sum(-(dist - NormWishtrace)), ...
%     sum(-avLLGamma) , sum(+KLdivTran) ,sum(+KLdiv) ,sum(FrEn));

end


function [fit] = compare_new(varargin)

% Determine list of inputs.
inpn = cell(1, length(varargin));
for kn = 1:length(varargin);
    inpn{kn} = inputname(kn);
end

v = {varargin{:} inpn};
th = idss(v{2});
th = th('y1', cell(0));

z = v{1};
z = iddata(z(:, 1), z(:, 2:end), 1);
y = pvget(z, 'OutputData');
z1 = z(:, 'y1', cell(0));

[yh, x01] = predict(th, z1, 1, 'e');
yhh = pvget(yh, 'OutputData');

%Compute fit.
err = norm(yhh{1} - y{1});
meanerr = norm(y{1} - mean(y{1}));
fit = 100*(1-err/meanerr);


function [data,times] = fiff_read_raw_segment_times(raw,from,to,sel)
%
% [data,times] = fiff_read_raw_segment_times(raw,from,to)
%
% Read a specific raw data segment
%
% raw    - structure returned by fiff_setup_read_raw
% from   - starting time of the segment in seconds
% to     - end time of the segment in seconds
% sel    - optional channel selection vector
%
% data   - returns the data matrix (channels x samples)
% times  - returns the time values corresponding to the samples (optional)
%

%
%   Author : Matti Hamalainen, MGH Martinos Center
%   License : BSD 3-clause
%
%   Revision 1.3  2006/04/23 15:29:40  msh
%   Added MGH to the copyright
%
%   Revision 1.2  2006/04/21 14:23:16  msh
%   Further improvements in raw data reading
%
%

me='MNE:fiff_read_raw_segment_times';

if nargin == 3
   sel = [];
elseif nargin ~= 4
   error(me,'Incorrect number of arguments');
end
%
%   Convert to samples
%
from = floor(from*raw.info.sfreq);
to   = ceil(to*raw.info.sfreq);
%
%   Read it
%
[ data, times ] = fiff_read_raw_segment(raw,from,to,sel);

return;

end


% DEMO_TEST.m

addpath(genpath('/home/vision/wren/caffe-dilate'));
caffe.reset_all();
clc; clear;

hazy_path = ('./inputs/');
type = '*.png';
hazy_data = dir(fullfile(hazy_path,type));

model_path = './models/';

solver_file = fullfile(model_path, 'dehaze_solver_test.prototxt');
save_file = fullfile(model_path, 'dehaze_ps128_bs1.mat');

Solver = modelconfig_test( solver_file, save_file);
% Solver.iter
Solver.batchsize = 1;
for ii = 45:length(hazy_data)
    disp(ii)
    clear batch;
    hazyimg = im2double(imread(fullfile(hazy_path,hazy_data(ii).name)));

    [row, col, cha] = size(hazyimg);

% resize the input to a multiple of 8
    height = ceil(row/8)*8;
    width = ceil(col/8)*8;
    hazyimg = imresize(hazyimg, [height, width]);

    hazy_wb = RealGWbal(uint8(255*hazyimg));
    hazy_wb = hazy_wb/255;
    hazy_cont = (2*(0.5+mean(hazyimg(:)))).*(hazyimg-mean(hazyimg(:)));
    hazy_gamma = hazyimg.^2.5;

    batch(:,:,1:3) = hazyimg;
    batch(:,:,4:6) = hazy_wb;
    batch(:,:,7:9) = hazy_cont;
    batch(:,:,10:12) = hazy_gamma;

%    figure(1);subplot(221), imshow(hazyimg);subplot(222),imshow(hazy_wb);
%              subplot(223), imshow(hazy_cont); subplot(224),imshow(hazy_gamma);

    batchc = {single(batch)};

    Solver.Solver_.net.blobs('data').reshape([height, width, 12, 1]);

    tic
    activec = Solver.Solver_.net.forward(batchc);
    toc
    dehazed= activec{3};

% 	dehazed = imresize(dehazed, [size(TEST_IMAGE, 1), size(TEST_IMAGE, 2)]);

	imwrite(dehazed, strcat('./results/',hazy_data(ii).name(1:end-4),'_dehazed.png'));
end
%imshow(out);title('Original/Proposed/GT');
%weights=Solver.Solver_.net.get_weights();
%data=Solver.Solver_.net.get_data();
%diff=Solver.Solver_.net.get_diff();


function [dat] = volplot(x, y, z, dat, sel, cscale)

% VOLPLOT make 2D or 3D plot of volumetric data (e.g. MRI)
% that is defined on a regular orthogonal grid
%
% volplot(dat, sel) or
% volplot(x, y, z, dat, sel)
% volplot(x, y, z, dat, sel, caxis)
%
% where sel is one of
%   [x, y, z]     intersection through the three orthogonal directions
%   index         linear index of the voxel of interest
%   'min'         intersection at the minimum
%   'max'         intersection at the maximum
%   'center'      intersect at the center of each axis
%   'interactive' intersect at the center, then go into interactive mode
%   'maxproject'  project the maximum value along each orthogonal direction
%   'sumproject'  integrated value along each orthogonal direction (glassbrain)
%   'montage'     show all slices
% and caxis is the [min max] used for the color scaling
%
% See also TRIPLOT, LINEPLOT (in ~roberto/matlab/misc)
% See also NDGRID

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

if nargin<2
  dat = x;
  sel = 'interactive';
  x = 1:size(dat,1);
  y = 1:size(dat,2);
  z = 1:size(dat,3);
elseif nargin<3
  dat = x;
  sel = y;
  x = 1:size(dat,1);
  y = 1:size(dat,2);
  z = 1:size(dat,3);
elseif nargin>4
  if length(size(dat))==3
    if length(x)~=size(dat,1), ft_error('incorrect x-axis specification'), end
    if length(y)~=size(dat,2), ft_error('incorrect y-axis specification'), end
    if length(z)~=size(dat,3), ft_error('incorrect z-axis specification'), end
  end
else
  ft_error('incorrect number of input arguments');
end

if nargin==6
  cmin = cscale(1);
  cmax = cscale(2);
else
  % ensure same color scaling for all figures
  cmin = min(dat(:));
  cmax = max(dat(:));
end

% convert from 1-d to 3-d array
if any(size(dat)==1)
  dim(1) = length(x);
  dim(2) = length(y);
  dim(3) = length(z);
  dat = reshape(dat, dim);
else
  dim = size(dat);
end

% convert the selection to the indices of the x/y/z intersection
if ischar(sel) && strcmp(sel, 'min')
  [minval, minindx] = min(dat(:));
  [xi, yi, zi] = ind2sub(size(dat), minindx);
elseif ischar(sel) && strcmp(sel, 'max')
  [maxval, maxindx] = max(dat(:));
  [xi, yi, zi] = ind2sub(size(dat), maxindx);
elseif ischar(sel) && strcmp(sel, 'center')
  xi = round(length(x)/2);
  yi = round(length(y)/2);
  zi = round(length(z)/2);
elseif ischar(sel) && strcmp(sel, 'interactive')
  xi = round(length(x)/2);
  yi = round(length(y)/2);
  zi = round(length(z)/2);
elseif ~ischar(sel) && length(sel)==1
  [xi, yi, zi] = ind2sub(dim, sel);
else
  xi = nearest(x, sel(1));
  yi = nearest(y, sel(2));
  zi = nearest(z, sel(3));
end

% start the plotting
if strcmp(sel, 'interactive')
  xc = x(xi);
  yc = y(yi);
  zc = z(zi);
  nas = [];
  lpa = [];
  rpa = [];
  while(1)
    fprintf('============================================================\n');
    fprintf('click with mouse button to reslice the display to a new position\n');
    fprintf('press n/l/r on keyboard to record a fiducial position\n');
    fprintf('press q on keyboard to quit interactive mode\n');
    volplot(x, y, z, dat, [xc yc zc]);
    drawnow;
    try, [d1, d2, key] = ginput(1); catch, key='q'; end
    if key=='q'
      % rename the first output argument of this function
      h = nas;
      break;
    elseif key=='l'
      lpa = [xc yc zc];
    elseif key=='r'
      rpa = [xc yc zc];
    elseif key=='n'
      nas = [xc yc zc];
    elseif key=='x'
      selx= round((xc-0):(xc+0));
      sely= round((yc-0):(yc+0));
      selz= round((zc-0):(zc+0));
      dat(selx,sely,selz) = 0;
    elseif key=='X'
      selx= round((xc-1):(xc+1));
      sely= round((yc-1):(yc+1));
      selz= round((zc-1):(zc+1));
      dat(selx,sely,selz) = 0;
    else
      % update the view to a new position
      l1 = get(get(gca, 'xlabel'), 'string');
      l2 = get(get(gca, 'ylabel'), 'string');
      switch l1
        case 'x'
          xc = d1;
        case 'y'
          yc = d1;
        case 'z'
          zc = d1;
      end
      switch l2
        case 'x'
          xc = d2;
        case 'y'
          yc = d2;
        case 'z'
          zc = d2;
      end
    end
    if ~isempty(nas), fprintf('nas = [%f %f %f]\n', nas); else fprintf('nas = undefined\n'); end
    if ~isempty(lpa), fprintf('lpa = [%f %f %f]\n', lpa); else fprintf('lpa = undefined\n'); end
    if ~isempty(rpa), fprintf('rpa = [%f %f %f]\n', rpa); else fprintf('rpa = undefined\n'); end
  end

elseif strcmp(sel, 'montage')
  % make plot of x-y slices for all z values
  maxval = max(dat(:));
%  for z=1:size(dat,3)
%    % convert to 4D image for montage display
%    % transpose to correct for x-y axis change in MATLAB image function
%    img(:,:,1,z) = transpose(dat(:,:,z));
%  end
%  montage(img);
%  axis xy

  % this works if java fails
  siz    = size(dat);
  ndiv   = [ceil(sqrt(siz(3))) floor(sqrt(siz(3)))];
  map    = zeros(siz(2)*ndiv(2),siz(1)*ndiv(1));
  for k=1:siz(3)
    [nx,ny] = ind2sub(ndiv,k);
    map(siz(2)*(ny-1)+1:siz(2)*ny,siz(1)*(nx-1)+1:siz(1)*nx) = dat(:,:,k)';
  end
  imagesc(map);axis xy;axis equal;axis off;
  caxis([cmin cmax]);
  colormap jet

elseif strcmp(sel, 'sumproject')
  % make plot of integrated-value projection along the thee orthogonal directions
  delete(subplot(2,2,4));   % delete the old colorbar
  h1 = subplot(2,2,1);
  h2 = subplot(2,2,2);
  h3 = subplot(2,2,3);
  h4 = subplot(2,2,4);  % this will  be the new colorbar

  % change not-a-number values to zero
  dat(find(isnan(dat(:)))) = 0;

  % update cmin and cmax
  cmin = 0;
  cmax = squeeze(max(max(sum(dat,1))));
  cmax = max(cmax, squeeze(max(max(sum(dat,2)))));
  cmax = max(cmax, squeeze(max(max(sum(dat,3)))));

  subplot(h1);
  imagesc(x, z, squeeze(sum(dat, 2))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('x'); ylabel('z');
  caxis([cmin cmax]);

  subplot(h2);
  imagesc(y, z, squeeze(sum(dat, 1))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('y'); ylabel('z');
  caxis([cmin cmax]);

  subplot(h3);
  imagesc(x, y, squeeze(sum(dat, 3))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('x'); ylabel('y');
  caxis([cmin cmax]);

  subplot(h4);
  imagesc(cmin:cmax);
  caxis([cmin cmax]);
  xlabel('colorscale')

elseif strcmp(sel, 'maxproject')
  % make plot of maximum-value projection along the thee orthogonal directions
  delete(subplot(2,2,4));   % delete the old colorbar
  h1 = subplot(2,2,1);
  h2 = subplot(2,2,2);
  h3 = subplot(2,2,3);
  h4 = subplot(2,2,4);  % this will  be the new colorbar

  subplot(h1);
  imagesc(x, z, squeeze(max(dat, [], 2))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('x'); ylabel('z');
  caxis([cmin cmax]);

  subplot(h2);
  imagesc(y, z, squeeze(max(dat, [], 1))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('y'); ylabel('z');
  caxis([cmin cmax]);

  subplot(h3);
  imagesc(x, y, squeeze(max(dat, [], 3))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('x'); ylabel('y');
  caxis([cmin cmax]);

  subplot(h4);
  colorbar(h4, 'peer', h1);
  xlabel('colorscale')

else
  % make plot of three orthogonal slices intersecting at [xi yi zi]
  if ~exist('xi', 'var') || ~exist('yi', 'var') || ~exist('zi', 'var')
    ft_error('nothing to plot, no selection given')
  end

  fprintf('value of %f in voxel %d at [%.02f %.02f %.02f]\n', double(dat(xi, yi, zi)), sub2ind(dim, xi, yi, zi), x(xi), y(yi), z(zi));

  warning off
  delete(subplot(2,2,4));   % delete the old colorbar
  warning on
  h1 = subplot(2,2,1);
  h2 = subplot(2,2,2);
  h3 = subplot(2,2,3);
  h4 = subplot(2,2,4);  % this will  be the new colorbar

  subplot(h1);
  imagesc(x, z, squeeze(dat(:,yi,:))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('x'); ylabel('z');
  caxis([cmin cmax]);
  ft_plot_crosshair([x(xi) z(zi)], 'color', 'yellow');

  subplot(h2);
  imagesc(y, z, squeeze(dat(xi,:,:))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('y'); ylabel('z');
  caxis([cmin cmax]);
  ft_plot_crosshair([y(yi) z(zi)], 'color', 'yellow');

  subplot(h3);
  imagesc(x, y, squeeze(dat(:,:,zi))'); set(gca, 'ydir', 'normal')
  axis equal; axis tight;
  xlabel('x'); ylabel('y');
  caxis([cmin cmax]);
  ft_plot_crosshair([x(xi) y(yi)], 'color', 'yellow');

  subplot(h4);
  imagesc(cmin:((cmax-cmin)./64):cmax);
  caxis([cmin cmax]);
  xlabel('colorscale')
end


%-fanDTasia ToolBox------------------------------------------------------------------
% This Matlab script is part of the fanDTasia ToolBox: a Matlab library for Diffusion
% Weighted MRI (DW-MRI) Processing, Diffusion Tensor (DTI) Estimation, High-order
% Diffusion Tensor Analysis, Tensor ODF estimation, Visualization and more.
%
% A Matlab Tutorial on DW-MRI can be found in:
% http://www.cise.ufl.edu/~abarmpou/lab/fanDTasia/tutorial.php
%
%----------------------------------------------
%openFDT
%This function opens an image volume in fanDTasia(FDT) file format.
%fanDTasia is an on-line tool for DTI DW-MRI processing.
%
%example 1: A=openFDT('DTI.fdt')
%A is a 4-dimensional matrix that contains a set of volume images.
%
%example 2: [A,B]=openFDT('DTI.fdt')
%A is a 4-dimensional matrix that contains a set of volume images.
%B is a Nx4 matrix that contains the gradient orientations and bvalues.
%B is read from a .txt file with the same name as the fdt file. (In example2: DTI.txt)
%
%----------------------------------------------
%
%Downloaded from Angelos Barmpoutis' web-page.
%
%This program is freely distributable without
%licensing fees and is provided without guarantee
%or warrantee expressed or implied.
%
%Copyright (c) 2007 Angelos Barmpoutis.
%
%VERSION : 20110611
%
%-----------------------------------------------

function [data,bval]=openFDT(name)

fid=fopen(name,'r','b');

for i=1:4
  sz(i)=fread(fid,1,'int');
end

	data=zeros(sz(1),sz(2),sz(3),sz(4));
	for c=1:sz(4)
       for z=1:sz(3)
          for y=1:sz(2)
              data(:,y,z,c)=fread(fid,sz(1),'float');
          end
       end
	end

fclose(fid);

if nargout==2
    bname=name;
    bname(length(name))='t';
    bname(length(name)-1)='x';
    bname(length(name)-2)='t';
    bval=open_TXT(bname);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bval=open_TXT(fnm)
%this simple function opens a txt file that contain 4 columns of numbers
%An example of such a text file is here:
%0.1 100.23 24.3 0.334
%10.345 0.2 1.23 123.4
%... as many lines you want.

fid=fopen(fnm,'r');

if fid==-1
    fprintf(1,'ERROR: FILE CANNOT BE OPENED\n');
    return;
end

bval=[];
b=zeros(1,4);
while feof(fid)==0
    b=fscanf(fid,'%f',4)';
    bval=[bval;b];
end

fclose(fid);


function ExampleMusicSpeechClassification(cDatasetPath)

    if (nargin<1)
        % this script is written for the GTZAN music/speech dataset
        % modify this path or use the function parameter to specify your
        % dataset path
        cDatasetPath = 'd:\dataset\music_speech\';
    end
    if (exist('ComputeFeature') ~= 2)
        error('Please add the ACA scripts (https://github.com/alexanderlerch/ACA-Code) to your path!');
    end
    if ((exist([cDatasetPath 'music']) ~= 7) || (exist([cDatasetPath 'speech']) ~= 7))
        error('Dataset path wrong or does not contain music/speech folders!')
    end

    iNumFeatures = 2;

    % read directory contents
    music_files = dir([cDatasetPath 'music/*.au']);
    speech_files = dir([cDatasetPath 'speech/*.au']);

    v_music = zeros(iNumFeatures,size(music_files,1));
    v_speech = zeros(iNumFeatures,size(speech_files,1));

    % extract features, this may take a while...
    for i = 1:size(music_files, 1)
        v_music(:, i) = ExtractFeaturesFromFile_I(...
            [cDatasetPath 'music/' music_files(i).name]);
    end
    for i = 1:size(speech_files, 1)
        v_speech(:, i) = ExtractFeaturesFromFile_I(...
            [cDatasetPath 'speech/' speech_files(i).name]);
    end

    % assign class labels for training and eval
    C = [zeros(1, size(music_files, 1)) ones(1, size(speech_files, 1))];

    % normalize features
    v = [v_music, v_speech];
    m = mean(v, 2);
    s = std(v, 0, 2);
    v = (v - repmat(m, 1, size(music_files, 1) + size(speech_files, 1)))./...
        repmat(s, 1, size(music_files, 1)+size(speech_files, 1));

    % compute the overall accuracy with cross validation
    [acc, mat] = ToolLooCrossVal(v, C);

    disp('confusion matrix:'),
    disp(mat);

    disp('micro accuracy:'),
    disp(sum(diag(mat)) / sum(sum(mat)))
    tmp = zeros(size(mat, 1), 1);
    for i = 1:size(mat, 1)
        tmp(i) = mat(i, i) / sum(mat(i, :));
    end
    disp('macro accuracy:'),
    disp(mean(tmp))

    % compute the individual feature performance
    [acc1, mat1] = ToolLooCrossVal(v(1, :), C);
    sprintf('centroid accuracy: %f', acc1)
    [acc2, mat2] = ToolLooCrossVal(v(2 ,:), C);
    sprintf('rms accuracy: %f', acc2)
end

function [v] = ExtractFeaturesFromFile_I(cFilePath)

    cFeatureNames = char('SpectralCentroid',...
    'TimeRms');

    % read audio
    [x, fs] = audioread(cFilePath);
    x = x / max(abs(x));

    % compute first feature
    feature = ComputeFeature (deblank(cFeatureNames(1, :)), x, fs);
    v(1, 1)  = mean(feature);

    % compute second feature
    feature = ComputeFeature (deblank(cFeatureNames(2, :)), x, fs);
    v(2, 1)  = std(feature(1,:));
end


classdef InputFemFilePrinter < FilePrinter

    properties (Access = private)
        connectivities
        coordinates
        isElemInThisSet
        masterSlave
        corners
        nnode
        npnod
        nelem
        ndim
        resultsDir
        scale
        pdim
        ptype
        type
    end

    methods (Access = public)

        function obj = InputFemFilePrinter(inputData)
            obj.init(inputData);
            obj.createOutPutFolder();
        end

        function print(obj)
            obj.openFile();
            obj.printDataProblem();
            obj.printCoordinates();
            obj.printConnectivities();
            obj.printDirichletData();
            obj.printMasterSlave();
            obj.printMaterialSets();
            obj.closeFile();
        end

    end

    methods (Access = private)

        function init(obj,d)
            obj.connectivities  = d.connec;
            obj.coordinates     = d.coord;
            obj.isElemInThisSet = d.isElemInThisSet;
            obj.masterSlave     = d.masterSlave;
            obj.corners         = d.corners;
            obj.scale           = d.scale;
            obj.pdim            = d.pdim;
            obj.ptype           = d.ptype;
            obj.resultsDir      = d.resultsDir;
            obj.fileName        = d.fileName;
            obj.type            = d.type;
            obj.nnode           = size(d.connec,2);
            obj.nelem           = size(d.connec,1);
            obj.npnod           = size(d.coord,1);
            obj.ndim            = 2;
        end

        function createOutPutFolder(obj)
            dir = obj.resultsDir;
            if ~exist(dir,'dir')
                mkdir(dir)
                addpath(dir)
            end
        end

        function printDataProblem(obj)
            iD = obj.fileID;
            fprintf(iD,'Data_prb = { \n');
            fprintf(iD,['''',obj.type,'''','; \n']);
            fprintf(iD,'''SI''; \n');
            fprintf(iD,['''',obj.pdim,'''','; \n']);
            fprintf(iD,'''Plane_Stress''; \n');
            fprintf(iD,['''',obj.ptype,'''','; \n']);
            fprintf(iD,['''',obj.scale,'''','; \n']);
            fprintf(iD,'}; \n');
        end

        function printCoordinates(obj)
            iD      = obj.fileID;
            coor    = obj.coordinates;
            nodInEl = obj.npnod;
            nDim    = obj.ndim;
            fprintf(iD,'\n');
            fprintf(iD,'coord = [\n');
            printFormat = ['%6.0f ',repmat('%12.5d ',1,nDim),' 0 \n'];
            toPrint = [1:nodInEl;coor'];
            fprintf(iD,printFormat,toPrint);
            fprintf(iD,']; \n');
        end

        function printConnectivities(obj)
            iD     = obj.fileID;
            con    = obj.connectivities;
            nNodes = obj.nnode;
            fprintf(iD,'\n');
            fprintf(iD,'connec = [ \n');
            printFormat = [repmat('%6.0f ',1,nNodes+1),' \n'];
            fprintf(iD,printFormat,[1:obj.nelem;con']);
            fprintf(iD,']; \n');
        end

        function printMasterSlave(obj)
            if ~ isempty(obj.masterSlave)
                iD = obj.fileID;
                fprintf(iD,'\n');
                fprintf(iD,'Master_slave = [\n');
                printFormat = [repmat('%12.0d ',1,2),'\n'];
                fprintf(iD,printFormat,obj.masterSlave');
                fprintf(iD,']; \n');
            end
        end

        function printDirichletData(obj)
            iD = obj.fileID;
            fprintf(iD,'\n');
            fprintf(iD,'dirichlet_data = [\n');
            corn = obj.corners;
            ncorners = size(corn,1);
            repCorn = repmat(corn,1,2)';
            repDir  = repmat((1:obj.ndim)',ncorners,1);
            ToPrint = [repCorn(:)';repDir(:)'];
            printFormat = [repmat('%12.0f ',1,2),'       0 \n'];
            fprintf(iD,printFormat,ToPrint);
            fprintf(iD,']; \n');
        end

        function printMaterialSets(obj)
            iD = obj.fileID;
            fprintf(iD,'\n');
            fprintf(iD,'MaterialSets = [\n');
            printFormat = [repmat('%12.0d ',1,2),'\n'];
            for imatSet = 1:numel(obj.isElemInThisSet)
                elemSet = obj.isElemInThisSet{imatSet};
                n       = length(elemSet);
                toPrint = [elemSet';imatSet*ones(1,n)];
                fprintf(iD,printFormat,toPrint);
            end
            fprintf(iD,']; \n');
        end

    end

end


clear
% define the root name of database
root = '../data_preparation/prepared_data/';

% which scales we're doing
sigma = 1;
num_samples = 5e5;

scales = [0.25,0.35,0.5];
frontalView = 1;

profileViewInds = [];

version = 'cofw';
ratio_neg = 5;
norm = 1;

data_loc = 'cofw_';
rng(0);

similarities = {};
sparsity = 1;
sparsity_types = [];

lambda_a = 100;
lambda_b = 1000;
lambda_th = 1;
num_layers = 7;

for s=scales

    Train_all_patch_experts(root, frontalView, profileViewInds,...
        s, sigma, version, 'ratio_neg', ratio_neg,...
        'num_samples', num_samples, 'data_loc', data_loc,...
        'normalisation_size', 19, 'similarity_types', similarities, 'sparsity', sparsity,...
        'sparsity_types', sparsity_types, 'lambda_a', lambda_a, 'lambda_b', lambda_b, 'lambda_th', lambda_th, 'num_layers', num_layers);
end


function [] = plotKspaceVolumes(kspaceVolumes, scales)
%PLOTKSPACEVOLUMES Plot the kspace 3D volumes.
%   volumes: Cell array of volumes to plot
%   scales: Cell array of scales ([min, max]) for the image plots.
%
%   Code refractored from Berkin Bilgic's scripts: "script_Laplacian_unwrap_Sharp_Fast_TV_gre3D.m"
%   and "script_Laplacian_unwrap_Sharp_Fast_TV_gre3D.m"
%   Original source: https://martinos.org/~berkin/software.html
%
%   Original reference:
%   Bilgic et al. (2014), Fast quantitative susceptibility mapping with
%   L1-regularization and automatic parameter selection. Magn. Reson. Med.,
%   72: 1444-1459. doi:10.1002/mrm.25029

    for volumeIndex = 1:length(kspaceVolumes)
        figure(), subplot(1,3,1), imagesc( kspaceVolumes{volumeIndex}(:,:,1+end/2), scales{volumeIndex} ), axis square off, colormap gray
        figure(get(gcf,'Number')), subplot(1,3,2), imagesc( squeeze(kspaceVolumes{volumeIndex}(:,1+end/2,:)), scales{volumeIndex} ), axis square off, colormap gray
        figure(get(gcf,'Number')), subplot(1,3,3), imagesc( squeeze(kspaceVolumes{volumeIndex}(1+end/2,:,:)), scales{volumeIndex} ), axis square off, colormap gray
    end

end


function sorted_model_files = sort_nnet_by_dev(model_files)

for i=1:length(model_files)
    idx = regexp(model_files{i}, '\.CV');
    CV_score(i) = str2num( model_files{i}(idx(end)+3:end-4) );
end

[tmp, idx] = sort(CV_score);
sorted_model_files = model_files(idx);

end


function [region_meta_info, region_meta_info_true]=preprocess_cpmc_candidates(imnames, cpmcdir, cpmcgtdir, gtdir, ovoutdir, N)
if(~exist(ovoutdir, 'file'))
    mkdir(ovoutdir);
end

for i=1:numel(imnames)
    %load sprep
    x1=load(fullfile(cpmcdir, [imnames{i} '.mat']));
    sp=x1.sp;
    reg2sp=x1.sp_app;

    %compute overlaps between everything
    ov=double(reg2sp')*double(reg2sp);
    ov=ov>0;
    if(~exist(fullfile(ovoutdir, [imnames{i} '.mat']), 'file'))
    save(fullfile(ovoutdir, [imnames{i} '.mat']), 'ov');
    end
    %load gt
    if(isempty(gtdir))
        %no gt
        inst=zeros(size(sp));
        categories=[];
    else
    [cls, inst, categories]=load_gt(gtdir, imnames{i});
    end
    x2=load(fullfile(cpmcgtdir, imnames{i}));
    %compute overlap of projected ground truth with ground truth
    gt_overlap=get_gt_overlaps(x2.sp_app, x2.sp, inst);

    %for each projected gt get the instance it corresponds to
    [m, assigned_index]=max(gt_overlap,[],1);

    %compute overlaps with ground truth
    overlap=get_gt_overlaps(reg2sp, sp, inst);
    box_overlap=get_gt_overlaps_box(reg2sp, sp, inst);
    %populate meta info
    region_meta_info.num_regs(i)=size(reg2sp,2)+numel(categories(assigned_index));
    region_meta_info.overlaps{i}=overlap(assigned_index,:);
    region_meta_info.box_overlaps{i}=box_overlap(assigned_index,:);
    region_meta_info.gt{i}=[categories(assigned_index(:))' zeros(1,size(reg2sp,2))];

    region_meta_info_true.num_regs(i)=size(reg2sp,2)+numel(categories);
    region_meta_info_true.overlaps{i}=overlap;
    region_meta_info_true.box_overlaps{i}=box_overlap;
    region_meta_info_true.gt{i}=[categories(:)' zeros(1,size(reg2sp,2))];

    fprintf('Done %d\n', i);
end

function write_sprep_text(sp, filename)
fid=fopen(filename, 'w');
fprintf(fid,'%d %d\n', size(sp,1), size(sp,2));
fprintf(fid, '%d ', sp(:));
fclose(fid);

function [sp, sp2reg]=intersect_partitions(sp1, sp2, sp2reg1, sp2reg2)
%do a unique
[unique_pairs, junk, sp]=unique([sp1(:) sp2(:)], 'rows');
sp=reshape(sp, size(sp1));

%create new sp2reg
sp2reg=[sp2reg1(unique_pairs(:,1),:) sp2reg2(unique_pairs(:,2),:)];

%break disconnected sp
 spNew = zeros(size(sp));
  sp2regNew = false(size(sp2reg));
  cnt = 0;
  %% Check connectivity of superpixels
  for i = 1:max(sp(:))
    tt = bwconncomp(sp == i);
    for j = 1:tt.NumObjects,
      cnt = cnt+1;
      spNew(tt.PixelIdxList{j}) = cnt;
      sp2regNew(cnt, :) = sp2reg(i, :);
    end
  end

sp=spNew;
sp2reg=sp2regNew;

function [spNew sp2regNew] = compressSp2reg(sp, sp2reg)
  assert(islogical(sp2reg), 'sp2reg should be logical');
  [sp2reg bb spSame] = unique(sp2reg, 'rows');
  sp = spSame(sp);

  spNew = zeros(size(sp));
  sp2regNew = false(size(sp2reg));
  cnt = 0;
  %% Check connectivity of superpixels
  for i = 1:max(sp(:))
    tt = bwconncomp(sp == i);
    for j = 1:tt.NumObjects,
      cnt = cnt+1;
      spNew(tt.PixelIdxList{j}) = cnt;
      sp2regNew(cnt, :) = sp2reg(i, :);
    end
  end


function RegTranslation(handles, metric)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
% CERR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
% without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with CERR.  If not, see <http://www.gnu.org/licenses/>.

global planC stateS;
indexS = planC{end};

    [originF, spacingF, centerF] = getScanOriginSpacing(planC{indexS.scan}(stateS.imageRegistrationBaseDataset));

    [originM, spacingM, centerM] = getScanOriginSpacing(planC{indexS.scan}(stateS.imageRegistrationMovDataset));

    minstep = str2double(get(handles.para.minstep, 'string'));
    maxstep = str2double(get(handles.para.maxstep, 'string'));
    iternum = str2double(get(handles.para.iternum, 'string'));

    output = cell(1, 8);

    FImg = planC{indexS.scan}(stateS.imageRegistrationBaseDataset).scanArray;
    MImg = planC{indexS.scan}(stateS.imageRegistrationMovDataset).scanArray;

%     downsample the input datasets
    if (get(handles.dsampleCheck,'Value') == get(handles.dsampleCheck,'Max'))

        tic;
        FImg = imdesample3d(FImg,2,2);
        MImg = imdesample3d(MImg,2,2);
        toc;
        DesampleTime = num2str(floor(toc/60));

    end

%     call registration method
    tic;
    switch (metric)
        case 'mean squares'
            [im, Rotation, Offset] = MeanSquare3D(int16(FImg), originF, spacingF, ... %MeanSquare3D,NormalizedCorrelation3D
                                                int16(MImg), originM, spacingM, ...
                                                minstep, maxstep, iternum);
        case 'normalized correlation'
            [im, Rotation, Offset] = NormalizedCorrelation3D(int16(FImg), originF, spacingF, ... %MeanSquare3D,NormalizedCorrelation3D
                                                int16(MImg), originM, spacingM, ...
                                                minstep, maxstep, iternum);
    end
    toc;
    RegTime = num2str(floor(toc/60));

    output{1} = ['Translation X = ' num2str(Offset(1))];
    output{2} = ['Translation Y = ' num2str(Offset(2))];
    output{3} = ['Translation Z = ' num2str(Offset(3))];
    output{4} = ['Number of Iterations = ' num2str(Offset(4))];
    output{5} = ['Best Value = ' num2str(Offset(5))];
    output{6} = ['Desample time = ' DesampleTime 'm'];
    output{7} = ['Register time = ' RegTime 'm'];

    set(handles.OutputList, 'string', output);

    %update the transM;
    dx = Offset(1); dy = Offset(2); dz = Offset(3);

    scanSetM = stateS.imageRegistrationMovDataset;
    oldTransM = getTransM(stateS.imageRegistrationMovDatasetType, scanSetM, planC);

    newTransform = eye(4);
    newTransform(:,4) = [dx dy dz 1];

%     planC{indexS.(stateS.imageRegistrationMovDatasetType)}(scanSetM).transM = (newTransform * oldTransM);
%     planC{indexS.dose}(scanSetM).transM = (newTransform * oldTransM);
    planC{indexS.(stateS.imageRegistrationMovDatasetType)}(scanSetM).transM = newTransform;
    sliceCallBack('refresh');

end


function options = dnetOptions(mappingType, latentPoints, mappingOptions)

% DNETOPTIONS Options for a density network.
% FORMAT
% DESC returns the default options for a density network.
% RETURN options : default options structure for density network.
%
% FORMAT
% returns the default options for a density network given a
% number of hidden units.
% ARG mappingType : type of mapping to use in density network.
% ARG latentPoints : number of latent points to use. If give as a vector,
% layout is assumed to be a grid with rows and columns given by the vector.
% ARG mappingOptions : the options for the mapping model.
% RETURN options : default options structure for density network with the
% specified number of hidden units.
%
% SEEALSO : dnetCreate, modelOptions
%
% COPYRIGHT : Neil D. Lawrence, 2008

% MLTOOLS

if nargin < 1
  % This is the GTM settings
  mappingType = 'rbf';
end
if nargin < 2
  latentPoints = [16 16];
end
if nargin < 3
  options = modelOptions(mappingType);
end

options.mappingOptions = options;
options.mappingType = mappingType;
options.latentSamples = latentPoints;

options.alpha = 1;

options.activeFunc = 'linear';
options.optimiser = optimiDefaultOptimiser;

options.initX = 'ppca'; % Initialise X by ppca by default.
if length(latentPoints)>1
  options.M = prod(latentPoints);
  options.grid = latentPoints;
  options.basisStored = true;
else
  options.grid =[];
  options.M = latentPoints;
  options.basisStored = false;
end


%% (Internal) Calculate the performance data of a QRS detection task.
% This function is used by the ECGtask related with QRS detection to
% calculate performance of detectors.
%
% Example
%
%   payload_out = CalculatePerformanceECGtaskQRSdet(payload_out, ECG_annotations, ECG_header);
%
% Arguments:
%     +payload_out: Internal payload with all detections
%
%     +ECG_annotations: Gold standard to calculate performances.
%
%     +ECG_header: ECG header information.
%
%     +ECG_start_offset: Offset from ECG start.
%
% Output:
%     + payload: payloads generated by ECGtask_QRS_Detection.Process result
%        of concatenating plA and plB.
%
% See also ECGtask_QRS_Detection
%
% Author: Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar
% Version: 0.1 beta
% Last update: 06/10/2015
% Birthdate  : 06/10/2015
% Copyright 2008-2015
function payload_out = CalculatePerformanceECGtaskQRSdet(payload_out, ECG_annotations, ECG_header, ECG_start_offset)

    if( isempty(payload_out) || isempty(ECG_annotations) )
        return
    end

    AnnNames = payload_out.series_quality.AnnNames(:,1);
    cant_lead_name = size(AnnNames,1);
    payload_out.series_performance.conf_mat = zeros(2,2,cant_lead_name);
    payload_out.series_performance.error = nan(cant_lead_name,2);

    if(isempty(ECG_annotations))
        disp_string_framed(2, sprintf('Trusted references not found for %s', ECG_header.recname) );
    else
        % offset refs, produced anns were already shifted
        %ECG_annotations.time = ECG_annotations.time + ECG_start_offset - 1;
        ECG_annotations.time = ECG_annotations.time(ECG_annotations.time >= ECG_start_offset & ...
            ECG_annotations.time <= ECG_header.nsamp + ECG_start_offset);

        payload_out.series_performance.conf_mat_details = cell(cant_lead_name,4);

        for kk = 1:cant_lead_name
            this_lead_det = payload_out.(AnnNames{kk}).time;
            [payload_out.series_performance.conf_mat(:,:,kk), ...
                TP_gs_idx, ...
                TP_det_idx, ...
                FN_idx, ...
                FP_idx ] = bxb(ECG_annotations, this_lead_det, ECG_header );

            % details about the confusion matrix
            payload_out.series_performance.conf_mat_details(kk,:) = { TP_gs_idx, TP_det_idx, FN_idx, FP_idx };

            % meadian/mad of the error wrt the gold standard
            if( ~isempty(TP_det_idx) )
                aux_val = (colvec(this_lead_det(TP_det_idx)) - colvec(ECG_annotations.time(TP_gs_idx)));
                payload_out.series_performance.error(kk,:) = [ median(aux_val) mad(aux_val) ] /ECG_header.freq;
            end
        end
    end


function Err = errornormalize(Err)
%ERRORNORMALIZE  Normalization of error term
%
%For internal use only

%
%  Err = errornormalize(Err)
%
%with Err = Err.mant * beta^Err.exp and Err.mant normalized to
%approximately 1.
%

% written  12/30/98     S.M. Rump
% modified 08/26/12     S.M. Rump  global variables removed
%

  INTLAB_LONG_BETA = getappdata(0,'INTLAB_LONG_BETA');

  % adapt error mantissa and exponent such that Err.mant around 1
  index = ( Err.mant~=0 );
  if any(index)
    q = floor( log( Err.mant(index) ) / log( INTLAB_LONG_BETA ) );
    Err.mant(index) = Err.mant(index) ./ INTLAB_LONG_BETA.^q;
    Err.exp(index) = Err.exp(index) + q;
  end
  Err.exp(~index) = 0;


function wprob_temp = probwTemperature(BandBT,idwt,h_pt)
%PROBTEMPERATURE calculate temperature probability for water.

    % [temperature test (over water)]
    F_wtemp=BandBT(idwt); % get clear water temperature
    clear idwt;
    t_wtemp=prctile(F_wtemp,100*h_pt);
    clear F_wtemp h_pt;
    wprob_temp=(t_wtemp-BandBT)/400;
    clear t_wtemp BandBT;
    wprob_temp(wprob_temp<0)=0;
    %    wTemp_prob(wTemp_prob > 1) = 1;
end


%Simply returns the next point which is closest to the startpoint and as close as possible on the line
function [x, dist, dir, searchPoints] = getNextPoint(searchPoints, x0, dir0, X, Y, MAXDIST, MAXANGLE, MAXDIST2LINE, doshow)

    %REturn values in case of its not working
    x = -1;
    dir = [0;0];
    dist = -1;
    %Returns the index of points which are close to the line
    [dl, ix_l,angles] = getClosestPointToLine(searchPoints, x0, dir0, 32);

    %for i=1:length(dl)
    %    dl(i)
    %end
    %Only take those points that are less than MAXPIXEL away from the line
    ix = find(dl < MAXDIST2LINE);
    ix_l = ix_l(ix);

    %Returns the index of points which are close to the start point
    [ix_n, d] = getClosestNeighbours(searchPoints(:, ix_l), x0, 16); %x0 important

    %Make a new index with closest points that are close to the line!
    ix = ix_l(ix_n);
    if(numel(ix)>0)
        d = norm(searchPoints(2:3, ix(1))-x0); %x0 important
        if(d < MAXDIST)
            %Check that there ar epoints, otherwise return a zero value
            if(length(ix) > 0 )
                %Take the best match
                x = searchPoints(2:3,ix(1));
                %Recompute direction
                dir = x-x0(1:2);  %x0 faux
                dist = norm(dir);
                dir = dir/dist;
                %Get the angle
                theta = acos(dir'*dir0)/(norm(dir)*norm(dir0))/pi*180;

%                 if(theta<85 | theta>105)
                if(theta<MAXANGLE)
                    %Mark it as used and store the point correspondance
                    searchPoints(1,ix(1)) = 0;
                    searchPoints(4:5, ix(1)) = [X;Y];
                    if(doshow)
                        text(searchPoints(2,ix(1))+5,searchPoints(3,ix(1))+5,[num2str(searchPoints(4,ix(1))) ',' num2str(searchPoints(5,ix(1)))],'Color','m')
                    end
                else
                    x = -1;
                end
            end
        end
    end

%
% %Simply returns the next point which is closest to the startpoint and as close as possible on the line
% function [x, dist, dir, searchPoints] = getNextPoint(searchPoints, x0, dir0, X, Y, MAXDIST, MAXANGLE, MAXDIST2LINE, doshow)
%
%     %REturn values in case of its not working
%     x = -1;
%     dir = [0;0];
%     dist = -1;
%     %Returns the index of points which are close to the line
%     [dl, ix_l,angles] = getClosestPointToLine(searchPoints, x0, dir0, 8);
%     %Only take those points that are less than MAXPIXEL away from the line
%     ix = find(dl < MAXDIST2LINE);
%     ix_l = ix_l(ix);
%
%     %Returns the index of points which are close to the start point
%     [ix_n, d] = getClosestNeighbours(searchPoints(:, ix_l), x0, 16);
%
%     %Make a new index with closest points that are close to the line!
%     ix = ix_l(ix_n);
%     if(numel(ix)>0)
%         d = norm(searchPoints(2:3, ix(1))-x0);
%         if(d < MAXDIST)
%             %Check that there ar epoints, otherwise return a zero value
%             if(length(ix) > 0 )
%                 %Take the best match
%                 x = searchPoints(2:3,ix(1));
%                 %Recompute direction
%                 dir = x-x0(1:2);
%                 dist = norm(dir);
%                 dir = dir/dist;
%                 %Get the angle
%                 theta = acos(dir'*dir0)/(norm(dir)*norm(dir0))/pi*180;
%
% %                 if(theta<85 | theta>105)
%                 if(theta<MAXANGLE)
%                     %Mark it as used and store the point correspondance
%                     searchPoints(1,ix(1)) = 0;
%                     searchPoints(4:5, ix(1)) = [X;Y];
%                     if(doshow)
%                         text(searchPoints(2,ix(1))+5,searchPoints(3,ix(1))+5,[num2str(searchPoints(4,ix(1))) ',' num2str(searchPoints(5,ix(1)))],'Color','m')
%                     end
%                 else
%                     x = -1;
%                 end
%             end
%         end
%     end
%
%
%
%
%
%
%


function xscore = mergeAllClusters(rez)

Nfilt = size(rez.W,2);

xscore = zeros(Nfilt);
chckd  = zeros(Nfilt);

nmerges = 0;
for ik = 1:Nfilt
   s0 = rez.st3(:,2) ==ik;

   ipair = rez.iNeigh(:, ik);

   %%
   for j = 2:length(ipair)
       i2 = ipair(j);

       if chckd(ik, i2)
           continue;
       end

       j2 = find(rez.iNeigh(:, i2)==ik);

       if ~isempty(j2) && rez.simScore(ik, i2)>.5
          s1 = rez.st3(:,2) ==i2;

          c1 = rez.cProj(s0, [1 j]);
          c2 = cat(1, c1, rez.cProj(s1, [j2 1]));

          xs = c2(:,1) - c2(:,2);

          if ik==161 && i2==167
              keyboard;
          end

          xscore(i2, ik) = mergeScore(xs);
          chckd(i2, ik) = 1;

          if xscore(i2, ik)>0
              nmerges = nmerges + 1;
          end
       end
   end
   %%
   if rem(ik, 100)==1
       fprintf('Found %d merges, checked %d/%d clusters \n', nmerges, ik, Nfilt)
   end

end


function TestMappingDNN()

modeldir = my_dir('nnet');
modelfiles = findFiles(['nnet/' modeldir{1}], 'mat');
modelfiles = sort_nnet_by_itr(modelfiles);      % get the last iteration model

dnn = load(modelfiles{1});
para = dnn.para;
layer = dnn.layer;

[~, Data_cv, para] = LoadData_AU4_Mapping(para);

para.out_layer_idx = length(layer) + [-2 -3];   % you can specify which layers' activation will be outputed
output = FeatureTree2(Data_cv, para, layer);

for i=1:length(output)
    enhanced{i} = output{i}{1};
end

for i=1:length(enhanced)
    subplot(3,1,1); imagesc(Data_cv(1).data{i});    title('Noisy MFCC');
    subplot(3,1,2); imagesc(enhanced{i});          title('Enhanced MFCC');
    subplot(3,1,3); imagesc(Data_cv(2).data{i});       title('Clean MFCC');
    pause
end

end


function varargout = remez(f, varargin)
%REMEZ   Best polynomial or rational approximation for real valued CHEBFUNs.
%   This code is obsolete as of May 2017.  Use MINIMAX instead.

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

warning('CHEBFUN:CHEBFUN:remez', ...
        [' This command is deprecated.', ...
         ' Use minimax instead.']);
polyOutput = detectType(f,varargin{:});

if ( polyOutput )
    [p,err,status] = minimax(f,varargin{:});
    varargout = {p, err, status};
else
    [p,q,r,err,status] = minimax(f,varargin{:});
    varargout = {p, q, r, err, status};
end

end

function polyOutput = detectType(~, varargin)

isSilent = 0;
for k = 1:length(varargin)
    if ( ischar(varargin{k}) && strcmpi('silent', varargin{k}) )
        isSilent = 1;
    end
end

% Detect polynomial / rational approximation type.
polyOutput = true;
if ( mod(nargin - isSilent, 2) ) % Odd number of inputs --> rational case.
    polyOutput = false;
end

end


 function ob = Gtomo2_wtfmex(file, chat, sp_group_type)
%function ob = Gtomo2_wtfmex(file, chat, sp_group_type)
%
% THIS IS OBSOLETE; USE Gtomo2_wtmex INSTEAD!
%
% Construct Gtomo2_wtfmex object, which does 2d forward and backprojection
% using the wtfmex cabilities for any system geometry.
% See Gtomo2_wtfmex_test.m for example usage.
% This object avoids the memory pigging property of matlab's sparse matrices
% using wtfmex's static system matrix capability.
% Basically, you create a wtfmex system matrix by calling:
%	G = Gtomo2_wtfmex(file)
% and then you can use it thereafter by typing commands like
%	y = G * x;
% which will auto-magically call wtfmex to do the multiplication
% in the compiled C mex program.
%
% Alternative usage: let "file" be geometry description from arg_pair().
%
% Copyright 2002-2-20, Jeff Fessler, The University of Michigan

if ~isvar('chat') | isempty(chat)
	chat = 0;
end

if ~isvar('sp_group_type') | isempty(sp_group_type)
	sp_group_type = 'row';
end

%
% create default object, as required by Mathworks
%
ob = Gtomo2(chat);
ob.file = '';
ob.arg = '';

if ~nargin % required by Mathworks
	ob = class(ob, 'Gtomo2_wtfmex');
return
end

warning 'Gtomo2_wtfmex is obsolete.  use Gtomo2_wtmex instead'

if exist(file, 'file')
	ob.file = file;

	[ob.nx, ob.ny, ob.nb, ob.na] = wtfmex('read', ob.file);
else
	ob.arg = file;
	wtfmex('gensys', ob.arg', sp_group_type);
	ob.nx = str2num(arg_get(ob.arg, 'nx'));
	ob.ny = str2num(arg_get(ob.arg, 'ny'));
	ob.nb = str2num(arg_get(ob.arg, 'nb'));
	ob.na = str2num(arg_get(ob.arg, 'na'));
end

ob.dims = [ob.nb * ob.na, ob.nx * ob.ny];

ob = class(ob, 'Gtomo2_wtfmex');

tmp = sum(ob) > 0;
ob.mask = reshape(tmp, ob.nx, ob.ny);

if ob.chat
	wtfmex('print'); % display header info
end


function disprog(i,N,steps);
%DISPROG Display progression of a loop.
%	DISPROG(i,N,steps) displays the progression of a loop.
%
%	I     : loop variable
%	N     : final value of i
%	STEPS : number of displayed steps.
%
%	Example:
%	 N=16; for i=1:N, disprog(i,N,5); end;

%	F. Auger, August, December 1995.
%       from an idea of R. Settineri.
%	Copyright (c) 1996 by CNRS (France).
%
%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2 of the License, or
%  (at your option) any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; if not, write to the Free Software
%  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

global begin_time_disprog ;

if (i==1),
 begin_time_disprog=cputime;
end;

if (i==N),
 fprintf('100 %% complete in %g seconds.\n', cputime-begin_time_disprog);
 clear begin_time_disprog;
elseif (floor(i*steps/N)~=floor((i-1)*steps/N)),
 fprintf('%g ', floor(i*steps/N)*ceil(100/steps));
end;


%-------------------------------------------------------------------------------------------------------------------%
%
% IB2d is an Immersed Boundary Code (IB) for solving fully coupled non-linear
% 	fluid-structure interaction models. This version of the code is based off of
%	Peskin's Immersed Boundary Method Paper in Acta Numerica, 2002.
%
% Author: Nicholas A. Battista
% Email:  nick.battista@unc.edu
% Date Created: September 9th, 2016
% Institution: UNC-CH
%
% This code is capable of creating Lagrangian Structures using:
% 	1. Springs
% 	2. Beams (*torsional springs)
% 	3. Target Points
%	4. Muscle-Model (combined Force-Length-Velocity model, "HIll+(Length-Tension)")
%
% One is able to update those Lagrangian Structure parameters, e.g., spring constants, resting %%	lengths, etc
%
% There are a number of built in Examples, mostly used for teaching purposes.
%
% If you would like us %to add a specific muscle model, please let Nick (nick.battista@unc.edu) know.
%
%--------------------------------------------------------------------------------------------------------------------%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: creates the geometry and prints associated input files
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Make_Your_Geometry_and_Input_Files()

%
% Grid Parameters (MAKE SURE MATCHES IN input2d !!!)
%
Nx =  1024;      % # of Eulerian Grid Pts. in x-Direction (MUST BE EVEN!!!)
Lx = 5.0;        % Length of Eulerian Grid in x-Direction
dx = Lx/Nx;      % Grid spatial resolution

%
% Immersed Structure Geometric / Dynamic Parameters %
%
ds = 0.45*dx;               % Lagrangian Pt. Spacing (2x resolution of Eulerian grid)
struct_name = 'insect_HT'; % Name for .vertex, .spring, etc files. (must match what's in 'input2d')

% Call function to construct geometry
[xLag,yLag] = give_Me_Immsersed_Boundary_Geometry(ds,Nx,Lx);
yLag = yLag - 2+0.125;

% Plot Geometry to test
plot(xLag,yLag,'r-'); hold on;
plot(xLag,yLag,'*'); hold on;
xlabel('x'); ylabel('y');
axis([0 Lx 0 Lx]);

% Prints .vertex file!
print_Lagrangian_Vertices(xLag,yLag,struct_name);

% Prints .spring file!
%k_Spring = 2.5e4;                    % Spring stiffness (does not need to be equal for all springs)
%ds_Rest = 0.0;                       % Spring resting length (does not need to be equal for all springs)
%print_Lagrangian_Springs(xLag,yLag,k_Spring,ds_Rest,struct_name);

% Prints .beam file!
% k_Beam = 0.5;                      % Beam Stiffness (does not need to be equal for all beams)
% C = compute_Curvatures(xLag,yLag)  % Computes curvature of initial configuration
%print_Lagrangian_Beams(xLag,yLag,k_Beam,C,struct_name);

% Prints .target file!
k_Target = 2e5;
print_Lagrangian_Target_Pts(xLag,k_Target,struct_name);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: prints VERTEX points to a file called 'struct_name'.vertex
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Lagrangian_Vertices(xLag,yLag,struct_name)

    N = length(xLag); % Total # of Lag. Pts

    vertex_fid = fopen([struct_name '.vertex'], 'w');

    fprintf(vertex_fid, '%d\n', N );

    %Loops over all Lagrangian Pts.
    for s = 1:N
        X_v = xLag(s);
        Y_v = yLag(s);
        fprintf(vertex_fid, '%1.16e %1.16e\n', X_v, Y_v);
    end

    fclose(vertex_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: prints TARGET points to a file called 'struct_name'.target
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Lagrangian_Target_Pts(xLag,k_Target,struct_name)

    N = length(xLag);

    target_fid = fopen([struct_name '.target'], 'w');

    fprintf(target_fid, '%d\n', N );

    %Loops over all Lagrangian Pts.
    for s = 1:N
        fprintf(target_fid, '%d %1.16e\n', s, k_Target);
    end

    fclose(target_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: prints SPRING points to a file called 'struct_name'.spring
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Lagrangian_Springs(xLag,yLag,k_Spring,ds_Rest,struct_name)

    N = length(xLag);

    spring_fid = fopen([struct_name '.spring'], 'w');

    fprintf(spring_fid, '%d\n', N );    % Print # of springs

    %SPRINGS BETWEEN VERTICES
    for s = 1:N
            if s < N
                fprintf(spring_fid, '%d %d %1.16e %1.16e\n', s, s+1, k_Spring, ds_Rest);
            else
                %Case s=N
                fprintf(spring_fid, '%d %d %1.16e %1.16e\n', s, 1,   k_Spring, ds_Rest);
            end
    end
    fclose(spring_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: prints BEAM (Torsional Spring) points to a file called 'struct_name'.beam
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Lagrangian_Beams(xLag,yLag,k_Beam,C,struct_name)

    % k_Beam: beam stiffness
    % C: beam curvature

    N = length(xLag); % NOTE: Total number of beams = Number of Total Lag Pts. - 2

    beam_fid = fopen([struct_name '.beam'], 'w');

    fprintf(beam_fid, '%d\n', N );

    %spring_force = kappa_spring*ds/(ds^2);

    %BEAMS BETWEEN VERTICES
    for s = 2:N-1
            if  s <= N-1
                fprintf(beam_fid, '%d %d %d %1.16e %1.16e\n',s-1, s, s+1, k_Beam, C(s) );
            else
                %Case s=N
                fprintf(beam_fid, '%d %d %d %1.16e %1.16e\n',s-1, s, 1,   k_Beam, C(s) );
            end
    end
    fclose(beam_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: computes "curvature" of starting configuration
%
% NOTE: not curvature in the traditional geometric sense, in the 'discrete'
% sense through cross product.
%
% NOTE: assumes a CLOSED structure
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function C = compute_Curvatures(xLag,yLag)

N = length(xLag);
C = zeros( N );

%Note: needs to be done same order as you print .beam file!
for i=1:N

   % Pts Xp -> Xq -> Xr (same as beam force calc.)

   if ( (i > 1) && (i < N) )

        Xp = xLag(i-1); Xq = xLag(i); Xr = xLag(i+1);
        Yp = yLag(i-1); Yq = yLag(i); Yr = yLag(i+1);

   elseif (i==1)

        Xp = xLag(N); Xq = xLag(i); Xr = xLag(i+1);
        Yp = yLag(N); Yq = yLag(i); Yr = yLag(i+1);

   elseif (i==N)

        Xp = xLag(N-1); Xq = xLag(N); Xr = xLag(1);
        Yp = yLag(N-1); Yq = yLag(N); Yr = yLag(1);

   end

   C(i) = (Xr-Xq)*(Yq-Yp) - (Yr-Yq)*(Xq-Xp); %Cross product btwn vectors

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: creates the Lagrangian structure geometry
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [xLag,yLag] = give_Me_Immsersed_Boundary_Geometry(ds,Nx,Lx)

% ds: Lagrangian pt. spacing
% Nx: Eulerian grid resolution

% Gives elliptical subset for tube side
a = 0.5;    % semi-major axis (horizontal)
b = 0.45;   % semi-minor axis (vertical)
ang = pi/6; % angle start/cuttoff for ellipse
[xE,yE] = give_Me_Elliptical_Geometry(ds,a,b,ang);
xOff = 2*xE(1);

% Gives top and bottom portion of one section of tube
d = 0.2;                  % separation distance
xTube = [xE+3*xOff xE+3*xOff xE+2*xOff xE+2*xOff xE+xOff xE+xOff xE xE];          % top first, then bottom
xTube = xTube + 1;
xTube = xTube(end:-1:1);  % reverse it!
yTube = [yE+d/2 -yE-d/2 yE+d/2 -yE-d/2 yE+d/2 -yE-d/2 yE+d/2 -yE-d/2]; % top first, then bottom
yTube = yTube + Lx/2;

% Give indices for to attach valves
ind_Top = 1;                 % node index for first point on top (on RHS)
ind_Bot = length(xTube)/8+1; % node index for first point on bottom (on RHS)

xFlat = xTube(ind_Top)-Lx/20:ds:xTube(ind_Top);
yFlatTop = yTube(ind_Top)*ones(1,length(xFlat));
yFlatBot = yTube(ind_Bot)*ones(1,length(xFlat));

xLag = [xTube xFlat xFlat];
yLag = [yTube yFlatTop yFlatBot];

% Gives valve geometry
[xV,yV] = give_Valve_Geometry(d,ds);

% TESTING (i.e., PLOT IT, yo!)
%plot(xTube,yTube,'b*'); hold on
%len = length(xTube);
%plot(xTube(len/8+1),yTube(len/8+1),'r*'); hold on
%plot(xTube(1),yTube(1),'k*'); hold on;
%axis([0 5 0 5]);
%pause();

%plot(xV,yV,'g*'); hold on;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: gives valve geometry inside a distance, d, between the edges of
% the tube
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [xV,yV] = give_Valve_Geometry(d,ds)

% for A*x^2 geometry -> 2 eqns and 2 unknowns
%y(0) = 0 = 0
%y(0.9d/2) = A(0.9/2)^2*d^2 = 1.5*d
%
% ----> A = 1.5 / ( (0.45)^2 * d )
%
A = 1.0 / ( (0.45)^2 * d );

yV = -0:ds/2:0.9/2*d;
xV = -A*yV.^2;

%figure(2)
%plot(xV,yV,'b*'); hold on;
%pause();

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: gives elliptical geometry
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [xE,yE] = give_Me_Elliptical_Geometry(ds,a,b,ang)

dtheta = ds/max(a,b); % use minimum of axis lengths

n = 1;
xE(n) = a*cos(ang); yE(n) = b*sin(ang);
ang_n = ang + dtheta;

while ang_n < (pi/2)

    n = n+1;                % update counter
    xE(n) = a*cos(ang_n);   % next xVal along ellipse
    yE(n) = b*sin(ang_n);   % next yVal along ellipse
    ang_n = ang_n + dtheta; % update angle

end
xE(n+1) = a*cos(pi/2);
yE(n+1) = b*sin(pi/2);

xE = [xE -xE(end-1:-1:1)];
yE = [yE yE(end-1:-1:1)];

yE = yE - yE(1);           % Translate down

%plot(xE,yE,'*'); hold on;
%axis([-a a -a a]);

xLength = abs( 2*xE(1) );
fprintf('\nThe x-Length of the tube section is: %d\n',xLength);


function all_boxes = selective_search(image_filenames, output_filename)

addpath('Dependencies');

if(~exist('anigauss'))
    mex Dependencies/anigaussm/anigauss_mex.c Dependencies/anigaussm/anigauss.c -output anigauss
end

if(~exist('mexCountWordsIndex'))
    mex Dependencies/mexCountWordsIndex.cpp
end

if(~exist('mexFelzenSegmentIndex'))
    mex Dependencies/FelzenSegment/mexFelzenSegmentIndex.cpp -output mexFelzenSegmentIndex;
end

colorTypes = {'Hsv', 'Lab', 'RGI', 'H', 'Intensity'};
colorType = colorTypes{1}; % Single color space for demo

% Here you specify which similarity functions to use in merging
simFunctionHandles = {@SSSimColourTextureSizeFillOrig, @SSSimTextureSizeFill, @SSSimBoxFillOrig, @SSSimSize};
simFunctionHandles = simFunctionHandles(1:2); % Two different merging strategies

% Thresholds for the Felzenszwalb and Huttenlocher segmentation algorithm.
% Note that by default, we set minSize = k, and sigma = 0.8.
k = 200; % controls size of segments of initial segmentation.
minSize = k;
sigma = 0.8;

% Process all images.
all_boxes = {};
for i=1:length(image_filenames)
    im = imread(image_filenames{i});
    [boxes blobIndIm blobBoxes hierarchy] = Image2HierarchicalGrouping(im, sigma, k, minSize, colorType, simFunctionHandles);
    all_boxes{i} = BoxRemoveDuplicates(boxes);
end

if nargin > 1
    all_boxes
    save(output_filename, 'all_boxes', '-v7');
end


classdef LvdOptimization < matlab.mixin.SetGet
    %LvdOptimization Summary of this class goes here
    %   Detailed explanation goes here

    properties
        lvdData LvdData

        vars OptimizationVariableSet
%         objFcn(1,1) AbstractObjectiveFcn = NoOptimizationObjectiveFcn()
        objFcn(1,1) AbstractObjectiveFcn = CompositeObjectiveFcn()
        constraints(1,1) ConstraintSet =  ConstraintSet()

        %Optimization Algo Selection
        optAlgo(1,1) LvdOptimizerAlgoEnum = LvdOptimizerAlgoEnum.Fmincon;

        %Optimizers
        fminconOpt(1,1) FminconOptimizer = FminconOptimizer();
        patternSearchOpt(1,1) PatternSearchOptimizer = PatternSearchOptimizer();
        nomadOpt(1,1) NomadOptimizer = NomadOptimizer();
        ipoptOpt(1,1) IpOptOptimizer = IpOptOptimizer();
        surragateOpt(1,1) SurrogateOptimizer = SurrogateOptimizer();

        %Gradient Calc Algo Selection
        gradAlgo(1,1) LvdOptimizerGradientCalculationAlgoEnum = LvdOptimizerGradientCalculationAlgoEnum.BuiltIn;

        %Gradient Calculation Algos
        builtInGradMethod(1,1) BuiltInGradientCalculationMethod = BuiltInGradientCalculationMethod();
        customFiniteDiffsCalcMethod(1,1) CustomFiniteDiffsCalculationMethod = CustomFiniteDiffsCalculationMethod();
    end

    methods
        function obj = LvdOptimization(lvdData)
            obj.lvdData = lvdData;

            obj.vars = OptimizationVariableSet(obj.lvdData);
            obj.objFcn = CompositeObjectiveFcn(GenericObjectiveFcn.empty(1,0), ObjFcnDirectionTypeEnum.Minimize, ObjFcnCompositeMethodEnum.Sum, lvdData.optimizer, lvdData);
            obj.constraints = ConstraintSet(obj, lvdData);

            obj.optAlgo = LvdOptimizerAlgoEnum.Fmincon;
            obj.fminconOpt = FminconOptimizer();
            obj.patternSearchOpt = PatternSearchOptimizer();
            obj.nomadOpt = NomadOptimizer();
            obj.ipoptOpt = IpOptOptimizer();
            obj.surragateOpt = SurrogateOptimizer();

            obj.builtInGradMethod = BuiltInGradientCalculationMethod();
            obj.customFiniteDiffsCalcMethod = CustomFiniteDiffsCalculationMethod();
        end

        function [exitflag, message] = optimize(obj, writeOutput, callOutputFcn, hLvdMainGUI)
            obj.vars.sortVarsByEvtNum();
            optimizer = obj.getSelectedOptimizer();

            [x0All, actVars, ~] = obj.vars.getTotalScaledXVector();

            if(isempty(x0All) && isempty(actVars))
                uialert(hLvdMainGUI, 'There are no optimization variables enabled in this mission.  Optimization requires at least one variable.  Please enable at least one variable to continue with optimization.', 'Launch Vehicle Designer', 'Icon','error');

                return;
            end

            [exitflag, message] = optimizer.optimize(obj, writeOutput, callOutputFcn, hLvdMainGUI);
        end

        function [exitflag, message] = consoleOptimize(obj)
            global options_gravParamType %#ok<GVMIS>

            if(isempty(options_gravParamType))
                options_gravParamType = 'kspStockLike';
            end

            writeOutput = @(varargin) disp('');
            callOutputFcn = false;

            [exitflag, message] = obj.optimize(writeOutput, callOutputFcn, []);
        end

        function optimizer = getSelectedOptimizer(obj)
            optAlgorithm = obj.optAlgo;
            optimizer = obj.getOptimizerForEnum(optAlgorithm);
        end

        function optimizer = getOptimizerForEnum(obj, optAlgorithm)
            if(optAlgorithm == LvdOptimizerAlgoEnum.Fmincon)
                optimizer = obj.fminconOpt;
            elseif(optAlgorithm == LvdOptimizerAlgoEnum.PatternSearch)
                optimizer = obj.patternSearchOpt;
            elseif(optAlgorithm == LvdOptimizerAlgoEnum.Nomad)
                optimizer = obj.nomadOpt;
            elseif(optAlgorithm == LvdOptimizerAlgoEnum.Ipopt)
                optimizer = obj.ipoptOpt;
            elseif(optAlgorithm == LvdOptimizerAlgoEnum.Surrogate)
                optimizer = obj.surragateOpt;
            else
                error('Unknown LVD optimization algorithm!');
            end
        end

        function gradAlgo = getGradAlgoForEnum(obj, gradAlgoEnum)
            if(gradAlgoEnum == LvdOptimizerGradientCalculationAlgoEnum.BuiltIn)
                gradAlgo = obj.builtInGradMethod;
            elseif(gradAlgoEnum == LvdOptimizerGradientCalculationAlgoEnum.FiniteDifferences)
                gradAlgo = obj.customFiniteDiffsCalcMethod;
            else
                error('Unknown LVD gradient algorithm!');
            end
        end

        function tf = usesParallel(obj)
            tf = obj.getSelectedOptimizer().usesParallel();
        end

        function tf = usesStage(obj, stage)
            tf = obj.objFcn.usesStage(stage);

            tf = tf || obj.constraints.usesStage(stage);
        end

        function tf = usesEngine(obj, engine)
            tf = obj.objFcn.usesEngine(engine);

            tf = tf || obj.constraints.usesEngine(engine);
        end

        function tf = usesTank(obj, tank)
            tf = obj.objFcn.usesTank(tank);

            tf = tf || obj.constraints.usesTank(tank);
        end

        function tf = usesEngineToTankConn(obj, engineToTank)
            tf = obj.objFcn.usesEngineToTankConn(engineToTank);

            tf = tf || obj.constraints.usesEngineToTankConn(engineToTank);
        end

        function tf = usesExtremum(obj, extremum)
            tf = obj.objFcn.usesExtremum(extremum);

            tf = tf || obj.constraints.usesExtremum(extremum);
        end

        function tf = usesGroundObj(obj, grdObj)
            tf = obj.objFcn.usesGroundObj(grdObj) || obj.constraints.usesGroundObj(grdObj);
        end

        function tf = usesCalculusCalc(obj, calculusCalc)
            tf = obj.objFcn.usesCalculusCalc(calculusCalc);

            tf = tf || obj.constraints.usesCalculusCalc(calculusCalc);
        end

        function tf = usesGeometricPoint(obj, point)
            tf = obj.constraints.usesGeometricPoint(point);
        end

        function tf = usesGeometricVector(obj, vector)
            tf = obj.constraints.usesGeometricVector(vector);
        end

        function tf = usesGeometricCoordSys(obj, coordSys)
            tf = obj.constraints.usesGeometricCoordSys(coordSys);
        end

        function tf = usesGeometricRefFrame(obj, refFrame)
            tf = obj.constraints.usesGeometricRefFrame(refFrame);
        end

        function tf = usesGeometricAngle(obj, angle)
            tf = obj.constraints.usesGeometricAngle(angle);
        end

        function tf = usesGeometricPlane(obj, plane)
            tf = obj.constraints.usesGeometricPlane(plane);
        end

        function tf = usesPlugin(obj, plugin)
            tf = obj.constraints.usesPlugin(plugin);
        end
    end

    methods(Static)
        function obj = loadobj(obj)
            if(isempty(obj.vars.lvdData))
                obj.vars.lvdData = obj.lvdData;
            end
        end
    end

    methods(Access=private)
        function evtNumToStartScriptExecAt = getEvtNumToStartScriptExecAt(obj, actVars)
            evtNumToStartScriptExecAt = obj.lvdData.script.getTotalNumOfEvents();
            for(i=1:length(actVars)) %#ok<*NO4LP>
                var = actVars(i);

                if(isVarInLaunchVehicle(var, obj.lvdData) || isVarInLaunchVehicle(var, obj.lvdData))
                    varEvtNum = 1;
                else
                    varEvtNum = getEventNumberForVar(var, obj.lvdData);

                    if(isempty(varEvtNum))
                        varEvtNum = 1;
                    end
                end

                if(varEvtNum < evtNumToStartScriptExecAt)
                    evtNumToStartScriptExecAt = varEvtNum;
                end

                if(evtNumToStartScriptExecAt == 1)
                    break; %it can't go lower than 1, so we're executing the whole thing.  No reason to keep going.
                end
            end
        end

        function evtNumToEndScriptExecAt = getEvtNumToEndScriptExecAt(obj)
            [~, activeVars, ~, ~] = obj.vars.getTotalScaledXVector();

            evtNumToEndScriptExecAt = -1;
            for(i=1:length(activeVars))
                var = activeVars(i);

                if(isVarInLaunchVehicle(var, obj.lvdData) || isVarInLaunchVehicle(var, obj.lvdData))
                    varEvtNum = 1;
                else
                    varEvtNum = getEventNumberForVar(var, obj.lvdData);

                    if(isempty(varEvtNum))
                        varEvtNum = 1;
                    end
                end

                if(varEvtNum > evtNumToEndScriptExecAt)
                    evtNumToEndScriptExecAt = varEvtNum;
                end
            end

            objFcnEvts = obj.objFcn.getObjFuncEvents();
            for(i=1:length(objFcnEvts))
                objFcnEvtNum = objFcnEvts(i).getEventNum();

                if(objFcnEvtNum > evtNumToEndScriptExecAt)
                    evtNumToEndScriptExecAt = objFcnEvtNum;
                end
            end

            constrEvts = obj.constraints.getConstrEvents();
            for(i=1:length(constrEvts))
                constrEvtNum = constrEvts(i).getEventNum();

                if(constrEvtNum > evtNumToEndScriptExecAt)
                    evtNumToEndScriptExecAt = constrEvtNum;
                end
            end
        end
    end
end


function test_pull1412

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY ft_heartrate

cd(dccnpath('/home/common/matlab/fieldtrip/data/test/pull1412'));

%%
% this corresponds to the preprocessed dataset 006_3013065.02_rest1 from bug3433

load datappg

cfg = [];
cfg.channel = 'HR';
cfg.threshold = 0.7;
cfg.method = 'findpeaks';
% cfg.method = 'pantompkin'; this does not work very well on the PPG data
heartrate0 = ft_heartrate(cfg, data);

figure
plot(heartrate0.time{1}, heartrate0.trial{1}(1,:), '-');

%%
% this corresponds to the ECG channel from ArtifactMEG.ds as documented on
% http://www.fieldtriptoolbox.org/example/use_independent_component_analysis_ica_to_remove_ecg_artifacts/

load dataecg

cfg = [];
cfg.channel = 'ECG';
cfg.threshold = 1.2;
cfg.method = 'findpeaks';
cfg.flipsignal = 'no';
heartrate1 = ft_heartrate(cfg, data);

cfg = [];
cfg.channel = 'ECG';
cfg.method = 'pantompkin';
heartrate2 = ft_heartrate(cfg, data);

figure
plot(heartrate1.time{1}, heartrate1.trial{1}(1,:), 'b-');
hold on
plot(heartrate2.time{1}, heartrate2.trial{1}(1,:), 'rx');
legend({'findpeaks', 'pantompkin'});


function res = imrecerode(img, h, varargin)
%IMRECERODE Perform a morphological reconstruction by erosion
%
%   usage:
%   RES = imrecerode(IMG, H)
%   performs morphological reconstruction by erosion of img+h over img.
%
%   RES = imrecerode(IMG, H, CONN)
%   specifies connectivity, by default 8 or 26, depending on image
%   dimension
%

% Process input arguments
if length(size(img))==3
    conn = 26;
else
    conn = 8;
end

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

% apply reconstruction
marker = imcomplement(img);
res = imcomplement(imreconstruct(marker, imadd(marker, h), conn));