function newVesicles = fVesicleFilter(vesicles, img)
% V4. This function filters the vesicles according to the specified in
% PARAM criteria. It returns filtered vesicles structure. In this version
% R2 used as fit error criterium.
global PARAM;


% adds a logical flag (to delete?) field to all vesicles
[vesicles(:).delFlag] = deal(false);

% create log structure to count deleted vesicles
delCounter = struct('pointErrCri', 0, 'r2Cri', 0, 'circularCri', 0,...
    'widthCriMin', 0, 'widthCriMax', 0, 'amplCri', 0, 'baseCri', 0,...
    'edgeCri', 0, 'centreDisCri', 0, 'distanceCri', 0);

for i = 1:length(vesicles)
   % if all points are properly fitted? satisfies pointErrCri
   if max(max(vesicles(i).pointerror)) > PARAM.pointErrCri/100
       vesicles(i).delFlag = true;
       delCounter.pointErrCri = delCounter.pointErrCri + 1;
       continue;
   end
   
   % if satisfies total fit error criteria
   if vesicles(i).r2 < PARAM.r2Cri
       vesicles(i).delFlag = true;
       delCounter.r2Cri = delCounter.r2Cri + 1;
       continue;
   end
   
   % if satisfies to the circularity criteria
   circularity = vesicles(i).sx / vesicles(i).sy;
   if circularity < PARAM.circularCri || circularity > 1/PARAM.circularCri
       vesicles(i).delFlag = true;
       delCounter.circularCri = delCounter.circularCri + 1;
       continue;
   end
   
   % if satisfies to the minimal width criteria
   if min(vesicles(i).sx, vesicles(i).sy) < PARAM.widthCriMin 
       vesicles(i).delFlag = true;
       delCounter.widthCriMin = delCounter.widthCriMin + 1;
       continue;
   end
   
   % if satisfies to the maximal width criteria
   if max(vesicles(i).sx, vesicles(i).sy) > PARAM.widthCriMax 
       vesicles(i).delFlag = true;
       delCounter.widthCriMax = delCounter.widthCriMax + 1;
       continue;
   end
   
   % if satisfies to the minimal amplitude criteria
   if vesicles(i).a < PARAM.amplCri 
       vesicles(i).delFlag = true;
       delCounter.amplCri = delCounter.amplCri + 1;
       continue;
   end
   
   % if satisfies to the maximal baseline height criteria
   if vesicles(i).b > PARAM.baseCri 
       vesicles(i).delFlag = true;
       delCounter.baseCri = delCounter.baseCri + 1;
       continue;
   end
   
   % if satisfies to the minimal distance to image edge criteria
   if min(vesicles(i).x0, vesicles(i).y0) < PARAM.edgeCri ||...
           (size(img, 1) - vesicles(i).x0) < PARAM.edgeCri ||...
           (size(img, 2) - vesicles(i).y0) < PARAM.edgeCri
       vesicles(i).delFlag = true;
       delCounter.edgeCri = delCounter.edgeCri + 1;
       continue;
   end
   
   % if fitted maximum and observed maximum are close enough 
   centreDistance=sqrt( (vesicles(i).m-vesicles(i).x0)^2 + (vesicles(i).n-vesicles(i).y0)^2);
   if centreDistance > PARAM.centreDisCri 
       vesicles(i).delFlag = true;
       delCounter.centreDisCri = delCounter.centreDisCri + 1;
       continue;
   end
   
end

% delete all vesicles marked with delFlag
newVesicles = vesicles([vesicles(:).delFlag] ~= true);

% temporary converts vesicles to cell array to sort them my 'm' colomn
tempcell = struct2cell(newVesicles)';
tempfields = fieldnames(newVesicles);
mCol = find(ismember(tempfields, 'm'));
tempcell = sortrows(tempcell, mCol);
newVesicles = cell2struct(tempcell', tempfields);

% check is two vesicles are not very close to each other
for i = 1:length(newVesicles)-1
   if (newVesicles(i+1).m - newVesicles(i).m) < PARAM.distanceCri
       if sqrt( (newVesicles(i+1).m-newVesicles(i).m)^2 + (newVesicles(i+1).n-newVesicles(i).n)^2) < PARAM.distanceCri
           [newVesicles(i:i+1).delFlag] = deal(true);
           delCounter.distanceCri = delCounter.distanceCri + 1;
       end
   end
end

% delete all vesicles marked with delFlag
newVesicles = newVesicles([newVesicles(:).delFlag] ~= true);

% print number of deleted vesicles in each case
temp = fieldnames(delCounter);
for i = 1:length(temp)
   fprintf('%d vesicles were deleted by %s criteria \n', getfield(delCounter, temp{i}), temp{i}) 
end
fprintf('%d vesicles left \n', length(newVesicles))