function [xtable, ytable, utable, vtable, typevector,correlation_map] = piv_FFTensemble (autolimit,filepath,video_frame_selection,bg_img_A,bg_img_B,clahe,highp,intenscap,clahesize,highpsize,wienerwurst,wienerwurstsize,roi_inpt,maskiererx,maskierery,interrogationarea,step,subpixfinder,passes,int2,int3,int4,mask_auto,imdeform,repeat,do_pad)
%this funtion performs the  PIV analysis. It is a modification of the
%pivFFTmulti, and will do ensemble correlation. That is a suitable
%algorithm for low seeding density as it happens in microPIV.
warning off %#ok<*WNOFF> %MATLAB:log:logOfZero
%% pre-processing is done in this function
result_conv_ensemble = zeros(interrogationarea,interrogationarea); % prepare empty result_conv
if isempty(video_frame_selection) %list with image files was passed
	amount_input_imgs=size(filepath,1);
else
	amount_input_imgs=numel(video_frame_selection);
end
total_analyses_amount=amount_input_imgs / 2 * passes;
from_total = 0;
tic
skippy=0;
for ensemble_i1=1:2:amount_input_imgs
	if isempty(video_frame_selection) %list with image files was passed
		%detect if it is b16 or standard pixel image
		[~,~,ext] = fileparts(filepath{1});
		if strcmp(ext,'.b16')
			image1=f_readB16(filepath{ensemble_i1});
			image2=f_readB16(filepath{ensemble_i1+1});
		else
			image1=imread(filepath{ensemble_i1});
			image2=imread(filepath{ensemble_i1+1});
		end
	else % video file was passed
		image1 = read(filepath,video_frame_selection(ensemble_i1));
		image2 = read(filepath,video_frame_selection(ensemble_i1+1));
	end
	if size(image1,3)>1
		image1=uint8(mean(image1,3));
		image2=uint8(mean(image2,3));
		%disp('Warning: To optimize speed, your images should be grayscale, 8 bit!')
	end
	%Subtract background (if existent)
	if ~isempty(bg_img_A)
		image1=image1-bg_img_A;
	end
	if ~isempty(bg_img_B)
		image2=image2-bg_img_B;
	end
	%if autolimit == 1 %if autolimit is desired: do autolimit for each image seperately
		if size(image1,3)>1
			stretcher = stretchlim(rgb2gray(image1));
		else
			stretcher = stretchlim(image1);
		end
		minintens1 = stretcher(1);
		maxintens1 = stretcher(2);
		if size(image2,3)>1
			stretcher = stretchlim(rgb2gray(image2));
		else
			stretcher = stretchlim(image2);
		end
		minintens2 = stretcher(1);
		maxintens2 = stretcher(2);
	%end
	image1 = PIVlab_preproc (image1,roi_inpt,clahe, clahesize,highp,highpsize,intenscap,wienerwurst,wienerwurstsize,minintens1,maxintens1);
	image2 = PIVlab_preproc (image2,roi_inpt,clahe, clahesize,highp,highpsize,intenscap,wienerwurst,wienerwurstsize,minintens2,maxintens2);
	if numel(roi_inpt)>0
		xroi=roi_inpt(1);
		yroi=roi_inpt(2);
		widthroi=roi_inpt(3);
		heightroi=roi_inpt(4);
		image1_roi=double(image1(yroi:yroi+heightroi,xroi:xroi+widthroi));
		image2_roi=double(image2(yroi:yroi+heightroi,xroi:xroi+widthroi));
	else
		xroi=0;
		yroi=0;
		image1_roi=double(image1);
		image2_roi=double(image2);
	end
	gen_image1_roi = image1_roi;
	gen_image2_roi = image2_roi;
	%prepare a matrix for calculating the average mask of all images
	if ensemble_i1==1
		average_mask=zeros(size(image1_roi));
	end
	%get mask from mask list
	ximask={};
	yimask={};
	if size(maskiererx,2)>=ensemble_i1
		for j=1:size(maskiererx,1)
			if isempty(maskiererx{j,ensemble_i1})==0
				ximask{j,1}=maskiererx{j,ensemble_i1}; %#ok<*AGROW>
				yimask{j,1}=maskierery{j,ensemble_i1};
			else
				break
			end
		end
		if size(ximask,1)>0
			mask_inpt=[ximask yimask];
		else
			mask_inpt=[];
		end
	else
		mask_inpt=[];
	end
	if numel(mask_inpt)>0
		cellmask=mask_inpt;
		mask=zeros(size(image1_roi));
		for i=1:size(cellmask,1)
			masklayerx=cellmask{i,1};
			masklayery=cellmask{i,2};
			mask = mask + poly2mask(masklayerx-xroi,masklayery-yroi,size(image1_roi,1),size(image1_roi,2)); %kleineres eingangsbild und maske geshiftet
		end
	else
		mask=zeros(size(image1_roi));
	end
	mask(mask>1)=1;
	gen_mask = mask;
	try
		average_mask=average_mask + mask; %will fail if images are not same dimensions.
	catch
		cancel = 1;
		hgui=getappdata(0,'hgui');
		setappdata(hgui, 'cancel', cancel);
		text(gca(getappdata(0,'hgui')),10,10,'Error: Image dimensions inconsistent!','color',[1 0 0],'fontsize',20)
		drawnow;
		break
	end
	miniy=1+(ceil(interrogationarea/2));
	minix=1+(ceil(interrogationarea/2));
	maxiy=step*(floor(size(image1_roi,1)/step))-(interrogationarea-1)+(ceil(interrogationarea/2)); %statt size deltax von ROI nehmen
	maxix=step*(floor(size(image1_roi,2)/step))-(interrogationarea-1)+(ceil(interrogationarea/2));

	numelementsy=floor((maxiy-miniy)/step+1);
	numelementsx=floor((maxix-minix)/step+1);

	LAy=miniy;
	LAx=minix;
	LUy=size(image1_roi,1)-maxiy;
	LUx=size(image1_roi,2)-maxix;
	shift4centery=round((LUy-LAy)/2);
	shift4centerx=round((LUx-LAx)/2);
	if shift4centery<0 %shift4center will be negative if in the unshifted case the left border is bigger than the right border. the vectormatrix is hence not centered on the image. the matrix cannot be shifted more towards the left border because then image2_crop would have a negative index. The only way to center the matrix would be to remove a column of vectors on the right side. but then we weould have less data....
		shift4centery=0;
	end
	if shift4centerx<0 %shift4center will be negative if in the unshifted case the left border is bigger than the right border. the vectormatrix is hence not centered on the image. the matrix cannot be shifted more towards the left border because then image2_crop would have a negative index. The only way to center the matrix would be to remove a column of vectors on the right side. but then we weould have less data....
		shift4centerx=0;
	end
	miniy=miniy+shift4centery;
	minix=minix+shift4centerx;
	maxix=maxix+shift4centerx;
	maxiy=maxiy+shift4centery;

	image1_roi=padarray(image1_roi,[ceil(interrogationarea/2) ceil(interrogationarea/2)], min(min(image1_roi)));
	image2_roi=padarray(image2_roi,[ceil(interrogationarea/2) ceil(interrogationarea/2)], min(min(image1_roi)));
	mask=padarray(mask,[ceil(interrogationarea/2) ceil(interrogationarea/2)],0);

	if (rem(interrogationarea,2) == 0) %for the subpixel displacement measurement
		SubPixOffset=1;
	else
		SubPixOffset=0.5;
	end
	xtable=zeros(numelementsy,numelementsx);
	ytable=xtable; %#ok<*NASGU>
	utable=xtable;
	vtable=xtable;
	typevector=ones(numelementsy,numelementsx);

	%% MAINLOOP
	try %check if used from GUI
		handles=guihandles(getappdata(0,'hgui'));
		GUI_avail=1;
		hgui=getappdata(0,'hgui');
		cancel=getappdata(hgui, 'cancel');
		if cancel == 1
			break
			%disp('user cancelled');
		end

	catch %#ok<CTCH>
		GUI_avail=0;
		disp('no GUI')
	end
	% divide images by small pictures
	% new index for image1_roi and image2_roi
	s0 = (repmat((miniy:step:maxiy)'-1, 1,numelementsx) + repmat(((minix:step:maxix)-1)*size(image1_roi, 1), numelementsy,1))';
	s0 = permute(s0(:), [2 3 1]);
	s1 = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
	ss1 = repmat(s1, [1, 1, size(s0,3)])+repmat(s0, [interrogationarea, interrogationarea, 1]);

	image1_cut = image1_roi(ss1);
	image2_cut = image2_roi(ss1);

	if do_pad==1 && passes == 1 %only on first pass
		%subtract mean to avoid high frequencies at border of correlation:
		image1_cut=image1_cut-mean(image1_cut,[1 2]);
		image2_cut=image2_cut-mean(image2_cut,[1 2]);
		% padding (faster than padarray) to get the linear correlation:
		image1_cut=[image1_cut zeros(interrogationarea,interrogationarea-1,size(image1_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cut,3))];
		image2_cut=[image2_cut zeros(interrogationarea,interrogationarea-1,size(image2_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cut,3))];
	end
	%do fft2:

	result_conv = fftshift(fftshift(real(ifft2(conj(fft2(image1_cut)).*fft2(image2_cut))), 1), 2);
	if do_pad==1 && passes == 1
		%cropping of correlation matrix:
		result_conv =result_conv((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
	end

	%% repeated  Correlation in the first pass (might make sense to repeat more often to make it even more robust...)
	if repeat == 1 && passes == 1
		ms=round(step/4); %multishift parameter so groß wie viertel int window
		%Shift left bot
		s0B = (repmat((miniy+ms:step:maxiy+ms)'-1, 1,numelementsx) + repmat(((minix-ms:step:maxix-ms)-1)*size(image1_roi, 1), numelementsy,1))';
		s0B = permute(s0B(:), [2 3 1]);
		s1B = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
		ss1B = repmat(s1B, [1, 1, size(s0B,3)])+repmat(s0B, [interrogationarea, interrogationarea, 1]);
		image1_cutB = image1_roi(ss1B);
		image2_cutB = image2_roi(ss1B);
		if do_pad==1 && passes == 1
			%subtract mean to avoid high frequencies at border of correlation:
			image1_cutB=image1_cutB-mean(image1_cutB,[1 2]);
			image2_cutB=image2_cutB-mean(image2_cutB,[1 2]);
			% padding (faster than padarray) to get the linear correlation:
			image1_cutB=[image1_cutB zeros(interrogationarea,interrogationarea-1,size(image1_cutB,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cutB,3))];
			image2_cutB=[image2_cutB zeros(interrogationarea,interrogationarea-1,size(image2_cutB,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cutB,3))];
		end
		result_convB = fftshift(fftshift(real(ifft2(conj(fft2(image1_cutB)).*fft2(image2_cutB))), 1), 2);
		if do_pad==1 && passes == 1
			%cropping of correlation matrix:
			result_convB =result_convB((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
		end

		%Shift right bot
		s0C = (repmat((miniy+ms:step:maxiy+ms)'-1, 1,numelementsx) + repmat(((minix+ms:step:maxix+ms)-1)*size(image1_roi, 1), numelementsy,1))';
		s0C = permute(s0C(:), [2 3 1]);
		s1C = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
		ss1C = repmat(s1C, [1, 1, size(s0C,3)])+repmat(s0C, [interrogationarea, interrogationarea, 1]);
		image1_cutC = image1_roi(ss1C);
		image2_cutC = image2_roi(ss1C);
		if do_pad==1 && passes == 1
			%subtract mean to avoid high frequencies at border of correlation:
			image1_cutC=image1_cutC-mean(image1_cutC,[1 2]);
			image2_cutC=image2_cutC-mean(image2_cutC,[1 2]);
			% padding (faster than padarray) to get the linear correlation:
			image1_cutC=[image1_cutC zeros(interrogationarea,interrogationarea-1,size(image1_cutC,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cutC,3))];
			image2_cutC=[image2_cutC zeros(interrogationarea,interrogationarea-1,size(image2_cutC,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cutC,3))];
		end
		result_convC = fftshift(fftshift(real(ifft2(conj(fft2(image1_cutC)).*fft2(image2_cutC))), 1), 2);
		if do_pad==1 && passes == 1
			%cropping of correlation matrix:
			result_convC =result_convC((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
		end

		%Shift left top
		s0D = (repmat((miniy-ms:step:maxiy-ms)'-1, 1,numelementsx) + repmat(((minix-ms:step:maxix-ms)-1)*size(image1_roi, 1), numelementsy,1))';
		s0D = permute(s0D(:), [2 3 1]);
		s1D = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
		ss1D = repmat(s1D, [1, 1, size(s0D,3)])+repmat(s0D, [interrogationarea, interrogationarea, 1]);
		image1_cutD = image1_roi(ss1D);
		image2_cutD = image2_roi(ss1D);

		if do_pad==1 && passes == 1
			%subtract mean to avoid high frequencies at border of correlation:
			image1_cutD=image1_cutD-mean(image1_cutD,[1 2]);
			image2_cutD=image2_cutD-mean(image2_cutD,[1 2]);
			% padding (faster than padarray) to get the linear correlation:
			image1_cutD=[image1_cutD zeros(interrogationarea,interrogationarea-1,size(image1_cutD,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cutD,3))];
			image2_cutD=[image2_cutD zeros(interrogationarea,interrogationarea-1,size(image2_cutD,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cutD,3))];
		end
		result_convD = fftshift(fftshift(real(ifft2(conj(fft2(image1_cutD)).*fft2(image2_cutD))), 1), 2);
		if do_pad==1 && passes == 1
			%cropping of correlation matrix:
			result_convD =result_convD((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
		end

		%Shift right top
		s0E = (repmat((miniy-ms:step:maxiy-ms)'-1, 1,numelementsx) + repmat(((minix+ms:step:maxix+ms)-1)*size(image1_roi, 1), numelementsy,1))';
		s0E = permute(s0E(:), [2 3 1]);
		s1E = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
		ss1E = repmat(s1E, [1, 1, size(s0E,3)])+repmat(s0E, [interrogationarea, interrogationarea, 1]);
		image1_cutE = image1_roi(ss1E);
		image2_cutE = image2_roi(ss1E);
		if do_pad==1 && passes == 1
			%subtract mean to avoid high frequencies at border of correlation:
			image1_cutE=image1_cutE-mean(image1_cutE,[1 2]);
			image2_cutE=image2_cutE-mean(image2_cutE,[1 2]);
			% padding (faster than padarray) to get the linear correlation:
			image1_cutE=[image1_cutE zeros(interrogationarea,interrogationarea-1,size(image1_cutE,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cutE,3))];
			image2_cutE=[image2_cutE zeros(interrogationarea,interrogationarea-1,size(image2_cutE,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cutE,3))];
		end
		result_convE = fftshift(fftshift(real(ifft2(conj(fft2(image1_cutE)).*fft2(image2_cutE))), 1), 2);
		if do_pad==1 && passes == 1
			%cropping of correlation matrix:
			result_convE =result_convE((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
		end
		result_conv=result_conv.*result_convB.*result_convC.*result_convD.*result_convE;
	end

	if mask_auto == 1
		%das zentrum der Matrize (3x3) mit dem mittelwert ersetzen = Keine Autokorrelation
		%MARKER
		h = fspecial('gaussian', 3, 1.5);
		h=h/h(2,2);
		h=1-h;
		%h=repmat(h,1,1,size(result_conv,3));
		h=repmat(h,[1,1,size(result_conv,3)]);
		h=h.*result_conv((interrogationarea/2)+SubPixOffset-1:(interrogationarea/2)+SubPixOffset+1,(interrogationarea/2)+SubPixOffset-1:(interrogationarea/2)+SubPixOffset+1,:);
		result_conv((interrogationarea/2)+SubPixOffset-1:(interrogationarea/2)+SubPixOffset+1,(interrogationarea/2)+SubPixOffset-1:(interrogationarea/2)+SubPixOffset+1,:)=h;
	end
	%apply mask
	ii = find(mask(ss1(round(interrogationarea/2+1), round(interrogationarea/2+1), :)));
	result_conv(:,:, ii) = 0;
	%average the correlation matrices
	try
		result_conv_ensemble=result_conv_ensemble+result_conv;
	catch % older matlab releases
		result_conv_ensemble = zeros(size(result_conv));
		result_conv_ensemble=result_conv_ensemble+result_conv;
	end

	if GUI_avail==1
		progri=ensemble_i1/(amount_input_imgs)*100;
		from_total=from_total+1;
		set(handles.progress, 'string' , ['Pass ' int2str(1) ' progress: ' int2str(progri) '%' ])
		set(handles.overall, 'string' , ['Total progress: ' int2str(from_total / total_analyses_amount * 100) '%'])
		zeit=toc;
		done=from_total;
		tocome=total_analyses_amount-done;
		zeit=zeit/done*tocome;
		hrs=zeit/60^2;
		mins=(hrs-floor(hrs))*60;
		secs=(mins-floor(mins))*60;
		hrs=floor(hrs);
		mins=floor(mins);
		secs=floor(secs);
		set(handles.totaltime,'string', ['Time left: ' sprintf('%2.2d', hrs) 'h ' sprintf('%2.2d', mins) 'm ' sprintf('%2.2d', secs) 's']);

		%xxx update display every 10 frames...?
		%aber wie, dann müsste man peakfinder machen
		if skippy ==0
			[xtable,ytable,utable, vtable] = peakfinding (result_conv_ensemble, mask, interrogationarea,minix,step,maxix,miniy,maxiy,SubPixOffset,ss1,subpixfinder);
			if verLessThan('matlab','8.4')
				delete (findobj(getappdata(0,'hgui'),'type', 'hggroup'))
			else
				delete (findobj(getappdata(0,'hgui'),'type', 'quiver'))
			end
			hold on;
			vecscale=str2double(get(handles.vectorscale,'string'));
			%Problem: wenn colorbar an, zï¿½hlt das auch als aexes...
			colorbar('off')

			%u_table original gibts nicjt, braichts auch nicht...
			quiver ((findobj(getappdata(0,'hgui'),'type', 'axes')),xtable(isnan(utable)==0)+xroi-interrogationarea/2,ytable(isnan(utable)==0)+yroi-interrogationarea/2,utable(isnan(utable)==0)*vecscale,vtable(isnan(utable)==0)*vecscale,'Color', [1-(from_total / total_analyses_amount) (from_total / total_analyses_amount) 0.15],'autoscale','off')
			%quiver ((findobj(getappdata(0,'hgui'),'type', 'axes')),xtable(isnan(utable)==1)+xroi-interrogationarea/2,ytable(isnan(utable)==1)+yroi-interrogationarea/2,utable(isnan(utable)==1)*vecscale,vtable(isnan(utable)==1)*vecscale,'Color',[0.7 0.15 0.15], 'autoscale','off')
			hold off
			drawnow;
		end
		if skippy <10
			skippy=skippy+1;
		else
			skippy=0;
		end
		try
			drawnow limitrate
		catch
			drawnow
		end
	else
		fprintf('.');
	end
	if passes==1 % only 1 pass selected, so correlation coefficient will be calculated in this (first & final) pass.
		if ensemble_i1==1 %first image pair
			correlation_map=zeros(size(typevector));
			corr_map_cnt=0;
		end
		for cor_i=1:size(image1_cut,3)
			correlation_map(cor_i)=correlation_map(cor_i) + corr2(image1_cut(:,:,cor_i),image2_cut(:,:,cor_i));
		end
		corr_map_cnt=corr_map_cnt+1;
	end
end
%correlation_map=[];
if cancel == 0
	%% Correlation matrix of pass 1 is done.
	[xtable,ytable,utable, vtable] = peakfinding (result_conv_ensemble, mask, interrogationarea,minix,step,maxix,miniy,maxiy,SubPixOffset,ss1,subpixfinder);

	for multipass=1:passes-1
		% unfortunately, preprocessing has to be done again for every pass, otherwise i would have to save the modified data somehow.
		if multipass==1
			interrogationarea=round(int2/2)*2;
		end
		if multipass==2
			interrogationarea=round(int3/2)*2;
		end
		if multipass==3
			interrogationarea=round(int4/2)*2;
		end
		result_conv_ensemble = zeros(interrogationarea,interrogationarea); % prepare empty result_conv
		skippy=0;
		for ensemble_i1=1:2:amount_input_imgs
			if skippy <10
				skippy=skippy+1;
			else
				skippy=0;
			end
			if isempty(video_frame_selection) %list with image files was passed
				if strcmp(ext,'.b16')
					image1=f_readB16(filepath{ensemble_i1});
					image2=f_readB16(filepath{ensemble_i1+1});
				else
					image1=imread(filepath{ensemble_i1});
					image2=imread(filepath{ensemble_i1+1});
				end
			else % video file was passed
				image1 = read(filepath,video_frame_selection(ensemble_i1));
				image2 = read(filepath,video_frame_selection(ensemble_i1+1));
			end
			if size(image1,3)>1
				image1=uint8(mean(image1,3));
				image2=uint8(mean(image2,3));
			end
			%subtract bg if present
			if ~isempty(bg_img_A)
				image1=image1-bg_img_A;
			end
			if ~isempty(bg_img_B)
				image2=image2-bg_img_B;
			end
			%if autolimit == 1 %if autolimit is desired: do autolimit for each image seperately
				if size(image1,3)>1
					stretcher = stretchlim(rgb2gray(image1));
				else
					stretcher = stretchlim(image1);
				end
				minintens1 = stretcher(1);
				maxintens1 = stretcher(2);
				if size(image2,3)>1
					stretcher = stretchlim(rgb2gray(image2));
				else
					stretcher = stretchlim(image2);
				end
				minintens2 = stretcher(1);
				maxintens2 = stretcher(2);
			%end
			image1 = PIVlab_preproc (image1,roi_inpt,clahe, clahesize,highp,highpsize,intenscap,wienerwurst,wienerwurstsize,minintens1,maxintens1);
			image2 = PIVlab_preproc (image2,roi_inpt,clahe, clahesize,highp,highpsize,intenscap,wienerwurst,wienerwurstsize,minintens2,maxintens2);
			if numel(roi_inpt)>0
				xroi=roi_inpt(1);
				yroi=roi_inpt(2);
				widthroi=roi_inpt(3);
				heightroi=roi_inpt(4);
				image1_roi=double(image1(yroi:yroi+heightroi,xroi:xroi+widthroi));
				image2_roi=double(image2(yroi:yroi+heightroi,xroi:xroi+widthroi));
			else
				xroi=0;
				yroi=0;
				image1_roi=double(image1);
				image2_roi=double(image2);
			end
			gen_image1_roi = image1_roi;
			gen_image2_roi = image2_roi;
			if GUI_avail==1
				progri=ensemble_i1/(amount_input_imgs)*100;
				from_total=from_total+1;
				set(handles.progress, 'string' , ['Pass ' int2str(multipass+1) ' progress: ' int2str(progri) '%' ])
				set(handles.overall, 'string' , ['Total progress: ' int2str(from_total / total_analyses_amount * 100) '%'])

				zeit=toc;
				done=from_total;
				tocome=total_analyses_amount-done;
				zeit=zeit/done*tocome;
				hrs=zeit/60^2;
				mins=(hrs-floor(hrs))*60;
				secs=(mins-floor(mins))*60;
				hrs=floor(hrs);
				mins=floor(mins);
				secs=floor(secs);
				set(handles.totaltime,'string', ['Time left: ' sprintf('%2.2d', hrs) 'h ' sprintf('%2.2d', mins) 'm ' sprintf('%2.2d', secs) 's']);
				try
					drawnow limitrate

				catch
					drawnow
				end
			else
				fprintf('.');
			end
			%multipass validation, smoothing
			utable_orig=utable;
			vtable_orig=vtable;
			[utable,vtable] = PIVlab_postproc (utable,vtable,[],[], [], 1,4, 1,1.5);
			if GUI_avail==1
				cancel=getappdata(hgui, 'cancel');
				if cancel == 1
					break
					%disp('user cancelled');
				end
				if skippy ==0
					if verLessThan('matlab','8.4')
						delete (findobj(getappdata(0,'hgui'),'type', 'hggroup'))
					else
						delete (findobj(getappdata(0,'hgui'),'type', 'quiver'))
					end
					hold on;
					vecscale=str2double(get(handles.vectorscale,'string'));
					%Problem: wenn colorbar an, zï¿½hlt das auch als aexes...
					colorbar('off')
					quiver ((findobj(getappdata(0,'hgui'),'type', 'axes')),xtable(isnan(utable)==0)+xroi-interrogationarea/2,ytable(isnan(utable)==0)+yroi-interrogationarea/2,utable(isnan(utable)==0)*vecscale,vtable(isnan(utable)==0)*vecscale,'Color', [1-(from_total / total_analyses_amount) (from_total / total_analyses_amount) 0.15],'autoscale','off')

					%                    quiver ((findobj(getappdata(0,'hgui'),'type', 'axes')),xtable(isnan(utable)==0)+xroi-interrogationarea/2,ytable(isnan(utable)==0)+yroi-interrogationarea/2,utable_orig(isnan(utable)==0)*vecscale,vtable_orig(isnan(utable)==0)*vecscale,'Color', [0.15 0.7 0.15],'autoscale','off')
					%quiver ((findobj(getappdata(0,'hgui'),'type', 'axes')),xtable(isnan(utable)==1)+xroi-interrogationarea/2,ytable(isnan(utable)==1)+yroi-interrogationarea/2,utable_orig(isnan(utable)==1)*vecscale,vtable_orig(isnan(utable)==1)*vecscale,'Color',[0.7 0.15 0.15], 'autoscale','off')
					drawnow
					hold off
				end
			end
			%replace nans
			utable=inpaint_nans(utable,4);
			vtable=inpaint_nans(vtable,4);
			%smooth predictor
			try
				if multipass<passes-1
					utable = smoothn(utable,0.6); %stronger smoothing for first passes
					vtable = smoothn(vtable,0.6);
				else
					utable = smoothn(utable); %weaker smoothing for last pass
					vtable = smoothn(vtable);
				end
			catch
				%old matlab versions: gaussian kernel
				h=fspecial('gaussian',5,1);
				utable=imfilter(utable,h,'replicate');
				vtable=imfilter(vtable,h,'replicate');
			end
			if multipass==1
				interrogationarea=round(int2/2)*2;
			end
			if multipass==2
				interrogationarea=round(int3/2)*2;
			end
			if multipass==3
				interrogationarea=round(int4/2)*2;
			end
			step=interrogationarea/2;

			%bildkoordinaten neu errechnen:
			image1_roi = gen_image1_roi;
			image2_roi = gen_image2_roi;
			%get mask from mask list
			ximask={};
			yimask={};
			if size(maskiererx,2)>=ensemble_i1
				for j=1:size(maskiererx,1)
					if isempty(maskiererx{j,ensemble_i1})==0
						ximask{j,1}=maskiererx{j,ensemble_i1}; %#ok<*AGROW>
						yimask{j,1}=maskierery{j,ensemble_i1};
					else
						break
					end
				end
				if size(ximask,1)>0
					mask_inpt=[ximask yimask];
				else
					mask_inpt=[];
				end
			else
				mask_inpt=[];
			end
			if numel(mask_inpt)>0
				cellmask=mask_inpt;
				mask=zeros(size(image1_roi));
				for i=1:size(cellmask,1)
					masklayerx=cellmask{i,1};
					masklayery=cellmask{i,2};
					mask = mask + poly2mask(masklayerx-xroi,masklayery-yroi,size(image1_roi,1),size(image1_roi,2)); %kleineres eingangsbild und maske geshiftet
				end
			else
				mask=zeros(size(image1_roi));
			end
			mask(mask>1)=1;
			gen_mask = mask;
			miniy=1+(ceil(interrogationarea/2));
			minix=1+(ceil(interrogationarea/2));
			maxiy=step*(floor(size(image1_roi,1)/step))-(interrogationarea-1)+(ceil(interrogationarea/2)); %statt size deltax von ROI nehmen
			maxix=step*(floor(size(image1_roi,2)/step))-(interrogationarea-1)+(ceil(interrogationarea/2));

			numelementsy=floor((maxiy-miniy)/step+1);
			numelementsx=floor((maxix-minix)/step+1);

			LAy=miniy;
			LAx=minix;
			LUy=size(image1_roi,1)-maxiy;
			LUx=size(image1_roi,2)-maxix;
			shift4centery=round((LUy-LAy)/2);
			shift4centerx=round((LUx-LAx)/2);
			if shift4centery<0 %shift4center will be negative if in the unshifted case the left border is bigger than the right border. the vectormatrix is hence not centered on the image. the matrix cannot be shifted more towards the left border because then image2_crop would have a negative index. The only way to center the matrix would be to remove a column of vectors on the right side. but then we weould have less data....
				shift4centery=0;
			end
			if shift4centerx<0 %shift4center will be negative if in the unshifted case the left border is bigger than the right border. the vectormatrix is hence not centered on the image. the matrix cannot be shifted more towards the left border because then image2_crop would have a negative index. The only way to center the matrix would be to remove a column of vectors on the right side. but then we weould have less data....
				shift4centerx=0;
			end
			miniy=miniy+shift4centery;
			minix=minix+shift4centerx;
			maxix=maxix+shift4centerx;
			maxiy=maxiy+shift4centery;

			image1_roi=padarray(image1_roi,[ceil(interrogationarea/2) ceil(interrogationarea/2)], min(min(image1_roi)));
			image2_roi=padarray(image2_roi,[ceil(interrogationarea/2) ceil(interrogationarea/2)], min(min(image1_roi)));
			mask=padarray(mask,[ceil(interrogationarea/2) ceil(interrogationarea/2)],0);
			if (rem(interrogationarea,2) == 0) %for the subpixel displacement measurement
				SubPixOffset=1;
			else
				SubPixOffset=0.5;
			end

			xtable_old=xtable;
			ytable_old=ytable;
			typevector=ones(numelementsy,numelementsx);
			xtable = repmat((minix:step:maxix), numelementsy, 1) + interrogationarea/2;
			ytable = repmat((miniy:step:maxiy)', 1, numelementsx) + interrogationarea/2;

			%xtable alt und neu geben koordinaten wo die vektoren herkommen.
			%d.h. u und v auf die gewï¿½nschte grï¿½ï¿½e bringen+interpolieren

			utable=interp2(xtable_old,ytable_old,utable,xtable,ytable,'*spline');
			vtable=interp2(xtable_old,ytable_old,vtable,xtable,ytable,'*spline');

			utable_1= padarray(utable, [1,1], 'replicate');
			vtable_1= padarray(vtable, [1,1], 'replicate');

			%add 1 line around image for border regions... linear extrap

			firstlinex=xtable(1,:);
			firstlinex_intp=interp1(1:1:size(firstlinex,2),firstlinex,0:1:size(firstlinex,2)+1,'linear','extrap');
			xtable_1=repmat(firstlinex_intp,size(xtable,1)+2,1);

			firstliney=ytable(:,1);
			firstliney_intp=interp1(1:1:size(firstliney,1),firstliney,0:1:size(firstliney,1)+1,'linear','extrap')';
			ytable_1=repmat(firstliney_intp,1,size(ytable,2)+2);

			X=xtable_1; %original locations of vectors in whole image
			Y=ytable_1;
			U=utable_1; %interesting portion of u
			V=vtable_1; % "" of v

			X1=X(1,1):1:X(1,end)-1;
			Y1=(Y(1,1):1:Y(end,1)-1)';
			X1=repmat(X1,size(Y1, 1),1);
			Y1=repmat(Y1,1,size(X1, 2));

			U1 = interp2(X,Y,U,X1,Y1,'*linear');
			V1 = interp2(X,Y,V,X1,Y1,'*linear');

			image2_crop_i1 = interp2(1:size(image2_roi,2),(1:size(image2_roi,1))',double(image2_roi),X1+U1,Y1+V1,imdeform); %linear is 3x faster and looks ok...

			xb = find(X1(1,:) == xtable_1(1,1));
			yb = find(Y1(:,1) == ytable_1(1,1));

			% divide images by small pictures
			% new index for image1_roi
			s0 = (repmat((miniy:step:maxiy)'-1, 1,numelementsx) + repmat(((minix:step:maxix)-1)*size(image1_roi, 1), numelementsy,1))';
			s0 = permute(s0(:), [2 3 1]);
			s1 = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
			ss1 = repmat(s1, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
			% new index for image2_crop_i1
			s0 = (repmat(yb-step+step*(1:numelementsy)'-1, 1,numelementsx) + repmat((xb-step+step*(1:numelementsx)-1)*size(image2_crop_i1, 1), numelementsy,1))';
			s0 = permute(s0(:), [2 3 1]) - s0(1);
			s2 = repmat((1:2*step)',1,2*step) + repmat(((1:2*step)-1)*size(image2_crop_i1, 1),2*step,1);
			ss2 = repmat(s2, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
			image1_cut = image1_roi(ss1);
			image2_cut = image2_crop_i1(ss2);
			if do_pad==1 && multipass==passes-1
				%subtract mean to avoid high frequencies at border of correlation:
				try
					image1_cut=image1_cut-mean(image1_cut,[1 2]);
					image2_cut=image2_cut-mean(image2_cut,[1 2]);
				catch
					for oldmatlab=1:size(image1_cut,3);
						image1_cut(:,:,oldmatlab)=image1_cut(:,:,oldmatlab)-mean(mean(image1_cut(:,:,oldmatlab)));
						image2_cut(:,:,oldmatlab)=image2_cut(:,:,oldmatlab)-mean(mean(image2_cut(:,:,oldmatlab)));
					end
				end
				% padding (faster than padarray) to get the linear correlation:
				image1_cut=[image1_cut zeros(interrogationarea,interrogationarea-1,size(image1_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cut,3))];
				image2_cut=[image2_cut zeros(interrogationarea,interrogationarea-1,size(image2_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cut,3))];
			end
			%do fft2:
			result_conv = fftshift(fftshift(real(ifft2(conj(fft2(image1_cut)).*fft2(image2_cut))), 1), 2);
			if do_pad==1 && multipass==passes-1
				%cropping of correlation matrix:
				result_conv =result_conv((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
			end

			%% repeated correlation
			if repeat == 1 && multipass==passes-1
				ms=round(step/4); %multishift parameter so groß wie viertel int window

				%Shift left bot
				image2_crop_i1 = interp2(1:size(image2_roi,2),(1:size(image2_roi,1))',double(image2_roi),X1+U1-ms,Y1+V1+ms,imdeform); %linear is 3x faster and looks ok...
				xb = find(X1(1,:) == xtable_1(1,1));
				yb = find(Y1(:,1) == ytable_1(1,1));
				s0 = (repmat((miniy+ms:step:maxiy+ms)'-1, 1,numelementsx) + repmat(((minix-ms:step:maxix-ms)-1)*size(image1_roi, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]);
				s1 = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
				ss1 = repmat(s1, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				s0 = (repmat(yb-step+step*(1:numelementsy)'-1, 1,numelementsx) + repmat((xb-step+step*(1:numelementsx)-1)*size(image2_crop_i1, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]) - s0(1);
				s2 = repmat((1:2*step)',1,2*step) + repmat(((1:2*step)-1)*size(image2_crop_i1, 1),2*step,1);
				ss2 = repmat(s2, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				image1_cut = image1_roi(ss1);
				image2_cut = image2_crop_i1(ss2);
				if do_pad==1 && multipass==passes-1
					%subtract mean to avoid high frequencies at border of correlation:
					try
						image1_cut=image1_cut-mean(image1_cut,[1 2]);
						image2_cut=image2_cut-mean(image2_cut,[1 2]);
					catch
						for oldmatlab=1:size(image1_cut,3);
							image1_cut(:,:,oldmatlab)=image1_cut(:,:,oldmatlab)-mean(mean(image1_cut(:,:,oldmatlab)));
							image2_cut(:,:,oldmatlab)=image2_cut(:,:,oldmatlab)-mean(mean(image2_cut(:,:,oldmatlab)));
						end
					end
					% padding (faster than padarray) to get the linear correlation:
					image1_cut=[image1_cut zeros(interrogationarea,interrogationarea-1,size(image1_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cut,3))];
					image2_cut=[image2_cut zeros(interrogationarea,interrogationarea-1,size(image2_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cut,3))];
				end
				result_convB = fftshift(fftshift(real(ifft2(conj(fft2(image1_cut)).*fft2(image2_cut))), 1), 2);
				if do_pad==1 && multipass==passes-1
					%cropping of correlation matrix:
					result_convB =result_convB((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
				end
				%Shift right bot
				image2_crop_i1 = interp2(1:size(image2_roi,2),(1:size(image2_roi,1))',double(image2_roi),X1+U1+ms,Y1+V1+ms,imdeform); %linear is 3x faster and looks ok...
				xb = find(X1(1,:) == xtable_1(1,1));
				yb = find(Y1(:,1) == ytable_1(1,1));
				s0 = (repmat((miniy+ms:step:maxiy+ms)'-1, 1,numelementsx) + repmat(((minix+ms:step:maxix+ms)-1)*size(image1_roi, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]);
				s1 = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
				ss1 = repmat(s1, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				s0 = (repmat(yb-step+step*(1:numelementsy)'-1, 1,numelementsx) + repmat((xb-step+step*(1:numelementsx)-1)*size(image2_crop_i1, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]) - s0(1);
				s2 = repmat((1:2*step)',1,2*step) + repmat(((1:2*step)-1)*size(image2_crop_i1, 1),2*step,1);
				ss2 = repmat(s2, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				image1_cut = image1_roi(ss1);
				image2_cut = image2_crop_i1(ss2);
				if do_pad==1 && multipass==passes-1
					%subtract mean to avoid high frequencies at border of correlation:
					try
						image1_cut=image1_cut-mean(image1_cut,[1 2]);
						image2_cut=image2_cut-mean(image2_cut,[1 2]);
					catch
						for oldmatlab=1:size(image1_cut,3);
							image1_cut(:,:,oldmatlab)=image1_cut(:,:,oldmatlab)-mean(mean(image1_cut(:,:,oldmatlab)));
							image2_cut(:,:,oldmatlab)=image2_cut(:,:,oldmatlab)-mean(mean(image2_cut(:,:,oldmatlab)));
						end
					end
					% padding (faster than padarray) to get the linear correlation:
					image1_cut=[image1_cut zeros(interrogationarea,interrogationarea-1,size(image1_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cut,3))];
					image2_cut=[image2_cut zeros(interrogationarea,interrogationarea-1,size(image2_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cut,3))];
				end
				result_convC = fftshift(fftshift(real(ifft2(conj(fft2(image1_cut)).*fft2(image2_cut))), 1), 2);
				if do_pad==1 && multipass==passes-1
					%cropping of correlation matrix:
					result_convC =result_convC((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
				end
				%Shift left top
				image2_crop_i1 = interp2(1:size(image2_roi,2),(1:size(image2_roi,1))',double(image2_roi),X1+U1-ms,Y1+V1-ms,imdeform); %linear is 3x faster and looks ok...
				xb = find(X1(1,:) == xtable_1(1,1));
				yb = find(Y1(:,1) == ytable_1(1,1));
				s0 = (repmat((miniy-ms:step:maxiy-ms)'-1, 1,numelementsx) + repmat(((minix-ms:step:maxix-ms)-1)*size(image1_roi, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]);
				s1 = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
				ss1 = repmat(s1, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				s0 = (repmat(yb-step+step*(1:numelementsy)'-1, 1,numelementsx) + repmat((xb-step+step*(1:numelementsx)-1)*size(image2_crop_i1, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]) - s0(1);
				s2 = repmat((1:2*step)',1,2*step) + repmat(((1:2*step)-1)*size(image2_crop_i1, 1),2*step,1);
				ss2 = repmat(s2, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				image1_cut = image1_roi(ss1);
				image2_cut = image2_crop_i1(ss2);
				if do_pad==1 && multipass==passes-1
					%subtract mean to avoid high frequencies at border of correlation:
					try
						image1_cut=image1_cut-mean(image1_cut,[1 2]);
						image2_cut=image2_cut-mean(image2_cut,[1 2]);
					catch
						for oldmatlab=1:size(image1_cut,3)
							image1_cut(:,:,oldmatlab)=image1_cut(:,:,oldmatlab)-mean(mean(image1_cut(:,:,oldmatlab)));
							image2_cut(:,:,oldmatlab)=image2_cut(:,:,oldmatlab)-mean(mean(image2_cut(:,:,oldmatlab)));
						end
					end
					% padding (faster than padarray) to get the linear correlation:
					image1_cut=[image1_cut zeros(interrogationarea,interrogationarea-1,size(image1_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cut,3))];
					image2_cut=[image2_cut zeros(interrogationarea,interrogationarea-1,size(image2_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cut,3))];
				end
				result_convD = fftshift(fftshift(real(ifft2(conj(fft2(image1_cut)).*fft2(image2_cut))), 1), 2);
				if do_pad==1 && multipass==passes-1
					%cropping of correlation matrix:
					result_convD =result_convD((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
				end
				%Shift right top
				image2_crop_i1 = interp2(1:size(image2_roi,2),(1:size(image2_roi,1))',double(image2_roi),X1+U1+ms,Y1+V1-ms,imdeform); %linear is 3x faster and looks ok...
				xb = find(X1(1,:) == xtable_1(1,1));
				yb = find(Y1(:,1) == ytable_1(1,1));
				s0 = (repmat((miniy-ms:step:maxiy-ms)'-1, 1,numelementsx) + repmat(((minix+ms:step:maxix+ms)-1)*size(image1_roi, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]);
				s1 = repmat((1:interrogationarea)',1,interrogationarea) + repmat(((1:interrogationarea)-1)*size(image1_roi, 1),interrogationarea,1);
				ss1 = repmat(s1, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				s0 = (repmat(yb-step+step*(1:numelementsy)'-1, 1,numelementsx) + repmat((xb-step+step*(1:numelementsx)-1)*size(image2_crop_i1, 1), numelementsy,1))';
				s0 = permute(s0(:), [2 3 1]) - s0(1);
				s2 = repmat((1:2*step)',1,2*step) + repmat(((1:2*step)-1)*size(image2_crop_i1, 1),2*step,1);
				ss2 = repmat(s2, [1, 1, size(s0,3)]) + repmat(s0, [interrogationarea, interrogationarea, 1]);
				image1_cut = image1_roi(ss1);
				image2_cut = image2_crop_i1(ss2);
				if do_pad==1 && multipass==passes-1
					%subtract mean to avoid high frequencies at border of correlation:
					try
						image1_cut=image1_cut-mean(image1_cut,[1 2]);
						image2_cut=image2_cut-mean(image2_cut,[1 2]);
					catch
						for oldmatlab=1:size(image1_cut,3)
							image1_cut(:,:,oldmatlab)=image1_cut(:,:,oldmatlab)-mean(mean(image1_cut(:,:,oldmatlab)));
							image2_cut(:,:,oldmatlab)=image2_cut(:,:,oldmatlab)-mean(mean(image2_cut(:,:,oldmatlab)));
						end
					end
					% padding (faster than padarray) to get the linear correlation:
					image1_cut=[image1_cut zeros(interrogationarea,interrogationarea-1,size(image1_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image1_cut,3))];
					image2_cut=[image2_cut zeros(interrogationarea,interrogationarea-1,size(image2_cut,3)); zeros(interrogationarea-1,2*interrogationarea-1,size(image2_cut,3))];
				end
				result_convE = fftshift(fftshift(real(ifft2(conj(fft2(image1_cut)).*fft2(image2_cut))), 1), 2);
				if do_pad==1 && multipass==passes-1
					%cropping of correlation matrix:
					result_convE =result_convE((interrogationarea/2):(3*interrogationarea/2)-1,(interrogationarea/2):(3*interrogationarea/2)-1,:);
				end
				result_conv=result_conv.*result_convB.*result_convC.*result_convD.*result_convE;
			end

			if mask_auto == 1
				%limit peak search arena....
				emptymatrix=zeros(size(result_conv,1),size(result_conv,2),size(result_conv,3));
				%emptymatrix=emptymatrix+0.1;
				if interrogationarea > 8 % masking central peak will not work for extrmely small interrogation areas. And it also doesn't make sense.
					sizeones=4;
					%h = fspecial('gaussian', sizeones*2+1,1);
					h=fspecial('disk',4);
					h=h/max(max(h));
					%h=repmat(h,1,1,size(result_conv,3));
					h=repmat(h,[1,1,size(result_conv,3)]);
					emptymatrix((interrogationarea/2)+SubPixOffset-sizeones:(interrogationarea/2)+SubPixOffset+sizeones,(interrogationarea/2)+SubPixOffset-sizeones:(interrogationarea/2)+SubPixOffset+sizeones,:)=h;
					result_conv = result_conv .* emptymatrix;
				else
					disp('All interrogation areas must be larger than 8 pixels for disabling auto correlation successfully.')
				end
			end

			%apply mask ---
			ii = find(mask(ss1(round(interrogationarea/2+1), round(interrogationarea/2+1), :)));
			result_conv(:,:, ii) = 0;
			%add alle result_conv
			try
				result_conv_ensemble=result_conv_ensemble+result_conv;
			catch % older matlab releases
				result_conv_ensemble = zeros(size(result_conv));
				result_conv_ensemble=result_conv_ensemble+result_conv;
			end

			if multipass==passes-1 %correlation strength only in last pass

				if ensemble_i1==1 %first image pair
					correlation_map=zeros(size(typevector));
					corr_map_cnt=0;
				end
				%Correlation strength
				for cor_i=1:size(image1_cut,3)
					correlation_map(cor_i)=correlation_map(cor_i)+corr2(image1_cut(:,:,cor_i),image2_cut(:,:,cor_i));
				end
				corr_map_cnt=corr_map_cnt+1;
			end
		end
		[xtable,ytable,utable2, vtable2] = peakfinding (result_conv_ensemble, [], interrogationarea,minix,step,maxix,miniy,maxiy,SubPixOffset,ss1,subpixfinder);
		utable = utable+utable2;
		vtable = vtable+vtable2;
	end
	if cancel == 0
		%mask only if all frames are masked
		%apply mask
		nrx=0;
		nrxreal=0;
		nry=0;
		average_mask=padarray(average_mask,[ceil(interrogationarea/2) ceil(interrogationarea/2)],0);
		for jmask = miniy:step:maxiy %vertical loop
			nry=nry+1;
			for imask = minix:step:maxix % horizontal loop
				nrx=nrx+1;%used to determine the pos of the vector in resulting matrix
				if nrxreal < numelementsx
					nrxreal=nrxreal+1;
				else
					nrxreal=1;
				end
				%fehlerzeile:
				if average_mask(round(jmask+interrogationarea/2),round(imask+interrogationarea/2)) >= amount_input_imgs/2
					typevector(nry,nrxreal)=0;
				end
			end
		end
		xtable=xtable-ceil(interrogationarea/2);
		ytable=ytable-ceil(interrogationarea/2);

		xtable=xtable+xroi;
		ytable=ytable+yroi;
	end
	%% Write correlation matrices to the workspace
	%{
try
    counter=evalin('base','counter');
    counter=counter+1;
    assignin('base','counter',counter);
    all_matrices=evalin('base','all_matrices');
    all_matrices{end+1}=result_conv_ensemble;
    assignin('base','all_matrices',all_matrices);
    disp('appended matrix')
catch
    assignin('base','counter',1);
    all_matrices{1}=result_conv_ensemble;
    assignin('base','all_matrices',all_matrices);
    disp('created new matrix')
end
	%}
	correlation_map = permute(reshape(correlation_map, [size(xtable')]), [2 1 3])/corr_map_cnt;
	%clear Correlation map in masked area
	correlation_map(typevector==0) = 0;
end

function [xtable,ytable,utable, vtable] = peakfinding (result_conv_ensemble, mask, interrogationarea,minix,step,maxix,miniy,maxiy,SubPixOffset,ss1,subpixfinder)
minres = permute(repmat(squeeze(min(min(result_conv_ensemble))), [1, size(result_conv_ensemble, 1), size(result_conv_ensemble, 2)]), [2 3 1]);
deltares = permute(repmat(squeeze(max(max(result_conv_ensemble))-min(min(result_conv_ensemble))),[ 1, size(result_conv_ensemble, 1), size(result_conv_ensemble, 2)]), [2 3 1]);
result_conv_ensemble = ((result_conv_ensemble-minres)./deltares)*255;

%apply mask ---
if isempty (mask)==0
	ii = find(mask(ss1(round(interrogationarea/2+1), round(interrogationarea/2+1), :)));
	result_conv_ensemble(:,:, ii) = 0;
end

[y, x, z] = ind2sub(size(result_conv_ensemble), find(result_conv_ensemble==255));

% we need only one peak from each couple pictures
[z1, zi] = sort(z);
dz1 = [z1(1); diff(z1)];
i0 = find(dz1~=0);
x1 = x(zi(i0));
y1 = y(zi(i0));
z1 = z(zi(i0));

xtable = repmat((minix:step:maxix)+interrogationarea/2, length(miniy:step:maxiy), 1);
ytable = repmat(((miniy:step:maxiy)+interrogationarea/2)', 1, length(minix:step:maxix));

if subpixfinder==1
	[vector] = SUBPIXGAUSS (result_conv_ensemble,interrogationarea, x1, y1, z1, SubPixOffset);
elseif subpixfinder==2
	[vector] = SUBPIX2DGAUSS (result_conv_ensemble,interrogationarea, x1, y1, z1, SubPixOffset);
end
vector = permute(reshape(vector, [size(xtable') 2]), [2 1 3]);

utable = vector(:,:,1);
vtable = vector(:,:,2);

function [vector] = SUBPIXGAUSS(result_conv, interrogationarea, x, y, z, SubPixOffset)
%was hat peak nr.1 für einen Durchmesser?
%figure;imagesc((1-im2bw(uint8(result_conv(:,:,155)),0.9)).*result_conv(:,:,101))
xi = find(~((x <= (size(result_conv,2)-1)) & (y <= (size(result_conv,1)-1)) & (x >= 2) & (y >= 2)));
x(xi) = [];
y(xi) = [];
z(xi) = [];
xmax = size(result_conv, 2);
vector = NaN(size(result_conv,3), 2);
if(numel(x)~=0)
	ip = sub2ind(size(result_conv), y, x, z);
	%the following 8 lines are copyright (c) 1998, Uri Shavit, Roi Gurka, Alex Liberzon, Technion ï¿½ Israel Institute of Technology
	%http://urapiv.wordpress.com
	f0 = log(result_conv(ip));
	f1 = log(result_conv(ip-1));
	f2 = log(result_conv(ip+1));
	peaky = y + (f1-f2)./(2*f1-4*f0+2*f2);
	f0 = log(result_conv(ip));
	f1 = log(result_conv(ip-xmax));
	f2 = log(result_conv(ip+xmax));
	peakx = x + (f1-f2)./(2*f1-4*f0+2*f2);

	SubpixelX=peakx-(interrogationarea/2)-SubPixOffset;
	SubpixelY=peaky-(interrogationarea/2)-SubPixOffset;
	vector(z, :) = [SubpixelX, SubpixelY];
end

function [vector] = SUBPIX2DGAUSS(result_conv, interrogationarea, x, y, z, SubPixOffset)
xi = find(~((x <= (size(result_conv,2)-1)) & (y <= (size(result_conv,1)-1)) & (x >= 2) & (y >= 2)));
x(xi) = [];
y(xi) = [];
z(xi) = [];
xmax = size(result_conv, 2);
vector = NaN(size(result_conv,3), 2);
if(numel(x)~=0)
	c10 = zeros(3,3, length(z));
	c01 = c10;
	c11 = c10;
	c20 = c10;
	c02 = c10;
	ip = sub2ind(size(result_conv), y, x, z);

	for i = -1:1
		for j = -1:1
			%following 15 lines based on
			%H. Nobach ï¿½ M. Honkanen (2005)
			%Two-dimensional Gaussian regression for sub-pixel displacement
			%estimation in particle image velocimetry or particle position
			%estimation in particle tracking velocimetry
			%Experiments in Fluids (2005) 38: 511ï¿½515
			c10(j+2,i+2, :) = i*log(result_conv(ip+xmax*i+j));
			c01(j+2,i+2, :) = j*log(result_conv(ip+xmax*i+j));
			c11(j+2,i+2, :) = i*j*log(result_conv(ip+xmax*i+j));
			c20(j+2,i+2, :) = (3*i^2-2)*log(result_conv(ip+xmax*i+j));
			c02(j+2,i+2, :) = (3*j^2-2)*log(result_conv(ip+xmax*i+j));
			%c00(j+2,i+2)=(5-3*i^2-3*j^2)*log(result_conv_norm(maxY+j, maxX+i));
		end
	end
	c10 = (1/6)*sum(sum(c10));
	c01 = (1/6)*sum(sum(c01));
	c11 = (1/4)*sum(sum(c11));
	c20 = (1/6)*sum(sum(c20));
	c02 = (1/6)*sum(sum(c02));
	%c00=(1/9)*sum(sum(c00));

	deltax = squeeze((c11.*c01-2*c10.*c02)./(4*c20.*c02-c11.^2));
	deltay = squeeze((c11.*c10-2*c01.*c20)./(4*c20.*c02-c11.^2));
	peakx = x+deltax;
	peaky = y+deltay;

	SubpixelX = peakx-(interrogationarea/2)-SubPixOffset;
	SubpixelY = peaky-(interrogationarea/2)-SubPixOffset;

	vector(z, :) = [SubpixelX, SubpixelY];
end


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

function pmdistance = point_model_distance(P,cylinder)

% ---------------------------------------------------------------------
% POINT_MODEL_DISTANCE.M    Computes the distances of the points to the
%                               cylinder model
%
% Version 2.1.1
% Latest update     8 Oct 2021
%
% Copyright (C) 2015-2021 Pasi Raumonen
% ---------------------------------------------------------------------

% Changes from version 2.1.0 to 2.1.1, 8 Oct 2021:
% 1) Changed the determinationa NE, the number of empty edge layers, so
%     that is now limited in size, before it is given as input for
%     cubical_partition function.

% Changes from version 2.0.0 to 2.1.0, 26 Nov 2019:
% 1) Bug fix: Corrected the computation of the output at the end of the
%    code so that trees without branches are computed correctly.

% Cylinder data
Rad = cylinder.radius;
Len = cylinder.length;
Sta = cylinder.start;
Axe = cylinder.axis;
BOrd = cylinder.BranchOrder;

% Select randomly 25 % or max one million points for the distance comput.
np0 = size(P,1);
a = min(0.25*np0,1000000);
I = logical(round(0.5/(1-a/np0)*rand(np0,1)));
P = P(I,:);

% Partition the points into cubes
L = 2*median(Len);
NE = max(3,min(10,ceil(max(Len)/L)))+3;
[Partition,~,Info] = cubical_partition(P,L,NE);
Min = Info(1:3);
EL = Info(7);
NE = Info(8);

% Calculates the cube-coordinates of the starting points
CC = floor([Sta(:,1)-Min(1) Sta(:,2)-Min(2) Sta(:,3)-Min(3)]/EL)+NE+1;

% Compute the number of cubes needed for each starting point
N = ceil(Len/L);

% Correct N so that cube indexes are not too small or large
I = CC(:,1) < N+1;
N(I) = CC(I,1)-1;
I = CC(:,2) < N+1;
N(I) = CC(I,2)-1;
I = CC(:,3) < N+1;
N(I) = CC(I,3)-1;
I = CC(:,1)+N+1 > Info(4);
N(I) = Info(4)-CC(I,1)-1;
I = CC(:,2)+N+1 > Info(5);
N(I) = Info(5)-CC(I,2)-1;
I = CC(:,3)+N+1 > Info(6);
N(I) = Info(6)-CC(I,3)-1;

% Calculate the distances to the cylinders
n = size(Rad,1);
np = size(P,1);
Dist = zeros(np,2); % Distance and the closest cylinder of each points
Dist(:,1) = 2; % Large distance initially
Points = zeros(ceil(np/10),1,'int32'); % Auxiliary variable
Data = cell(n,1);
for i = 1:n
  Par = Partition(CC(i,1)-N(i):CC(i,1)+N(i),CC(i,2)-N(i):CC(i,2)+N(i),...
    CC(i,3)-N(i):CC(i,3)+N(i));
  if N(i) > 1
    S = cellfun('length',Par);
    I = S > 0;
    S = S(I);
    Par = Par(I);
    stop = cumsum(S);
    start = [0; stop]+1;
    for k = 1:length(stop)
      Points(start(k):stop(k)) = Par{k}(:);
    end
    points = Points(1:stop(k));
  else
    points = vertcat(Par{:});
  end
  [d,~,h] = distances_to_line(P(points,:),Axe(i,:),Sta(i,:));
  d = abs(d-Rad(i));
  Data{i} = [d h double(points)];
  I = d < Dist(points,1);
  J = h >= 0;
  K = h <= Len(i);
  L = d < 0.5;
  M = I&J&K&L;
  points = points(M);
  Dist(points,1) = d(M);
  Dist(points,2) = i;
end

% Calculate the distances to the cylinders for points not yet calculated
% because they are not "on side of cylinder
for i = 1:n
  if ~isempty(Data{i})
    d = Data{i}(:,1);
    h = Data{i}(:,2);
    points = Data{i}(:,3);
    I = d < Dist(points,1);
    J = h >= -0.1 & h <= 0;
    K = h <= Len(i)+0.1 & h >= Len(i);
    L = d < 0.5;
    M = I&(J|K)&L;
    points = points(M);
    Dist(points,1) = d(M);
    Dist(points,2) = i;
  end
end

% Select only the shortest 95% of distances for each cylinder
N = zeros(n,1);
O = zeros(np,1);
for i = 1:np
  if Dist(i,2) > 0
    N(Dist(i,2)) = N(Dist(i,2))+1;
    O(i) = N(Dist(i,2));
  end
end
Cyl = cell(n,1);
for i = 1:n
  Cyl{i} = zeros(N(i),1);
end
for i = 1:np
  if Dist(i,2) > 0
    Cyl{Dist(i,2)}(O(i)) = i;
  end
end
DistCyl = zeros(n,1); % Average point distance to each cylinder
for i = 1:n
  I = Cyl{i};
  m = length(I);
  if m > 19 % select the smallest 95% of distances
    d = sort(Dist(I,1));
    DistCyl(i) = mean(d(1:floor(0.95*m)));
  elseif m > 0
    DistCyl(i) = mean(Dist(I,1));
  end
end

% Define the output
pmdistance.CylDist = single(DistCyl);
pmdistance.median = median(DistCyl(:,1));
pmdistance.mean = mean(DistCyl(:,1));
pmdistance.max = max(DistCyl(:,1));
pmdistance.std = std(DistCyl(:,1));

T = BOrd == 0;
B1 = BOrd == 1;
B2 = BOrd == 2;
B = DistCyl(~T,1);
T = DistCyl(T,1);
B1 = DistCyl(B1,1);
B2 = DistCyl(B2,1);

pmdistance.TrunkMedian = median(T);
pmdistance.TrunkMean = mean(T);
pmdistance.TrunkMax = max(T);
pmdistance.TrunkStd = std(T);

if ~isempty(B)
  pmdistance.BranchMedian = median(B);
  pmdistance.BranchMean = mean(B);
  pmdistance.BranchMax = max(B);
  pmdistance.BranchStd = std(B);
else
  pmdistance.BranchMedian = 0;
  pmdistance.BranchMean = 0;
  pmdistance.BranchMax = 0;
  pmdistance.BranchStd = 0;
end

if ~isempty(B1)
  pmdistance.Branch1Median = median(B1);
  pmdistance.Branch1Mean = mean(B1);
  pmdistance.Branch1Max = max(B1);
  pmdistance.Branch1Std = std(B1);
else
  pmdistance.Branch1Median = 0;
  pmdistance.Branch1Mean = 0;
  pmdistance.Branch1Max = 0;
  pmdistance.Branch1Std = 0;
end

if ~isempty(B2)
  pmdistance.Branch2Median = median(B2);
  pmdistance.Branch2Mean = mean(B2);
  pmdistance.Branch2Max = max(B2);
  pmdistance.Branch2Std = std(B2);
else
  pmdistance.Branch2Median = 0;
  pmdistance.Branch2Mean = 0;
  pmdistance.Branch2Max = 0;
  pmdistance.Branch2Std = 0;
end


function M = imfiltermtx(F, sz, bndry);
%IMFILTERMTX   N-D image filtering matrix
%   M = IMFILTERMTX(F, SZ[, BNDRY]) returns the image filtering matrix
%   for the matrix F.  SZ gives the size of the array that the filtering
%   (convolution) should be applied to.  The returned matrix M is sparse.
%   If X is of size SZ, then reshape(M * X(:), SZ + size(F) - 1) is the
%   same as imfilter(X, F, BNDRY, 'conv').
%
%   The optional parameter BNDRY controls the boundary handling:
%     * 'replicate':  Input array values outside the bounds of the array
%                     are assumed to equal the nearest array border
%                     value.
%     * 'circular':   Input array values outside the bounds of the array
%                     wrap around to the opposite bound.
%     * '0':          (default) Input array values outside of the bounds
%                     of the array are assumed to be zero.
%
%   See also IMFILTER, MAKE_IMFILTER_MAT.
%
%   Author:  Stefan Roth, Department of Computer Science, TU Darmstadt
%   Contact: sroth@cs.tu-darmstadt.de
%   $Date: 2007-03-27 14:09:11 -0400 (Tue, 27 Mar 2007) $
%   $Revision: 252 $

% Copyright 2004-2007, Brown University, Providence, RI. USA
% Copyright 2007-2010 TU Darmstadt, Darmstadt, Germany.
%
%                          All Rights Reserved
%
% All commercial use of this software, whether direct or indirect, is
% strictly prohibited including, without limitation, incorporation into in
% a commercial product, use in a commercial service, or production of other
% artifacts for commercial purposes.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for research purposes is hereby granted without fee,
% provided that the above copyright notice appears in all copies and that
% both that copyright notice and this permission notice appear in
% supporting documentation, and that the name of the author and Brown
% University not be used in advertising or publicity pertaining to
% distribution of the software without specific, written prior permission.
%
% For commercial uses contact the Technology Venture Office of Brown University
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO
% THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR
% BROWN UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
% DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
% PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
% ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
% THIS SOFTWARE.

  % Size of padding for boundary handling
  pad_size = 0.5 * (size(F) - 1);

  % Corners of the original image in the padded image
  corner_lo = 1 + pad_size;
  corner_hi = size(F) + sz - 1 - pad_size;

  % Pixel index of the output image M
  M_idx = zeros(sz + size(F) - 1);
  M_idx(:) = 1:numel(M_idx);

  % Pixel index of the "input" image X
  X_idx = zeros(sz);
  X_idx(:) = 1:numel(X_idx);
  % Pad it to the size of M
  X_idx = [zeros(pad_size(1), sz(2) + size(F, 2) - 1); ...
           zeros(sz(1), pad_size(2)), X_idx, zeros(sz(1), pad_size(2)); ...
           zeros(pad_size(1), sz(2) + size(F, 2) - 1)];

  switch(bndry)
    case 'symmetric'
      error('Not implemented yet!')

    case 'replicate'
      % Replicate pixel values from the edges & corners

      % Fill all 4 corners
      for c = 0:3

        % Position or corner and range of block next to corner
        pos = cell(1, 2);
        rng = cell(1, 2);
        for d = 1:2
          if bitand(c, 2^(d-1))
            pos{d} = corner_hi(d);
            rng{d} = corner_hi(d)+1:size(M_idx, d);
          else
            pos{d} = corner_lo(d);
            rng{d} = 1:corner_lo(d)-1;
          end
        end

        % Get index of corner pixel
        idx = sub2ind(size(M_idx), pos{:});

        % Set entire block to corner pixel index
        M_idx(rng{:}) = idx;

      end

      % Fill all 4 edges
      for d = 1:2
        for c = 0:3

          % I don't quite understand this code anymore, but it appears to
          % work fine :)
          pos = cell(1, 2);
          rng = cell(1, 2);
          for e = 1:2
            if (d == e)
              pos{d} = corner_lo(e):corner_hi(e);
              rng{d} = corner_lo(e):corner_hi(e);
            else
              if bitand(c, 2^(e-1))
                pos{e} = repmat(corner_hi(e), 1, sz(d));
                rng{e} = corner_hi(e)+1:size(M_idx, e);
              else
                pos{e} = repmat(corner_lo(e), 1, sz(d));
                rng{e} = 1:corner_lo(e)-1;
              end
            end
          end

          % Get indices of edge pixels
          idx = sub2ind(size(M_idx), pos{:});

          % Generate fill indices from the nearest edge pixel
          tmp_sz = pad_size;
          tmp_sz(d) = 1;
          tmp2_sz = ones(1, 2);
          tmp2_sz(d) = sz(d);
          M_idx(rng{:}) = repmat(reshape(idx, tmp2_sz), tmp_sz);
        end
      end

      % Convert indices from the output image to the input image
      M_idx = X_idx(M_idx);

    case 'circular'
      % Create padded indices of rows and columns
      r = -pad_size(1)+1:sz(1)+pad_size(1);
      c = -pad_size(2)+1:sz(2)+pad_size(2);

      % Take the modolus to make sure they are in the valid bounds
      r = 1 + mod(r - 1, sz(1));
      c = 1 + mod(c - 1, sz(2));

      M_idx = sub2ind(sz, repmat(r(:), 1, length(c)), ...
                      repmat(c(:)', length(r), 1));

    otherwise
      % Assume all zeros outside of the boundaries
      M = convmtxn(F, sz);
      return;

  end

  % The pixel indices give a mapping of the columns of the padded image
  % to the output image
  col_map = M_idx(:);

  % Get convolution matrix and split the resulting sparse array
  M = make_convn_mat(F, sz + size(F) - 1, 'same');
  [rows, cols, vals] = find(M);

  % Re-assemble the sparse array, but use the column map to accumulate
  % rows appropriately
  M = sparse(rows, col_map(cols), vals, prod(size(F) + sz - 1), prod(sz));


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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 [vertices, sph_verts, faces, fvec, new_name]=align_CPS_SHREC(filename, confs)
global fact;
global sgm;

gran = confs.GroupAlpha;  % gran = # of alphas to process together
res = [confs.BaseRes confs.HierarchyStep confs.HierarchyDepth confs.Top_K confs.GammaRes];
% base res R + step of hierarchy Hs + depth of hierarchy Hd + top N + 3rd Angle res (gammares)

switch upper(deblank(char(confs.NormalizeSize)))
    case 'YES'
        scale = 1;
    case 'NO'
        scale = 0;
end

% factorial(170) = Inf
for i=0:170
    fact(i+1) = factorial(i);
end

utl_sgm(15);

% Load a template object
load(confs.Template);
[fvec, max_d] = fixed_fvec(fvec,confs.MaxSPHARMDegree,scale);
%tvertices = vertices; tsph_verts=sph_verts; tfvec = fvec;
tfvec = fvec;

load(filename);
[fvec, max_d] = fixed_fvec(fvec,confs.MaxSPHARMDegree,scale);
[path,name,ext] = fileparts(filename);

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

rmsd_org = SPHARM_rmsd(fvec, tfvec);

if rmsd_org > 0

    % create samples in rotation space
    [alpha, beta, gamma] = utl_eas(res); % euler_angle hierarchy

    % initial alignment using ICP
    [fvec_icp, Robj_icp] = match_icp(fvec, tfvec, max_d);
    [fvec_icp, Aprm] = match_param_hie(fvec_icp,tfvec,alpha,beta,gamma,gran,res,max_d);
    [fvec_icp, Robj_icp] = match_cps(fvec_icp, tfvec, max_d);

    % assume that fvec and atlas are roughly aligned in the object space
    [fvec_cps, Robj_cps] = match_cps(fvec, tfvec, max_d);

    rmsd_icp = SPHARM_rmsd(fvec_icp, tfvec);
    rmsd_cps = SPHARM_rmsd(fvec_cps, tfvec);

    disp(sprintf('RMSD: org %0.3f, icp %0.3f, cps %0.3f',rmsd_org,rmsd_icp,rmsd_cps))

    if rmsd_org > min(rmsd_icp,rmsd_cps)
        if rmsd_icp < rmsd_cps
            fvec = fvec_icp;
            Robj = Robj_icp;
        else
            fvec = fvec_cps;
            Robj = Robj_cps;
        end
    end

    % assume that fvec and atlas are roughly aligned in both object and
    % parameter spaces
    for k = 1:5
        rmsd(1) = SPHARM_rmsd(fvec, tfvec);

        % use cps to align objects together first
        [fvec_a, Robj] = match_cps(fvec, tfvec, max_d);
        rmsd(2) = SPHARM_rmsd(fvec_a, tfvec);

        if rmsd(2)<rmsd(1)
            fvec = fvec_a; % update
        end

        % assume aligned in object space, register the parameterization
        [fvec, Aprm] = match_param_hie(fvec,tfvec,alpha,beta,gamma,gran,res,max_d);
        rmsd(3) = SPHARM_rmsd(fvec, tfvec);

        disp(sprintf('Base Res %d, Step %d, Depth %d, Top %d, Gamma %d: RMSD %0.3f => %0.3f => %0.3f',res,rmsd));

        if sum(abs(Aprm(:)))==0
            break;
        end
    end
else
    disp(sprintf('RMSD = %d: Individual (%s) is the same as template (%s)',rmsd_org,filename,confs.Template));
end

new_name = sprintf('%s/%sSHREC_reg.mat',confs.OutDirectory, name(1:end-3));
if exist(new_name,'file')
    prompt = {'Enter new filename:'};
    dlg_title = 'New File Name';
    num_lines = 1;
    def = {new_name};
    answer = inputdlg(prompt,dlg_title,num_lines,def);
    new_name = answer{1};
end
save(new_name, 'fvec');

clear('fact','sgm');

return;


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


%io_readlcmcoord_getBackground.m
%Jamie Near, McGill University 2014.
%
% USAGE:
% out = io_readlcmcoord_getBackground(filename,part)
%
% DESCRIPTION:
% Reads a LCModel .coord file and extracts the desired part.
%
% INPUTS:
% filename   = filename of the LCModel .coord file.
% part       = Which part of the .coord file to extract - 'bg' extracts the
%             LCModel baseline signal, 'sp' extracts the spectrum, and
%             'fit' extracts the fit.
%
% OUTPUTS:
% out        = Desired background component in simplified FID-A structure format.

function [out]=io_readlcmcoord_getBackground(filename,part)

fid=fopen(filename);
linenum=1;
line=fgets(fid)

%READ PPM AXIS
ppmstr='points on ppm-axis ='
ppm_index=findstr(line,ppmstr);
while isempty(ppm_index)
    line=fgets(fid);
    ppm_index=findstr(line,ppmstr);
end

Npts=str2num(line(2:5))

line=fgets(fid);
while linenum<=(Npts/10)
    [A,count, errmsg, nextindex] = sscanf(line, '%f', inf);
    A
    ppm((linenum-1)*10+1:linenum*10,1)=A;
    linenum=linenum+1;
    line=fgets(fid);
end

%GET BACKGROUND

linenum=1;
switch part
    case 'bg'
        bgstr='NY background values follow'
    case 'sp'
        bgstr='NY phased data points follow'
    case 'fit'
        bgstr='NY points of the fit to the data follow'
    otherwise
        error('ERROR:  part not found');
end
bg_index=findstr(line,bgstr);
while isempty(bg_index)
    line=fgets(fid);
    bg_index=findstr(line,bgstr);
end

line=fgets(fid);
while linenum<=(Npts/10)
    [A,count, errmsg, nextindex] = sscanf(line, '%f', inf);
    A;
    bg((linenum-1)*10+1:linenum*10,1)=A;
    linenum=linenum+1;
    line=fgets(fid);
end

out.ppm=ppm;
out.specs=bg;