target_folder = 'aligned_images';

pdollar_toolbox_path='D:/face project/pdollar-toolbox';
addpath(genpath(pdollar_toolbox_path));

MTCNN_path = 'D:\face project\MTCNN_face_detection_alignment\code\codes\MTCNNv2';
caffe_model_path=[MTCNN_path , '/model'];
addpath(genpath(MTCNN_path));

coord5points = [30.2946, 65.5318, 48.0252, 33.5493, 62.7299; ...
                51.6963, 51.5014, 71.7366, 92.3655, 92.2041];
imgSize = [112, 96];

%caffe.set_mode_cpu();
gpu_id=0;
caffe.set_mode_gpu();
caffe.set_device(gpu_id);
caffe.reset_all();

%three steps's threshold
threshold=[0.6 0.7 0.7]

minsize = 100;

%scale factor
factor=0.709;

%load caffe models
prototxt_dir =strcat(caffe_model_path,'/det1.prototxt');
model_dir = strcat(caffe_model_path,'/det1.caffemodel');
PNet=caffe.Net(prototxt_dir,model_dir,'test');
prototxt_dir = strcat(caffe_model_path,'/det2.prototxt');
model_dir = strcat(caffe_model_path,'/det2.caffemodel');
RNet=caffe.Net(prototxt_dir,model_dir,'test');
prototxt_dir = strcat(caffe_model_path,'/det3.prototxt');
model_dir = strcat(caffe_model_path,'/det3.caffemodel');
ONet=caffe.Net(prototxt_dir,model_dir,'test');
prototxt_dir =  strcat(caffe_model_path,'/det4.prototxt');
model_dir =  strcat(caffe_model_path,'/det4.caffemodel');
LNet=caffe.Net(prototxt_dir,model_dir,'test');
faces=cell(0);

identity_list = dir('./Images');
identity_list = identity_list(3:end);

for i=1:length(identity_list)
    subset_list = dir(fullfile('./Images',identity_list(i).name));
    subset_list = subset_list(3:end);
    for j=1:length(subset_list)
        image_list = dir(fullfile('./Images',identity_list(i).name, subset_list(j).name));
        image_list = image_list(3:end);
        disp([fullfile('./Images',identity_list(i).name, subset_list(j).name) ' ' num2str(length(image_list)) ' files']);
        for k=1:length(image_list)
            filename = fullfile('./Images',identity_list(i).name, subset_list(j).name, image_list(k).name);
            [~, ~, c] = fileparts(filename);
            if strcmp(c,'.png')==0
                continue;
            end;
            img = imread(filename);
            if size(img,1) == 112 && size(img,2) == 96
                continue;
            end;
            [boundingboxes points]=detect_face(img,minsize,PNet,RNet,ONet,LNet,threshold,false,factor);
            if isempty(boundingboxes)
                continue;
            end;
            default_face = 1;
            if size(boundingboxes,1) > 1
                for bb=2:size(boundingboxes,1)
                    if abs((boundingboxes(bb,1) + boundingboxes(bb,3))/2 - size(img,2) / 2) + abs((boundingboxes(bb,2) + boundingboxes(bb,4))/2 - size(img,1) / 2) < ...
                            abs((boundingboxes(default_face,1) + boundingboxes(default_face,3))/2 - size(img,2) / 2) + abs((boundingboxes(default_face,2) + boundingboxes(default_face,4))/2 - size(img,1) / 2)
                        default_face = bb;
                    end;
                end;
            end;
            facial5points = double(reshape(points(:,default_face),[5 2])');
            Tfm =  cp2tform(facial5points', coord5points', 'similarity');
            cropImg = imtransform(img, Tfm, 'XData', [1 imgSize(2)],...
                                          'YData', [1 imgSize(1)], 'Size', imgSize);
            imwrite(cropImg, filename);
            %show detection result
        % 	numbox=size(boundingboxes,1);
        %     figure(1);
        % 	imshow(img)
        % 	hold on;
        % 	for j=1:numbox
        % 		plot(points(1:5,j),points(6:10,j),'g.','MarkerSize',10);
        % 		r=rectangle('Position',[boundingboxes(j,1:2) boundingboxes(j,3:4)-boundingboxes(j,1:2)],'Edgecolor','g','LineWidth',3);
        %     end
        %     hold off;
        %     figure(2);
        %     imshow(cropImg);
        % 	pause

        end;
    end;
end;


clear; clc;
load mariodata;

global H;
global A;
global mario;
global dxnkey;
global dxnpressed;
global shiftpressed;
global spacepressed;
global spacetime;
dxnpressed=0;
shiftpressed=0;
spacepressed=0;
dxnkey='';

timeout	= 30;	% duration of sim (sec)
% rfrsh	= 1/60;	% NTSC refresh rate (sec)
rfrsh	= 1/10;	% refresh rate that works for now (want better rate)
scale	= 1;	%

%SETUP FIGURE:
figure(1); clf;
hold on;
gnd=patch([0 0 10000 10000 0],[-20 0 0 -20 -20],7);
set(gca,'YTick',[],'XTick',[],'Color',[0.3 0.6 0.94]);
plot3([0 1000],[0 0],[-1 -1],'k','LineWidth',2);
axis([0 400 -20 200]);
set(gcf,'keypressfcn',@keypress,'keyreleasefcn',@keyrelease,'WindowButtonUpFcn','');
axis equal;

%INITIALIZE SPRITE PATCHES:
maxdims = [32 17]; %sprite dimensions
colormap(clrs);
for i=1:maxdims(1)	%rows
	for j=1:maxdims(2)	%cols
		H(i,j)=patch([-1 -1 0 0 -1]+j,[-1 0 0 -1 -1]+i,0,'FaceAlpha',0);
	end;
end;
shading flat;
ttl = title(sprintf('TIME\n%03.0f',max(timeout,0)),'FontWeight','bold','Color',[1 1 1],'FontSize',14,'FontName','Monotxt','HorizontalAlignment','right','Position', [390,150,1]);

%INITIAL STATE:
%states:	1:small, 2:big, 3:firepower
%actions:	1:stand, 2:run, 3:jump, 4:duck, 5:skid, 6:climb, 7:switm, 8:shoot, 9: die
%dxns:		1:right, 2:left
state	= 3;		%current character state
dxn		= 1;		%current character direction
action	= 1;		%current character action
iter	= 1;		%frame within current action
loc		= [0 0];	%initial position
spd		= [0 0];	%current x and y speed
spdlim	= [8 18];	%magnitude of max speed in x and y
acc		= [0 0];	%current x and y acceleration
updatesprite(state,dxn,action,iter,[0 0])

%REMINDER:
%states:	1:small	2:big  3:firepower
%dxns:		1:right 2:left
%actions:	1:stand 2:walk 3:jump 4:duck 5:skid 6:climb 7:swim 8:shoot 9:die

%MAIN LOOP:
tic;
tnext=0;
t=toc;
while toc<timeout,
	%DIRECTION COMMANDED:
	if dxnpressed,				%accelerate
		if dxnkey(1)=='d'	%user pressed down (duck)
			action=4;
			if spd(1)==0	%stay at rest
				acc(1)=0;
			else
				acc(1) = -sign(spd(1))*ceil(abs(spd(1)/2)); %decellerate
			end;

		elseif dxnkey(1)=='r'		%accelerate right
			acc(1) = 2*(spd(1)<spdlim(1));
			if spd(1)<0			%skidding turn left to right
				action	= 5;
				dxn		= 2;
			else				%running right
				action	= 2;
				dxn		= 1;
			end;

		elseif dxnkey(1)=='l'	%accelerate left
			acc(1) = -2*(spd(1)>-spdlim(1));
			if spd(1)>0			%skidding turn right to left
				action	= 5;
				dxn		= 1;
			else				%running left
				action	= 2;
				dxn		= 2;
			end;
		end;
	%NO ARROWS PRESSED: slow to rest
	else
		if spd(1)==0	%stay at rest
			acc(1)=0;
			action=1;
		else
			acc(1) = -sign(spd(1))*ceil(abs(spd(1)/2)); %decellerate
		end;
	end;

	%SHOOTING:
	if state==3 && shiftpressed,
		action=8;
	end;

	%Jumping:
	if spacepressed && loc(2)==0,
		spacepressed = 0;
		acc(2)=-3;
		spd(2)=18;
	end;

	%UPDATE POSITION:
	spd = round(spd+acc);
	loc = loc+spd;

	%end jump?
	if loc(2)<=0 && spd(2)<0	%end jump
		loc(2)=0;
		spd(2)=0;
		acc(2)=0;
		if dxnkey(1)=='l' || dxnkey(1)=='r' %end running
			action=2;
		elseif dxnkey(1)=='d'				%end ducking
			action=4;
		end;
	elseif loc(2)>0
		if action==4 || action==8 %jumping stance unless ducking or shooting
		else
			action=3;	%airborne stance
		end;
	end;

	%INCREMENT FRAME OF CURRENT ACTION:
	if action==2,
		if iter==1, iter=3;
		else iter=iter-1;
		end;
	elseif sum(action==[1 3 4 5 7 9])
		iter=1;
	end;

	%UPDATE FIGURE:
	updatesprite(state,dxn,action,iter,loc)
	axis([0 400 -20 200])
	set(ttl,'String',sprintf('TIME\n%03.0f',max(timeout-toc,0)));
	drawnow;

	%CONTROL REFRESH RATE:
% 	tnext	= tnext+rfrsh;
% 	t=toc;
% 	txtra	= tnext-t;
% 	if txtra>0,
% 		pause(txtra);
% 		disp('paused');
% 	else
% 		disp([t,tnext,txtra])
% 	end;
end;

%DEATH
ylims = get(gca,'YLim');
spd=[0 12];
acc=[0 -3];
updatesprite(1,1,9,1,loc);
pause(1);
while loc(2)>ylims(1)-30
	spd(2)=max(spd(2)+acc(2),-spdlim(2)); %terminal velocity
	loc=loc+spd;
	updatesprite(1,1,9,1,loc);
	drawnow;
end;

clf;
plot(0,0);
set(gca,'Color','k','XTick',[],'YTick',[],'ButtonDownFcn','test1');
text(140,100,'click to continue','Color','w','FontSize',18);
axis([0 400 -20 200],'equal');


%                                      [zhi,zlo] = quadadd(xhi,xlo,y)
% QUADADD   Compute (zhi+zlo) = (xhi+xlo) + y.
%   x an z are in double-double format (quad precision)
%
% **********  INTERNAL FUNCTION OF SEDUMI **********
%
% See also sedumi

function [zhi,zlo] = quadadd(xhi,xlo,y) %#ok
%
% 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
%

disp('The SeDuMi binaries are not installed.')
disp('In Matlab, launch "install_sedumi" in the folder you put the SeDuMi files.')
disp('For more information see the file Install.txt.')
error(' ')


function producetSNEPlots(propertiesFolder,infoFilePath,reconVersion,customFeatures)
% This function plots reaction presence and uptake and secretion potential
% by taxon with t-SNE.
%
% USAGE
%   producetSNEPlots(propertiesFolder,infoFilePath,reconVersion)
%
% INPUTS
% propertiesFolder      Folder where the reaction presences and uptake and
%                       secretion potential to be analyzed are stored
%                       (default: current folder)
% infoFilePath          Path to spreadsheet with taxonomical information of
%                       the refined strains
% reconVersion          Name assigned to the reconstruction resource
% OPTIONAL INPUT
% customFeatures        Features other than taxonomy to cluster microbes
%                       by. Need to be a table header in the file with
%                       information on reconstructions.
%
%   - AUTHOR
%   Almut Heinken, 06/2020

% euclidean should work for most
distance='euclidean';
alg='barneshut';

currentDir=pwd;
cd(propertiesFolder)
mkdir('tSNE_Plots')

Summary=struct;

tol=0.0000001;

% read the file with organism information
if contains(infoFilePath,'.xlsx')
    [~,infoFile,~]=xlsread(infoFilePath);
else
    gettab=tdfread(infoFilePath);
    getcols=fieldnames(gettab);
    infoFile={};
    for j=1:length(getcols)
        infoFile{1,j}=getcols{j};
        if isnumeric(gettab.(getcols{j}))
            infoFile(2:size(gettab.(getcols{j}),1)+1,j)=cellstr(num2str(gettab.(getcols{j})));
        else
            infoFile(2:size(gettab.(getcols{j}),1)+1,j)=cellstr(gettab.(getcols{j}));
        end
    end
end

% define files to analyze
analyzedFiles={
    'Reaction presence' ['ReactionMetabolitePresence' filesep 'ReactionPresence_' reconVersion]
    'Metabolite presence' ['ReactionMetabolitePresence' filesep 'MetabolitePresence_' reconVersion]
    'Uptake and secretion potential' ['ComputedFluxes' filesep 'UptakeSecretion_' reconVersion]
    'Internal metabolite production' ['ComputedFluxes' filesep 'InternalProduction_' reconVersion]
    };

for k=1:size(analyzedFiles,1)
    if isfile([propertiesFolder filesep analyzedFiles{k,2} '.txt'])
        DataToAnalyze = readInputTableForPipeline([propertiesFolder filesep analyzedFiles{k,2} '.txt']);
        DataToAnalyze=DataToAnalyze';

        [C,I]=setdiff(DataToAnalyze(1,:),infoFile(:,1),'stable');
        DataToAnalyze(:,I(2:end))=[];

        % can only be performed if there are enough strains with taxonomical information
        if size(DataToAnalyze,2) >= 10

            if contains(version,'(R202') % for Matlab R2020a and newer
                rp=cell2mat(DataToAnalyze(2:end,2:end));
            else
                rp=str2double(DataToAnalyze(2:end,2:end));
            end
            orgs=DataToAnalyze(1,2:end)';

            taxonlevels={
                'Phylum'
                'Class'
                'Order'
                'Family'
                'Genus'
                'Species'
                };

            for i=1:length(taxonlevels)
                % plot on different taxon levels
                taxa={};
                taxcol=find(strcmp(infoFile(1,:),taxonlevels{i}));
                for j=2:size(DataToAnalyze,2)
                    if ~any(strcmp(infoFile(:,1),DataToAnalyze{1,j}))
                        taxa{j-1,1}='N/A';
                    else
                        taxa{j-1,1}=infoFile{find(strcmp(infoFile(:,1),DataToAnalyze{1,j})),taxcol};
                    end
                end

                data=rp';
                red_orgs=orgs;

                % remove entries that are all zeros
                toDel=sum(data,1)<tol;
                data(:,toDel)=[];

                % remove entries that are NaNs or empty
                findnans=any(isnan(data));
                data(:,findnans==1)=[];

                % remove unclassified organisms
                data(find(strcmp(taxa,'N/A')),:)=[];
                red_orgs(strcmp(taxa,'N/A'),:)=[];
                taxa(find(strcmp(taxa,'N/A')),:)=[];
                data(find(strcmp(taxa,'NA')),:)=[];
                red_orgs(strcmp(taxa,'NA'),:)=[];
                taxa(find(strcmp(taxa,'NA')),:)=[];

                % remove empty cells
                data(find(strcmp(taxa,'')),:)=[];
                red_orgs(strcmp(taxa,''),:)=[];
                taxa(find(strcmp(taxa,'')),:)=[];

                % remove unclassified organisms
                data(find(strncmp(taxa,'unclassified',length('unclassified'))),:)=[];
                red_orgs(find(strncmp(taxa,'unclassified',length('unclassified'))),:)=[];
                taxa(find(strncmp(taxa,'unclassified',length('unclassified'))),:)=[];

                if i==6
                    % remove unclassified species
                    toDel=[];
                    cnt=1;
                    for j=1:size(data,1)
                        if strcmp(taxa{j,1}(length(taxa{j,1})-2:length(taxa{j,1})),' sp')
                            toDel(cnt)=j;
                            cnt=cnt+1;
                        end
                    end
                    data(toDel,:)=[];
                    red_orgs(toDel,:)=[];
                    taxa(toDel,:)=[];
                end

                % remove taxa with too few members
                [uniqueXX, ~, J]=unique(taxa) ;
                occ = histc(J, 1:numel(uniqueXX));

                if length(uniqueXX) >15
                    % sort by number of entries and remove the ones with the least
                    % entries
                    [B,I]=sort(occ,'descend');
                    uniqueXX=uniqueXX(I);

                    if sum(B==1) > length(B)-15
                        % remove all that are just one entry
                        uniqueXX(B==1)=[];
                    else
                        % remove all but 20 highest
                        uniqueXX=uniqueXX(1:20);
                    end

                    [C,IA]=setdiff(taxa,uniqueXX);
                    data(find(ismember(taxa,C)),:)=[];
                    red_orgs(ismember(taxa,C),:)=[];
                    taxa(find(ismember(taxa,C)),:)=[];
                end

                % sort alphabetically
                [B,I]=sortrows(taxa,'ascend');
                data = data(I,:);
                red_orgs = red_orgs(I,:);
                taxa = taxa(I,:);

                if size(data,1)>10

                    % adjust perplicity to number of variables
                    if size(data,1) > 150
                        perpl=50;
                    elseif size(data,1) >= 50
                        perpl=30;
                    elseif size(data,1) >= 20
                        perpl=10;
                    else
                        perpl=5;
                    end

                    Y = tsne(data,'Distance',distance,'Algorithm',alg,'Perplexity',perpl,'NumDimensions',2);
                    %                 Y = tsne(data,'Distance',distance,'Algorithm',alg,'Perplexity',perpl,'NumDimensions',3);
                    Summary.([strrep(analyzedFiles{k,1},' ','_') '_' taxonlevels{i}])(:,1)=red_orgs;
                    Summary.([strrep(analyzedFiles{k,1},' ','_') '_' taxonlevels{i}])(:,2)=taxa;
                    Summary.([strrep(analyzedFiles{k,1},' ','_') '_' taxonlevels{i}])(:,3:size(Y,2)+2)=cellstr(string(Y));

                    if size(data,1) == size(Y,1) && size(Y,2) > 1
                        f=figure;
                        cols=hsv(length(unique(taxa)));
                        % define markers to better distinguish groups
                        cmarkers='';
                        for j=1:7:length(unique(taxa))
                            cmarkers=[cmarkers '+o*xsdp'];
                        end
                        cmarkers=cmarkers(1:length(unique(taxa)));
                        %                     gscatter3(Y(:,1),Y(:,2),Y(:,3),taxa,cols,{},30);
                        h=gscatter(Y(:,1),Y(:,2),taxa,cols,cmarkers);
                        set(h,'MarkerSize',4)
                        hold on
                        title(analyzedFiles{k,1})

                        h=legend('Location','northeastoutside');
                        if length(uniqueXX) < 12
                            set(h,'FontSize',12)
                        elseif length(uniqueXX) < 20
                            set(h,'FontSize',11)
                        else
                            set(h,'FontSize',8)
                        end
                        set(h, 'Interpreter', 'none')
                        grid off
                        f.Renderer='painters';
                        print(['tSNE_Plots' filesep taxonlevels{i} '_' strrep(analyzedFiles{k,1},' ','_') '_' reconVersion],'-dpng','-r300')
                    else
                        warning('Not enough strains with available organism information. Cannot cluster based on taxonomy.')
                    end
                end
            end

            % if the data should be clustered by any custom features from the info file
            if nargin > 3
                for i=1:length(customFeatures)
                    % plot on different taxon levels
                    feats={};
                    cuscol=find(strcmp(infoFile(1,:),customFeatures{i}));
                    if ~isempty(cuscol)
                        for j=2:size(DataToAnalyze,2)
                            if ~any(strcmp(infoFile(:,1),DataToAnalyze{1,j}))
                                feats{j-1,1}='N/A';
                            else
                                feats{j-1,1}=infoFile{find(strcmp(infoFile(:,1),DataToAnalyze{1,j})),cuscol};
                            end
                        end

                        data=rp';
                        red_orgs=orgs;

                        % remove organisms with no data
                        data(find(strcmp(taxa,'N/A')),:)=[];
                        red_orgs(strcmp(taxa,'N/A'),:)=[];
                        taxa(find(strcmp(taxa,'N/A')),:)=[];

                        if size(data,1) >= 10

                            % remove features with too few members
                            [uniqueXX, ~, J]=unique(feats) ;
                            occ = histc(J, 1:numel(uniqueXX));
                            toofew=uniqueXX(occ<sum(occ)/2000);
                            data(find(ismember(feats,toofew)),:)=[];
                            red_orgs(ismember(feats,toofew),:)=[];
                            feats(find(ismember(feats,toofew)),:)=[];

                            Y = tsne(data,'Distance',distance,'Algorithm',alg,'Perplexity',perpl,'NumDimensions',3);
                            Summary.([strrep(analyzedFiles{k,1},' ','_') '_' strrep(customFeatures{i},' ','_')])(:,1)=red_orgs;
                            Summary.([strrep(analyzedFiles{k,1},' ','_') '_' strrep(customFeatures{i},' ','_')])(:,2)=feats;
                            Summary.([strrep(analyzedFiles{k,1},' ','_') '_' strrep(customFeatures{i},' ','_')])(:,3:4)=cellstr(string(Y));

                            f=figure;
                            hold on
                            gscatter3(Y(:,1),Y(:,2),Y(:,3),feats);
                            title(analyzedFiles{k,1})
                            h=legend('Location','northeastoutside');
                            if length(uniqueXX) < 12
                                set(h,'FontSize',11)
                            elseif length(uniqueXX) < 20
                                set(h,'FontSize',9)
                            else
                                set(h,'FontSize',6)
                            end
                            grid off
                            set(h, 'Interpreter', 'none')
                            f.Renderer='painters';
                            print(['tSNE_Plots' filesep customFeatures{i} '_' strrep(analyzedFiles{k,1},' ','_') '_' reconVersion],'-dpng','-r300')
                        else
                            warning('Not enough strains with available organism information. Cannot cluster based on features.')
                        end
                    end
                end
            end
        end
    end
end

% export computed distance underlying the plots
datasets=fieldnames(Summary);
if length(datasets)>0
    mkdir(['tSNE_Plots' filesep 'ComputedDistances'])
    for i=1:length(datasets)
        data = vertcat({'Data point','Stratifying feature','x-axis value','y-axis value'},Summary.(datasets{i}));
        cell2csv(['tSNE_Plots' filesep 'ComputedDistances' filesep datasets{i} '.csv'],data)
    end
end

cd(currentDir)

end


function [trl, conditionlabels, S] = spm_eeg_definetrial(S)
% Definition of trials based on events
% FORMAT [trl, conditionlabels, S] = spm_eeg_definetrial(S)
% S                 - input structure (optional)
% (optional) fields of S:
%   S.D             - MEEG object or filename of M/EEG mat-file
%   S.timewin       - time window {in PST ms}
%   S.trialdef      - structure array for trial definition with fields (optional)
%       S.trialdef.conditionlabel - string label for the condition
%       S.trialdef.eventtype      - string
%       S.trialdef.eventvalue     - string, numeric or empty
%       S.trialdef.trlshift       - shift the triggers by a fixed amount {ms}
%                                   (e.g. projector delay).
%   S.reviewtrials  - review individual trials after selection [yes/no: 1/0]
%   S.save          - save trial definition [yes/no: 1/0]
%
% OUTPUT:
%   trl             - Nx3 matrix [start end offset]
%   conditionlabels - Nx1 cell array of strings, label for each trial
%   S               - modified configuration structure (for history)
%__________________________________________________________________________
% Copyright (C) 2008-2017 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak, Robert Oostenveld
% $Id: spm_eeg_definetrial.m 7132 2017-07-10 16:22:58Z guillaume $

SVNrev = '$Rev: 7132 $';

%-Startup
%--------------------------------------------------------------------------
spm('sFnBanner', mfilename, SVNrev);
spm_figure('FindWin','Interactive'); spm_clf('Interactive');

%-Get MEEG object
%--------------------------------------------------------------------------
try
    D = S.D;
catch
    [D, sts] = spm_select(1, 'mat', 'Select M/EEG mat file');
    if ~sts, trl = []; conditionlabels = {}; S = []; return; end
    S.D = D;
end

D = spm_eeg_load(D);

%-Get input parameters
%--------------------------------------------------------------------------
if ~isequal(D.type, 'continuous')
    error('Trial definition requires continuous dataset as input.');
end

event    = events(D, 1, 'samples');
fsample  = D.fsample;

if isempty(event)
    error('No event information was found in the input.');
end

if ~isfield(S, 'timewin')
    S.timewin = spm_input('Time window (ms)', '+1', 'r', [], 2);
end

pretrig  = S.timewin(1);
posttrig = S.timewin(2);

if ~isfield(S, 'trialdef')
    S.trialdef = [];
    ncond = spm_input('How many conditions?', '+1', 'n', '1');
    for i = 1:ncond
        OK = false;
        pos = '+1';
        while ~OK
            conditionlabel = spm_input(['Label of condition ' num2str(i)], pos, 's');
            selected = spm_eeg_select_event_ui(event);
            if isempty(conditionlabel) || isempty(selected)
                pos = '-1';
            else
                shift = spm_input('Shift triggers (ms)', pos, 'r', '0');
                for j = 1:size(selected, 1)
                    S.trialdef = [S.trialdef ...
                        struct('conditionlabel', conditionlabel, ...
                        'eventtype', selected{j, 1}, ...
                        'eventvalue', selected{j, 2}, ...
                        'trlshift', shift)];
                    OK = true;
                end
            end
        end
    end
end

for i = 1:length(S.trialdef)
    if ~isfield(S.trialdef(i),'trlshift')
        trlshift(i) = 0;
    else
        trlshift(i) = round(S.trialdef(i).trlshift * fsample/1000); % assume passed as ms
    end
end

%-Build trl based on selected events
%--------------------------------------------------------------------------
trl = [];
conditionlabels = {};
for i=1:numel(S.trialdef)

    if ischar(S.trialdef(i).eventvalue)
        % convert single string into cell-array, otherwise the intersection does not work as intended
        S.trialdef(i).eventvalue = {S.trialdef(i).eventvalue};
    end

    sel = [];
    % select all events of the specified type and with the specified value
    for j=find(strcmp(S.trialdef(i).eventtype, {event.type}))
        if isempty(S.trialdef(i).eventvalue)
            sel = [sel j];
        elseif ~isempty(intersect(event(j).value, S.trialdef(i).eventvalue))
            sel = [sel j];
        end
    end

    for j=1:length(sel)
        % override the offset of the event
        trloff = round(0.001*pretrig*fsample);
        % also shift the begin sample with the specified amount
        if ismember(event(sel(j)).type, {'trial', 'average'})
            % In case of trial events treat the 0 time point as time of the
            % event rather than the beginning of the trial
            trlbeg = event(sel(j)).sample - event(sel(j)).offset + trloff;
        else
            trlbeg = event(sel(j)).sample + trloff;
        end
        trldur = round(0.001*(-pretrig+posttrig)*fsample);
        trlend = trlbeg + trldur;

        % Added by Rik in case wish to shift triggers (e.g, due to a delay
        % between trigger and visual/auditory stimulus reaching subject).
        trlbeg = trlbeg + trlshift(i);
        trlend = trlend + trlshift(i);

        % add the beginsample, endsample and offset of this trial to the list
        trl = [trl; trlbeg trlend trloff];
        conditionlabels{end+1} = S.trialdef(i).conditionlabel;
    end
end

%-Sort the trl in right temporal order
%--------------------------------------------------------------------------
if isempty(trl)
    warning('No trials found.');
else
    [junk, sortind] = sort(trl(:,1));
    trl             = trl(sortind, :);
    conditionlabels = conditionlabels(sortind);
end

%-Review selected trials
%--------------------------------------------------------------------------
if ~isfield(S, 'reviewtrials')
    S.reviewtrials = spm_input('Review individual trials?','+1','yes|no',[1 0], 0);
end

if S.reviewtrials && ~isempty(trl)
    eventstrings = cell(size(trl,1),1);
    for i=1:size(trl,1)
        eventstrings{i} = [num2str(i) ' Label: ' conditionlabels{i} ' Time (sec): ' num2str((trl(i, 1)- trl(i, 3))./fsample)];
    end

    selected = find(trl(:,1)>0);

    [indx,ok] = listdlg('ListString', eventstrings, 'SelectionMode', 'multiple', 'InitialValue', ...
        selected, 'Name', 'Select events', 'ListSize', [300 300]);

    if ok
        trl = trl(indx, :);
        conditionlabels = conditionlabels(indx);
    end
end

%-Create trial definition file
%--------------------------------------------------------------------------
if ~isfield(S, 'save')
    S.save = spm_input('Save trial definition?','+1','yes|no',[1 0], 0);
end

if S.save
    [trlfilename, trlpathname] = uiputfile( ...
        {'*.mat', 'MATLAB File (*.mat)'}, 'Save trial definition as');

    if ~isequal(trlfilename,0) && ~isequal(trlpathname,0)
        trialdef = S.trialdef;
        timewin  = S.timewin;
        source   = D.fname;

        save(fullfile(trlpathname, trlfilename),...
            'trl', 'conditionlabels', 'trialdef', 'source', 'timewin', ...
            spm_get_defaults('mat.format'));
    end
end

%-Cleanup
%--------------------------------------------------------------------------
spm_clf('Interactive');


function [ctmediumphantom,ctdensityphantom] = dicomrt_ctcreate(inpct_matrix,ct_xmesh,ct_ymesh,ct_zmesh,rtdose_xmesh,rtdose_ymesh,rtdose_zmesh,plotramp,int)
% dicomrt_ctcreate(inpct_matrix,ct_xmesh,ct_ymesh,ct_zmesh,rtdose_xmesh,rtdose_ymesh,rtdose_zmesh,plotramp,int)
%
% Create a ct phantom for BEAM/DOSXYZ simulation. Light Version.
%
% inpct_matrix is the CT dataset
% ct_xmesh, ct_ymesh, ct_zmesh are the coordinates of the voxels for the CT dataset
% rtdose_xmesh, rtdose_ymesh, rtdose_zmesh are the coordinates of the voxels
% of the 3D dose distribution
% plotramp is an option for plotting the CT ramp (~=0 plot, =0[default] no plot)
% Int is a parameter for interactive session.
%     If int ~=1 or if int is not given session is not interactive
%     and default parameters (e.g. directories names) will be used. If int = 1 the user will
%     be asked to set some parameters.
%
% Parameters for this specific m file are:
%
% nmat				    number of material
% materials			    materials name
% medium				materials number
% mat_ct_up_bound		materials upper bound (see dosxyz user's manual)
% density_lo_bound		density lower bound (see dosxyz user's manual)
% density_up_bound		density upper bound (see dosxyz user's manual)
% estepe				estepe (see dosxyz user's manual)
% filename			    ct phantom filename for export
%
% See also dicomrt_loaddose, dicomrt_rotate180x
%
% Copyright (C) 2002 Emiliano Spezi (emiliano.spezi@physics.org)

% Check number of argument
error(nargchk(8,9,nargin))

if nargin<=8
    int=0;
end

% Check case and set-up some parameters and variables
[ct_matrix_temp,type_dose,label,PatientPosition]=dicomrt_checkinput(inpct_matrix);
ct_matrix=dicomrt_varfilter(ct_matrix_temp);

[ct_xmesh_2d,ct_ymesh_2d]=dicomrt_build2dgrid(ct_xmesh,ct_ymesh);
[dose_xmesh_2d,dose_ymesh_2d]=dicomrt_build2dgrid(rtdose_xmesh,rtdose_ymesh);

% 1a) resize ct_matrix using dose_xmesh, dose_ymesh, dose_zmesh
% loop over dose_zmesh size since the rt plan could have been performed on a subset of the original ct images
for i=1:length(rtdose_zmesh)
    if i==1 % locate z position of the first slice to start with
      first_zlocation=rtdose_zmesh(i);
      for k=1:length(ct_zmesh)
         temp=num2str(ct_zmesh(k));
         array=char(temp,num2str(first_zlocation));
         if array(1,:)==array(2,:);
            break
         end
      end
      zstart=k; % match with dose matrix
   end
   ctphantom(:,:,i)=interp2(ct_xmesh_2d,ct_ymesh_2d,ct_matrix(:,:,k+i-1), ...
       dose_xmesh_2d,dose_ymesh_2d,'nearest');
end

% 1b) Cut off negative values form outside CT FOV
ctphantom(find((ctphantom)<=0))=10; % a CT value for air

% 2a) Retrieve ctphantom parameters: if int==1 start interactive session
if isnumeric(int)==1 &  int==1
    nmat = input('Input the number of materials [Enter for default]: '); % Number of material
    if isempty(nmat)==1
        nmat=4;
        %disp('The following materials will be used: ');
        materials          = char('AIR521ICRU','LUNG521ICRU','ICRUTISSUE521ICRU','ICRPBONE521ICRU');
        medium             = [1;     2;     3;     4];
        mat_ct_up_bound    = [50;    300;   1125;  5000];
        density_lo_bound   = [0.001; 0.044; 0.302; 1.101];
        density_up_bound   = [0.044; 0.302; 1.101; 3.48];
        estepe             = [0.25;  0.25;  0.25;  0.25];
    else
        medium = [1:nmat]';
        for i=1:nmat
            mat = input('Input the name of material: ','s'); % Name of material
            if i==1
                materials = mat;
            else
                materials = char(materials,mat);
            end
            mat_ct_up_bound(i) = input('Input the material ct upper bound: ');
            density_lo_bound(i) = input('Input the density ct lower bound: ');
            density_up_bound(i) = input('Input the density ct upper bound: ');
            estepe(i) = input('Input estepe for this material: ');
        end
        estepe=estepe';
    end % ctphantom parameters retrieved
else
    nmat=4;
    %disp('The following materials will be used: ');
    materials          = char('AIR521ICRU','LUNG521ICRU','ICRUTISSUE521ICRU','ICRPBONE521ICRU');
    medium             = [1;     2;     3;     4];
    mat_ct_up_bound    = [50;    300;   1125;  5000];
    density_lo_bound   = [0.001; 0.044; 0.302; 1.101];
    density_up_bound   = [0.044; 0.302; 1.101; 3.84];
    estepe             = [0.25;  0.25;  0.25;  0.25];
end

% 2b) Plot CT ramp
if plotramp~=0
    disp('Plotting CT conversion ramp being used: ');
    dicomrt_plotctramp(inputname(1),materials,mat_ct_up_bound,density_lo_bound,density_up_bound);
end

% 3) Build ctphantom

% 3a) CT to medium
ctmediumphantom=ctphantom;
for i=1:nmat
    if i==1
        ctmediumphantom(find((ctmediumphantom<=mat_ct_up_bound(i) & ...
            ctmediumphantom>0)))=medium(i);
    else
        ctmediumphantom(find((ctmediumphantom<=mat_ct_up_bound(i) & ...
            ctmediumphantom>mat_ct_up_bound(i-1))))=medium(i);
    end
end

% 3b) Convert CT data to density
ctdensityphantom=ones(size(ctmediumphantom,1),size(ctmediumphantom,2),size(ctmediumphantom,3));
for i=1:nmat
    if i==1
        a=density_lo_bound(i);
        b=density_up_bound(i)-density_lo_bound(i);
        c=mat_ct_up_bound(i);
        d=ctphantom(find((ctmediumphantom==medium(i))));
        ctdensityphantom(find((ctmediumphantom==medium(i)))) = a+(b/c)*d;
    else
        a=density_lo_bound(i);
        b=density_up_bound(i)-density_lo_bound(i);
        c=mat_ct_up_bound(i)-mat_ct_up_bound(i-1);
        d=ctphantom(find((ctmediumphantom==medium(i))))-mat_ct_up_bound(i-1);
        ctdensityphantom(find((ctmediumphantom==medium(i)))) = a+(b/c)*d;
    end
end

% 5) Export to file.
%
% ImagePositionPatient is the (x,y,z) coordinate of the first pixel (mm).
% Therefore the mesh produced so far represent the coordinates of the center of the voxels.
% CTphantom need the coordinates of the boundaries of the voxels.
%
if isnumeric(int)==1 &  int==1
    export = input('Do you want to export the ctphantom ? Y/N [N]: ','s');
    if export == 'Y' | export == 'y';
        % Prepare to export
        % pixel spacing
        xthick=abs(rtdose_xmesh(1)-rtdose_xmesh(2));
        ythick=abs(rtdose_ymesh(1)-rtdose_ymesh(2));
        zthick=abs(rtdose_zmesh(1)-rtdose_zmesh(2));

        x_bound=dicomrt_createboundgrid(rtdose_xmesh);
        y_bound=dicomrt_createboundgrid(rtdose_ymesh);
        z_bound=dicomrt_createboundgrid(rtdose_zmesh);

        filename = input('Input the egs4phant filename (no ext): ','s'); % Name of the file where to store ctphantom

        if filename == 'N' | filename == 'n';
            warning('dicomrt_ctcreate: No filename was input. Filename "filename" will be used');
            filename=['filename.egs4phant'];
            dicomrt_writeegs4phant(PatientPosition,nmat,materials,estepe,length(rtdose_xmesh),length(rtdose_ymesh), ...
                length(rtdose_zmesh),x_bound,y_bound,z_bound,ctmediumphantom,ctdensityphantom,filename);
        else
            filename=[filename,'.egs4phant'];
            dicomrt_writeegs4phant(PatientPosition,nmat,materials,estepe,length(rtdose_xmesh),length(rtdose_ymesh), ...
                length(rtdose_zmesh),x_bound,y_bound,z_bound,ctmediumphantom,ctdensityphantom,filename);
        end
    else
        disp('No export will be performed. Data will be stored on disk');
        save
    end
else
    % Prepare to export
    % pixel spacing
    xthick=abs(rtdose_xmesh(1)-rtdose_xmesh(2));
    ythick=abs(rtdose_ymesh(1)-rtdose_ymesh(2));
    zthick=abs(rtdose_zmesh(1)-rtdose_zmesh(2));

    x_bound=dicomrt_createboundgrid(rtdose_xmesh);
    y_bound=dicomrt_createboundgrid(rtdose_ymesh);
    z_bound=dicomrt_createboundgrid(rtdose_zmesh);

    filename=inputname(1);
    filename=[filename,'.egs4phant'];

    dicomrt_writeegs4phant(PatientPosition,nmat,materials,estepe,length(rtdose_xmesh),length(rtdose_ymesh), ...
        length(rtdose_zmesh),x_bound,y_bound,z_bound,ctmediumphantom,ctdensityphantom,filename);
end


clc;

close all;
clear all;

%discremeinateanalysis
linearRegression
%logisticregression
naivbayes
regresstree
ccaregression
svm


% IN ORDER TO SIMULATE THE PROGRAM:
%   A) FIRST, LOAD A ROBOT
%       robot = load_robot('abb','irb140');
%   B) NEXT, LOAD SOME EQUIPMENT.
%       robot.equipment = load_robot('equipment','tables/table_small');
%       OR
%       robot.equipment = load_robot('equipment','bumper_cutting');
%   C) NOW, LOAD AN END TOOL
%       robot.tool= load_robot('equipment','end_tools/parallel_gripper_0');
%   D) FINALLY, LOAD A PIECE TO GRAB BY THE ROBOT
%       robot.piece{1}=load_robot('equipment','cylinders/cylinder_tiny');
%
%   E) IF NECESSARY, CHANGE THE POSITION AND ORIENTATION OF THE ROBOT'S
%   BASE
%       robot.piece{1}.T0= [1 0 0 -0.35;
%                        0 1 0 -0.55;
%                        0 0 1 0.2;
%                        0 0 0 1];

function kuka_KR60_painting_jaguar_ftype

global TD_tool0 RT_tp1 RT_tp2 RT_tp3 RT_tp4 RT_tp5 RT_tp6 RT_tp7 RT_tp8 RT_tp9 RT_tp10 RT_tp11 RT_tp12 RT_tp13 RT_tp14 RT_tp15 RT_tp16

TD_tool0=[1,[[0,0,0],[1,0,0,0]],[0,[0,0,0],[1,0,0,0],0,0,0]];

RT_tp1=[[1.3400, -0.0000, 1.8100],[0.7006, -0.0954, 0.7006, -0.0954], [0, 0, 1, 0], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp2=[[1.1648, 0.6617, 1.8206],[0.7233, -0.2626, 0.6324, 0.0894], [-1, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp3=[[1.4924, 0.9803, 1.1556],[0.5816, -0.3339, 0.7362, 0.0911], [-1, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp4=[[1.5020, 0.8533, 1.3436],[0.6364, -0.2942, 0.7086, 0.0787], [-1, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp5=[[1.5207, 0.6786, 1.4836],[0.6784, -0.2480, 0.6898, 0.0507], [-1, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp6=[[1.6593, 0.3815, 1.4044],[0.6580, -0.1850, 0.7298, -0.0146], [-1, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp7=[[1.6990, 0.1099, 1.4044],[0.6547, -0.1255, 0.7423, -0.0677], [-1, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp8=[[1.6707, -0.3278, 1.4044],[0.6406, -0.0289, 0.7523, -0.1514], [0, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp9=[[1.6064, -0.8202, 1.1348],[0.5463, 0.0815, 0.8060, -0.2127], [0, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp10=[[1.4123, -1.1863, 0.9392],[0.5177, 0.1723, 0.7925, -0.2725], [0, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp11=[[1.2529, -1.3639, 0.9736],[0.5680, 0.2052, 0.7172, -0.3476], [0, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp12=[[1.2075, -0.7363, 1.1201],[0.5774, 0.1073, 0.7697, -0.2503], [0, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp13=[[1.2048, -0.5831, 1.2640],[0.5698, 0.0714, 0.7900, -0.2149], [0, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp14=[[1.2754, -0.1696, 1.3640],[0.6362, -0.0526, 0.7587, -0.1299], [0, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp15=[[1.2481, 0.3127, 1.3640],[0.6493, -0.1940, 0.7354, -0.0081], [-1, 0, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
RT_tp16=[[1.1268, 0.6211, 1.3640],[0.6449, -0.2871, 0.7042, 0.0756], [-1, -1, 1, 1], [9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
main
end

function main()

global TD_tool0 RT_tp1 RT_tp2 RT_tp3 RT_tp4 RT_tp5 RT_tp6 RT_tp7 RT_tp8 RT_tp9 RT_tp10 RT_tp11 RT_tp12 RT_tp13 RT_tp14 RT_tp15 RT_tp16

 MoveL(RT_tp1, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp2, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp3, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp4, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp5, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp6, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp7, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp8, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp9, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp10, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp11, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp12, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp13, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp14, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp15, 'vmax' , 'fine' , TD_tool0, 'wobj0');
 MoveL(RT_tp16, 'vmax' , 'fine' , TD_tool0, 'wobj0');

end


function writeGLTF(filename,V,F,varargin)
  % writeGLTF(filename,V,F)
  %
  % Inputs:
  %   filename  path to .gltf file
  %   V  #V by 3 list of mesh vertex positions
  %   F  #F by 3 list of mesh triangle indices into rows of V
  %   Optional:
  %   'SkinningTransforms' followed by
  %     T  3 by 4 by #T by #A list of animated global skinning transformations
  %   'SkinningWeights' followed by
  %     W  #V by #T list of skinning weights
  %   'MorphTargets' followed by
  %     MV  #V by 3 by #M list of morph targets
  %   'MorphWeights' followed by
  %     MW  #frames by #M list of morph weights
  %   'TextureCoordinates' followed by
  %     UV  #V by 2 list of texture coordinates
  %
  % Examples:
  %   !python -m json.tool octopus.gltf > octopus-pretty.gltf
  NEAREST = 9728;
  LINEAR = 9729;
  NEAREST_MIPMAP_NEAREST = 9984;
  LINEAR_MIPMAP_NEAREST = 9985;
  NEAREST_MIPMAP_LINEAR = 9986;
  LINEAR_MIPMAP_LINEAR = 9987;
  CLAMP_TO_EDGE = 33071;
  MIRRORED_REPEAT = 33648;
  REPEAT = 10497;

  T = [];
  W = [];
  MV = [];
  MN = [];
  MW = [];
  N = [];
  fps = 30;
  nf = 0;
  UV = [];
  tex_im = [];
  mag_filter = LINEAR;
  min_filter = LINEAR_MIPMAP_LINEAR;
  wrap_s = MIRRORED_REPEAT;
  wrap_t = MIRRORED_REPEAT;

  % Map of parameter names to variable names
  params_to_variables = containers.Map( ...
    {'FPS','MagFilter','MinFilter','MorphTargets','MorphNormals','MorphWeights','Normals','SkinningTransforms','SkinningWeights','TextureCoordinates','TextureImage'}, ...
    {'fps','mag_filter','min_filter','MV','MN','MW','N','T','W','UV','tex_im'});
  v = 1;
  while v <= numel(varargin)
    param_name = varargin{v};
    if isKey(params_to_variables,param_name)
      assert(v+1<=numel(varargin));
      v = v+1;
      % Trick: use feval on anonymous function to use assignin to this workspace
      feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
    else
      error('Unsupported parameter: %s',varargin{v});
    end
    v=v+1;
  end

  mag_filter = string_to_magic_value(mag_filter);
  min_filter = string_to_magic_value(min_filter);
  function value = string_to_magic_value(string)
    if ischar(string)
      switch(string)
      case 'LINEAR'
        value = LINEAR;
      case 'NEAREST'
        value = NEAREST;
      case 'LINEAR_MIPMAP_NEAREST'
        value = LINEAR_MIPMAP_NEAREST;
      case 'LINEAR_MIPMAP_LINEAR'
        value = LINEAR_MIPMAP_LINEAR;
      otherwise
        error([string ' not found/implemented.']);
      end
    else
      value = string;
    end
  end

  % set flags
  has_normals = ~isempty(N);
  has_skinning_weights = ~isempty(W);
  has_skinning_transforms = ~isempty(T);
  has_morph_target_positions = ~isempty(MV);
  has_morph_target_weights = ~isempty(MW);
  has_morph_target_normals = ~isempty(MN);
  has_texture_coordinates = ~isempty(UV);
  has_texture_image = ~isempty(tex_im);

  % Determine what type to use for faces
  BYTE = 5120;
  UNSIGNED_BYTE = 5121;
  SHORT = 5122;
  UNSIGNED_SHORT = 5123;
  UNSIGNED_INT = 5125;
  FLOAT = 5126;
  ARRAY_BUFFER = 34962;
  ELEMENT_ARRAY_BUFFER = 34963;
  if max(F(:)) < 2^16
    F_size = 2;
    F_type = UNSIGNED_SHORT;
    F_matlab_type = 'uint16';
  else
    F_size = 4;
    F_type = UNSIGNED_INT;
    F_matlab_type = 'uint32';
  end

  % prepare things to write
  buffered_data = {};
  buffered_data{end+1} = struct('Name','F','Data',F,'Type','SCALAR','ComponentType',F_type,'Size',F_size,'MatlabType',F_matlab_type,'Target',ELEMENT_ARRAY_BUFFER);
  buffered_data{end+1} = struct('Name','V','Data',V,'Target',ARRAY_BUFFER);
  if has_normals
    buffered_data{end+1} = struct('Name','N','Data',normalizerow(N),'Target',ARRAY_BUFFER);
  end
  if has_morph_target_weights
    assert(size(MW,2) == size(MV,3));
    buffered_data{end+1} = struct('Name','MW','Data',MW,'Type','SCALAR');
    MWt = (0:size(MW,1)-1)*1/fps;
    buffered_data{end+1} = struct('Name','MWt','Data',MWt,'Type','SCALAR');
  end
  if has_morph_target_positions
    buffered_data{end+1} = struct('Name','MV','Data',MV,'Target',ARRAY_BUFFER);
  end
  if has_morph_target_normals
    buffered_data{end+1} = struct('Name','MN','Data',MN,'Target',ARRAY_BUFFER);
  end
  if has_skinning_weights
    [WIk,Wk] = prepare_skinning_weights(W);
    if max(WIk(:)) < 2^8
      WIk_size = 1;
      WIk_type = UNSIGNED_BYTE;
      WIk_matlab_type = 'uint8';
    else
      WIk_size = 2;
      WIk_type = UNSIGNED_SHORT;
      WIk_matlab_type = 'uint16';
    end
    buffered_data{end+1} = struct('Name','WIk','Data',WIk,'Size',WIk_size,'MatlabType',WIk_matlab_type,'ComponentType',WIk_type,'Target',ARRAY_BUFFER);
    buffered_data{end+1} = struct('Name','Wk','Data',Wk,'Target',ARRAY_BUFFER);
  end
  if has_skinning_transforms
    assert(size(W,2) == size(T,3));
    [tT,qU,sS,qVT] = prepare_skinning_transforms(T);
    buffered_data{end+1} = struct('Name','tT','Data',tT);
    buffered_data{end+1} = struct('Name','qU','Data',qU);
    buffered_data{end+1} = struct('Name','sS','Data',sS);
    buffered_data{end+1} = struct('Name','qVT','Data',qVT);
    Tt = (0:size(T,4)-1)*1/fps;
    buffered_data{end+1} = struct('Name','Tt','Data',Tt,'Type','SCALAR');
  end
  if has_texture_coordinates
    buffered_data{end+1} = struct('Name','UV','Data',UV,'Target',ARRAY_BUFFER);
  end

  [buffer,bufferViews,accessors,accessor_hash] = prepare_buffer(buffered_data);

  % First node is the mesh
  attributes = struct("POSITION",accessor_hash.V);

  if has_normals
    attributes.NORMAL = accessor_hash.N;
  end
  if has_texture_coordinates
    attributes.TEXCOORD_0 = accessor_hash.UV;
  end
  if has_skinning_weights
    attributes.JOINTS_0 = accessor_hash.WIk;
    attributes.WEIGHTS_0 = accessor_hash.Wk;
  end
  mesh = struct( ...
    "primitives",{{struct("attributes",attributes,"indices",accessor_hash.F)}});
  if has_morph_target_positions
    if ~isfield(mesh.primitives{1},'targets')
      mesh.primitives{1}.targets = num2cell(repmat(struct(),size(MV,3),1));
    end
    for i = 1:size(MV,3)
      mesh.primitives{1}.targets{i} = setfield(mesh.primitives{1}.targets{i},'POSITION',accessor_hash.MV(i));
    end
    mesh.weights = zeros(1,size(MV,3));
  end
  if has_morph_target_normals
    if ~isfield(mesh.primitives{1},'targets')
      mesh.primitives{1}.targets = num2cell(repmat(struct(),size(MN,3),1));
    end
    for i = 1:size(MN,3)
      mesh.primitives{1}.targets{i} = setfield(mesh.primitives{1}.targets{i},'NORMAL',accessor_hash.MN(i));
    end
  end

  nodes_list = {0};
  nodes = {struct("mesh",0)};
  if has_skinning_weights
    m = size(W,2);
    nodes{end}.skin = 0;
    % First put leaf nodes that will animate V-rotation
    for i = 1:m
      nodes{end+1} = struct( ...
        "name",sprintf('V-%d',i), ...
        "rotation",[0 0 0 1]);
    end
    % Then put parent auxiliary nodes that will animate translation, U-rotation, scale
    for i = 1:m
      nodes{end+1} = struct( ...
        "name",sprintf('TUS-%d',i), ...
        "children",{{i}}, ...
        "translation",[0 0 0], ...
        "rotation",[0 0 0 1], ...
        "scale",[1 1 1]);
    end
    %Put fake root at scene level and attach parents
    nodes_list{end+1} = 2*m+1;
    common_root = struct("name","root","children",{num2cell(m+(1:m))});
    nodes = {nodes{:} common_root};
  end

  % These {{double-brackets}} are needed when using the `struct` function.
  gltf = struct( ...
    "scene",0, ...
    "scenes",{{struct("nodes",{nodes_list})}}, ...
    "nodes",{nodes}, ...
    "meshes",{{mesh}}, ...
    "buffers",{{buffer}}, ...
    "bufferViews",{bufferViews}, ...
    "accessors",{accessors}, ...
    "asset",struct("version","2.0") ...
    );

  % Are these just for animation or do they overlap with texture samplers?
  samplers = {};
  channels = {};
  if has_skinning_weights
    gltf.skins = {struct('joints',{num2cell(0+1:m)})};
    if has_skinning_transforms
      for i = 1:m
        channels{end+1} = struct('sampler',numel(samplers),'target',struct('node',m+i,'path','translation'));
        samplers{end+1} = struct('input',accessor_hash.Tt,'output',accessor_hash.tT(i),'interpolation', 'STEP');
        channels{end+1} = struct('sampler',numel(samplers),'target',struct('node',m+i,'path','rotation'));
        samplers{end+1} = struct('input',accessor_hash.Tt,'output',accessor_hash.qU(i),'interpolation', 'STEP');
        channels{end+1} = struct('sampler',numel(samplers),'target',struct('node',m+i,'path','scale'));
        samplers{end+1} = struct('input',accessor_hash.Tt,'output',accessor_hash.sS(i),'interpolation', 'STEP');
        channels{end+1} = struct('sampler',numel(samplers),'target',struct('node',i,'path','rotation'));
        samplers{end+1} = struct('input',accessor_hash.Tt,'output',accessor_hash.qVT(i),'interpolation','STEP');
      end
    end
  end
  if has_morph_target_weights
    channels{end+1} = struct('sampler',numel(samplers),'target',struct('node',0,'path','weights'));
    samplers{end+1} = struct('input',accessor_hash.MWt,'output',accessor_hash.MW,'interpolation','LINEAR');
  end
  if ~isempty(samplers)
    gltf.animations = {struct('samplers',{samplers},'channels',{channels})};
  end
  if has_texture_image

    if mag_filter == LINEAR
      tmpfile = 'writeGLTF.jpg';
      imwrite(flipud(tex_im),tmpfile,'Quality',100);
    else
      tmpfile = 'writeGLTF.png';
      imwrite(flipud(tex_im),tmpfile);
    end
    tex_image_uri = imdata(tmpfile);
    delete(tmpfile);

    gltf.images = {struct('uri',tex_image_uri)};
    tex_image_index = numel(gltf.images)-1;
    if ~isfield(gltf,'samplers')
      gltf.samplers = {};
    end
    gltf.samplers{end+1} = struct('magFilter',mag_filter,'minFilter',min_filter,'wrapS',wrap_s,'wrapT',wrap_t);
    gltf.textures = {struct('sampler',numel(gltf.samplers)-1,'source',tex_image_index)};

    if has_texture_coordinates
      gltf.materials = {struct( ...
        'name','default', ...
        'pbrMetallicRoughness', ...
          struct( ...
            'baseColorTexture',struct('index',0), ...
            'metallicFactor',0, ...
            'roughnessFactor',1))};
      gltf.meshes{1}.primitives{1}.material = numel(gltf.materials)-1;
    end
  end

  fid = fopen(filename,'w');
  fprintf(fid,'%s',jsonencode(gltf));
  fclose(fid);

  function [buffer,bufferViews,accessors,accessor_hash] = prepare_buffer(buffered_data)
    buffer_index = 0;
    bufferViews = {};
    accessors = {};
    accessor_hash = struct();
    byte_count = 0;
    % write all data, tracking offsets
    tmpfile = 'writeGLTF.tmp';
    fp = fopen(tmpfile,'wb');
    for bi = 1:numel(buffered_data)
      item = buffered_data{bi};
      if isfield(item,'Size')
        adjusted_data = item.Data - 1;
        pad_amount = 4;
      else
        % default to single
        item.ComponentType = FLOAT;
        item.Size = 4;
        item.MatlabType = 'single';
        pad_amount = 8;
        adjusted_data = item.Data;
      end
      if ~isfield(item,'Type')
        switch(size(adjusted_data,2))
        case 2
          item.Type = 'VEC2';
        case 3
          item.Type = 'VEC3';
        case 4
          item.Type = 'VEC4';
        otherwise
          item.Type = 'SCALAR';
        end
      end

      accessor_ids = numel(accessors)-1 + (1:size(item.Data,3));
      for i = 1:size(item.Data,3)
        adjusted_data_i = adjusted_data(:,:,i);
        switch(item.Type)
        case 'SCALAR'
          accessor_count = numel(adjusted_data_i);
          accessor_min = {{min(  adjusted_data_i,[],[1 2])}};
          accessor_max = {{max(  adjusted_data_i,[],[1 2])}};
        case {'VEC2','VEC3','VEC4'}
          accessor_count = size( adjusted_data_i,1);
          accessor_min = min(    adjusted_data_i,[],1);
          accessor_max = max(    adjusted_data_i,[],1);
        end

        fwrite(fp,adjusted_data_i',item.MatlabType);
        % pad so that next block starts aligned at 4-byte
        bi_pad = mod(pad_amount-mod(numel(adjusted_data_i),pad_amount),pad_amount);
        fwrite(fp,zeros(bi_pad,1),item.MatlabType);
        % prepare bufferView and accessor
        % Always use 'buffer',0  → caller MUST adjust all if needed
        bufferViews{end+1} = struct( ...
          'name',item.Name, ...
          'buffer',buffer_index, ...
          'byteOffset',byte_count, ...
          'byteLength',numel(adjusted_data_i)*item.Size);
        if isfield(item,'Target')
          bufferViews{end} = setfield(bufferViews{end},'target',item.Target);
        end
        accessors{end+1} = struct( ...
          'name',item.Name, ...
          'bufferView',numel(bufferViews)-1, ...
          'byteOffset',0, ...
          'componentType',item.ComponentType, ...
          'type',item.Type, ...
          'count',accessor_count, ...
          'min',accessor_min, ...
          'max',accessor_max);
        % Increment byte_count
        byte_count = byte_count + (numel(adjusted_data_i)+bi_pad)*item.Size;
      end
      accessor_hash = setfield(accessor_hash,item.Name,accessor_ids);
    end
    fclose(fp);
    fp = fopen(tmpfile,'r');
    B = fread(fp,byte_count);
    fclose(fp);
    delete(tmpfile);
    Bstr = base64encode(B);
    %assert(isequal(Bstr,matlab.net.base64encode(uint8(B))))
    buffer = struct( ...
      'uri',['data:application/octet-stream;base64,' Bstr], ...
      'byteLength', numel(B));
  end

  function [WIk,Wk] = prepare_skinning_weights(W)
    % Number of skinning weights/handles/bones
    m = size(W,2) * ~isempty(W);
    % Convert weight matrix into multiple of 4 index-value pairs
    assert(size(W,2) == m);
    k = max(sum(W~=0,2));
    k4 = ceil(k/4)*4;
    % I'm not sure how >4 is handled.
    assert(k4 == 4);
    [Wk,WIk] = maxk(W,k,2);
    % Pad with null bones
    Wk(:,k+1:k4)  = 0;
    WIk(:,k+1:k4) = 0+1;%repmat(m+(1:k4-k),size(WIk,1),1);
    WIk(Wk==0) = 0+1;
  end

  function [tT,qU,sS,qVT] = prepare_skinning_transforms(T)
    m = size(T,3);
    nf = size(T,4) * ~isempty(T);
    T = permute(T,[1 2 4 3]);
    assert(size(T,2) == 4);
    tT = T(:,4,:,:);
    [sU,sS,sV] = pagesvd(T(1:3,1:3,:,:));
    % Push all of the reflection into sS
    % matlabFunction(det(sym('m',[3 3])))
    pagedet = @(m1_1,m1_2,m1_3,m2_1,m2_2,m2_3,m3_1,m3_2,m3_3) m1_1.*m2_2.*m3_3-m1_1.*m2_3.*m3_2-m1_2.*m2_1.*m3_3+m1_2.*m2_3.*m3_1+m1_3.*m2_1.*m3_2-m1_3.*m2_2.*m3_1;
    pagedet = @(m) pagedet(m(1,1,:,:),m(1,2,:,:),m(1,3,:,:),m(2,1,:,:),m(2,2,:,:),m(2,3,:,:),m(3,1,:,:),m(3,2,:,:),m(3,3,:,:));
    sUdet = sign(pagedet(sU));
    sVdet = sign(pagedet(sV));
    sU = sU.*sUdet;
    sV = sV.*sVdet;
    sS = sS.*sVdet.*sUdet;
    sS = cat(2,sS(1,1,:,:),sS(2,2,:,:),sS(3,3,:,:));

    qU = reshape(mat2quat(reshape(sU,[3 3 m*nf]))',[4 nf m]);
    qVT = reshape(mat2quat(reshape(permute(sV,[2 1 3 4]),[3 3 m*nf]))',[4 nf m]);
    for i = 1:m
      for f = 1:nf
        assert(norm(T(:,:,f,i) - [quat2mat(qU(:,f,i)')*diag(sS(:,:,f,i))*quat2mat(qVT(:,f,i)') tT(:,:,f,i)],inf)<1e-12);
      end
    end
    % gltf uses ijkw
    qU = qU([2 3 4 1],:,:);
    qVT = qVT([2 3 4 1],:,:);

    tT = permute(tT,[3 1 4 2]);
    sS = permute(sS,[3 2 4 1]);
    qU = permute(qU,[2 1 3]);
    qVT = permute(qVT,[2 1 3]);
  end

end


function [pred_boxes, scores] = rfcn_im_detect(conf, caffe_net, im, boxes, max_rois_num_in_gpu)
% [pred_boxes, scores] = rfcn_im_detect(conf, caffe_net, im, boxes, max_rois_num_in_gpu)
% --------------------------------------------------------
% R-FCN implementation
% Modified from MATLAB Faster R-CNN (https://github.com/shaoqingren/faster_rcnn)
% Copyright (c) 2016, Jifeng Dai
% Licensed under The MIT License [see LICENSE for details]

    [im_blob, rois_blob, ~] = get_blobs(conf, im, boxes);

    % When mapping from image ROIs to feature map ROIs, there's some aliasing
    % (some distinct image ROIs get mapped to the same feature ROI).
    % Here, we identify duplicate feature ROIs, so we only compute features
    % on the unique subset.
    [~, index, inv_index] = unique(rois_blob, 'rows');
    rois_blob = rois_blob(index, :);
    boxes = boxes(index, :);

    % permute data into caffe c++ memory, thus [num, channels, height, width]
    im_blob = im_blob(:, :, [3, 2, 1], :); % from rgb to brg
    im_blob = permute(im_blob, [2, 1, 3, 4]);
    im_blob = single(im_blob);
    rois_blob = rois_blob - 1; % to c's index (start from 0)
    rois_blob = permute(rois_blob, [3, 4, 2, 1]);
    rois_blob = single(rois_blob);

    total_rois = size(rois_blob, 4);
    total_scores = cell(ceil(total_rois / max_rois_num_in_gpu), 1);
    total_box_deltas = cell(ceil(total_rois / max_rois_num_in_gpu), 1);
    for i = 1:ceil(total_rois / max_rois_num_in_gpu)

        sub_ind_start = 1 + (i-1) * max_rois_num_in_gpu;
        sub_ind_end = min(total_rois, i * max_rois_num_in_gpu);
        sub_rois_blob = rois_blob(:, :, :, sub_ind_start:sub_ind_end);

        net_inputs = {im_blob, sub_rois_blob};

        % Reshape net's input blobs
        caffe_net.reshape_as_input(net_inputs);
        caffe_net.forward(net_inputs);

        if conf.test_binary
            % simulate binary logistic regression
            scores = caffe_net.blobs('cls_score').get_data();
            scores = squeeze(scores)';
            % Return scores as fg - bg
            scores = bsxfun(@minus, scores, scores(:, 1));
        else
            % use softmax estimated probabilities
            scores = caffe_net.blobs('cls_prob').get_data();
            scores = squeeze(scores)';
        end

        % Apply bounding-box regression deltas
        box_deltas = caffe_net.blobs('bbox_pred').get_data();
        box_deltas = squeeze(box_deltas)';

        total_scores{i} = scores;
        total_box_deltas{i} = box_deltas;
    end

    scores = cell2mat(total_scores);
    box_deltas = cell2mat(total_box_deltas);

    pred_boxes = rfcn_bbox_transform_inv(boxes, box_deltas);
    pred_boxes = clip_boxes(pred_boxes, size(im, 2), size(im, 1));

    % Map scores and predictions back to the original set of boxes
    scores = scores(inv_index, :);
    pred_boxes = pred_boxes(inv_index, :);

    % remove scores and boxes for back-ground
    pred_boxes = pred_boxes(:, 5:end);
    scores = scores(:, 2:end);
    if conf.bbox_class_agnostic
        pred_boxes = repmat(pred_boxes, [1, size(scores,2)]);
    end
end

function [data_blob, rois_blob, im_scale_factors] = get_blobs(conf, im, rois)
    [data_blob, im_scale_factors] = get_image_blob(conf, im);
    rois_blob = get_rois_blob(conf, rois, im_scale_factors);
end

function [blob, im_scales] = get_image_blob(conf, im)
    [ims, im_scales] = arrayfun(@(x) prep_im_for_blob(im, conf.image_means, x, conf.test_max_size), conf.test_scales, 'UniformOutput', false);
    im_scales = cell2mat(im_scales);
    blob = im_list_to_blob(ims);
end

function [rois_blob] = get_rois_blob(conf, im_rois, im_scale_factors)
    [feat_rois, levels] = map_im_rois_to_feat_rois(conf, im_rois, im_scale_factors);
    rois_blob = single([levels, feat_rois]);
end

function [feat_rois, levels] = map_im_rois_to_feat_rois(conf, im_rois, scales)
    im_rois = single(im_rois);

    if length(scales) > 1
        widths = im_rois(:, 3) - im_rois(:, 1) + 1;
        heights = im_rois(:, 4) - im_rois(:, 2) + 1;

        areas = widths .* heights;
        scaled_areas = bsxfun(@times, areas(:), scales(:)'.^2);
        [~, levels] = min(abs(scaled_areas - 224.^2), [], 2);
    else
        levels = ones(size(im_rois, 1), 1);
    end

    feat_rois = round(bsxfun(@times, im_rois-1, scales(levels))) + 1;
end

function boxes = clip_boxes(boxes, im_width, im_height)
    % x1 >= 1 & <= im_width
    boxes(:, 1:4:end) = max(min(boxes(:, 1:4:end), im_width), 1);
    % y1 >= 1 & <= im_height
    boxes(:, 2:4:end) = max(min(boxes(:, 2:4:end), im_height), 1);
    % x2 >= 1 & <= im_width
    boxes(:, 3:4:end) = max(min(boxes(:, 3:4:end), im_width), 1);
    % y2 >= 1 & <= im_height
    boxes(:, 4:4:end) = max(min(boxes(:, 4:4:end), im_height), 1);
end


function flat = rmVol2flat(gray,flat)
% flat = rmVol2flat(gray,flat)
%
% sd 04/2008 wrote it

% Don't do this unless gray is really a gray and flat is really a flat
if ~strcmp(gray.viewType,'Gray') || ~strcmp(flat.viewType,'Flat')
    myErrorDlg('vol2flatCorAnal can only be used to transform from gray to flat.');
end

% Check that both gray & flat are properly initialized
if isempty(gray)
  myErrorDlg('Gray view must be open.  Use "Open Gray Window" from the Window menu.');
end
if isempty(flat)
  myErrorDlg('Flat view must be open.  Use "Open Flat Window" from the Window menu.');
end

% Check that dataType is the same for both views. If not, doesn't make sense to do the xform.
% because for example the two dataTypes may have a different number of scans.
checkTypes(gray,flat);

% get/load selected file
try
  rmFile = viewGet(gray,'rmFile');
catch
  disp(sprintf('[%s]:Please select file',mfilename));
  gray    = rmSelect(gray);
  rmFile  = viewGet(gray,'rmFile');
end;
load(rmFile,'model',  'params');
modelGray = model; %#ok<NODEF>

% Mask image for masking the flat map away from where we have data
mask = flat.ui.mask;

% Put up wait bar
waitHandle = mrvWaitbar(0,'Transforming retModel.  Please wait...');
% Intersect the coords from the gray view and the Flat view.
grayIndices=cell(1,2);
flatIndices=cell(1,2);
for h=1:2
    % Get the data corresponding to flat coordinates: coData,
    % ampData, and phData are each of size nVoxels x nScans where
    % nVoxels = size(flat.grayCoords,2).  First, find the
    % intersection of gray.coords and flat.grayCoords.  Then make
    % the data arrays by culling out the values from the
    % intersecting voxels.
    % Find gray nodes that are both in the inplanes and included
    % in the unfold.
    % gray.coords are the gray coords that lie in the inplanes.
    % flat.grayCoords are the gray coords in the unfold.
    % Note: this code segment is essentially identical to
    % code in getFlatCoords.
    [foo,grayIndicesTmp,flatIndicesTmp] = intersectCols(gray.coords,flat.grayCoords{h});
    grayIndices{h}=grayIndicesTmp;
    flatIndices{h}=flatIndicesTmp;
    % Error check on flatIndices.  Because the above code segment
    % is the same as that used to get the flat coords in
    % getFlatCoords, all of the flatIndices should be in the
    % intersection.  If not, something is busted.
    if length(flatIndicesTmp)~=size(flat.grayCoords{h},2)
        myWarnDlg('Ack!  Your flat maps do not appear to come from this segmentation!');
    end
end

ds = viewGet(flat,'datasize');
for m = 1:numel(model),
    % get all model fields
    fnames = fieldnames(model{m});
    for f = 1:numel(fnames),   % loop over model fields
        mrvWaitbar(((m-1).*length(model)+f) ./ (length(model).*length(fnames)))
        paramGray = rmGet(modelGray{m},fnames{f});
        % only xfm model fields that have data of a certain size
        if numel(paramGray)>1 && isnumeric(paramGray),
            % reshape both left and right
            paramFlat = zeros(ds);
            for h=1:2
                % Corresponding coords on the flat map
                coords = flat.coords{h}(:,flatIndices{h});
                switch lower(fnames{f})
                    case {'b',  'beta'}
                        for ii = 1:size(paramGray,1),
                            paramFlat(:,:,h,ii) = ...
								myGriddata(coords, ...
                                           paramGray(ii,grayIndices{h}).',  ...
                                           mask(:,  :,h));
                        end;
                    otherwise,
                        paramFlat(:,  :,h) = ...
							myGriddata(coords, ...
                                       paramGray(grayIndices{h}).', ...
                                       mask(:, :,h));
                end;
            end
            model{m} = rmSet(model{m},fnames{f},paramFlat); %#ok<AGROW>
        end;
    end;
end;
close(waitHandle)

% Now save output
[p outputname] = fileparts(rmFile);
pathStr        = fullfile(dataDir(flat),outputname);

% Overwrite?
if exist(pathStr,'file')
    saveFlag = questdlg([pathStr, ' already exists. Overwrite?'],  ...
						'Save model file?',  'Yes',  'No',  'No');
else
    saveFlag = 'Yes';
end

% Save
if strcmp(saveFlag, 'Yes')
    save(pathStr, 'model', 'params');
    flat = viewSet(flat, 'rmFile', pathStr);
    fprintf(1, '[%s]:Saved %s.\n', mfilename, pathStr);
else
    fprintf(1, '[%s]:Model not saved.\n', mfilename);
end

% If we transformed it, we probably want to view the data. Load the model.
flat = rmSelect(flat, 1, [pathStr '.mat']);
flat = rmLoadDefault(flat);

return;


function [ all_results ] = evaluate_average_precision_pascal( ...
    all_bbox_gt, all_detected_bbox, classes, varargin)
%
% This file is part of the code that implements the following ICCV2015 accepted paper:
% title: "Object detection via a multi-region & semantic segmentation-aware CNN model"
% authors: Spyros Gidaris, Nikos Komodakis
% institution: Universite Paris Est, Ecole des Ponts ParisTech
% Technical report: http://arxiv.org/abs/1505.01749
% code: https://github.com/gidariss/mrcnn-object-detection
%
% AUTORIGHTS
% --------------------------------------------------------
% Copyright (c) 2015 Spyros Gidaris
%
% "Object detection via a multi-region & semantic segmentation-aware CNN model"
% Technical report: http://arxiv.org/abs/1505.01749
% Licensed under The MIT License [see LICENSE for details]
% ---------------------------------------------------------

%************************** OPTIONS *************************************
ip = inputParser;
ip.addParamValue('minoverlap', 0.5,   @isnumeric);

ip.parse(varargin{:});
opts = ip.Results;

minoverlap  = opts.minoverlap;
all_results = compute_average_precision_of_detection(all_bbox_gt, all_detected_bbox, minoverlap);
% fprintf('\n~~~~~~~~~~~~~~~~~~~~\n');
% fprintf('Results:\n');
% aps = [all_results(:).ap]' * 100;
% disp(mean(aps));
% fprintf('~~~~~~~~~~~~~~~~~~~~\n');
end

function [false_positives, true_positives] = find_detection_labels(bbox_detections, bbox_gt, is_difficult, minoverlap)
false_positives = zeros(size(bbox_detections,1), 1);
true_positives  = zeros(size(bbox_detections,1), 1);
overlap         = zeros(size(bbox_detections,1), size(bbox_gt,1));
num_bbox_gt     = size(bbox_gt,1);

for j = 1:num_bbox_gt
    overlap(:,j) = boxoverlap(bbox_detections(:,1:4), bbox_gt(j,1:4));
end

overlap(overlap==0) = -inf;
[max_overlap, jmax] = max(overlap,[],2);

does_overlap = max_overlap >= minoverlap;

false_positives(~does_overlap) = 1; % false positive

does_overlap = does_overlap & ~is_difficult(jmax); % dont care about the difficult ones

if any(does_overlap)
    bbox_indices = find(does_overlap);
    jmax         = jmax(does_overlap);

    for j = 1:num_bbox_gt
        overlap_j = bbox_indices(jmax == j);
        if ~isempty(overlap_j)
            true_positives(overlap_j(1)) = 1; % true positive
            if numel(overlap_j) > 1
                false_positives(overlap_j(2:end)) = 1; % false positive - multiple detections
            end
        end
    end
end
end

function all_results = compute_average_precision_of_detection(all_bbox_gt, all_detected_bbox, minoverlap)
num_imgs       = length(all_bbox_gt);
num_classes    = length(all_detected_bbox);
true_positives   = cell(num_classes,1);
false_positives  = cell(num_classes,1);
detection_scores = cell(num_classes,1);

for class_idx = 1:num_classes
    true_positives{class_idx}   = cell(num_imgs,1);
    false_positives{class_idx}  = cell(num_imgs,1);
    detection_scores{class_idx} = cell(num_imgs,1);
end

num_positives = zeros(num_classes, 1);
for img_idx = 1:num_imgs
    for class_idx = 1:num_classes
        ground_truth_idx = all_bbox_gt{img_idx}(:,5) == class_idx;
        bbox_gt          = all_bbox_gt{img_idx}(ground_truth_idx,1:4);
        is_difficult     = all_bbox_gt{img_idx}(ground_truth_idx,6) > 0;
        num_positives(class_idx) = num_positives(class_idx) + sum(~is_difficult);

        bbox_detections = all_detected_bbox{class_idx}{img_idx};
        num_detections  = size(bbox_detections, 1);
        if num_detections > 0
            if isempty(bbox_gt)
                false_positives{class_idx}{img_idx} = ones(num_detections, 1);
                true_positives{class_idx}{img_idx}  = zeros(num_detections, 1);
            else
                [~, order]      = sort(bbox_detections(:,5), 'descend');
                bbox_detections = bbox_detections(order, :);

                [false_positives{class_idx}{img_idx},...
                    true_positives{class_idx}{img_idx}] = ...
                        find_detection_labels(bbox_detections(:,1:4), ...
                        bbox_gt, is_difficult, minoverlap);
            end
            detection_scores{class_idx}{img_idx} = double(bbox_detections(:,5));
        end
    end
end

all_results = compute_average_precision(true_positives, false_positives, ...
    detection_scores, 1:num_classes, num_positives);
end

function res = compute_average_precision(true_positives, false_positives, detection_scores, class_indices, num_positives)
for class_idx = class_indices
    all_true_positives  = cell2mat(true_positives{class_idx}(:));
    all_false_positives = cell2mat(false_positives{class_idx}(:));
    all_scores          = cell2mat(detection_scores{class_idx}(:));
    [all_scores, order] = sort(all_scores, 'descend');
    all_true_positives  = all_true_positives(order);
    all_false_positives = all_false_positives(order);

    % compute precision/recall
    all_false_positives = cumsum(all_false_positives);
    all_true_positives  = cumsum(all_true_positives);

    recall    = all_true_positives  /  num_positives(class_idx);
    precision = all_true_positives ./ (all_false_positives + all_true_positives);
    f1_score  = 2 * (recall.*precision) ./ (recall + precision + eps);
    [f1_score, max_idx] = max(f1_score);
    f1_thresh    = all_scores(max_idx);

    % compute average precision
    average_precion = 0;
    for t=0:0.1:1
        p = max(precision(recall>=t));
        if ~isempty(p)
            average_precion = average_precion + p/11;
        end
    end
    ap_auc = xVOCap(recall, precision);
    res(class_idx).recall    = recall;
    res(class_idx).precision = precision;
    res(class_idx).ap        = average_precion;
    res(class_idx).ap_auc    = ap_auc;
    res(class_idx).f1_score  = f1_score;
    res(class_idx).f1_thresh = f1_thresh;
%     fprintf('!!! %s : %.4f %.4f\n', classes{class_idx}, average_precion, ap_auc);
end
end

function ap = xVOCap(rec,prec)
mrec=[0 ; rec ; 1];
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
    mpre(i)=max(mpre(i),mpre(i+1));
end
i=find(mrec(2:end)~=mrec(1:end-1))+1;
ap=sum((mrec(i)-mrec(i-1)).*mpre(i));
end


%-----------------------------------------------------------------------
% Job saved on 08-Feb-2017 12:38:53 by cfg_util (rev $Rev: 7703 $)
% spm SPM - SPM12 (12.3)
% cfg_basicio BasicIO - Unknown
%-----------------------------------------------------------------------
matlabbatch{1}.spm.meeg.source.headmodel.D = {''};
matlabbatch{1}.spm.meeg.source.headmodel.val = 1;
matlabbatch{1}.spm.meeg.source.headmodel.comment = '';
matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1;
matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2;
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0;
matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM';
matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell';
matlabbatch{2}.spm.tools.beamforming.data.dir = '<UNDEFINED>';
matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('Head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D'));
matlabbatch{2}.spm.tools.beamforming.data.val = 1;
matlabbatch{2}.spm.tools.beamforming.data.gradsource = 'inv';
matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned';
matlabbatch{2}.spm.tools.beamforming.data.overwrite = 0;
matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{3}.spm.tools.beamforming.sources.reduce_rank = [2 3];
matlabbatch{3}.spm.tools.beamforming.sources.keep3d = 1;
matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 10;
matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template';
matlabbatch{3}.spm.tools.beamforming.sources.visualise = 1;
matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1;
matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf];
matlabbatch{4}.spm.tools.beamforming.features.modality = {'MEG'};
matlabbatch{4}.spm.tools.beamforming.features.fuse = 'no';
matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.foi = [0 100];
matlabbatch{4}.spm.tools.beamforming.features.plugin.cov.taper = 'none';
matlabbatch{4}.spm.tools.beamforming.features.regularisation.manual.lambda = 5;
matlabbatch{4}.spm.tools.beamforming.features.bootstrap = false;
matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.orient = true;
matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv.keeplf = false;
matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.whatconditions.all = 1;
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.contrast = [-1 1];
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.isdesign.custom.woi = [-100 0
                                                                                100 200];
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.datafeatures = 'sumpower';
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.foi = [5 15
                                                                   15 30
                                                                   30 60
                                                                   60 90];
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.result = 'BIC';
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.sametrials = false;
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_mv.modality = 'MEG';
matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'no';
matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni';


y = 17;
x = (y + 3) / 2);


function pass = example_graze_pair_filt(sicdmeta1, sicdmeta2)
%EXAMPLE_GRAZE_PAIR_FILT An example image pair filter used by 'image_pair_search'
% EXAMPLE_GRAZE_PAIR_FILT(sicdmeta1, sicdmeta) takes two SICD-compatible
% structures and returns a boolean indicating pass/fail.  Any image/SICD
% structure pair which yields a "pass" (boolean true) will be included in
% the list returned by image_pair_search.
%
% Note: No this isn't a useful filter.  At all.  You should never use it.
% We (i.e. you) should, of course, provide a filter specific to your
% particular use.  This is meant to be a stub...
%
% Just FYI...  This filter will return images whos grazing angles are
% within 5 degrees and have lat,lon locations within 0.001.  No.  There's
% no real point to it.
%
% See Also:  example_graze_filt, write_SICD_KML_placemark,
%            write_KML_header, write_KML_footer
%
% Author: Tom Krauss, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

  pass = false;

  if isfield(sicdmeta1,'SCPCOA')  &&  ...
     isfield(sicdmeta1.SCPCOA,'GrazeAng')  &&  ...
     isfield(sicdmeta1, 'GeoData')  &&  ...
     isfield(sicdmeta1.GeoData, 'SCP')  &&  ...
     isfield(sicdmeta1.GeoData.SCP, 'LLH')  &&  ...
     isfield(sicdmeta2,'SCPCOA')  &&  ...
     isfield(sicdmeta2.SCPCOA,'GrazeAng')  &&  ...
     isfield(sicdmeta2, 'GeoData')  &&  ...
     isfield(sicdmeta1.GeoData, 'SCP')  &&  ...
     isfield(sicdmeta2.GeoData.SCP, 'LLH')

    if abs(sicdmeta1.SCPCOA.GrazeAng-sicdmeta2.SCPCOA.GrazeAng) < 5 && ...
       abs(sicdmeta1.GeoData.SCP.LLH.Lat-sicdmeta2.GeoData.SCP.LLH.Lat) < 0.001 && ...
       abs(sicdmeta1.GeoData.SCP.LLH.Lon-sicdmeta2.GeoData.SCP.LLH.Lon) < 0.001
      pass = true;
    end

  end
end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////