diff --git a/main.py b/main.py
index 6a757a5d5c56755c43a20f8c9245181a6ae2bc01..68097d37cc63103781f4bf78cebcfa060f57b8e7 100644
--- a/main.py
+++ b/main.py
@@ -3,8 +3,9 @@ from utils.files import output
 from utils.files.input import ScannedObject
 from utils.math.position_manipulation import verticalise
 from utils.graph3D.visplot_render import render3D
+import time
 
-def get_raw_data(obj:ScannedObject, ndigits:int)->dict:
+def get_raw_data(obj:ScannedObject, ndigits:int, delta_z:int = 1)->dict:
     """
     Calculates data from the given object
 
@@ -19,11 +20,11 @@ def get_raw_data(obj:ScannedObject, ndigits:int)->dict:
         - Xi-Xmoy       : list of Xi-Xmoy values
         - Yi-Ymoy       : list of Yi-Ymoy values
     """
-    colones = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"]
+    columns = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"]
     data = {}
-    for colone in colones:
-        data[colone] = []
-    for discrete_values in obj.get_discrete_vertices():
+    for column in columns:
+        data[column] = []
+    for discrete_values in obj.get_discrete_vertices(delta_z):
         mean_x ,mean_y, mean_z = data_extraction.get_x_y_z_mean(discrete_values)
         for x,y,z in discrete_values:
             data["X (en mm)"].append(round(x, ndigits))
@@ -35,7 +36,7 @@ def get_raw_data(obj:ScannedObject, ndigits:int)->dict:
             data["Yi-Ymoy"].append(round(y-mean_y, ndigits))
     return data
 
-def get_discrete_data(obj:ScannedObject, ndigits:int)->dict:
+def get_discrete_data(obj:ScannedObject, ndigits:int,delta_z:int= 1)->dict:
     """
     Calculates data from the given object
 
@@ -48,11 +49,11 @@ def get_discrete_data(obj:ScannedObject, ndigits:int)->dict:
         - Rayon moyen (en mm)       : list of mean radius values
         - Rayon ecart type (en mm)  : list of radius standard deviation values
     """
-    colones = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Delta z(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"]
+    columns = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Delta z(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"]
     data = {}
-    for colone in colones:
-        data[colone] = []
-    for discrete_values in obj.get_discrete_vertices():
+    for column in columns:
+        data[column] = []
+    for discrete_values in obj.get_discrete_vertices(delta_z):
         x,y,z = data_extraction.get_x_y_z_mean(discrete_values)
         data["X moy (en mm)"].append(round(x, ndigits))
         data["Y moy (en mm)"].append(round(y, ndigits))
@@ -66,12 +67,26 @@ def get_discrete_data(obj:ScannedObject, ndigits:int)->dict:
 
 def main():
     # Create an object from the given file
+    total_time = time.time()
+    print("Loading file...")
+    t = time.time()
     obj = ScannedObject.from_obj_file("datasets/Barette/1 - BARETTE.obj")
+    print("File loaded in {} seconds".format(time.time()-t))
+    t = time.time()
+    print("Verticalising object...")
     verticalise(obj)
+    print("Object verticalised in {} seconds".format(time.time()-t))
+    t = time.time() 
+    print("Normalising object...")
     obj.normalise()
+    print("Object normalised in {} seconds".format(time.time()-t))
 
     # Calculate raw data and save it in a file
-    data = get_raw_data(obj, 6)
+    t = time.time()
+    data = get_raw_data(obj, 6,2)
+    print("Raw data calculated in {} seconds".format(time.time()-t))
+    t = time.time()
+    print("Saving data...")
     output.save_output_file('analyse_brute.txt',
                              output.format_data(data,
                                                 '\t',
@@ -82,9 +97,15 @@ def main():
                                                 "rayon (en mm)",
                                                 "Xi-Xmoy",
                                                 "Yi-Ymoy"] ))
-
+    print("Data saved in {} seconds".format(time.time()-t))
+    
     # Calculate discrete data and save it in a file
-    data = get_discrete_data(obj, 6)
+    t = time.time()
+    print("Calculating discrete data...")
+    data = get_discrete_data(obj, 6,2)
+    print("Discrete data calculated in {} seconds".format(time.time()-t))
+    t = time.time()
+    print("Saving data...")
     output.save_output_file('analyse_rayon.txt',
                              output.format_data(data,
                                                 '\t',
@@ -94,6 +115,8 @@ def main():
                                                 "Delta z(en mm)",
                                                 "Rayon moyen (en mm)",
                                                 "Rayon ecart type (en mm)"] ))
+    print("Data saved in {} seconds".format(time.time()-t))
+    print("Total time : {} seconds".format(time.time()-total_time))
 
 if __name__ == '__main__':
     main()
\ No newline at end of file
diff --git a/utils/files/input.py b/utils/files/input.py
index 94412c881209295a6bbee935cdc30d2e3aad5199..bc6fd244808c3c21aef827e0cd7388b61b061991 100644
--- a/utils/files/input.py
+++ b/utils/files/input.py
@@ -19,9 +19,16 @@ class ScannedObject:
     """
     This class is used to manage the data of the 3D object.
 
-    :param vertices: List of vertices
-    :param faces: List of faces
+    :param vertices: List of verticesm Ndarray of shape (n,2)
+    :param faces: List of faces, Ndarray of shape (n,2)
     :param result_file_path: Path to the result file (deprecated, used for the bruteforce discretization)
+    
+    :ivar vertices: List of vertices, Ndarray of shape (n,2)
+    :ivar faces: List of faces, Ndarray of shape (n,2)
+    :ivar result_file_path: Path to the result file (deprecated, used for the bruteforce discretization)
+    :ivar x: List of x values of the vertices
+    :ivar y: List of y values of the vertices
+    :ivar z: List of z values of the vertices
 
     :static method from_xyz_file(): Creates a ScannedObject from a .xyz file
     :static method from_obj_file(): Creates a ScannedObject from a .obj file
diff --git a/utils/files/output.py b/utils/files/output.py
index 3eca9abca6b4a4369bd4aca75c198f6a4b7dfc1e..ec1f1aba7adaff5a6592cb7c24cd01edcc9d06a5 100644
--- a/utils/files/output.py
+++ b/utils/files/output.py
@@ -32,7 +32,7 @@ def format_data(data:dict, separator:str, selected_columns:list = None) -> str:
     output += '\n'
     for i in range(len(data[selected_columns[0]])):
         for column in selected_columns:
-            output += str(data[column][i]).ljust(len(column)) + separator
+            output += str(data[column][i]).ljust(len(column) if len(column) > 6 else 7 ) + separator
         output += '\n'
     return output
 
diff --git a/utils/graph2D/mpl_render.py b/utils/graph2D/mpl_render.py
index dd6450fdbce88f7b364018ffe93634e86ac9cda1..9f78215a20cd1f9a7aa8f562d1fe8e6ca42c302e 100644
--- a/utils/graph2D/mpl_render.py
+++ b/utils/graph2D/mpl_render.py
@@ -10,12 +10,13 @@ def render2D(values:list):
     ax.plot(values)
     plt.show()
 
-def cross_section(x:list,y:list):
+def cross_section(x_values:list, y_values:list):
     """
-    Render a 2D model using matplotlib
-    :param values: A list with the values
+    Render a 2D cross section using matplotlib
+    :param x: A list with the x values
+    :param y: A list with the y values
     """
     fig = plt.figure()
     ax = fig.add_subplot()
-    ax.scatter(x,y)
+    ax.scatter(x_values,y_values)
     plt.show()
\ No newline at end of file
diff --git a/utils/graph2D/visplot_render.py b/utils/graph2D/visplot_render.py
index 86627b172d37bacf4fd527c604d9603807be574d..31925ab063e575d04d305f62f8b30c138b3e3bfe 100644
--- a/utils/graph2D/visplot_render.py
+++ b/utils/graph2D/visplot_render.py
@@ -1,9 +1,11 @@
 import vispy.plot as vp
 import numpy as np
 
-
-
 def render2D(values:list):
+    """
+    Render a 2D plot using vispy
+    :param values: A list with the values
+    """
     fig = vp.Fig(size=(600, 500), show=False)
     plotwidget = fig[0, 0]
     fig.title = "bollu"
@@ -11,11 +13,15 @@ def render2D(values:list):
     plotwidget.colorbar(position="top", cmap="autumn")
     fig.show(run=True)
 
-
-def cross_section(x:list,y:list):
+def cross_section(x_values:list, y_values:list):
+    """
+    Render a 2D cross section using vispy
+    :param x: A list with the x values
+    :param y: A list with the y values
+    """
     color = (0.3, 0.5, 0.8)
     fig = vp.Fig(show=False)
-    line = fig[0:4, 0:4].plot(np.column_stack((x,y)), symbol='o', width=0,
+    line = fig[0:4, 0:4].plot(np.column_stack((x_values,y_values)), symbol='o', width=0,
                             face_color=color + (0.02,), edge_color=None,
                             marker_size=8)
     line.set_gl_state(depth_test=False)
diff --git a/utils/graph3D/mpl_render.py b/utils/graph3D/mpl_render.py
index c4757fe36e03a2d20fa218cff61b668960bfcdda..1e2e32f50b3e372b59e0a0e8ec85f5cb50a63208 100644
--- a/utils/graph3D/mpl_render.py
+++ b/utils/graph3D/mpl_render.py
@@ -5,8 +5,8 @@ from utils.files.input import ScannedObject
 
 def render3D(obj:ScannedObject):
     """
-    Render a 3D model using matplotlib poly3dcollection
-    :param data: A dict with the vertices and faces
+    Render a 3D model using matplotlib's Poly3dcollection
+    :param obj: A ScannedObject to be rendered
     """
     fig = plt.figure()
     ax = fig.add_subplot(projection='3d')
diff --git a/utils/graph3D/visplot_render.py b/utils/graph3D/visplot_render.py
index d2cd0f24021018cb49a43ee2424a12b8c7382ec8..2dccf7f72462fd9576fbaee03a284daf982f8d3c 100644
--- a/utils/graph3D/visplot_render.py
+++ b/utils/graph3D/visplot_render.py
@@ -1,12 +1,15 @@
 import numpy as np
 from vispy import app, scene
 from vispy.scene.visuals import Mesh
-from vispy.scene import transforms
 from vispy.visuals.filters import ShadingFilter, WireframeFilter
 from utils.files.input import ScannedObject
 
 
 def render3D(obj:ScannedObject):
+    """
+    Render a 3D model using vispy
+    :param obj: A ScannedObject to be rendered
+    """
     vertices = np.asarray(obj.get_vertices())
     faces = np.asarray(obj.get_faces())
     canvas = scene.SceneCanvas(keys='interactive', bgcolor='white')
diff --git a/utils/math/position_manipulation.py b/utils/math/position_manipulation.py
index 53af77c58c384a20cf78291f9daf687b8b451734..94055f366d2945d98da95b77b9696705d9eaac6a 100644
--- a/utils/math/position_manipulation.py
+++ b/utils/math/position_manipulation.py
@@ -3,15 +3,19 @@ from utils.files.input import ScannedObject
 from utils.math.data_extraction import get_mean
 
 
-def get_mass_properties(obj:ScannedObject):
+def get_mass_properties(obj:ScannedObject)->tuple:
     '''
     Evaluate and return a tuple with the following elements:
         - the volume
         - the position of the center of gravity (COG)
         - the inertia matrix expressed at the COG
+    :param obj: Object to analyse
+    :return: tuple(float, numpy.array, numpy.array)
+
+    From numpy-stl:(https://pypi.org/project/numpy-stl/)
+        Documentation can be found here:
+        http://www.geometrictools.com/Documentation/PolyhedralMassProperties.pdf
 
-    Documentation can be found here:
-    http://www.geometrictools.com/Documentation/PolyhedralMassProperties.pdf
     '''
 
     verts = np.asarray(obj.get_vertices())
@@ -66,6 +70,10 @@ def get_mass_properties(obj:ScannedObject):
     return volume, cog, inertia
 
 def verticalise(obj:ScannedObject):
+    """
+    Rotate the object so that the principal axis of inertia is vertical
+    :param obj: Object to analyse
+    """
     cog = get_mass_properties(obj)
     cog, inertia = get_mass_properties(obj)[1:]
     [val,vect] = np.linalg.eig(inertia)