% =========================================================================
%                 TCDCN face alignment tool (68 points)
% =========================================================================
% The provided tool is a re-implementation of the papers:
%
% [1] Zhanpeng Zhang, Ping Luo, Chen Change Loy, Xiaoou Tang. Facial Landmark Detection
%     by Deep Multi-task Learning, in Proceedings of European Conference on Computer Vision (ECCV), 2014
%
% [2] Zhanpeng Zhang, Ping Luo, Chen Change Loy, Xiaoou Tang. Learning Deep Representation for Face Alignment
%     with Auxiliary Attributes. Technical report, arXiv:1408.3967v2, 2014.
% =========================================================================
% Prerequisites:
% 1. Piotr's Computer Vision Matlab Toolbox (http://vision.ucsd.edu/~pdollar/toolbox/doc/index.html,
%                                            https://github.com/pdollar/toolbox)
%
%Usuage:
%
% IN:
% - "listFileName " is a file that contains the images to be tested.
% OUT:
% - "outputFileName" a file that will be generated by this tool and records the computed facial landmark locations.
% =========================================================================
% Format:
%
% Format of the listfile:
% Each of  line contains the image path, followed by the left, top, width and height of the face bounding boxe.
% (see the example file "list.txt" in the package and "boundingbox.jpg" illusrates how large the bounding box should be.)
%
% Format of the outputFile:
% Each line contrains input image path followed by the 68 facial landmark locations (x1,y1,x2,y2....x68,y68).
% To view the format of the output file, see visualize.m.
% Notice
% 1) This demo has been tested on Windows 7 64 bit, Matlab 2013a.
%
% *More details of our implementation, please feel free to drop me an email, zhzhanp@gmail.com.
% =========================================================================

clear; clc;
addpath('./TCDCN/');

%% paramter setup
listFileName = 'list.txt';
modelFile = 'model.mat';
outputFileName = 'output.txt';

%% run
main(listFileName,modelFile,outputFileName)


function priors = spm_cfg_eeg_inv_priors
% Configuration file to set up priors for M/EEG source reconstruction
%__________________________________________________________________________
% Copyright (C) 2010-2017 Wellcome Trust Centre for Neuroimaging

% Gareth Barnes
% $Id: spm_cfg_eeg_inv_priors.m 7110 2017-06-15 11:45:05Z guillaume $

D = cfg_files;
D.tag = 'D';
D.name = 'M/EEG datasets';
D.filter = 'mat';
D.num = [1 Inf];
D.help = {'Select the M/EEG mat files.'};

val = cfg_entry;
val.tag = 'val';
val.name = 'Inversion index';
val.strtype = 'n';
val.help = {'Index of the cell in D.inv where the forward model can be found and the results will be stored.'};
val.val = {1};

priorname = cfg_entry;
priorname.tag = 'priorname';
priorname.name = 'Prefix for prior';
priorname.strtype = 's';
priorname.num = [1 Inf];
priorname.val = {'priorset1'};
priorname.help = {'Prefix for prior directory'};

sensorlevel = cfg_entry;
sensorlevel.tag = 'sensorlevel';
sensorlevel.name = 'RMS Sensor level noise';
sensorlevel.strtype = 'r';
sensorlevel.help = {'Assuming white sensor noise of same magnitude on all channels. Units fT for MEG. eg 10fT/rt(Hz) white noise for 100Hz bandwidth would be 100fT rms'};
sensorlevel.val = {100};

FWHMmm = cfg_entry;
FWHMmm.tag = 'FWHMmm';
FWHMmm.name = 'Patch smoothness';
FWHMmm.strtype = 'r';
FWHMmm.num = [1 1];
FWHMmm.val = {[4]};
FWHMmm.help = {'FWHM on cortex in mm. NB. Ignored for EBB and IID. Square windowed for COH '};

popular=cfg_menu;
popular.tag='popular';
popular.name='prior types';
popular.help={' Select from popular priors: IID (min norm), COH (LORETA) or EBB (beamforming)'};
popular.labels={'IID','COH','EBB','sparseEBB'};
popular.values={'IID','COH','EBB','sparseEBB'};
popular.val={'IID'};

popularpars=cfg_branch;
popularpars.tag='popularpars';
popularpars.name='Popular priors';
popularpars.help={' Select from popular priors and kernel smoothness (no smoothing used for IID)'};
popularpars.val={popular,FWHMmm};

npatches = cfg_entry;
npatches.tag = 'npatches';
npatches.name = 'Number of randomly selected patches';
npatches.strtype = 'i';
npatches.num = [1 1];
npatches.val = {[512]};
npatches.help = {'Number of randomly centred patches (priors) on each iteration'};

niter = cfg_entry;
niter.tag = 'niter';
niter.name = 'Number of iterations';
niter.strtype = 'i';
niter.num = [1 1];
niter.val = {[1]};
niter.help = {'Number of iterations'};

probfile = cfg_entry;
probfile.tag = 'probfile';
probfile.name = 'Prior to bias distribution of patches X';
probfile.strtype = 's';
%probfile.num = [1 1];
probfile.val = {''};
probfile.help = {'Name of patch probability file'};

randpatch = cfg_branch;
randpatch.tag = 'randpatch';
randpatch.name = 'Random Patches';
randpatch.help = {'Define random patches'};
randpatch.val  = {npatches,niter,FWHMmm,probfile};

fixedfile = cfg_files;
fixedfile.tag = 'fixedfile';
fixedfile.name = 'Patch definition file ';
fixedfile.filter = 'mat';
fixedfile.num = [1 1];
fixedfile.help = {'Select patch definition file (mat file with variable Ip: rows are iterations columns are patch indices '};
fixedfile.val={{''}};

fixedrows = cfg_entry;
fixedrows.tag = 'fixedrows';
fixedrows.name = 'Rows from fixed patch file';
fixedrows.strtype = 'i';
fixedrows.num = [1 2];
fixedrows.val = {[1 Inf]};
fixedrows.help = {'Select first and last row of patch sets to use from file'};

fixedpatch = cfg_branch;
fixedpatch.tag = 'fixedpatch';
fixedpatch.name = 'Fixed Patches';
fixedpatch.help = {'Define fixed patches'};
fixedpatch.val  = {fixedfile,fixedrows,FWHMmm};

sparsify = cfg_entry;
sparsify.tag = 'sparsify';
sparsify.name = 'Sparsify to N largest local maxima';
sparsify.strtype = 'i';
sparsify.num = [1 2];
sparsify.val = {[1 Inf]};
sparsify.help = {'Select first and last row of patch sets to use from file'};

space = cfg_menu;
space.tag = 'space';
space.name = 'Prior image space';
space.help = {'Space of the mask image.'};
space.labels = {'MNI', 'Native'};
space.values = {1, 0};
space.val = {1};

clean = cfg_menu;
clean.tag = 'clean';
clean.name = 'Start fresh';
clean.help = {'Start from fresh or keep existing priors'};
clean.labels = {'Fresh', 'Keep'};
clean.values = {1, 0};
clean.val = {1};

priorsmask  = cfg_files;
priorsmask.tag = 'priorsmask';
priorsmask.name = 'Priors file';
priorsmask.filter = '(.*\.gii$)|(.*\.mat$)|(.*\.nii(,\d+)?$)|(.*\.img(,\d+)?$)';
priorsmask.num = [0 1];
priorsmask.help = {'Select a mask or a mat file with priors or posterior.'};
priorsmask.val = {{''}};

funcpriors = cfg_branch;
funcpriors.tag = 'funcpriors';
funcpriors.name = 'Functionally defined priors';
funcpriors.help = {'Use posterior from previous inversion or restrict solutions to pre-specified VOIs'};
funcpriors.val  = {priorsmask, space,sparsify};

priortype = cfg_repeat;
priortype.tag = 'priortype';
priortype.name = 'Prior';
priortype.help = {'Specify the prior type to add'};
priortype.num  = [1 Inf];
priortype.values  = {randpatch,fixedpatch,funcpriors,popularpars};
priortype.val  = {randpatch};

%
% npost = cfg_entry;
% npost.tag = 'npost';
% npost.name = 'N posteriors';
% npost.strtype = 'n';
% npost.help = {'Nunber of posterior files to generate'};
% npost.val = {1};
%
% noisepost = cfg_entry;
% noisepost.tag = 'noisepost';
% noisepost.name = 'Percentage max noise';
% noisepost.strtype = 'r';
% noisepost.help = {'Add Gaussian noise with of a certain percentage of maximum power to posterior'};
% noisepost.val = {0};
%
%
% smoothpost = cfg_entry;
% smoothpost.tag = 'smoothpost';
% smoothpost.name = 'Number of smoothing iterations';
% smoothpost.strtype = 'r';
% smoothpost.help = {'Number of smoothing iterations (0 for no smoothing)'};
% smoothpost.val = {0};
%
% noisepost = cfg_entry;
% noisepost.tag = 'noisepost';
% noisepost.name = 'Percentage max noise';
% noisepost.strtype = 'r';
% noisepost.help = {'Add Gaussian noise with of a certain percentage of maximum power to posterior'};
% noisepost.val = {0};
%
% threshpost = cfg_entry;
% threshpost.tag = 'threshpost';
% threshpost.name = 'Percentage of maximum power at at which to threshold';
% threshpost.strtype = 'r';
% threshpost.help = {'Save posterior with full (0) or thresholded power distribution'};
% threshpost.val = {0};
%
% nmaxpost = cfg_entry;
% nmaxpost.tag = 'nmaxpost';
% nmaxpost.name = 'Number of maxima to keep as patch centers';
% nmaxpost.strtype = 'r';
% nmaxpost.help = {'Generate another file containing patch centres in Ip structure (0 make no file)'};
% nmaxpost.val = {0};
%
%
% postname = cfg_entry;
% postname.tag = 'postname';
% postname.name = 'Prefix for posterior';
% postname.strtype = 's';
% postname.num = [1 Inf];
% postname.val = {'postset1'};
% postname.help = {'Prefix for posterior directory'};
%

priors = cfg_exbranch;
priors.tag = 'priors';
priors.name = 'Inversion priors';
priors.val = {D, val,sensorlevel,priortype,priorname,clean};
priors.help = {'Set priors for source reconstruction'};
priors.prog = @add_priors;
priors.vout = @vout_priors;

%==========================================================================
function  out = add_priors(job)

val=job.val;
D = spm_eeg_load(job.D{val});

if ~isfield(D.inv{job.val}.inverse,'L')
    error('Need to set up spatial modes first');
else
    UL=D.inv{val}.inverse.L; %% dimension reduced lead field matrix
end

[a1,b1,c1]=fileparts(D.fname);
priordir=[D.path filesep job.priorname '_' b1];

if exist(priordir,'dir') ~= 7
    fprintf('Making directory for priors: %s\n',priordir);
    mkdir(priordir);
else
    mesh=D.inv{job.val}.mesh.tess_mni;
    [priorfiles] = spm_select('FPListRec',priordir,'.*\.mat$');

    count=size(priorfiles,1);
    fprintf('Found %d existing priors in this directory\n',count);

    if job.clean
        fprintf('Deleting existing priors\n');
        for f=1:count
            delete(deblank(priorfiles(f,:)));
        end
    else
        fprintf('Keeping existing priors\n');
    end

end

mesh=D.inv{val}.forward.mesh; %% assume this is in metres

Ns=size(mesh.vert,1);

% Set up sensor level prior
Qe{1}=eye(size(UL,1)).*job.sensorlevel;
Qp={}; %% source level covariance or svd components

% add in functional (from other modalities or experiment) hypotheses

for i=1:numel(job.priortype) %% move through different prior specifications
    allIp=[];
    Qp=[];

    % RANDOM PATCH CENTRES
    if isfield(job.priortype{i},'randpatch')

        base=job.priortype{i}.randpatch;

        Np = base.npatches;
        Npatchiter = base.niter;
        probfile=base.probfile;

        if isempty(probfile)
            prob=ones(Ns,1)./Ns;
        else

            probmesh=gifti(probfile);

            data=double(probmesh.cdata);
            M0.vertices=probmesh.vertices;
            M0.faces=probmesh.faces;

            if size(probmesh.vertices,1)==size(mesh.vert,1)
            %    fprintf('NB smoothing prior with 20 iterations\n');
                %prob=spm_mesh_smooth(M0,data',20);
                prob=data;
            else
                error('Gifti mesh size does not match');
            end
        end
        if sum(prob)>1.01
            warning('Rescaling bias file to unit sum');
        end

        prob=prob./sum(prob);
        Ip=[];

        fprintf('Using %d iterations of %d random patches\n',Npatchiter,Np);
        allIp=sparse(Npatchiter,Np);

        %rng('shuffle');

        dum=sparse(1,Ns);
        figure;
        hold on;

        for j=1:Npatchiter

            for k=1:Np
                pval=max(prob)*(k-1)./Np;
                sind=find(prob>=pval);
                randind=randperm(length(sind));
                allIp(j,k)=sind(randind(1));
                dum(allIp(j,k))=dum(allIp(j,k))+1;
            end
            %end; %% IF
            plot(1:length(prob),dum,'.');  drawnow;
        end % for j
        fprintf('Sampled %3.2f percent of cortex (%d vertices) \n',100*length(find(dum>0))./length(dum),length(find(dum>0)));

    end % random patch

    % FIXED PATCH CENTRES FROM FILE
    if isfield(job.priortype{i},'fixedpatch')

        base=job.priortype{i}.fixedpatch;
        try
            dum=load(char(base.fixedfile));
        catch
            error('failed to load fixedpatch file');
        end
        if ~isfield(dum,'Ip')
            error('Need to have patch indices in structure Ip');
        end
        allIp=dum.Ip;
        rows=base.fixedrows;
        lastrow=min(rows(2),size(allIp,1));
        rowind=[rows(1):lastrow];
        allIp=allIp(rowind,:);
    end % fixed patch

    %%%%%%%%%%%%%%% FIXED OR RANDOM PATCHES
    if isfield(job.priortype{i},'fixedpatch') || isfield(job.priortype{i},'randpatch')

        % Set up patches on cortical surface determined by indices of allIp
        % one prior files per row of Ip

        [Qp,Qe,allpriornames]=spm_eeg_invert_setuppatches(allIp,mesh,base,priordir,Qe,UL);

    end % if fixedpatch or randpatch

    % figure;
    %
    % if job.nmaxpost>0,
    %     postIpname=[postdir filesep sprintf('post_Ip.mat')];
    %     Ip=zeros(job.npost,job.nmaxpost);
    % end;
    %
    % M0=[];M0.vertices=mesh.vert; M0.faces=mesh.face;
    % for f=1:job.npost,
    %
    %     subplot(job.npost,1,f);
    %     plot(sourcevar,'k');hold on;
    %     postname=[postdir filesep sprintf('post%d.mat',f)];
    %     fprintf('adding %f percent noise to posterior\n',job.noisepost);
    %     nsourcevar=sourcevar+max(sourcevar)*job.noisepost*randn(size(sourcevar))./100;
    %     fprintf('Smoothing by %d iterations\n',job.smoothpost);
    %     nsourcevar = spm_mesh_smooth(M0, nsourcevar',job.smoothpost);
    %
    %     fprintf('Thresholding at %f percent of max power\n',job.threshpost);
    %     thresh=max(nsourcevar)*job.threshpost./100;
    %     plot([0,length(sourcevar)],[thresh thresh],':g');
    %     nsourcevar(nsourcevar<thresh)=0;
    %     plotind=find(nsourcevar);
    %     plot(plotind,nsourcevar(plotind),'ro');
    %     legend('orig','thresh','thresh noisy');
    %     nsourcevar=sparse(nsourcevar);
    %     Qp{1}=diag(nsourcevar);
    %     fprintf('SAving %s\n',postname);
    %     F=-Inf;
    %     save(postname,'Qp','Qe','UL','F','-v7.3');
    %     %%
    %     fprintf('\n Getting %d local maxima ',job.nmaxpost);
    %     Ip1 = spm_mesh_get_lm(M0,nsourcevar); %% get local maxima
    %
    %     [vals,ind]=sort(nsourcevar(Ip1),'descend');
    %     Ip(f,:)=Ip1(ind(1:job.nmaxpost));
    %
    %
    %
    % end; % for f
    % if job.nmaxpost>0,
    %     fprintf('Saving %s\n',postIpname);
    %     save(postIpname,'Ip'); % =[postdir filesep sprintf('post_Ip.mat')];
    %     %Ip=zeros(job.npost,job.nmaxpost);
    % end;

    %%%%%%%%%%% FUNCTIONALLY DEFINED PRIORS

    if isfield(job.priortype{i},'funcpriors')
        base=job.priortype{i}.funcpriors;
        P = char(base.priorsmask);
        priors{i}.priortype='funcpriors';
        priors{i}.priorfname=P;

        fprintf('Using priors from file %s\n',P);

        P=priors{i}.priorfname;
        [p,f,e] = fileparts(P);
        switch lower(e)
            case '.mat'
                a=load(P);
                if isfield(a,'Qp')

                    disp('Replacing sensor and source posterior distribution');
                    for f=1:numel(a.Qp)
                        Qp{end+1}=a.Qp{f};
                    end

                    % now need to compress the original Qe (say 275 channels) into reduced channel form
                    U=D.inv{val}.inverse.U{1}; %% get spatial modes definition
                    disp('NOT SURE IF WE NEED TO RESCALE FOR CHAN REDUCTION');
                    scaleU=size(a.Qe,1)./size(U,1); % white noise power pwer channel reduce with number of channels

                    Qe{1}=U*a.Qe*U'./scaleU;
                    fprintf('\n Reducing white noise variance from %3.2f fT^2 on each of %d channels to %3.2f fT^2 on each of %d channels\n',...
                        mean(diag(a.Qe)),size(a.Qe,1),mean(diag(Qe{1})),size(U,1));

                else
                    disp('loading just source level posterior');
                    Qp{end+1}=a.pQ;
                end

            case '.gii'
                g = gifti(P);

                for i=1:size(g.cdata,2)
                    Qp{end+1} = double(g.cdata(:,i));
                end

            case {'.img', '.nii'}
                S.D = D;
                S.fmri = P;
                S.space = job.isstandard.custom.priors.space;
                D = spm_eeg_inv_fmripriors(S);
                inverse.fmri = D.inv{D.val}.inverse.fmri;
                a=load(inverse.fmri.priors);

                Qp{end+1} = a.pQ;
            otherwise
                error('Unknown file type.');
        end % switch

        idnum=randi(1e6);

        priorfname=[priordir filesep sprintf('prior%d.mat',idnum)];
        fprintf('Saving %s\n',priorfname);
        F=[]; % no associated free energy value
        save(priorfname,'Qp','Qe','UL','F');
    end % func priors

    % POPULAR PRIORS

    if isfield(job.priortype{i},'popularpars')
        base=job.priortype{i}.popularpars;

        fprintf('Adding prior covariance matrix for %s algorithm\n',base.popular);

        if strcmp(base.popular,'sparseEBB')

            % calculate power on cortical surface
            % using beamformer assumptions
            AYYA=D.inv{val}.inverse.AYYA;

            InvCov = spm_inv(AYYA);

            allsource = sparse(Ns,1);
            Sourcepower = sparse(Ns,1);

            for bk = 1:Ns
                normpower = 1/(UL(:,bk)'*UL(:,bk));
                Sourcepower(bk) = 1/(UL(:,bk)'*InvCov*UL(:,bk));
                % normalise power by unit noise through lead fields
                allsource(bk) = Sourcepower(bk)./normpower;
            end

            % now get local maxima on mesh
            M.vertices=mesh.vert;
            M.faces=mesh.face;

            Ip = spm_mesh_get_lm(M,allsource); %% get local maxima
            figure;
            plot(allsource);
            legend('sparse EBB');
            hold on;
            maxBFpatch=100;
            fprintf('Limiting to a max of %d peaks\n',maxBFpatch);

            [vals,ind]=sort(allsource(Ip),'descend');
            Ip=Ip(ind(1:maxBFpatch));
            plot(Ip,allsource(Ip),'ro');

            [Qp,Qe,allpriornames]=spm_eeg_invert_setuppatches(Ip,mesh,base,priordir,Qe{1},UL);

        end % sparse EBB

        if strcmp(base.popular,'EBB')

            % calculate power on cortical surface
            % using beamformer assumptions
            AYYA=D.inv{val}.inverse.AYYA;

            InvCov = spm_inv(AYYA);

            allsource = sparse(Ns,1);
            Sourcepower = sparse(Ns,1);

            for bk = 1:Ns
                normpower = 1/(UL(:,bk)'*UL(:,bk));
                Sourcepower(bk) = 1/(UL(:,bk)'*InvCov*UL(:,bk));
                % normalise power by unit noise through lead fields
                allsource(bk) = Sourcepower(bk)./normpower;
            end

            figure;
            plot(allsource);
            legend('EBB');
            hold on;
            % now get local maxima on mesh
            M.vertices=mesh.vert;
            M.faces=mesh.face;
            warning('Smoothing not used');
            Qp{1}=diag(allsource);

            idnum=randi(1e6);
            priorfname=[priordir filesep sprintf('prior%d.mat',idnum)];
            F=[];
            save(priorfname,'Qp','Qe','UL','F');

        end % EBB

        if strcmp(base.popular,'COH')

            % create minimum norm prior
            %------------------------------------------------------------------
            Qp{1}  = speye(Ns,Ns);
            warning('SQUARE SMOOTHING KERNEL OF FWHM MM');

            M=[];M.faces=mesh.face;M.vertices=mesh.vert;
            dist=spm_mesh_distmtx(M,1);
            ind2=find(dist>0);
            ind=find(dist<base.FWHMmm./1000);
            ind=intersect(ind,ind2);
            Qp{1}(ind)=1;

            disp('Set up COH prior');

            idnum=randi(1e6);
            priorfname=[priordir filesep sprintf('prior%d.mat',idnum)];
            fprintf('Saving %s\n',priorfname);
            F=[]; % no associated free energy value

            save(priorfname,'Qp','Qe','UL','F');
        end % COH

        if strcmp(base.popular,'IID')

            % create minimum norm prior
            %------------------------------------------------------------------
            Qp{1}  = speye(Ns,Ns);

            disp('Set up IID prior');

            idnum=randi(1e6);

            priorfname=[priordir filesep sprintf('prior%d.mat',idnum)];
            fprintf('Saving %s\n',priorfname);
            F=[]; % no associated free energy value
            save(priorfname,'Qp','Qe','UL','F');
        end % IID

    end % popular priors

end % for i (looping over priors)

% NOW JUST WANT TO PLOT OUT THE CURRENT DENSITY PRIORS FOR A RANDOM SET OF PATCHES
% THIS SHOULD ALL GO IN A PREVIEW FUNCTION

[LCpL,Q,sumLCpL,QE,Cy,M,Cp,Cq,Lq]=spm_eeg_assemble_priors(UL,Qp,Qe);

figure;
mesh=D.inv{job.val}.mesh.tess_mni;
M0.vertices=mesh.vert;
M0.faces=mesh.face;
sourcepwr=diag(Cp);

spm_mip(sourcepwr,mesh.vert',6);
title('Prior');
colorbar;

CHECKSMOOTH=0;
if CHECKSMOOTH
    figure;
    r=randperm(length(Qp));

    sigma2=[];
    for f=1:min(length(r),4)
        if isfield(Qp{r(f)},'q')
            q=Qp{r(f)}.q;
            [val,ind]=max(q);

            order=1; %1 distance in mm, 0 distance in edges
            dist = spm_mesh_geodesic(M,ind-1,order);
            distind=intersect(find(dist<0.020),find(q>0)); % less than 2cm away

            y=spm_vec(log(q(distind)'));
            x=spm_vec(-dist(distind).^2);
            B = regress(y,[x ones(size(x,1),1)] );
            sigma2(f)=1./(2*B(1)); %% sd squared of gaussian
            plot(dist(distind).*1000,q(distind),'r.',dist(distind).*1000,max(q).*exp(-(dist(distind).^2)/(2*sigma2(f))),'go'); %% plot in mm
        end

    end

    if ~isempty(sigma2)
        title(sprintf('Prior Profile of prior amplitude across cortex'));
        meanfwhm=mean(sqrt(sigma2))*2.355*1000; %% in mm
        stdfwhm=std(sqrt(sigma2))*2.355*1000;
        legend(sprintf('Mean FWHM=%3.2f mm,std FWHM= %3.2fmm',meanfwhm,stdfwhm));
        drawnow;
    end

end %% if CHECKSMOOTH

out.D = job.D;

%==========================================================================
function dep = vout_priors(job)
% Output is always in field "D", no matter how job is structured
dep = cfg_dep;
dep.sname = 'M/EEG dataset(s) after imaging source reconstruction';
% reference field "D" from output
dep.src_output = substruct('.','D');
% this can be entered into any evaluated input
dep.tgt_spec   = cfg_findspec({{'filter','mat'}});

% function [q,dist,useind]= gauss_patch(M,i,FWHM,q)
%
% order=1;
%
%
% sigma=FWHM./2.355;
% sigma2=sigma^2;
%
% d=spm_mesh_geodesic(M,i-1,order);
% useind=find(d<FWHM*2);
% dist=d(useind);
% q(useind)=exp(-(dist.^2)/(2*sigma2));


%            [Lden, Ld] = deninfac(symLden, L,dense,DAt, d, absd, qblkstart,pars)
% DENINFAC
% Uses pars.maxuden as max. allowable |L(i,k)|. Otherwise num. reordering.
%
% ******************** INTERNAL FUNCTION OF SEDUMI ********************
%
% See also sedumi

function [Lden, Ld] = deninfac(symLden, L,dense,DAt, d, absd, qblkstart,pars)
%
% This file is part of SeDuMi 1.1 by Imre Polik and Oleksandr Romanko
% Copyright (C) 2005 McMaster University, Hamilton, CANADA  (since 1.1)
%
% Copyright (C) 2001 Jos F. Sturm (up to 1.05R5)
%   Dept. Econometrics & O.R., Tilburg University, the Netherlands.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% Affiliation SeDuMi 1.03 and 1.04Beta (2000):
%   Dept. Quantitative Economics, Maastricht University, the Netherlands.
%
% Affiliations up to SeDuMi 1.02 (AUG1998):
%   CRL, McMaster University, Canada.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
% 02110-1301, USA
%

% ------------------------------------------------------------
% INITIALIZE: check the numerical tolerance parameters in "pars",
%   and supply with defaults if necessary.
% ------------------------------------------------------------
if nargin < 7
    pars.maxuden = 10;                  % Stability of product-form factors
else
    if ~isfield(pars,'maxuden')
        pars.maxuden = 10;                % Stability of product-form factors
    end
end
% --------------------------------------------------
% Scaling: let Ad = Aden * Dden, as [LP, QBLK, QNORM, QTR]
% with QBLK=DAt.denq, and the others dense.A(:,j)*dj,
% with dj = sqrt(d.l(k)) or dj=sqrt(d.det(k)).
% NOTE that A*P(d)*A' = ADA + Ad * Ad'.
% --------------------------------------------------
if ~isempty(dense.cols)
    i1 = dense.l+1; i2 = i1 + length(dense.q);
    Ad = [dense.A(:,1:i1-1), DAt.denq, dense.A(:,i2:end), dense.A(:,i1:i2-1)];
    smult = [d.l(dense.cols(1:dense.l)); ones(length(dense.q),1); ...
        adenscale(dense,d,qblkstart); -d.det(dense.q)];
    % --------------------------------------------------
    % Correct for sparse part, i.e. let LAD = L\Ad
    % (this also handles L.perm)
    % --------------------------------------------------
    LAD = sparfwslv(L,Ad, symLden.LAD);
    clear Ad;
    % --------------------------------------------------
    % Factor the dense columns as "diag+rank-1"=diag(L.d)+LAD(:,k)*LAD(:,k)'
    % --------------------------------------------------'
    [Lden, Ld] = dpr1fact(LAD, L.d, symLden, smult, pars.maxuden);
    Lden.dz = symLden.dz;
    Lden.first = symLden.first;
    Lden.perm = symLden.perm;
    clear LAD;
else
    % --------------------------------------------------
    % If no dense columns
    % --------------------------------------------------
    Lden.betajc = 0;
    Ld = L.d;
    Lden.rowperm = 1:length(L.d);
end
% ------------------------------------------------------------
% If still Ld(i) = 0, then set to something positive. Otherwise
% we cannot do PCG.
% ------------------------------------------------------------
skip = find(L.skip);
if ~isempty(skip)
    dtol = pars.canceltol * absd(L.perm(skip));
    dtol = max(dtol, pars.abstol);
    Ld(skip(Ld(skip) <= dtol)) = 1;
end


%信号解扩

function out = despread(data, code)

% ****************************************************************
%   data    : 输入数据序列
%   code    : 解扩使用的扩频码序列
%   out     : 解扩后的输出数据序列
% ****************************************************************

switch nargin                           %如果输入参数个数不对，提示错误
case { 0 , 1 }
    error('缺少输入参数');
end

[hn,vn] = size(data);
[hc,vc] = size(code);

out    = zeros(hc,vn/vc);

for ii=1:hc
    xx=reshape(data(ii,:),vc,vn/vc);
    out(ii,:)= code(ii,:)*xx/vc;
end

%******************************** end of file ********************************


function varargout = ensureManifoldMesh(varargin)
%ENSUREMANIFOLDMESH Apply several simplification to obtain a manifold mesh.
%
%   Try to transform an input mesh into a manifold mesh.
%
%   Not all cases of "non-manifoldity" are checked, so please use with
%   care.
%
%   [V2, F2] = ensureManifoldMesh(V, F);
%   [V2, F2] = ensureManifoldMesh(MESH);
%   MESH2 = ensureManifoldMesh(...);
%
%   Example
%   ensureManifoldMesh
%
%   See also
%    meshes3d, isManifoldMesh

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2019-02-01,    using Matlab 9.5.0.944444 (R2018b)
% Copyright 2019 INRA - Cepia Software Platform.

%% Parse input arguments

[vertices, faces] = parseMeshData(varargin{:});
verbose = true;

%% Pre-processing

% remove duplicate faces if any
faces = removeDuplicateFaces(faces);

%% Iterative processing of multiple edges
% Reduces all edges connected to more than two faces, by collapsing second
% vertex onto the first one.

% iter = 0;
% while ~isManifoldMesh(vertices, faces) && iter < 10
%     iter = iter + 1;
    [vertices, faces] = collapseEdgesWithManyFaces(vertices, faces);
% end

%% Format output
varargout = formatMeshOutput(nargout, vertices, faces);


report_this_filefun(mfilename('fullpath'));

dy = 0.15;
tmin1 = 0.05;
newt0 = newt2;
tpre = 365;
dt = 1;

save_aspar2;
do = [ ' ! '  hodi '/aspar/myaspar' ];
eval(do)

try
    load aspar3.out
catch ME
    error_handler(ME,@do_nothing);
end
re = aspar3;

% std of p etc form pauls code.
pvar0 = 0.04, bvar0 = 0.029; avar0 = 0.337, cvar0 = 0.002;
bv = re(2,3);
p =  re(1,3);
c =  re(4,3);
A =  re(3,3);
bv0 = re(2,1);
p0 =  re(1,1);
c0 =  re(4,1);
A0 =  re(3,1);
tpre2 = 100

la = 0;
m0 = maepi(1,6);

m = min(newt2.Magnitude);
dt = 1;

t0 = ( max(newt2.Date) - mati)*365;
pla = 0;plae = 0;

P2 = [];
mp = 6;

for tpre = 0.1:tpre2
    pla = 0; plae = 0;
    for t = t0:dt:t0+tpre
        pla = pla + (10^(A + bv*(7.4-mp)) * (t + c)^(-p))  *dt;
        plae = plae + (10^(A-avar0 + bv+bvar0*(7.3-mp)) * (t + c+cvar0)^(-p+pvar0))  *dt;

    end
    P = 1 - exp(-pla);
    Pe = 1-exp(-plae);
    P2 = [P2 ; P tpre Pe];

end

P0 = [];

for tpre = 0.1:tpre2
    pla = 0;
    for t = t0:dt:t0+tpre
        pla = pla + (10^(A0 + bv0*(7.4-mp)) * (t + c0)^(-p0))  *dt;
    end
    P  =  1 - exp(-pla);
    P0 = [P0 ; P tpre ];
end

figure
axes('position',[0.1 0.25 0.35 0.6])
hold on; box on
plot(P2(:,2),P2(:,1));
hold on
%plot(P2(:,2),P2(:,3),'k');

hold  on
plot(P0(:,2),P0(:,1),'r-.');
set(gca,'TickDir','out','fontweight','bold')

legend('Bayes Estimate','Generic Model', 'Location', 'SouthEast');
xlabel('Time after Mainshock')
ylabel('Probability')
te = text(0.1,0.9,'Mag. 6','units','normalized','fontweight','bold')

P2 = [];
mp = 7;

for tpre = 0.1:tpre2
    pla = 0;
    for t = t0:dt:t0+tpre
        pla = pla + (10^(A + bv*(7.3-mp)) * (t + c)^(-p))  *dt;
    end
    P = 1 - exp(-pla);
    P2 = [P2 ; P tpre ];

end

P0 = [];

for tpre = 0.1:tpre2
    pla = 0;
    for t = t0:dt:t0+tpre
        pla = pla + (10^(A0 + bv0*(7.3-mp)) * (t + c0)^(-p0))  *dt;
    end
    P  =  1 - exp(-pla);
    P0 = [P0 ; P tpre ];
end

axes('position',[0.55 0.25 0.35 0.6])
hold on; box on
plot(P2(:,2),P2(:,1));
hold  on
plot(P0(:,2),P0(:,1),'r-.');
set(gca,'TickDir','out','fontweight','bold')

legend('Bayes Estimate','Generic Model', 'Location', 'SouthEast');
xlabel('Time after Mainshock')
te = text(0.1,0.9,'Mag. 7','units','normalized','fontweight','bold');


classdef yolov3Layer < nnet.layer.Layer
    % 该自定义类仍有很大不灵活性，表现在1、predict函数输出不能自由控制；2、类属性在predict函数里面无法改变；3、训练阶段forward函数不执行
    % 4、该类无法自定义其他普通成员函数。
    % 参考官方文档：Define Custom Deep Learning Layers
    properties
        mask       % 如当前yolov3层mask为[1，2，3]，matlab中从1开始，对应cfg文件中以0开始的mask
        anchors  % 所有的anchors,形如[width1,height1; weight2,height2; ...]，对应cfg文件中的anchors，大小为allnumAnchors*2
        num % total number of anchors,所有anchors的数量，对应cfg文件中的num
        ignore_thresh % keeps duplicated detections if IoU(detect, truth) >ignore_thresh, which will be fused during NMS (is used for training only)
        truth_thresh % adjusts duplicated detections if IoU(detect, truth) > truth_thresh, which will be fused during NMS (is used for training only)
        jitter % randomly crops and resizes images with changing aspect ratio from x(1 - 2*jitter) to x(1 + 2*jitter) (data augmentation parameter is used only from the last layer)
        random % randomly resizes network for each 10 iterations from 1/1.4 to 1.4(data augmentation parameter is used only from the last layer)
        classes   % 目标检测总共类别数量，对应cfg文件中的classes

        anchorsUse %当前yolov3层的anchors，n*2大小，[width, height]，宽高为相对输入原图大小,注意这个与matlab官网estimateAnchorBoxes的宽高顺序相反
        nAnchors % 当前yolov3层使用anchors的数量，一般为3
        numX          % 传入到该yolov3层特征图的宽，像素
        numY          % 传入到该yolov3层特征图的宽，像素
        imageSize     % 网络输入图像大小，[imageHeight,imageWidth]
        arc           % 方式,取'default'、'uCE'、'uBCE'中的一种
        stride       % 传入到该yolov3层特征下采样率，[w,h],如输入网络大小是416*416宽乘高，该特征层为13*13，则stride = 32
    end

    methods
        function layer = yolov3Layer(name, mask,allAnchors,nClasses,yoloIndex,imageSize,arc)
            % 输入参数：
            % name: 字符向量或字符串，层名字
            % mask: 见上面properties说明
            % allAnchors：同上面properties之anchors说明
            % nClasses： 1*1 标量，检测的类别数量
            % imageSize：[imageHeight,imageWidth],输入网络的图像大小
            % yoloIndex：1*1标量，从1开始的索引，输出yolo检测层的序号
            % arc:字符向量或字符串，计算损失的方式
            %
            % cuixingxing150@gmail.com
            % 2020.4.20
            %
            assert(size(allAnchors,2)==2,'allAnchors must have n*2 shape!');% nAchors*2,形如[width,height]

            layer.mask = mask;
            layer.anchors = allAnchors;
            layer.num = numel(allAnchors)/2;
            layer.classes = nClasses;
            layer.ignore_thresh = .7;
            layer.truth_thresh = 1;
            layer.jitter = .3;
            layer.random = 1;

            anchorsUse = allAnchors(mask,:);% na*2, 注意matlab中mask是从1开始的索引
            layer.Name = name;
            text = ['all number classes:', num2str(nClasses),...
                ',used anchor box:',mat2str(round(anchorsUse)),...
                ', yoloLayerID:',num2str(yoloIndex),...
                ', arc:',arc];
            layer.Description = text;
            layer.Type = 'yoloV3Layer';

            layer.numY = 1;
            layer.numX = 1;
            layer.stride =1;

            layer.anchorsUse = anchorsUse;
            layer.nAnchors = size(anchorsUse,1);
            layer.imageSize = imageSize;
            layer.arc = arc;
        end

         function Z = predict(layer, X) % training
            % matlab中上一层输入的特征X为H*W*C*N，即h*w*c*bs
            X = dlarray(X);
            layer.numY = size(X,1);
            layer.numX = size(X,2);
            bs = size(X,4);
            layer.stride = max(layer.imageSize)./max(layer.numX,layer.numY);

            Z = X;
            % 2020.4.23 实际写下面2行的话，待整个yolov3网络predict时候报错！！！故移到外面写
%             Z = X.reshape(layer.numY,layer.numX,layer.nAnchors,(5+layer.nClasses),bs);
%             Z = permute(Z,[5,3,1,2,4]);% 输出特征图，Z=bs*na*h*w*(5+nc),
         end

    end
end


addpath(genpath('D:\GitHub\KiloSort2')) % path to kilosort folder
addpath('D:\GitHub\npy-matlab')

pathToYourConfigFile = 'D:\GitHub\KiloSort2\configFiles'; % take from Github folder and put it somewhere else (together with the master_file)
run(fullfile(pathToYourConfigFile, 'configFileBench384.m'))

% common options for every probe
% ops.chanMap     = 'D:\GitHub\KiloSort2\configFiles\neuropixPhase3A_kilosortChanMap_385.mat';
ops.chanMap = 'H:\DATA\Spikes\Bekesy\neuropixPhase3B1_kilosortChanMap.mat';
ops.trange      = [0 Inf]; % TIME RANGE IN SECONDS TO PROCESS

 % these settings overwrite any settings from config
ops.Th       = [10 10];     % threshold on projections (like in Kilosort1)
ops.lam      = 40^2;   % weighting on the amplitude penalty (like in Kilosort1, but it has to be much larger)

ops.ThS      = [8 8];  % lower bound on acceptable single spike quality
ops.momentum = [20 400]; % number of samples to average over
ops.minFR    = 1/50; % minimum spike rate (Hz)

ops.sigmaMask  = 30;

ops.Nfilt       = 1024; % max number of clusters
ops.nfullpasses = 3; % how many forward backward passes to do
ops.nPCs        = 3; % how many PCs to project the spikes into

ops.useRAM = 0;
ops.ccsplit = .99;
ops.NchanTOT = 385;
ops.nPCs = 3;

% rootZ = 'D:\DATA\ALLEN\mouse366119\probeC_2018-03-02_15-18-32_SN619041624\experiment1\recording1\continuous\Neuropix-120.0\';
% rootZ = 'H:\DATA\Spikes\Robbins\ZNP1';
rootZ = 'H:\DATA\Spikes\Bekesy';
rootH = 'H:\DATA\Spikes\temp\';

fs = dir(fullfile(rootZ, '*.bin'));

fname = fs(1).name;

ops.fbinary     = fullfile(rootZ,  fname);
ops.fproc       = fullfile(rootH, 'temp_wh.dat'); % residual from RAM of preprocessed data

%%
% preprocess data
rez = preprocessDataSub(ops);

rez.ops.NchanTOT

rez.iorig = 1:rez.temp.Nbatch;

% fname = fullfile(rootZ, 'rez.mat');
% save(fname, 'rez');
%%

% clusterSingleBatches;
clusterSingleBatches;

% figure(191);
% imagesc(rez.ccb(rez.iorig, rez.iorig), [20 100])
%%
rez = learnAndSolve8(rez);

rez2    = splitAllClusters(rez);

rezToPhy(rez2, rootZ);


function test_issue922

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

%test case for ft_freqanalysis rounding bug

load(dccnpath('/home/common/matlab/fieldtrip/data/test/issue922.mat'));
[freq] = ft_freqanalysis(cfg, test);


function airway_tree = PTKCloseBranchesInTree(airway_tree, closing_size_mm, image_size, reporting)
    % PTKCloseBranchesInTree. Takes a segmented airway tree and
    %     performs a morphological closing on each segment, and between each segment
    %     and its child segments.
    %
    % This function is used by PTKAirwayRegionGrowingWithExplosionControl.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD Pulmonary Toolkit. https://github.com/tomdoel/pulmonarytoolkit
    %     Author: Tom Doel, 2012.  www.tomdoel.com
    %     Distributed under the GNU GPL v3 licence. Please see website for details.
    %

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

    number_of_segments = airway_tree.CountBranches;

    reporting.ShowProgress('Closing branches in the airway tree');
    segments_to_do = airway_tree;
    segment_index = 0;

    while ~isempty(segments_to_do)
        segment = segments_to_do(end);
        segments_to_do(end) = [];
        segments_to_do = [segments_to_do, segment.Children];

        if ~isempty(reporting)
            if reporting.HasBeenCancelled
                reporting.Error(CoreReporting.CancelErrorId, 'User cancelled');
            end

            progress_value = round(100*(segment_index/number_of_segments));
            reporting.UpdateProgressValue(progress_value);
        end
        segment_index = segment_index + 1;

        CloseSegment(segment, closing_size_mm, image_size);
    end
end

function CloseSegment(segment, closing_size_mm, image_size)
    voxel_indices = segment.GetAcceptedVoxels;

    if ~isempty(voxel_indices)
        all_points = GetClosedIndicesForSegmentAndChildren(segment, closing_size_mm, image_size);
        new_points = setdiff(all_points, voxel_indices);
        segment.AddClosedPoints(unique(new_points));
    end
end

function result_points = GetClosedIndicesForSegmentAndChildren(current_segment, closing_size_mm, image_size)
    segment_indices = current_segment.GetAcceptedVoxels;
    if isempty(current_segment.Children)
        result_points = GetClosedIndices(segment_indices, closing_size_mm, image_size);
    else
        result_points = [];
        for child_segment  = current_segment.Children
            child_indices = child_segment.GetAcceptedVoxels;
            all_indices = [segment_indices; child_indices];
            new_points_all = GetClosedIndices(all_indices, closing_size_mm, image_size);
            new_points_children = GetClosedIndices(child_indices, closing_size_mm, image_size);

            new_points = setdiff(new_points_all, new_points_children);
            result_points = [result_points; new_points];
        end
    end
    result_points = unique(result_points);
end

function new_points = GetClosedIndices(voxel_indices, closing_size_mm, image_size)
    [offset, segment_image, ~] = MimImageCoordinateUtilities.GetMinimalImageForIndices(voxel_indices', image_size);
    border_size = 3;
    bordered_segment_image = PTKImage(segment_image);
    bordered_segment_image.AddBorder(border_size);
    bordered_segment_image.BinaryMorph(@imclose, closing_size_mm);

    border_offset = border_size;
    bordered_image_size = bordered_segment_image.ImageSize;
    all_points = find(bordered_segment_image.RawImage(:));
    new_points = MimImageCoordinateUtilities.OffsetIndices(int32(all_points), -border_offset + int32(offset), int32(bordered_image_size), int32(image_size));
end


function [ boxlayout,surface_labels ] = getspatiallayout(imdir,imagename,workspcdir)
% GETSPATIALLAYOUT Given an image, estimate its spatial layout, consisting
%   of a boxlayout and pixel labels of different surfaces. Please refer to
%   the readme file provided with this software for detailed meaning of
%   these outputs.
%
% USAGE: [ boxlayout,surface_labels ] =
%               getspatiallayout(imdir,imagename,workspcdir)
%
% INPUT:
%   imdir - directory containing the original image to be processed. Use '/'
%       (not '\') to separate directories.
%   imagename - original image name
%   workspcdir - directory to hold intermediate results. Internally, two
%       independent directories are created inside this directory to hold
%       visualizations and data files.
%
% OUTPUT:
%   binlayout - structure containing the estimated approximation of the
%       indoor scene as a 3D box, with the following fields -
%   .polyg - cell array of size (n x 5), each containing coordinates of
%       planar surfaces of the room (left, right, middle walls, and, floor
%       and ceiling). The (i,j)-th cell entry corresponds to i-th box
%       layout hypothesis, and j-th plane of that hypothesis.
%   .init - An array of size (n x 2). The i-th row (score,index) represents
%       score and index of a hypothesis in the polyg cell array above, as
%       estimated by our algorithm.
%   .reestimated - An array of size (n x 2). The i-th row (score,index) represents
%       score and index of a hypothesis in the polyg cell array above, as
%       estimated by the second iteration of our algorithm.
%   surface_labels - structure containing the per pixel likelihood of each of
%       the surfaces, and objects, with following fields -
%   .init - An array of size (m x 7), where m is th total number of
%       superpixels detected in the image. The (i,j)-th entry represents
%       the likelihood of the i-th superpixel being labeled as j-th
%       surface.
%
% Copyright (c) Varsha Hedau, University of Illinois at Urbana Champaign,
% 2011.
% To use this code or any part of the package, for any purpose, you agree
% to abide by the restrictions set forth in the file Readme.txt

outimgdir = [workspcdir 'Images/'];
if ~exist(outimgdir,'dir')
    mkdir(outimgdir);
end
workspcdir = [workspcdir 'data/'];
if ~exist(workspcdir,'dir')
    mkdir(workspcdir);
end

% tempdir='./sptiallayouttempworkspace/';
%Compute vps
boxlayout=[];
surface_labels=[];

[vp p All_lines]=getVP(imdir,imagename,0,workspcdir);

img=imread([imdir imagename]);
[h w kk]=size(img);
VP=vp;
if numel(VP)<6
    return;
end

vp=[VP(1) VP(2);VP(3) VP(4);VP(5) VP(6)];
[vp P]=ordervp(vp,h,w,p);
[vv linemem]=max(P,[],2);
vpdata.vp=vp;
vpdata.lines=All_lines;
vpdata.linemem=linemem;
vpdata.dim=[h w];
%visvp(vpdata,img)
%Get segmentation and GC surface confidence maps
% sigma=num2str(0.8);
% k1=num2str(100);
% min1=num2str(100);
% inputim=[workspcdir imagename(1:end-4) '.ppm'];
% outputim=[workspcdir imagename(1:end-4) '.pnm'];
% [s w]=system(['./segment' ' ' sigma ' '  k1  ' ' min1 ' ' inputim ' ' outputim ]);

segext='pnm';
nsegments=[5 15 25 35 40 60 80 100];
fn=['../Imsegs/' imagename(1:end-4) '.' segext];
imseg = processSuperpixelImage(fn);

tic
imdata = mcmcComputeImageData(im2double(img), imseg);% made changes here
toc

load(fullfile('../LabelClassifier/', 'Classifiers_gc.mat'));

spfeatures = mcmcGetAllSuperpixelData(imdir, imseg);
[efeatures, adjlist] = mcmcGetAllEdgeData(spfeatures, imseg(1));

nsegments=[5 15 25 35 40 60 80 100];

pE{1} = test_boosted_dt_mc(eclassifier, efeatures{1});
pE{1} = 1 ./ (1+exp(ecal(1)*pE{1}+ecal(2)));
smaps{1} = msCreateMultipleSegmentations(pE{1}, adjlist{1}, ...
    imseg(1).nseg, nsegments);

for k = 1:numel(nsegments)
    if max(smaps{1}(:, k))>0
        segfeatures{1, k} = mcmcGetSegmentFeatures(imseg, ...
            spfeatures{1}, imdata, smaps{1}(:, k), (1:max(smaps{1}(:, k))));
    end
end

%Get surface label confidences initial from GC
normalize = 1;
pg=zeros(imseg.nseg,7);%7 labels
%get P(L/I)
pg = msTest(imseg, segfeatures, smaps, ...
    labelclassifier, segclassifier,normalize);

filename=fullfile(workspcdir, [imagename(1:end-4) '_lc_gc.mat' ]);
save(filename,'pg');

%visualize

%Compute intergral images for features
tic
[integData]=getIntegralimages([imagename],vpdata,imseg,500,workspcdir,imdir);
toc

%Get candidate layouts and their features
[polyg, Features] = getcandboxlayout( vpdata.vp,vpdata.dim(1),vpdata.dim(2),integData);

%Get initial estimate
Features1=Features;

load ../LearntClassifiers/pf_i.mat

lay_score=[];
numL=size(Features,1);
% change features
if(numel(weights)==14)
    tmpf1=sum(Features(:,1:5).*Features(:,11:15),2);
    tmpf2=sum(Features(:,1:5).*Features(:,16:20),2);
    tmpf3=sum(Features(:,6:10).*Features(:,11:15),2);
    tmpf4=sum(Features(:,6:10).*Features(:,16:20),2);
    Features=[Features(:,1:10) tmpf1 tmpf2 tmpf3 tmpf4];

end
%evaluate
score=repmat(weights,[numL,1]).*Features;
score=sum(score,2);
[vv ii]=sort(score,'descend');

boxlayout.polyg=polyg;
boxlayout.init=[vv ii];

load ../LearntClassifiers/pf_il.mat
Features=Features1;
if(numel(weights)==59)
    tmpf1=sum(Features(:,1:5).*Features(:,11:15),2);
    tmpf2=sum(Features(:,1:5).*Features(:,16:20),2);
    tmpf3=sum(Features(:,6:10).*Features(:,11:15),2);
    tmpf4=sum(Features(:,6:10).*Features(:,16:20),2);
    Features=[Features(:,1:10) tmpf1 tmpf2 tmpf3 tmpf4 Features(:,31:75) ];%Features(:,114:122)];

end
score=repmat(weights,[numL,1]).*Features;
score=sum(score,2);
[vv ii]=sort(score,'descend');

boxlayout.reestimated=[vv ii];

lay_scores=[vv ii];
save([workspcdir imagename(1:end-4) '_layres.mat'],'polyg','lay_scores');%,'avg_pg');

% figure(101);
% drawnow;
% for lay=1:25
%     layoutid=ii(lay);
%     Polyg=[];
%     for fie=1:5
%         Polyg{fie}=[];
%         if size(polyg{layoutid,fie})>0
%             Polyg{fie}=polyg{layoutid,fie};
%         end
%     end
%
%     tempimg=displayout(Polyg,w,h,img);
%     subplot(5,5,lay);imshow(uint8(tempimg),[]);title(num2str(vv(lay)));
% end
% saveas(101,[outimgdir imagename(1:end-4) '_boxlayouts.png']);
%
% Polyg=[];
% for fie=1:5
%     Polyg{fie}=[];
%     if size(polyg{ii(1),fie})>0
%         Polyg{fie}=polyg{ii(1),fie};
%     end
% end
% ShowGTPolyg(img,Polyg,103);
% saveas(103,[outimgdir imagename(1:end-4) '_boxlayout.png']);

%Re-Compute Surface labels (GC+box layout features)
load(['../LabelClassifier/' 'Classifiers_stage2.mat']);
tic
xspfields=[];%save per image
numSup=imseg.nseg;
for lay=1:numL %each layout
    xspf=[];
    for  supno=1:numSup
        tempbndy=imdata.tracedbndy{supno}{1};
        if size(tempbndy,1) > 30

            YY1=tempbndy(1:10:end,1);XX1=tempbndy(1:10:end,2);
        else

            YY1=tempbndy(:,1);XX1=tempbndy(:,2);
        end

        for fi=1:5  %each field
            xarea=0;
            if size(polyg{lay,fi},1)>0

                XX2=polyg{lay,fi}(:,1);
                YY2=polyg{lay,fi}(:,2);

                [in on]=inpolygon(XX1,YY1,[XX2;XX2(1)],[YY2;YY2(1)]);

                if numel(find(in==1))==length(in)
                    X0=XX1;Y0=YY1;
                    xarea=polyarea([X0;X0(1)],[Y0;Y0(1)]);
                elseif  numel(find(in==1))==0

                    X0=[];Y0=[];
                    xarea=0;
                else
                    xarea=polyintarea(XX1,YY1,XX2,YY2,0);

                end

            end
            xspf(supno,fi)=xarea;
        end

    end
    xspfields{lay}=xspf;
end
toc

nsp=imseg.nseg; %num of suppixels
smap = [1:nsp];
smaps{1} = smap(:);

clear segfeatures
for k = 1: 1%numel(nsegments)
    features = mcmcGetSegmentFeatures(imseg, ...
        spfeatures{1}, imdata, smaps{1}(:, k), (1:max(smaps{1}(:, k))));

    for lay=1:numL
        tempfeatures=features;
        [fieldfeatures]=segfieldsfeat_sup(imseg,imseg.nseg,smaps{1}(:,k),xspfields{lay});
        tempfeatures(:,95:100)=fieldfeatures(1:size(features,1),:);
        tempfeatures(:,101:106)=pg{1}(:,1:6);
        segfeatures{lay,k}  = tempfeatures;
    end
end

if numel(vv)>100
    A = [vv(1) 1;vv(100) 1];
else
    A = [vv(1) 1;vv(end) 1];
end
b = [0;log(49)];
params = inv(A)*b;

%     conf = 1./(1+exp(params(1)*vv(1:5)+params(2)));
conf = 1./(1+exp(params(1)*vv(1)+params(2)));
conf=conf./sum(conf);

avg_pg=zeros(imseg.nseg,7);%7 labels

tic
for j=1:1 %take best 5 scored layouts
    lay=ii(j);

    %get P(L/F,I)
    pg = msTest(imseg, segfeatures(lay, :), smaps, ...
        labelclassifier);%, segclassifier,normalize);
    avg_pg=avg_pg+pg{1}.*conf(j);

end
toc

filename=fullfile(workspcdir,[imagename(1:end-4) '_lc_st2.mat' ]);
save(filename,'avg_pg');

surface_labels.restimated={avg_pg};
surface_labels.init=pg;

rl=[255  255 0  0 0 255 0];
gl=[255 0 255  255 0 0 0];
bl=[0  0 255 0 255 255 0];
rl1=[255 202 132 255 0 255 0 191 0 0];
gl1=[236 255 112 255 191 0 255 21 0 0];
bl1=[139 112 255  255 255 0 0 133 255 0];
cimages = msPg2confidenceImages(imseg,{avg_pg});
[aa indd]=max(cimages{1}(:,:,1:6),[],3);

figure(102);
clear mask_color;
mask_r = rl(indd);
mask_g = gl(indd);
mask_b = bl(indd);
mask_color(:,:,1) = mask_r;
mask_color(:,:,2) = mask_g;
mask_color(:,:,3) = mask_b;

hsvmask=rgb2hsv(mask_color);
hsvmask(:,:,3)=aa*255;
%     hsvmask(:,:,2)=aa;
mask_color=hsv2rgb(hsvmask);

tempimg = double(img)*0.5 + mask_color*0.5;
%         tempimg =  mask_color;
imshow(uint8(tempimg));
saveas(102,[outimgdir imagename(1:end-4) '_surfacelabels.png']);

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spherical Harmonic Modeling and Analysis Toolkit (SPHARM-MAT) is a 3D
% shape modeling and analysis toolkit.
% It is a software package developed at Shenlab in Center for Neuroimaging,
% Indiana University (SpharmMat@gmail.com, http://www.iupui.edu/~shenlab/)
% It is available to the scientific community as copyright freeware
% under the terms of the GNU General Public Licence.
%
% Copyright 2009, 2010, ShenLab, Center for Neuroimaging, Indiana University
%
% This file is part of SPHARM-MAT.
%
% SPHARM-MAT 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.
%
% SPHARM-MAT 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 SPHARM-MAT. If not, see <http://www.gnu.org/licenses/>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%
%
%

function write_metaNcoef(filename, confs)

load(filename);

if ~exist('faces', 'var') | ~exist('vertices', 'var') | ~exist('fvec', 'var')
    disp('One or more of faces, vertices, and SPHARM coefficients are missing');
    return;
end

[fvec] = read_coef(coef);

[pa, na, ex]=fileparts(filename);

type = size(faces,2);
filename1 = sprintf('%s/%s_surfSPHARM.meta', confs.OutDirectory, na(1:end-4));
filename2 = sprintf('%s/%s_surfSPHARM.coef', confs.OutDirectory, na(1:end-4));

if exist(filename1,'file') & exist(filename2,'file')
    prompt = {'Enter new filenames:'};
    dlg_title = 'New File Names';
    num_lines = 2;
    def = {filename1; filename2};
    answer = inputdlg(prompt,dlg_title,num_lines,def);
    filename1 = answer{1};
    filename2 = answer{2};
end

% Write a meta file
if type == 3
    disp('This function does not support any objects in the general triangular mesh now');
elseif type == 4
    write_meta_quad(filename1, vertices, faces);
%    write_meta_quad(filename2, sph_verts, faces);
end

% Write a coef file
write_coef(filename2, fvec);

return;


classdef CatalogExplorationPlot < handle
    % CATALOGEXPLORATIONPLOT create a plot where x,y,z,color, and size are modifiable
    properties
        x_by (1,:)      char
        y_by (1,:)      char
        z_by (1,:)      char
        color_by (1,:)  char            = ZmapGlobal.Data.mainmap_plotby%'Date'
        size_by (1,:)   char            ='Magnitude'
        colorFcn        function_handle = @datenum
        sizeFcn         function_handle = @mag2dotsize
        catalogFcn      function_handle;
        axes_choices    cell            = {};
        myscatter;
        ax              matlab.graphics.axis.Axes;
        conversions;
        curview;
        marker                          = ZmapGlobal.Data.event_marker;
    end
    methods

        function obj=CatalogExplorationPlot(ax, catalogFcn)
            % creates a plot with arbitrarily modifiable axes
            % obj=CATALOGEXPLORATIONPLOT(ax, catalogFcn)
            mycat = catalogFcn();
            obj.x_by = mycat.XLabel;
            obj.y_by = mycat.YLabel;
            obj.z_by = mycat.ZLabel;
            obj.catalogFcn = catalogFcn;
            obj.set_valid_axes_choices();
            obj.set_conversions();
            obj.ax=ax;
            c=ax.UIContextMenu;
            if isempty(c)
                c=uicontextmenu(ancestor(ax,'figure'),'Tag','catexplot');
                addLegendToggleContextMenuItem(c,'top','below');
                ax.UIContextMenu=c;
            else
                addLegendToggleContextMenuItem(c,'top','below');
            end
        end

        function scatter(obj, tag, varargin)
            % scatter plot with interactive axes
            c=obj.catalogFcn();
            x=c.(obj.x_by);
            y=c.(obj.y_by);
            z=c.(obj.z_by);
            s=c.(obj.size_by);
            if ~iscategorical(s)
                s=obj.sizeFcn(s);
            end
            if obj.color_by == "-none-"
                cl=[0 0 0];
            else
                cl=c.(obj.color_by);
                if ~iscategorical(cl)
                    cl=obj.colorFcn(cl);
                end
            end
            % delete(findobj(obj.ax,'Tag',tag));
            if isempty(obj.myscatter)
                obj.myscatter=scatter3(obj.ax,x, y, z, s, cl,'Marker',obj.marker,'Tag',tag);
                obj.myscatter.DisplayName=sprintf('size:%s\ncolor:%s',obj.size_by,obj.color_by);
                grid(obj.ax,'on');
                box(obj.ax,'on');
                fig=ancestor(obj.ax,'figure');
                xl = xlabel(obj.x_by,'interpreter','none');
                yl = ylabel(obj.y_by,'interpreter','none');
                zl = zlabel(obj.z_by,'interpreter','none');
                obj.xContextMenu(xl, tag, fig);
                obj.yContextMenu(yl, tag, fig);
                obj.zContextMenu(zl, tag, fig);
                obj.scatterContextMenu(obj.myscatter, tag);
                obj.ax.UserData.cep = obj;
            else
                obj.ax.NextPlot='replace';
                obj.myscatter.XData=x;
                obj.myscatter.YData=y;
                obj.myscatter.ZData=z;
                obj.myscatter.SizeData=s;
                obj.myscatter.CData=cl;
                obj.myscatter.DisplayName=sprintf('size:%s\ncolor:%s',obj.size_by,obj.color_by);
            end
            if isempty(obj.curview)
                view(obj.ax,2);
            else
                view(obj.ax,obj.curview);
            end

        end

        function update(obj, specific)
            % UPDATE updates the scatter plot, optionally changing only one axis (or color or size)
            %
            % obj.update() update all aspects of the scatter plot
            %
            % obj.update( SPECIFIC ) updates only thes specific part of the plot, where SPECIFIC can
            % be 'x_by', 'y_by', 'z_by', 'size_by', 'sin
            %
            c=obj.catalogFcn();
            [obj.curview(1), obj.curview(2)] = view(obj.ax);
            if ~exist('specific','var')
                switch obj.color_by
                    case '-none-'
                        cdata=obj.colorFcn(1);
                        if ~isequal(size(cdata),[1,3])
                            cdata = [0 0 0];
                        end
                    case 'MagnitudeType'
                        cdata= c.(obj.color_by);
                        set(obj.myscatter,'CData',cdata);
                        cc = categories(cdata);
                        ncats = numel(cc);
                        colormap(obj.ax, lines(ncats) );
                        centers = linspace(1.5, ncats - 0.5, ncats);
                        colorbar('Limits',[1,ncats],...
                            'Ytick', centers,...
                            'YtickLabel', cc)
                    otherwise
                        cdata= obj.colorFcn(c.(obj.color_by));

                end
                switch obj.size_by
                    case 'Single Size'
                        sdata=obj.sizeFcn(1);
                    case 'MagnitudeType'
                        sdata=c.(obj.size_by);
                    otherwise
                        sdata=obj.sizeFcn(c.(obj.size_by));
                end
                set( obj.myscatter,...
                    'XData', c.(obj.x_by),...
                    'YData', c.(obj.y_by),...
                    'ZData', c.(obj.z_by),...
                    'SizeData',sdata,...
                    'CData',cdata...
                    );
            else
                switch specific
                    case 'x_by'
                        doit('XAxis','XData', obj.x_by);
                    case 'y_by'
                        doit('YAxis','YData', obj.y_by);
                    case 'z_by'
                        doit('ZAxis','ZData', obj.z_by);
                    case 'size_by'
                        switch obj.size_by
                            case 'Single Size'
                                set(obj.myscatter,'SizeData',obj.sizeFcn(1));
                    case 'MagnitudeType'
                                set(obj.myscatter,'SizeData',c.(obj.size_by));
                            otherwise
                                set(obj.myscatter,'SizeData',obj.sizeFcn(c.(obj.size_by)));
                        end
                    case 'color_by'
                        switch obj.color_by
                            case '-none-'
                                set(obj.myscatter,'CData',obj.colorFcn(1));
                            case 'MagnitudeType'
                                cdata= c.(obj.color_by);
                                set(obj.myscatter,'CData',cdata);
                                cc = categories(cdata);
                                ncats = numel(cc);
                                colormap(obj.ax, lines(ncats) );
                                centers = linspace(1.5, ncats - 0.5, ncats);
                                colorbar('Limits',[1,ncats],...
                                    'Ytick', centers,...
                                    'YtickLabel', cc)
                            otherwise
                                set(obj.myscatter,'CData',obj.colorFcn(c.(obj.color_by)));
                        end

                end
            end
            %{
            function val = use_correct_ruler(obj, axisName, val)
                switch class(val)
                    case 'datetime'
                        if ~isa(obj.ax.(axisName),'matlab.graphics.axis.decorator.DatetimeRuler')
                            set(obj.ax, axisName, matlab.graphics.axis.decorator.DatetimeRuler);
                        end
                    case 'duration'
                        if ~isa(obj.ax.(axisName),'matlab.graphics.axis.decorator.DurationRuler')
                            set(obj.ax, axisName, matlab.graphics.axis.decorator.DurationRuler);
                        end
                    case 'categorical'
                        if ~isa(obj.ax.(axisName),'matlab.graphics.axis.decorator.CategoricalRuler')
                            set(obj.ax, axisName, matlab.graphics.axis.decorator.CategoricalRuler);
                        end
                    otherwise % numeric
                        if ~isa(obj.ax.(axisName),'matlab.graphics.axis.decorator.NumericRuler')
                            set(obj.ax, axisName, matlab.graphics.axis.decorator.NumericRuler);
                        end
                end
            end
            %}
            function doit(axAx, where, fld)
                % doit(axAx, where, fld) poor name.
                % axAx: 'XAxis', etc...
                % where: 'XData', etc...
                % fld: 'Longitude', etc... which is the result of obj.x_by, etc...
                % axisH = obj.ax.(axAx);
                    enforce_linear_scale_if_necessary();
                    try
                        obj.myscatter.(where) = c.(fld);
                        axruler=obj.ax.(axAx);
                        assert(...
                            (isnumeric(c.fld) &&  isa(axruler,'matlab.graphics.axis.decorator.NumericRuler')) || ...
                            (isdatetime(c.fld) && isa(axruler,'matlab.graphics.axis.decorator.DatetimeRuler')) || ...
                            (iscategorical(c.fld) && isa(axruler,'matlab.graphics.axis.decorator.CategoricalRuler')) ||...
                            (isduration(c.fld) && isa(axruler,'matlab.graphics.axis.decorator.DurationRuler'))...
                            );

                    catch
                        % unable to reuse existing axes rulers. Since they are read-only, we'll have
                        % to recreate.  However, first stash some information that will be lost, so
                        % that the figure appears to only change instead of being recreated.

                        % what is this scatter plot called again?
                        t=obj.myscatter.Tag;
                        ttl=get(obj.ax.Title);
                        % what is the state of the legend?
                        reshowLegend= ~isempty(obj.ax.Legend) && obj.ax.Legend.Visible =="on";
                        if reshowLegend
                            legendLocation = obj.ax.Legend.Location;
                        end

                        % recreate the axes and scatter plot
                        cla(obj.ax);
                        obj.myscatter=[];
                        obj.scatter(t);

                        obj.ax.Title.String=ttl.String;
                        obj.ax.Title.Color=ttl.Color;
                        obj.ax.Title.FontSize=ttl.FontSize;
                        obj.ax.Title.FontName=ttl.FontName;
                        obj.ax.Title.FontWeight=ttl.FontWeight;

                        % restore the legend
                        if reshowLegend
                            legend(obj.ax,'show','Location',legendLocation);
                        end
                    end

                %end

                function enforce_linear_scale_if_necessary()
                    xyzscale=[where(1) 'Scale'];
                    if obj.ax.(xyzscale)=="linear"
                        return
                    end

                    if iscell(c.(fld)) || iscategorical(c.(fld))
                        beep;
                        disp(['enforcing linear ' xyzscale ' because of data type']);
                        obj.ax.(xyzscale)='linear';
                    elseif isnumeric(c.(fld))&&any(c.(fld)<=0) && obj.ax.(xyzscale) == "log"
                        beep;
                        disp(['enforcing linear ' xyzscale ' because of negative values']);
                        obj.ax.(xyzscale)='linear';
                    end
                end

                function [n, scalename] = duration2numbers(d)
                    % put the duration on a reasonable scale
                    persistent logic
                    if isempty(logicparts)
                        % do change how durations are displayed, change this table
                        logictable={... scalename , converterFcn , minValue
                            'years', @years, years(4);
                            'months',@months, months(6);
                            'days',  @days, days(5);
                            'hours', @hours, hours(3);
                            'minutes', @minutes, minutes(2);
                            'seconds', @seconds, seconds(-inf)};

                        logic = cell2struct(logictable,{'name','fn','minval'},2);
                    end
                    idx = 1;
                    mymax = max(d);

                    % min_dur gives us the minimum duration value based on the index

                    while mymax < logic(idx).minval
                        idx = idx + 1;
                    end

                    scalename = logic(idx).name;
                    n = logic(idx).fn(d);
                end

            end % DOIT
        end

    end
    methods(Hidden)

        function set_valid_axes_choices(obj)
            c=obj.catalogFcn();
            p = properties(c);
            usable=true(size(p));
            nEvents=  c.Count;
            for i=1:numel(p)
                try
                    usable(i)=length(c.(p{i}))==nEvents;
                catch
                    usable(i)=false;
                end
                try
                    if all(isnan(c.(p{i})))
                        usable(i)=false;
                    end
                end
            end
            obj.axes_choices=p(usable);
        end

        function set_conversions(obj)
            for j=1:numel(obj.axes_choices)
                ch=obj.axes_choices{j};
            end

        end

        function updateCheckedStatus(obj,h, checkmask)
            labels = {h.Children.Label};
            choices=string(obj.axes_choices);
            for j=1:numel(h.Children)
                whichChoice = labels(j) == choices;
                set(h.Children(whichChoice), 'Checked', tf2onoff(checkmask(whichChoice)) );
            end
        end

        function xContextMenu(obj,xl, tag, fig)
            %delete(findobj(ancestor(ax),['xsel_ctxt' tag]));
            h=xl.UIContextMenu;
            checkmask = strcmp(obj.axes_choices, obj.x_by);
            if isempty(h)
                mytag = ['xsel_ctxt ' tag];
                delete(findobj(fig,'Type','uicontextmenu','-and','Tag',mytag));
                h=uicontextmenu('Tag',mytag);
                for i=1:numel(obj.axes_choices)
                    uimenu(h,'Label',obj.axes_choices{i}, 'MenuSelectedFcn', @(s,~)obj.change(s,'x_by'));
                end
                obj.add_axes_toggles(h,'X');
                xl.UIContextMenu=h;
            end
            obj.updateCheckedStatus(h, checkmask);
        end

        function yContextMenu(obj,yl,tag, fig)
            h=yl.UIContextMenu;
            checkmask = strcmp(obj.axes_choices, obj.y_by);
            if isempty(h)
                mytag = ['ysel_ctxt ' tag];
                delete(findobj(fig,'Type','uicontextmenu','-and','Tag',mytag));
                h=uicontextmenu('Tag',mytag);
                for i=1:numel(obj.axes_choices)
                    uimenu(h,'Label',obj.axes_choices{i},'MenuSelectedFcn',@(s,~)obj.change(s,'y_by'));
                end
                obj.add_axes_toggles(h,'Y');
                yl.UIContextMenu=h;
            end
            obj.updateCheckedStatus(h, checkmask);
        end

        function zContextMenu(obj,zl,tag, fig)
            h=zl.UIContextMenu;
            checkmask = strcmp(obj.axes_choices, obj.z_by);
            if isempty(h)
                mytag = ['zsel_ctxt ' tag];
                delete(findobj(fig,'Type','uicontextmenu','-and','Tag',mytag));
                h=uicontextmenu('Tag',mytag);
                for i=1:numel(obj.axes_choices)
                    uimenu(h,'Label',obj.axes_choices{i}, 'MenuSelectedFcn', @(s,v)obj.change(s,v,'z_by'));
                end
                obj.add_axes_toggles(h,'Z');
                zl.UIContextMenu=h;
            end
            obj.updateCheckedStatus(h, checkmask);
        end

        function scatterContextMenu(obj,sc,tag)
            tag=['ssel_ctxt ' tag];
            f = ancestor(obj.ax,'figure');
            delete(findobj(f,'Tag',tag));
            h=uicontextmenu(f,'Tag',tag);
            szm = uimenu(h,'Label','Size by...',...
                'MenuSelectedFcn', @(src,~)obj.cleanChildren_cb(src, 'size_by'));
            clm = uimenu(h,'Label','Color by...',...
                'MenuSelectedFcn', @(src,~)obj.cleanChildren_cb(src, 'color_by'));
            obj.sizeContextMenu(szm);
            obj.colorContextMenu(clm);
            sc.UIContextMenu=h;
        end
        function cleanChildren_cb(obj,src,bywhat)
            m=findobj(src.Children,'Type','uimenu');
            labels = get(m,'Label');
            ison = get(m,'Checked') == "on";
            isoff = ~ison;
            checkmask = strcmp(labels, obj.(bywhat));
            disp(labels{checkmask})
            set(m(~checkmask & ison),'Checked','off');
            set(m(checkmask & isoff),'Checked','on');
        end

        function sizeContextMenu(obj,h)
            for i=1:numel(obj.axes_choices)
                uimenu(h,'Label',obj.axes_choices{i},'MenuSelectedFcn',@obj.changeSize);
            end
            uimenu(h,'Separator','on','Label','Single Size','MenuSelectedFcn',@obj.changeSize);

        end

        function colorContextMenu(obj,h)
            for i=1:numel(obj.axes_choices)
                uimenu(h,'Label',obj.axes_choices{i},'MenuSelectedFcn',@obj.changeColor);
            end
            uimenu(h,'Separator','on','Label','-none-','MenuSelectedFcn',@obj.changeColor);
        end

        function add_axes_toggles(obj,h,letter)
            uimenu(h,'Label','Flip axes direction','Separator','on',...
                'MenuSelectedFcn',@(src,~)cb_axisdir(letter));
            uimenu(h,'Label','Toggle Log/Linear scale','Separator','on',...
                'MenuSelectedFcn',@(src,~)cb_axisscale(letter));

            function cb_axisdir(letter)
                dirs={'normal','reverse'};
                prop=[letter 'Dir'];
                dirs(strcmp(obj.ax.(prop),dirs))=[];
                obj.ax.(prop) = dirs{1};
            end

            function cb_axisscale(letter)
                scales={'linear','log'};
                prop=[letter 'Scale'];

                scales(strcmp(obj.ax.(prop),scales))=[];

                % if any data is non-positive, axes must remain linear
                if any(obj.myscatter.([letter 'Data']) <=0) && scales{1} == "log"
                    beep
                    disp(['enforcing linear ' prop ' because of negative values'])
                    obj.ax.(prop) = 'linear';
                else
                    obj.ax.(prop) = scales{1};
                end
            end
        end
        function change(obj,src,whatby)
            % whatby is x_by, y_by, etc...

            % remove checkmarks
            set(src.Parent.Children,'Checked','off');

            % change the plotting value
            obj.(whatby) = src.Label;

            % add new checkmark
            src.Checked='on';

            % relabel
            obj.ax.([upper(whatby(1)), 'Label']).String=src.Label;
            %h.String=src.Label;

            %replot
            obj.update(whatby);
        end

        function changeSize(obj,src,~)
            % whatby is x_by, y_by, etc...

            % change the plotting value
            obj.size_by= src.Label;

            % relabel
            set(gco,'DisplayName',sprintf('size:%s\ncolor:%s', obj.size_by, obj.color_by));
            switch(obj.size_by)
                case 'Date'
                    obj.sizeFcn=@(x) normalize(x,2,8,@(x)x.^2 );
                case 'Magnitude'
                    obj.sizeFcn=@mag2dotsize;
                case 'Single Size'
                    sz=num2str(round(mode(obj.myscatter.SizeData)));
                    val = str2double(inputdlg('Choose Marker Size','',1,{sz}));
                    if ~isempty(val) && ~isnan(val)
                        obj.sizeFcn=@(x)val;
                    end
                otherwise
                    obj.sizeFcn=@(x) normalize(x,2,8,@(x)x.^2);
            end
            %replot
            obj.update('size_by');

            function x=normalize(x, minval, scalar, modifier)
                if isa(x,'datetime')
                    x=x - min(x); % now duration
                end
                if isa(x,'duration')
                    x=days(x);
                end
                x = (x-min(x)) ./ range(x);
                x = modifier(x .* scalar + minval);
            end

        end
        function changeColor(obj,src,~)
            % whatby is x_by, y_by, etc...

            % remove checkmarks
            set(src.Parent.Children,'Checked','off');

            % change the plotting value
            obj.color_by = src.Label;

            % add new checkmark
            src.Checked='on';

            % relabel
            set(gco,'DisplayName',sprintf('size:%s\ncolor:%s',obj.size_by,obj.color_by));
            %h.String=src.Label;

            switch(obj.color_by)
                case 'Date'
                    obj.colorFcn=@datenum;
                case '-none-'
                    val=uisetcolor();
                    obj.colorFcn=@(x)val;
                otherwise
                    obj.colorFcn=@(x) normalize(x, 0, 1,@(x)x);
            end

            function x=normalize(x, minval, scalar, modifier)
                if iscategorical(x)
                    return;
                end
                if isdatetime(x)
                    x=x - min(x); % now duration
                end
                if isduration(x)
                    x=days(x);
                end
                x = (x-min(x)) / range(x);
                x = modifier(x.* scalar + minval);
            end
            %replot
            obj.update('color_by');
        end
    end % HIDDEN methods

    methods (Static)
        function s=instructions(varargin)
            % Explore your data in 4-5 dimensions by choosing a parameter for each axis.
            % Right-click on the X, Y, or Z axes for a list of available variables.
            % Right-click on data points to choose how they will be sized or colored.
            helpwin('CatalogExplorationPlot.instructions');
        end
    end
end


%% Example
% real time control of the KUKA iiwa 7 R 800
% the impedence control is turned on
% Moving first joint of the robot, using a sinisoidal function

% An example script, it is used to show how to use the different
% functions of the KUKA Sunrise matlab toolbox

% First start the server on the KUKA iiwa controller
% Then run this script using Matlab

% Copyright: Mohammad SAFEEA, 8th of Nov 2017

% Important: Be careful when runnning the script, be sure that no human, nor obstacles
% are around the robot

close all,clear all;clc;

warning('off')

ip='172.31.1.147'; % The IP of the controller
% start a connection with the server
global t_Kuka;
t_Kuka=net_establishConnection( ip );

if ~exist('t_Kuka','var') || isempty(t_Kuka) || strcmp(t_Kuka.Status,'closed')
  warning('Connection could not be establised, script aborted');
  return;
else

      %% Get position roientation of end effector

%      jPos={0,pi/6,0,-pi/2,0,pi/2-pi/6,0};

        jPos={0,0,0,-pi/2,0,pi/2,0};
      %jPos={0,0,0,0,0,0,0};
      setBlueOff(t_Kuka); % turn Off blue light

      relVel=0.15;
      movePTPJointSpace( t_Kuka , jPos, relVel); % move to initial configuration
     %% Pause for 3 seocnds
     pause(3);
        %% Start direct servo in joint space
        massOfTool=0.5; % the mass of the tool attached to flange in Kg
        cOMx=0; % X coordinate of the center of mass of the tool in (mm)
        cOMy=0; % Y coordinate of the center of mass of the tool in (mm)
        cOMz=40; % Z coordinate of the center of mass of the tool in (mm)
        cStiness=900; % cartizian stifness
        rStifness=80; % rotational stifness
        nStifness=50; % null space stifness

        % Start the realtime control with impedence
        realTime_startImpedanceJoints(t_Kuka,massOfTool,cOMx,cOMy,cOMz,...
        cStiness,rStifness,nStifness);

       w=0.6; % motion constants, frequency rad/sec
       A=0.2; % motion constants, amplitude of motion

       a=datevec(now);
       t0=a(6)+a(5)*60+a(4)*60*60; % calculate initial time

       dt=0;
     precission=1000;
     precission_flag=true;
     tstart=t0;
     counter=0;
     duration=1*60; %1 minutes
     time_stamps=zeros(1,1000*duration);
       while(dt<duration)
         %% ferform trajectory calculation here
          a=datevec(now);
          time=a(6)+a(5)*60+a(4)*60*60;
          dt=time-t0;

          temp=A*(1-cos(w*dt));
            for dacount=1:7
                jPosCommand{dacount}=jPos{dacount}+temp;
            end
          counter=counter+1;
          %% Send joint positions to robot
          %sendJointsPositions( t ,jPos);
          sendJointsPositionsf( t_Kuka ,jPosCommand);
          time_stamps(counter)=dt;

       end
       tend=time;
       rate=counter/(tend-tstart);

       %% Stop the realtime control with impedence motion
       realTime_stopImpedanceJoints( t_Kuka );

       fprintf('\nThe rate of joint nagles update per second is: \n');
       disp(rate);
       fprintf('\n')
       pause(2);
       %% turn off light
       setBlueOff(t_Kuka);

      %% turn off the server
       net_turnOffServer( t_Kuka );

       fclose(t_Kuka);

       %% save time stamps
       save('timingdata.mat','time_stamps');

end
 warning('on')


function [mCat, mCatSmStdr] = calc_fpfitqual(mCatalog, fSm, fStdr, fUncertMin, fUncertMax)
% [mCat, mCatSmStdr] = calc_fpfitqual(mCatalog,fSm, fStdr, fUncertMin, fUncertMax)
% --------------------------------------------------------------------------------
% Create quality restricted catalog using quality parameters from FPFIT
% Reference: Oppenheimer & Reasenberg, Open-File Report 85-739, 1985
% Based on catalogs imported using ncedc_fomech_imp.m
%
% Input variables
% mCatalog   : Focal meachnism catalog
% fSm        : Maximum solution misfit
% fStdr      : Minimum station distribution ratio
% fUncertMin : Min uncertainty for strike (dip direction), rake, dip
% fUncertMax : Max uncertainty for strike (dip direction), rake, dip
%
% Output:
% mCat       : Quality catalog selected according to the input
% mCatSmStdr : Quality only selected for Stdr and SM
%
% J. Woessner, 04.2004

% Selection of solution misfit and station distribution ratio
vSel = (mCatalog(:,15) >= fStdr & mCatalog(:,13) <= fSm);
mCatSmStdr = mCatalog(vSel,:);

% Selection using the uncertainties for strike, dip and slip
vSel = (mCatSmStdr(:,17) >= fUncertMin & mCatSmStdr(:,17) < fUncertMax & mCatSmStdr(:,18) >= fUncertMin & mCatSmStdr(:,18) < fUncertMax & mCatSmStdr(:,19) >= fUncertMin & mCatSmStdr(:,19) < fUncertMax);
mCat = mCatSmStdr(vSel,:);


% eegplugin_firfilt() - EEGLAB plugin for filtering data using linear-
%                       phase FIR filters
%
% Usage:
%   >> eegplugin_firfilt(fig, trystrs, catchstrs);
%
% Inputs:
%   fig        - [integer]  EEGLAB figure
%   trystrs    - [struct] "try" strings for menu callbacks.
%   catchstrs  - [struct] "catch" strings for menu callbacks.
%
% Author: Andreas Widmann, University of Leipzig, Germany, 2005

%123456789012345678901234567890123456789012345678901234567890123456789012

% Copyright (C) 2005 Andreas Widmann, University of Leipzig, widmann@uni-leipzig.de
%
% 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

function vers = eegplugin_firfilt(fig, trystrs, catchstrs)

    vers = 'firfilt1.6.1';
    if nargin < 3
        error('eegplugin_firfilt requires 3 arguments');
    end

    % add folder to path
    % -----------------------
    if ~exist('pop_firws')
        p = which('eegplugin_firfilt');
        p = p(1:findstr(p,'eegplugin_firfilt.m')-1);
        addpath([p vers]);
    end

    % find import data menu
    % ---------------------
    menu = findobj(fig, 'tag', 'filter');

    % menu callbacks
    % --------------
    comfirfiltnew = [trystrs.no_check '[EEG LASTCOM] = pop_eegfiltnew(EEG);' catchstrs.new_and_hist];
    comfirws = [trystrs.no_check '[EEG LASTCOM] = pop_firws(EEG);' catchstrs.new_and_hist];
    comfirpm = [trystrs.no_check '[EEG LASTCOM] = pop_firpm(EEG);' catchstrs.new_and_hist];
    comfirma = [trystrs.no_check '[EEG LASTCOM] = pop_firma(EEG);' catchstrs.new_and_hist];

    % create menus if necessary
    % -------------------------
    uimenu( menu, 'Label', 'Basic FIR filter (new, default)', 'CallBack', comfirfiltnew, 'Separator', 'on', 'position', 1);
    uimenu( menu, 'Label', 'Windowed sinc FIR filter', 'CallBack', comfirws, 'position', 2);
    uimenu( menu, 'Label', 'Parks-McClellan (equiripple) FIR filter', 'CallBack', comfirpm, 'position', 3);
    uimenu( menu, 'Label', 'Moving average FIR filter', 'CallBack', comfirma, 'position', 4);


global data Ysiz d1 d2 numFrame;

%% select file
if ~exist('nam', 'var') || isempty(nam)
    % choose files manually
    try
        load .dir.mat; %load previous path
    catch
        dir_nm = [cd(), filesep]; %use the current path
    end
    [file_nm, dir_nm] = uigetfile(fullfile(dir_nm, '*.tif;*.mat;*.h5'));
    nam = [dir_nm, file_nm];  % full name of the data file
    [dir_nm, file_nm, file_type] = fileparts(nam);
else
    % use pre-specified file
    if exist(nam, 'file')
        [dir_nm, file_nm, file_type] = fileparts(nam);
    else
        dir_nm = 0;
    end
end
if dir_nm~=0
    save .dir.mat dir_nm;
else
    fprintf('no file was selected. STOP!\n');
    return;
end

%% convert the data to mat file
nam_mat = [dir_nm, filesep, file_nm, '.mat'];
if strcmpi(file_type, '.mat')
    fprintf('The selected file is *.mat file\n');
elseif  exist(nam_mat, 'file')
    % the selected file has been converted to *.mat file already
    fprintf('The selected file has been replaced with its *.mat version.\n');
elseif or(strcmpi(file_type, '.tif'), strcmpi(file_type, '.tiff'))
    % convert
    tic;
    fprintf('converting the selected file to *.mat version...\n');
    nam_mat = tif2mat(nam);
    fprintf('Time cost in converting data to *.mat file:     %.2f seconds\n', toc);
elseif or(strcmpi(file_type, '.h5'), strcmpi(file_type, '.hdf5'))
    fprintf('the selected file is hdf5 file\n');
    temp = h5info(nam);
    dataset_nam = ['/', temp.Datasets.Name];
    dataset_info = h5info(nam, dataset_nam);
    dims = dataset_info.Dataspace.Size;
    ndims = length(dims);
    d1 = dims(2);
    d2 = dims(3);
    numFrame = dims(end);
    Ysiz = [d1, d2, numFrame];
    fprintf('\nThe data has %d X %d pixels X %d frames. \nLoading all data requires %.2f GB RAM\n\n', d1, d2, numFrame, prod(Ysiz)*8/(2^30));
    return;
else
    fprintf('The selected file type was not supported yet! email me to get support (zhoupc1988@gmail.com)\n');
    return;
end

%% information of the data
data = matfile(nam_mat);
Ysiz = data.Ysiz;
d1 = Ysiz(1);   %height
d2 = Ysiz(2);   %width
numFrame = Ysiz(3);    %total number of frames

fprintf('\nThe data has been mapped to RAM. It has %d X %d pixels X %d frames. \nLoading all data requires %.2f GB RAM\n\n', d1, d2, numFrame, prod(Ysiz)*8/(2^30));


% Command list:
% turtleBot('openSerial') - open turtlebot serial port
% turtleBot('setSpeed', trans, rot) - set translational and rotational speed
% pos = turtleBot('getPosition') - get turtleBot position, return value is [x; y; angle]
% turtleBot('goTo', pos) - go to target position
% turtleBot('bye') - close serial and kill all threads

% compile
% mex turtleBot.cpp

% To get connected to the turtleBot, we need to open the serial port
turtleBot('openSerial');

% To simply set speed
% unit: translational speed - m/s, rotational speed - rad/s
turtleBot('setSpeed', trans, rot);

% To obtain the current position
pos = turtleBot('getPosition');
disp(pos);

% Go to a target position, pos = [x y angle heading].
% unit: x - mm y - mm angle - deg heading - TOWARD 0; BACKWARD 1
turtleBot('goTo', pos);

% IMPORTANT: remember to shutdown after finishing everything!
turtleBot('bye');


% Mex file interface to the lp_solve 5.5 toolkit. Please see
% reference guide for more information.
%
% mxlpsolve is a low-level interface to the `lp_solve toolkit`. It may be called
% directly, or may be used to build higher level functions for solving
% various kinds of linear and mixed-integer linear programs. It uses an
% integer handle to point to a linear program.
%
%     return = mxlpsolve('add_column', lp, [column])
%
%     return = mxlpsolve('add_columnex', lp, [column])
%
%     return = mxlpsolve('add_constraint', lp, [row], constr_type, rh)
%
%     return = mxlpsolve('add_constraintex', lp, [row], constr_type, rh)
%
%     return = mxlpsolve('add_SOS', lp, name, sostype, priority, [sosvars], [weights])
%
%     return = mxlpsolve('column_in_lp', lp, [column])
%
%     mxlpsolve('default_basis', lp)
%
%     return = mxlpsolve('del_column', lp, column)
%
%     return = mxlpsolve('del_constraint', lp, del_row)
%
%     lp_handle = mxlpsolve('copy_lp', lp)
%
%     mxlpsolve('delete_lp', lp)
%
%     mxlpsolve('dualize_lp', lp)
%
%     mxlpsolve('free_lp', lp)
%
%     return = mxlpsolve('get_anti_degen', lp)
%
%     [bascolumn] = mxlpsolve('get_basis', lp {, nonbasic})
%
%     return = mxlpsolve('get_basiscrash', lp)
%
%     return = mxlpsolve('get_bb_depthlimit', lp)
%
%     return = mxlpsolve('get_bb_floorfirst', lp)
%
%     return = mxlpsolve('get_bb_rule', lp)
%
%     return = mxlpsolve('get_bounds_tighter', lp)
%
%     return = mxlpsolve('get_break_at_value', lp)
%
%     name = mxlpsolve('get_col_name', lp, column)
%
%     [names] = mxlpsolve('get_col_name', lp)
%
%     [column, return] = mxlpsolve('get_column', lp, col_nr)
%
%     [column, return] = mxlpsolve('get_columnex', lp, col_nr)
%
%     return = mxlpsolve('get_constr_type', lp, row)
%
%     return = mxlpsolve('get_constr_value', lp, row {, primsolution})
%
%     [constr_type] = mxlpsolve('get_constr_type', lp)
%
%     [constr, return] = mxlpsolve('get_constraints', lp)
%
%     [duals, return] = mxlpsolve('get_dual_solution', lp)
%
%     return = mxlpsolve('get_epsb', lp)
%
%     return = mxlpsolve('get_epsd', lp)
%
%     return = mxlpsolve('get_epsel', lp)
%
%     return = mxlpsolve('get_epsint', lp)
%
%     return = mxlpsolve('get_epsperturb', lp)
%
%     return = mxlpsolve('get_epspivot', lp)
%
%     lp_handle = mxlpsolve('get_handle', lp_name)
%
%     return = mxlpsolve('get_improve', lp)
%
%     return = mxlpsolve('get_infinite', lp)
%
%     return = mxlpsolve('get_lowbo', lp, column)
%
%     [return] = mxlpsolve('get_lowbo', lp)
%
%     return = mxlpsolve('get_lp_index', lp, orig_index)
%
%     name = mxlpsolve('get_lp_name', lp)
%
%     value = mxlpsolve('get_mat', lp, row, col)
%
%     [matrix, return] = mxlpsolve('get_mat', lp {, sparse})
%
%     return = mxlpsolve('get_max_level', lp)
%
%     return = mxlpsolve('get_maxpivot', lp)
%
%     return = mxlpsolve('get_mip_gap', lp, absolute)
%
%     return = mxlpsolve('get_nameindex', lp, name, isrow)
%
%     return = mxlpsolve('get_Ncolumns', lp)
%
%     return = mxlpsolve('get_negrange', lp)
%
%     return = mxlpsolve('get_nonzeros', lp)
%
%     return = mxlpsolve('get_Norig_columns', lp)
%
%     return = mxlpsolve('get_Norig_rows', lp)
%
%     return = mxlpsolve('get_Nrows', lp)
%
%     return = mxlpsolve('get_obj_bound', lp)
%
%     [row_vec, return] = mxlpsolve('get_obj_fn', lp)
%
%     [row_vec, return] = mxlpsolve('get_obj_fun', lp)
%
%     return = mxlpsolve('get_objective', lp)
%
%     name = mxlpsolve('get_objective_name', lp)
%
%     return = mxlpsolve('get_orig_index', lp, lp_index)
%
%     name = mxlpsolve('get_origcol_name', lp, column)
%
%     [names] = mxlpsolve('get_origcol_name', lp)
%
%     name = mxlpsolve('get_origrow_name', lp, row)
%
%     [names] = mxlpsolve('get_origrow_name', lp)
%
%     return = mxlpsolve('get_pivoting', lp)
%
%     return = mxlpsolve('get_presolve', lp)
%
%     return = mxlpsolve('get_presolveloops', lp)
%
%     [pv, return] = mxlpsolve('get_primal_solution', lp)
%
%     return = mxlpsolve('get_print_sol', lp)
%
%     return = mxlpsolve('get_rh', lp, row)
%
%     [rh] = mxlpsolve('get_rh', lp)
%
%     return = mxlpsolve('get_rh_range', lp, row)
%
%     [rh_ranges] = mxlpsolve('get_rh_range', lp)
%
%     [row, return] = mxlpsolve('get_row', lp, row_nr)
%
%     [row, return] = mxlpsolve('get_rowex', lp, row_nr)
%
%     name = mxlpsolve('get_row_name', lp, row)
%
%     [names] = mxlpsolve('get_row_name', lp)
%
%     return = mxlpsolve('get_scalelimit', lp)
%
%     return = mxlpsolve('get_scaling', lp)
%
%     [objfrom, objtill, objfromvalue, objtillvalue, return] = mxlpsolve('get_sensitivity_obj', lp)
%
%     [objfrom, objtill, objfromvalue, objtillvalue, return] = mxlpsolve('get_sensitivity_objex', lp)
%
%     [duals, dualsfrom, dualstill, return] = mxlpsolve('get_sensitivity_rhs', lp)
%
%     [duals, dualsfrom, dualstill, return] = mxlpsolve('get_sensitivity_rhsex', lp)
%
%     return = mxlpsolve('get_simplextype', lp)
%
%     [obj, x, duals, return] = mxlpsolve('get_solution', lp)
%
%     return = mxlpsolve('get_solutioncount', lp)
%
%     return = mxlpsolve('get_solutionlimit', lp)
%
%     return = mxlpsolve('get_status', lp)
%
%     return = mxlpsolve('get_statustext', lp, statuscode)
%
%     return = mxlpsolve('get_timeout', lp)
%
%     return = mxlpsolve('get_total_iter', lp)
%
%     return = mxlpsolve('get_total_nodes', lp)
%
%     return = mxlpsolve('get_upbo', lp, column)
%
%     [upbo] = mxlpsolve('get_upbo', lp)
%
%     return = mxlpsolve('get_var_branch', lp, column)
%
%     [var_branch] = mxlpsolve('get_var_branch', lp)
%
%     return = mxlpsolve('get_var_dualresult', lp, index)
%
%     return = mxlpsolve('get_var_primalresult', lp, index)
%
%     return = mxlpsolve('get_var_priority', lp, column)
%
%     [var_priority] = mxlpsolve('get_var_priority', lp)
%
%     [var, return] = mxlpsolve('get_variables', lp)
%
%     return = mxlpsolve('get_verbose', lp)
%
%     return = mxlpsolve('get_working_objective', lp)
%
%     return = mxlpsolve('has_BFP', lp)
%
%     return = mxlpsolve('has_XLI', lp)
%
%     return = mxlpsolve('is_add_rowmode', lp)
%
%     return = mxlpsolve('is_anti_degen', lp, testmask)
%
%     return = mxlpsolve('is_binary', lp, column)
%
%     [binary] = mxlpsolve('is_binary', lp)
%
%     return = mxlpsolve('is_break_at_first', lp)
%
%     return = mxlpsolve('is_constr_type', lp, row, mask)
%
%     return = mxlpsolve('is_debug', lp)
%
%     return = mxlpsolve('is_feasible', lp, [values] {, threshold})
%
%     return = mxlpsolve('is_free', lp, column)
%
%     return = mxlpsolve('is_unbounded', lp, column)
%
%     [free] = mxlpsolve('is_free', lp)
%
%     [free] = mxlpsolve('is_unbounded', lp)
%
%     return = mxlpsolve('is_infinite', lp, value)
%
%     return = mxlpsolve('is_int', lp, column)
%
%     [int] = mxlpsolve('is_int', lp)
%
%     return = mxlpsolve('is_integerscaling', lp)
%
%     return = mxlpsolve('is_maxim', lp)
%
%     return = mxlpsolve('is_nativeBFP', lp)
%
%     return = mxlpsolve('is_nativeXLI', lp)
%
%     return = mxlpsolve('is_negative', lp, column)
%
%     [negative] = mxlpsolve('is_negative', lp)
%
%     return = mxlpsolve('is_piv_mode', lp, testmask)
%
%     return = mxlpsolve('is_piv_rule', lp, rule)
%
%     return = mxlpsolve('is_presolve', lp, testmask)
%
%     return = mxlpsolve('is_scalemode', lp, testmask)
%
%     return = mxlpsolve('is_scaletype', lp, scaletype)
%
%     return = mxlpsolve('is_semicont', lp, column)
%
%     [semicont] = mxlpsolve('is_semicont', lp)
%
%     return = mxlpsolve('is_SOS_var', lp, column)
%
%     [SOS_var] = mxlpsolve('is_SOS_var', lp)
%
%     return = mxlpsolve('is_trace', lp)
%
%     return = mxlpsolve('is_use_names', lp, isrow)
%
%     versionstring = mxlpsolve('lp_solve_version')
%
%     lp_handle = mxlpsolve('make_lp', rows, columns)
%
%     mxlpsolve('print_constraints', lp {, columns})
%
%     return = mxlpsolve('print_debugdump', lp, filename)
%
%     mxlpsolve('print_duals', lp)
%
%     mxlpsolve('print_lp', lp)
%
%     mxlpsolve('print_objective', lp)
%
%     mxlpsolve('print_scales', lp)
%
%     mxlpsolve('print_solution', lp {, columns})
%
%     mxlpsolve('print_str', lp, str)
%
%     mxlpsolve('print_tableau', lp)
%
%     [handle_vec] = mxlpsolve('print_handle')
%
%     lp_handle = mxlpsolve('read_freeMPS', filename {, verbose})
%
%     lp_handle = mxlpsolve('read_lp_file', filename {, verbose {, lp_name}})
%
%     lp_handle = mxlpsolve('read_lp', filename {, verbose {, lp_name}})
%
%     lp_handle = mxlpsolve('read_LP', filename {, verbose {, lp_name}})
%
%     lp_handle = mxlpsolve('read_mps', filename {, verbose})
%
%     lp_handle = mxlpsolve('read_MPS', filename {, verbose})
%
%     return = mxlpsolve('read_params', lp, filename {, options})
%
%     return = mxlpsolve('reset_params', lp)
%
%     lp_handle = mxlpsolve('read_XLI', xliname, modelname {, dataname {, options {, verbose}}})
%
%     return = mxlpsolve('set_add_rowmode', lp, turnon)
%
%     mxlpsolve('set_anti_degen', lp, anti_degen)
%
%     return = mxlpsolve('set_basis', lp, [bascolumn], nonbasic)
%
%     mxlpsolve('set_basiscrash', lp, mode)
%
%     mxlpsolve('set_basisvar', lp, basisPos, enteringCol)
%
%     mxlpsolve('set_bb_depthlimit', lp, bb_maxlevel)
%
%     mxlpsolve('set_bb_floorfirst', lp, bb_floorfirst)
%
%     mxlpsolve('set_bb_rule', lp, bb_rule)
%
%     return = mxlpsolve('set_BFP', lp, filename)
%
%     return = mxlpsolve('set_binary', lp, column, must_be_bin)
%
%     return = mxlpsolve('set_binary', lp, [must_be_bin])
%
%     return = mxlpsolve('set_bounds', lp, column, lower, upper)
%
%     return = mxlpsolve('set_bounds', lp, [lower], [upper])
%
%     mxlpsolve('set_bounds_tighter', lp, tighten)
%
%     mxlpsolve('set_break_at_first', lp, break_at_first)
%
%     mxlpsolve('set_break_at_value', lp, break_at_value)
%
%     return = mxlpsolve('set_col_name', lp, column, name)
%
%     return = mxlpsolve('set_col_name', lp, [names])
%
%     return = mxlpsolve('set_column', lp, col_no, [column])
%
%     return = mxlpsolve('set_columnex', lp, col_no, [column])
%
%     return = mxlpsolve('set_constr_type', lp, row, con_type)
%
%     return = mxlpsolve('set_constr_type', lp, [con_type])
%
%     mxlpsolve('set_debug', lp, debug)
%
%     mxlpsolve('set_epsb', lp, epsb)
%
%     mxlpsolve('set_epsd', lp, epsd)
%
%     mxlpsolve('set_epsel', lp, epsel)
%
%     mxlpsolve('set_epsint', lp, epsint)
%
%     mxlpsolve('set_epslevel', lp, epslevel)
%
%     mxlpsolve('set_epsperturb', lp, epsperturb)
%
%     mxlpsolve('set_epspivot', lp, epspivot)
%
%     return = mxlpsolve('set_free', lp, column)
%
%     return = mxlpsolve('set_unbounded', lp, column)
%
%     mxlpsolve('set_improve', lp, improve)
%
%     mxlpsolve('set_infinite', lp, infinite)
%
%     return = mxlpsolve('set_int', lp, column, must_be_int)
%
%     return = mxlpsolve('set_int', lp, [must_be_int])
%
%     return = mxlpsolve('set_lowbo', lp, column, value)
%
%     return = mxlpsolve('set_lowbo', lp, [values])
%
%     return = mxlpsolve('set_lp_name', lp, name)
%
%     return = mxlpsolve('set_mat', lp, [matrix])
%
%     return = mxlpsolve('set_mat', lp, row, column, value)
%
%     mxlpsolve('set_maxim', lp)
%
%     mxlpsolve('set_maxpivot', max_num_inv)
%
%     mxlpsolve('set_minim', lp)
%
%     mxlpsolve('set_mip_gap', lp, absolute, mip_gap)
%
%     mxlpsolve('set_negrange', negrange)
%
%     return = mxlpsolve('set_obj', lp, column, value)
%
%     return = mxlpsolve('set_obj', lp, [values])
%
%     mxlpsolve('set_obj_bound', lp, obj_bound)
%
%     return = mxlpsolve('set_obj_fn', lp, [row])
%
%     return = mxlpsolve('set_obj_fnex', lp, [row])
%
%     return = mxlpsolve('set_outputfile', lp, filename)
%
%     mxlpsolve('set_pivoting', lp, pivoting)
%
%     mxlpsolve('set_preferdual', lp, dodual)
%
%     mxlpsolve('set_presolve', lp, do_presolve {, maxloops})
%
%     mxlpsolve('set_print_sol', lp, print_sol)
%
%     return = mxlpsolve('set_rh', lp, row, value)
%
%     return = mxlpsolve('set_rh', lp, [values])
%
%     return = mxlpsolve('set_rh_range', lp, row, deltavalue)
%
%     return = mxlpsolve('set_rh_range', lp, [deltavalues])
%
%     mxlpsolve('set_rh_vec', lp, [rh])
%
%     return = mxlpsolve('set_row', lp, row_no, [row])
%
%     return = mxlpsolve('set_rowex', lp, row_no, [row])
%
%     return = mxlpsolve('set_row_name', lp, row, name)
%
%     return = mxlpsolve('set_row_name', lp, [names])
%
%     mxlpsolve('set_scalelimit', lp, scalelimit)
%
%     mxlpsolve('set_scaling', lp, scalemode)
%
%     return = mxlpsolve('set_semicont', lp, column, must_be_sc)
%
%     return = mxlpsolve('set_semicont', lp, [must_be_sc])
%
%     mxlpsolve('set_sense', lp, maximize)
%
%     mxlpsolve('set_simplextype', lp, simplextype)
%
%     mxlpsolve('set_solutionlimit', lp, simplextype)
%
%     mxlpsolve('set_timeout', lp, sectimeout)
%
%     mxlpsolve('set_trace', lp, trace)
%
%     return = mxlpsolve('set_upbo', lp, column, value)
%
%     return = mxlpsolve('set_upbo', lp, [values])
%
%     mxlpsolve('set_use_names', lp, isrow, use_names)
%
%     return = mxlpsolve('set_var_branch', lp, column, branch_mode)
%
%     return = mxlpsolve('set_var_branch', lp, [branch_mode])
%
%     return = mxlpsolve('set_var_weights', lp, [weights])
%
%     mxlpsolve('set_verbose', lp, verbose)
%
%     return = mxlpsolve('set_XLI', lp, filename)
%
%     result = mxlpsolve('solve', lp)
%
%     return = mxlpsolve('time_elapsed', lp)
%
%     mxlpsolve('unscale', lp)
%
%     return = mxlpsolve('write_freemps', lp, filename)
%
%     return = mxlpsolve('write_freeMPS', lp, filename)
%
%     return = mxlpsolve('write_lp', lp, filename)
%
%     return = mxlpsolve('write_LP', lp, filename)
%
%     return = mxlpsolve('write_mps', lp, filename)
%
%     return = mxlpsolve('write_MPS', lp, filename)
%
%     return = mxlpsolve('write_params', lp, filename {, options})
%
%     return = mxlpsolve('write_XLI', lp, filename {, options {, results}})
%

disp('mxlpsolve driver not found !!!');
disp('Check if mxlpsolve.dll is on your system and in a directory known to MATLAB.');
disp('Press enter to see the paths where MATLAB looks for the driver.');
pause
path
disp('A path can be added via the menu: File, Set Path');
error('mxlpsolve.dll not found');