Source code for importMeshFromTXT

import numpy as np
import pyvista as pv
import pandas as pd
import os
import h5py

#resultsPath="/Users/alessandromastrofini/LocalFiles/acePlaqueGlobalResults/FinalOne/"


[docs] def loadMeshFromHDF5(name, customPath=None): """ Loads a 3D mesh from an HDF5 file for the specified patient. Args: name (str): The name of the patient. customPath (str, optional): Custom path to the patient's data. Defaults to None. Returns: pyvista.UnstructuredGrid: The loaded 3D mesh representing the patient's anatomy. Raises: ValueError: If `customPath` is not provided, it prints a message to specify it. Details: - The function first builds the file path to the HDF5 file containing the mesh data. - It reads the nodes and elements from the HDF5 file, supporting two mesh types: `QuadraticTetra` and `LinearTetra`. - For `QuadraticTetra`, 10 points per element are processed, while for `LinearTetra`, 4 points are used. - The elements are adjusted to match PyVista's expected format (zero-indexed). - Finally, the function creates an unstructured grid using PyVista and returns the mesh. """ # Determine the paths based on whether a custom path is provided if customPath is not None: hdf5Path = os.path.join(customPath,name,"mesh","mesh.h5") #print(hdf5Path) else: print("NO CUSTOM PATH SET, SPECIFY IT!") meshType = 'QuadraticTetra' # or 'LinearTetra' # Read the HDF5 file with h5py.File(hdf5Path, 'r') as h5file: # Load the nodes dataset #print(h5file.keys()) # List all top-level objects in the HDF5 file nodes = h5file['/nodes'][:] # Load the elements dataset (Element_O2) elements = h5file['/Elements_O2'][:] # Determine the number of points per element based on mesh type if meshType == 'QuadraticTetra': nPts = 10 # number of points for each element cellType = np.full(len(elements), pv.CellType.QUADRATIC_TETRA, dtype=np.int8) elif meshType == 'LinearTetra': nPts = 4 cellType = np.full(len(elements), pv.CellType.TETRA, dtype=np.int8) # Adjust the elements array to match PyVista's expected format inElements = np.zeros((len(elements), nPts + 1), dtype=np.uint) for i in range(len(elements)): if meshType == 'QuadraticTetra': data = [elements[i][j] - 1 for j in range(10)] # zero-indexed for PyVista elif meshType == 'LinearTetra': data = [elements[i][j] - 1 for j in range(4)] # zero-indexed for PyVista data.insert(0, nPts) # insert the number of points at the beginning inElements[i] = data # Create the unstructured grid mesh = pv.UnstructuredGrid(np.ravel(inElements), cellType, nodes) return mesh
[docs] def loadMeshFromTXT(name, customPath=None): """ Loads a 3D mesh from a TXT file for the specified patient. Args: name (str): The name of the patient. customPath (str, optional): Custom path to the patient's data. Defaults to None. Returns: pyvista.UnstructuredGrid: The loaded 3D mesh representing the patient's anatomy. Details: - The function first builds the file paths for the nodes and elements from the provided directory. - It reads the nodes from the TXT file and stores them in a NumPy array. - For elements, it supports both `QuadraticTetra` (10 points per element) and `LinearTetra` (4 points per element). - The elements are adjusted to match PyVista's expected format (zero-indexed). - Finally, the function creates an unstructured grid using PyVista and returns the mesh. """ if customPath is not None: nodesPath=customPath+'/'+name+"/mesh/nodes.txt" elementsPath=customPath+'/'+name+"/mesh/Elements_O2.txt" else: nodesPath="/Users/alessandromastrofini/LocalFiles/acePlaque-preprod/T02_Patients/"+name+"/mesh/nodes.txt" elementsPath="/Users/alessandromastrofini/LocalFiles/acePlaque-preprod/T02_Patients/"+name+"/mesh/Elements_O2.txt" meshFileName='' meshType='QuadraticTetra' # or 'LinearTetra' # read all the nodes if meshFileName=='': with open(nodesPath, 'r') as f: inPointsString = f.readlines() inPoints=np.zeros((len(inPointsString),3)) #3=dimensions for i in range(len(inPointsString)): inPoints[i]=list(map(float, inPointsString[i].rstrip().split(' '))) if meshFileName=='': with open(elementsPath, 'r') as f: inElementsString = f.readlines() nOfElements=len(inElementsString) if meshType=='QuadraticTetra': nPts=10 #number of points for each element inCellType=np.full(nOfElements,[pv.CellType.QUADRATIC_TETRA], np.int8) elif meshType=='LinearTetra': nPts=4 inCellType=np.full(nOfElements,[pv.CellType.TETRA], np.int8) # load all the elements inElements=np.zeros((nOfElements,nPts+1), dtype=np.uint) for i in range(0,nOfElements): tmpdata=list(map(int, inElementsString[i].rstrip().split(' '))) if meshType=='QuadraticTetra': data=[tmpdata[0]-1,tmpdata[1]-1,tmpdata[2]-1,tmpdata[3]-1,tmpdata[4]-1,tmpdata[5]-1,tmpdata[6]-1,tmpdata[7]-1,tmpdata[8]-1,tmpdata[9]-1] elif meshType=='LinearTetra': data=[tmpdata[0]-1,tmpdata[1]-1,tmpdata[2]-1,tmpdata[3]-1] data.insert(0,nPts) inElements[i]=data if meshFileName=='': mesh=pv.UnstructuredGrid(np.ravel(inElements), inCellType, inPoints) else: mesh=pv.read(meshFileName) return mesh
[docs] def loadMaterialFromHDF5(mesh, name, customPath=None): """ Loads material properties from an HDF5 file and assigns them to a given mesh. Args: mesh (pyvista.UnstructuredGrid): The patient's mesh to which the material data will be applied. name (str): The name of the patient. customPath (str, optional): Custom path to the patient's data. Defaults to None. Returns: pyvista.UnstructuredGrid: The mesh with material properties added as point data. Raises: ValueError: If `customPath` is not provided, it prints a message to specify it. Details: - The function reads the HDF5 file containing material data (e.g., c2 values). - The material data is assigned to the mesh's `point_data` under the field name 'mats'. """ if customPath is not None: hdf5Path = os.path.join(customPath,name,"Results","materials.h5") else: print("NO CUSTOM PATH SET, SPECIFY IT!") # Step 1: Retrieve all dataset keys with h5py.File(hdf5Path, 'r') as hdf: data = hdf['/c2'][:] mesh.point_data['mats'] = data[0:len(mesh.points)] return mesh
[docs] def loadMaterialFromTXT(mesh, pt, customPath=None): """ Loads material properties from a CSV, Parquet, or HDF5 file and assigns them to a given mesh. Args: mesh (pyvista.UnstructuredGrid): The patient's mesh to which the material data will be applied. pt (str): The name of the patient or patient-specific identifier. customPath (str, optional): Custom path to the patient's data. Defaults to None. Returns: pyvista.UnstructuredGrid: The mesh with material properties added as point data. Raises: FileNotFoundError: If no material file is found in supported formats (.csv, .parquet, .hdf5). Details: - The function searches for the material file in CSV, Parquet, or HDF5 formats in the given directory. - Once the correct file is found, it reads the material data into a DataFrame. - The material data (e.g., c2 values) is then assigned to the mesh's `point_data` under the field name 'mats'. """ if customPath is not None: loadPath = os.path.join(customPath, pt) else: loadPath = os.path.join(resultsPath, pt) # Trova il file materials con l'estensione corretta file_found = None for ext in ['csv', 'parquet', 'hdf5']: file_path = os.path.join(loadPath, f'materials.{ext}') if os.path.exists(file_path): file_found = file_path break if file_found is None: raise FileNotFoundError("Il file materials non è stato trovato in nessuno dei formati supportati (.csv, .parquet, .hdf5).") # Legge il file nel formato corretto if file_found.endswith('.csv'): df2 = pd.read_csv(file_found) elif file_found.endswith('.parquet'): df2 = pd.read_parquet(file_found) elif file_found.endswith('.hdf5'): df2 = pd.read_hdf(file_found, key='df') # Assumendo che il key sia 'df', puoi modificarlo se necessario # Aggiunge i dati al mesh mesh.point_data['mats'] = df2['c2'][0:len(mesh.points)] return mesh