def Geo_reduction_wall_radius(path_patients_data, nb_generation = 20, rot_sec = False, mesh_extractor = False):

    print("---------------------------------- START PROGRAMM ----------------------------------")

    #############################################################################
    ################ TRAINING DATA READING AND EXTRACTION #######################
    #############################################################################

    # EXTRACT DATA FROM FOLDER "path_patients_data". READ ALL PARAMETRIZATION FILES.
    print("--> DATAS EXTRACTION FROM PARAMETRIZATION FILES")
    folder = sorted([f for f in os.listdir(path_patients_data) if not f.startswith('.')], key = str.lower)
    print("----> Number of patients considered : {}".format(len(folder)))

    liste_control = []
    liste_r_theta = []
    liste_originale_centerline = []

    thetas = np.linspace(0, 2*np.pi, 160)

    #WE LOOP ON EACH PARAMETRIZATION FILE AND EXTRACT RELEVANT INFORMATION
    for i in folder :
        #CHANGE path IF YOU GAVE ANOTHER NAME TO PARAMETRIZATION FILE
        path = path_patients_data + '/' + i + '/' + i + '_parametrization.csv'
        PARA = gf.Read_parametrization(path)

        #EXTRACTION CENTERLINE
        CENTERLINE = PARA[:,0:3]
        liste_originale_centerline.append(CENTERLINE)

        #EXTRACTION CONTROL POINTS TO USE PROCRUSTES ANALYSES AND RECONSTRUCTION B-SPLINES
        extract = np.linspace(0, np.shape(CENTERLINE)[0]-1, 10, dtype = 'int')
        CONTROL = CENTERLINE[extract,:]
        liste_control.append(CONTROL)

        #EXTRACTION OF FUNCTION R_THETA : DISTANCE TO ANGLE
        r_theta = PARA[:,12:]
        liste_r_theta.append(r_theta)

    #UNCOMMENT NEXT LINE IF YOU WANT TO STORE ORIGINAL CENTERLINE IN A FILE
    #gf.Write_csv("ORIGINAL_CENTERLINES.csv", np.vstack(liste_originale_centerline), "x, y, z")
    #############################################################################
    #############################################################################
    #############################################################################

    #############################################################################
    ################ PARAMETERS FOR GEOMETRIC MODEL REDUCTION ###################
    #############################################################################

    #EPSILON TO AUTOMATICALLY EXTRACT NUMBER OF POD MODES
    epsilon_c = 1.e-3
    epsilon_w = 1.e-3
    epsilon_r = 1.e-3
    #PARAMETERS TO RECONSTRUCT ANEURYSMS
    nb_sections = 500
    nb_thetas = 160

    #############################################################################
    #############################################################################
    #############################################################################

    print("")
    print("--> EXTRACTION CENTERLINE REDUCED BASIS")

    dilatation, PHI_CENTERLINE, COEFFS_CENTERLINE = gmr.Centerline_pod(liste_control, epsilon = epsilon_c)

    print("")
    print("--> EXTRACTION WALL AND RADIUS REDUCED BASIS")

    PHI_WALL, PHI_RAYON, COEFFS_WALL, COEFFS_RAYON = gmr.Wall_radius_pod(thetas, liste_r_theta, epsilon_wall = epsilon_w, epsilon_radius = epsilon_r, read_file = True)

    print("")
    print("--> GENERATION OF RANDOM AORTIC ANEURYSMS GEOMETRIES")

    if rot_sec == True :

        path_to_save = "results/generation_wall_radius_with_rotation"
        if os.path.exists(path_to_save):
            shutil.rmtree(path_to_save)
        os.makedirs(path_to_save)

        for i in range(nb_generation) :

            print("----> GENERATED ANEURYSM NUMBER : ", i)

            #GIVE A NAME FOR THE ANEURYSM TO SAVE IT
            name = "ANEURYSM_WALL_RADIUS_" + str(i)
            #GIVE NAME OF FOLDER IN WHICH TO STORE ANEURYSMS

            ANEVRISME, ANEVRISME_ROT = gmr.Generator_wall_radius(PHI_CENTERLINE, PHI_WALL, PHI_RAYON, COEFFS_CENTERLINE, COEFFS_WALL, COEFFS_RAYON, dilatation, nb_sections, nb_thetas, rotation_section = True)
            gf.Write_csv(path_to_save + "/reconstruction_" + name + ".csv", ANEVRISME, "x, y, z")
            gf.Write_csv(path_to_save + "/reconstruction_rotation_" + name + ".csv", ANEVRISME_ROT, "x, y, z")

            if mesh_extractor == True :
                CONTOUR = ANEVRISME[nb_sections:,:]
                geo_treat.Mesh_generation(CONTOUR, path_to_save + "/mesh_contour_" + name + ".stl", nb_sections, nb_thetas)
                geo_treat.Read_and_Smooth(path_to_save + "/mesh_contour_" + name + ".stl", path_to_save + "mesh_smooth_" + name + ".stl", coeff_smooth = 0.001)

                CONTOUR2 = ANEVRISME_ROT[nb_sections:,:]
                geo_treat.Mesh_generation(CONTOUR2, path_to_save + "/mesh_contour_rotation_" + name + ".stl", nb_sections, nb_thetas)
                geo_treat.Read_and_Smooth(path_to_save + "/mesh_contour_rotation_" + name + ".stl", path_to_save + "mesh_smooth_rotation_" + name + ".stl", coeff_smooth = 0.001)

                #UNCOMMENT NEXT LINE IF YOU WANT TO REMESH FILES (WARNING : CAN BE VERY LOOONG TO COMPUTE!)
                #geo_treat.Surface_Remesh(path_to_save + "mesh_smooth_" + name + ".stl", path_to_save + "mesh_remesh_" + name + ".stl", target_edge_length = 0.3, nb_iterations = 10)

    else :

        path_to_save = "results/generation_wall_radius_no_rotation"
        if os.path.exists(path_to_save):
            shutil.rmtree(path_to_save)
        os.makedirs(path_to_save)

        for i in range(nb_generation) :

            print("----> GENERATED ANEURYSM NUMBER : ", i)

            #GIVE A NAME FOR THE ANEURYSM TO SAVE IT
            name = "ANEURYSM_WALL_RADIUS_" + str(i)
            #GIVE NAME OF FOLDER IN WHICH TO STORE ANEURYSMS

            ANEVRISME = gmr.Generator_wall_radius(PHI_CENTERLINE, PHI_WALL, PHI_RAYON, COEFFS_CENTERLINE, COEFFS_WALL, COEFFS_RAYON, dilatation, nb_sections, nb_thetas, rotation_section = False)
            gf.Write_csv(path_to_save + "/reconstruction_" + name + ".csv", ANEVRISME, "x, y, z")

            if mesh_extractor == True :
                CONTOUR = ANEVRISME[nb_sections:,:]
                geo_treat.Mesh_generation(CONTOUR, path_to_save + "/mesh_contour_" + name + ".stl", nb_sections, nb_thetas)
                geo_treat.Read_and_Smooth(path_to_save + "/mesh_contour_" + name + ".stl", path_to_save + "mesh_smooth_" + name + ".stl", coeff_smooth = 0.001)

                #UNCOMMENT NEXT LINE IF YOU WANT TO REMESH FILES (WARNING : CAN BE VERY LOOONG TO COMPUTE!)
                #geo_treat.Surface_Remesh(path_to_save + "mesh_smooth_" + name + ".stl", path_to_save + "mesh_remesh_" + name + ".stl", target_edge_length = 0.3, nb_iterations = 10)

    return 0
def Test_rotation_invariant(path_parametrization, path_solution):

    #### INITIALISATION
    PARA, average_radius, arc_length = Parametrization_analysis(
        path_parametrization)
    SOLUTION = Extract_solution(path_solution)

    #### COMPUTE CYLINDER
    CYLINDER = Mesh_cylinder(int(arc_length), int(average_radius), 1000, 160,
                             10)

    #### ORIGINAL MAPPING
    MESH_ORIGINAL = Mesh_original(PARA, 160, 10)
    INTERPOL = Interpolated_solution(MESH_ORIGINAL, SOLUTION)
    SOL_MESH_ORIGINAL = np.hstack((MESH_ORIGINAL, INTERPOL))
    SOL_CYLINDER = np.hstack((CYLINDER, INTERPOL))
    gf.Write_csv("SOL_ORIGINAL.csv", SOL_MESH_ORIGINAL,
                 "x, y, z, pressure, Vx, Vy, Vz, magnitude")
    gf.Write_csv("SOL_CYLINDER.csv", SOL_CYLINDER,
                 "x, y, z, pressure, Vx, Vy, Vz, magnitude")

    ### ROTATION
    thetax = 2 * np.pi * np.random.random()
    print("X axis rotation of angle : ", thetax)
    thetay = 2 * np.pi * np.random.random()
    print("Y axis rotation of angle : ", thetay)
    thetaz = 2 * np.pi * np.random.random()
    print("Z axis rotation of angle : ", thetaz)
    ROTX = np.array([[1, 0, 0], [0, np.cos(thetax), -np.sin(thetax)],
                     [0, np.sin(thetax), np.cos(thetax)]])
    ROTY = np.array([[np.cos(thetay), 0, np.sin(thetay)], [0, 1, 0],
                     [-np.sin(thetay), 0, np.cos(thetay)]])
    ROTZ = np.array([[np.cos(thetaz), -np.sin(thetaz), 0],
                     [np.sin(thetaz), np.cos(thetaz), 0], [0, 0, 1]])

    ### ROTATION SOLUTION VTU
    POINTS = SOLUTION[:, 0:3]
    VALUES = SOLUTION[:, 3:]
    ROT_POINTS_X = np.dot(ROTX, POINTS.T)
    ROT_POINTS_Y = np.dot(ROTY, ROT_POINTS_X)
    ROT_POINTS_Z = np.dot(ROTZ, ROT_POINTS_Y)
    ROT_SOLUTION = np.hstack((ROT_POINTS_Z.T, VALUES))

    ### ROTATION PARAMETRIZATION
    P = PARA[:, 0:3]
    T = PARA[:, 3:6]
    N = PARA[:, 6:9]
    B = PARA[:, 9:12]
    RT = PARA[:, 12:]
    ROT_P_X = np.dot(ROTX, P.T)
    ROT_T_X = np.dot(ROTX, T.T)
    ROT_N_X = np.dot(ROTX, N.T)
    ROT_B_X = np.dot(ROTX, B.T)
    ROT_P_Y = np.dot(ROTY, ROT_P_X)
    ROT_T_Y = np.dot(ROTY, ROT_T_X)
    ROT_N_Y = np.dot(ROTY, ROT_N_X)
    ROT_B_Y = np.dot(ROTY, ROT_B_X)
    ROT_P_Z = np.dot(ROTZ, ROT_P_Y)
    ROT_T_Z = np.dot(ROTZ, ROT_T_Y)
    ROT_N_Z = np.dot(ROTZ, ROT_N_Y)
    ROT_B_Z = np.dot(ROTZ, ROT_B_Y)

    ROT_PARA = np.hstack((ROT_P_Z.T, ROT_T_Z.T, ROT_N_Z.T, ROT_B_Z.T, RT))

    #### MAPPING GEO ROTATION
    MESH_ROT = Mesh_original(ROT_PARA, 160, 10)
    INTERPOL_ROT = Interpolated_solution(MESH_ROT, ROT_SOLUTION)
    SOL_MESH_ROT = np.hstack((MESH_ROT, INTERPOL_ROT))
    SOL_CYLINDER_ROT = np.hstack((CYLINDER, INTERPOL_ROT))
    gf.Write_csv("SOL_ORIGINAL_ROT.csv", SOL_MESH_ROT,
                 "x, y, z, pressure, Vx, Vy, Vz, magnitude")
    gf.Write_csv("SOL_CYLINDER_ROT.csv", SOL_CYLINDER_ROT,
                 "x, y, z, pressure, Vx, Vy, Vz, magnitude")

    #### COMPUTE ERROR
    error = np.linalg.norm(SOL_CYLINDER[:, -1] - SOL_CYLINDER_ROT[:, -1])
    print("L'erreur est de ", error)

    return 0
Esempio n. 3
0
def Main_pre_processing(path_nifti_all, add_extension=False):

    print(
        "---------------------------------- START FILE TREATMENT ----------------------------------"
    )

    #READ THE FOLDER
    folder = sorted(
        [f for f in os.listdir(path_nifti_all) if not f.startswith('.')],
        key=str.lower)
    print("Number of nifti files in folder : {} \n".format(len(folder)))

    #WRITE HERE FOLDER NAME WHERE YOU WANT TO STORE YOUR DATA ! (MINE IS CALLED patients_data)
    path_datas = "patients_data_large/"

    #READ EACH FILE IN FOLDER
    for file in folder:

        print(
            "------------------------------ Treatment of patient {} ------------------------------ "
            .format(file))

        start_time = time.time()

        name_file = file[:4]

        print(
            " -> Creation of folder named {} and initialisation of all paths".
            format(name_file))

        #CREATION FOLDER
        dir = path_datas + name_file
        if os.path.exists(dir):
            shutil.rmtree(dir)
        os.makedirs(dir)

        #ALL PATH TO BE USED
        path_nifti_file = path_nifti_all + '/' + file
        path_marching_cube = dir + '/' + name_file + '_marching_cube.stl'
        path_mesh_closed = dir + '/' + name_file + '_mesh_closed.stl'
        path_centerline_vtp = dir + '/' + name_file + '_centerline.vtp'
        path_centerline_csv = dir + "/" + name_file + "_centerline_bspline.csv"
        path_control_csv = dir + "/" + name_file + "_centerline_control.csv"
        path_parametrization = dir + '/' + name_file + '_parametrization.csv'
        path_reconstruction = dir + '/' + name_file + '_reconstruction.csv'
        path_mesh_opened = dir + '/' + name_file + '_mesh_opened.stl'
        path_mesh_opened_remesh = dir + '/' + name_file + '_mesh_opened_remesh.stl'
        path_extension = dir + '/' + name_file + '_mesh_extension.stl'

        ########################################################################
        ######################## PARAMETERS USED ###############################
        ########################################################################

        #SMOOTHING
        coefficient_smoothing = 0.001
        iterations_smoothing = 50

        #CENTERLINE EXTRACTION
        coefficient_centerline = 0.1
        iterations_centerline = 50

        #CONVERT CENTERLINE TO BSPLINES
        nb_control_points = 10
        nb_centerline_points = 200
        bspline_degree = 3

        #WALL PARAMETRIZATION
        degree_centerline = 3
        nb_centerline_points_parametrization = 3000
        nb_thetas = 200
        fourier_order = 5

        #REMESH THE OPENED GEOMETRY
        edge_length = 0.5
        iterations_remesh = 5

        ########################################################################
        ########################################################################
        ########################################################################

        print("")
        print(
            " -> Read and Convert Nifti file {} to STL format thanks to Marching-Cube algorithm"
            .format(file))
        geo_treat.Mesh_from_Nifti(path_nifti_file,
                                  path_marching_cube,
                                  only_lumen=True)
        print("")

        print(
            " -> Read Marching-Cube STL file, Smooth it and Convert the result to STL format"
        )
        geo_treat.Read_and_Smooth(path_marching_cube,
                                  path_mesh_closed,
                                  coeff_smooth=coefficient_smoothing,
                                  nb_iterations=iterations_smoothing)
        print("")

        print(
            " -> Extraction of Centerline, Smooth it and Convert the result to VTP format"
        )
        geo_treat.Centerline_Extraction(path_mesh_closed,
                                        path_centerline_vtp,
                                        coeff_smooth=coefficient_centerline,
                                        nb_iterations=iterations_centerline)
        print("")

        print(
            " -> Conversion centerline .VTP to numpy format and save as .CSV file"
        )
        CONTROL, CENTERLINE = geo_treat.Centerline_BSpline(
            path_centerline_vtp,
            nb_control=nb_control_points,
            nb_points=nb_centerline_points,
            degree=bspline_degree)
        gf.Write_csv(path_control_csv, CONTROL, "x, y, z")
        gf.Write_csv(path_centerline_csv, CENTERLINE, "x, y, z")
        print("")

        print(" -> Parametrization of the mesh named " + name_file +
              "_mesh_closed.stl")
        PARAMETRIZATION, RECONSTRUCTION = para.Parametrization(
            CENTERLINE,
            path_mesh_closed,
            degree=degree_centerline,
            nb_centerline=nb_centerline_points_parametrization,
            nb_thetas=nb_thetas,
            nb_modes_fourier=fourier_order)
        np.savetxt(path_parametrization, PARAMETRIZATION, delimiter=", ")
        gf.Write_csv(path_reconstruction, RECONSTRUCTION, "x, y, z")
        print("")

        print(" -> Cut the geometry to the extremity to open it")
        geo_treat.Mesh_Slice(path_mesh_closed, PARAMETRIZATION,
                             path_mesh_opened)
        print("")

        #print(" -> Remesh of the open mesh geometry")
        #geo_treat.Surface_Remesh(path_mesh_opened, path_mesh_opened_remesh, target_edge_length = edge_length, nb_iterations = iterations_remesh)

        if add_extension == True:
            print(" -> Add extension at the boudaries of the open mesh")
            geo_treat.Add_extension(path_mesh_opened_remesh,
                                    path_extension,
                                    extension_ratio=10,
                                    target_edge_length=0.5,
                                    nb_iterations=5)

        end_time = time.time()
        print("Total time for current patient : ",
              round(end_time - start_time, 2))
        print("")
        print("\a")

    return 0
def Main_generative_algorithm(path_patients_data):

    print("Start Generation Algorithm \n")

    start_time = time.time()

    #READ THE FOLDER
    folder = sorted(
        [f for f in os.listdir(path_patients_data) if not f.startswith('.')],
        key=str.lower)
    print("Number of patients data files in folder : {} \n".format(
        len(folder)))

    # Name of folder were generative surfaces are going to be stored
    path_datas = "results/gen_surfaces/training_set"
    path_datas_random = "results/gen_surfaces/predict_set"

    print(" -> Creation of folder named {} to store all generative surfaces", )
    dir1 = path_datas
    if os.path.exists(dir1):
        shutil.rmtree(dir1)
    os.makedirs(dir1)
    dir2 = path_datas_random
    if os.path.exists(dir2):
        shutil.rmtree(dir2)
    os.makedirs(dir2)

    # creating surfaces training set
    training_set = []
    liste_control = []

    #READ EACH FILE IN FOLDER
    for file in folder:

        print("Creating Generative Surface from patient {} surface ".format(
            file))

        # name of the .csv file that contains the radii
        surf_file_name = path_patients_data + '/' + file + '/' + file + '_parametrization.csv'

        # loading .csv file (surf_data is of type 'float64')
        #print("surf_file_name: ", surf_file_name, "\n")
        PARA = gf.Read_parametrization(surf_file_name)

        CENTERLINE = PARA[:, 0:3]
        extract = np.linspace(0, np.shape(CENTERLINE)[0] - 1, 10, dtype='int')
        CONTROL = CENTERLINE[extract, :]
        liste_control.append(CONTROL)

        RADIUS = PARA[:, 12:]
        n_point = np.shape(RADIUS)[0]
        n_radius = np.shape(RADIUS)[1]

        # preparing mesh for plotting
        nb_centerline_points = np.linspace(0,
                                           n_point,
                                           n_point,
                                           endpoint=True,
                                           dtype=int)
        nb_thetas = np.linspace(0,
                                n_radius,
                                n_radius,
                                endpoint=True,
                                dtype=int)
        X, Y = np.meshgrid(nb_centerline_points, nb_thetas)
        Z = RADIUS

        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.plot_surface(X, Y, Z.T,
                        cmap='ocean')  # Remember:  rows, cols = Z.shape
        #plt.show()

        # surface plot file name:
        surf_plot_name = path_datas + '/' + file + '_surface.png'
        plt.savefig(surf_plot_name)
        # vista 'dall'alto' (piano X-Y)
        #ax.view_init(90, 90)
        # surface plot seen from above file name:
        #surf_plot_name = surf_folder_name + '/' + name_file + '_surface_XY.png'
        #plt.savefig(surf_plot_name)

        # add surface file to list for generation algorithm
        training_set.append(RADIUS.ravel())

    ######## CENTERLINE ##############
    print(
        "Procrustes Analysis + Save dilatation coefficient + Creation Matrix of coefficients"
    )
    #EXTRACT CONTROL POINTS FROM PROCRSUTES ANALYSIS
    procrust_control, disparity = gmr.Procrustes(liste_control)
    #EXTRACT DILATATION (SCALING) FROM PROCRUSTES ANALYSIS
    dilatation = gmr.Dilatation(liste_control)
    DILATATION = np.asarray(dilatation).reshape(-1, 1)
    print("Size of dilatation training set : ", np.shape(DILATATION))
    #RECONSTRUCT NEW CENTERLINES FROM PROCRUSTES CONTROL POINTS
    procrust_bspline = gmr.Construction_bsplines(procrust_control, 200, 5)
    for i in range(len(procrust_bspline)):
        SPLINE = procrust_bspline[i]
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.scatter(SPLINE[:, 0], SPLINE[:, 1],
                   SPLINE[:, 2])  # Remember:  rows, cols = Z.shape
        spline_plot_name = path_datas + '/' + str(i) + '_spline.png'
        plt.savefig(spline_plot_name)

    #DEGREE OF POLYNOMIAL APPROXIMATION
    degree = 5
    #CREATE MATRIX ON WHICH TO RUN POD OF POLYNOMIAL COEFFICIENTS
    print("Degree polynomial approximation : ", degree)
    TRAIN_COEFF = gmr.Matrice_coefficients_centerline(procrust_bspline,
                                                      degree_approx=degree)
    print("Size of coefficient training set ", np.shape(TRAIN_COEFF))

    ######### RADIUS ##################
    TRAIN_RADIUS = np.vstack(training_set)
    print("Size of the radius training set : ", np.shape(TRAIN_RADIUS))

    TRAIN = np.hstack((DILATATION, TRAIN_COEFF.T, TRAIN_RADIUS))
    print("Size of the full training set : ", np.shape(TRAIN))

    ##### DIMENSIONALITY REDUCTION ##########
    pca = PCA(0.99999, whiten=True, svd_solver='full')
    REDUCED = pca.fit_transform(TRAIN)
    print('PCA : shape of digits reduced dataset: ', np.shape(REDUCED))

    ##### PERFORM AIC TO SEARCH BEST NUMBER OF COMPONENTS ################
    min_n_components = 1
    max_n_components = np.shape(REDUCED)[0]
    n_components = np.arange(min_n_components, max_n_components, 3)
    models = [
        GMM(n, covariance_type='full', random_state=0) for n in n_components
    ]
    aics = [model.fit(REDUCED).aic(REDUCED) for model in models]

    fig = plt.figure()
    plt.plot(n_components, aics)
    #plt.show()
    plt.savefig(path_datas + '/' +
                'AIC_graph.png')  # can hide DeprecationWarning

    mini = np.argmin(aics)
    best_nb_components = n_components[mini]
    print("Best number of components is : ", best_nb_components)

    ##### PERFORM GMM WITH BEST NUMBER COMPONENTS #######################
    gmm = GMM(best_nb_components, covariance_type='full', random_state=0)
    gmm.fit(REDUCED)
    print('Convergence of GMM model fit to digits reduced dataset: ',
          gmm.converged_)

    # n_sample: sample of new surfaces
    n_sample = 30
    DATA_NEW = gmm.sample(n_sample, random_state=0)
    print('Shape of random data : ', np.shape(DATA_NEW))

    # inverse transform of the PCA object to construct the new surfaces
    NEW = pca.inverse_transform(DATA_NEW)
    print('Shape of random data after inverse PCA : ', np.shape(NEW))

    thetas = np.linspace(0, 2 * np.pi, n_radius)
    t_anevrisme = np.linspace(0, 1, 1000)

    for i in range(n_sample):

        print("Saving sample {} and create aneurysm".format(i))

        SAMPLE = NEW[i, :]
        DILATATION_SAMPLE = SAMPLE[0]
        CENTERLINE_SAMPLE = SAMPLE[1:3 * (degree + 1) + 1]
        RADIUS_SAMPLE = SAMPLE[3 * (degree + 1) + 1:]

        ### CENTERLINE ##############
        step = int(len(CENTERLINE_SAMPLE) / 3)
        coeffs_x = CENTERLINE_SAMPLE[0:step]
        coeffs_y = CENTERLINE_SAMPLE[step:2 * step]
        coeffs_z = CENTERLINE_SAMPLE[2 * step:]
        px = np.poly1d(coeffs_x)
        py = np.poly1d(coeffs_y)
        pz = np.poly1d(coeffs_z)
        der1x = np.polyder(px, m=1)
        der1y = np.polyder(py, m=1)
        der1z = np.polyder(pz, m=1)
        der2x = np.polyder(px, m=2)
        der2y = np.polyder(py, m=2)
        der2z = np.polyder(pz, m=2)

        COORD = np.zeros((len(t_anevrisme), 3))
        COORD[:, 0] = px(t_anevrisme)
        COORD[:, 1] = py(t_anevrisme)
        COORD[:, 2] = pz(t_anevrisme)
        COORD *= DILATATION_SAMPLE
        print("------> Arc Length of the centerline : ",
              stats.arc_length(1, COORD))
        BSPLINE, TAN, NOR, BI = stats.frenet_frame(COORD)

        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.scatter(BSPLINE[:, 0], BSPLINE[:, 1],
                   BSPLINE[:, 2])  # Remember:  rows, cols = Z.shape
        bspline_plot_name = path_datas_random + '/random_bspline_' + str(
            i) + '.png'
        plt.savefig(bspline_plot_name)

        ### RADIUS ##################
        RADIUS_SAMPLE = RADIUS_SAMPLE.reshape(n_point, n_radius)
        #np.savetxt(path_datas + '/random_' + str(i) + ".csv", SAMPLE, delimiter = ',')

        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.plot_surface(X, Y, RADIUS_SAMPLE.T,
                        cmap='ocean')  # Remember:  rows, cols = Z.shape
        surf_plot_name = path_datas_random + '/random_radius_' + str(
            i) + '.png'
        plt.savefig(surf_plot_name)

        liste_contour = []

        for k in range(len(COORD)):

            R_THETA = RADIUS_SAMPLE[k, :]
            TAB = np.hstack((thetas[np.newaxis].T, R_THETA[np.newaxis].T))

            #COORD
            C = BSPLINE[k, :]
            T = TAN[k, :]
            N = NOR[k, :]
            B = BI[k, :]

            #RECONSTRUCTION OF SHAPE OF THE SECTION
            PASSAGE = gmr.Matrice_de_passage(T, N, B)
            COORD_PLAN = ((np.dot(PASSAGE.T, C.T)).T)
            CONTOUR = gmr.Reconstruction_contour(COORD_PLAN, TAB, PASSAGE)
            liste_contour.append(CONTOUR)

        L = np.vstack(liste_contour)
        ANEVRISME = np.vstack((BSPLINE, L))
        gf.Write_csv(
            path_datas_random + '/' + "RANDOM_ANEURYSM_{}.csv".format(i),
            ANEVRISME, "x, y, z")

    end_time = time.time()
    print("Total time ", round(end_time - start_time, 2))
    print("")

    return 0