diff --git a/MainScripts/displayCombinedMap.m b/MainScripts/displayCombinedMap.m
index 57e5f023902bf89f3e3ab580d2c97fadcac87456..f07a467273c3530361cc6c2f63b66fad32ac88ec 100644
--- a/MainScripts/displayCombinedMap.m
+++ b/MainScripts/displayCombinedMap.m
@@ -3,12 +3,14 @@
 function displayCombinedMap(tableOutputDeproj,tableOutputBell,contour3D,outputFolder)
 % If not specified, the default display is now in real space (not projected)
 % For shape descriptor see publication Zdilla et al. 2016
-% Usual call is 
+% Usual call is
 % displayCombinedMap(tableOutputDeproj,tableOutputBell,dataCells.cellContour3D)
 
 % close all
 
-scriptVersion = 'displayCombinedMap_v0p3';
+scriptVersion = 'displayCombinedMap_v0p5';
+
+nSec = 5; % give 5 sec to the software to save the image before going to the next
 
 if nargin==3
     outputFolder = uigetdir(pwd,'Select the output folder');
@@ -24,16 +26,18 @@ dataBool.doPerimeter = true;
 dataBool.doAnisotropy = true;
 dataBool.doCircularity = true;
 dataBool.doRoundness = true;
-% 
+dataBool.doOrientation = true;
+
+
 % dataBool.doApical = false;
 % dataBool.doNeighbours = false;
 % dataBool.doAreaRatioRP = false;
 % dataBool.doAreaRatioPB = false;
 % dataBool.doPerimeter = false;
 % dataBool.doAnisotropy = false;
-% dataBool.doCircularity = true;
+% dataBool.doCircularity = false;
 % dataBool.doRoundness = false;
-
+% dataBool.doOrientation = true;
 
 save('displayParameters','scriptVersion','dataBool');
 
@@ -54,7 +58,7 @@ if dataBool.doApical
     dataVal = tableOutputDeproj.AreaReal;
     titleFig = 'Cell apical surface area (Real)';
     figName = 'mapApicalArea';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
 
 % Nbr of neighbours
@@ -62,7 +66,7 @@ if dataBool.doNeighbours
     dataVal = tableOutputDeproj.NbrNeighbours;
     titleFig = 'Nbr of neighbours';
     figName = 'mapNbrNeighbours';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
 
 % Area ratio (real vs proj)
@@ -70,15 +74,15 @@ if dataBool.doAreaRatioRP
     dataVal = tableOutputDeproj.AreaReal./tableOutputDeproj.AreaProj;
     titleFig = 'Cell apical surface area ratio (Real/Proj)';
     figName = 'mapAreaRatio_RP';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
-    
+
 % Area ratio (Proj vs Bell)
 if dataBool.doAreaRatioPB
     dataVal = tableOutputDeproj.AreaProj./tableOutputBell.AreaBell;
     titleFig = 'Cell apical surface area ratio (Proj/Bell)';
     figName = 'mapAreaRatio_PB';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
 
 % Perimeter
@@ -86,7 +90,7 @@ if dataBool.doPerimeter
     dataVal = tableOutputDeproj.PerimeterReal;
     titleFig = 'Cell perimeter (Real)';
     figName = 'mapPerimeter';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
 
 % Anisotropy (Real) (as calculated by Bellaiche lab: 1-1/elongation)
@@ -94,65 +98,100 @@ if dataBool.doAnisotropy
     dataVal = tableOutputDeproj.AnisotropyReal;
     titleFig = 'Cell anisotropy (Real)';
     figName = 'mapAnisotropy';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
 
 % Circularity is a shape descriptor that can mathematically indicate the degree of similarity to a perfect circle
-if dataBool.doCircularity % Error in the method   
+if dataBool.doCircularity % Error in the method
     dataVal = (4*pi*(tableOutputDeproj.AreaEllipseReal) ./ (tableOutputDeproj.PerimeterEllipseReal.^2));
     titleFig = 'Cell circularity (Real)';
     figName = 'mapCircularity';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
 end
 
 % Roundness is similar to circularity but is insensitive to irregular borders along the perimeter
 if dataBool.doRoundness
     dataVal = 4*tableOutputDeproj.AreaEllipseReal./(pi*(tableOutputDeproj.semiMajAxReal*2).^2);
-    titleFig = 'Cell roundness (Real)';
+    titleFig = 'Cell roundness (Real)'; 
     figName = 'mapRoundness';
-    dispMap(dataVal,titleFig,figName,contour3D);
+    dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec);
+end
+
+% Orientation of the cell is representing the orientation of the fitted
+% ellipse on the cell contour on the mesh. Vector length is weighted by the
+if dataBool.doOrientation
+    % Arrow length is function of the anisotropy
+    dataVec = tableOutputDeproj.OrientationEllipseReal.*...
+        tableOutputDeproj.AnisotropyReal;
+    % Set the origin of the arrow
+    dataOri = tableOutputDeproj.centerEllipseReal;
+    titleFig = 'Cell orientation (Real)';
+    figName = 'mapOrientation';
+    dispQuiverMap(dataOri,dataVec,titleFig,figName,nSec);
 end
 
+
 end
 
 
-function dispMap(dataVal,titleFig,figName,contour3D)
-    
-    %% Preparing the colormap
-    dataRange = max(dataVal)-min(dataVal);
-    greyLvlNbr = 200;
-    color2plot = round(((dataVal-min(dataVal))/dataRange)*(greyLvlNbr-1)+1);
-    fprintf('displaying: %s\n',titleFig);
-    dataColor = parula(greyLvlNbr);
-    
-    %% Plot the figure
-    figure
-    hold on
-    for bioCell = 1:numel(dataVal)
-        if isnan(dataVal(bioCell))
-            fprintf('Warning: A value was not set properly: skipping cell %d\n',bioCell);
-            continue
-        else
-            fill3(contour3D{bioCell}.VerticesOrdered(:,1),...
-                contour3D{bioCell}.VerticesOrdered(:,2),...
-                contour3D{bioCell}.VerticesOrdered(:,3),...
-                dataColor(color2plot(bioCell),:), ...
-                'LineStyle', 'none');
-        end
+function dispPolygonMap(dataVal,titleFig,figName,contour3D,nSec)
+
+%% Preparing the colormap
+dataRange = max(dataVal)-min(dataVal);
+greyLvlNbr = 200;
+color2plot = round(((dataVal-min(dataVal))/dataRange)*(greyLvlNbr-1)+1);
+fprintf('displaying: %s\n',titleFig);
+dataColor = parula(greyLvlNbr);
+
+%% Plot the figure
+figure
+hold on
+for bioCell = 1:numel(dataVal)
+    if isnan(dataVal(bioCell))
+        fprintf('Warning: A value was not set properly: skipping cell %d\n',bioCell);
+        continue
+    else
+        fill3(contour3D{bioCell}.cellCt(:,1),...
+            contour3D{bioCell}.cellCt(:,2),...
+            contour3D{bioCell}.cellCt(:,3),...
+            dataColor(color2plot(bioCell),:), ...
+            'LineStyle', 'none');
     end
-    
-    %% Set axes and colorbar
-    h = colorbar;
-    caxis([min(dataVal) max(dataVal)])
-    axis equal
-    title(titleFig);
-    xlabel('X position (µm)'); ylabel('Y position (µm)');
-    zlabel('Z position (µm)');
-
-    savefig(figName)
-    
 end
 
+%% Set axes and colorbar
+h = colorbar;
+caxis([min(dataVal) max(dataVal)])
+axis equal
+title(titleFig);
+xlabel('X position ({\mu}m)'); ylabel('Y position ({\mu}m)');
+zlabel('Z position ({\mu}m)');
+
+savefig(figName)
+export_fig(figName,'-png','-m5');
+pause(nSec);
+end
+
+
+function dispQuiverMap(dataOri,dataVec,titleFig,figName,nSec)
+
+fprintf('displaying: %s\n',titleFig);
+
+% plot the figure
+figure
+quiver3(dataOri(:,1),dataOri(:,2),dataOri(:,3),dataVec(:,1),dataVec(:,2),dataVec(:,3),'ShowArrowHead','off')
+axis equal
+
+%% Set axes and colorbar
+axis equal
+title(titleFig);
+xlabel('X position ({\mu}m)'); ylabel('Y position ({\mu}m)');
+zlabel('Z position ({\mu}m)');
+
+savefig(figName)
+export_fig(figName,'-png','-m5');
+pause(nSec);
+end
 
 
 
diff --git a/MainScripts/findContour.m b/MainScripts/findContour.m
index a3fda501db0624796c0f3bee4612a8ffe850ee47..0304c9bdfed7434c38a31ff8a9307f2788fb2a1f 100644
--- a/MainScripts/findContour.m
+++ b/MainScripts/findContour.m
@@ -20,7 +20,7 @@ function cellContour2D = findContour(contour2Dpos,bmethod,PARAMS)
 % - cellContour2D.Line: paired vertices matrix to infer the pixel
 % connections -> deleted
 % - cellContour2D.Vertices: XY sorted vertices -> deleted
-% - cellContour2D.VerticesOrdered: XY sorted vertices in "CW" order
+% - cellContour2D.cellCt: XY sorted vertices in "CW" order
 
 fprintf('Recreating the cellular contours\n');
 
@@ -69,7 +69,7 @@ for bioCell = 1:length(contour2Dpos) % for all cells
             
         case 'bwboundary'
             [boundaries,~] = bwboundaries(miniImg,'noholes');
-            cellContour2D{bioCell}.VerticesOrdered = boundaries{1}+...
+            cellContour2D{bioCell}.cellCt = boundaries{1}+...
                 min(contour2Dpos{bioCell})-2; % replace in full image % -1 for start table at 1 and -1 for appened lines
             
         case 'mask2poly'
@@ -79,7 +79,7 @@ for bioCell = 1:length(contour2Dpos) % for all cells
             polyCell(:,1) = polyCell(:,2);
             polyCell(:,2) = polyCell(:,3);
             polyCell(:,3) = [];
-            cellContour2D{bioCell}.VerticesOrdered = polyCell+...
+            cellContour2D{bioCell}.cellCt = polyCell+...
                 min(contour2Dpos{bioCell})-2; % replace in full image % -1 for start table at 1 and -1 for appened lines
         
         otherwise
@@ -100,10 +100,10 @@ for bioCell = 1:length(contour2Dpos) % for all cells
                 end
                 Ori = find(cellContour2D{bioCell}.Lines(:,1)==Dest);
             end
-            cellContour2D{bioCell}.VerticesOrdered = tempVert;
+            cellContour2D{bioCell}.cellCt = tempVert;
             clear tempVert
     end
-    cellContour2D{bioCell}.VerticesOrdered = cellContour2D{bioCell}.VerticesOrdered*PARAMS.imSettings.latPixSize; % scale back to µm
+    cellContour2D{bioCell}.cellCt = cellContour2D{bioCell}.cellCt*PARAMS.imSettings.latPixSize; % scale back to µm
 end
 cellContour2D = cellContour2D';
 
diff --git a/MainScripts/formatTableOuputSurfaceCombine.m b/MainScripts/formatTableOuputSurfaceCombine.m
index 043d83224292ca0514989680f5cc1079a70e938d..f0ad0d21ecc8017856f846d21358e7583dbaf882 100644
--- a/MainScripts/formatTableOuputSurfaceCombine.m
+++ b/MainScripts/formatTableOuputSurfaceCombine.m
@@ -10,10 +10,16 @@ tableOutputBell = table;
 tableOutputDeproj.Numbers = dataCells.numbers;
 tableOutputBell.Numbers = dataSeg.CELLS.numbers(dataCells.numbers);
 
+%% Cell center (ellipse real)
+for bioCell = 1:numel(dataCells.numbers)
+    EllipseRealCenter(bioCell,:) = dataCells.cellContour3D{bioCell}.ellipseReal.center;
+end
+tableOutputDeproj.EllipseRealCenter = EllipseRealCenter;
+
 %% Cell areas
 for bioCell = 1:numel(dataCells.numbers)
-    areaEllReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseFlatten.areaEllipse;
-    areaEllProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseFlatten.areaEllipse;
+    areaEllReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseRotViaOri.areaEllipse;
+    areaEllProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseProj.areaEllipse;
 end
 tableOutputDeproj.AreaReal = cell2mat(dataCells.area.areaRealTot);
 tableOutputDeproj.AreaProj = cell2mat(dataCells.area.areaProjTot);
@@ -25,12 +31,12 @@ tableOutputBell.AreaBell = dataSeg.CELLS.areas(dataCells.numbers);
 tableOutputDeproj.nbrNeighbours = dataSeg.CELLS.n_neighbors(dataCells.numbers);
 tableOutputBell.nbrNeighbours = dataSeg.CELLS.n_neighbors(dataCells.numbers);
 
-%% Cell anisotropy (Bellaiche style)
+%% Cell anisotropy (Bellaiche style) % Change for precalculated values !
 for bioCell = 1:numel(dataCells.numbers)
-    elongationReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseFlatten.semiMajAx / ...
-        dataCells.cellContour3D{bioCell}.ellipseFlatten.semiMinAx;
-    elongationProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseFlatten.semiMajAx / ...
-        dataCells.cellContour2D{bioCell}.ellipseFlatten.semiMinAx;
+    elongationReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseRotViaOri.semiMajAx / ...
+        dataCells.cellContour3D{bioCell}.ellipseRotViaOri.semiMinAx;
+    elongationProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseProj.semiMajAx / ...
+        dataCells.cellContour2D{bioCell}.ellipseProj.semiMinAx;
     elongationBell(bioCell) = dataSeg.CELLS.anisotropies(dataCells.numbers(bioCell));
 end
 tableOutputDeproj.anisostropyReal = 1-1./elongationReal';
@@ -39,8 +45,8 @@ tableOutputBell.anisotropyBell = elongationBell';
 
 %% Cell longer axis
 for bioCell = 1:numel(dataCells.numbers)
-    semiMajorAxisReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseFlatten.semiMajAx;
-    semiMajorAxisProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseFlatten.semiMajAx;
+    semiMajorAxisReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseRotViaOri.semiMajAx;
+    semiMajorAxisProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseProj.semiMajAx;
 end
 tableOutputDeproj.semiMajAxisReal = semiMajorAxisReal';
 tableOutputDeproj.semiMajAxisProj = semiMajorAxisProj';
@@ -48,20 +54,31 @@ tableOutputDeproj.semiMajAxisProj = semiMajorAxisProj';
 %% Cell angle (Projected only)
 for bioCell = 1:length(dataCells.numbers)
     %     angleReal(bioCell) =
-    %     dataCells.cellContour3D{bioCell}.ellipseFlatten.alpha; => Not
+    %     dataCells.cellContour3D{bioCell}.ellipseRotViaOri.alpha; => Not
     %     calculated yet
-    angleProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseFlatten.alpha;
+    angleProj(bioCell) = dataCells.cellContour2D{bioCell}.ellipseProj.alpha;
     angleBell(bioCell) = dataSeg.CELLS.orientations(dataCells.numbers(bioCell));
 end
 % tableOutputDeproj.angleReal = angleReal';
 tableOutputDeproj.angleProj = angleProj';
 tableOutputBell.angleBell = angleBell';
 
+%% Cell orientation real
+for bioCell = 1:numel(dataCells.numbers) % Only keep the end point of the vector. The beginning is the ellipse center
+    if isnan(dataCells.cellContour3D{bioCell}.ellipseReal.normOrientation(1,1))
+        EllipseRealOrient(bioCell,:) = dataCells.cellContour3D{bioCell}.ellipseReal.normOrientation(1,1);
+    else
+        EllipseRealOrient(bioCell,:) = dataCells.cellContour3D{bioCell}.ellipseReal.normOrientation(:,2)-...
+            dataCells.cellContour3D{bioCell}.ellipseReal.normOrientation(:,1); % Centered on the origin
+    end
+end
+tableOutputDeproj.EllipseRealOrient = EllipseRealOrient;
+
 %% Cell perimeters
 for bioCell = 1:length(dataCells.numbers)
-    perimeterReal(bioCell) = dataCells.cellContour3D{bioCell}.perimeter3D;
+    perimeterReal(bioCell) = dataCells.cellContour3D{bioCell}.perimeterReal;
     perimeterProj(bioCell) = dataCells.cellContour2D{bioCell}.perimeterProj;
-    perimeterEllipseReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseFlatten.perimeterEllipse;
+    perimeterEllipseReal(bioCell) = dataCells.cellContour3D{bioCell}.ellipseRotViaOri.perimeterEllipse;
 end
 tableOutputDeproj.perimeterReal = perimeterReal';
 tableOutputDeproj.perimeterProj = perimeterProj';
@@ -69,8 +86,8 @@ tableOutputDeproj.perimeterEllipseReal = perimeterEllipseReal';
 tableOutputBell.perimeterBell = dataSeg.CELLS.perimeters(dataCells.numbers);
 
 %% Field naming
-tableOutputDeproj.Properties.VariableNames = {'cellID' 'AreaReal' 'AreaProj' 'AreaEllipseReal' 'AreaEllipseProj'...
-    'NbrNeighbours' 'AnisotropyReal' 'AnisotropyProj' 'semiMajAxReal' 'semiMajAxProj' 'AngleProj'...
+tableOutputDeproj.Properties.VariableNames = {'cellID' 'centerEllipseReal' 'AreaReal' 'AreaProj' 'AreaEllipseReal' 'AreaEllipseProj'...
+    'NbrNeighbours' 'AnisotropyReal' 'AnisotropyProj' 'semiMajAxReal' 'semiMajAxProj' 'AngleProj' 'OrientationEllipseReal'...
     'PerimeterReal' 'PerimeterProj' 'PerimeterEllipseReal'};
 tableOutputBell.Properties.VariableNames = {'cellID' 'AreaBell' 'NbrNeighbours' 'AnisotropyBell' 'AngleBell'...
     'PerimeterBell'};
diff --git a/MainScripts/surface3D_combine.m b/MainScripts/surface3D_combine.m
index d20fa4a25cf177a311aec74eed375b1a54544187..c1b5576ae1342219cd8693b529f82b14411cfe1c 100644
--- a/MainScripts/surface3D_combine.m
+++ b/MainScripts/surface3D_combine.m
@@ -34,7 +34,7 @@ PARAMS = {};
 
 %%%%%%%%%%%%%%%%%%%%%% PARAMETERS %%%%%%%%%%%%%%%%%%%%%% 
 
-PARAMS.softVersion = 'surface3D_combine_v0p9.m';
+PARAMS.softVersion = 'surface3D_combine_v0p12.m';
 
 PARAMS.doDispBell = true; % display the 2D segmentation
 PARAMS.doDispMesh = true; % display the 3D mesh
@@ -266,8 +266,8 @@ else
     plotTable.XData = (vertices(:,1));
 end
 % axis equal
-xlabel('X position (µm)');
-ylabel('Y position (µm)');
+xlabel('X position ({\mu}m)');
+ylabel('Y position ({\mu}m)');
 title('2D segmentation result');
 axis([0 PARAMS.imSettings.x*PARAMS.imSettings.latPixSize ...
     0 PARAMS.imSettings.y*PARAMS.imSettings.latPixSize]);
@@ -284,8 +284,8 @@ patchHandle = patch('Faces',dataMesh.faces,'Vertices',dataMesh.vertices,...
 % hold on
 % plot3(dataMesh.vertices(:,1),dataMesh.vertices(:,2),dataMesh.vertices(:,3),'.');
 axis equal
-xlabel('X position (µm)');
-ylabel('Y position (µm)');
+xlabel('X position ({\mu}m)');
+ylabel('Y position ({\mu}m)');
 title('3D Mesh result');
 axis([0 PARAMS.imSettings.x*PARAMS.imSettings.latPixSize...
     0 PARAMS.imSettings.y*PARAMS.imSettings.latPixSize...
@@ -328,8 +328,8 @@ for meshTri = 1:size(dataMesh.faces,1) % USE A PARFOR HERE IF POSSIBLE !
     % for every cell of the mesh
     for bioCell = 1: length(dataCells.numbers)
         %         bioCell = 1000;
-        [xInter, ~] = polybool('intersection', dataCells.cellContour2D{bioCell}.VerticesOrdered(:,1),...
-            dataCells.cellContour2D{bioCell}.VerticesOrdered(:,2),...
+        [xInter, ~] = polybool('intersection', dataCells.cellContour2D{bioCell}.cellCt(:,1),...
+            dataCells.cellContour2D{bioCell}.cellCt(:,2),...
             dataMesh.contour{meshTri}(:,1),dataMesh.contour{meshTri}(:,2));
         if ~isempty(xInter)
             %             fprintf('cell %d Connected with mesh face %d\n', bioCell, meshTri);
@@ -360,8 +360,8 @@ for bioCell = 1 : length(dataCells.contourPo2D)
         % for every face of the mesh connected to the cell
 
         % Find the intersection of the face and cell
-        [xInter, yInter] = polybool('intersection', dataCells.cellContour2D{bioCell}.VerticesOrdered(:,1),...
-            dataCells.cellContour2D{bioCell}.VerticesOrdered(:,2),...
+        [xInter, yInter] = polybool('intersection', dataCells.cellContour2D{bioCell}.cellCt(:,1),...
+            dataCells.cellContour2D{bioCell}.cellCt(:,2),...
             dataMesh.contour{dataCells.cell2Face{bioCell}(polyInd)}(:,1),...
             dataMesh.contour{dataCells.cell2Face{bioCell}(polyInd)}(:,2));
         
@@ -448,10 +448,10 @@ function dataCells = contour2face(dataCells,dataMesh)
 for bioCell = 1:length(dataCells.cellContour2D) % for each cell 
     % last position is the same as first for a close contour
     dataCells.cellContour2D{bioCell}.vertexOnFace = ...
-        zeros(length(dataCells.cellContour2D{bioCell}.VerticesOrdered),1); 
+        zeros(length(dataCells.cellContour2D{bioCell}.cellCt),1); 
     for triFace = 1:length(dataCells.cell2Face{bioCell}) % for each triangular face of the mesh connected to the cell
-        in = inpolygon(dataCells.cellContour2D{bioCell}.VerticesOrdered(1:end-1,1),...
-            dataCells.cellContour2D{bioCell}.VerticesOrdered(1:end-1,2),...
+        in = inpolygon(dataCells.cellContour2D{bioCell}.cellCt(1:end-1,1),...
+            dataCells.cellContour2D{bioCell}.cellCt(1:end-1,2),...
             dataMesh.contour{dataCells.cell2Face{bioCell}(triFace)}(:,1),...
             dataMesh.contour{dataCells.cell2Face{bioCell}(triFace)}(:,2));
         dataCells.cellContour2D{bioCell}.vertexOnFace(in) = dataCells.cell2Face{bioCell}(triFace);
@@ -463,7 +463,6 @@ end
 
 end
 
-
 function dataCells = checkCoverage(dataCells,dataMesh,dataSeg,PARAMS)
 
 % Save dataset prior to filtering
@@ -489,7 +488,6 @@ displayClipped(PARAMS,dataMesh,dataCells,dataSeg);
 
 end
 
-
 function overCoveredCells = checkOverCovered(dataCells,dataMesh)
 % list cells covered by a downwards oriented face
 
@@ -498,7 +496,6 @@ overCoveredCells = unique(vertcat(dataCells.Face2Cell{downFaces}));
 
 end
 
-
 function underCoveredCells = checkUnderCovered(dataCells,PARAMS)
 
 % List cells for which the coverage is only partial (below a user defined
@@ -506,8 +503,8 @@ function underCoveredCells = checkUnderCovered(dataCells,PARAMS)
 areaCell = zeros(length(dataCells.numbers),1);
 areaSeg = zeros(length(dataCells.numbers),1);
 for bioCell = 1:length(dataCells.numbers)
-    areaSeg(bioCell) = polyarea(dataCells.cellContour2D{bioCell}.VerticesOrdered(:,1),...
-        dataCells.cellContour2D{bioCell}.VerticesOrdered(:,2));
+    areaSeg(bioCell) = polyarea(dataCells.cellContour2D{bioCell}.cellCt(:,1),...
+        dataCells.cellContour2D{bioCell}.cellCt(:,2));
     if isempty(dataCells.area.areaProjTot{bioCell})
         areaCell(bioCell) = 0;
     else
@@ -662,12 +659,12 @@ for meshFace = 1:length(dataMesh.faces)
 end
 
 % Use face plane coefficients to deproject the 2D contour on the mesh
-for bioCell = 1:length(dataCells.numbers)
-    dataCells.cellContour3D{bioCell}.VerticesOrdered = ...
-        dataCells.cellContour2D{bioCell}.VerticesOrdered;
-    dataCells.cellContour3D{bioCell}.VerticesOrdered(:,3) = diag(...
-        horzcat(dataCells.cellContour2D{bioCell}.VerticesOrdered,...
-        ones(length(dataCells.cellContour2D{bioCell}.VerticesOrdered),1)) * ...
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.cellCt = ...
+        dataCells.cellContour2D{bioCell}.cellCt;
+    dataCells.cellContour3D{bioCell}.cellCt(:,3) = diag(...
+        horzcat(dataCells.cellContour2D{bioCell}.cellCt,...
+        ones(length(dataCells.cellContour2D{bioCell}.cellCt),1)) * ...
         dataMesh.planeCoefPerFace(dataCells.cellContour2D{bioCell}.vertexOnFace,:)');
 end
 dataCells.cellContour3D = dataCells.cellContour3D';
@@ -684,11 +681,11 @@ for vertex = 1:length(dataCells.VERTICES.vertexOnFace)
         dataMesh.planeCoefPerFace(dataCells.VERTICES.vertexOnFace(vertex),:)';
 end
 
-displayDeprojected(PARAMS,dataMesh,dataCells,dataSeg)
+displayDeprojected(PARAMS,dataMesh,dataCells)
 
 end
 
-function displayDeprojected(PARAMS,dataMesh,dataCells,dataSeg)
+function displayDeprojected(PARAMS,dataMesh,dataCells)
 % display the 3D deprojected mesh and segmentation
 % List of the different sides populations to plot
 sidesList{1} = dataCells.SIDES.goodSides;
@@ -727,7 +724,7 @@ dataCells.planeFit = avPlaneOfFaces(dataCells,dataMesh.planeCoefPerFace);
 
 % Project 3D contour on average plane
 for bioCell = 1:length(dataCells.numbers)
-    dataCells.cellContour3D{bioCell}.bestPlaneProj = projPointOnPlane(dataCells.cellContour3D{bioCell}.VerticesOrdered,...
+    dataCells.cellContour3D{bioCell}.cellCtFlat = projPointOnPlane(dataCells.cellContour3D{bioCell}.cellCt,...
         dataCells.planeFit{bioCell}.geom3Dvectors);
 end
 
@@ -740,21 +737,149 @@ dataCells = allDimEllipseFitting(dataCells,PARAMS);
 end
 
 function dataCells = allDimEllipseFitting(dataCells,PARAMS)
+% Call the ellipse fitting and addition calculation for each independant
+% case of data (Flatten and rotated or Projected)
 
-%% for flatten contours
+% for flatten contours
 [dataCells.cellContour3D, dataCells.ellipseFitError3D] =...
-    BioCellEllipseFitting(dataCells.cellContour3D,dataCells.numbers,3,PARAMS);
+    BioCellEllipseFitting(dataCells.cellContour3D,dataCells.numbers,3,PARAMS,'ellipseRotViaOri');
 
-%% for old 2D contours
+% for old 2D contours
 [dataCells.cellContour2D, dataCells.ellipseFitError2D] =...
-    BioCellEllipseFitting(dataCells.cellContour2D,dataCells.numbers,2,PARAMS);
+    BioCellEllipseFitting(dataCells.cellContour2D,dataCells.numbers,2,PARAMS,'ellipseProj');
+
+% Replace the semiaxes into the ellipse space for simpler display
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.ellipseRotViaOri = replaceSemiAxesInEllipseSpace...
+        (dataCells.cellContour3D{bioCell}.ellipseRotViaOri);
+    dataCells.cellContour2D{bioCell}.ellipseProj = replaceSemiAxesInEllipseSpace...
+        (dataCells.cellContour2D{bioCell}.ellipseProj);
+end
 
+% Derotate the real space ellipse
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.ellipseViaOri = ...
+        derotateEllipseData(dataCells.cellContour3D{bioCell}.ellipseRotViaOri,dataCells.planeFit{bioCell});
 end
 
+% Relocate the real space ellipse into the mesh
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.ellipseReal = relocateEllipseInMeshSpace...
+        (dataCells.cellContour3D{bioCell}.ellipseViaOri, dataCells.cellContour3D{bioCell}.cellCtFlat);
+end
 
+end
+
+function ellipseStruct = setEllipseStructToNaN(ellipseStruct)
+% If the fit didn't work then simply create the fields with NaN
+
+ellipseStruct.ellipseContour = NaN;
+ellipseStruct.semiMajVec = NaN;
+ellipseStruct.semiMinVec = NaN;
+ellipseStruct.center = NaN;
+ellipseStruct.normOrientation = NaN;
+
+end
+
+
+function ellipseStruct = relocateEllipseInMeshSpace(ellipseViaOri,cellCt)
+% Relocate the fitted ellipse, center and semiaxes onto the mesh
+
+ellipseStruct = {};
+
+if isnan(ellipseViaOri.semiMajVec) % If the fit didn't work => pad with nan
+    ellipseStruct = setEllipseStructToNaN(ellipseStruct);
+    return
+end
+
+x0 = cellCt(1,:)'; % translation to apply
+
+% Apply translation to ellipse contour, center and semiaxes
+ellipseStruct.ellipseContour = ellipseViaOri.ellipseContour+x0;
+ellipseStruct.semiMajVec = ellipseViaOri.semiMajVec+x0;
+ellipseStruct.semiMinVec = ellipseViaOri.semiMinVec+x0;
+ellipseStruct.center = ellipseViaOri.center+x0;
+
+% Normalized orientation
+ellipseStruct.normOrientation = ellipseStruct.semiMajVec;
+ellipseStruct.normOrientation(:,2) = normalizeVector3d(ellipseStruct.semiMajVec(:,2)'-ellipseStruct.semiMajVec(:,1)')'+ellipseStruct.semiMajVec(:,1);
+
+end
 
+function ellipseStruct = derotateEllipseData(ellipseRotViaOri,planeFit)
+% Rotate the ellipse, center and semiaxes from the XY axis
 
-function [cellData, ellipseFitError] = BioCellEllipseFitting(cellData,cell_ID,dim,PARAMS)
+ellipseStruct = {};
+
+if isnan(ellipseRotViaOri.semiMajVec)  % If the fit didn't work => pad with nan
+    ellipseStruct = setEllipseStructToNaN(ellipseStruct);
+    return
+end
+
+x0 = []; % no translation in addition to rotation
+
+% Allocate for simple reading of rotation axis, rotation amplitude, 
+axisRot = planeFit.axisRot; % Rotation axis between Z axis and cell normal vector in mesh
+angleRot = -planeFit.angleRot; % % inverse of the original rotation amplitude to revert to original
+
+% Apply rotation to ellipse contour, center and semiaxes
+ellipseStruct.ellipseContour = AxelRot(ellipseRotViaOri.ellipseContour,...
+    angleRot, axisRot, x0);
+ellipseStruct.semiMajVec = AxelRot(ellipseRotViaOri.semiMajVec,...
+    angleRot,axisRot,x0);
+ellipseStruct.semiMinVec = AxelRot(ellipseRotViaOri.semiMinVec,...
+    angleRot,axisRot,x0);
+ellipseStruct.center = ellipseStruct.semiMajVec(:,1);
+
+% Normalized orientation
+ellipseStruct.normOrientation = ellipseStruct.semiMajVec;
+ellipseStruct.normOrientation(:,2) = normalizeVector3d(ellipseStruct.semiMajVec(:,2)'-ellipseStruct.semiMajVec(:,1)')'+ellipseStruct.semiMajVec(:,1);
+
+end
+
+function ellipseStruct = replaceSemiAxesInEllipseSpace(ellipseStruct)
+% Here the ellipse is only bidimensionnal either projected on the XY plane
+% or ortho projected on the best fitting plane and then rotated on the XY
+% plane. In any case, the ellipse is flatten on XY and will remain so
+% during the function run
+
+if isnan(ellipseStruct.semiMajAx)  % If the fit didn't work => pad with nan
+    ellipseStruct = setEllipseStructToNaN(ellipseStruct);
+    return
+end
+
+% create an ellipse without rotation
+data.x = sin(linspace(0,2*pi));
+data.y = cos(linspace(0,2*pi));
+ell = ([ellipseStruct.semiMajAx*data.x; ellipseStruct.semiMinAx*data.y]);
+
+% rotate the ellipse plot
+normalVector = [0 0 1]; % final normal vector
+x0 = []; % no translation
+alphaAngle = mod(ellipseStruct.alpha/(2*pi)*360,360); % ellipse angle around the 
+% Z axis; from radians to degrees.
+% Rotate the ellipse around the Z axis
+ell = AxelRot([ell; zeros(1,length(ell))],alphaAngle,normalVector,x0);
+
+% set the center properly. MUST be done after rotation
+centersRot = [ellipseStruct.center; 0]; % ellipse center (needs 3D)
+ellipseStruct.ellipseContour = centersRot + ell;
+
+% Prepare the ellipse orientation vector
+referential = [ellipseStruct.semiMajAx 0 0 ; 0 ellipseStruct.semiMinAx 0; 0 0 0];
+referential = AxelRot(referential,alphaAngle,normalVector,x0);
+ellipseStruct.semiMajVec = horzcat(centersRot,centersRot+referential(:,1)); 
+ellipseStruct.semiMinVec = horzcat(centersRot,centersRot+referential(:,2));
+
+% Set center
+ellipseStruct.center = ellipseStruct.semiMajVec(:,1);
+
+% Normalized orientation
+ellipseStruct.normOrientation = centersRot;
+ellipseStruct.normOrientation(:,2) = normalizeVector3d(ellipseStruct.semiMajVec(:,2)'-ellipseStruct.semiMajVec(:,1)')'+ellipseStruct.semiMajVec(:,1);
+end
+ 
+function [cellData, ellipseFitError] = BioCellEllipseFitting(cellData,cell_ID,dim,PARAMS,structLoc)
 
 ellipseFitError = {}; % for ellipses not fitted properly
 cellListError = [];
@@ -762,16 +887,16 @@ for bioCell = 1:length(cell_ID)
 
     % Set the correct contour and perimeter (fields are function of the dimension)
     if dim == 3
-        cellContour = cellData{bioCell}.ContourFlattenViaOrigin(:,1:2)';
-        perimeter = cellData{bioCell}.perimeter3D;
+        cellContour = cellData{bioCell}.cellCtFlatViaOriRot(:,1:2)';
+        perimeter = cellData{bioCell}.perimeterReal;
     elseif dim == 2
-        cellContour = cellData{bioCell}.VerticesOrdered';
+        cellContour = cellData{bioCell}.cellCt';
         perimeter = cellData{bioCell}.perimeterProj;
     end
     
     
     try % Catch errors thrwon by the fitting method
-        [cellData{bioCell}.ellipseFlatten.center,...
+        [cellData{bioCell}.(structLoc).center,...
             ag, bg, alphaAng] = ...
             fitellipse(cellContour);
     catch ME % catch error if no fit possible
@@ -792,7 +917,7 @@ for bioCell = 1:length(cell_ID)
         temp = bg;
         bg = ag;
         ag = temp;
-        alphaAng = alphaAng+pi/2;
+        alphaAng = alphaAng+pi/2; % could be mod(pi) to simplify the ellipseFitError.cellListErrorvalues
     end
     
     if ~isnan(bg) % if the fit worked properly
@@ -802,30 +927,26 @@ for bioCell = 1:length(cell_ID)
     % Calculate ellipse area
     ellipseArea = pi*ag*bg;
     
-    % Set values in structure
+    % Set direct values in structure
     % Semi Major Axis
-    cellData{bioCell}.ellipseFlatten.semiMajAx = ag;
+    cellData{bioCell}.(structLoc).semiMajAx = ag;
     % Semi Minor Axis
-    cellData{bioCell}.ellipseFlatten.semiMinAx = bg;
+    cellData{bioCell}.(structLoc).semiMinAx = bg;
     % Ellipse angle
-    cellData{bioCell}.ellipseFlatten.alpha = alphaAng;
+    cellData{bioCell}.(structLoc).alpha = alphaAng; % in radians
     % Ellipse perimeter
-    cellData{bioCell}.ellipseFlatten.perimeterEllipse = perimeterEllipse;
-    % Contour length / Ellipse perimeter
-    cellData{bioCell}.perimsRatio_3D_Ellipse(bioCell) =...
-        perimeter/perimeterEllipse;
+    cellData{bioCell}.(structLoc).perimeterEllipse = perimeterEllipse;
     % Ellipse area
-    cellData{bioCell}.ellipseFlatten.areaEllipse = ellipseArea;
+    cellData{bioCell}.(structLoc).areaEllipse = ellipseArea;  
+    
 end
 
-
 if PARAMS.doDispErrorEllipse == true % Only if user asked for the error on the ellipse fits
     displaySubplotCellContour(cellListError, cellListContour, dim)
 end
     
 end
 
-
 function dataCells = flattenContour(dataCells)
 
 normalVector = [0 0 1]; % final normal vector
@@ -833,38 +954,38 @@ x0 = []; % no translation
 
 for bioCell = 1:length(dataCells.numbers)
     planNormal = dataCells.planeFit{bioCell}.normal;
+    % Calculate rotation vector and amplitude
     dataCells.planeFit{bioCell}.angleRot = -acos(dot(normalVector,planNormal))*360 / (2*pi);
     dataCells.planeFit{bioCell}.axisRot = cross(normalVector,planNormal);
     
-    % Set first 3DContour position at position 0,0,0 to ensure that the plane passes by the
-    % origin
-    dataCells.cellContour3D{bioCell}.ContourViaOrigin = dataCells.cellContour3D{bioCell}.bestPlaneProj-...
-        dataCells.cellContour3D{bioCell}.bestPlaneProj(1,:);
-    dataCurrent = dataCells.cellContour3D{bioCell}.ContourViaOrigin;
+    % Set first 3DContour position at position 0,0,0 to ensure that the plane passes by the origin
+    dataCells.cellContour3D{bioCell}.cellCtFlatViaOri = dataCells.cellContour3D{bioCell}.cellCtFlat-...
+        dataCells.cellContour3D{bioCell}.cellCtFlat(1,:);
+    dataCurrent = dataCells.cellContour3D{bioCell}.cellCtFlatViaOri;
 
     % Calculate the rotated contour using a vector and a rotation angle
     [newContour, dataCells.planeFit{bioCell}.rotationMatrix, ~] = AxelRot(dataCurrent',...
         dataCells.planeFit{bioCell}.angleRot, dataCells.planeFit{bioCell}.axisRot, x0);
     
     % Allocate to the proper structure
-    dataCells.cellContour3D{bioCell}.ContourFlattenViaOrigin = newContour';
-    dataCells.cellContour3D{bioCell}.ContourFlatten = dataCells.cellContour3D{bioCell}.ContourFlattenViaOrigin +...
-        dataCells.cellContour3D{bioCell}.bestPlaneProj(1,:);
+    dataCells.cellContour3D{bioCell}.cellCtFlatViaOriRot = newContour';
+    dataCells.cellContour3D{bioCell}.cellCtFlatRot = dataCells.cellContour3D{bioCell}.cellCtFlatViaOriRot +...
+        dataCells.cellContour3D{bioCell}.cellCtFlat(1,:);
     
     % Calculate perimeters for proper control
-    perimeter3D = 0;
-    perimeterFlatten = 0;
+    perimeterReal = 0;
+    perimeterRot = 0;
     perimeterProj = 0;
     for point = 2:length(newContour)
-        perimeter3D = perimeter3D + sqrt(sum((dataCells.cellContour3D{bioCell}.ContourViaOrigin(point,:)-...
-            dataCells.cellContour3D{bioCell}.ContourViaOrigin(point-1,:)).^2,2));
-        perimeterFlatten = perimeterFlatten + sqrt(sum((dataCells.cellContour3D{bioCell}.ContourFlatten(point,:)-...
-            dataCells.cellContour3D{bioCell}.ContourFlatten(point-1,:)).^2,2));
-        perimeterProj = perimeterProj + sqrt(sum((dataCells.cellContour3D{bioCell}.ContourViaOrigin(point,1:2)-...
-            dataCells.cellContour3D{bioCell}.ContourViaOrigin(point-1,1:2)).^2,2));
+        perimeterReal = perimeterReal + sqrt(sum((dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point,:)-...
+            dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point-1,:)).^2,2));
+        perimeterRot = perimeterRot + sqrt(sum((dataCells.cellContour3D{bioCell}.cellCtFlatRot(point,:)-...
+            dataCells.cellContour3D{bioCell}.cellCtFlatRot(point-1,:)).^2,2));
+        perimeterProj = perimeterProj + sqrt(sum((dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point,1:2)-...
+            dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point-1,1:2)).^2,2));
     end
-    dataCells.cellContour3D{bioCell}.perimeter3D = perimeter3D;
-    dataCells.cellContour3D{bioCell}.perimeterFlatten = perimeterFlatten;
+    dataCells.cellContour3D{bioCell}.perimeterReal = perimeterReal;
+    dataCells.cellContour3D{bioCell}.perimeterRot = perimeterRot;
     dataCells.cellContour2D{bioCell}.perimeterProj = perimeterProj;
 end
 
@@ -889,11 +1010,11 @@ for bioCell = 1:length(dataCells.numbers)
     % it as geom3Dvectors structure
     % Calculate it's normal vecteur and (not yet) cartesian equation using Alpha Beta
     % and Gamma
-    planeFit{bioCell}.pointsOfPlane(1,1:2) = min(dataCells.cellContour3D{bioCell}.VerticesOrdered(:,1:2));
-    planeFit{bioCell}.pointsOfPlane(2,1:2) = [min(dataCells.cellContour3D{bioCell}.VerticesOrdered(:,1)) , ...
-        max(dataCells.cellContour3D{bioCell}.VerticesOrdered(:,2))];
-    planeFit{bioCell}.pointsOfPlane(3,1:2) = [max(dataCells.cellContour3D{bioCell}.VerticesOrdered(:,1)) , ...
-        max(dataCells.cellContour3D{bioCell}.VerticesOrdered(:,2))];
+    planeFit{bioCell}.pointsOfPlane(1,1:2) = min(dataCells.cellContour3D{bioCell}.cellCt(:,1:2));
+    planeFit{bioCell}.pointsOfPlane(2,1:2) = [min(dataCells.cellContour3D{bioCell}.cellCt(:,1)) , ...
+        max(dataCells.cellContour3D{bioCell}.cellCt(:,2))];
+    planeFit{bioCell}.pointsOfPlane(3,1:2) = [max(dataCells.cellContour3D{bioCell}.cellCt(:,1)) , ...
+        max(dataCells.cellContour3D{bioCell}.cellCt(:,2))];
     planeFit{bioCell}.pointsOfPlane(:,3) = ...
         planeFit{bioCell}.avAlBeGa(1)*planeFit{bioCell}.pointsOfPlane(:,1) + ...
         planeFit{bioCell}.avAlBeGa(2)*planeFit{bioCell}.pointsOfPlane(:,2) + ...
diff --git a/MainScripts/surface3D_combine_dev.m b/MainScripts/surface3D_combine_dev.m
new file mode 100644
index 0000000000000000000000000000000000000000..d79bed0082d522e5aabf44d76485a029e8cb5f51
--- /dev/null
+++ b/MainScripts/surface3D_combine_dev.m
@@ -0,0 +1,1076 @@
+
+% The objective here is to recalculate the geometrical parameters of cells
+% segmented in a 2D projected map using a 3D mesh. Desired geometrical
+% parameters are area, orientation, ratio (length-width), curvature
+%
+% V2D - vertex of the cell contour in the 2D segmentation
+% V3D - vertex of the mesh
+%
+
+%{
+Steps:
+1) Input parameter
+2) Load 2D segmentation (and double check parameters)
+3) Load 3D segmentation
+4) Recreate the cellular surface contour using a marching square method
+5) Find which faces of the mesh are relevant for which cell of the
+projected seg (based on the polygon surface of the cell)
+6) Calculate the surface of each cell (projected and real)
+7) Finding bellaiche sides and mesh faces connections
+8) Finding bellaiche contour and mesh faces connections
+9) Clear over and under covered cells
+10) Deproject both the cell contour and the edges on the mesh
+11) Recalculate the fit to ellipse 
+12) Create a table output
+13) Saving output
+14) Display final maps
+%}
+
+function surface3D_combine()
+tic
+close all
+
+PARAMS = {};
+
+%%%%%%%%%%%%%%%%%%%%%% PARAMETERS %%%%%%%%%%%%%%%%%%%%%% 
+
+PARAMS.softVersion = 'surface3D_combine_v0p12.m';
+
+% Set the following switches to false if not desired (true if desired)
+PARAMS.doDispBell = true; % display the 2D segmentation
+PARAMS.doDispMesh = true; % display the 3D mesh
+PARAMS.doDispOverlay = true; % display the overlayed 2D seg and 3D mesh
+PARAMS.doDispErrorEllipse = true; % display the cells with an ellipse fit error 
+
+% PARAMS.imSettings.x = 3342; % image size in X (in px) % set in dataSeg
+% PARAMS.imSettings.y = 2916; % image size in Y (in px) % set in dataSeg
+PARAMS.imSettings.z = 103; % image size in Z (in px)
+% PARAMS.imSettings.latPixSize = 0.2076; % Lateral pixel size (in um) % set in dataSeg
+PARAMS.imSettings.axPixSize = 0.5; % Axial pixel size (in um)
+
+PARAMS.maxFaces = 3000; % set he maximum number of faces for the mesh (will use the reducepatch
+% function if the number is too high
+
+PARAMS.maxTolAreaRatio = 0.001; % set the maximum tolerance for the ratio faceArea / cellArea
+
+%%%%%%%%%%%%%%%%%%%%%% END OF PARAMETERS %%%%%%%%%%%%%%%%%%%%%% 
+
+PARAMS.outputFolder = uigetdir(pwd,'Select the output folder');
+cd(PARAMS.outputFolder)
+PARAMS.meshLoc = uipickfiles( 'Prompt','Select the mesh file (.ply or .py format)',...
+    'FilterSpec','*.ply','out','ch','num',1);
+PARAMS.segLoc = uipickfiles( 'Prompt','Select the 2D segmented file (.mat format)',...
+    'FilterSpec','*.mat','out','ch','num',1);
+
+
+
+% % GUI call bypass
+% PARAMS.meshLoc =...
+%     'D:\sherbert\project1\newMesh_\processedMesh_bin.ply';
+% PARAMS.segLoc = ...
+%     'D:\sherbert\project1\testSeg2D\Bellaiche_output\SIA_161210_gfapnlsg_Backup_001.mat';
+
+
+%% Load 2D segmetation from Bellaiche soft and resize/flip
+[dataSeg, dataCells, PARAMS] = loadSeg(PARAMS);
+
+%% Load 3D mesh from MorphographX soft
+% to be a GUI later
+dataMesh = loadMesh(PARAMS);
+
+        
+%% plots of 2D segmentation and Mesh
+% Plot Bellaiche data if asked
+if PARAMS.doDispBell % only plots the light version (nodes only)
+    figure
+    plotSeg(dataSeg.SIDES.vertices,dataSeg.VERTICES.XYs,PARAMS);
+    axis equal
+    savefig(gcf,[PARAMS.outputFolder filesep 'seg2D']);
+end
+% Plot Mesh data if asked
+if PARAMS.doDispMesh
+    figure
+    plotMesh(dataMesh,PARAMS);
+    axis equal
+    savefig(gcf,[PARAMS.outputFolder filesep 'mesh3D']);
+end
+% Plot combined images if asked % currently an issue since displayed
+% bellaiche is in µm and mesh in pix
+if PARAMS.doDispOverlay
+    figure
+    hold on
+    plotSeg(dataSeg.SIDES.vertices,dataSeg.VERTICES.XYs,PARAMS);
+    plotMesh(dataMesh,PARAMS);
+    axis equal
+    title('2D segmentation and 3D mesh combined');
+    savefig(gcf,[PARAMS.outputFolder filesep 'seg2D_mesh3D']);
+    export_fig([PARAMS.outputFolder filesep 'seg2D_mesh3D2'],'-png','-m5');
+end
+
+%% Here will go the mesh parsing function for limits in angle, holes and folds
+% for getting rid of holes => check intersection in a square matrice of the
+% faces and rid of the ones for which intersection > 0 on the fly to limit
+% the calculations
+
+%% Restructure projected cells to proper contours
+% Find contiguous points of each cell/polygon countour
+% Creates the edges for later use
+dataCells.cellContour2D = findContour(dataCells.contourPo2D,'bwboundary',PARAMS);
+
+% % create triangulated areas Check with polygon intersection instead
+% dataCells = polygon2surface(dataCells);
+
+%% delete cells at the boundary of the mesh or at the boundary of forbidden areas such as too steep angles
+
+
+%% Find which faces of the mesh are relevant for which cell of the projected seg
+[dataCells, dataMesh] = cell2face(dataMesh,dataCells);
+
+%% Calculate the surface of each cell
+dataCells = cellSurface(dataMesh,dataCells);
+
+%% finding bellaiche sides and faces connections
+dataCells = side2face(dataCells,dataSeg,dataMesh);
+
+%% Sort contour pixels by face and biological cell
+dataCells = contour2face(dataCells,dataMesh);
+
+%% Clear over and under covered cells
+dataCells = checkCoverage(dataCells,dataMesh,dataSeg,PARAMS);
+% check polygon of cell - polygon of faces result => if ~empty => delete
+
+%% Projected both the cell contour and the edges on the mesh
+[dataCells, dataMesh] = projectOnMesh(dataCells, dataSeg, dataMesh, PARAMS);
+
+%% Recalculate the fit to ellipse 
+dataCells = cell2ellipse(dataCells,dataMesh,PARAMS);
+
+%% Create a table output
+[tableOutputDeproj, tableOutputBell] = formatTableOuputSurfaceCombine(dataCells,dataSeg);
+
+%% Saving output
+save([PARAMS.outputFolder filesep 'deprojectedData.mat'],...
+    'dataCells','dataMesh','dataSeg','PARAMS');
+
+% save([PARAMS.outputFolder filesep 'deprojectedTable.mat'],'tableOutputDeproj');
+save('deprojectedTable.mat','tableOutputDeproj');
+
+% save([PARAMS.outputFolder filesep 'bellaicheTable.mat'],'tableOutputBell');
+save('bellaicheTable.mat','tableOutputBell');
+
+%% Display final maps
+displayCombinedMap(tableOutputDeproj,tableOutputBell,dataCells.cellContour3D,PARAMS.outputFolder)
+toc
+
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% 
+%%%%%%%%%%%%%%%%%%%%%%%%%     END MAIN FUNCTION     %%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% 
+
+function dataMesh = loadMesh(PARAMS)
+
+% load data
+% Add we GUI after original test phase
+fprintf('Loading mesh file\n');
+[dataMesh.vertices,dataMesh.faces] = read_ply(PARAMS.meshLoc);
+
+ 
+% Correct the centering of the image (force 0,0,0 in bottom left)
+dataMesh.vertices = bsxfun(@plus,dataMesh.vertices,[PARAMS.imSettings.x*PARAMS.imSettings.latPixSize...
+    PARAMS.imSettings.y*PARAMS.imSettings.latPixSize...
+    PARAMS.imSettings.z*PARAMS.imSettings.axPixSize]/2);
+
+% Flip in Y the image for overlay with the 2D segmentation
+dataMesh.vertices(:,2) = abs(bsxfun(@minus,dataMesh.vertices(:,2),...
+    PARAMS.imSettings.y*PARAMS.imSettings.latPixSize));
+
+% If the number of faces is too high than reduce them
+if length(dataMesh.faces)>PARAMS.maxFaces
+    fprintf('Reducing the number of faces in the Mesh\n');
+    dataMesh = reducepatch(dataMesh,PARAMS.maxFaces,'verbose');    
+end
+
+% Calculate normals of the faces
+[dataMesh.normalV,dataMesh.normalF] = compute_normal(dataMesh.vertices,dataMesh.faces);
+
+end
+
+function [dataSeg, dataCells, PARAMS] = loadSeg(PARAMS) 
+% load and parse data from the Bellaiche analysis 
+% returns the main structure + an additionnal field for the cells contour
+% in pixels (0,0,0 = corners bottom left)
+
+% Load data 
+% Add we GUI after original test phase
+fprintf('Loading segmentation file\n');
+dataSeg = load(PARAMS.segLoc);
+
+% Set x y and frame parameters
+PARAMS.imSettings.x = dataSeg.FRAME.imageSize(2); % image size in X (in px) % exists in dataSeg
+PARAMS.imSettings.y = dataSeg.FRAME.imageSize(1); % image size in Y (in px) % exists in dataSeg
+% PARAMS.imSettings.z and PARAMS.imSettings.axPixSize => are set by hand at
+% the beginning
+PARAMS.imSettings.latPixSize = dataSeg.FRAME.scale1D; % Lateral pixel size (in um) % exists in dataSeg
+
+% Check Parameter values
+PARAMS = checkPARAMS(PARAMS);
+
+% rescale and calculate the 2D position of each cell contour (and delete the whole sample fake cell)
+dataCells.contourPo2D = {};
+for bioCell=1:length(dataSeg.CELLS.numbers) % for each cell
+    dataCells.contourPo2D{bioCell} = zeros(length(dataSeg.CELLS.contour_indices{bioCell}),2);
+    for vertice=1:length(dataSeg.CELLS.contour_indices{bioCell})
+        %         dataCells.contourPo2D{bioCell}(vertice,1)=...
+        %             idivide(dataSeg.CELLS.contour_indices{bioCell}(vertice),int32(2916))*PARAMS.imSettings.latPixSize;
+        %         dataCells.contourPo2D{bioCell}(vertice,2)=...
+        %             rem(dataSeg.CELLS.contour_indices{bioCell}(vertice),int32(2916))*PARAMS.imSettings.latPixSize;
+        %         dataCells.contourPo2D{bioCell}(vertice,3)=0; % fake z position for plot 3D
+        
+        dataCells.contourPo2D{bioCell}(vertice,1)=...
+            double(idivide(dataSeg.CELLS.contour_indices{bioCell}(vertice),int32(2916)))*PARAMS.imSettings.latPixSize;
+        dataCells.contourPo2D{bioCell}(vertice,2)=...
+            double(rem(dataSeg.CELLS.contour_indices{bioCell}(vertice),int32(2916)))*PARAMS.imSettings.latPixSize;
+    end
+end
+dataCells.contourPo2D = dataCells.contourPo2D';
+
+dataCells.types = dataSeg.CELLS.types;
+dataCells.numbers = dataSeg.CELLS.numbers;
+
+% % delete largest cell => whole sample fake cell % to be used if too long
+% % calculation or proves to be a problem
+% [sorted_contour_length,I] = sort(dataSeg.CELLS.contour_chord_lengths,'descend');
+% if sorted_contour_length(1)/sorted_contour_length(2) > 10
+%     % if not the largest cell may not be the sample contour
+%     dataCells.contourPo2D(I(1)) = [];
+% else
+%     disp('Warning: check that the largest cell is the sample contour');
+% end
+
+end
+
+function plotTable = plotSeg(sides,vertices,PARAMS)
+% plots the 2D segmention from Bellaiche in the open figure
+uSides = unique(sides, 'rows'); % get rid of duplicates
+uSides = uSides(uSides(:,1)~=uSides(:,2),:); % get rid of circular cell
+graphTable = graph();
+graphTable = addnode(graphTable,size(vertices,1));
+graphTable = addedge(graphTable,uSides(:,1),uSides(:,2));
+plotTable = plot(graphTable,'marker','none','NodeLabel',[],'EdgeColor','k');
+if size(vertices,2)==3
+    plotTable.ZData = (vertices(:,3));
+    plotTable.YData = (vertices(:,2));
+    plotTable.XData = (vertices(:,1));
+else
+    plotTable.YData = (vertices(:,2));
+    plotTable.XData = (vertices(:,1));
+end
+% axis equal
+xlabel('X position ({\mu}m)');
+ylabel('Y position ({\mu}m)');
+title('2D segmentation result');
+axis([0 PARAMS.imSettings.x*PARAMS.imSettings.latPixSize ...
+    0 PARAMS.imSettings.y*PARAMS.imSettings.latPixSize]);
+end
+
+function patchHandle = plotMesh(dataMesh,PARAMS)
+% Display mesh with z info encoded in colormap with transparency
+
+patchHandle = patch('Faces',dataMesh.faces,'Vertices',dataMesh.vertices,...
+    'FaceVertexCData',dataMesh.vertices(:,3),'FaceColor','interp','LineStyle','none',...
+    'FaceVertexAlphaData',0.3,'FaceAlpha','flat');
+% % Display mesh with only edges and vertices
+% patchedMesh = patch(dataMesh, 'FaceColor','none','LineWidth',0.5);
+% hold on
+% plot3(dataMesh.vertices(:,1),dataMesh.vertices(:,2),dataMesh.vertices(:,3),'.');
+axis equal
+xlabel('X position ({\mu}m)');
+ylabel('Y position ({\mu}m)');
+title('3D Mesh result');
+axis([0 PARAMS.imSettings.x*PARAMS.imSettings.latPixSize...
+    0 PARAMS.imSettings.y*PARAMS.imSettings.latPixSize...
+    0 PARAMS.imSettings.z*PARAMS.imSettings.axPixSize]);
+end
+
+function [dataCells, dataMesh] = cell2face(dataMesh,dataCells)
+% cycle through each cell and finds wich face of the mesh idoFirstPassntersect
+% Numerical problems can occur when the polygons have a large offset from
+% the origin !
+
+fprintf('Establishing the cell/mesh connectivity\n');
+
+% Preallocate structures
+dataCells.cell2Face = cell(length(dataCells.numbers),1);
+dataCells.Face2Cell = cell(size(dataMesh.faces,1),1);
+dataMesh.contour = cell(size(dataMesh.faces,1),1);
+
+% For every face of the mesh (first since it has to be reallocated into a
+% more manageable structure for every comparison)
+tic
+tempTime = 0;
+for meshTri = 1:size(dataMesh.faces,1) % USE A PARFOR HERE IF POSSIBLE !
+    if mod(meshTri,100)== 0
+        fprintf('Analysed faces = %d out of %d. Time since last timepoint = %.1fs\n',meshTri,size(dataMesh.faces,1),...
+            toc-tempTime);
+        tempTime = toc;
+    end
+    % allocate the triangular of the Mesh face
+    dataMesh.contour{meshTri} = vertcat(dataMesh.vertices(dataMesh.faces(meshTri,1),:),...
+        dataMesh.vertices(dataMesh.faces(meshTri,2),:),...
+        dataMesh.vertices(dataMesh.faces(meshTri,3),:));
+    if ~ispolycw(dataMesh.contour{meshTri}(:,1),dataMesh.contour{meshTri}(:,2))
+        % check and force clockwise ordering
+        [dataMesh.contour{meshTri}(:,1),dataMesh.contour{meshTri}(:,2)] = ...
+            poly2cw(dataMesh.contour{meshTri}(:,1), dataMesh.contour{meshTri}(:,2));
+    end
+    % end
+    
+    % for every cell of the mesh
+    for bioCell = 1: length(dataCells.numbers)
+        %         bioCell = 1000;
+        [xInter, ~] = polybool('intersection', dataCells.cellContour2D{bioCell}.cellCt(:,1),...
+            dataCells.cellContour2D{bioCell}.cellCt(:,2),...
+            dataMesh.contour{meshTri}(:,1),dataMesh.contour{meshTri}(:,2));
+        if ~isempty(xInter)
+            %             fprintf('cell %d Connected with mesh face %d\n', bioCell, meshTri);
+            dataCells.cell2Face{bioCell} = cat(1,dataCells.cell2Face{bioCell},meshTri);
+            dataCells.Face2Cell{meshTri} = cat(1,dataCells.Face2Cell{meshTri},bioCell);
+        end
+    end
+end
+fprintf('Total time = %.1fs\n',toc);
+
+end
+
+function dataCells = cellSurface(dataMesh,dataCells)
+% calculate the surface of each 2D segmented cell
+
+
+%% calculate the 2D surfaces of the polygonal faces intersecting the cell
+fprintf('Calculating the 2D surface of the polygonal faces intersecting each cell\n')
+
+dataCells.area.areaProjTot = cell(length(dataCells.numbers),1);
+dataCells.area.areaProjPerFace = cell(length(dataCells.numbers),1);
+
+for bioCell = 1 : length(dataCells.contourPo2D)
+    if isempty(dataCells.cell2Face{bioCell})
+        continue
+    end
+    for polyInd = 1:length(dataCells.cell2Face{bioCell})
+        % for every face of the mesh connected to the cell
+
+        % Find the intersection of the face and cell
+        [xInter, yInter] = polybool('intersection', dataCells.cellContour2D{bioCell}.cellCt(:,1),...
+            dataCells.cellContour2D{bioCell}.cellCt(:,2),...
+            dataMesh.contour{dataCells.cell2Face{bioCell}(polyInd)}(:,1),...
+            dataMesh.contour{dataCells.cell2Face{bioCell}(polyInd)}(:,2));
+        
+        % If more than 1 intersection, split the polygon
+        [xsplit, ysplit] = polysplit(xInter,yInter);
+        
+        % Calculates the projected intersecting surface for the n splitted
+        % polygons when needed
+        dataCells.area.areaProjPerFace{bioCell}(polyInd) = 0;
+        for n = 1:numel(xsplit)
+            dataCells.area.areaProjPerFace{bioCell}(polyInd) = ...
+                dataCells.area.areaProjPerFace{bioCell}(polyInd)+polyarea(xsplit{n}, ysplit{n});
+        end
+    end
+    dataCells.area.areaProjTot{ bioCell } = sum(dataCells.area.areaProjPerFace{bioCell});
+    dataCells.area.areaProjPerFace{ bioCell } = dataCells.area.areaProjPerFace{bioCell}';
+end
+
+%% Calculate the real and projected surfaces of the mesh Faces
+dataMesh = face2Area(dataMesh);
+
+%% Correct each polygon 2D surface using the mesh face normal vector to obtain the 3D surface
+dataCells.area.areaRealTot = cell(length(dataCells.numbers),1);
+dataCells.area.areaRealPerFace = cell(length(dataCells.numbers),1);
+for bioCell = 1:length(dataCells.contourPo2D)
+    dataCells.area.areaRealPerFace{bioCell} = [];
+    dataCells.area.areaRealPerFace{bioCell} = dataCells.area.areaProjPerFace{bioCell}.*...
+        dataMesh.surfRatio(dataCells.cell2Face{bioCell});
+    dataCells.area.areaRealTot{bioCell} = [];
+    dataCells.area.areaRealTot{bioCell} = sum(dataCells.area.areaRealPerFace{bioCell});
+end
+
+end
+
+function dataMesh = face2Area(dataMesh)
+% Calculates both the projected along z and the real surface of each face
+% of the mesh
+
+fprintf('Calculating the mesh faces real and projected surfaces\n');
+
+% vectors of sides 1 and 2 of triangle
+u = dataMesh.vertices(dataMesh.faces(:,2), :) - dataMesh.vertices(dataMesh.faces(:,1), :);
+v = dataMesh.vertices(dataMesh.faces(:,3), :) - dataMesh.vertices(dataMesh.faces(:,1), :);
+% Real surface calculation
+dataMesh.realSurfFace = 1/2 * sqrt(sum(cross(u,v,2).^2, 2));
+% Z Projected surface calculation
+u(:,3) = 0;
+v(:,3) = 0;
+dataMesh.zProjSurfFace = 1/2 * sqrt(sum(cross(u,v,2).^2, 2));
+% Surface ratio
+dataMesh.surfRatio = dataMesh.realSurfFace./dataMesh.zProjSurfFace;
+end
+
+function dataCells = side2face(dataCells,dataSeg,dataMesh)
+% Returns a faceID of the face above any specific vertex of the contour
+% based on Bellaiche side figure
+% Will provide a face connection to 0 if not covered by the mesh
+for vertex = 1:length(dataSeg.VERTICES.XYs)
+    if mod(vertex,1000)==0
+        fprintf('Scanning vertex %d out of %d\n', vertex, length(dataSeg.VERTICES.XYs));
+    end
+    for triFace = 1:length(dataMesh.faces) % for each triangular face of the mesh 
+        in = inpolygon(dataSeg.VERTICES.XYs(vertex,1),...
+            dataSeg.VERTICES.XYs(vertex,2),...
+            dataMesh.contour{triFace}(:,1),...
+            dataMesh.contour{triFace}(:,2));
+        if in
+           dataCells.VERTICES.vertexOnFace(vertex) = triFace;
+           continue
+        end
+    end
+end
+
+toc
+
+end
+
+function dataCells = contour2face(dataCells,dataMesh)
+% for each cell, this function will parse the contour and find at which
+% face this contour point is attached. This sorting will be used for later
+% cell orientation calculation and cell coverage check
+% Precedently used for presence check (now merged in checkOverlap)
+
+for bioCell = 1:length(dataCells.cellContour2D) % for each cell 
+    % last position is the same as first for a close contour
+    dataCells.cellContour2D{bioCell}.vertexOnFace = ...
+        zeros(length(dataCells.cellContour2D{bioCell}.cellCt),1); 
+    for triFace = 1:length(dataCells.cell2Face{bioCell}) % for each triangular face of the mesh connected to the cell
+        in = inpolygon(dataCells.cellContour2D{bioCell}.cellCt(1:end-1,1),...
+            dataCells.cellContour2D{bioCell}.cellCt(1:end-1,2),...
+            dataMesh.contour{dataCells.cell2Face{bioCell}(triFace)}(:,1),...
+            dataMesh.contour{dataCells.cell2Face{bioCell}(triFace)}(:,2));
+        dataCells.cellContour2D{bioCell}.vertexOnFace(in) = dataCells.cell2Face{bioCell}(triFace);
+    end
+    % last position is the same as first for a close contour
+    dataCells.cellContour2D{bioCell}.vertexOnFace(end) = dataCells.cellContour2D{bioCell}.vertexOnFace(1);
+end
+
+
+end
+
+function dataCells = checkCoverage(dataCells,dataMesh,dataSeg,PARAMS)
+
+% Save dataset prior to filtering
+dataCells.allCells = dataCells;
+
+% First: Check for overcovered cells
+dataCells.allCells.overCoveredCells = checkOverCovered(dataCells,dataMesh);
+% after comparison of 3 methods (area ratio, normal to faces and contour
+% check) the normal method is the most conservative and doesn't let any
+% cell through if there is the smallest fold above it
+
+% Second: Check the remaining cells for undercoverage
+dataCells.allCells.underCoveredCells = checkUnderCovered(dataCells,PARAMS);
+% after comparison of 2 methods (area ratio (0.01% of difference) and
+% contour check), it seems that no method is more conservative and both
+% will miss a few cells (1-3 out of 3k). => merge of methods
+
+% Crop those cells out
+dataCells = cropOutCells(dataCells,dataSeg);
+
+% Display the croped out cells
+displayClipped(PARAMS,dataMesh,dataCells,dataSeg);
+
+end
+
+function overCoveredCells = checkOverCovered(dataCells,dataMesh)
+% list cells covered by a downwards oriented face
+
+downFaces = dataMesh.normalF(3,:)<0;
+overCoveredCells = unique(vertcat(dataCells.Face2Cell{downFaces}));
+
+end
+
+function underCoveredCells = checkUnderCovered(dataCells,PARAMS)
+
+% List cells for which the coverage is only partial (below a user defined
+% threshold)
+areaCell = zeros(length(dataCells.numbers),1);
+areaSeg = zeros(length(dataCells.numbers),1);
+for bioCell = 1:length(dataCells.numbers)
+    areaSeg(bioCell) = polyarea(dataCells.cellContour2D{bioCell}.cellCt(:,1),...
+        dataCells.cellContour2D{bioCell}.cellCt(:,2));
+    if isempty(dataCells.area.areaProjTot{bioCell})
+        areaCell(bioCell) = 0;
+    else
+        areaCell(bioCell) = dataCells.area.areaProjTot{bioCell};
+    end
+end
+areaRatio = areaCell./areaSeg;
+underCoveredArea = find((areaRatio+PARAMS.maxTolAreaRatio)<1);
+
+% Make sure every pixel of the contour is under the mesh, might otherwise
+% be an issue later
+% if there is unallocated vertexes the default face value will be 0
+% (otherwise >= 1)
+underCoveredContour = [];
+for bioCell = 1:length(dataCells.numbers)
+    if(logical(sum(dataCells.cellContour2D{bioCell}.vertexOnFace == 0)))
+        underCoveredContour = horzcat(underCoveredContour,bioCell);
+    end
+end
+
+% Merge both tests
+underCoveredCells = unique(vertcat(underCoveredArea,underCoveredContour'));
+
+end
+
+function displayClipped(PARAMS,dataMesh,dataCells,dataSeg)
+% display the 2D segmentation and the 3D mesh
+% List of the different sides populations to plot
+sidesList{1} = dataCells.SIDES.goodSides;
+leg1 = sprintf('Good cells (N=%d)',length(dataCells.numbers));
+sidesList{2} = dataCells.SIDES.underSides;
+leg2 = sprintf('Undercovered cells (N=%d)',length(dataCells.allCells.underCoveredCells));
+sidesList{3} = dataCells.SIDES.overSides;
+leg3 = sprintf('Overcovered cells (N=%d)',length(dataCells.allCells.overCoveredCells));
+sidesList{4} = dataCells.SIDES.underOverSides;
+leg4 = sprintf('Under and Overcovered cells (N=%d)',length(dataCells.allCells.underAndOverCells));
+allVertices = dataSeg.VERTICES.XYs;
+% dispPARAMS: parameters of the display
+dispPARAMS{1}.LineWidth = 0.5;
+dispPARAMS{1}.EdgeColor = [0.5;0.5;0.5]';
+dispPARAMS{2}.LineWidth = 2;
+dispPARAMS{2}.EdgeColor = [0.64;0.08;0.18]';
+dispPARAMS{3}.LineWidth = 2;
+dispPARAMS{3}.EdgeColor = [0.20;0.41;0]';
+dispPARAMS{4}.LineWidth = 2;
+dispPARAMS{4}.EdgeColor = [1;0;1]';
+% Legends to be associated
+fullLegs = {leg1 leg2 leg3 leg4 'Mesh overlay'};
+
+displaySubPop(PARAMS,sidesList,allVertices,fullLegs,dispPARAMS,dataMesh);
+
+title('Rejected clipped cells');
+savefig(gcf,[PARAMS.outputFolder filesep 'rejected_clipped_cells']);
+export_fig([PARAMS.outputFolder filesep 'rejected_clipped_cells'],'-png','-m5');
+end
+
+function displaySubPop(PARAMS,sidesList,allVertices,fullLegs,dispPARAMS,dataMesh)
+
+figure
+hold on
+
+for graphPt = 1:length(sidesList)
+    h{graphPt} = plotSeg(sidesList{graphPt},allVertices,PARAMS);
+    h{graphPt}.EdgeColor = dispPARAMS{graphPt}.EdgeColor;
+    h{graphPt}.LineWidth = dispPARAMS{graphPt}.LineWidth;
+end
+
+% Overlay with mesh in blue only if the dataMesh arg is provided
+if nargin == 6
+    h{length(sidesList)+1} = plotMesh(dataMesh,PARAMS);
+    h{length(sidesList)+1}.FaceColor = [0;0.45;0.74];
+end
+
+axis equal
+box
+
+legend(fullLegs);
+
+end
+
+function dataCells = cropOutCells(dataCells,dataSeg)
+
+% Combine both over and under pop
+catClipped = vertcat(dataCells.allCells.overCoveredCells,...
+    dataCells.allCells.underCoveredCells);
+
+% Boil up the array to only keep unique cells
+clippedCellList = unique(catClipped);
+
+% Find redondant cells (overAndUnder pop)
+occurence = sum(catClipped==catClipped');
+if sum(occurence>1)/2+length(clippedCellList) ~= length(catClipped)
+    % means that the number of cells occuring once + the number of cells
+    % occuring more than once is not the same as the whole population =>
+    % which is not normal
+    fprintf('WARNING : Coverage check malfunction (number of duplicated cells)\n');
+end
+dataCells.allCells.underAndOverCells = unique(catClipped(occurence>1));
+
+% make a copy of all the SIDES associated with each population (except
+% for the good ones which will be selected by default) into a separate copy
+% to be able to display them separately
+dataCells.SIDES.underSides = dataSeg.SIDES.vertices(...
+    vertcat(dataSeg.CELLS.sides{dataCells.numbers(dataCells.allCells.underCoveredCells)}),:);
+dataCells.SIDES.overSides = dataSeg.SIDES.vertices(...
+    vertcat(dataSeg.CELLS.sides{dataCells.numbers(dataCells.allCells.overCoveredCells)}),:);
+dataCells.SIDES.underOverSides = dataSeg.SIDES.vertices(...
+    vertcat(dataSeg.CELLS.sides{dataCells.numbers(dataCells.allCells.underAndOverCells)}),:);
+
+% Delete all the badly covered cells from the main structure
+dataCells.contourPo2D(clippedCellList) = [];
+dataCells.cellContour2D(clippedCellList) = [];
+dataCells.cell2Face(clippedCellList) = [];
+dataCells.area.areaProjPerFace(clippedCellList) = [];
+dataCells.area.areaProjTot(clippedCellList) = [];
+dataCells.area.areaRealPerFace(clippedCellList) = [];
+dataCells.area.areaRealTot(clippedCellList) = [];
+dataCells.types(clippedCellList) = [];
+dataCells.numbers(clippedCellList) = [];
+
+% Create the last SIDES copy for the good cells
+dataCells.SIDES.goodSides = dataSeg.SIDES.vertices(vertcat(...
+    dataSeg.CELLS.sides{dataCells.numbers}),:);
+
+% Make sure than the total number of cells is unchanged 
+if sum(length(clippedCellList)+length(dataCells.numbers))~=...
+        length(dataCells.allCells.numbers)
+    % means that the number of cells kept + the number of deleted cells is
+    % equal to the total number of cells
+    fprintf('WARNING : Coverage check malfunction (total number of cells)\n');
+end
+
+% Remove the clipped cells from the face2cell connections
+for meshFace = 1:length(dataCells.Face2Cell)
+    tempConnect = dataCells.allCells.Face2Cell{meshFace};
+    for clipped = 1:length(clippedCellList)
+        tempConnect = tempConnect(tempConnect ~= clippedCellList(clipped));
+    end
+    dataCells.Face2Cell{meshFace} = tempConnect;
+end
+
+end
+
+function [dataCells, dataMesh] = projectOnMesh(dataCells, dataSeg, dataMesh, PARAMS)
+
+% Calculate plane equations describing each face (Alpha*X,Beta*Y,Gamma = Z)
+for meshFace = 1:length(dataMesh.faces)
+    faceCoords = dataMesh.vertices(dataMesh.faces(meshFace,:),:);
+    XYmat = horzcat(faceCoords(:,1:2),ones(3,1));
+    Zmat = faceCoords(:,3);
+    dataMesh.planeCoefPerFace(meshFace,:) = XYmat \ Zmat;
+end
+
+% Use face plane coefficients to deproject the 2D contour on the mesh
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.cellCt = ...
+        dataCells.cellContour2D{bioCell}.cellCt;
+    dataCells.cellContour3D{bioCell}.cellCt(:,3) = diag(...
+        horzcat(dataCells.cellContour2D{bioCell}.cellCt,...
+        ones(length(dataCells.cellContour2D{bioCell}.cellCt),1)) * ...
+        dataMesh.planeCoefPerFace(dataCells.cellContour2D{bioCell}.vertexOnFace,:)');
+end
+dataCells.cellContour3D = dataCells.cellContour3D';
+
+% And the 2D sides on the mesh
+dataCells.VERTICES.XYZs = zeros(size(dataSeg.VERTICES.XYs,1),3);
+dataCells.VERTICES.XYZs = dataSeg.VERTICES.XYs;
+for vertex = 1:length(dataCells.VERTICES.vertexOnFace)
+    if dataCells.VERTICES.vertexOnFace(vertex)==0
+        % when the vertex is not under the mesh, keep its z position at 0
+        continue
+    end
+    dataCells.VERTICES.XYZs(vertex,3) = horzcat(dataCells.VERTICES.XYZs(vertex,1:2),ones(1)) * ...
+        dataMesh.planeCoefPerFace(dataCells.VERTICES.vertexOnFace(vertex),:)';
+end
+
+displayDeprojected(PARAMS,dataMesh,dataCells)
+
+end
+
+function displayDeprojected(PARAMS,dataMesh,dataCells)
+% display the 3D deprojected mesh and segmentation
+% List of the different sides populations to plot
+sidesList{1} = dataCells.SIDES.goodSides;
+leg1 = sprintf('Good cells (N=%d)',length(dataCells.cellContour3D));
+sidesList{2} = dataCells.SIDES.underSides;
+leg2 = sprintf('Undercovered cells (N=%d)',length(dataCells.allCells.underCoveredCells));
+sidesList{3} = dataCells.SIDES.overSides;
+leg3 = sprintf('Overcovered cells (N=%d)',length(dataCells.allCells.overCoveredCells));
+sidesList{4} = dataCells.SIDES.underOverSides;
+leg4 = sprintf('Under and Overcovered cells (N=%d)',length(dataCells.allCells.underAndOverCells));
+allVertices = dataCells.VERTICES.XYZs;
+% dispPARAMS: parameters of the display
+dispPARAMS{1}.LineWidth = 0.5;
+dispPARAMS{1}.EdgeColor = [0.5;0.5;0.5]';
+dispPARAMS{2}.LineWidth = 2;
+dispPARAMS{2}.EdgeColor = [0.64;0.08;0.18]';
+dispPARAMS{3}.LineWidth = 2;
+dispPARAMS{3}.EdgeColor = [0.20;0.41;0]';
+dispPARAMS{4}.LineWidth = 2;
+dispPARAMS{4}.EdgeColor = [1;0;1]';
+% Legends to be associated
+fullLegs = {leg1 leg2 leg3 leg4 'Mesh overlay'};
+
+displaySubPop(PARAMS,sidesList,allVertices,fullLegs,dispPARAMS,dataMesh)
+
+titleStr = 'Deprojected Rejected clipped cells';
+title(titleStr);
+savefig(gcf,[PARAMS.outputFolder filesep titleStr]);
+export_fig([PARAMS.outputFolder filesep titleStr],'-png','-m5');
+end
+
+function dataCells = cell2ellipse(dataCells,dataMesh,PARAMS)
+
+% Calculate average plane according to each individual contours
+dataCells.planeFit = avPlaneOfFaces(dataCells,dataMesh.planeCoefPerFace);
+
+% Project 3D contour on average plane
+for bioCell = 1:length(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.cellCtFlat = projPointOnPlane(dataCells.cellContour3D{bioCell}.cellCt,...
+        dataCells.planeFit{bioCell}.geom3Dvectors);
+end
+
+% Flatten on the Z=0 plane for further ellipse fitting
+dataCells = flattenContour(dataCells);
+
+% Fit an ellipse to the new flatten contour and the projected contour
+dataCells = allDimEllipseFitting(dataCells,PARAMS);
+
+end
+
+function dataCells = allDimEllipseFitting(dataCells,PARAMS)
+% Call the ellipse fitting and addition calculation for each independant
+% case of data (Flatten and rotated or Projected)
+
+% for flatten contours
+[dataCells.cellContour3D, dataCells.ellipseFitError3D] =...
+    BioCellEllipseFitting(dataCells.cellContour3D,dataCells.numbers,3,PARAMS,'ellipseRotViaOri');
+
+% for old 2D contours
+[dataCells.cellContour2D, dataCells.ellipseFitError2D] =...
+    BioCellEllipseFitting(dataCells.cellContour2D,dataCells.numbers,2,PARAMS,'ellipseProj');
+
+% Replace the semiaxes into the ellipse space for simpler display
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.ellipseRotViaOri = replaceSemiAxesInEllipseSpace...
+        (dataCells.cellContour3D{bioCell}.ellipseRotViaOri);
+    dataCells.cellContour2D{bioCell}.ellipseProj = replaceSemiAxesInEllipseSpace...
+        (dataCells.cellContour2D{bioCell}.ellipseProj);
+end
+
+% Derotate the real space ellipse
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.ellipseViaOri = ...
+        derotateEllipseData(dataCells.cellContour3D{bioCell}.ellipseRotViaOri,dataCells.planeFit{bioCell});
+end
+
+% Relocate the real space ellipse into the mesh
+for bioCell = 1:numel(dataCells.numbers)
+    dataCells.cellContour3D{bioCell}.ellipseReal = relocateEllipseInMeshSpace...
+        (dataCells.cellContour3D{bioCell}.ellipseViaOri, dataCells.cellContour3D{bioCell}.cellCtFlat);
+end
+
+end
+
+function ellipseStruct = setEllipseStructToNaN(ellipseStruct)
+% If the fit didn't work then simply create the fields with NaN
+
+ellipseStruct.ellipseContour = NaN;
+ellipseStruct.semiMajVec = NaN;
+ellipseStruct.semiMinVec = NaN;
+ellipseStruct.center = NaN;
+ellipseStruct.normOrientation = NaN;
+
+end
+
+
+function ellipseStruct = relocateEllipseInMeshSpace(ellipseViaOri,cellCt)
+% Relocate the fitted ellipse, center and semiaxes onto the mesh
+
+ellipseStruct = {};
+
+if isnan(ellipseViaOri.semiMajVec) % If the fit didn't work => pad with nan
+    ellipseStruct = setEllipseStructToNaN(ellipseStruct);
+    return
+end
+
+x0 = cellCt(1,:)'; % translation to apply
+
+% Apply translation to ellipse contour, center and semiaxes
+ellipseStruct.ellipseContour = ellipseViaOri.ellipseContour+x0;
+ellipseStruct.semiMajVec = ellipseViaOri.semiMajVec+x0;
+ellipseStruct.semiMinVec = ellipseViaOri.semiMinVec+x0;
+ellipseStruct.center = ellipseViaOri.center+x0;
+
+% Normalized orientation
+ellipseStruct.normOrientation = ellipseStruct.semiMajVec;
+ellipseStruct.normOrientation(:,2) = normalizeVector3d(ellipseStruct.semiMajVec(:,2)'-ellipseStruct.semiMajVec(:,1)')'+ellipseStruct.semiMajVec(:,1);
+
+end
+
+function ellipseStruct = derotateEllipseData(ellipseRotViaOri,planeFit)
+% Rotate the ellipse, center and semiaxes from the XY axis
+
+ellipseStruct = {};
+
+if isnan(ellipseRotViaOri.semiMajVec)  % If the fit didn't work => pad with nan
+    ellipseStruct = setEllipseStructToNaN(ellipseStruct);
+    return
+end
+
+x0 = []; % no translation in addition to rotation
+
+% Allocate for simple reading of rotation axis, rotation amplitude, 
+axisRot = planeFit.axisRot; % Rotation axis between Z axis and cell normal vector in mesh
+angleRot = -planeFit.angleRot; % % inverse of the original rotation amplitude to revert to original
+
+% Apply rotation to ellipse contour, center and semiaxes
+ellipseStruct.ellipseContour = AxelRot(ellipseRotViaOri.ellipseContour,...
+    angleRot, axisRot, x0);
+ellipseStruct.semiMajVec = AxelRot(ellipseRotViaOri.semiMajVec,...
+    angleRot,axisRot,x0);
+ellipseStruct.semiMinVec = AxelRot(ellipseRotViaOri.semiMinVec,...
+    angleRot,axisRot,x0);
+ellipseStruct.center = ellipseStruct.semiMajVec(:,1);
+
+% Normalized orientation
+ellipseStruct.normOrientation = ellipseStruct.semiMajVec;
+ellipseStruct.normOrientation(:,2) = normalizeVector3d(ellipseStruct.semiMajVec(:,2)'-ellipseStruct.semiMajVec(:,1)')'+ellipseStruct.semiMajVec(:,1);
+
+end
+
+function ellipseStruct = replaceSemiAxesInEllipseSpace(ellipseStruct)
+% Here the ellipse is only bidimensionnal either projected on the XY plane
+% or ortho projected on the best fitting plane and then rotated on the XY
+% plane. In any case, the ellipse is flatten on XY and will remain so
+% during the function run
+
+if isnan(ellipseStruct.semiMajAx)  % If the fit didn't work => pad with nan
+    ellipseStruct = setEllipseStructToNaN(ellipseStruct);
+    return
+end
+
+% create an ellipse without rotation
+data.x = sin(linspace(0,2*pi));
+data.y = cos(linspace(0,2*pi));
+ell = ([ellipseStruct.semiMajAx*data.x; ellipseStruct.semiMinAx*data.y]);
+
+% rotate the ellipse plot
+normalVector = [0 0 1]; % final normal vector
+x0 = []; % no translation
+alphaAngle = mod(ellipseStruct.alpha/(2*pi)*360,360); % ellipse angle around the 
+% Z axis; from radians to degrees.
+% Rotate the ellipse around the Z axis
+ell = AxelRot([ell; zeros(1,length(ell))],alphaAngle,normalVector,x0);
+
+% set the center properly. MUST be done after rotation
+centersRot = [ellipseStruct.center; 0]; % ellipse center (needs 3D)
+ellipseStruct.ellipseContour = centersRot + ell;
+
+% Prepare the ellipse orientation vector
+referential = [ellipseStruct.semiMajAx 0 0 ; 0 ellipseStruct.semiMinAx 0; 0 0 0];
+referential = AxelRot(referential,alphaAngle,normalVector,x0);
+ellipseStruct.semiMajVec = horzcat(centersRot,centersRot+referential(:,1)); 
+ellipseStruct.semiMinVec = horzcat(centersRot,centersRot+referential(:,2));
+
+% Set center
+ellipseStruct.center = ellipseStruct.semiMajVec(:,1);
+
+% Normalized orientation
+ellipseStruct.normOrientation = centersRot;
+ellipseStruct.normOrientation(:,2) = normalizeVector3d(ellipseStruct.semiMajVec(:,2)'-ellipseStruct.semiMajVec(:,1)')'+ellipseStruct.semiMajVec(:,1);
+end
+ 
+function [cellData, ellipseFitError] = BioCellEllipseFitting(cellData,cell_ID,dim,PARAMS,structLoc)
+
+ellipseFitError = {}; % for ellipses not fitted properly
+cellListError = [];
+for bioCell = 1:length(cell_ID)
+
+    % Set the correct contour and perimeter (fields are function of the dimension)
+    if dim == 3
+        cellContour = cellData{bioCell}.cellCtFlatViaOriRot(:,1:2)';
+        perimeter = cellData{bioCell}.perimeterReal;
+    elseif dim == 2
+        cellContour = cellData{bioCell}.cellCt';
+        perimeter = cellData{bioCell}.perimeterProj;
+    end
+    
+    
+    try % Catch errors thrwon by the fitting method
+        [cellData{bioCell}.(structLoc).center,...
+            ag, bg, alphaAng] = ...
+            fitellipse(cellContour);
+    catch ME % catch error if no fit possible
+        fprintf('Cell %d could not be fitted in %dD with an ellipse\n',bioCell, dim)
+        ellipseFitError{end+1}.errorMes = ME;
+        ellipseFitError{end}.numbers = cell_ID(bioCell);
+        ellipseFitError{end}.bioCell = bioCell;
+        % pad with NaN results for later analysis
+        bg = NaN; 
+        ag = NaN;
+        perimeterEllipse = NaN;
+        alphaAng = NaN;
+        cellListError = [cellListError bioCell];
+        cellListContour{numel(cellListError)} = cellContour;
+    end
+    
+    if bg>ag % invert long and short axes if needed (+ switch axes)
+        temp = bg;
+        bg = ag;
+        ag = temp;
+        alphaAng = alphaAng+pi/2; % could be mod(pi) to simplify the ellipseFitError.cellListErrorvalues
+    end
+    
+    if ~isnan(bg) % if the fit worked properly
+        perimeterEllipse = ellipsePerimeter([ag bg]);
+    end
+        
+    % Calculate ellipse area
+    ellipseArea = pi*ag*bg;
+    
+    % Set direct values in structure
+    % Semi Major Axis
+    cellData{bioCell}.(structLoc).semiMajAx = ag;
+    % Semi Minor Axis
+    cellData{bioCell}.(structLoc).semiMinAx = bg;
+    % Ellipse angle
+    cellData{bioCell}.(structLoc).alpha = alphaAng; % in radians
+    % Ellipse perimeter
+    cellData{bioCell}.(structLoc).perimeterEllipse = perimeterEllipse;
+    % Ellipse area
+    cellData{bioCell}.(structLoc).areaEllipse = ellipseArea;  
+    
+end
+
+if PARAMS.doDispErrorEllipse == true % Only if user asked for the error on the ellipse fits
+    displaySubplotCellContour(cellListError, cellListContour, dim)
+end
+    
+end
+
+function dataCells = flattenContour(dataCells)
+
+normalVector = [0 0 1]; % final normal vector
+x0 = []; % no translation
+
+for bioCell = 1:length(dataCells.numbers)
+    planNormal = dataCells.planeFit{bioCell}.normal;
+    % Calculate rotation vector and amplitude
+    dataCells.planeFit{bioCell}.angleRot = -acos(dot(normalVector,planNormal))*360 / (2*pi);
+    dataCells.planeFit{bioCell}.axisRot = cross(normalVector,planNormal);
+    
+    % Set first 3DContour position at position 0,0,0 to ensure that the plane passes by the origin
+    dataCells.cellContour3D{bioCell}.cellCtFlatViaOri = dataCells.cellContour3D{bioCell}.cellCtFlat-...
+        dataCells.cellContour3D{bioCell}.cellCtFlat(1,:);
+    dataCurrent = dataCells.cellContour3D{bioCell}.cellCtFlatViaOri;
+
+    % Calculate the rotated contour using a vector and a rotation angle
+    [newContour, dataCells.planeFit{bioCell}.rotationMatrix, ~] = AxelRot(dataCurrent',...
+        dataCells.planeFit{bioCell}.angleRot, dataCells.planeFit{bioCell}.axisRot, x0);
+    
+    % Allocate to the proper structure
+    dataCells.cellContour3D{bioCell}.cellCtFlatViaOriRot = newContour';
+    dataCells.cellContour3D{bioCell}.cellCtFlatRot = dataCells.cellContour3D{bioCell}.cellCtFlatViaOriRot +...
+        dataCells.cellContour3D{bioCell}.cellCtFlat(1,:);
+    
+    % Calculate perimeters for proper control
+    perimeterReal = 0;
+    perimeterRot = 0;
+    perimeterProj = 0;
+    for point = 2:length(newContour)
+        perimeterReal = perimeterReal + sqrt(sum((dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point,:)-...
+            dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point-1,:)).^2,2));
+        perimeterRot = perimeterRot + sqrt(sum((dataCells.cellContour3D{bioCell}.cellCtFlatRot(point,:)-...
+            dataCells.cellContour3D{bioCell}.cellCtFlatRot(point-1,:)).^2,2));
+        perimeterProj = perimeterProj + sqrt(sum((dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point,1:2)-...
+            dataCells.cellContour3D{bioCell}.cellCtFlatViaOri(point-1,1:2)).^2,2));
+    end
+    dataCells.cellContour3D{bioCell}.perimeterReal = perimeterReal;
+    dataCells.cellContour3D{bioCell}.perimeterRot = perimeterRot;
+    dataCells.cellContour2D{bioCell}.perimeterProj = perimeterProj;
+end
+
+end
+
+function planeFit = avPlaneOfFaces(dataCells, planeCoefPerFace)
+
+clear planeFit
+
+planeFit = cell(length(dataCells.numbers),1);
+for bioCell = 1:length(dataCells.numbers)
+    % plane equation is of the type avAlpha*x+avBeta*y+avGamma=z
+    % equivalent to Ax+By+Cz+D = 0
+    % With avAlpha = -A/C ; avBeta = -B/C ; avGamma = -D/C ; 
+    planeFit{bioCell}.avAlBeGa(1) = 1/dataCells.area.areaRealTot{bioCell} * sum(dataCells.area.areaRealPerFace{bioCell}.*...
+        planeCoefPerFace(dataCells.cell2Face{bioCell},1));  %avAlpha
+    planeFit{bioCell}.avAlBeGa(2) = 1/dataCells.area.areaRealTot{bioCell} * sum(dataCells.area.areaRealPerFace{bioCell}.*...
+        planeCoefPerFace(dataCells.cell2Face{bioCell},2)); % avBeta
+    planeFit{bioCell}.avAlBeGa(3) = 1/dataCells.area.areaRealTot{bioCell} * sum(dataCells.area.areaRealPerFace{bioCell}.*...
+        planeCoefPerFace(dataCells.cell2Face{bioCell},3)); % avGamma
+    % Create 2 vectors part of the plan to describe it and further and save
+    % it as geom3Dvectors structure
+    % Calculate it's normal vecteur and (not yet) cartesian equation using Alpha Beta
+    % and Gamma
+    planeFit{bioCell}.pointsOfPlane(1,1:2) = min(dataCells.cellContour3D{bioCell}.cellCt(:,1:2));
+    planeFit{bioCell}.pointsOfPlane(2,1:2) = [min(dataCells.cellContour3D{bioCell}.cellCt(:,1)) , ...
+        max(dataCells.cellContour3D{bioCell}.cellCt(:,2))];
+    planeFit{bioCell}.pointsOfPlane(3,1:2) = [max(dataCells.cellContour3D{bioCell}.cellCt(:,1)) , ...
+        max(dataCells.cellContour3D{bioCell}.cellCt(:,2))];
+    planeFit{bioCell}.pointsOfPlane(:,3) = ...
+        planeFit{bioCell}.avAlBeGa(1)*planeFit{bioCell}.pointsOfPlane(:,1) + ...
+        planeFit{bioCell}.avAlBeGa(2)*planeFit{bioCell}.pointsOfPlane(:,2) + ...
+        planeFit{bioCell}.avAlBeGa(3);
+    planeFit{bioCell}.geom3Dvectors = normalizePlane([planeFit{bioCell}.pointsOfPlane(1,:)...
+        planeFit{bioCell}.pointsOfPlane(2,:)-planeFit{bioCell}.pointsOfPlane(1,:)...
+        planeFit{bioCell}.pointsOfPlane(3,:)-planeFit{bioCell}.pointsOfPlane(1,:)]);
+    % Calculate normal vector to the plan
+    planeFit{bioCell}.normal = planeNormal(planeFit{bioCell}.geom3Dvectors);
+end
+
+end
+
+function PARAMS = checkPARAMS(PARAMS)
+% Double check with the user that the parameters are adapted
+
+prompt = {'Nbr of pixels in X:','Nbr of pixels in Y:', 'Nbr of Z slices',...
+    'Lateral pixel size','Axial pixel size'};
+dlg_title = 'Check parameters';
+num_lines = 1;
+defaultans = {num2str(PARAMS.imSettings.x),num2str(PARAMS.imSettings.y),num2str(PARAMS.imSettings.z),...
+    num2str(PARAMS.imSettings.latPixSize), num2str(PARAMS.imSettings.axPixSize)};
+answer = inputdlg(prompt,dlg_title,num_lines,defaultans);
+
+PARAMS.imSettings.x = str2double(answer{1}); % image size in X (in px) % exists in dataSeg
+PARAMS.imSettings.y = str2double(answer{2}); % image size in Y (in px) % exists in dataSeg
+PARAMS.imSettings.z = str2double(answer{3}); % image size in Z (in px)
+PARAMS.imSettings.latPixSize = str2double(answer{4}); % Lateral pixel size (in um) % exists in dataSeg
+PARAMS.imSettings.axPixSize = str2double(answer{5}); % Axial pixel size (in um)
+
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+