From 25ccc0d999a00cd69d49fbcadbfee5eae7a25b7b Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 15:44:10 +0100 Subject: [PATCH 01/70] Updated formatting --- .../Generate_Boundaries/extract_rings.py | 427 +++---- .../extract_rings_TOP_epi_endo.py | 440 +++---- .../Generate_Boundaries/generate_mesh.py | 8 +- .../Generate_Boundaries/generate_surf_id.py | 30 +- .../Generate_Boundaries/separate_epi_endo.py | 13 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 405 +++--- Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py | 37 +- .../LDRBM/Fiber_LA/la_calculate_gradient.py | 32 +- .../LDRBM/Fiber_LA/la_generate_fiber.py | 451 +++---- Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py | 88 +- Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py | 92 +- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 221 ++-- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 359 +++--- .../LDRBM/Fiber_RA/create_bridges_test.py | 11 +- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 112 +- .../LDRBM/Fiber_RA/ra_calculate_gradient.py | 28 +- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 999 ++++++++------- Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py | 181 ++- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 104 +- Atrial_LDRBM/README.md | 7 +- LICENSE.md | 134 +- README.md | 40 +- main.py | 18 +- pipeline.py | 155 ++- poetry.lock | 1090 ++++++++--------- standalones/create_SSM_instance.py | 17 +- standalones/getmarks.py | 213 ++-- standalones/open_orifices_manually.py | 84 +- standalones/open_orifices_with_curvature.py | 211 ++-- standalones/prealign_meshes.py | 53 +- standalones/resample_surf_mesh.py | 102 +- .../Methods_fit_to_clinical_LAT.py | 188 +-- ...tune_conductivities_to_fit_clinical_LAT.py | 421 ++++--- 33 files changed, 3543 insertions(+), 3228 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 7fee4aa..f05c8b5 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -38,17 +38,18 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + class Ring: - def __init__(self, index, name, points_num, center_point, distance, polydata): - self.id = index - self.name = name - self.np = points_num - self.center = center_point - self.ap_dist = distance - self.vtk_polydata = polydata + def __init__(self, index, name, points_num, center_point, distance, polydata): + self.id = index + self.name = name + self.np = points_num + self.center = center_point + self.ap_dist = distance + self.vtk_polydata = polydata + def parser(): - parser = argparse.ArgumentParser(description='Generate boundaries.') parser.add_argument('--mesh', type=str, @@ -76,8 +77,8 @@ def parser(): help='Set to 1 for debbuging the code') return parser -def smart_reader(path): +def smart_reader(path): extension = str(path).split(".")[-1] if extension == "vtk": @@ -105,30 +106,30 @@ def smart_reader(path): return output -def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_id="", debug=1): +def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_id="", debug=1): """Extrating Rings""" print('Extracting rings...') - + mesh_surf = smart_reader(mesh) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(mesh_surf) geo_filter.Update() - + mesh_surf = geo_filter.GetOutput() - + centroids = dict() - + extension = mesh.split('.')[-1] - mesh = mesh[:-(len(extension)+1)] + mesh = mesh[:-(len(extension) + 1)] meshname = mesh.split("/")[-1] outdir = "{}_surf".format(mesh) if not os.path.exists(outdir): os.makedirs(outdir) - - fname = glob(outdir+'/ids_*') + + fname = glob(outdir + '/ids_*') for r in fname: os.remove(r) # Biatrial geometry @@ -138,20 +139,20 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i centroids["LAA"] = LA_ap_point centroids["RAA"] = RA_ap_point - + if (LAA_base_id != "" and RAA_base_id != ""): LA_bs_point = mesh_surf.GetPoint(int(LAA_base_id)) RA_bs_point = mesh_surf.GetPoint(int(RAA_base_id)) centroids["LAA_base"] = LA_bs_point centroids["RAA_base"] = RA_bs_point - + connect = vtk.vtkConnectivityFilter() connect.SetInputConnection(geo_filter.GetOutputPort()) connect.SetExtractionModeToAllRegions() connect.ColorRegionsOn() connect.Update() - mesh_conn=connect.GetOutput() + mesh_conn = connect.GetOutput() mesh_conn.GetPointData().GetArray("RegionId").SetName("RegionID") id_vec = numpy_support.vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) @@ -164,15 +165,15 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] - + thr = vtk.vtkThreshold() thr.SetInputData(mesh_conn) - thr.ThresholdBetween(LA_tag,LA_tag) + thr.ThresholdBetween(LA_tag, LA_tag) thr.Update() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thr.GetOutputPort()) geo_filter.Update() - + idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_filter.GetOutputPort()) if int(vtk_version) >= 9: @@ -181,37 +182,37 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i else: idFilter.SetIdsArrayName('Ids') idFilter.Update() - + LA = idFilter.GetOutput() - - vtkWrite(LA, outdir+'/LA.vtk') - + + vtkWrite(LA, outdir + '/LA.vtk') + loc = vtk.vtkPointLocator() loc.SetDataSet(LA) loc.BuildLocator() LAA_id = loc.FindClosestPoint(LA_ap_point) - + if LAA_base_id != "": loc = vtk.vtkPointLocator() loc.SetDataSet(LA) loc.BuildLocator() LAA_base_id = loc.FindClosestPoint(LA_bs_point) - + b_tag = np.zeros((LA.GetNumberOfPoints(),)) - LA_rings = detect_and_mark_rings(LA, LA_ap_point,outdir, debug) + LA_rings = detect_and_mark_rings(LA, LA_ap_point, outdir, debug) b_tag, centroids = mark_LA_rings(LAA_id, LA_rings, b_tag, centroids, outdir, LA) dataSet = dsa.WrapDataObject(LA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/LA_boundaries_tagged.vtk'.format(mesh)) - thr.ThresholdBetween(RA_tag,RA_tag) + vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) + + thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thr.GetOutputPort()) geo_filter.Update() - + idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_filter.GetOutputPort()) if int(vtk_version) >= 9: @@ -220,33 +221,33 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i else: idFilter.SetIdsArrayName('Ids') idFilter.Update() - + RA = idFilter.GetOutput() - + loc = vtk.vtkPointLocator() loc.SetDataSet(RA) loc.BuildLocator() RAA_id = loc.FindClosestPoint(RA_ap_point) - + if LAA_base_id != "": loc = vtk.vtkPointLocator() loc.SetDataSet(RA) loc.BuildLocator() RAA_base_id = loc.FindClosestPoint(RA_bs_point) - - vtkWrite(RA, outdir+'/RA.vtk') + + vtkWrite(RA, outdir + '/RA.vtk') b_tag = np.zeros((RA.GetNumberOfPoints(),)) - RA_rings = detect_and_mark_rings(RA, RA_ap_point,outdir,debug) + RA_rings = detect_and_mark_rings(RA, RA_ap_point, outdir, debug) b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) - cutting_plane_to_identify_tv_f_tv_s(RA, RA_rings, outdir,debug) + cutting_plane_to_identify_tv_f_tv_s(RA, RA_rings, outdir, debug) dataSet = dsa.WrapDataObject(RA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/RA_boundaries_tagged.vtk'.format(mesh)) - + + vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) + elif RAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir+'/LA.vtk'.format(mesh)) + vtkWrite(geo_filter.GetOutput(), outdir + '/LA.vtk'.format(mesh)) LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) centroids["LAA"] = LA_ap_point idFilter = vtk.vtkIdFilter() @@ -258,17 +259,17 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i idFilter.SetIdsArrayName('Ids') idFilter.Update() LA = idFilter.GetOutput() - LA_rings = detect_and_mark_rings(LA, LA_ap_point, outdir,debug) + LA_rings = detect_and_mark_rings(LA, LA_ap_point, outdir, debug) b_tag = np.zeros((LA.GetNumberOfPoints(),)) b_tag, centroids = mark_LA_rings(LAA_id, LA_rings, b_tag, centroids, outdir, LA) dataSet = dsa.WrapDataObject(LA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/LA_boundaries_tagged.vtk'.format(mesh)) + + vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) elif LAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir+'/RA.vtk'.format(mesh)) + vtkWrite(geo_filter.GetOutput(), outdir + '/RA.vtk'.format(mesh)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_filter.GetOutputPort()) @@ -280,27 +281,27 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i idFilter.Update() centroids["RAA"] = RA_ap_point RA = idFilter.GetOutput() - RA_rings = detect_and_mark_rings(RA, RA_ap_point, outdir,debug) + RA_rings = detect_and_mark_rings(RA, RA_ap_point, outdir, debug) b_tag = np.zeros((RA.GetNumberOfPoints(),)) b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) - cutting_plane_to_identify_tv_f_tv_s(RA, RA_rings, outdir,debug) + cutting_plane_to_identify_tv_f_tv_s(RA, RA_rings, outdir, debug) dataSet = dsa.WrapDataObject(RA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/RA_boundaries_tagged.vtk'.format(mesh)) - + + vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) + df = pd.DataFrame(centroids) - df.to_csv(outdir+"/rings_centroids.csv", float_format="%.2f", index=False) + df.to_csv(outdir + "/rings_centroids.csv", float_format="%.2f", index=False) -def run(): +def run(): args = parser().parse_args() label_atrial_orifices(args.mesh, args.LAA, args.RAA, args.LAA_base, args.RAA_base, args.debug) - -def detect_and_mark_rings(surf, ap_point,outdir,debug): - + + +def detect_and_mark_rings(surf, ap_point, outdir, debug): boundaryEdges = vtk.vtkFeatureEdges() boundaryEdges.SetInputData(surf) boundaryEdges.BoundaryEdgesOn() @@ -308,19 +309,19 @@ def detect_and_mark_rings(surf, ap_point,outdir,debug): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + "Splitting rings" - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(boundaryEdges.GetOutput()) connect.SetExtractionModeToAllRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + connect.SetExtractionModeToSpecifiedRegions() - + rings = [] - + for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() @@ -332,7 +333,6 @@ def detect_and_mark_rings(surf, ap_point,outdir,debug): geo_filter.Update() surface = geo_filter.GetOutput() - cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() @@ -341,62 +341,64 @@ def detect_and_mark_rings(surf, ap_point,outdir,debug): # be careful overwrite previous rings if debug: vtkWrite(surface, outdir + '/ring_' + str(i) + '.vtk') - + ring_surf = vtk.vtkPolyData() ring_surf.DeepCopy(surface) - + centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(surface) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() - + c_mass = centerOfMassFilter.GetCenter() - - ring = Ring(i,"", surface.GetNumberOfPoints(), c_mass, np.sqrt(np.sum((np.array(ap_point)- \ - np.array(c_mass))**2, axis=0)), ring_surf) - + + ring = Ring(i, "", surface.GetNumberOfPoints(), c_mass, np.sqrt(np.sum((np.array(ap_point) - \ + np.array(c_mass)) ** 2, axis=0)), + ring_surf) + rings.append(ring) - + connect.DeleteSpecifiedRegion(i) connect.Update() - + return rings + def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): rings[np.argmax([r.np for r in rings])].name = "MV" - pvs = [i for i in range(len(rings)) if rings[i].name!="MV"] - + pvs = [i for i in range(len(rings)) if rings[i].name != "MV"] + estimator = KMeans(n_clusters=2) - estimator.fit([r.center for r in rings if r.name!="MV"]) + estimator.fit([r.center for r in rings if r.name != "MV"]) label_pred = estimator.labels_ - + min_ap_dist = np.argmin([r.ap_dist for r in [rings[i] for i in pvs]]) label_LPV = label_pred[min_ap_dist] - + LPVs = [pvs[i] for i in np.where(label_pred == label_LPV)[0]] LSPV_id = LPVs.index(pvs[min_ap_dist]) RPVs = [pvs[i] for i in np.where(label_pred != label_LPV)[0]] - + cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir) - + RSPV_id = cutting_plane_to_identify_RSPV(LPVs, RPVs, rings) RSPV_id = RPVs.index(RSPV_id) - + estimator = KMeans(n_clusters=2) estimator.fit([r.center for r in [rings[i] for i in LPVs]]) LPV_lab = estimator.labels_ LSPVs = [LPVs[i] for i in np.where(LPV_lab == LPV_lab[LSPV_id])[0]] LIPVs = [LPVs[i] for i in np.where(LPV_lab != LPV_lab[LSPV_id])[0]] - + estimator = KMeans(n_clusters=2) estimator.fit([r.center for r in [rings[i] for i in RPVs]]) RPV_lab = estimator.labels_ RSPVs = [RPVs[i] for i in np.where(RPV_lab == RPV_lab[RSPV_id])[0]] RIPVs = [RPVs[i] for i in np.where(RPV_lab != RPV_lab[RSPV_id])[0]] - + LPV = [] RPV = [] - + for i in range(len(pvs)): if pvs[i] in LSPVs: rings[pvs[i]].name = "LSPV" @@ -406,18 +408,18 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): rings[pvs[i]].name = "RIPV" else: rings[pvs[i]].name = "RSPV" - + for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_{}.vtx'.format(r.name) + fname = outdir + '/ids_{}.vtx'.format(r.name) if os.path.exists(fname): - id_vec= id_vec[0:len(id_vec) - 1] + id_vec = id_vec[0:len(id_vec) - 1] f = open(fname, 'a') else: f = open(fname, 'w') f.write('{}\n'.format(len(id_vec))) f.write('extra\n') - + if r.name == "MV": b_tag[id_vec] = 1 elif r.name == "LIPV": @@ -432,40 +434,40 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): elif r.name == "RSPV": b_tag[id_vec] = 5 RPV = RPV + list(id_vec) - + for i in id_vec: f.write('{}\n'.format(i)) f.close() - + centroids[r.name] = r.center - - fname = outdir+'/ids_LAA.vtx' + + fname = outdir + '/ids_LAA.vtx' f = open(fname, 'w') f.write('{}\n'.format(1)) f.write('extra\n') f.write('{}\n'.format(LAA_id)) f.close() - - fname = outdir+'/ids_LPV.vtx' + + fname = outdir + '/ids_LPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(LPV))) f.write('extra\n') for i in LPV: f.write('{}\n'.format(i)) f.close() - - fname = outdir+'/ids_RPV.vtx' + + fname = outdir + '/ids_RPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(RPV))) f.write('extra\n') for i in RPV: f.write('{}\n'.format(i)) f.close() - + return b_tag, centroids -def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): +def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): """ Identifies rings of the right atrium and assigns labels corresponding to their position Assumes that tricuspid valve is the closest ring to the right atrial appendage of the two larges orifices @@ -483,34 +485,34 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): rings[tv_index].name = "TV" # It can happen that the TV is not the biggest ring! - #rings[np.argmax([r.np for r in rings])].name = "TV" - other = [i for i in range(len(rings)) if rings[i].name!="TV"] - + # rings[np.argmax([r.np for r in rings])].name = "TV" + other = [i for i in range(len(rings)) if rings[i].name != "TV"] + estimator = KMeans(n_clusters=2) - estimator.fit([r.center for r in rings if r.name!="TV"]) + estimator.fit([r.center for r in rings if r.name != "TV"]) label_pred = estimator.labels_ - + min_ap_dist = np.argmin([r.ap_dist for r in [rings[i] for i in other]]) label_SVC = label_pred[min_ap_dist] - + SVC = other[np.where(label_pred == label_SVC)[0][0]] IVC_CS = [other[i] for i in np.where(label_pred != label_SVC)[0]] IVC_CS_r = [rings[r] for r in IVC_CS] IVC = IVC_CS[np.argmax([r.np for r in IVC_CS_r])] - + rings[SVC].name = "SVC" rings[IVC].name = "IVC" - if(len(other)>2): - rings[list(set(other)-set([IVC,SVC]))[0]].name = "CS" - + if (len(other) > 2): + rings[list(set(other) - set([IVC, SVC]))[0]].name = "CS" + for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_{}.vtx'.format(r.name) - + fname = outdir + '/ids_{}.vtx'.format(r.name) + f = open(fname, 'w') f.write('{}\n'.format(len(id_vec))) f.write('extra\n') - + if r.name == "TV": b_tag[id_vec] = 6 elif r.name == "SVC": @@ -519,45 +521,45 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): b_tag[id_vec] = 8 elif r.name == "CS": b_tag[id_vec] = 9 - + for i in id_vec: f.write('{}\n'.format(i)) - + f.close() - + centroids[r.name] = r.center - - fname = outdir+'/ids_RAA.vtx' + + fname = outdir + '/ids_RAA.vtx' f = open(fname, 'w') f.write('{}\n'.format(1)) f.write('extra\n') f.write('{}\n'.format(RAA_id)) f.close() - + return b_tag, centroids, rings def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): LPVs_c = np.array([r.center for r in [rings[i] for i in LPVs]]) - lpv_mean = np.mean(LPVs_c, axis = 0) + lpv_mean = np.mean(LPVs_c, axis=0) RPVs_c = np.array([r.center for r in [rings[i] for i in RPVs]]) - rpv_mean = np.mean(RPVs_c, axis = 0) + rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - + v1 = rpv_mean - mv_mean v2 = lpv_mean - mv_mean norm = np.cross(v1, v2) - + # # normalize vector norm = norm / np.linalg.norm(norm) plane = vtk.vtkPlane() plane.SetNormal(norm[0], norm[1], norm[2]) plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) - + appendFilter = vtk.vtkAppendPolyData() for r in [rings[i] for i in RPVs]: - tag_data = vtk.util.numpy_support.numpy_to_vtk(np.ones((r.np,))*r.id, deep=True, array_type=vtk.VTK_INT) + tag_data = vtk.util.numpy_support.numpy_to_vtk(np.ones((r.np,)) * r.id, deep=True, array_type=vtk.VTK_INT) tag_data.SetNumberOfComponents(1) tag_data.SetName("id") temp = vtk.vtkPolyData() @@ -565,44 +567,45 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): temp.GetPointData().SetScalars(tag_data) appendFilter.AddInputData(temp) appendFilter.Update() - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(appendFilter.GetOutput()) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + RSPV_id = int(vtk.util.numpy_support.vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) - + return RSPV_id + def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): LPVs_c = np.array([r.center for r in [rings[i] for i in LPVs]]) - lpv_mean = np.mean(LPVs_c, axis = 0) + lpv_mean = np.mean(LPVs_c, axis=0) RPVs_c = np.array([r.center for r in [rings[i] for i in RPVs]]) - rpv_mean = np.mean(RPVs_c, axis = 0) + rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - + v1 = rpv_mean - mv_mean v2 = lpv_mean - mv_mean norm = np.cross(v1, v2) - + # # normalize vector norm = norm / np.linalg.norm(norm) plane = vtk.vtkPlane() plane.SetNormal(norm[0], norm[1], norm[2]) plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(LA) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() surface = geo_filter.GetOutput() - + """ here we will extract the feature edge """ @@ -613,39 +616,39 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) ids = vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) MV_ring = [r for r in rings if r.name == "MV"] - + MV_ids = set(numpy_support.vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) - + MV_ant = set(ids).intersection(MV_ids) MV_post = MV_ids - MV_ant - - fname = outdir+'/ids_MV_ant.vtx' + + fname = outdir + '/ids_MV_ant.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(MV_ant))) f.write('extra\n') for i in MV_ant: f.write('{}\n'.format(i)) f.close() - - fname = outdir+'/ids_MV_post.vtx' + + fname = outdir + '/ids_MV_post.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(MV_post))) f.write('extra\n') for i in MV_post: f.write('{}\n'.format(i)) f.close() - + loc = vtk.vtkPointLocator() loc.SetDataSet(MV_ring[0].vtk_polydata) loc.BuildLocator() - + lpv_mv = loc.FindClosestPoint(lpv_mean) rpv_mv = loc.FindClosestPoint(rpv_mean) - + loc = vtk.vtkPointLocator() loc.SetDataSet(boundaryEdges.GetOutput()) loc.BuildLocator() @@ -653,70 +656,69 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_bb = loc.FindClosestPoint(rpv_mean) lpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(lpv_mv)) rpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundaryEdges.GetOutput()) path.SetStartVertex(lpv_bb) path.SetEndVertex(lpv_mv) path.Update() - + p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_lpv = set(ids[ii]) for r in rings: mv_lpv = mv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - - fname = outdir+'/ids_MV_LPV.vtx' + + fname = outdir + '/ids_MV_LPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(mv_lpv))) f.write('extra\n') for i in mv_lpv: f.write('{}\n'.format(i)) f.close() - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundaryEdges.GetOutput()) path.SetStartVertex(rpv_bb) path.SetEndVertex(rpv_mv) path.Update() - + p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_rpv = set(ids[ii]) for r in rings: mv_rpv = mv_rpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - - fname = outdir+'/ids_MV_RPV.vtx' + + fname = outdir + '/ids_MV_RPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(mv_rpv))) f.write('extra\n') for i in mv_rpv: f.write('{}\n'.format(i)) f.close() - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundaryEdges.GetOutput()) path.SetStartVertex(lpv_bb) path.SetEndVertex(rpv_bb) path.Update() - + p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) rpv_lpv = set(ids[ii]) for r in rings: rpv_lpv = rpv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - - fname = outdir+'/ids_RPV_LPV.vtx' + + fname = outdir + '/ids_RPV_LPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(rpv_lpv))) f.write('extra\n') for i in rpv_lpv: f.write('{}\n'.format(i)) f.close() - -def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): - + +def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): for r in rings: if r.name == "TV": tv_center = np.array(r.center) @@ -727,20 +729,20 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): elif r.name == "IVC": ivc_center = np.array(r.center) ivc = r.vtk_polydata - + # calculate the norm vector v1 = tv_center - svc_center v2 = tv_center - ivc_center norm = np.cross(v1, v2) - - #normalize norm + + # normalize norm n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm/n + norm_1 = norm / n plane = vtk.vtkPlane() plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) geo_filter.Update() @@ -750,15 +752,15 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): meshExtractFilter.SetInputData(surface) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() surface = geo_filter.GetOutput() if debug: - vtkWrite(surface,outdir+'/cutted_RA.vtk') - + vtkWrite(surface, outdir + '/cutted_RA.vtk') + """ here we will extract the feature edge """ @@ -769,7 +771,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + gamma_top = boundaryEdges.GetOutput() if debug: @@ -777,8 +779,8 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): geo_filter.SetInputData(gamma_top) geo_filter.Update() surface = geo_filter.GetOutput() - vtkWrite(surface, outdir+'/gamma_top.vtk') - + vtkWrite(surface, outdir + '/gamma_top.vtk') + """ separate the tv into tv tv-f and tv-f """ @@ -786,65 +788,65 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): v1 = svc_center - tv_center v2 = ivc_center - tv_center norm = np.cross(v2, v1) - - #normalize norm + + # normalize norm n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm/n + norm_1 = norm / n norm_2 = - norm_1 plane = vtk.vtkPlane() plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) - + plane2 = vtk.vtkPlane() plane2.SetNormal(norm_2[0][0], norm_2[0][1], norm_2[0][2]) plane2.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(tv) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + meshExtractFilter2 = vtk.vtkExtractGeometry() meshExtractFilter2.SetInputData(tv) meshExtractFilter2.ExtractBoundaryCellsOn() meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() tv_f = geo_filter.GetOutput() - + tv_f_ids = vtk.util.numpy_support.vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TV_F.vtx' + fname = outdir + '/ids_TV_F.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(tv_f_ids))) f.write('extra\n') for i in tv_f_ids: f.write('{}\n'.format(i)) f.close() - + geo_filter2 = vtk.vtkGeometryFilter() geo_filter2.SetInputData(meshExtractFilter2.GetOutput()) geo_filter2.Update() tv_s = geo_filter2.GetOutput() - + tv_s_ids = vtk.util.numpy_support.vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TV_S.vtx' + fname = outdir + '/ids_TV_S.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(tv_s_ids))) f.write('extra\n') for i in tv_s_ids: f.write('{}\n'.format(i)) f.close() - + svc_points = svc.GetPoints().GetData() svc_points = vtk.util.numpy_support.vtk_to_numpy(svc_points) - - ivc_points = svc.GetPoints().GetData() # Changed + + ivc_points = svc.GetPoints().GetData() # Changed ivc_points = vtk.util.numpy_support.vtk_to_numpy(ivc_points) - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(gamma_top) connect.SetExtractionModeToSpecifiedRegions() @@ -869,8 +871,8 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): points = points.tolist() if debug: - create_pts(points,'/border_points_{}'.format(str(i)),outdir) - + create_pts(points, '/border_points_{}'.format(str(i)), outdir) + in_ivc = False in_svc = False # if there is point of group i in both svc and ivc then it is the "top_endo+epi" we need @@ -884,14 +886,14 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): top_endo_id = i break else: - top_endo_id = i # comment this line if errors + top_endo_id = i # comment this line if errors break - + # delete added region id connect.DeleteSpecifiedRegion(i) connect.Update() # It can happen that the first i=region(0) is the CS. Remove the -1 if that is the case - connect.AddSpecifiedRegion(top_endo_id-1) # Find the id in the points dividing the RA, avoid CS + connect.AddSpecifiedRegion(top_endo_id - 1) # Find the id in the points dividing the RA, avoid CS connect.Update() surface = connect.GetOutput() @@ -899,44 +901,44 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() - + top_cut = cln.GetOutput() if debug: - vtkWrite(top_cut, outdir + '/top_endo_epi.vtk') # If this is the CS, then change top_endo_id in 877 - + vtkWrite(top_cut, outdir + '/top_endo_epi.vtk') # If this is the CS, then change top_endo_id in 877 + pts_in_top = vtk.util.numpy_support.vtk_to_numpy(top_cut.GetPointData().GetArray("Ids")) pts_in_svc = vtk.util.numpy_support.vtk_to_numpy(svc.GetPointData().GetArray("Ids")) pts_in_ivc = vtk.util.numpy_support.vtk_to_numpy(ivc.GetPointData().GetArray("Ids")) - + to_delete = np.zeros((len(pts_in_top),), dtype=int) - + for i in range(len(pts_in_top)): if pts_in_top[i] in pts_in_svc or pts_in_top[i] in pts_in_ivc: to_delete[i] = 1 - + meshNew = dsa.WrapDataObject(top_cut) meshNew.PointData.append(to_delete, "delete") - + thresh = vtk.vtkThreshold() thresh.SetInputData(meshNew.VTKObject) thresh.ThresholdByLower(0) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") thresh.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) geo_filter.Update() - + mv_id = vtk.util.numpy_support.vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(geo_filter.GetOutput()) connect.SetExtractionModeToSpecifiedRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() @@ -946,28 +948,28 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): cln.SetInputData(surface) cln.Update() surface = cln.GetOutput() - + pts_surf = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - + if mv_id not in pts_surf: found_id = i break - + # delete added region id connect.DeleteSpecifiedRegion(i) connect.Update() - + connect.AddSpecifiedRegion(found_id) connect.Update() surface = connect.GetOutput() - + # Clean unused points cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() - + top_endo = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TOP_ENDO.vtx' + fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(top_endo))) f.write('extra\n') @@ -975,8 +977,9 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir,debug): f.write('{}\n'.format(i)) f.close() -def create_pts(array_points,array_name,mesh_dir): - f = open("{}{}.pts".format(mesh_dir,array_name), "w") + +def create_pts(array_points, array_name, mesh_dir): + f = open("{}{}.pts".format(mesh_dir, array_name), "w") f.write("0 0 0\n") for i in range(len(array_points)): f.write("{} {} {}\n".format(array_points[i][0], array_points[i][1], array_points[i][2])) @@ -990,11 +993,13 @@ def to_polydata(mesh): polydata = geo_filter.GetOutput() return polydata + def vtkWrite(input_data, name): writer = vtk.vtkPolyDataWriter() writer.SetInputData(input_data) writer.SetFileName(name) writer.Write() + if __name__ == '__main__': run() diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 9d6aed6..7018bf0 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -38,17 +38,18 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + class Ring: - def __init__(self, index, name, points_num, center_point, distance, polydata): - self.id = index - self.name = name - self.np = points_num - self.center = center_point - self.ap_dist = distance - self.vtk_polydata = polydata + def __init__(self, index, name, points_num, center_point, distance, polydata): + self.id = index + self.name = name + self.np = points_num + self.center = center_point + self.ap_dist = distance + self.vtk_polydata = polydata + def parser(): - parser = argparse.ArgumentParser(description='Generate boundaries.') parser.add_argument('--mesh', type=str, @@ -72,8 +73,8 @@ def parser(): help='RAA basis point index, leave empty if no RA') return parser -def smart_reader(path): +def smart_reader(path): extension = str(path).split(".")[-1] if extension == "vtk": @@ -101,53 +102,53 @@ def smart_reader(path): return output -def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_id=""): +def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_id=""): """Extrating Rings""" print('Extracting rings...') - + mesh_surf = smart_reader(mesh) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(mesh_surf) geo_filter.Update() - + mesh_surf = geo_filter.GetOutput() - + centroids = dict() - + extension = mesh.split('.')[-1] - mesh = mesh[:-(len(extension)+1)] + mesh = mesh[:-(len(extension) + 1)] meshname = mesh.split("/")[-1] outdir = "{}_surf".format(mesh) if not os.path.exists(outdir): os.makedirs(outdir) - - fname = glob(outdir+'/ids_*') + + fname = glob(outdir + '/ids_*') for r in fname: os.remove(r) - + if (LAA_id != "" and RAA_id != ""): LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) centroids["LAA"] = LA_ap_point centroids["RAA"] = RA_ap_point - + if (LAA_base_id != "" and RAA_base_id != ""): LA_bs_point = mesh_surf.GetPoint(int(LAA_base_id)) RA_bs_point = mesh_surf.GetPoint(int(RAA_base_id)) centroids["LAA_base"] = LA_bs_point centroids["RAA_base"] = RA_bs_point - + connect = vtk.vtkConnectivityFilter() connect.SetInputConnection(geo_filter.GetOutputPort()) connect.SetExtractionModeToAllRegions() connect.ColorRegionsOn() connect.Update() - mesh_conn=connect.GetOutput() + mesh_conn = connect.GetOutput() mesh_conn.GetPointData().GetArray("RegionId").SetName("RegionID") id_vec = numpy_support.vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) @@ -159,15 +160,15 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] - + thr = vtk.vtkThreshold() thr.SetInputData(mesh_conn) - thr.ThresholdBetween(LA_tag,LA_tag) + thr.ThresholdBetween(LA_tag, LA_tag) thr.Update() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thr.GetOutputPort()) geo_filter.Update() - + idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_filter.GetOutputPort()) if int(vtk_version) >= 9: @@ -176,37 +177,37 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" else: idFilter.SetIdsArrayName('Ids') idFilter.Update() - + LA = idFilter.GetOutput() - - vtkWrite(LA, outdir+'/LA.vtp') - + + vtkWrite(LA, outdir + '/LA.vtp') + loc = vtk.vtkPointLocator() loc.SetDataSet(LA) loc.BuildLocator() LAA_id = loc.FindClosestPoint(LA_ap_point) - + if LAA_base_id != "": loc = vtk.vtkPointLocator() loc.SetDataSet(LA) loc.BuildLocator() LAA_base_id = loc.FindClosestPoint(LA_bs_point) - + b_tag = np.zeros((LA.GetNumberOfPoints(),)) LA_rings = detect_and_mark_rings(LA, LA_ap_point) b_tag, centroids = mark_LA_rings(LAA_id, LA_rings, b_tag, centroids, outdir, LA) dataSet = dsa.WrapDataObject(LA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/LA_boundaries_tagged.vtp'.format(mesh)) - thr.ThresholdBetween(RA_tag,RA_tag) + vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtp'.format(mesh)) + + thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thr.GetOutputPort()) geo_filter.Update() - + idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_filter.GetOutputPort()) if int(vtk_version) >= 9: @@ -215,21 +216,21 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" else: idFilter.SetIdsArrayName('Ids') idFilter.Update() - + RA = idFilter.GetOutput() - + loc = vtk.vtkPointLocator() loc.SetDataSet(RA) loc.BuildLocator() RAA_id = loc.FindClosestPoint(RA_ap_point) - + if LAA_base_id != "": loc = vtk.vtkPointLocator() loc.SetDataSet(RA) loc.BuildLocator() RAA_base_id = loc.FindClosestPoint(RA_bs_point) - - vtkWrite(RA, outdir+'/RA.vtp') + + vtkWrite(RA, outdir + '/RA.vtp') b_tag = np.zeros((RA.GetNumberOfPoints(),)) RA_rings = detect_and_mark_rings(RA, RA_ap_point) b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) @@ -237,11 +238,11 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" dataSet = dsa.WrapDataObject(RA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/RA_boundaries_tagged.vtp'.format(mesh)) - + + vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtp'.format(mesh)) + elif RAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir+'/LA.vtp'.format(mesh)) + vtkWrite(geo_filter.GetOutput(), outdir + '/LA.vtp'.format(mesh)) LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) centroids["LAA"] = LA_ap_point idFilter = vtk.vtkIdFilter() @@ -259,11 +260,11 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" dataSet = dsa.WrapDataObject(LA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/LA_boundaries_tagged.vtp'.format(mesh)) + + vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtp'.format(mesh)) elif LAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir+'/RA.vtp'.format(mesh)) + vtkWrite(geo_filter.GetOutput(), outdir + '/RA.vtp'.format(mesh)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_filter.GetOutputPort()) @@ -277,25 +278,25 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" RA = idFilter.GetOutput() RA_rings = detect_and_mark_rings(RA, RA_ap_point) b_tag = np.zeros((RA.GetNumberOfPoints(),)) - b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) + b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, RA, RA_rings, outdir) dataSet = dsa.WrapDataObject(RA) dataSet.PointData.append(b_tag, 'boundary_tag') - - vtkWrite(dataSet.VTKObject, outdir+'/RA_boundaries_tagged.vtp'.format(mesh)) - + + vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtp'.format(mesh)) + df = pd.DataFrame(centroids) - df.to_csv(outdir+"/rings_centroids.csv", float_format="%.2f", index=False) + df.to_csv(outdir + "/rings_centroids.csv", float_format="%.2f", index=False) -def run(): +def run(): args = parser().parse_args() label_atrial_orifices_TOP_epi_endo(args.mesh, args.LAA, args.RAA, args.LAA_base, args.RAA_base) - + + def detect_and_mark_rings(surf, ap_point): - boundaryEdges = vtk.vtkFeatureEdges() boundaryEdges.SetInputData(surf) boundaryEdges.BoundaryEdgesOn() @@ -303,19 +304,19 @@ def detect_and_mark_rings(surf, ap_point): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + "Splitting rings" - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(boundaryEdges.GetOutput()) connect.SetExtractionModeToAllRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + connect.SetExtractionModeToSpecifiedRegions() - + rings = [] - + for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() @@ -331,62 +332,64 @@ def detect_and_mark_rings(surf, ap_point): cln.SetInputData(surface) cln.Update() surface = cln.GetOutput() - + ring_surf = vtk.vtkPolyData() ring_surf.DeepCopy(surface) - + centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(surface) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() - + c_mass = centerOfMassFilter.GetCenter() - - ring = Ring(i,"", surface.GetNumberOfPoints(), c_mass, np.sqrt(np.sum((np.array(ap_point)- \ - np.array(c_mass))**2, axis=0)), ring_surf) - + + ring = Ring(i, "", surface.GetNumberOfPoints(), c_mass, np.sqrt(np.sum((np.array(ap_point) - \ + np.array(c_mass)) ** 2, axis=0)), + ring_surf) + rings.append(ring) - + connect.DeleteSpecifiedRegion(i) connect.Update() - + return rings + def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): rings[np.argmax([r.np for r in rings])].name = "MV" - pvs = [i for i in range(len(rings)) if rings[i].name!="MV"] - + pvs = [i for i in range(len(rings)) if rings[i].name != "MV"] + estimator = KMeans(n_clusters=2) - estimator.fit([r.center for r in rings if r.name!="MV"]) + estimator.fit([r.center for r in rings if r.name != "MV"]) label_pred = estimator.labels_ - + min_ap_dist = np.argmin([r.ap_dist for r in [rings[i] for i in pvs]]) label_LPV = label_pred[min_ap_dist] - + LPVs = [pvs[i] for i in np.where(label_pred == label_LPV)[0]] LSPV_id = LPVs.index(pvs[min_ap_dist]) RPVs = [pvs[i] for i in np.where(label_pred != label_LPV)[0]] - + cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir) - + RSPV_id = cutting_plane_to_identify_RSPV(LPVs, RPVs, rings) RSPV_id = RPVs.index(RSPV_id) - + estimator = KMeans(n_clusters=2) estimator.fit([r.center for r in [rings[i] for i in LPVs]]) LPV_lab = estimator.labels_ LSPVs = [LPVs[i] for i in np.where(LPV_lab == LPV_lab[LSPV_id])[0]] LIPVs = [LPVs[i] for i in np.where(LPV_lab != LPV_lab[LSPV_id])[0]] - + estimator = KMeans(n_clusters=2) estimator.fit([r.center for r in [rings[i] for i in RPVs]]) RPV_lab = estimator.labels_ RSPVs = [RPVs[i] for i in np.where(RPV_lab == RPV_lab[RSPV_id])[0]] RIPVs = [RPVs[i] for i in np.where(RPV_lab != RPV_lab[RSPV_id])[0]] - + LPV = [] RPV = [] - + for i in range(len(pvs)): if pvs[i] in LSPVs: rings[pvs[i]].name = "LSPV" @@ -396,17 +399,17 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): rings[pvs[i]].name = "RIPV" else: rings[pvs[i]].name = "RSPV" - + for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_{}.vtx'.format(r.name) + fname = outdir + '/ids_{}.vtx'.format(r.name) if os.path.exists(fname): f = open(fname, 'a') else: f = open(fname, 'w') f.write('{}\n'.format(len(id_vec))) f.write('extra\n') - + if r.name == "MV": b_tag[id_vec] = 1 elif r.name == "LIPV": @@ -421,67 +424,68 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): elif r.name == "RSPV": b_tag[id_vec] = 5 RPV = RPV + list(id_vec) - + for i in id_vec: f.write('{}\n'.format(i)) f.close() - + centroids[r.name] = r.center - - fname = outdir+'/ids_LAA.vtx' + + fname = outdir + '/ids_LAA.vtx' f = open(fname, 'w') f.write('{}\n'.format(1)) f.write('extra\n') f.write('{}\n'.format(LAA_id)) f.close() - - fname = outdir+'/ids_LPV.vtx' + + fname = outdir + '/ids_LPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(LPV))) f.write('extra\n') for i in LPV: f.write('{}\n'.format(i)) f.close() - - fname = outdir+'/ids_RPV.vtx' + + fname = outdir + '/ids_RPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(RPV))) f.write('extra\n') for i in RPV: f.write('{}\n'.format(i)) f.close() - + return b_tag, centroids + def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): rings[np.argmax([r.np for r in rings])].name = "TV" - other = [i for i in range(len(rings)) if rings[i].name!="TV"] - + other = [i for i in range(len(rings)) if rings[i].name != "TV"] + estimator = KMeans(n_clusters=2) - estimator.fit([r.center for r in rings if r.name!="TV"]) + estimator.fit([r.center for r in rings if r.name != "TV"]) label_pred = estimator.labels_ - + min_ap_dist = np.argmin([r.ap_dist for r in [rings[i] for i in other]]) label_SVC = label_pred[min_ap_dist] - + SVC = other[np.where(label_pred == label_SVC)[0][0]] IVC_CS = [other[i] for i in np.where(label_pred != label_SVC)[0]] IVC_CS_r = [rings[r] for r in IVC_CS] IVC = IVC_CS[np.argmax([r.np for r in IVC_CS_r])] - + rings[SVC].name = "SVC" rings[IVC].name = "IVC" - if(len(other)>2): - rings[list(set(other)-set([IVC,SVC]))[0]].name = "CS" - + if (len(other) > 2): + rings[list(set(other) - set([IVC, SVC]))[0]].name = "CS" + for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_{}.vtx'.format(r.name) - + fname = outdir + '/ids_{}.vtx'.format(r.name) + f = open(fname, 'w') f.write('{}\n'.format(len(id_vec))) f.write('extra\n') - + if r.name == "TV": b_tag[id_vec] = 6 elif r.name == "SVC": @@ -490,51 +494,52 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): b_tag[id_vec] = 8 elif r.name == "CS": b_tag[id_vec] = 9 - + for i in id_vec: f.write('{}\n'.format(i)) - + f.close() - + centroids[r.name] = r.center - - fname = outdir+'/ids_RAA.vtx' + + fname = outdir + '/ids_RAA.vtx' f = open(fname, 'w') f.write('{}\n'.format(1)) f.write('extra\n') f.write('{}\n'.format(RAA_id)) f.close() - + return b_tag, centroids, rings + def vtkWrite(input_data, name): - writer = vtk.vtkXMLPolyDataWriter() writer.SetInputData(input_data) writer.SetFileName(name) writer.Write() + def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): LPVs_c = np.array([r.center for r in [rings[i] for i in LPVs]]) - lpv_mean = np.mean(LPVs_c, axis = 0) + lpv_mean = np.mean(LPVs_c, axis=0) RPVs_c = np.array([r.center for r in [rings[i] for i in RPVs]]) - rpv_mean = np.mean(RPVs_c, axis = 0) + rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - + v1 = rpv_mean - mv_mean v2 = lpv_mean - mv_mean norm = np.cross(v1, v2) - + # # normalize vector norm = norm / np.linalg.norm(norm) plane = vtk.vtkPlane() plane.SetNormal(norm[0], norm[1], norm[2]) plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) - + appendFilter = vtk.vtkAppendPolyData() for r in [rings[i] for i in RPVs]: - tag_data = vtk.util.numpy_support.numpy_to_vtk(np.ones((r.np,))*r.id, deep=True, array_type=vtk.VTK_INT) + tag_data = vtk.util.numpy_support.numpy_to_vtk(np.ones((r.np,)) * r.id, deep=True, array_type=vtk.VTK_INT) tag_data.SetNumberOfComponents(1) tag_data.SetName("id") temp = vtk.vtkPolyData() @@ -542,44 +547,45 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): temp.GetPointData().SetScalars(tag_data) appendFilter.AddInputData(temp) appendFilter.Update() - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(appendFilter.GetOutput()) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + RSPV_id = int(vtk.util.numpy_support.vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) - + return RSPV_id + def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): LPVs_c = np.array([r.center for r in [rings[i] for i in LPVs]]) - lpv_mean = np.mean(LPVs_c, axis = 0) + lpv_mean = np.mean(LPVs_c, axis=0) RPVs_c = np.array([r.center for r in [rings[i] for i in RPVs]]) - rpv_mean = np.mean(RPVs_c, axis = 0) + rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - + v1 = rpv_mean - mv_mean v2 = lpv_mean - mv_mean norm = np.cross(v1, v2) - + # # normalize vector norm = norm / np.linalg.norm(norm) plane = vtk.vtkPlane() plane.SetNormal(norm[0], norm[1], norm[2]) plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(LA) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() surface = geo_filter.GetOutput() - + """ here we will extract the feature edge """ @@ -590,39 +596,39 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) ids = vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) MV_ring = [r for r in rings if r.name == "MV"] - + MV_ids = set(numpy_support.vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) - + MV_ant = set(ids).intersection(MV_ids) MV_post = MV_ids - MV_ant - - fname = outdir+'/ids_MV_ant.vtx' + + fname = outdir + '/ids_MV_ant.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(MV_ant))) f.write('extra\n') for i in MV_ant: f.write('{}\n'.format(i)) f.close() - - fname = outdir+'/ids_MV_post.vtx' + + fname = outdir + '/ids_MV_post.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(MV_post))) f.write('extra\n') for i in MV_post: f.write('{}\n'.format(i)) f.close() - + loc = vtk.vtkPointLocator() loc.SetDataSet(MV_ring[0].vtk_polydata) loc.BuildLocator() - + lpv_mv = loc.FindClosestPoint(lpv_mean) rpv_mv = loc.FindClosestPoint(rpv_mean) - + loc = vtk.vtkPointLocator() loc.SetDataSet(boundaryEdges.GetOutput()) loc.BuildLocator() @@ -630,70 +636,69 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_bb = loc.FindClosestPoint(rpv_mean) lpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(lpv_mv)) rpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundaryEdges.GetOutput()) path.SetStartVertex(lpv_bb) path.SetEndVertex(lpv_mv) path.Update() - + p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_lpv = set(ids[ii]) for r in rings: mv_lpv = mv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - - fname = outdir+'/ids_MV_LPV.vtx' + + fname = outdir + '/ids_MV_LPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(mv_lpv))) f.write('extra\n') for i in mv_lpv: f.write('{}\n'.format(i)) f.close() - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundaryEdges.GetOutput()) path.SetStartVertex(rpv_bb) path.SetEndVertex(rpv_mv) path.Update() - + p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_rpv = set(ids[ii]) for r in rings: mv_rpv = mv_rpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - - fname = outdir+'/ids_MV_RPV.vtx' + + fname = outdir + '/ids_MV_RPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(mv_rpv))) f.write('extra\n') for i in mv_rpv: f.write('{}\n'.format(i)) f.close() - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundaryEdges.GetOutput()) path.SetStartVertex(lpv_bb) path.SetEndVertex(rpv_bb) path.Update() - + p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) rpv_lpv = set(ids[ii]) for r in rings: rpv_lpv = rpv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - - fname = outdir+'/ids_RPV_LPV.vtx' + + fname = outdir + '/ids_RPV_LPV.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(rpv_lpv))) f.write('extra\n') for i in rpv_lpv: f.write('{}\n'.format(i)) f.close() - -def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): +def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): for r in rings: if r.name == "TV": tv_center = np.array(r.center) @@ -704,20 +709,20 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): elif r.name == "IVC": ivc_center = np.array(r.center) ivc = r.vtk_polydata - + # calculate the norm vector v1 = tv_center - svc_center v2 = tv_center - ivc_center norm = np.cross(v1, v2) - - #normalize norm + + # normalize norm n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm/n + norm_1 = norm / n plane = vtk.vtkPlane() plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) geo_filter.Update() @@ -727,12 +732,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): meshExtractFilter.SetInputData(surface) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() surface = geo_filter.GetOutput() - + """ here we will extract the feature edge """ @@ -743,12 +748,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + gamma_top_epi = boundaryEdges.GetOutput() # Endo - endo = smart_reader(mesh[:-3]+'endo.obj') + endo = smart_reader(mesh[:-3] + 'endo.obj') idFilter = vtk.vtkIdFilter() idFilter.SetInputData(endo) @@ -758,7 +763,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): else: idFilter.SetIdsArrayName('Ids') idFilter.Update() - + endo = idFilter.GetOutput() geo_filter = vtk.vtkGeometryFilter() @@ -770,12 +775,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): meshExtractFilter.SetInputData(surface) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() surface = geo_filter.GetOutput() - + """ here we will extract the feature edge """ @@ -786,9 +791,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + gamma_top_endo = boundaryEdges.GetOutput() - + """ separate the tv into tv tv-f and tv-f """ @@ -796,62 +801,62 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): v1 = svc_center - tv_center v2 = ivc_center - tv_center norm = np.cross(v2, v1) - - #normalize norm + + # normalize norm n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm/n + norm_1 = norm / n norm_2 = - norm_1 plane = vtk.vtkPlane() plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) - + plane2 = vtk.vtkPlane() plane2.SetNormal(norm_2[0][0], norm_2[0][1], norm_2[0][2]) plane2.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(tv) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - + meshExtractFilter2 = vtk.vtkExtractGeometry() meshExtractFilter2.SetInputData(tv) meshExtractFilter2.ExtractBoundaryCellsOn() meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(meshExtractFilter.GetOutput()) geo_filter.Update() tv_f = geo_filter.GetOutput() - + tv_f_ids = vtk.util.numpy_support.vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TV_F.vtx' + fname = outdir + '/ids_TV_F.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(tv_f_ids))) f.write('extra\n') for i in tv_f_ids: f.write('{}\n'.format(i)) f.close() - + geo_filter2 = vtk.vtkGeometryFilter() geo_filter2.SetInputData(meshExtractFilter2.GetOutput()) geo_filter2.Update() tv_s = geo_filter2.GetOutput() - + tv_s_ids = vtk.util.numpy_support.vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TV_S.vtx' + fname = outdir + '/ids_TV_S.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(tv_s_ids))) f.write('extra\n') for i in tv_s_ids: f.write('{}\n'.format(i)) f.close() - + svc_points = svc.GetPoints().GetData() svc_points = vtk.util.numpy_support.vtk_to_numpy(svc_points) - + ivc_points = ivc.GetPoints().GetData() ivc_points = vtk.util.numpy_support.vtk_to_numpy(ivc_points) @@ -872,7 +877,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): points = surface.GetPoints().GetData() points = vtk.util.numpy_support.vtk_to_numpy(points) points = points.tolist() - + in_ivc = False in_svc = False # if there is point of group i in both svc and ivc then it is the "top_endo+epi" we need @@ -887,7 +892,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): break else: break - + # delete added region id connect.DeleteSpecifiedRegion(i) connect.Update() @@ -895,14 +900,14 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): connect.AddSpecifiedRegion(top_epi_id) connect.Update() surface = connect.GetOutput() - + # Clean unused points cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() - + top_cut_epi = cln.GetOutput() - + pts_in_top_epi = vtk.util.numpy_support.vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) connect = vtk.vtkConnectivityFilter() @@ -922,7 +927,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): points = surface.GetPoints().GetData() points = vtk.util.numpy_support.vtk_to_numpy(points) points = points.tolist() - + in_ivc = False in_svc = False # if there is point of group i in both svc and ivc then it is the "top_endo+epi" we need @@ -937,7 +942,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): break else: break - + # delete added region id connect.DeleteSpecifiedRegion(i) connect.Update() @@ -945,25 +950,25 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): connect.AddSpecifiedRegion(top_endo_id) connect.Update() surface = connect.GetOutput() - + # Clean unused points cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() - + top_cut_endo = cln.GetOutput() - + pts_in_top_endo = vtk.util.numpy_support.vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids")) pts_in_svc_epi = vtk.util.numpy_support.vtk_to_numpy(svc.GetPointData().GetArray("Ids")) pts_in_ivc_epi = vtk.util.numpy_support.vtk_to_numpy(ivc.GetPointData().GetArray("Ids")) pts_in_tv_epi = vtk.util.numpy_support.vtk_to_numpy(tv.GetPointData().GetArray("Ids")) - tv_id_epi = np.intersect1d(pts_in_tv_epi,pts_in_top_epi) + tv_id_epi = np.intersect1d(pts_in_tv_epi, pts_in_top_epi) # pts_in_top_endo = vtk.util.numpy_support.vtk_to_numpy(top_cut_endo.GetPoints().GetData()) # pts_in_svc = vtk.util.numpy_support.vtk_to_numpy(svc.GetPoints().GetData()) # pts_in_ivc = vtk.util.numpy_support.vtk_to_numpy(ivc.GetPoints().GetData()) - + endo_ids = vtk.util.numpy_support.vtk_to_numpy(endo.GetPointData().GetArray("Ids")) tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(endo.GetPoints().GetData())) dd, ii = tree.query(svc_points) @@ -973,35 +978,35 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): dd, ii = tree.query(vtk.util.numpy_support.vtk_to_numpy(tv.GetPoints().GetData())) pts_in_tv_endo = endo_ids[ii] - tv_id_endo = np.intersect1d(pts_in_tv_endo,pts_in_top_endo) + tv_id_endo = np.intersect1d(pts_in_tv_endo, pts_in_top_endo) to_delete = np.zeros((len(pts_in_top_epi),), dtype=int) - + # tree = cKDTree(pts_in_top_epi) for i in range(len(pts_in_top_epi)): if pts_in_top_epi[i] in pts_in_svc_epi or pts_in_top_epi[i] in pts_in_ivc_epi: to_delete[i] = 1 - + meshNew = dsa.WrapDataObject(top_cut_epi) meshNew.PointData.append(to_delete, "delete") - + thresh = vtk.vtkThreshold() thresh.SetInputData(meshNew.VTKObject) thresh.ThresholdByLower(0) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") thresh.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) geo_filter.Update() - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(geo_filter.GetOutput()) connect.SetExtractionModeToSpecifiedRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() @@ -1011,61 +1016,61 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.SetInputData(surface) cln.Update() surface = cln.GetOutput() - + pts_surf = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - + if tv_id_epi not in pts_surf: found_id = i break - + # delete added region id connect.DeleteSpecifiedRegion(i) connect.Update() - + connect.AddSpecifiedRegion(found_id) connect.Update() surface = connect.GetOutput() - + # Clean unused points cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() top_epi = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TOP_EPI.vtx' + fname = outdir + '/ids_TOP_EPI.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(top_epi))) f.write('extra\n') for i in top_epi: f.write('{}\n'.format(i)) f.close() - + to_delete = np.zeros((len(pts_in_top_endo),), dtype=int) for i in range(len(pts_in_top_endo)): if pts_in_top_endo[i] in pts_in_svc_endo or pts_in_top_endo[i] in pts_in_ivc_endo: to_delete[i] = 1 - + meshNew = dsa.WrapDataObject(top_cut_endo) meshNew.PointData.append(to_delete, "delete") - + thresh = vtk.vtkThreshold() thresh.SetInputData(meshNew.VTKObject) thresh.ThresholdByLower(0) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") thresh.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) geo_filter.Update() - + mv_id_endo = vtk.util.numpy_support.vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(geo_filter.GetOutput()) connect.SetExtractionModeToSpecifiedRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() @@ -1075,28 +1080,28 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.SetInputData(surface) cln.Update() surface = cln.GetOutput() - + pts_surf = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - + if tv_id_endo not in pts_surf: found_id = i break - + # delete added region id connect.DeleteSpecifiedRegion(i) connect.Update() - + connect.AddSpecifiedRegion(found_id) connect.Update() surface = connect.GetOutput() - + # Clean unused points cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() - + top_endo = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) - fname = outdir+'/ids_TOP_ENDO.vtx' + fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') f.write('{}\n'.format(len(top_endo))) f.write('extra\n') @@ -1104,5 +1109,6 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): f.write('{}\n'.format(i)) f.close() + if __name__ == '__main__': run() diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py b/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py index ed23c01..3d9c2ba 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py @@ -27,16 +27,18 @@ import os import subprocess + def generate_mesh(path, la_mesh_scale=1): # # generate mesh in vtk form subprocess.run(["meshtool", "generate", "mesh", - #"-scale=" + str(la_mesh_scale), - "-surf=" + str(path)+'.obj', + # "-scale=" + str(la_mesh_scale), + "-surf=" + str(path) + '.obj', "-ofmt=vtk", - "-outmsh="+ str(path)+'_vol']) + "-outmsh=" + str(path) + '_vol']) + if __name__ == '__main__': generate_mesh() diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py index a0c01c8..1ca6db3 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py @@ -35,9 +35,9 @@ sys.path.append('Atrial_LDRBM/Generate_Boundaries') from extract_rings import smart_reader -def write_surf_ids(outdir, name, ii): - fname = outdir+'/ids_{}.vtx'.format(name) +def write_surf_ids(outdir, name, ii): + fname = outdir + '/ids_{}.vtx'.format(name) f = open(fname, 'w') if isinstance(ii, int): f.write('1\n') @@ -50,41 +50,45 @@ def write_surf_ids(outdir, name, ii): f.write('{}\n'.format(i)) f.close() + def generate_surf_id(meshname, atrium): """The whole model""" - - vol = smart_reader(meshname+"_{}_vol.vtk".format(atrium)) + + vol = smart_reader(meshname + "_{}_vol.vtk".format(atrium)) whole_model_points_coordinate = vtk.util.numpy_support.vtk_to_numpy(vol.GetPoints().GetData()) tree = cKDTree(whole_model_points_coordinate) - epi_pts = vtk.util.numpy_support.vtk_to_numpy(smart_reader(meshname+'_{}_epi.obj'.format(atrium)).GetPoints().GetData()) + epi_pts = vtk.util.numpy_support.vtk_to_numpy( + smart_reader(meshname + '_{}_epi.obj'.format(atrium)).GetPoints().GetData()) dd, ii = tree.query(epi_pts) epi_ids = np.array(ii) - outdir = meshname+"_{}_vol_surf".format(atrium) + outdir = meshname + "_{}_vol_surf".format(atrium) if not os.path.exists(outdir): os.makedirs(outdir) - shutil.copyfile(meshname+"_{}_vol.vtk".format(atrium), outdir+'/{}.vtk'.format(atrium)) - shutil.copyfile(meshname+"_{}_epi_surf/rings_centroids.csv".format(atrium), outdir+'/rings_centroids.csv') + shutil.copyfile(meshname + "_{}_vol.vtk".format(atrium), outdir + '/{}.vtk'.format(atrium)) + shutil.copyfile(meshname + "_{}_epi_surf/rings_centroids.csv".format(atrium), outdir + '/rings_centroids.csv') write_surf_ids(outdir, "EPI", ii) - dd, ii = tree.query(vtk.util.numpy_support.vtk_to_numpy(smart_reader(meshname+'_{}_endo.obj'.format(atrium)).GetPoints().GetData())) + dd, ii = tree.query(vtk.util.numpy_support.vtk_to_numpy( + smart_reader(meshname + '_{}_endo.obj'.format(atrium)).GetPoints().GetData())) ii = np.setdiff1d(ii, epi_ids) write_surf_ids(outdir, "ENDO", ii) - fol_name = meshname+'_{}_epi_surf'.format(atrium) - - ids_files = glob(fol_name+'/ids_*') + fol_name = meshname + '_{}_epi_surf'.format(atrium) + + ids_files = glob(fol_name + '/ids_*') for i in range(len(ids_files)): ids = np.loadtxt(ids_files[i], skiprows=2, dtype=int) name = ids_files[i].split('ids_')[-1][:-4] - dd, ii = tree.query(epi_pts[ids,:]) + dd, ii = tree.query(epi_pts[ids, :]) write_surf_ids(outdir, name, ii) + if __name__ == '__main__': generate_surf_id() diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index 0a6b919..63d9180 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -9,10 +9,11 @@ sys.path.append('Atrial_LDRBM/Generate_Boundaries') from extract_rings import smart_reader + def separate_epi_endo(path, atrium): extension = path.split('.')[-1] - meshname = path[:-(len(extension)+1)] - + meshname = path[:-(len(extension) + 1)] + with open('Atrial_LDRBM/element_tag.csv') as f: tag_dict = {} reader = csv.DictReader(f) @@ -41,7 +42,7 @@ def separate_epi_endo(path, atrium): geo_filter.Update() writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname+"_{}.obj".format(atrium)) + writer.SetFileName(meshname + "_{}.obj".format(atrium)) writer.SetInputData(geo_filter.GetOutput()) writer.Write() @@ -60,7 +61,7 @@ def separate_epi_endo(path, atrium): la_epi = geo_filter.GetOutput() writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname+"_{}_epi.obj".format(atrium)) + writer.SetFileName(meshname + "_{}_epi.obj".format(atrium)) writer.SetInputData(la_epi) writer.Write() @@ -79,6 +80,6 @@ def separate_epi_endo(path, atrium): la_endo = geo_filter.GetOutput() writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname+"_{}_endo.obj".format(atrium)) + writer.SetFileName(meshname + "_{}_endo.obj".format(atrium)) writer.SetInputData(la_endo) - writer.Write() \ No newline at end of file + writer.Write() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index b055b05..ac50213 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -35,6 +35,7 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + def smart_reader(path): extension = str(path).split(".")[-1] @@ -63,214 +64,220 @@ def smart_reader(path): return output -def vtk_thr(model,mode,points_cells,array,thr1,thr2="None"): + +def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thresh = vtk.vtkThreshold() thresh.SetInputData(model) if mode == 0: thresh.ThresholdByUpper(thr1) elif mode == 1: thresh.ThresholdByLower(thr1) - elif mode ==2: + elif mode == 2: if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1,thr2) + thresh.ThresholdBetween(thr1, thr2) else: thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() thr = thresh.GetOutput() thresh = vtk.vtkThreshold() thresh.SetInputData(thr) thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() - + output = thresh.GetOutput() - + return output - - -def mark_LA_endo_elemTag(model,tag,tao_mv,tao_lpv,tao_rpv,max_phie_ab_tau_lpv,max_phie_r2_tau_lpv): - + + +def mark_LA_endo_elemTag(model, tag, tao_mv, tao_lpv, tao_rpv, max_phie_ab_tau_lpv, max_phie_r2_tau_lpv): thresh = vtk.vtkThreshold() thresh.SetInputData(model) thresh.ThresholdByUpper(tao_mv) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r") thresh.Update() - + MV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - + thresh = vtk.vtkThreshold() thresh.SetInputData(model) - thresh.ThresholdByUpper(max_phie_r2_tau_lpv+0.01) + thresh.ThresholdByUpper(max_phie_r2_tau_lpv + 0.01) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r2") thresh.Update() - + thresh = vtk.vtkThreshold() thresh.SetInputConnection(thresh.GetOutputPort()) - thresh.ThresholdByLower(max_phie_ab_tau_lpv+0.01) + thresh.ThresholdByLower(max_phie_ab_tau_lpv + 0.01) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_ab") thresh.Update() - + LAA_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - + thresh = vtk.vtkThreshold() thresh.SetInputData(model) thresh.ThresholdByLower(tao_lpv) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") thresh.Update() - + LPV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - + thresh = vtk.vtkThreshold() thresh.SetInputData(model) thresh.ThresholdByUpper(tao_rpv) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") thresh.Update() - + RPV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - + meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") endo = meshNew.VTKObject -def move_surf_along_normals(mesh, eps, direction): +def move_surf_along_normals(mesh, eps, direction): extract_surf = vtk.vtkGeometryFilter() extract_surf.SetInputData(mesh) extract_surf.Update() - + # reverse = vtk.vtkReverseSense() # reverse.ReverseCellsOn() # reverse.ReverseNormalsOn() # reverse.SetInputConnection(extract_surf.GetOutputPort()) # reverse.Update() - + # polydata = reverse.GetOutput() polydata = extract_surf.GetOutput() - + normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) normalGenerator.ComputeCellNormalsOff() normalGenerator.ComputePointNormalsOn() normalGenerator.ConsistencyOn() normalGenerator.AutoOrientNormalsOff() - normalGenerator.SplittingOff() + normalGenerator.SplittingOff() normalGenerator.Update() - + PointNormalArray = numpy_support.vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) atrial_points = numpy_support.vtk_to_numpy(polydata.GetPoints().GetData()) - - atrial_points = atrial_points + eps*direction*PointNormalArray - + + atrial_points = atrial_points + eps * direction * PointNormalArray + vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_support.numpy_to_vtk(atrial_points)) polydata.SetPoints(vtkPts) - + mesh = vtk.vtkUnstructuredGrid() mesh.DeepCopy(polydata) - + return mesh - + + def generate_bilayer(endo, epi): - extract_surf = vtk.vtkGeometryFilter() extract_surf.SetInputData(epi) extract_surf.Update() - + reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() reverse.SetInputConnection(extract_surf.GetOutputPort()) reverse.Update() - + epi = vtk.vtkUnstructuredGrid() epi.DeepCopy(reverse.GetOutput()) - + endo_pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) epi_pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - + tree = cKDTree(endo_pts) dd, ii = tree.query(epi_pts) - + lines = vtk.vtkCellArray() - + for i in range(len(endo_pts)): line = vtk.vtkLine() - line.GetPointIds().SetId(0,i); - line.GetPointIds().SetId(1,len(endo_pts)+ii[i]); + line.GetPointIds().SetId(0, i); + line.GetPointIds().SetId(1, len(endo_pts) + ii[i]); lines.InsertNextCell(line) - - points = np.concatenate((endo_pts, epi_pts[ii,:]), axis=0) + + points = np.concatenate((endo_pts, epi_pts[ii, :]), axis=0) polydata = vtk.vtkUnstructuredGrid() vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_support.numpy_to_vtk(points)) polydata.SetPoints(vtkPts) polydata.SetCells(3, lines) - - fibers = np.zeros((len(endo_pts),3),dtype="float32") - fibers[:,0] = 1 - - tag = np.ones((len(endo_pts),1), dtype=int) - tag[:,] = 100 - + + fibers = np.zeros((len(endo_pts), 3), dtype="float32") + fibers[:, 0] = 1 + + tag = np.ones((len(endo_pts), 1), dtype=int) + tag[:, ] = 100 + meshNew = dsa.WrapDataObject(polydata) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(fibers, "fiber") - fibers = np.zeros((len(endo_pts),3),dtype="float32") - fibers[:,1] = 1 + fibers = np.zeros((len(endo_pts), 3), dtype="float32") + fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - + appendFilter = vtk.vtkAppendFilter() appendFilter.AddInputData(endo) appendFilter.AddInputData(epi) appendFilter.AddInputData(meshNew.VTKObject) appendFilter.MergePointsOn() appendFilter.Update() - + bilayer = appendFilter.GetOutput() - + return bilayer + def write_bilayer(bilayer, args, job): - if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_bilayer_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_LA/LA_bilayer_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_bilayer_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_LA/LA_bilayer_with_fiber.vtu") writer.SetInputData(bilayer) writer.Write() - + pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - with open(job.ID+'/result_LA/LA_bilayer_with_fiber.pts',"w") as f: + with open(job.ID + '/result_LA/LA_bilayer_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - + tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - with open(job.ID+'/result_LA/LA_bilayer_with_fiber.elem',"w") as f: + with open(job.ID + '/result_LA/LA_bilayer_with_fiber.elem', "w") as f: f.write("{}\n".format(bilayer.GetNumberOfCells())) for i in range(bilayer.GetNumberOfCells()): cell = bilayer.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag_epi[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_epi[i])) - + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag_epi[i])) + el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - - with open(job.ID+'/result_LA/LA_bilayer_with_fiber.lon',"w") as f: + + with open(job.ID + '/result_LA/LA_bilayer_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], sheet_epi[i][0], sheet_epi[i][1], sheet_epi[i][2])) + f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], + sheet_epi[i][0], sheet_epi[i][1], + sheet_epi[i][2])) print('Done..') - + + def creat_tube_around_spline(points_data, radius): # Creat a points set spline_points = vtk.vtkPoints() @@ -413,9 +420,8 @@ def creat_tube(center1, center2, radius): def get_element_ids_around_path_within_radius(mesh, points_data, radius): - gl_ids = vtk.util.numpy_support.vtk_to_numpy(mesh.GetCellData().GetArray('Global_ids')) - + locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) locator.BuildLocator() @@ -433,15 +439,16 @@ def get_element_ids_around_path_within_radius(mesh, points_data, radius): mesh.GetPointCells(mesh_id_list.GetId(i), mesh_cell_temp_id_list) for j in range(mesh_cell_temp_id_list.GetNumberOfIds()): mesh_cell_id_list.InsertNextId(mesh_cell_temp_id_list.GetId(j)) - + ids = [] - + for i in range(mesh_cell_id_list.GetNumberOfIds()): index = mesh_cell_id_list.GetId(i) ids.append(gl_ids[index]) return ids + def assign_element_tag_around_path_within_radius(mesh, points_data, radius, tag, element_tag): locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -832,24 +839,25 @@ def get_connection_point_la_and_ra(appen_point): return la_connect_point, ra_connect_point + def point_array_mapper(mesh1, mesh2, mesh2_name, idat): - pts1 = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPoints().GetData()) pts2 = vtk.util.numpy_support.vtk_to_numpy(mesh2.GetPoints().GetData()) - + tree = cKDTree(pts1) - dd, ii = tree.query(pts2) # n_jobs=-1) - + dd, ii = tree.query(pts2) # n_jobs=-1) + meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) + data = vtk.util.numpy_support.vtk_to_numpy( + mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] data2 = np.where(np.isnan(data2), 10000, data2) # ghosts = np.zeros(meshNew.GetNumberOfPoints(), dtype=np.uint8) @@ -860,66 +868,69 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] meshNew.PointData.append(data2, idat) - + writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName("{}_with_data.vtk".format(mesh2_name.split('.vtk')[0]))# It can happen that the relative directory is given + writer.SetFileName( + "{}_with_data.vtk".format(mesh2_name.split('.vtk')[0])) # It can happen that the relative directory is given writer.SetFileTypeToBinary() writer.SetInputData(meshNew.VTKObject) writer.Write() return meshNew.VTKObject + def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): - filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(mesh1) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() centroids1_array = vtk.util.numpy_support.vtk_to_numpy(centroids1.GetData()) - + filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(mesh2) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() pts2 = vtk.util.numpy_support.vtk_to_numpy(centroids2.GetData()) - + tree = cKDTree(centroids1_array) - dd, ii = tree.query(pts2)#, n_jobs=-1) - + dd, ii = tree.query(pts2) # , n_jobs=-1) + meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetCellData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetCellData().GetArray(mesh1.GetCellData().GetArrayName(i))) + data = vtk.util.numpy_support.vtk_to_numpy( + mesh1.GetCellData().GetArray(mesh1.GetCellData().GetArrayName(i))) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] meshNew.PointData.append(data2, mesh1.GetCellData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetCellData().GetArray(idat)) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] meshNew.CellData.append(data2, idat) - + # writer = vtk.vtkUnstructuredGridWriter() # writer.SetFileName("{}_with_data.vtk".format(mesh2_name.split('.')[0])) # writer.SetInputData(meshNew.VTKObject) # writer.Write() - + return meshNew.VTKObject + def get_bachmann_path_left(appendage_basis, lpv_sup_basis): la_mv_surface = smart_reader('../../Generate_Boundaries/LA/result/la_mv_surface.vtk') la_lpv_inf_surface = smart_reader('../../Generate_Boundaries/LA/result/la_lpv_inf_surface.vtk') @@ -953,6 +964,7 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): return bb_left, appendage_basis + def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_epi): # Extract the LAA thresh = vtk.vtkThreshold() @@ -960,40 +972,40 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e thresh.ThresholdBetween(left_atrial_appendage_epi, left_atrial_appendage_epi) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") thresh.Update() - + LAA = thresh.GetOutput() - + min_r2_cell_LAA = np.argmin(vtk.util.numpy_support.vtk_to_numpy(LAA.GetCellData().GetArray('phie_r2'))) - + ptIds = vtk.vtkIdList() - + LAA.GetCellPoints(min_r2_cell_LAA, ptIds) - #sup_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) + # sup_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) sup_appendage_basis = LAA.GetPoint(ptIds.GetId(0)) - + max_r2_cell_LAA = np.argmax(vtk.util.numpy_support.vtk_to_numpy(LAA.GetCellData().GetArray('phie_r2'))) - + ptIds = vtk.vtkIdList() - + LAA.GetCellPoints(max_r2_cell_LAA, ptIds) - #bb_mv_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) + # bb_mv_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) bb_mv_laa = LAA.GetPoint(ptIds.GetId(0)) - + max_v_cell_LAA = np.argmax(vtk.util.numpy_support.vtk_to_numpy(LAA.GetCellData().GetArray('phie_v'))) - + ptIds = vtk.vtkIdList() - + LAA.GetCellPoints(max_v_cell_LAA, ptIds) - - #inf_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) + + # inf_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) inf_appendage_basis = LAA.GetPoint(ptIds.GetId(0)) - + # Extract the border of the LAA geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) geo_filter.Update() - + boundaryEdges = vtk.vtkFeatureEdges() boundaryEdges.SetInputData(geo_filter.GetOutput()) boundaryEdges.BoundaryEdgesOn() @@ -1001,13 +1013,13 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e boundaryEdges.ManifoldEdgesOff() boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - + LAA_border = boundaryEdges.GetOutput() LAA_pts_border = vtk.util.numpy_support.vtk_to_numpy(LAA_border.GetPoints().GetData()) max_dist = 0 for i in range(len(LAA_pts_border)): - if np.sqrt(np.sum((LAA_pts_border[i]-df["LIPV"].to_numpy())**2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((LAA_pts_border[i]-df["LIPV"].to_numpy())**2, axis=0)) + if np.sqrt(np.sum((LAA_pts_border[i] - df["LIPV"].to_numpy()) ** 2, axis=0)) > max_dist: + max_dist = np.sqrt(np.sum((LAA_pts_border[i] - df["LIPV"].to_numpy()) ** 2, axis=0)) LAA_pt_far_from_LIPV = LAA_pts_border[i] # Extract the MV @@ -1016,25 +1028,25 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e thresh.ThresholdBetween(mitral_valve_epi, mitral_valve_epi) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") thresh.Update() - + MV = thresh.GetOutput() # MV_pts = vtk.util.numpy_support.vtk_to_numpy(MV.GetPoints().GetData()) - + # tree = cKDTree(LAA_pts) # max_dist = np.sqrt(np.sum((df["MV"].to_numpy()-df["LAA"].to_numpy())**2, axis=0)) # dd, ii = tree.query(MV_pts, distance_upper_bound=max_dist) - + # inf_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ii[np.argmin(dd)])[0]) - + # Get the closest point to the inferior appendage base in the MV loc = vtk.vtkPointLocator() loc.SetDataSet(MV) loc.BuildLocator() - - #bb_mv_id = int(MV.GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(epi.GetPoint(bb_mv_id)))[0]) + + # bb_mv_id = int(MV.GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(epi.GetPoint(bb_mv_id)))[0]) bb_mv = MV.GetPoint(loc.FindClosestPoint(bb_mv_laa)) - + if int(vtk_version) >= 9: thresh = vtk.vtkThreshold() thresh.SetInputData(epi) @@ -1045,7 +1057,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e else: thresh = vtk.vtkThreshold() thresh.SetInputData(epi) - thresh.ThresholdByLower(left_atrial_appendage_epi-1) + thresh.ThresholdByLower(left_atrial_appendage_epi - 1) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") thresh.Update() @@ -1053,7 +1065,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e thresh = vtk.vtkThreshold() thresh.SetInputData(epi) - thresh.ThresholdByUpper(left_atrial_appendage_epi+1) + thresh.ThresholdByUpper(left_atrial_appendage_epi + 1) thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") thresh.Update() @@ -1065,23 +1077,24 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e thresh.MergePointsOn() thresh.Update() - #inf_appendage_basis_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, inf_appendage_basis_id) - #sup_appendage_basis_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, sup_appendage_basis_id) - #bb_mv_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, bb_mv_id) - + # inf_appendage_basis_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, inf_appendage_basis_id) + # sup_appendage_basis_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, sup_appendage_basis_id) + # bb_mv_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, bb_mv_id) + loc = vtk.vtkPointLocator() loc.SetDataSet(thresh.GetOutput()) - #loc.SetDataSet(epi) + # loc.SetDataSet(epi) loc.BuildLocator() LAA_pt_far_from_LIPV_id = loc.FindClosestPoint(LAA_pt_far_from_LIPV) inf_appendage_basis_id = loc.FindClosestPoint(inf_appendage_basis) sup_appendage_basis_id = loc.FindClosestPoint(sup_appendage_basis) bb_mv_id = loc.FindClosestPoint(bb_mv) - bb_left = get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) - #bb_left = get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) - #bb_left = savgol_filter(bb_left, 5, 2, mode='interp', axis =0) - + bb_left = get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, + LAA_pt_far_from_LIPV_id) + # bb_left = get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) + # bb_left = savgol_filter(bb_left, 5, 2, mode='interp', axis =0) + # new = [] # diff = 1000 # for n in range(len(bb_left)): @@ -1091,31 +1104,28 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e # tck, u = interpolate.splprep([new[:,0],new[:,1],new[:,2]], s=100) # x_knots, y_knots, z_knots = interpolate.splev(tck[0], tck) - - #u_fine = np.linspace(0,1,len(bb_left)) - #x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) + + # u_fine = np.linspace(0,1,len(bb_left)) + # x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) # bb_left = np.array([x_knots, y_knots, z_knots]).T - #bb_left = np.array([x_fine, y_fine, z_fine]).T - - - - - #u_fine = np.linspace(0,1,len(bb_left)) - #x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) - #new_points = splev(u, tck) - #window_width = 1000 - #cumsum_vec = np.cumsum(np.insert(data, 0, 0)) - #ma_vec = (cumsum_vec[window_width:] - cumsum_vec[:-window_width]) / window_width + # bb_left = np.array([x_fine, y_fine, z_fine]).T + + # u_fine = np.linspace(0,1,len(bb_left)) + # x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) + # new_points = splev(u, tck) + # window_width = 1000 + # cumsum_vec = np.cumsum(np.insert(data, 0, 0)) + # ma_vec = (cumsum_vec[window_width:] - cumsum_vec[:-window_width]) / window_width # pts = vtk.vtkPoints() # for n in range(len(bb_left)): # pts.InsertNextPoint(bb_left[n]) - + # smoothingIterations = 15 # passBand = 0.001 # featureAngle = 120.0 - + # smoother = vtk.vtkWindowedSincPolyDataFilter() # smoother.SetInputConnection(discrete->GetOutputPort()) # smoother.SetNumberOfIterations(smoothingIterations) @@ -1126,7 +1136,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e # smoother.NonManifoldSmoothingOn() # smoother.NormalizeCoordinatesOn() # smoother.Update() - + # Smooth the path fitting a spline? # new = [] # diff = 1000 @@ -1145,24 +1155,24 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e # # mesh.VPos = final # bb_left = np.array(new) - - return bb_left, thresh.GetOutput().GetPoint(inf_appendage_basis_id), thresh.GetOutput().GetPoint(sup_appendage_basis_id), thresh.GetOutput().GetPoint(LAA_pt_far_from_LIPV_id) - #return bb_left, epi.GetPoint(inf_appendage_basis_id), epi.GetPoint(sup_appendage_basis_id), epi.GetPoint(LAA_pt_far_from_LIPV_id) + + return bb_left, thresh.GetOutput().GetPoint(inf_appendage_basis_id), thresh.GetOutput().GetPoint( + sup_appendage_basis_id), thresh.GetOutput().GetPoint(LAA_pt_far_from_LIPV_id) + # return bb_left, epi.GetPoint(inf_appendage_basis_id), epi.GetPoint(sup_appendage_basis_id), epi.GetPoint(LAA_pt_far_from_LIPV_id) + def get_in_surf1_closest_point_in_surf2(surf1, surf2, pt_id_in_surf2): - loc = vtk.vtkPointLocator() loc.SetDataSet(surf1) loc.BuildLocator() return loc.FindClosestPoint(surf2.GetPoint(pt_id_in_surf2)) - + def get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id): - geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(epi) geo_filter.Update() - + bb_1_points = dijkstra_path(geo_filter.GetOutput(), sup_appendage_basis_id, LAA_pt_far_from_LIPV_id) bb_2_points = dijkstra_path(geo_filter.GetOutput(), LAA_pt_far_from_LIPV_id, inf_appendage_basis_id) bb_3_points = dijkstra_path(geo_filter.GetOutput(), inf_appendage_basis_id, bb_mv_id) @@ -1173,6 +1183,7 @@ def get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis return bb_left + def creat_center_line(start_end_point): spline_points = vtk.vtkPoints() for i in range(len(start_end_point)): @@ -1196,22 +1207,23 @@ def creat_center_line(start_end_point): def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): meshNew = dsa.WrapDataObject(tube.GetOutput()) writer = vtk.vtkPolyDataWriter() - writer.SetFileName(job.ID+"/bridges/" + str(name) + "_tube.vtk") + writer.SetFileName(job.ID + "/bridges/" + str(name) + "_tube.vtk") writer.SetInputData(meshNew.VTKObject) writer.Write() meshNew = dsa.WrapDataObject(sphere_1.GetOutput()) writer = vtk.vtkPolyDataWriter() - writer.SetFileName(job.ID+"/bridges/" + str(name) + "_sphere_1.vtk") + writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_1.vtk") writer.SetInputData(meshNew.VTKObject) writer.Write() meshNew = dsa.WrapDataObject(sphere_2.GetOutput()) writer = vtk.vtkPolyDataWriter() - writer.SetFileName(job.ID+"/bridges/" + str(name) + "_sphere_2.vtk") + writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_2.vtk") writer.SetInputData(meshNew.VTKObject) writer.Write() - + + def find_tau(model, ub, lb, low_up, scalar): k = 1 while ub - lb > 0.01: @@ -1229,11 +1241,11 @@ def find_tau(model, ub, lb, low_up, scalar): connect.SetExtractionModeToAllRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + print("Iteration: ", k) print("Value of tao: ", (ub + lb) / 2) - print("Number of regions: ", num, "\n") - + print("Number of regions: ", num, "\n") + if low_up == "low": if num == 1: ub = (ub + lb) / 2 @@ -1246,24 +1258,25 @@ def find_tau(model, ub, lb, low_up, scalar): ub = (ub + lb) / 2 k += 1 - + if low_up == "low": return lb else: return ub + def distinguish_PVs(connect, PVs, df, name1, name2): num = connect.GetNumberOfExtractedRegions() connect.SetExtractionModeToSpecifiedRegions() - + centroid1 = df[name1].to_numpy() centroid2 = df[name2].to_numpy() - + for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() single_PV = connect.GetOutput() - + # Clean unused points geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(single_PV) @@ -1274,81 +1287,81 @@ def distinguish_PVs(connect, PVs, df, name1, name2): cln.SetInputData(surface) cln.Update() surface = cln.GetOutput() - + if name1.startswith("L"): phie_v = np.max(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) elif name1.startswith("R"): phie_v = np.min(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) - if name1.startswith("L") and phie_v>0.04:# 0.025 + if name1.startswith("L") and phie_v > 0.04: # 0.025 found, val = optimize_shape_PV(surface, 10, 0) if found: - single_PV = vtk_thr(single_PV, 1,"CELLS", "phie_v", val) + single_PV = vtk_thr(single_PV, 1, "CELLS", "phie_v", val) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(single_PV) geo_filter.Update() surface = geo_filter.GetOutput() - elif name1.startswith("R") and phie_v<0.9: # 0.975 + elif name1.startswith("R") and phie_v < 0.9: # 0.975 found, val = optimize_shape_PV(surface, 10, 1) if found: - single_PV = vtk_thr(single_PV, 0,"CELLS", "phie_v", val) + single_PV = vtk_thr(single_PV, 0, "CELLS", "phie_v", val) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(single_PV) geo_filter.Update() surface = geo_filter.GetOutput() - + centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(surface) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() - + c_mass = centerOfMassFilter.GetCenter() - - centroid1_d = np.sqrt(np.sum((np.array(centroid1) - np.array(c_mass))**2, axis=0)) - centroid2_d = np.sqrt(np.sum((np.array(centroid2) - np.array(c_mass))**2, axis=0)) - + + centroid1_d = np.sqrt(np.sum((np.array(centroid1) - np.array(c_mass)) ** 2, axis=0)) + centroid2_d = np.sqrt(np.sum((np.array(centroid2) - np.array(c_mass)) ** 2, axis=0)) + if centroid1_d < centroid2_d: PVs[name1] = vtk.util.numpy_support.vtk_to_numpy(single_PV.GetCellData().GetArray('Global_ids')) else: PVs[name2] = vtk.util.numpy_support.vtk_to_numpy(single_PV.GetCellData().GetArray('Global_ids')) - + connect.DeleteSpecifiedRegion(i) connect.Update() - + return PVs + def optimize_shape_PV(surface, num, bound): - if bound == 0: phie_v = np.max(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) else: phie_v = np.min(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) - + arr = np.linspace(bound, phie_v, num) c_mass_l = [] found = 0 - for l in range(num-1): + for l in range(num - 1): if bound == 0: - out = vtk_thr(surface, 2,"CELLS", "phie_v", arr[l], arr[l+1]) + out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l], arr[l + 1]) else: - out = vtk_thr(surface, 2,"CELLS", "phie_v", arr[l+1], arr[l]) + out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l + 1], arr[l]) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(out) geo_filter.Update() - + centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(geo_filter.GetOutput()) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() - + c_mass_l.append(centerOfMassFilter.GetCenter()) - v1 = np.array(c_mass_l[0])-np.array(c_mass_l[1]) - for l in range(1,num-2): - v2 = np.array(c_mass_l[l])-np.array(c_mass_l[l+1]) - if 1-cosine(v1, v2) < 0: + v1 = np.array(c_mass_l[0]) - np.array(c_mass_l[1]) + for l in range(1, num - 2): + v2 = np.array(c_mass_l[l]) - np.array(c_mass_l[l + 1]) + if 1 - cosine(v1, v2) < 0: found = 1 break - - return found, arr[l-1] \ No newline at end of file + + return found, arr[l - 1] diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py b/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py index 9d7db06..d3de781 100755 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py @@ -29,26 +29,27 @@ from carputils import tools from vtk.numpy_interface import dataset_adapter as dsa + def parser(): # Generate the standard command line parser parser = tools.standard_parser() # Add arguments parser.add_argument('--mesh1', - type=str, - default="", - help='path to meshname') + type=str, + default="", + help='path to meshname') parser.add_argument('--mesh2', - type=str, - default="", - help='path to meshname') + type=str, + default="", + help='path to meshname') parser.add_argument('--idat', - type=str, - default="", - help='input mesh format') + type=str, + default="", + help='input mesh format') parser.add_argument('--odat', - type=str, - default="", - help='input mesh format') + type=str, + default="", + help='input mesh format') parser.add_argument('--pts_or_cells', default='points', choices=['points', @@ -57,21 +58,23 @@ def parser(): return parser + def jobID(args): ID = '{}_fibers'.format(args.mesh1.split('/')[-1]) return ID + @tools.carpexample(parser, jobID) def run(args, job): - mesh1 = Method.smart_reader(args.mesh1) - + mesh2 = Method.smart_reader(args.mesh2) - + if args.pts_or_cells == "points": Method.point_array_mapper(mesh1, mesh2, args.mesh2, args.idat) else: Method.cell_array_mapper(mesh1, mesh2, args.mesh2, args.idat) - + + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py index ddfa0a0..2137b55 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py @@ -29,6 +29,7 @@ from vtk.numpy_interface import dataset_adapter as dsa import os + def la_calculate_gradient(args, model, job): name_list = ['phi', 'r', 'v', 'ab'] @@ -40,13 +41,14 @@ def la_calculate_gradient(args, model, job): for var in name_list: print('Calculating the gradient of ' + str(var) + '...') - if var =='phi': + if var == 'phi': # using the vtkGradientFilter to calculate the gradient if args.mesh_type == "vol": gradientFilter = vtk.vtkGradientFilter() gradientFilter.SetInputConnection(pointDataToCellData.GetOutputPort()) - gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "phie_"+str(var)) - gradientFilter.SetResultArrayName('grad_'+str(var)) + gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, + "phie_" + str(var)) + gradientFilter.SetResultArrayName('grad_' + str(var)) gradientFilter.Update() LA_gradient = gradientFilter.GetOutput() else: @@ -57,34 +59,34 @@ def la_calculate_gradient(args, model, job): normalFilter.SplittingOff() normalFilter.Update() LA_gradient = normalFilter.GetOutput() - LA_gradient.GetCellData().GetArray("Normals").SetName('grad_'+str(var)) - + LA_gradient.GetCellData().GetArray("Normals").SetName('grad_' + str(var)) + else: gradientFilter = vtk.vtkGradientFilter() gradientFilter.SetInputData(LA_gradient) - gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "phie_"+str(var)) - gradientFilter.SetResultArrayName('grad_'+str(var)) + gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, + "phie_" + str(var)) + gradientFilter.SetResultArrayName('grad_' + str(var)) gradientFilter.Update() LA_gradient = gradientFilter.GetOutput() - + print('Calculating the gradient of ' + str(var) + '... Done!') - + output = vtk.vtkUnstructuredGrid() output.DeepCopy(LA_gradient) if args.debug == 1: # write - simid = job.ID+"/gradient" + simid = job.ID + "/gradient" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) + print("Successfully created the directory %s " % simid) # write the file as vtk writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(simid+"/LA_with_lp_res_gradient.vtk") + writer.SetFileName(simid + "/LA_with_lp_res_gradient.vtk") writer.SetInputData(output) writer.Write() - - return output + return output diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index ff91a4f..ba9b032 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -38,21 +38,21 @@ EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] - + + def la_generate_fiber(model, args, job): - # size(Radius) of Bachmann Bundle in mm - w_bb = 2*args.scale - - simid = job.ID+"/result_LA" + w_bb = 2 * args.scale + + simid = job.ID + "/result_LA" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) - - with open(os.path.join(EXAMPLE_DIR,'../../element_tag.csv')) as f: + print("Successfully created the directory %s " % simid) + + with open(os.path.join(EXAMPLE_DIR, '../../element_tag.csv')) as f: tag_dict = {} reader = csv.DictReader(f) for row in reader: @@ -101,7 +101,7 @@ def la_generate_fiber(model, args, job): r_grad = model.GetCellData().GetArray('grad_r') r = vtk.util.numpy_support.vtk_to_numpy(r) r_grad = vtk.util.numpy_support.vtk_to_numpy(r_grad) - + # r2 r2 = model.GetCellData().GetArray('phie_r2') r2 = vtk.util.numpy_support.vtk_to_numpy(r2) @@ -110,7 +110,7 @@ def la_generate_fiber(model, args, job): if args.mesh_type == "vol": phie = model.GetCellData().GetArray('phie_phi') phie = vtk.util.numpy_support.vtk_to_numpy(phie) - + phie_grad = model.GetCellData().GetArray('grad_phi') phie_grad = vtk.util.numpy_support.vtk_to_numpy(phie_grad) @@ -124,18 +124,18 @@ def la_generate_fiber(model, args, job): else: cellid.SetIdsArrayName('Global_ids') cellid.Update() - + model = cellid.GetOutput() - - df = pd.read_csv(args.mesh+"_surf/rings_centroids.csv") - + + df = pd.read_csv(args.mesh + "_surf/rings_centroids.csv") + # LPV lb = 0 ub = 0.4 tao_lpv = Method.find_tau(model, ub, lb, "low", "phie_v") print('Calculating tao_lpv done! tap_lpv = ', tao_lpv) - - thr = Method.vtk_thr(model, 1, "CELLS","phie_v",tao_lpv) + + thr = Method.vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) connect = vtk.vtkConnectivityFilter() connect.SetInputData(thr) connect.SetExtractionModeToAllRegions() @@ -147,46 +147,46 @@ def la_generate_fiber(model, args, job): model = laplace_0_1(args, job, model, "RPV", "LAA", "phie_ab2") - thr = Method.vtk_thr(model, 1, "CELLS","phie_v", tao_lpv) - #thr = Method.vtk_thr(model, 1, "CELLS","phie_v", 0.35) - #found, val = Method.optimize_shape_PV(thr, 10, 0) - #print('Calculating opt_tao_lpv done! tap_lpv = ', val) - #if val!=0.35: + thr = Method.vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) + # thr = Method.vtk_thr(model, 1, "CELLS","phie_v", 0.35) + # found, val = Method.optimize_shape_PV(thr, 10, 0) + # print('Calculating opt_tao_lpv done! tap_lpv = ', val) + # if val!=0.35: # thr = Method.vtk_thr(model, 1, "CELLS","phie_v",val) - + phie_r2_tau_lpv = vtk.util.numpy_support.vtk_to_numpy(thr.GetCellData().GetArray('phie_r2')) max_phie_r2_tau_lpv = np.max(phie_r2_tau_lpv) - + phie_ab_tau_lpv = vtk.util.numpy_support.vtk_to_numpy(thr.GetPointData().GetArray('phie_ab2')) max_phie_ab_tau_lpv = np.max(phie_ab_tau_lpv) - print("max_phie_r2_tau_lpv ",max_phie_r2_tau_lpv) - print("max_phie_ab_tau_lpv ",max_phie_ab_tau_lpv) - + print("max_phie_r2_tau_lpv ", max_phie_r2_tau_lpv) + print("max_phie_ab_tau_lpv ", max_phie_ab_tau_lpv) + # RPV lb = 0.6 ub = 1 tao_rpv = Method.find_tau(model, ub, lb, "up", "phie_v") print('Calculating tao_rpv done! tap_rpv = ', tao_rpv) - - thr = Method.vtk_thr(model, 0, "CELLS","phie_v",tao_rpv) + + thr = Method.vtk_thr(model, 0, "CELLS", "phie_v", tao_rpv) connect = vtk.vtkConnectivityFilter() connect.SetInputData(thr) connect.SetExtractionModeToAllRegions() connect.Update() - + # Distinguish between RIPV and RSPV PVs = Method.distinguish_PVs(connect, PVs, df, "RIPV", "RSPV") start_time = datetime.datetime.now() print('Calculating fibers... ' + str(start_time)) - + #### Bundles selection #### # # Volume mesh # if 0:# args.mesh_type == 'vol': # tag = np.zeros(len(r)) - + # for i in range(len(ab_grad)): # # tagging endo-layer # if phie[i] <= 0.5: @@ -225,32 +225,32 @@ def la_generate_fiber(model, args, job): # tag[i] = superior_right_pulmonary_vein_epi # else: # tag[i] = left_atrial_wall_epi - + # meshNew = dsa.WrapDataObject(model) # meshNew.CellData.append(tag, "elemTag") # model = meshNew.VTKObject - + # # normlize the gradient phie # abs_phie_grad = np.linalg.norm(phie_grad, axis=1, keepdims=True) # abs_phie_grad = np.where(abs_phie_grad != 0, abs_phie_grad, 1) # phie_grad_norm = phie_grad / abs_phie_grad - + # ##### Local coordinate system ##### # # et # et = phie_grad_norm # print('############### et ###############') # print(et) - + # # k # k = ab_grad # print('############### k ###############') # print(k) - + # # en # en = ab_grad # #for i in range(len(k)): # # en[i] = k[i] - np.dot(k[i], et[i]) * et[i] - + # en = k - np.dot(k, et) * et # # normalize the en # abs_en = np.linalg.norm(en, axis=1, keepdims=True) @@ -258,12 +258,12 @@ def la_generate_fiber(model, args, job): # en = en / abs_en # print('############### en ###############') # print(en) - + # # el # el = np.cross(en, et) # print('############### el ###############') # print(el) - + # abs_v_grad = np.linalg.norm(v_grad, axis=1, keepdims=True) # abs_v_grad = np.where(abs_v_grad != 0, abs_v_grad, 1) # v_grad_norm = v_grad / abs_v_grad @@ -271,18 +271,18 @@ def la_generate_fiber(model, args, job): # for i in range(len(v_grad_norm)): # if phie[i] < 0.5 and v[i] <= 0.2: # el[i] = v_grad_norm[i] - + # end_time = datetime.datetime.now() # running_time = end_time - start_time # print('Calculating fibers... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - + # reader = vtk.vtkUnstructuredGridReader() # reader.SetFileName('Mesh/LA_mesh.vtk') # reader.Update() # model = reader.GetOutput() - + # print("Creating bachmann bundles...") - + # # Extract surface # geo_filter = vtk.vtkGeometryFilter() # geo_filter.SetInputData(model) @@ -291,48 +291,47 @@ def la_generate_fiber(model, args, job): # # Get only epi # thr = Method.vtk_thr(geo_filter.GetOutput(), 2, "CELLS","elemTag",mitral_valve_epi, left_atrial_roof_epi) # # Bachmann Bundle - + # # Get ending point of wide BB # # Extract the MV # thr = Method.vtk_thr(thr, 2, "CELLS","elemTag",mitral_valve_epi, mitral_valve_epi) - + # # Get the closest point to the inferior appendage base in the MV # loc = vtk.vtkPointLocator() # loc.SetDataSet(thr) # loc.BuildLocator() - + # bb_mv_id = int(model.GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(model.GetPoint(inf_appendage_basis_id)))[0]) - + # thresh = vtk.vtkThreshold() # thresh.SetInputData(model) # thresh.ThresholdBetween(max_phie_ab_tau_lpv-0.1, max_phie_ab_tau_lpv+0.1) # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_ab") # thresh.Update() - + # loc = vtk.vtkPointLocator() # loc.SetDataSet(thresh.GetOutput()) # loc.BuildLocator() - + # inf_appendage_basis_id = int(thresh.GetOutput().GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(df["MV"].to_numpy()))[0]) - + # thresh = vtk.vtkThreshold() # thresh.SetInputData(thresh.GetOutput()) # thresh.ThresholdBetween(max_phie_r2_tau_lpv-0.1, max_phie_r2_tau_lpv+0.1) # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r2") # thresh.Update() - + # loc = vtk.vtkPointLocator() # loc.SetDataSet(thresh.GetOutput()) # loc.BuildLocator() - + # sup_appendage_basis_id = int(thresh.GetOutput().GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(df["LAA"].to_numpy()))[0]) - - + # bb_left = Method.get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id) - + # tag = Method.assign_element_tag_around_path_within_radius(model, bb_left, 2, tag, bachmann_bundel_left) # el = Method.assign_element_fiber_around_path_within_radius(model, bb_left, 2, el, smooth=True) - + # # # Bachmann_Bundle internal connection # # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(la_appex_point) # # la_connect_point = np.asarray(la_connect_point) @@ -341,7 +340,7 @@ def la_generate_fiber(model, args, job): # # path_bb_ra = Method.creat_center_line(path_start_end) # # tag = Method.assign_element_tag_around_path_within_radius(model, path_bb_ra, 2, tag, bachmann_bundel_left) # # el = Method.assign_element_fiber_around_path_within_radius(model, path_bb_ra, 2, el, smooth=True) - + # print("Creating bachmann bundles... done") # abs_el = np.linalg.norm(el, axis=1, keepdims=True) # interpolate_arr = np.asarray([0, 0, 1]) @@ -349,16 +348,16 @@ def la_generate_fiber(model, args, job): # print('There is',len(index),'zero vector(s).') # for var in index: # el[var[0]] = interpolate_arr - + # #### save the result into vtk #### # start_time = datetime.datetime.now() # print('Writinga as LA_with_fiber... ' + str(start_time)) - + # # fiber_data = vtk.util.numpy_support.numpy_to_vtk(el, deep=True, array_type=vtk.VTK_DOUBLE) # # fiber_data.SetNumberOfComponents(3) # # fiber_data.SetName("fiber") # # model.GetCellData().SetVectors(fiber_data) # AddArray(fiber_data) - + # # tag_data = vtk.util.numpy_support.numpy_to_vtk(tag, deep=True, array_type=vtk.VTK_DOUBLE) # # tag_data.SetNumberOfComponents(1) # # tag_data.SetName("elemTag") @@ -369,28 +368,27 @@ def la_generate_fiber(model, args, job): # meshNew = dsa.WrapDataObject(model) # meshNew.CellData.append(tag, "elemTag") # meshNew.CellData.append(el, "fiber") - + # model = meshNew.VTKObject - + # end_time = datetime.datetime.now() # running_time = end_time - start_time # print('Writing as LA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - - + # Bilayer mesh if args.mesh_type == 'bilayer': epi = vtk.vtkUnstructuredGrid() epi.DeepCopy(model) - + tag_epi = np.zeros(len(r), dtype=int) tag_epi[:] = left_atrial_wall_epi tag_endo = np.zeros(len(r), dtype=int) tag_endo[:] = left_atrial_wall_endo - else: # Volume mesh - tag = np.ones(len(r), dtype=int)*left_atrial_wall_epi + else: # Volume mesh + tag = np.ones(len(r), dtype=int) * left_atrial_wall_epi - epi = Method.vtk_thr(model,0,"CELLS","phie_phi",0.5) + epi = Method.vtk_thr(model, 0, "CELLS", "phie_phi", 0.5) epi_ids = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('Global_ids')) @@ -399,17 +397,17 @@ def la_generate_fiber(model, args, job): endo_ids = np.setdiff1d(endo_ids, epi_ids) tag[endo_ids] = left_atrial_wall_endo - - LAA_s = Method.vtk_thr(model,0,"CELLS","phie_r2",max_phie_r2_tau_lpv+0.01) - - LAA_s = Method.vtk_thr(LAA_s,0,"POINTS","phie_ab2",max_phie_ab_tau_lpv-0.03) - + + LAA_s = Method.vtk_thr(model, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv + 0.01) + + LAA_s = Method.vtk_thr(LAA_s, 0, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03) + ## Optimize shape of LAA solving a laplacian with 0 in LAA and 1 in the boundary of LAA_s - - LAA_bb = Method.vtk_thr(model,2,"POINTS","phie_ab2",max_phie_ab_tau_lpv-0.03, max_phie_ab_tau_lpv+0.01) - + + LAA_bb = Method.vtk_thr(model, 2, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03, max_phie_ab_tau_lpv + 0.01) + LAA_bb_ids = vtk.util.numpy_support.vtk_to_numpy(LAA_bb.GetPointData().GetArray('Global_ids')) - + MV_ring_ids = np.loadtxt('{}_surf/ids_MV.vtx'.format(args.mesh), skiprows=2, dtype=int) LAA_bb_ids = np.append(LAA_bb_ids, MV_ring_ids) @@ -421,50 +419,49 @@ def la_generate_fiber(model, args, job): for i in LAA_bb_ids: f.write('{}\n'.format(i)) f.close() - + LAA_s = laplace_0_1(args, job, model, "LAA", "LAA_bb", "phie_ab3") - - LAA_s = Method.vtk_thr(LAA_s,1,"POINTS","phie_ab3",0.95) - + + LAA_s = Method.vtk_thr(LAA_s, 1, "POINTS", "phie_ab3", 0.95) + ring_ids = np.loadtxt('{}_surf/'.format(args.mesh) + 'ids_MV.vtx', skiprows=2, dtype=int) - - rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids,:] - - MV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4*args.scale) - + + rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] + + MV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) + LAA_ids = vtk.util.numpy_support.vtk_to_numpy(LAA_s.GetCellData().GetArray('Global_ids')) - + # tagging endo-layer if args.mesh_type == 'bilayer': tag_endo[MV_ids] = mitral_valve_endo ab_grad[MV_ids] = r_grad[MV_ids] - + tag_endo[LAA_ids] = left_atrial_appendage_endo - + tag_endo[PVs["RIPV"]] = inferior_right_pulmonary_vein_endo tag_endo[PVs["LIPV"]] = inferior_left_pulmonary_vein_endo - + tag_endo[PVs["RSPV"]] = superior_right_pulmonary_vein_endo tag_endo[PVs["LSPV"]] = superior_left_pulmonary_vein_endo - + ab_grad[PVs["RIPV"]] = v_grad[PVs["RIPV"]] ab_grad[PVs["LIPV"]] = v_grad[PVs["LIPV"]] ab_grad[PVs["RSPV"]] = v_grad[PVs["RSPV"]] ab_grad[PVs["LSPV"]] = v_grad[PVs["LSPV"]] - + # tagging epi-layer - + tag_epi[MV_ids] = mitral_valve_epi - + tag_epi[LAA_ids] = left_atrial_appendage_epi tag_epi[PVs["RIPV"]] = inferior_right_pulmonary_vein_epi tag_epi[PVs["LIPV"]] = inferior_left_pulmonary_vein_epi - + tag_epi[PVs["RSPV"]] = superior_right_pulmonary_vein_epi tag_epi[PVs["LSPV"]] = superior_left_pulmonary_vein_epi - - + ab_grad_epi = np.copy(ab_grad) else: @@ -472,10 +469,10 @@ def la_generate_fiber(model, args, job): MV_ids_endo = np.intersect1d(MV_ids, endo_ids) tag[MV_ids_endo] = mitral_valve_endo ab_grad[MV_ids_endo] = r_grad[MV_ids_endo] - + LAA_ids_endo = np.intersect1d(LAA_ids, endo_ids) tag[LAA_ids_endo] = left_atrial_appendage_endo - + RIPV_ids_endo = np.intersect1d(PVs["RIPV"], endo_ids) tag[RIPV_ids_endo] = inferior_right_pulmonary_vein_endo LIPV_ids_endo = np.intersect1d(PVs["LIPV"], endo_ids) @@ -484,17 +481,17 @@ def la_generate_fiber(model, args, job): tag[RSPV_ids_endo] = superior_right_pulmonary_vein_endo LSPV_ids_endo = np.intersect1d(PVs["LSPV"], endo_ids) tag[LSPV_ids_endo] = superior_left_pulmonary_vein_endo - + ab_grad[RIPV_ids_endo] = v_grad[RIPV_ids_endo] ab_grad[RSPV_ids_endo] = v_grad[RSPV_ids_endo] ab_grad[LIPV_ids_endo] = v_grad[LIPV_ids_endo] ab_grad[LSPV_ids_endo] = v_grad[LSPV_ids_endo] - + # tagging epi-layer - + MV_ids_epi = np.intersect1d(MV_ids, epi_ids) tag[MV_ids_epi] = mitral_valve_epi - + LAA_ids_epi = np.intersect1d(LAA_ids, epi_ids) tag[LAA_ids_epi] = left_atrial_appendage_epi @@ -506,21 +503,21 @@ def la_generate_fiber(model, args, job): tag[RSPV_ids_epi] = superior_right_pulmonary_vein_epi LSPV_ids_epi = np.intersect1d(PVs["LSPV"], epi_ids) tag[LSPV_ids_epi] = superior_left_pulmonary_vein_epi - + # Get epi bundle band - - lpv_mean = np.mean([df["LIPV"].to_numpy(), df["LSPV"].to_numpy()], axis = 0) - rpv_mean = np.mean([df["RIPV"].to_numpy(), df["RSPV"].to_numpy()], axis = 0) + + lpv_mean = np.mean([df["LIPV"].to_numpy(), df["LSPV"].to_numpy()], axis=0) + rpv_mean = np.mean([df["RIPV"].to_numpy(), df["RSPV"].to_numpy()], axis=0) mv_mean = df["MV"].to_numpy() - + v1 = rpv_mean - mv_mean v2 = lpv_mean - mv_mean norm = np.cross(v2, v1) - + norm = norm / np.linalg.norm(norm) - - band_s = Method.vtk_thr(epi,0,"CELLS","phie_r2",max_phie_r2_tau_lpv) - + + band_s = Method.vtk_thr(epi, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv) + plane = vtk.vtkPlane() plane.SetNormal(norm[0], norm[1], norm[2]) plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) @@ -529,16 +526,17 @@ def la_generate_fiber(model, args, job): meshExtractFilter.SetInputData(band_s) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - - band_cell_ids = vtk.util.numpy_support.vtk_to_numpy(meshExtractFilter.GetOutput().GetCellData().GetArray('Global_ids')) - + + band_cell_ids = vtk.util.numpy_support.vtk_to_numpy( + meshExtractFilter.GetOutput().GetCellData().GetArray('Global_ids')) + if args.mesh_type == "bilayer": ab_grad_epi[band_cell_ids] = r_grad[band_cell_ids] meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag_endo, "elemTag") endo = meshNew.VTKObject - + meshNew = dsa.WrapDataObject(epi) meshNew.CellData.append(tag_epi, "elemTag") epi = meshNew.VTKObject @@ -555,15 +553,15 @@ def la_generate_fiber(model, args, job): k_endo = ab_grad k_epi = ab_grad_epi print('############### k ###############') - - en_endo = k_endo - et*np.sum(k_endo*et,axis=1).reshape(len(et),1) - en_epi = k_epi - et*np.sum(k_epi*et,axis=1).reshape(len(et),1) - + + en_endo = k_endo - et * np.sum(k_endo * et, axis=1).reshape(len(et), 1) + en_epi = k_epi - et * np.sum(k_epi * et, axis=1).reshape(len(et), 1) + # normalize the en abs_en = np.linalg.norm(en_endo, axis=1, keepdims=True) abs_en = np.where(abs_en != 0, abs_en, 1) en_endo = en_endo / abs_en - + abs_en = np.linalg.norm(en_epi, axis=1, keepdims=True) abs_en = np.where(abs_en != 0, abs_en, 1) en_epi = en_epi / abs_en @@ -577,73 +575,77 @@ def la_generate_fiber(model, args, job): abs_v_grad = np.linalg.norm(v_grad, axis=1, keepdims=True) abs_v_grad = np.where(abs_v_grad != 0, abs_v_grad, 1) v_grad_norm = v_grad / abs_v_grad - + ### Subendo PVs bundle selection - + el_endo[PVs["LIPV"]] = v_grad_norm[PVs["LIPV"]] el_endo[PVs["LSPV"]] = v_grad_norm[PVs["LSPV"]] - + # for i in range(len(v_grad_norm)): # if v[i] <= 0.2: # el_endo[i] = v_grad_norm[i] end_time = datetime.datetime.now() - - el_endo = np.where(el_endo == [0,0,0], [1,0,0], el_endo).astype("float32") - + + el_endo = np.where(el_endo == [0, 0, 0], [1, 0, 0], el_endo).astype("float32") + sheet_endo = np.cross(el_endo, et) - sheet_endo = np.where(sheet_endo == [0,0,0], [1,0,0], sheet_endo).astype("float32") - - for i in range(endo.GetPointData().GetNumberOfArrays()-1, -1, -1): + sheet_endo = np.where(sheet_endo == [0, 0, 0], [1, 0, 0], sheet_endo).astype("float32") + + for i in range(endo.GetPointData().GetNumberOfArrays() - 1, -1, -1): endo.GetPointData().RemoveArray(endo.GetPointData().GetArrayName(i)) - - for i in range(endo.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(endo.GetCellData().GetNumberOfArrays() - 1, -1, -1): endo.GetCellData().RemoveArray(endo.GetCellData().GetArrayName(i)) - + meshNew = dsa.WrapDataObject(endo) meshNew.CellData.append(tag_endo, "elemTag") meshNew.CellData.append(el_endo, "fiber") meshNew.CellData.append(sheet_endo, "sheet") if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_LA/LA_endo_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_LA/LA_endo_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - + pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) - with open(job.ID+'/result_LA/LA_endo_with_fiber.pts',"w") as f: + with open(job.ID + '/result_LA/LA_endo_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - with open(job.ID+'/result_LA/LA_endo_with_fiber.elem',"w") as f: + with open(job.ID + '/result_LA/LA_endo_with_fiber.elem', "w") as f: f.write("{}\n".format(endo.GetNumberOfCells())) for i in range(endo.GetNumberOfCells()): cell = endo.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_endo[i])) + f.write( + "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_endo[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_endo[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag_endo[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_endo[i])) - - - with open(job.ID+'/result_LA/LA_endo_with_fiber.lon',"w") as f: + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag_endo[i])) + + with open(job.ID + '/result_LA/LA_endo_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el_endo)): - f.write("{} {} {} {} {} {}\n".format(el_endo[i][0], el_endo[i][1], el_endo[i][2], sheet_endo[i][0], sheet_endo[i][1], sheet_endo[i][2])) - + f.write("{} {} {} {} {} {}\n".format(el_endo[i][0], el_endo[i][1], el_endo[i][2], sheet_endo[i][0], + sheet_endo[i][1], sheet_endo[i][2])) + running_time = end_time - start_time - + print('Calculating fibers... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') else: ab_grad[band_cell_ids] = r_grad[band_cell_ids] - + # normalize the gradient phie phie_grad_norm = phie_grad @@ -655,14 +657,14 @@ def la_generate_fiber(model, args, job): # k k = ab_grad print('############### k ###############') - - en = k - et*np.sum(k*et,axis=1).reshape(len(et),1) - + + en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) + # normalize the en abs_en = np.linalg.norm(en, axis=1, keepdims=True) abs_en = np.where(abs_en != 0, abs_en, 1) en = en / abs_en - + print('############### en ###############') # el @@ -672,18 +674,18 @@ def la_generate_fiber(model, args, job): abs_v_grad = np.linalg.norm(v_grad, axis=1, keepdims=True) abs_v_grad = np.where(abs_v_grad != 0, abs_v_grad, 1) v_grad_norm = v_grad / abs_v_grad - + ### Subendo PVs bundle selection - + el[LIPV_ids_endo] = v_grad_norm[LIPV_ids_endo] el[LSPV_ids_endo] = v_grad_norm[LSPV_ids_endo] - + # for i in range(len(v_grad_norm)): # if v[i] <= 0.2: # el_endo[i] = v_grad_norm[i] end_time = datetime.datetime.now() - + meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") @@ -702,7 +704,7 @@ def la_generate_fiber(model, args, job): # writer.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtu") # writer.SetInputData(meshNew.VTKObject) # writer.Write() - + # pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) # with open(job.ID+'/result_LA/LA_endo_with_fiber.pts',"w") as f: # f.write("{}\n".format(len(pts))) @@ -719,29 +721,28 @@ def la_generate_fiber(model, args, job): # f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_endo[i])) # elif cell.GetNumberOfPoints() == 4: # f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_endo[i])) - - + # with open(job.ID+'/result_LA/LA_endo_with_fiber.lon',"w") as f: # f.write("2\n") # for i in range(len(el_endo)): # f.write("{} {} {} {} {} {}\n".format(el_endo[i][0], el_endo[i][1], el_endo[i][2], sheet_endo[i][0], sheet_endo[i][1], sheet_endo[i][2])) - + running_time = end_time - start_time - + print('Calculating fibers... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') print("Creating bachmann bundles...") # Bachmann Bundle - - if args.mesh_type == "vol": # Extract epicardial surface - + + if args.mesh_type == "vol": # Extract epicardial surface + # epi_surf = Method.smart_reader(args.mesh[:-4]+'_epi.obj') # epi_surf = Method.cell_array_mapper(model, epi_surf, "elemTag", "all") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) geo_filter.Update() surf = geo_filter.GetOutput() - epi_surf = Method.vtk_thr(surf,0,"CELLS","phie_phi",0.5) + epi_surf = Method.vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) epi_surf_ids = vtk.util.numpy_support.vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) # epi_surf_id_list = vtk.vtkIdList() @@ -753,26 +754,37 @@ def la_generate_fiber(model, args, job): # extract.Update() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(epi_surf) - #geo_filter.PassThroughCellIdsOn() + # geo_filter.PassThroughCellIdsOn() geo_filter.Update() epi_surf = geo_filter.GetOutput() if args.mesh_type == "bilayer": - bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_epi) + bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi, df, + left_atrial_appendage_epi, + mitral_valve_epi) tag_epi = Method.assign_element_tag_around_path_within_radius(epi, bb_left, w_bb, tag_epi, bachmann_bundel_left) el_epi = Method.assign_element_fiber_around_path_within_radius(epi, bb_left, w_bb, el_epi, smooth=True) else: - bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi_surf, df, left_atrial_appendage_epi, mitral_valve_epi) - tag[epi_surf_ids] = Method.assign_element_tag_around_path_within_radius(epi_surf, bb_left, w_bb, vtk.util.numpy_support.vtk_to_numpy(epi_surf.GetCellData().GetArray('elemTag')), bachmann_bundel_left) - el[epi_surf_ids] = Method.assign_element_fiber_around_path_within_radius(epi_surf, bb_left, w_bb, vtk.util.numpy_support.vtk_to_numpy(epi_surf.GetCellData().GetArray('fiber')), smooth=True) - + bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi_surf, df, + left_atrial_appendage_epi, + mitral_valve_epi) + tag[epi_surf_ids] = Method.assign_element_tag_around_path_within_radius(epi_surf, bb_left, w_bb, + vtk.util.numpy_support.vtk_to_numpy( + epi_surf.GetCellData().GetArray( + 'elemTag')), + bachmann_bundel_left) + el[epi_surf_ids] = Method.assign_element_fiber_around_path_within_radius(epi_surf, bb_left, w_bb, + vtk.util.numpy_support.vtk_to_numpy( + epi_surf.GetCellData().GetArray( + 'fiber')), smooth=True) + df["LAA_basis_inf"] = LAA_basis_inf df["LAA_basis_sup"] = LAA_basis_sup df["LAA_far_from_LIPV"] = LAA_far_from_LIPV - - df.to_csv(args.mesh+"_surf/rings_centroids.csv", float_format="%.2f", index = False) - + + df.to_csv(args.mesh + "_surf/rings_centroids.csv", float_format="%.2f", index=False) + # # Bachmann_Bundle internal connection # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(la_appex_point) # la_connect_point = np.asarray(la_connect_point) @@ -784,18 +796,18 @@ def la_generate_fiber(model, args, job): print("Creating bachmann bundles... done") if args.mesh_type == "bilayer": - el_epi = np.where(el_epi == [0,0,0], [1,0,0], el_epi).astype("float32") + el_epi = np.where(el_epi == [0, 0, 0], [1, 0, 0], el_epi).astype("float32") #### save the result into vtk #### start_time = datetime.datetime.now() print('Writinga as LA_with_fiber... ' + str(start_time)) - + sheet_epi = np.cross(el_epi, et) - sheet_epi = np.where(sheet_epi == [0,0,0], [1,0,0], sheet_epi).astype("float32") - - for i in range(epi.GetPointData().GetNumberOfArrays()-1, -1, -1): + sheet_epi = np.where(sheet_epi == [0, 0, 0], [1, 0, 0], sheet_epi).astype("float32") + + for i in range(epi.GetPointData().GetNumberOfArrays() - 1, -1, -1): epi.GetPointData().RemoveArray(epi.GetPointData().GetArrayName(i)) - - for i in range(epi.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(epi.GetCellData().GetNumberOfArrays() - 1, -1, -1): epi.GetCellData().RemoveArray(epi.GetCellData().GetArrayName(i)) meshNew = dsa.WrapDataObject(epi) @@ -804,59 +816,66 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(sheet_epi, "sheet") if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_epi_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_LA/LA_epi_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_epi_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_LA/LA_epi_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - + pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - with open(job.ID+'/result_LA/LA_epi_with_fiber.pts',"w") as f: + with open(job.ID + '/result_LA/LA_epi_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - with open(job.ID+'/result_LA/LA_epi_with_fiber.elem',"w") as f: + with open(job.ID + '/result_LA/LA_epi_with_fiber.elem', "w") as f: f.write("{}\n".format(epi.GetNumberOfCells())) for i in range(epi.GetNumberOfCells()): cell = epi.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f.write( + "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag_epi[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_epi[i])) - - with open(job.ID+'/result_LA/LA_epi_with_fiber.lon',"w") as f: + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag_epi[i])) + + with open(job.ID + '/result_LA/LA_epi_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], sheet_epi[i][0], sheet_epi[i][1], sheet_epi[i][2])) - + f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], + sheet_epi[i][0], sheet_epi[i][1], + sheet_epi[i][2])) + end_time = datetime.datetime.now() running_time = end_time - start_time print('Writing as LA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - - endo = Method.move_surf_along_normals(endo, 0.1*args.scale, 1) # Warning: set -1 if pts normals are pointing outside + + endo = Method.move_surf_along_normals(endo, 0.1 * args.scale, + 1) # Warning: set -1 if pts normals are pointing outside bilayer = Method.generate_bilayer(endo, epi) - + Method.write_bilayer(bilayer, args, job) else: - el = np.where(el == [0,0,0], [1,0,0], el).astype("float32") + el = np.where(el == [0, 0, 0], [1, 0, 0], el).astype("float32") #### save the result into vtk #### start_time = datetime.datetime.now() print('Writinga as LA_with_fiber... ' + str(start_time)) - + sheet = np.cross(el, et) - sheet = np.where(sheet == [0,0,0], [1,0,0], sheet).astype("float32") + sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") - for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): + for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) meshNew = dsa.WrapDataObject(model) @@ -865,36 +884,40 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(sheet, "sheet") if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_vol_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_LA/LA_vol_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_LA/LA_vol_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_LA/LA_vol_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - + pts = numpy_support.vtk_to_numpy(model.GetPoints().GetData()) - with open(job.ID+'/result_LA/LA_vol_with_fiber.pts',"w") as f: + with open(job.ID + '/result_LA/LA_vol_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - with open(job.ID+'/result_LA/LA_vol_with_fiber.elem',"w") as f: + with open(job.ID + '/result_LA/LA_vol_with_fiber.elem', "w") as f: f.write("{}\n".format(model.GetNumberOfCells())) for i in range(model.GetNumberOfCells()): cell = model.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag[i])) - - with open(job.ID+'/result_LA/LA_vol_with_fiber.lon',"w") as f: + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag[i])) + + with open(job.ID + '/result_LA/LA_vol_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el[i][0], el[i][1], el[i][2], sheet[i][0], sheet[i][1], sheet[i][2])) - + f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el[i][0], el[i][1], el[i][2], sheet[i][0], + sheet[i][1], sheet[i][2])) + end_time = datetime.datetime.now() running_time = end_time - start_time print('Writing as LA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py index 44e934c..c3da5e1 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py @@ -26,6 +26,7 @@ """ import os import sys + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) from carputils.carpio import igb @@ -37,22 +38,23 @@ import numpy as np from vtk.numpy_interface import dataset_adapter as dsa + def la_laplace(args, job, model): - meshdir = args.mesh+'_surf/LA' - surfdir ='{}_surf/'.format(args.mesh) - parfdir = os.path.join(EXAMPLE_DIR,'Parfiles') + meshdir = args.mesh + '_surf/LA' + surfdir = '{}_surf/'.format(args.mesh) + parfdir = os.path.join(EXAMPLE_DIR, 'Parfiles') if args.mesh_type == 'vol': #################################### # Solver for the phi laplace solution #################################### cmd = tools.carp_cmd(parfdir + '/la_lps_phi.par') - simid = job.ID+'/Lp_phi' + simid = job.ID + '/Lp_phi' cmd += ['-simID', simid, '-meshname', meshdir, '-stimulus[0].vtx_file', surfdir + 'ids_ENDO', '-stimulus[1].vtx_file', surfdir + 'ids_EPI'] - + # Run simulation job.carp(cmd) @@ -60,7 +62,7 @@ def la_laplace(args, job, model): # Solver for the ab laplace solution ##################################### cmd = tools.carp_cmd(parfdir + '/la_lps_ab.par') - simid = job.ID+'/Lp_ab' + simid = job.ID + '/Lp_ab' cmd += ['-simID', simid, '-meshname', meshdir, '-stimulus[0].vtx_file', surfdir + 'ids_LPV', @@ -75,7 +77,7 @@ def la_laplace(args, job, model): # Solver for the v laplace solution ##################################### cmd = tools.carp_cmd(parfdir + '/la_lps_v.par') - simid = job.ID+'/Lp_v' + simid = job.ID + '/Lp_v' cmd += ['-simID', simid, '-meshname', meshdir, '-stimulus[0].vtx_file', surfdir + 'ids_LPV', @@ -88,7 +90,7 @@ def la_laplace(args, job, model): # Solver for the r laplace solution ##################################### cmd = tools.carp_cmd(parfdir + '/la_lps_r.par') - simid = job.ID+'/Lp_r' + simid = job.ID + '/Lp_r' cmd += ['-simID', simid, '-meshname', meshdir, '-stimulus[0].vtx_file', surfdir + 'ids_LPV', @@ -98,12 +100,12 @@ def la_laplace(args, job, model): # Run simulation job.carp(cmd) - + ##################################### # Solver for the r2 laplace solution ##################################### cmd = tools.carp_cmd(parfdir + '/la_lps_r2.par') - simid = job.ID+'/Lp_r2' + simid = job.ID + '/Lp_r2' cmd += ['-simID', simid, '-meshname', meshdir, '-stimulus[0].vtx_file', surfdir + 'ids_LPV', @@ -116,85 +118,85 @@ def la_laplace(args, job, model): """ generate .vtu files that contain the result of laplace solution as point/cell data """ - + meshNew = dsa.WrapDataObject(model) - + name_list = ['r', 'r2', 'v', 'ab'] if args.mesh_type == 'vol': name_list = ['phi', 'r', 'r2', 'v', 'ab'] for var in name_list: - data = igb.IGBFile(job.ID+"/Lp_" + str(var) + "/phie.igb").data() + data = igb.IGBFile(job.ID + "/Lp_" + str(var) + "/phie.igb").data() # add the vtk array to model - meshNew.PointData.append(data, "phie_"+str(var)) - + meshNew.PointData.append(data, "phie_" + str(var)) + if args.debug == 1: # write - simid = job.ID+"/Laplace_Result" + simid = job.ID + "/Laplace_Result" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) + print("Successfully created the directory %s " % simid) if args.mesh_type == "vol": writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid+"/LA_with_laplace.vtu") + writer.SetFileName(simid + "/LA_with_laplace.vtu") else: writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(simid+"/LA_with_laplace.vtp") + writer.SetFileName(simid + "/LA_with_laplace.vtp") writer.SetInputData(meshNew.VTKObject) writer.Write() """ calculate the gradient """ output = la_calculate_gradient(args, meshNew.VTKObject, job) - + return output -def laplace_0_1(args, job, model, name1,name2, outname): - - meshdir = args.mesh+'_surf/LA' - surfdir ='{}_surf/'.format(args.mesh) - parfdir = os.path.join(EXAMPLE_DIR,'Parfiles') + +def laplace_0_1(args, job, model, name1, name2, outname): + meshdir = args.mesh + '_surf/LA' + surfdir = '{}_surf/'.format(args.mesh) + parfdir = os.path.join(EXAMPLE_DIR, 'Parfiles') ##################################### # Solver for the ab laplace solution ##################################### cmd = tools.carp_cmd(parfdir + '/la_lps_phi.par') - simid = job.ID+'/Lp_ab' + simid = job.ID + '/Lp_ab' cmd += ['-simID', simid, '-meshname', meshdir, '-stimulus[0].vtx_file', surfdir + 'ids_{}'.format(name1), '-stimulus[1].vtx_file', surfdir + 'ids_{}'.format(name2)] - + if name1 == "4": cmd = tools.carp_cmd(parfdir + '/la_lps_phi_0_1_4.par') - simid = job.ID+'/Lp_ab' + simid = job.ID + '/Lp_ab' cmd += ['-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir + 'ids_LSPV', - '-stimulus[1].vtx_file', surfdir + 'ids_LIPV', - '-stimulus[2].vtx_file', surfdir + 'ids_RSPV', - '-stimulus[3].vtx_file', surfdir + 'ids_RIPV'] + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_LSPV', + '-stimulus[1].vtx_file', surfdir + 'ids_LIPV', + '-stimulus[2].vtx_file', surfdir + 'ids_RSPV', + '-stimulus[3].vtx_file', surfdir + 'ids_RIPV'] # Run simulation job.carp(cmd) - + meshNew = dsa.WrapDataObject(model) - data = igb.IGBFile(job.ID+"/Lp_ab/phie.igb").data() + data = igb.IGBFile(job.ID + "/Lp_ab/phie.igb").data() meshNew.PointData.append(data, outname) - + if args.debug == 1: # write - simid = job.ID+"/Laplace_Result" + simid = job.ID + "/Laplace_Result" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) + print("Successfully created the directory %s " % simid) writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid+"/LA_with_laplace.vtu") + writer.SetFileName(simid + "/LA_with_laplace.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - - return meshNew.VTKObject \ No newline at end of file + + return meshNew.VTKObject diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py index 5b3b5ff..3402426 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py @@ -37,60 +37,62 @@ from la_generate_fiber import la_generate_fiber import Methods_LA + def parser(): # Generate the standard command line parser parser = tools.standard_parser() # Add arguments parser.add_argument('--mesh', - type=str, - default="", - help='path to meshname') + type=str, + default="", + help='path to meshname') parser.add_argument('--ifmt', - type=str, - default="vtk", - help='input mesh format') + type=str, + default="vtk", + help='input mesh format') parser.add_argument('--mesh_type', default='bilayer', choices=['vol', 'bilayer'], help='Mesh type') parser.add_argument('--debug', - type=int, - default=0, - help='path to meshname') + type=int, + default=0, + help='path to meshname') parser.add_argument('--scale', - type=int, - default=1, - help='normal unit is mm, set scaling factor if different') + type=int, + default=1, + help='normal unit is mm, set scaling factor if different') parser.add_argument('--ofmt', default='vtu', - choices=['vtu','vtk'], + choices=['vtu', 'vtk'], help='Output mesh format') parser.add_argument('--normals_outside', - type=int, - default=1, - help='set to 1 if surface normals are pointing outside') + type=int, + default=1, + help='set to 1 if surface normals are pointing outside') return parser + def jobID(args): ID = '{}_fibers'.format(args.mesh) return ID + @tools.carpexample(parser, jobID) def run(args, job): - - LA_mesh = args.mesh+'_surf/LA' - + LA_mesh = args.mesh + '_surf/LA' + if args.mesh_type == "bilayer": reader = vtk.vtkPolyDataReader() else: reader = vtk.vtkPolyDataReader() - #reader = vtk.vtkUnstructuredGridReader() - reader.SetFileName(LA_mesh+'.vtk') + # reader = vtk.vtkUnstructuredGridReader() + reader.SetFileName(LA_mesh + '.vtk') reader.Update() LA = reader.GetOutput() - + if args.normals_outside: reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() @@ -101,32 +103,35 @@ def run(args, job): LA = reverse.GetOutput() pts = numpy_support.vtk_to_numpy(LA.GetPoints().GetData()) - - with open(LA_mesh+'.pts',"w") as f: + + with open(LA_mesh + '.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - - with open(LA_mesh+'.elem',"w") as f: - f.write("{}\n".format(LA.GetNumberOfCells())) - for i in range(LA.GetNumberOfCells()): - cell = LA.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), 1)) - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), 1)) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), 1)) - - fibers = np.zeros((LA.GetNumberOfCells(),6)) - fibers[:,0]=1 - fibers[:,4]=1 - - with open(LA_mesh+'.lon',"w") as f: + + with open(LA_mesh + '.elem', "w") as f: + f.write("{}\n".format(LA.GetNumberOfCells())) + for i in range(LA.GetNumberOfCells()): + cell = LA.GetCell(i) + if cell.GetNumberOfPoints() == 2: + f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), 1)) + elif cell.GetNumberOfPoints() == 3: + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), 1)) + elif cell.GetNumberOfPoints() == 4: + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), 1)) + + fibers = np.zeros((LA.GetNumberOfCells(), 6)) + fibers[:, 0] = 1 + fibers[:, 4] = 1 + + with open(LA_mesh + '.lon', "w") as f: f.write("2\n") for i in range(len(fibers)): - f.write("{} {} {} {} {} {}\n".format(fibers[i][0], fibers[i][1], fibers[i][2], fibers[i][3],fibers[i][4],fibers[i][5])) - + f.write("{} {} {} {} {} {}\n".format(fibers[i][0], fibers[i][1], fibers[i][2], fibers[i][3], fibers[i][4], + fibers[i][5])) + start_time = datetime.datetime.now() init_start_time = datetime.datetime.now() print('[Step 1] Solving laplace-dirichlet... ' + str(start_time)) @@ -146,5 +151,6 @@ def run(args, job): tot_running_time = fin_end_time - init_start_time print('Total running time: ' + str(tot_running_time)) + if __name__ == '__main__': run() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 566aeb5..464c9b2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -32,6 +32,7 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + def smart_reader(path): extension = str(path).split(".")[-1] @@ -63,8 +64,9 @@ def smart_reader(path): def downsample_path(points_data, step): # down sampling - path_all = np.asarray([points_data[i] for i in range(len(points_data)) if i % step == 0 or i == len(points_data) - 1]) - + path_all = np.asarray( + [points_data[i] for i in range(len(points_data)) if i % step == 0 or i == len(points_data) - 1]) + # fit a spline spline_points = vtk.vtkPoints() for i in range(len(path_all)): @@ -78,92 +80,92 @@ def downsample_path(points_data, step): points_data = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) return points_data -def move_surf_along_normals(mesh, eps, direction): +def move_surf_along_normals(mesh, eps, direction): extract_surf = vtk.vtkGeometryFilter() extract_surf.SetInputData(mesh) extract_surf.Update() polydata = extract_surf.GetOutput() - + normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) normalGenerator.ComputeCellNormalsOff() normalGenerator.ComputePointNormalsOn() normalGenerator.ConsistencyOn() - normalGenerator.SplittingOff() + normalGenerator.SplittingOff() normalGenerator.Update() - + PointNormalArray = numpy_support.vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) atrial_points = numpy_support.vtk_to_numpy(polydata.GetPoints().GetData()) - - atrial_points = atrial_points + eps*direction*PointNormalArray - + + atrial_points = atrial_points + eps * direction * PointNormalArray + vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_support.numpy_to_vtk(atrial_points)) polydata.SetPoints(vtkPts) - + mesh = vtk.vtkUnstructuredGrid() mesh.DeepCopy(polydata) - + return mesh - + + def generate_bilayer(args, job, endo, epi, max_dist=np.inf): - extract_surf = vtk.vtkGeometryFilter() extract_surf.SetInputData(endo) extract_surf.Update() - + reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() reverse.SetInputConnection(extract_surf.GetOutputPort()) reverse.Update() - + endo = vtk.vtkUnstructuredGrid() endo.DeepCopy(reverse.GetOutput()) - #endo.DeepCopy(extract_surf.GetOutputPort()) - + # endo.DeepCopy(extract_surf.GetOutputPort()) + endo_pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) epi_pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - + tree = cKDTree(epi_pts) - dd, ii = tree.query(endo_pts, distance_upper_bound = max_dist)#, n_jobs=-1) - - endo_ids = np.where(dd!=np.inf)[0] + dd, ii = tree.query(endo_pts, distance_upper_bound=max_dist) # , n_jobs=-1) + + endo_ids = np.where(dd != np.inf)[0] epi_ids = ii[endo_ids] lines = vtk.vtkCellArray() - + for i in range(len(endo_ids)): line = vtk.vtkLine() - line.GetPointIds().SetId(0,i); - line.GetPointIds().SetId(1,len(endo_ids)+i); + line.GetPointIds().SetId(0, i); + line.GetPointIds().SetId(1, len(endo_ids) + i); lines.InsertNextCell(line) - + points = np.vstack((endo_pts[endo_ids], epi_pts[epi_ids])) polydata = vtk.vtkUnstructuredGrid() vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_support.numpy_to_vtk(points)) polydata.SetPoints(vtkPts) polydata.SetCells(3, lines) - - fibers = np.zeros((len(endo_ids),3),dtype="float32") - fibers[:,0] = 1 - + + fibers = np.zeros((len(endo_ids), 3), dtype="float32") + fibers[:, 0] = 1 + tag = np.ones((len(endo_ids),), dtype=int) tag[:] = 100 - + meshNew = dsa.WrapDataObject(polydata) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(fibers, "fiber") - fibers = np.zeros((len(endo_ids),3),dtype="float32") - fibers[:,1] = 1 + fibers = np.zeros((len(endo_ids), 3), dtype="float32") + fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - bilayer_1=meshNew.VTKObject + bilayer_1 = meshNew.VTKObject if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/test_LA_RA_bilayer.vtu") # Has three arrays :) - #writer.SetFileTypeToBinary() # 'vtkmodules.vtkIOXML.vtkXMLUnstructuredGridWriter' object has no attribute 'SetFileTypeToBinary' + writer.SetFileName(job.ID + "/result_RA/test_LA_RA_bilayer.vtu") # Has three arrays :) + # writer.SetFileTypeToBinary() # 'vtkmodules.vtkIOXML.vtkXMLUnstructuredGridWriter' object has no attribute 'SetFileTypeToBinary' writer.SetInputData(bilayer_1) writer.Write() @@ -178,16 +180,16 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): appendFilter.AddInputData(test) appendFilter.MergePointsOn() appendFilter.Update() - + bilayer = appendFilter.GetOutput() if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/LA_RA_bilayer_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :) + writer.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :) writer.SetInputData(bilayer) writer.Write() @@ -198,8 +200,8 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): return bilayer -def write_bilayer( args, job): - + +def write_bilayer(args, job): # if args.ofmt == 'vtk': # writer = vtk.vtkUnstructuredGridWriter() # writer.SetFileName(job.ID+"/result_RA/LA_RA_bilayer_with_fiber.vtk") @@ -216,42 +218,48 @@ def write_bilayer( args, job): bilayer = reader.GetOutput() pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - with open(job.ID+'/result_RA/LA_RA_bilayer_with_fiber.pts',"w") as f: + with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - + tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - with open(job.ID+'/result_RA/LA_RA_bilayer_with_fiber.elem',"w") as f: + with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.elem', "w") as f: f.write("{}\n".format(bilayer.GetNumberOfCells())) for i in range(bilayer.GetNumberOfCells()): cell = bilayer.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag_epi[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_epi[i])) + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag_epi[i])) else: - print("strange "+ str(cell.GetNumberOfPoints())) + print("strange " + str(cell.GetNumberOfPoints())) el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - - with open(job.ID+'/result_RA/LA_RA_bilayer_with_fiber.lon',"w") as f: + + with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], sheet_epi[i][0], sheet_epi[i][1], sheet_epi[i][2])) + f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], + sheet_epi[i][0], sheet_epi[i][1], + sheet_epi[i][2])) print('Done...') -def generate_sheet_dir(args, model, job): + +def generate_sheet_dir(args, model, job): fiber = model.GetCellData().GetArray('fiber') fiber = vtk.util.numpy_support.vtk_to_numpy(fiber) - fiber = np.where(fiber == [0,0,0], [1,0,0], fiber).astype("float32") - + fiber = np.where(fiber == [0, 0, 0], [1, 0, 0], fiber).astype("float32") + print('reading done!') - + ''' extract the surface ''' @@ -259,19 +267,18 @@ def generate_sheet_dir(args, model, job): geo_filter.SetInputData(model) geo_filter.Update() surface = geo_filter.GetOutput() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(surface) cleaner.Update() cln_surface = cleaner.GetOutput() - + # meshNew = dsa.WrapDataObject(cln_surface) # writer = vtk.vtkPolyDataWriter() # writer.SetFileName("test_model_surface.vtk") # writer.SetInputData(meshNew.VTKObject) # writer.Write() - - + ''' calculate normals of surface cells ''' @@ -282,13 +289,13 @@ def generate_sheet_dir(args, model, job): normals.Update() normal_vectors = normals.GetOutput().GetCellData().GetArray('Normals') normal_vectors = vtk.util.numpy_support.vtk_to_numpy(normal_vectors) - + # print('Normal vectors: \n', normal_vectors, '\n') print('Number of normals: ', len(normal_vectors)) - print('2nd norm of vectors: ', np.linalg.norm(normal_vectors[0],ord=2), '\n') - + print('2nd norm of vectors: ', np.linalg.norm(normal_vectors[0], ord=2), '\n') + if args.mesh_type == "vol": - + ''' calculate the centers of surface mesh cells ''' @@ -298,8 +305,7 @@ def generate_sheet_dir(args, model, job): center_surface = filter_cell_centers.GetOutput().GetPoints() center_surface_array = vtk.util.numpy_support.vtk_to_numpy(center_surface.GetData()) print('Number of center_surface: ', len(center_surface_array), '\n') - - + ''' calculate the centers of volume mesh cells ''' @@ -309,35 +315,34 @@ def generate_sheet_dir(args, model, job): center_volume = filter_cell_centers.GetOutput().GetPoints().GetData() center_volume = vtk.util.numpy_support.vtk_to_numpy(center_volume) print('Number of center_volume: ', len(center_volume), '\n') - - + ''' Mapping ''' - normals = np.ones([len(center_volume), 3], dtype = float) + normals = np.ones([len(center_volume), 3], dtype=float) kDTree = vtk.vtkKdTree() kDTree.BuildLocatorFromPoints(center_surface) - + for i in range(len(center_volume)): id_list = vtk.vtkIdList() kDTree.FindClosestNPoints(1, center_volume[i], id_list) index = id_list.GetId(0) normals[i] = normal_vectors[index] - + print('Mapping done!') ''' calculate the sheet ''' - + elif args.mesh_type == "bilayer": normals = normal_vectors - + sheet = np.cross(normals, fiber) - sheet = np.where(sheet == [0,0,0], [1,0,0], sheet).astype("float32") + sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") # normalize abs_sheet = np.linalg.norm(sheet, axis=1, keepdims=True) sheet_norm = sheet / abs_sheet - + ''' writing ''' @@ -346,44 +351,46 @@ def generate_sheet_dir(args, model, job): # sheet_data.SetNumberOfComponents(3) # sheet_data.SetName("sheet") # model.GetCellData().AddArray(sheet_data) - + meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(fiber, "fiber") meshNew.CellData.append(sheet_norm, "sheet") if args.debug: writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/model_with_sheet.vtk") + writer.SetFileName(job.ID + "/result_RA/model_with_sheet.vtk") writer.SetInputData(meshNew.VTKObject) writer.Write() print('writing... done!') - + return meshNew.VTKObject - -def vtk_thr(model,mode,points_cells,array,thr1,thr2="None"): + + +def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thresh = vtk.vtkThreshold() thresh.SetInputData(model) if mode == 0: thresh.ThresholdByUpper(thr1) elif mode == 1: thresh.ThresholdByLower(thr1) - elif mode ==2: + elif mode == 2: if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1,thr2) + thresh.ThresholdBetween(thr1, thr2) else: thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() thr = thresh.GetOutput() thresh = vtk.vtkThreshold() thresh.SetInputData(thr) thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() - + output = thresh.GetOutput() - + return output + def creat_tube_around_spline(points_data, radius): # Creat a points set spline_points = vtk.vtkPoints() @@ -452,14 +459,14 @@ def dijkstra_path(polydata, StartVertex, EndVertex): points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) return points_data + def dijkstra_path_coord(polydata, StartVertex, EndVertex): - loc = vtk.vtkPointLocator() loc.SetDataSet(polydata) loc.BuildLocator() StartVertex = loc.FindClosestPoint(StartVertex) EndVertex = loc.FindClosestPoint(EndVertex) - + path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(polydata) @@ -470,6 +477,7 @@ def dijkstra_path_coord(polydata, StartVertex, EndVertex): points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) return points_data + def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point): point_start = np.asarray(polydata.GetPoint(StartVertex)) point_end = np.asarray(polydata.GetPoint(EndVertex)) @@ -492,7 +500,7 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point meshExtractFilter1.SetImplicitFunction(plane) meshExtractFilter1.Update() - point_moved = point_start - 2*args.scale * norm_1 + point_moved = point_start - 2 * args.scale * norm_1 plane2 = vtk.vtkPlane() plane2.SetNormal(-norm_1[0], -norm_1[1], -norm_1[2]) plane2.SetOrigin(point_moved[0], point_moved[1], point_moved[2]) @@ -501,7 +509,7 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() - + band = meshExtractFilter2.GetOutput() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(band) @@ -512,7 +520,7 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point band = cln.GetOutput() if args.debug: - writer_vtk(band, '{}_surf/'.format(args.mesh) + "band_"+ str(StartVertex)+ "_" + str(EndVertex) + ".vtk") + writer_vtk(band, '{}_surf/'.format(args.mesh) + "band_" + str(StartVertex) + "_" + str(EndVertex) + ".vtk") loc = vtk.vtkPointLocator() loc.SetDataSet(band) @@ -520,7 +528,6 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point StartVertex = loc.FindClosestPoint(point_start) EndVertex = loc.FindClosestPoint(point_end) - points_data = dijkstra_path(band, StartVertex, EndVertex) return points_data @@ -548,6 +555,7 @@ def creat_tube(center1, center2, radius): tube.Update() return tube + def find_elements_around_path_within_radius(mesh, points_data, radius): locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -572,11 +580,11 @@ def find_elements_around_path_within_radius(mesh, points_data, radius): id_set.add(mesh_cell_id_list.GetId(i)) return id_set - + + def get_element_ids_around_path_within_radius(mesh, points_data, radius): - gl_ids = vtk.util.numpy_support.vtk_to_numpy(mesh.GetCellData().GetArray('Global_ids')) - + locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) locator.BuildLocator() @@ -594,15 +602,16 @@ def get_element_ids_around_path_within_radius(mesh, points_data, radius): mesh.GetPointCells(mesh_id_list.GetId(i), mesh_cell_temp_id_list) for j in range(mesh_cell_temp_id_list.GetNumberOfIds()): mesh_cell_id_list.InsertNextId(mesh_cell_temp_id_list.GetId(j)) - + ids = [] - + for i in range(mesh_cell_id_list.GetNumberOfIds()): index = mesh_cell_id_list.GetId(i) ids.append(gl_ids[index]) return ids + def assign_element_tag_around_path_within_radius(mesh, points_data, radius, tag, element_tag): locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -929,8 +938,9 @@ def get_endo_ct_intersection_cells(endo, ct): return endo_ct -def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_inf_surface, la_epi_surface, ra_epi_surface): +def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_inf_surface, la_epi_surface, + ra_epi_surface): loc_mv = vtk.vtkPointLocator() loc_mv.SetDataSet(la_mv_surface) loc_mv.BuildLocator() @@ -986,6 +996,7 @@ def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_in return la_connect_point, ra_connect_point + def get_connection_point_la_and_ra(appen_point): la_mv_surface = smart_reader('../../Generate_Boundaries/LA/result/la_mv_surface.vtk') la_rpv_inf_surface = smart_reader('../../Generate_Boundaries/LA/result/la_rpv_inf_surface.vtk') @@ -1048,6 +1059,7 @@ def get_connection_point_la_and_ra(appen_point): return la_connect_point, ra_connect_point + def get_bachmann_path_left(appendage_basis, lpv_sup_basis): la_mv_surface = smart_reader('../../Generate_Boundaries/LA/result/la_mv_surface.vtk') la_lpv_inf_surface = smart_reader('../../Generate_Boundaries/LA/result/la_lpv_inf_surface.vtk') @@ -1081,6 +1093,7 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): return bb_left, appendage_basis + def create_free_bridge_semi_auto(la_epi, ra_epi, ra_point, radius): loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi) @@ -1099,6 +1112,7 @@ def create_free_bridge_semi_auto(la_epi, ra_epi, ra_point, radius): fiber_direction_norm = normalize_vector(fiber_direction) return tube, sphere_a, sphere_b, fiber_direction_norm + def creat_center_line(start_end_point): spline_points = vtk.vtkPoints() for i in range(len(start_end_point)): @@ -1118,33 +1132,35 @@ def creat_center_line(start_end_point): return points + def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): meshNew = dsa.WrapDataObject(tube.GetOutput()) writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID+"/bridges/" + str(name) + "_tube.obj") + writer.SetFileName(job.ID + "/bridges/" + str(name) + "_tube.obj") writer.SetInputData(meshNew.VTKObject) writer.Write() meshNew = dsa.WrapDataObject(sphere_1.GetOutput()) writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID+"/bridges/" + str(name) + "_sphere_1.obj") + writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_1.obj") writer.SetInputData(meshNew.VTKObject) writer.Write() meshNew = dsa.WrapDataObject(sphere_2.GetOutput()) writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID+"/bridges/" + str(name) + "_sphere_2.obj") + writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_2.obj") writer.SetInputData(meshNew.VTKObject) writer.Write() -def create_pts(array_points,array_name,mesh_dir): - f = open("{}{}.pts".format(mesh_dir,array_name), "w") +def create_pts(array_points, array_name, mesh_dir): + f = open("{}{}.pts".format(mesh_dir, array_name), "w") f.write("0 0 0\n") for i in range(len(array_points)): f.write("{} {} {}\n".format(array_points[i][0], array_points[i][1], array_points[i][2])) f.close() + def to_polydata(mesh): geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(mesh) @@ -1152,8 +1168,9 @@ def to_polydata(mesh): polydata = geo_filter.GetOutput() return polydata -def writer_vtk(mesh,filename): + +def writer_vtk(mesh, filename): writer = vtk.vtkPolyDataWriter() writer.SetFileName(filename) writer.SetInputData(to_polydata(mesh)) - writer.Write() \ No newline at end of file + writer.Write() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 3220c08..a808f01 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -40,18 +40,18 @@ EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) -def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): +def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ######################################## - with open(os.path.join(EXAMPLE_DIR,'../../element_tag.csv')) as f: + with open(os.path.join(EXAMPLE_DIR, '../../element_tag.csv')) as f: tag_dict = {} reader = csv.DictReader(f) for row in reader: tag_dict[row['name']] = row['tag'] - - bridge_radius = 1.65*args.scale - - bachmann_bundel_left = int(tag_dict['bachmann_bundel_left']) + + bridge_radius = 1.65 * args.scale + + bachmann_bundel_left = int(tag_dict['bachmann_bundel_left']) bachmann_bundel_right = int(tag_dict['bachmann_bundel_right']) bachmann_bundel_internal = int(tag_dict['bachmann_bundel_internal']) middle_posterior_bridge_left = int(tag_dict['middle_posterior_bridge_left']) @@ -64,79 +64,89 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): left_atrial_wall_epi = int(tag_dict["left_atrial_wall_epi"]) mitral_valve_epi = int(tag_dict["mitral_valve_epi"]) tricuspid_valve_epi = int(tag_dict["tricuspid_valve_epi"]) - - #la_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) + + # la_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) geo_filter_la = vtk.vtkGeometryFilter() geo_filter_la.SetInputData(la_epi) geo_filter_la.Update() la_epi_surface = geo_filter_la.GetOutput() - - #ra_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) + + # ra_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) geo_filter_ra = vtk.vtkGeometryFilter() geo_filter_ra.SetInputData(ra_epi) geo_filter_ra.Update() ra_epi_surface = geo_filter_ra.GetOutput() - + SVC_p = np.array(df["SVC"]) IVC_p = np.array(df["IVC"]) TV_p = np.array(df["TV"]) - - ra_septum = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", right_atrial_septum_epi,right_atrial_septum_epi) - la_wall = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", left_atrial_wall_epi,left_atrial_wall_epi) - mv_la = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", mitral_valve_epi,mitral_valve_epi) - tv_ra = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi,tricuspid_valve_epi) - + + ra_septum = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", right_atrial_septum_epi, right_atrial_septum_epi) + la_wall = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", left_atrial_wall_epi, left_atrial_wall_epi) + mv_la = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", mitral_valve_epi, mitral_valve_epi) + tv_ra = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) + # Find middle and upper posterior bridges points - + loc = vtk.vtkPointLocator() loc.SetDataSet(ra_septum) loc.BuildLocator() point_septum_SVC = ra_septum.GetPoint(loc.FindClosestPoint(SVC_p)) point_septum_IVC = ra_septum.GetPoint(loc.FindClosestPoint(IVC_p)) - + SVC_IVC_septum_path = Method.dijkstra_path_coord(ra_epi_surface, point_septum_SVC, point_septum_IVC) if args.debug: Method.create_pts(SVC_IVC_septum_path, 'SVC_IVC_septum_path', '{}_surf/'.format(args.mesh)) - middle_posterior_bridge_point = SVC_IVC_septum_path[int(len(SVC_IVC_septum_path)*0.6),:] # Can happen that the 0.6 is where the BB is - - upper_posterior_bridge_point = SVC_IVC_septum_path[int(len(SVC_IVC_septum_path)*0.4),:] - - mpb_tube, mpb_sphere_1, mpb_sphere_2, mpb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, ra_epi_surface, middle_posterior_bridge_point, bridge_radius) + middle_posterior_bridge_point = SVC_IVC_septum_path[int(len(SVC_IVC_septum_path) * 0.6), + :] # Can happen that the 0.6 is where the BB is + + upper_posterior_bridge_point = SVC_IVC_septum_path[int(len(SVC_IVC_septum_path) * 0.4), :] + + mpb_tube, mpb_sphere_1, mpb_sphere_2, mpb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, + ra_epi_surface, + middle_posterior_bridge_point, + bridge_radius) Method.smart_bridge_writer(mpb_tube, mpb_sphere_1, mpb_sphere_2, "middle_posterior_bridge", job) - - upb_tube, upb_sphere_1, upb_sphere_2, upb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, ra_epi_surface, upper_posterior_bridge_point, bridge_radius) + + upb_tube, upb_sphere_1, upb_sphere_2, upb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, + ra_epi_surface, + upper_posterior_bridge_point, + bridge_radius) Method.smart_bridge_writer(upb_tube, upb_sphere_1, upb_sphere_2, "upper_posterior_bridge", job) # Coronary sinus bridge point - loc = vtk.vtkPointLocator() # it happened that the point is too close to the edge and the heart is not found + loc = vtk.vtkPointLocator() # it happened that the point is too close to the edge and the heart is not found loc.SetDataSet(mv_la) loc.BuildLocator() - point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p+TV_p*0.1)) # adapt this value if CS is too low + point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p + TV_p * 0.1)) # adapt this value if CS is too low + + # loc = vtk.vtkPointLocator() + # loc.SetDataSet(la_wall) + # loc.BuildLocator() + # point_CS_on_MV = la_wall.GetPoint(loc.FindClosestPoint(CS_p+TV_p*0.1)) - #loc = vtk.vtkPointLocator() - #loc.SetDataSet(la_wall) - #loc.BuildLocator() - #point_CS_on_MV = la_wall.GetPoint(loc.FindClosestPoint(CS_p+TV_p*0.1)) - loc = vtk.vtkPointLocator() loc.SetDataSet(ra_septum) loc.BuildLocator() point_CS_bridge = ra_septum.GetPoint(loc.FindClosestPoint(point_CS_on_MV)) - csb_tube, csb_sphere_1, csb_sphere_2, csb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, ra_epi_surface, point_CS_bridge, bridge_radius) + csb_tube, csb_sphere_1, csb_sphere_2, csb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, + ra_epi_surface, + point_CS_bridge, + bridge_radius) Method.smart_bridge_writer(csb_tube, csb_sphere_1, csb_sphere_2, "coronary_sinus_bridge", job) - + if args.mesh_type == "vol": append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_epi) append_filter.AddInputData(ra_epi) append_filter.Update() - tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),),dtype=int) + tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) tag[:la_epi.GetNumberOfCells()] = vtk.util.numpy_support.vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) tag[la_epi.GetNumberOfCells():] = vtk.util.numpy_support.vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) @@ -146,7 +156,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(meshNew.VTKObject) append_filter.Update() writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/la_ra_res.vtu") + writer.SetFileName(job.ID + "/result_RA/la_ra_res.vtu") writer.SetInputData(append_filter.GetOutput()) writer.Write() elif args.mesh_type == "bilayer": @@ -166,10 +176,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_e) append_filter.AddInputData(ra_e) - append_filter.Update() # la_ra_usg + append_filter.Update() # la_ra_usg writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu") # Good till here! + writer.SetFileName(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu") # Good till here! writer.SetInputData(append_filter.GetOutput()) writer.Write() @@ -188,10 +198,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: - - mesh_A = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_tube.obj") - mesh_B = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_sphere_1.obj") - mesh_C = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_sphere_2.obj") + mesh_A = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_tube.obj") + mesh_B = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_sphere_1.obj") + mesh_C = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_sphere_2.obj") output_mesh_1 = pymesh.boolean(mesh_A, mesh_B, operation="union", engine="igl") @@ -203,17 +212,18 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # add the mesh to the MeshSet ms.add_mesh(m, "bridge_mesh") # apply filter - ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=0.4*args.scale, adaptive=True) - ms.save_current_mesh(job.ID+"/bridges/"+str(var)+"_bridge_resampled.obj",\ - save_vertex_color=False, save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) + ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=0.4 * args.scale, adaptive=True) + ms.save_current_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj", \ + save_vertex_color=False, save_vertex_normal=False, save_face_color=False, + save_wedge_texcoord=False, save_wedge_normal=False) subprocess.run(["meshtool", - "generate", - "mesh", - "-ofmt=vtk", - "-prsv_bdry=1", - "-surf="+job.ID+"/bridges/"+str(var)+"_bridge_resampled.obj", - "-outmsh="+job.ID+"/bridges/"+str(var)+"_bridge_resampled.vtk"]) + "generate", + "mesh", + "-ofmt=vtk", + "-prsv_bdry=1", + "-surf=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj", + "-outmsh=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.vtk"]) # if args.mesh_type == "vol": @@ -311,7 +321,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # append_filter.AddInputData(la_BB) # append_filter.AddInputData(ra_BB) # append_filter.Update() - la_ra_usg = append_filter.GetOutput() # this has already elemTag + la_ra_usg = append_filter.GetOutput() # this has already elemTag if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() @@ -325,52 +335,51 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): earth_cell_ids_list = [] for var in bridge_list: print(var) - + reader = vtk.vtkUnstructuredGridReader() - reader.SetFileName(job.ID+"/bridges/"+str(var)+'_bridge_resampled.vtk') + reader.SetFileName(job.ID + "/bridges/" + str(var) + '_bridge_resampled.vtk') reader.Update() bridge_usg = reader.GetOutput() - # geo_filter = vtk.vtkGeometryFilter() # geo_filter.SetInputData(bridge_usg) # geo_filter.Update() # bridge = geo_filter.GetOutput() - + # reverse = vtk.vtkReverseSense() # reverse.ReverseCellsOn() # reverse.ReverseNormalsOn() # reverse.SetInputConnection(cleaner.GetOutputPort()) # reverse.Update() - + # earth = reverse.GetOutput() - + # vbool = vtk.vtkBooleanOperationPolyDataFilter() # vbool.SetOperationToDifference() # vbool.SetInputData( 0, epi_surf ) # vbool.SetInputData( 1, bridge ) - + # vbool.Update() locator = vtk.vtkStaticPointLocator() locator.SetDataSet(la_ra_usg) locator.BuildLocator() - - #intersection_points = vbool.GetOutput().GetPoints().GetData() + + # intersection_points = vbool.GetOutput().GetPoints().GetData() intersection_points = bridge_usg.GetPoints().GetData() intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) - + earth_point_ids_temp = vtk.vtkIdList() earth_point_ids = vtk.vtkIdList() for i in range(len(intersection_points)): - locator.FindPointsWithinRadius(0.7*args.scale, intersection_points[i], earth_point_ids_temp) + locator.FindPointsWithinRadius(0.7 * args.scale, intersection_points[i], earth_point_ids_temp) for j in range(earth_point_ids_temp.GetNumberOfIds()): earth_point_ids.InsertNextId(earth_point_ids_temp.GetId(j)) earth_cell_ids_temp = vtk.vtkIdList() earth_cell_ids = vtk.vtkIdList() for i in range(earth_point_ids.GetNumberOfIds()): - la_ra_usg.GetPointCells(earth_point_ids.GetId(i),earth_cell_ids_temp) + la_ra_usg.GetPointCells(earth_point_ids.GetId(i), earth_cell_ids_temp) for j in range(earth_cell_ids_temp.GetNumberOfIds()): earth_cell_ids.InsertNextId(earth_cell_ids_temp.GetId(j)) earth_cell_ids_list += [earth_cell_ids_temp.GetId(j)] @@ -383,30 +392,30 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): geo_filter.SetInputData(extract.GetOutput()) geo_filter.Update() earth = geo_filter.GetOutput() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(earth) cleaner.Update() earth = cleaner.GetOutput() - + # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID+"/bridges/"+str(var)+"_earth.obj") + writer.SetFileName(job.ID + "/bridges/" + str(var) + "_earth.obj") writer.SetInputData(earth) writer.Write() - + # Here print("Extracted earth") cell_id_all = [] for i in range(la_ra_usg.GetNumberOfCells()): cell_id_all.append(i) - - la_diff =list(set(cell_id_all).difference(set(earth_cell_ids_list))) + + la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) la_ra_new = vtk.vtkIdList() for item in la_diff: la_ra_new.InsertNextId(item) - + extract = vtk.vtkExtractCells() extract.SetInputData(la_ra_usg) extract.SetCellList(la_ra_new) @@ -414,15 +423,15 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter = vtk.vtkAppendFilter() append_filter.MergePointsOn() - #append_filter.SetTolerance(0.01*args.scale) + # append_filter.SetTolerance(0.01*args.scale) append_filter.AddInputData(extract.GetOutput()) - append_filter.Update() # added + append_filter.Update() # added la_ra_epi = append_filter.GetOutput() # we lose this mesh, when defining the append filter later - if args.debug and var =='upper_posterior_bridge': + if args.debug and var == 'upper_posterior_bridge': writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") # Still has element Tag + writer.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") # Still has element Tag writer.SetInputData(la_ra_epi) writer.Write() @@ -514,14 +523,14 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # append_filter.AddInputData(append_filter.GetOutput()) # meshNew = dsa.WrapDataObject(extract.GetOutput()) - filename = job.ID+'/bridges/bb_fiber.dat' + filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') bb_fiber = pickle.load(f) - + spline_points = vtk.vtkPoints() for i in range(len(bb_fiber)): spline_points.InsertPoint(i, bb_fiber[i][0], bb_fiber[i][1], bb_fiber[i][2]) - + # Fit a spline to the points spline = vtk.vtkParametricSpline() spline.SetPoints(spline_points) @@ -531,29 +540,29 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) functionSource.Update() bb_fiber_points_data = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) - + print("Union between earth and bridges") for var in bridge_list: - + # if args.mesh_type == "vol": # mesh_D = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_bridge_resampled.obj") # mesh_E = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_earth.obj") # output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="igl") # elif args.mesh_type == "bilayer": # Here - mesh_D = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_bridge_resampled.obj") - mesh_E = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_earth.obj") + mesh_D = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj") + mesh_E = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_earth.obj") # # Warning: set -1 if pts normals are pointing outside # # Use union if the endo normals are pointing outside - #output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - if args.mesh_type=="bilayer": + # output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") + if args.mesh_type == "bilayer": # Use difference if the endo normals are pointing inside output_mesh_2 = pymesh.boolean(mesh_E, mesh_D, operation="difference", engine="corefinement") - pymesh.save_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj", output_mesh_2, ascii=True) + pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) else: output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - pymesh.save_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj", output_mesh_2, ascii=True) - + pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) + # reader = vtk.vtkOBJReader() # reader.SetFileName(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") # reader.Update() @@ -571,34 +580,36 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # pymesh.save_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj", output_mesh_2, ascii=True) - print("Union between earth and bridges in "+var) - + print("Union between earth and bridges in " + var) + ms = pymeshlab.MeshSet() - #if args.just_bridges and var == 'BB_intern_bridges': - #job.ID='../'+job.ID# Change if you enter from ra_main and not from pipeline.py, otherwise comment the line - ms.load_new_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=0.4*args.scale, adaptive=True) - ms.save_current_mesh(job.ID+"/bridges/"+str(var)+"_union.obj",save_vertex_color=False, save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) - + # if args.just_bridges and var == 'BB_intern_bridges': + # job.ID='../'+job.ID# Change if you enter from ra_main and not from pipeline.py, otherwise comment the line + ms.load_new_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj") + ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=0.4 * args.scale, adaptive=True) + ms.save_current_mesh(job.ID + "/bridges/" + str(var) + "_union.obj", save_vertex_color=False, + save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, + save_wedge_normal=False) + if args.mesh_type == "vol": - subprocess.run(["meshtool", - "generate", - "mesh", - "-ofmt=vtk", - "-prsv_bdry=1", - #"-scale={}".format(0.4*args.scale), - "-surf="+job.ID+"/bridges/"+str(var)+"_union.obj", - "-outmsh="+job.ID+"/bridges/"+str(var)+"_union_mesh.vtk"]) - - reader = vtk.vtkUnstructuredGridReader() #vtkXMLUnstructuredGridReader - reader.SetFileName(job.ID+"/bridges/"+str(var)+"_union_mesh.vtk") + subprocess.run(["meshtool", + "generate", + "mesh", + "-ofmt=vtk", + "-prsv_bdry=1", + # "-scale={}".format(0.4*args.scale), + "-surf=" + job.ID + "/bridges/" + str(var) + "_union.obj", + "-outmsh=" + job.ID + "/bridges/" + str(var) + "_union_mesh.vtk"]) + + reader = vtk.vtkUnstructuredGridReader() # vtkXMLUnstructuredGridReader + reader.SetFileName(job.ID + "/bridges/" + str(var) + "_union_mesh.vtk") reader.Update() bridge_union = reader.GetOutput() elif args.mesh_type == "bilayer": reader = vtk.vtkOBJReader() - reader.SetFileName(job.ID+"/bridges/"+str(var)+"_union.obj") - reader.Update() + reader.SetFileName(job.ID + "/bridges/" + str(var) + "_union.obj") + reader.Update() bridge_union = vtk.vtkUnstructuredGrid() bridge_union.DeepCopy(reader.GetOutput()) @@ -610,18 +621,19 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): tag[:] = coronary_sinus_bridge_left elif var == 'middle_posterior_bridge': tag[:] = middle_posterior_bridge_left - elif var =='upper_posterior_bridge': + elif var == 'upper_posterior_bridge': tag[:] = upper_posterior_bridge_left fiber = np.ones((bridge_union.GetNumberOfCells(), 3), dtype="float32") if var == 'BB_intern_bridges': - fiber = Method.assign_element_fiber_around_path_within_radius(bridge_union, bb_fiber_points_data, 3*args.scale, fiber, smooth=True) + fiber = Method.assign_element_fiber_around_path_within_radius(bridge_union, bb_fiber_points_data, + 3 * args.scale, fiber, smooth=True) elif var == 'coronary_sinus_bridge': fiber[:] = csb_fiber elif var == 'middle_posterior_bridge': fiber[:] = mpb_fiber - elif var =='upper_posterior_bridge': + elif var == 'upper_posterior_bridge': fiber[:] = upb_fiber meshNew = dsa.WrapDataObject(bridge_union) @@ -629,7 +641,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): meshNew.CellData.append(fiber, "fiber") writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/bridges/"+str(var)+"_union_mesh.vtk") # we have the elemTags here + writer.SetFileName(job.ID + "/bridges/" + str(var) + "_union_mesh.vtk") # we have the elemTags here writer.SetInputData(meshNew.VTKObject) writer.Write() @@ -639,7 +651,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): cs = meshNew.VTKObject elif var == 'middle_posterior_bridge': mp = meshNew.VTKObject - elif var =='upper_posterior_bridge': + elif var == 'upper_posterior_bridge': up = meshNew.VTKObject reader = vtk.vtkUnstructuredGridReader() @@ -671,35 +683,35 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): bridges = append_filter.GetOutput() writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :) + writer.SetFileName(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :) writer.SetInputData(bridges) writer.Write() - # # Append all the bridges first - # if var == bridge_list[0]: # just define append_filter in the first iteration - # append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(meshNew.VTKObject) - # append_filter.Update() - # temp = append_filter.GetOutput() - # else: - # append_filter.AddInputData(temp) - # append_filter.AddInputData(meshNew.VTKObject) - # append_filter.Update() - # temp = append_filter.GetOutput() - # - # if args.debug and var == bridge_list[-1]: - # writer = vtk.vtkXMLUnstructuredGridWriter() - # writer.SetFileName(job.ID + "/result_RA/append_bridges_with_tag.vtu") - # writer.SetInputData(temp) - # writer.Write() - - #append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag - #append_filter.Update() - - #writer = vtk.vtkXMLUnstructuredGridWriter() - #writer.SetFileName(job.ID + "/result_RA/LA_RA_with_bundles_with_" + str(var) + ".vtu") # Here we lose the elemTag - #writer.SetInputData(append_filter.GetOutput()) - #writer.Write() + # # Append all the bridges first + # if var == bridge_list[0]: # just define append_filter in the first iteration + # append_filter = vtk.vtkAppendFilter() + # append_filter.AddInputData(meshNew.VTKObject) + # append_filter.Update() + # temp = append_filter.GetOutput() + # else: + # append_filter.AddInputData(temp) + # append_filter.AddInputData(meshNew.VTKObject) + # append_filter.Update() + # temp = append_filter.GetOutput() + # + # if args.debug and var == bridge_list[-1]: + # writer = vtk.vtkXMLUnstructuredGridWriter() + # writer.SetFileName(job.ID + "/result_RA/append_bridges_with_tag.vtu") + # writer.SetInputData(temp) + # writer.Write() + + # append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag + # append_filter.Update() + + # writer = vtk.vtkXMLUnstructuredGridWriter() + # writer.SetFileName(job.ID + "/result_RA/LA_RA_with_bundles_with_" + str(var) + ".vtu") # Here we lose the elemTag + # writer.SetInputData(append_filter.GetOutput()) + # writer.Write() reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") @@ -712,95 +724,102 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): bridges = reader.GetOutput() append_filter = vtk.vtkAppendFilter() - #append_filter.AddInputData(la_ra_epi) + # append_filter.AddInputData(la_ra_epi) append_filter.AddInputData(epi_new) append_filter.AddInputData(bridges) - #append_filter.MergePointsOn() + # append_filter.MergePointsOn() append_filter.Update() epi = append_filter.GetOutput() writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/LA_RA_with_bundles.vtu") + writer.SetFileName(job.ID + "/result_RA/LA_RA_with_bundles.vtu") writer.SetInputData(epi) writer.Write() - + epi = Method.generate_sheet_dir(args, epi, job) - + writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/LA_RA_with_sheets.vtu") + writer.SetFileName(job.ID + "/result_RA/LA_RA_with_sheets.vtu") writer.SetInputData(epi) writer.Write() - + if args.mesh_type == "bilayer": writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/la_ra_epi_with_sheets.vtu") # Has elemTag! :) + writer.SetFileName(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu") # Has elemTag! :) writer.SetInputData(epi) writer.Write() reader = vtk.vtkXMLUnstructuredGridReader() - reader.SetFileName(job.ID+"/result_RA/RA_CT_PMs.vtu") # Has elemTag! :) + reader.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") # Has elemTag! :) reader.Update() ra_endo = reader.GetOutput() - + reader = vtk.vtkXMLUnstructuredGridReader() - #reader.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtu") # Has elemTag! :) + # reader.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtu") # Has elemTag! :) reader.SetFileName(job.ID + "/result_RA/LA_endo_with_holes.vtu") # Has elemTag! :) reader.Update() la_endo = reader.GetOutput() - + append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_endo) append_filter.AddInputData(ra_endo) append_filter.Update() writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :) + writer.SetFileName(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :) writer.SetInputData(append_filter.GetOutput()) writer.Write() - endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1*args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - + endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, + 1) # # Warning: set -1 if pts normals are pointing outside + writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/la_ra_endo.vtu") # Has elemTag! :) + writer.SetFileName(job.ID + "/result_RA/la_ra_endo.vtu") # Has elemTag! :) writer.SetInputData(endo) writer.Write() - - bilayer = Method.generate_bilayer(args,job, endo, epi, 0.12*args.scale) # Does not have elemTag :(! - + + bilayer = Method.generate_bilayer(args, job, endo, epi, 0.12 * args.scale) # Does not have elemTag :(! + Method.write_bilayer(args, job) else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/LA_RA_vol_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu") writer.SetInputData(epi) writer.Write() pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - with open(job.ID+'/result_RA/LA_RA_vol_with_fiber.pts',"w") as f: + with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - + tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) - with open(job.ID+'/result_RA/LA_RA_vol_with_fiber.elem',"w") as f: + with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', "w") as f: f.write("{}\n".format(epi.GetNumberOfCells())) for i in range(epi.GetNumberOfCells()): cell = epi.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f.write( + "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag_epi[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_epi[i])) + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag_epi[i])) else: - print("strange "+ str(cell.GetNumberOfPoints())) + print("strange " + str(cell.GetNumberOfPoints())) el_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('sheet')) - - with open(job.ID+'/result_RA/LA_RA_vol_with_fiber.lon',"w") as f: + + with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], sheet_epi[i][0], sheet_epi[i][1], sheet_epi[i][2])) + f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], + sheet_epi[i][0], sheet_epi[i][1], + sheet_epi[i][2])) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index df1b1f3..5d2c568 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -46,7 +46,6 @@ import Methods_RA as Method import pandas as pd - EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -72,7 +71,6 @@ def parser(): default=1, help='normal unit is mm, set scaling factor if different') - return parser @@ -83,16 +81,14 @@ def jobID(args): @tools.carpexample(parser, jobID) def run(args, job): + la_epi = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") - la_epi = Method.smart_reader(job.ID+"/result_LA/LA_epi_with_fiber.vtu") - - model = Method.smart_reader(job.ID+"/result_RA/RA_epi_with_fiber.vtu") + model = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") df = pd.read_csv(args.mesh + "_surf/rings_centroids.csv") CS_p = np.array(df["CS"]) - print('[Step 3] Generate Bridges and Bilayer... ') add_free_bridge(args, la_epi, model, CS_p, df, job) @@ -705,5 +701,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): sheet_epi[i][0], sheet_epi[i][1], sheet_epi[i][2])) + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index e5ec902..8d6cff2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -29,7 +29,6 @@ def run(args): - reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(args.mesh + "/RA_CT_PMs.vtk") reader.Update() @@ -40,163 +39,168 @@ def run(args): # reader.Update() # ra_endo = reader.GetOutput() - reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(args.mesh + "/RA_epi_with_fiber.vtk") reader.Update() ra_epi = reader.GetOutput() - endo = move_surf_along_normals(ra_endo, 0.1*args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - + endo = move_surf_along_normals(ra_endo, 0.1 * args.scale, + 1) # # Warning: set -1 if pts normals are pointing outside + writer = vtk.vtkUnstructuredGridWriter() writer.SetFileName(args.mesh + "/RA_endo_with_fiber_moved.vtk") writer.SetInputData(endo) writer.Write() - bilayer = generate_bilayer(endo, ra_epi, 0.12*args.scale) - #bilayer = generate_bilayer(ra_endo, ra_epi) - + bilayer = generate_bilayer(endo, ra_epi, 0.12 * args.scale) + # bilayer = generate_bilayer(ra_endo, ra_epi) + write_bilayer(bilayer) -def move_surf_along_normals(mesh, eps, direction): +def move_surf_along_normals(mesh, eps, direction): extract_surf = vtk.vtkGeometryFilter() extract_surf.SetInputData(mesh) extract_surf.Update() - + # reverse = vtk.vtkReverseSense() # reverse.ReverseCellsOn() # reverse.ReverseNormalsOn() # reverse.SetInputConnection(extract_surf.GetOutputPort()) # reverse.Update() - + # polydata = reverse.GetOutput() polydata = extract_surf.GetOutput() - + normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) normalGenerator.ComputeCellNormalsOff() normalGenerator.ComputePointNormalsOn() normalGenerator.ConsistencyOn() - #normalGenerator.AutoOrientNormalsOn() - normalGenerator.SplittingOff() + # normalGenerator.AutoOrientNormalsOn() + normalGenerator.SplittingOff() normalGenerator.Update() - + PointNormalArray = numpy_support.vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) atrial_points = numpy_support.vtk_to_numpy(polydata.GetPoints().GetData()) - - atrial_points = atrial_points + eps*direction*PointNormalArray - + + atrial_points = atrial_points + eps * direction * PointNormalArray + vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_support.numpy_to_vtk(atrial_points)) polydata.SetPoints(vtkPts) - + mesh = vtk.vtkUnstructuredGrid() mesh.DeepCopy(polydata) - + return mesh + def generate_bilayer(endo, epi, max_dist=np.inf): - extract_surf = vtk.vtkGeometryFilter() extract_surf.SetInputData(endo) extract_surf.Update() - + reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() reverse.SetInputConnection(extract_surf.GetOutputPort()) reverse.Update() - + endo = vtk.vtkUnstructuredGrid() endo.DeepCopy(reverse.GetOutput()) - + endo_pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) epi_pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - + tree = cKDTree(epi_pts) - dd, ii = tree.query(endo_pts, distance_upper_bound = max_dist, n_jobs=-1) - - endo_ids = np.where(dd!=np.inf)[0] + dd, ii = tree.query(endo_pts, distance_upper_bound=max_dist, n_jobs=-1) + + endo_ids = np.where(dd != np.inf)[0] epi_ids = ii[endo_ids] lines = vtk.vtkCellArray() - + for i in range(len(endo_ids)): line = vtk.vtkLine() - line.GetPointIds().SetId(0,i); - line.GetPointIds().SetId(1,len(endo_ids)+i); + line.GetPointIds().SetId(0, i); + line.GetPointIds().SetId(1, len(endo_ids) + i); lines.InsertNextCell(line) - + points = np.vstack((endo_pts[endo_ids], epi_pts[epi_ids])) polydata = vtk.vtkUnstructuredGrid() vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_support.numpy_to_vtk(points)) polydata.SetPoints(vtkPts) polydata.SetCells(3, lines) - - fibers = np.zeros((len(endo_ids),3),dtype="float32") - fibers[:,0] = 1 - + + fibers = np.zeros((len(endo_ids), 3), dtype="float32") + fibers[:, 0] = 1 + tag = np.ones((len(endo_ids),), dtype=int) tag[:] = 100 - + meshNew = dsa.WrapDataObject(polydata) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(fibers, "fiber") - fibers = np.zeros((len(endo_ids),3),dtype="float32") - fibers[:,1] = 1 + fibers = np.zeros((len(endo_ids), 3), dtype="float32") + fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - + appendFilter = vtk.vtkAppendFilter() appendFilter.AddInputData(endo) appendFilter.AddInputData(epi) appendFilter.AddInputData(meshNew.VTKObject) appendFilter.MergePointsOn() appendFilter.Update() - + bilayer = appendFilter.GetOutput() - + return bilayer -#Creates VTK and CARP files: .pts, .lon, .elem +# Creates VTK and CARP files: .pts, .lon, .elem def write_bilayer(bilayer): - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(args.mesh+"/RA_bilayer_with_fiber.vtk") + writer.SetFileName(args.mesh + "/RA_bilayer_with_fiber.vtk") writer.SetFileTypeToBinary() writer.SetInputData(bilayer) writer.Write() - + pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - with open(args.mesh+'/RA_bilayer_with_fiber.pts',"w") as f: + with open(args.mesh + '/RA_bilayer_with_fiber.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - + tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - with open(args.mesh+'/RA_bilayer_with_fiber.elem',"w") as f: + with open(args.mesh + '/RA_bilayer_with_fiber.elem', "w") as f: f.write("{}\n".format(bilayer.GetNumberOfCells())) for i in range(bilayer.GetNumberOfCells()): cell = bilayer.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), tag_epi[i])) elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_epi[i])) + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), + tag_epi[i])) else: - print("strange "+ str(cell.GetNumberOfPoints())) + print("strange " + str(cell.GetNumberOfPoints())) el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - - with open(args.mesh+'/RA_bilayer_with_fiber.lon',"w") as f: + + with open(args.mesh + '/RA_bilayer_with_fiber.lon', "w") as f: f.write("2\n") for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], sheet_epi[i][0], sheet_epi[i][1], sheet_epi[i][2])) + f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], + sheet_epi[i][0], sheet_epi[i][1], + sheet_epi[i][2])) print('Generated Bilayer RA') + if __name__ == '__main__': run(args) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py index 524f2d0..d8d8eb7 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py @@ -29,6 +29,7 @@ from vtk.numpy_interface import dataset_adapter as dsa import os + def ra_calculate_gradient(args, model, job): name_list = ['phi', 'r', 'v', 'ab', 'w'] @@ -37,7 +38,7 @@ def ra_calculate_gradient(args, model, job): pointDataToCellData.PassPointDataOn() pointDataToCellData.SetInputData(model) pointDataToCellData.Update() - + for var in name_list: print('Calculating the gradient of ' + str(var) + '...') if var == 'phi': @@ -45,8 +46,9 @@ def ra_calculate_gradient(args, model, job): if args.mesh_type == "vol": gradientFilter = vtk.vtkGradientFilter() gradientFilter.SetInputData(pointDataToCellData.GetOutput()) - gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "phie_"+str(var)) - gradientFilter.SetResultArrayName('grad_'+str(var)) + gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, + "phie_" + str(var)) + gradientFilter.SetResultArrayName('grad_' + str(var)) gradientFilter.Update() RA_gradient = gradientFilter.GetOutput() else: @@ -57,15 +59,16 @@ def ra_calculate_gradient(args, model, job): normalFilter.SplittingOff() normalFilter.Update() RA_gradient = normalFilter.GetOutput() - RA_gradient.GetCellData().GetArray("Normals").SetName('grad_'+str(var)) + RA_gradient.GetCellData().GetArray("Normals").SetName('grad_' + str(var)) else: gradientFilter = vtk.vtkGradientFilter() gradientFilter.SetInputData(RA_gradient) - gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "phie_"+str(var)) - gradientFilter.SetResultArrayName('grad_'+str(var)) + gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, + "phie_" + str(var)) + gradientFilter.SetResultArrayName('grad_' + str(var)) gradientFilter.Update() RA_gradient = gradientFilter.GetOutput() - + print('Calculating the gradient of ' + str(var) + '... Done!') output = vtk.vtkUnstructuredGrid() @@ -73,18 +76,17 @@ def ra_calculate_gradient(args, model, job): if args.debug == 1: # write - simid = job.ID+"/gradient" + simid = job.ID + "/gradient" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) + print("Successfully created the directory %s " % simid) # write the file as vtk writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid+"/RA_with_lp_res_gradient.vtu") + writer.SetFileName(simid + "/RA_with_lp_res_gradient.vtu") writer.SetInputData(output) writer.Write() - - return output + return output diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 5bffedf..78ea2e5 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -42,34 +42,34 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + def ra_generate_fiber(model, args, job): - - simid = job.ID+"/result_RA" + simid = job.ID + "/result_RA" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) - - simid = job.ID+"/bridges" + print("Successfully created the directory %s " % simid) + + simid = job.ID + "/bridges" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) - + print("Successfully created the directory %s " % simid) + # Riunet tao_tv = 0.9 - tao_icv = 0.95 #0.05 # dk01 biatrial fit_both + tao_icv = 0.95 # 0.05 # dk01 biatrial fit_both tao_scv = 0.10 tao_ct_plus = -0.10 tao_ct_minus = -0.13 tao_ib = -0.06 tao_ras = 0.13 tao_raw = 0.55 - with open(os.path.join(EXAMPLE_DIR,'../../element_tag.csv')) as f: + with open(os.path.join(EXAMPLE_DIR, '../../element_tag.csv')) as f: tag_dict = {} reader = csv.DictReader(f) for row in reader: @@ -99,7 +99,7 @@ def ra_generate_fiber(model, args, job): # load bridges tag bachmann_bundel_right = int(tag_dict['bachmann_bundel_right']) bachmann_bundel_internal = int(tag_dict['bachmann_bundel_internal']) - + # load left atrial wall epi left_atrial_wall_epi = int(tag_dict['left_atrial_wall_epi']) @@ -110,16 +110,16 @@ def ra_generate_fiber(model, args, job): pm_num = 15 # size(Radius) of crista terminalis in mm - w_ct = 4.62*args.scale + w_ct = 4.62 * args.scale # size(Radius) of pectinate muscle in mm - w_pm = 0.66*args.scale + w_pm = 0.66 * args.scale # size(Radius) of Bachmann Bundle in mm - w_bb = 2*args.scale - + w_bb = 2 * args.scale + # radius sinus node - r_SN = 2.5*args.scale + r_SN = 2.5 * args.scale # ab ab = model.GetCellData().GetArray('phie_ab') @@ -154,10 +154,10 @@ def ra_generate_fiber(model, args, job): start_time = datetime.datetime.now() print('Calculating fibers... ' + str(start_time)) - + cellid = vtk.vtkIdFilter() cellid.CellIdsOn() - cellid.SetInputData(model) # vtkPolyData() + cellid.SetInputData(model) # vtkPolyData() cellid.PointIdsOn() if int(vtk_version) >= 9: cellid.SetPointIdsArrayName('Global_ids') @@ -165,33 +165,33 @@ def ra_generate_fiber(model, args, job): else: cellid.SetIdsArrayName('Global_ids') cellid.Update() - + model = cellid.GetOutput() - + # TV - - tag = np.zeros((len(ab),), dtype = int) - + + tag = np.zeros((len(ab),), dtype=int) + k = np.copy(ab_grad) - + # # # Get valve using Laplacian solutions # TV_s = Method.vtk_thr(model,0,"CELLS","phie_r",tao_tv) # grad_r - + # TV_ids = vtk.util.numpy_support.vtk_to_numpy(TV_s.GetCellData().GetArray('Global_ids')) # no_TV_s = Method.vtk_thr(model, 1,"CELLS","phie_r",tao_tv) - + # Use fixed thickness ring_ids = np.loadtxt('{}_surf/'.format(args.mesh) + 'ids_TV.vtx', skiprows=2, dtype=int) - rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids,:] + rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] if args.debug: - Method.create_pts(rings_pts,'TV_ring','{}_surf/'.format(args.mesh)) + Method.create_pts(rings_pts, 'TV_ring', '{}_surf/'.format(args.mesh)) - TV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4*args.scale) + TV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) ra_TV = vtk.vtkIdList() for var in TV_ids: @@ -204,7 +204,9 @@ def ra_generate_fiber(model, args, job): TV_s = extract.GetOutput() - ra_diff = list(set(list(vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('Global_ids')))).difference(set(TV_ids))) + ra_diff = list( + set(list(vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('Global_ids')))).difference( + set(TV_ids))) ra_no_TV = vtk.vtkIdList() for var in ra_diff: ra_no_TV.InsertNextId(var) @@ -222,25 +224,23 @@ def ra_generate_fiber(model, args, job): Method.writer_vtk(no_TV_s, '{}_surf/'.format(args.mesh) + "no_tv_s.vtk") # del ra_TV, ra_diff, ra_no_TV - + tag[TV_ids] = tricuspid_valve_epi - - k[TV_ids] = r_grad[TV_ids] + k[TV_ids] = r_grad[TV_ids] - IVC_s = Method.vtk_thr(no_TV_s, 0,"CELLS","phie_v",tao_icv) # Changed 0-1 because ICV and SVC are inverted - no_IVC_s = Method.vtk_thr(no_TV_s, 1,"CELLS","phie_v",tao_icv) #Changed 1-0 + IVC_s = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_v", tao_icv) # Changed 0-1 because ICV and SVC are inverted + no_IVC_s = Method.vtk_thr(no_TV_s, 1, "CELLS", "phie_v", tao_icv) # Changed 1-0 - IVC_s = Method.extract_largest_region(IVC_s) # Added + IVC_s = Method.extract_largest_region(IVC_s) # Added + max_phie_r_ivc = np.max(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_r'))) + 0.2 - max_phie_r_ivc = np.max(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_r')))+0.2 + RAW_s = Method.vtk_thr(no_TV_s, 1, "CELLS", "phie_r", max_phie_r_ivc) # Added +0.03 fro dk01 - RAW_s = Method.vtk_thr(no_TV_s, 1,"CELLS","phie_r", max_phie_r_ivc) # Added +0.03 fro dk01 + SVC_s = Method.vtk_thr(RAW_s, 1, "CELLS", "phie_v", tao_scv) # Changed 1->0 + no_SVC_s = Method.vtk_thr(RAW_s, 0, "CELLS", "phie_v", tao_scv) # Changed 0->1 - SVC_s = Method.vtk_thr(RAW_s, 1,"CELLS","phie_v",tao_scv) # Changed 1->0 - no_SVC_s = Method.vtk_thr(RAW_s, 0,"CELLS","phie_v",tao_scv) #Changed 0->1 - SVC_s = Method.extract_largest_region(SVC_s) if args.debug: # CHECK @@ -249,33 +249,35 @@ def ra_generate_fiber(model, args, job): Method.writer_vtk(SVC_s, '{}_surf/'.format(args.mesh) + "svc_s.vtk") Method.writer_vtk(no_SVC_s, '{}_surf/'.format(args.mesh) + "no_svc_s.vtk") Method.writer_vtk(RAW_s, '{}_surf/'.format(args.mesh) + "raw_s.vtk") - + tao_ct_plus = np.min(vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetCellData().GetArray('phie_w'))) - + SVC_CT_pt = SVC_s.GetPoint(np.argmin(vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetPointData().GetArray('phie_w')))) - + tao_ct_minus = np.min(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_w'))) - + IVC_CT_pt = IVC_s.GetPoint(np.argmin(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) - - IVC_SEPT_CT_pt = IVC_s.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) - - IVC_max_r_CT_pt = IVC_s.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_r')))) # not always the best choice for pm1 - #thr_min = 0.150038 - #thr_max = 0.38518 + IVC_SEPT_CT_pt = IVC_s.GetPoint( + np.argmax(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) + + IVC_max_r_CT_pt = IVC_s.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy( + IVC_s.GetPointData().GetArray('phie_r')))) # not always the best choice for pm1 + + # thr_min = 0.150038 + # thr_max = 0.38518 - #CT_band = Method.vtk_thr(RAW_s, 2,"CELLS","phie_w", thr_min, thr_max) # dk01 fit_both - CT_band = Method.vtk_thr(RAW_s, 2,"CELLS","phie_w", 0.1,tao_ct_plus) # grad_w + # CT_band = Method.vtk_thr(RAW_s, 2,"CELLS","phie_w", thr_min, thr_max) # dk01 fit_both + CT_band = Method.vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w CT_band = Method.extract_largest_region(CT_band) - CT_ub = Method.vtk_thr(RAW_s, 2,"CELLS","phie_w", tao_ct_plus-0.02, tao_ct_plus) # grad_w + CT_ub = Method.vtk_thr(RAW_s, 2, "CELLS", "phie_w", tao_ct_plus - 0.02, tao_ct_plus) # grad_w CT_ub = Method.extract_largest_region(CT_ub) if args.debug: Method.writer_vtk(CT_band, '{}_surf/'.format(args.mesh) + "ct_band.vtk") Method.writer_vtk(CT_ub, '{}_surf/'.format(args.mesh) + "ct_ub.vtk") - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(CT_band) geo_filter.Update() @@ -290,7 +292,7 @@ def ra_generate_fiber(model, args, job): SVC_CT_pt_id = loc.FindClosestPoint(np.array(SVC_CT_pt)) CT_ub_pts = Method.dijkstra_path(mesh_surf, IVC_CT_pt_id, SVC_CT_pt_id) - + filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(CT_band) filter_cell_centers.Update() @@ -299,8 +301,8 @@ def ra_generate_fiber(model, args, job): tree = cKDTree(centroids_array) - ii = tree.query_ball_point(CT_ub_pts, r = 7*args.scale)#, n_jobs=-1) - + ii = tree.query_ball_point(CT_ub_pts, r=7 * args.scale) # , n_jobs=-1) + ii = set([item for sublist in ii for item in sublist]) cell_ids = vtk.vtkIdList() @@ -310,36 +312,36 @@ def ra_generate_fiber(model, args, job): extract.SetInputData(CT_band) extract.SetCellList(cell_ids) extract.Update() - + CT_band = extract.GetOutput() - #IVC_max_r_CT_pt = CT_band.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetPointData().GetArray('phie_r')))) # optional choice for pm, be careful as it overwrites + # IVC_max_r_CT_pt = CT_band.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetPointData().GetArray('phie_r')))) # optional choice for pm, be careful as it overwrites if args.debug: Method.writer_vtk(CT_band, '{}_surf/'.format(args.mesh) + "ct_band_2.vtk") - + CT_band_ids = vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) tao_RAA = np.max(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('phie_v2'))) - #tao_RAA = 0.45 # for patient 20220203 - + # tao_RAA = 0.45 # for patient 20220203 + # CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) - + # tag[CT_ids] = crista_terminalis # CT part from IVC to septum - + loc = vtk.vtkPointLocator() loc.SetDataSet(CT_band) loc.BuildLocator() IVC_CT_pt_id = loc.FindClosestPoint(np.array(IVC_CT_pt)) - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(no_IVC_s) geo_filter.Update() no_IVC_s = geo_filter.GetOutput() - + loc = vtk.vtkPointLocator() loc.SetDataSet(no_IVC_s) loc.BuildLocator() @@ -347,17 +349,18 @@ def ra_generate_fiber(model, args, job): IVC_CT_pt_id = loc.FindClosestPoint(np.array(CT_band.GetPoint(IVC_CT_pt_id))) IVC_max_r_CT_pt_id = loc.FindClosestPoint(np.array(IVC_max_r_CT_pt)) IVC_SEPT_CT_pt_id = loc.FindClosestPoint(np.array(IVC_SEPT_CT_pt)) - - CT_SEPT_path = np.concatenate((Method.dijkstra_path(no_IVC_s, IVC_CT_pt_id, IVC_max_r_CT_pt_id), Method.dijkstra_path(no_IVC_s, IVC_max_r_CT_pt_id, IVC_SEPT_CT_pt_id)), axis=0) - + + CT_SEPT_path = np.concatenate((Method.dijkstra_path(no_IVC_s, IVC_CT_pt_id, IVC_max_r_CT_pt_id), + Method.dijkstra_path(no_IVC_s, IVC_max_r_CT_pt_id, IVC_SEPT_CT_pt_id)), axis=0) + CT_SEPT_ids = Method.get_element_ids_around_path_within_radius(no_IVC_s, CT_SEPT_path, w_ct) # SVC_CT_pt_id = loc.FindClosestPoint(SVC_CT_pt) - - CT_minus = Method.vtk_thr(RAW_s, 1,"CELLS","phie_w", tao_ct_plus) # grad_ab - + + CT_minus = Method.vtk_thr(RAW_s, 1, "CELLS", "phie_w", tao_ct_plus) # grad_ab + RAW_I_ids = vtk.util.numpy_support.vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) - + ii = set(RAW_I_ids) - set(CT_SEPT_ids) - set(CT_band_ids) cell_ids = vtk.vtkIdList() for i in ii: @@ -366,111 +369,110 @@ def ra_generate_fiber(model, args, job): extract.SetInputData(CT_minus) extract.SetCellList(cell_ids) extract.Update() - + CT_minus = extract.GetOutput() - + RAW_I_ids = vtk.util.numpy_support.vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) - + tag[RAW_I_ids] = right_atrial_lateral_wall_epi - + k[TV_ids] = r_grad[TV_ids] - - CT_plus = Method.vtk_thr(RAW_s, 0,"CELLS","phie_w", tao_ct_plus) - - RAW_S = Method.vtk_thr(CT_plus, 2,"CELLS","phie_v", tao_scv, tao_icv) # IB_S grad_v Changed order tao_scv, tao_icv - + + CT_plus = Method.vtk_thr(RAW_s, 0, "CELLS", "phie_w", tao_ct_plus) + + RAW_S = Method.vtk_thr(CT_plus, 2, "CELLS", "phie_v", tao_scv, + tao_icv) # IB_S grad_v Changed order tao_scv, tao_icv + RAW_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_S.GetCellData().GetArray('Global_ids')) - + tag[RAW_S_ids] = right_atrial_lateral_wall_epi - + k[RAW_S_ids] = ab_grad[RAW_S_ids] - - IB = Method.vtk_thr(RAW_S, 1,"CELLS","phie_r", 0.05) # grad_r or w - + + IB = Method.vtk_thr(RAW_S, 1, "CELLS", "phie_r", 0.05) # grad_r or w + IB_ids = vtk.util.numpy_support.vtk_to_numpy(IB.GetCellData().GetArray('Global_ids')) - - tag[IB_ids] = inter_caval_bundle_epi # Change to 68 + + tag[IB_ids] = inter_caval_bundle_epi # Change to 68 if args.debug: Method.writer_vtk(IB, '{}_surf/'.format(args.mesh) + "ib.vtk") Method.writer_vtk(RAW_S, '{}_surf/'.format(args.mesh) + "raw_s.vtk") Method.writer_vtk(CT_plus, '{}_surf/'.format(args.mesh) + "ct_plus.vtk") - k[IB_ids] = v_grad[IB_ids] - - df = pd.read_csv(args.mesh+"_surf/rings_centroids.csv") - + + df = pd.read_csv(args.mesh + "_surf/rings_centroids.csv") + # calculate the norm vector v1 = np.array(df["IVC"]) - np.array(df["SVC"]) v2 = np.array(df["TV"]) - np.array(df["IVC"]) norm = np.cross(v1, v2) - - #normalize norm + + # normalize norm n = np.linalg.norm(norm) - norm_1 = norm/n # Changed sign + norm_1 = norm / n # Changed sign plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) # changed + plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) # changed plane.SetOrigin(df["TV"][0], df["TV"][1], df["TV"][2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(Method.to_polydata(RAW_S)) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() septal_surf = meshExtractFilter.GetOutput() - - RAS_S = Method.vtk_thr(septal_surf, 0,"CELLS","phie_w", tao_ct_plus) - RAS_S = Method.vtk_thr(RAS_S, 0,"CELLS","phie_r", 0.05) # grad_r or w + RAS_S = Method.vtk_thr(septal_surf, 0, "CELLS", "phie_w", tao_ct_plus) + RAS_S = Method.vtk_thr(RAS_S, 0, "CELLS", "phie_r", 0.05) # grad_r or w if args.debug: Method.writer_vtk(septal_surf, '{}_surf/'.format(args.mesh) + "septal_surf.vtk") Method.writer_vtk(RAS_S, '{}_surf/'.format(args.mesh) + "ras_s.vtk") - + RAS_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAS_S.GetCellData().GetArray('Global_ids')) - + tag[RAS_S_ids] = right_atrial_septum_epi - + k[RAS_S_ids] = r_grad[RAS_S_ids] - - RAW_low = Method.vtk_thr(no_TV_s, 0,"CELLS","phie_r", max_phie_r_ivc) - + + RAW_low = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_r", max_phie_r_ivc) + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(RAW_low) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() RAS_low = meshExtractFilter.GetOutput() - - RAS_low = Method.vtk_thr(RAS_low, 0,"CELLS","phie_w", 0) # grad_r overwrites the previous - + + RAS_low = Method.vtk_thr(RAS_low, 0, "CELLS", "phie_w", 0) # grad_r overwrites the previous + RAS_low_ids = vtk.util.numpy_support.vtk_to_numpy(RAS_low.GetCellData().GetArray('Global_ids')) - + tag[RAS_low_ids] = right_atrial_septum_epi - + k[RAS_low_ids] = r_grad[RAS_low_ids] - - RAW_low = Method.vtk_thr(RAW_low, 1,"CELLS","phie_w", 0) # grad_ab - + + RAW_low = Method.vtk_thr(RAW_low, 1, "CELLS", "phie_w", 0) # grad_ab + RAW_low_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_low.GetCellData().GetArray('Global_ids')) - + tag[RAW_low_ids] = right_atrial_lateral_wall_epi - + k[RAW_low_ids] = ab_grad[RAW_low_ids] - + # calculate the norm vector - #v1 = np.array(IVC_SEPT_CT_pt) - np.array(IVC_CT_pt) - #v2 = np.array(df["TV"]) - np.array(df["IVC"]) - #norm = np.cross(v1, v2) + # v1 = np.array(IVC_SEPT_CT_pt) - np.array(IVC_CT_pt) + # v2 = np.array(df["TV"]) - np.array(df["IVC"]) + # norm = np.cross(v1, v2) norm = np.array(df["SVC"]) - np.array(df["IVC"]) - #normalize norm + # normalize norm n = np.linalg.norm(norm) - norm_1 = norm/n + norm_1 = norm / n plane = vtk.vtkPlane() plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) plane.SetOrigin(IVC_SEPT_CT_pt[0], IVC_SEPT_CT_pt[1], IVC_SEPT_CT_pt[2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(no_TV_s) meshExtractFilter.SetImplicitFunction(plane) @@ -479,32 +481,31 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.writer_vtk(septal_surf, '{}_surf/'.format(args.mesh) + "septal_surf_2.vtk") - + CS_ids = vtk.util.numpy_support.vtk_to_numpy(septal_surf.GetCellData().GetArray('Global_ids')) - #if len(CS_ids) == 0: + # if len(CS_ids) == 0: ring_ids = np.loadtxt('{}_surf/'.format(args.mesh) + 'ids_CS.vtx', skiprows=2, dtype=int) - - rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids,:] - - CS_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4*args.scale) - + + rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] + + CS_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) + tag[CS_ids] = coronary_sinus k[CS_ids] = ab_grad[CS_ids] - - #tag = Method.assign_ra_appendage(model, SVC_s, np.array(df["RAA"]), tag, right_atrial_appendage_epi) - RAA_s = Method.vtk_thr(no_TV_s, 0,"CELLS","phie_v2", tao_RAA) + + # tag = Method.assign_ra_appendage(model, SVC_s, np.array(df["RAA"]), tag, right_atrial_appendage_epi) + RAA_s = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_v2", tao_RAA) if args.debug: Method.writer_vtk(RAS_low, '{}_surf/'.format(args.mesh) + "ras_low.vtk") - Method.writer_vtk(RAA_s, '{}_surf/'.format(args.mesh) + "raa_s.vtk") # Check here if RAA is correctly tagged + Method.writer_vtk(RAA_s, '{}_surf/'.format(args.mesh) + "raa_s.vtk") # Check here if RAA is correctly tagged Method.writer_vtk(RAW_low, '{}_surf/'.format(args.mesh) + "raw_low.vtk") - RAA_ids = vtk.util.numpy_support.vtk_to_numpy(RAA_s.GetCellData().GetArray('Global_ids')) - + tag[RAA_ids] = right_atrial_appendage_epi - + loc = vtk.vtkPointLocator() loc.SetDataSet(CT_band) loc.BuildLocator() @@ -515,7 +516,7 @@ def ra_generate_fiber(model, args, job): # v1 = np.array(SVC_CT_pt) - np.array(RAA_CT_pt) # v2 = np.array(SVC_CT_pt) - np.array(df["TV"]) # norm = np.cross(v1, v2) - + # #normalize norm # n = np.linalg.norm(norm) # norm_1 = norm/n @@ -523,51 +524,51 @@ def ra_generate_fiber(model, args, job): # plane = vtk.vtkPlane() # plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) # plane.SetOrigin(SVC_CT_pt[0], SVC_CT_pt[1], SVC_CT_pt[2]) - + # meshExtractFilter = vtk.vtkExtractGeometry() # meshExtractFilter.SetInputData(CT_band) # meshExtractFilter.SetImplicitFunction(plane) # meshExtractFilter.Update() # CT = meshExtractFilter.GetOutput() - + # CT = Method.extract_largest_region(CT) CT = CT_band - + CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) - - CT_ids = np.setdiff1d(CT_ids, RAA_ids, assume_unique = True) - + + CT_ids = np.setdiff1d(CT_ids, RAA_ids, assume_unique=True) + tag[CT_ids] = crista_terminalis - + k[CT_ids] = w_grad[CT_ids] - + tag[CT_SEPT_ids] = crista_terminalis - + SVC_ids = vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetCellData().GetArray('Global_ids')) - + tag[SVC_ids] = superior_vena_cava_epi - + k[SVC_ids] = v_grad[SVC_ids] - + IVC_ids = vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('Global_ids')) - + tag[IVC_ids] = inferior_vena_cava_epi - + k[IVC_ids] = v_grad[IVC_ids] - + tag = np.where(tag == 0, right_atrial_lateral_wall_epi, tag) - + SN_ids = Method.get_element_ids_around_path_within_radius(no_SVC_s, np.asarray([SVC_CT_pt]), r_SN) - + tag[SN_ids] = sinus_node - + # meshNew = dsa.WrapDataObject(model) # meshNew.CellData.append(tag, "elemTag") # writer = vtk.vtkUnstructuredGridWriter() # writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") # writer.SetInputData(meshNew.VTKObject) # writer.Write() - + # print('Region growing...to get the tao_ct_minus...') # # extract septum # thresh = vtk.vtkThreshold() @@ -601,7 +602,6 @@ def ra_generate_fiber(model, args, job): # points_data = SCV.GetPoints().GetData() # SCV_points = vtk.util.numpy_support.vtk_to_numpy(points_data) - # """ # region growing to get tao_ct_minus # """ @@ -697,14 +697,14 @@ def ra_generate_fiber(model, args, job): # if v[i] <= tao_scv: # tag[i] = superior_vena_cava_epi # # tag = Method.assign_ra_appendage(model, SCV, ra_appex_point, tag, right_atrial_appendage_epi) - + # meshNew = dsa.WrapDataObject(model) # meshNew.CellData.append(tag, "elemTag") # writer = vtk.vtkUnstructuredGridWriter() # writer.SetFileName(job.ID+"/result_RA/RA_Tianbao_epi_with_fiber.vtk") # writer.SetInputData(meshNew.VTKObject) # writer.Write() - + print('Bundles selection...done') # normalize the gradient phie abs_phie_grad = np.linalg.norm(phie_grad, axis=1, keepdims=True) @@ -718,16 +718,16 @@ def ra_generate_fiber(model, args, job): # print(et) # k - #k = ab_grad + # k = ab_grad print('############### k ###############') # print(k) # en - #en = ab_grad + # en = ab_grad # for i in range(len(k)): # en[i] = k[i] - np.dot(k[i], et[i]) * et[i] - - en = k - et*np.sum(k*et,axis=1).reshape(len(et),1) + + en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) # normlize the en # abs_en = np.linalg.norm(en, axis=1, keepdims=True) # for i in range(len(abs_en)): @@ -742,26 +742,26 @@ def ra_generate_fiber(model, args, job): # el el = np.cross(en, et) - + el = Method.assign_element_fiber_around_path_within_radius(model, CT_SEPT_path, w_ct, el, smooth=True) - - el = np.where(el == [0,0,0], [1,0,0], el).astype("float32") + + el = np.where(el == [0, 0, 0], [1, 0, 0], el).astype("float32") print('############### el ###############') # print(el) end_time = datetime.datetime.now() running_time = end_time - start_time print('Calculating epicardial fibers... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - + if args.mesh_type == "bilayer": sheet = np.cross(el, et) - - for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): + + for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) - + meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") @@ -770,21 +770,21 @@ def ra_generate_fiber(model, args, job): writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - + """ PM and CT """ cellid = vtk.vtkIdFilter() cellid.CellIdsOn() - cellid.SetInputData(meshNew.VTKObject) # vtkPolyData() + cellid.SetInputData(meshNew.VTKObject) # vtkPolyData() cellid.PointIdsOn() if int(vtk_version) >= 9: cellid.SetPointIdsArrayName('Global_ids') @@ -792,14 +792,14 @@ def ra_generate_fiber(model, args, job): else: cellid.SetIdsArrayName('Global_ids') cellid.Update() - + model = cellid.GetOutput() - + endo = vtk.vtkUnstructuredGrid() endo.DeepCopy(model) - - CT = Method.vtk_thr(model, 2,"CELLS","elemTag", crista_terminalis, crista_terminalis) - + + CT = Method.vtk_thr(model, 2, "CELLS", "elemTag", crista_terminalis, crista_terminalis) + CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) elif args.mesh_type == "vol": @@ -819,7 +819,7 @@ def ra_generate_fiber(model, args, job): CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) if args.debug: - + meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") @@ -827,59 +827,59 @@ def ra_generate_fiber(model, args, job): writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - - center = np.asarray((np.array(df["SVC"])+np.array(df["IVC"]))/2) - + + center = np.asarray((np.array(df["SVC"]) + np.array(df["IVC"])) / 2) + loc = vtk.vtkPointLocator() loc.SetDataSet(CT) loc.BuildLocator() - + point1_id = loc.FindClosestPoint(IVC_max_r_CT_pt) point2_id = loc.FindClosestPoint(SVC_CT_pt) - + loc = vtk.vtkPointLocator() loc.SetDataSet(TV_s) loc.BuildLocator() - + point3_id = loc.FindClosestPoint(IVC_max_r_CT_pt) point4_id = loc.FindClosestPoint(np.array(df["RAA"])) # this is also the id for Bachmann-Bundle on the right atrium - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(CT) geo_filter.Update() CT = geo_filter.GetOutput() - + # calculate the norm vector v1 = np.array(df["IVC"]) - np.array(df["SVC"]) v2 = np.array(df["TV"]) - np.array(df["IVC"]) norm = np.cross(v2, v1) - - #normalize norm + + # normalize norm n = np.linalg.norm(norm) - norm_1 = norm/n + norm_1 = norm / n plane = vtk.vtkPlane() plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) plane.SetOrigin(df["TV"][0], df["TV"][1], df["TV"][2]) - + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(TV_s) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() TV_lat = meshExtractFilter.GetOutput() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(TV_lat) geo_filter.Update() TV_lat = geo_filter.GetOutput() - + cln = vtk.vtkCleanPolyData() cln.SetInputData(TV_lat) cln.Update() @@ -887,35 +887,36 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.writer_vtk(TV_lat, '{}_surf/'.format(args.mesh) + "TV_lat.vtk") - + # writer = vtk.vtkPolyDataWriter() # writer.SetFileName("TV_lat.vtk") # writer.SetInputData(TV_lat) # writer.Write() - + ct_points_data = Method.dijkstra_path(CT, point1_id, point2_id) - + # np.savetxt("ct_points_data.txt", ct_points_data, fmt='%.4f') if args.debug: Method.create_pts(ct_points_data, 'ct_points_data', '{}_surf/'.format(args.mesh)) - + loc = vtk.vtkPointLocator() loc.SetDataSet(TV_lat) loc.BuildLocator() - + point3_id = loc.FindClosestPoint(TV_s.GetPoint(point3_id)) - point4_id = loc.FindClosestPoint(TV_s.GetPoint(point4_id)) # this is also the id for Bachmann-Bundle on the right atrium - + point4_id = loc.FindClosestPoint( + TV_s.GetPoint(point4_id)) # this is also the id for Bachmann-Bundle on the right atrium + tv_points_data = Method.dijkstra_path(TV_lat, point3_id, point4_id) if args.debug: Method.create_pts(tv_points_data, 'tv_points_data', '{}_surf/'.format(args.mesh)) # np.savetxt("tv_points_data.txt", tv_points_data, fmt='%.4f') - + # np.savetxt("point3_id_new.txt", TV_lat.GetPoint(point3_id), fmt='%.4f') # np.savetxt("point4_id_new.txt", TV_lat.GetPoint(point4_id), fmt='%.4f') - + print("Creating Pectinate muscle...") if args.mesh_type == "vol": @@ -929,9 +930,9 @@ def ra_generate_fiber(model, args, job): geo_filter.Update() surface = geo_filter.GetOutput() - epi = Method.vtk_thr(surface, 0,"POINTS","phie_phi", 0.5) + epi = Method.vtk_thr(surface, 0, "POINTS", "phie_phi", 0.5) - endo = Method.vtk_thr(surface, 1,"POINTS","phie_phi", 0.5) + endo = Method.vtk_thr(surface, 1, "POINTS", "phie_phi", 0.5) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(endo) @@ -942,7 +943,7 @@ def ra_generate_fiber(model, args, job): fiber_endo = el.copy() tag_endo = np.copy(tag) - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(endo) geo_filter.Update() @@ -962,188 +963,185 @@ def ra_generate_fiber(model, args, job): pm_ct_dis = int(len(ct_points_data) / pm_num) pm_tv_dis = int(len(tv_points_data) / pm_num) - - # the first PM is the one to the appendage - - # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) - - # tag = Method.assign_element_tag_around_path_within_radius(mesh, pm, w_pm, tag, pectinate_muscle) - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, pm, w_pm, fiber_endo, smooth=True) - - # for i in range(pm_num): - # pm_point_1 = pm_ct_id_list[(i + 1) * pm_ct_dis] - # pm_point_2 = pm_tv_id_list[(i + 1) * pm_tv_dis] - # pm = Method.dijkstra_path_on_a_plane(surface, args, pm_point_1, pm_point_2, center) - # # pm = Method.dijkstra_path(surface, pm_point_1, pm_point_2) - # # if i == 0: - # # pm = Method.dijkstra_path(surface, pm_point_1, pm_point_2) - # # else: - # # pm = Method.dijkstra_path_on_a_plane(surface, pm_point_1, pm_point_2, center) - # print("The ", i + 1, "th pm done") - # tag = Method.assign_element_tag_around_path_within_radius(mesh, pm, w_pm, tag, pectinate_muscle) - # print("The ", i + 1, "th pm's tag is done") - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, pm, w_pm, fiber_endo, smooth=True) - # print("The ", i + 1, "th pm's fiber is done") - - # print("Creating Pectinate muscle... done!") - - # # Crista Terminalis - # print("Creating Crista Terminalis...") - # tag = Method.assign_element_tag_around_path_within_radius(mesh, ct_points_data, w_ct, tag, crista_terminalis) - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, ct_points_data, w_ct, fiber_endo, smooth=True) - # print("Creating Crista Terminalis... done!") - - # """ - # over write the pm on the TV - # """ - # for i in range(len(ab_grad)): - # if r[i] >= tao_tv: - # fiber_endo[i] = el[i] - # if phie[i] <= 0.5: - # tag[i] = tricuspid_valve_endo - # else: - # tag[i] = tricuspid_valve_epi - - # # Bachmann-Bundle - - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(surface) - # loc.BuildLocator() - - # # Bachmann-Bundle starting point - # bb_1_id = loc.FindClosestPoint(SVC_CT_pt) - # bb_2_id = loc.FindClosestPoint(TV_s.GetPoint(point4_id)) - - # bachmann_bundle_points_data = Method.dijkstra_path(surface, bb_1_id, bb_2_id) - # bb_step = 10 - # bb_path = np.asarray([bachmann_bundle_points_data[i] for i in range(len(bachmann_bundle_points_data)) if i % bb_step == 0 or i == len(bachmann_bundle_points_data)-1]) - # spline_points = vtk.vtkPoints() - # for i in range(len(bb_path)): - # spline_points.InsertPoint(i, bb_path[i][0], bb_path[i][1], bb_path[i][2]) - - # # Fit a spline to the points - # spline = vtk.vtkParametricSpline() - # spline.SetPoints(spline_points) - # functionSource = vtk.vtkParametricFunctionSource() - # functionSource.SetParametricFunction(spline) - # functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - # functionSource.Update() - - # bb_points = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) - - # tag = Method.assign_element_tag_around_path_within_radius(model, bb_points, w_bb, tag, bachmann_bundel_right) - # el = Method.assign_element_fiber_around_path_within_radius(model, bb_points, w_bb, el, smooth=True) - - # tag[SN_ids] = sinus_node - - # for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): - # model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - # for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): - # model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) - - # meshNew = dsa.WrapDataObject(model) - # meshNew.CellData.append(tag, "elemTag") - # meshNew.CellData.append(el, "fiber") - # meshNew.CellData.append(sheet, "sheet") - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - - # # Bachmann_Bundle internal connection - # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(df["LAA"]) - # la_connect_point = np.asarray(la_connect_point) - # ra_connect_point = np.asarray(ra_connect_point) - - # la_epi = Method.smart_reader("/home/luca/IBT/AtrialLDRBM_la816/LDRBM/Fiber_LA/result_RA/LA_epi_with_fiber.vtk") - # la_appendage_basis_point = np.asarray(df["LAA_basis_inf"]) - # length = len(bachmann_bundle_points_data) - # ra_bb_center = bachmann_bundle_points_data[int(length * 0.45)] - # # TODO PLAN D - # geo_filter_la_epi = vtk.vtkGeometryFilter() - # geo_filter_la_epi.SetInputData(la_epi) - # geo_filter_la_epi.Update() - # la_epi = geo_filter_la_epi.GetOutput() - - # geo_filter_ra_epi = vtk.vtkGeometryFilter() - # geo_filter_ra_epi.SetInputData(model) - # geo_filter_ra_epi.Update() - # ra_epi = geo_filter_ra_epi.GetOutput() - - # loc_la_epi = vtk.vtkPointLocator() - # loc_la_epi.SetDataSet(la_epi) - # loc_la_epi.BuildLocator() - - # loc_ra_epi = vtk.vtkPointLocator() - # loc_ra_epi.SetDataSet(ra_epi) - # loc_ra_epi.BuildLocator() - - # ra_a_id = loc_ra_epi.FindClosestPoint(ra_bb_center) - # ra_b_id = loc_ra_epi.FindClosestPoint(ra_connect_point) - # la_c_id = loc_la_epi.FindClosestPoint(la_connect_point) - # la_d_id = loc_la_epi.FindClosestPoint(la_appendage_basis_point) - # path_1 = Method.dijkstra_path(ra_epi, ra_a_id, ra_b_id) - # path_2 = Method.dijkstra_path(la_epi, la_c_id, la_d_id) - # path_all_temp = np.vstack((path_1, path_2)) - # # down sampling to smooth the path - # step = 10 - # path_all = np.asarray([path_all_temp[i] for i in range(len(path_all_temp)) if i % step == 0 or i == len(path_all_temp)-1]) - - # # save points for bb fiber - # filename = job.ID+'/bridges/bb_fiber.dat' - # f = open(filename, 'wb') - # pickle.dump(path_all, f) - # f.close() - - - # # BB tube - - # bb_tube = Method.creat_tube_around_spline(path_all, 2) - # sphere_a = Method.creat_sphere(la_appendage_basis_point, 2 * 1.02) - # sphere_b = Method.creat_sphere(ra_bb_center, 2 * 1.02) - # Method.smart_bridge_writer(bb_tube, sphere_a, sphere_b, "BB_intern_bridges") - - - # # tag = Method.assign_element_tag_around_path_within_radius(mesh, path_bb_ra, w_bb, tag, bachmann_bundel_right) - # # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, path_bb_ra, w_bb, fiber_endo, - # # smooth=True) - - # tag_data = vtk.util.numpy_support.numpy_to_vtk(tag, deep=True, array_type=vtk.VTK_INT) - # tag_data.SetNumberOfComponents(1) - # tag_data.SetName("elemTag") - # model.GetCellData().RemoveArray("elemTag") - # model.GetCellData().SetScalars(tag_data) - - # #model.GetCellData().AddArray(tag_data) - # abs_el = np.linalg.norm(fiber_endo, axis=1, keepdims=True) - # interpolate_arr = np.asarray([0, 0, 1]) - # index = np.argwhere(abs_el == 0) - # print('There is',len(index),'zero vector(s).') - # for var in index: - # fiber_endo[var[0]] = interpolate_arr - - # fiber_data = vtk.util.numpy_support.numpy_to_vtk(fiber_endo, deep=True, array_type=vtk.VTK_DOUBLE) - # fiber_data.SetNumberOfComponents(3) - # fiber_data.SetName("fiber") - # model.GetCellData().SetVectors(fiber_data) - - - # start_time = datetime.datetime.now() - # print('Writing as RA_with_fiber... ' + str(start_time)) - # meshNew = dsa.WrapDataObject(mesh) - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/RA_with_fiber.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - # end_time = datetime.datetime.now() - # running_time = end_time - start_time - # print('Writing as RA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - + + # the first PM is the one to the appendage + + # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) + + # tag = Method.assign_element_tag_around_path_within_radius(mesh, pm, w_pm, tag, pectinate_muscle) + # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, pm, w_pm, fiber_endo, smooth=True) + + # for i in range(pm_num): + # pm_point_1 = pm_ct_id_list[(i + 1) * pm_ct_dis] + # pm_point_2 = pm_tv_id_list[(i + 1) * pm_tv_dis] + # pm = Method.dijkstra_path_on_a_plane(surface, args, pm_point_1, pm_point_2, center) + # # pm = Method.dijkstra_path(surface, pm_point_1, pm_point_2) + # # if i == 0: + # # pm = Method.dijkstra_path(surface, pm_point_1, pm_point_2) + # # else: + # # pm = Method.dijkstra_path_on_a_plane(surface, pm_point_1, pm_point_2, center) + # print("The ", i + 1, "th pm done") + # tag = Method.assign_element_tag_around_path_within_radius(mesh, pm, w_pm, tag, pectinate_muscle) + # print("The ", i + 1, "th pm's tag is done") + # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, pm, w_pm, fiber_endo, smooth=True) + # print("The ", i + 1, "th pm's fiber is done") + + # print("Creating Pectinate muscle... done!") + + # # Crista Terminalis + # print("Creating Crista Terminalis...") + # tag = Method.assign_element_tag_around_path_within_radius(mesh, ct_points_data, w_ct, tag, crista_terminalis) + # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, ct_points_data, w_ct, fiber_endo, smooth=True) + # print("Creating Crista Terminalis... done!") + + # """ + # over write the pm on the TV + # """ + # for i in range(len(ab_grad)): + # if r[i] >= tao_tv: + # fiber_endo[i] = el[i] + # if phie[i] <= 0.5: + # tag[i] = tricuspid_valve_endo + # else: + # tag[i] = tricuspid_valve_epi + + # # Bachmann-Bundle + + # loc = vtk.vtkPointLocator() + # loc.SetDataSet(surface) + # loc.BuildLocator() + + # # Bachmann-Bundle starting point + # bb_1_id = loc.FindClosestPoint(SVC_CT_pt) + # bb_2_id = loc.FindClosestPoint(TV_s.GetPoint(point4_id)) + + # bachmann_bundle_points_data = Method.dijkstra_path(surface, bb_1_id, bb_2_id) + # bb_step = 10 + # bb_path = np.asarray([bachmann_bundle_points_data[i] for i in range(len(bachmann_bundle_points_data)) if i % bb_step == 0 or i == len(bachmann_bundle_points_data)-1]) + # spline_points = vtk.vtkPoints() + # for i in range(len(bb_path)): + # spline_points.InsertPoint(i, bb_path[i][0], bb_path[i][1], bb_path[i][2]) + + # # Fit a spline to the points + # spline = vtk.vtkParametricSpline() + # spline.SetPoints(spline_points) + # functionSource = vtk.vtkParametricFunctionSource() + # functionSource.SetParametricFunction(spline) + # functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) + # functionSource.Update() + + # bb_points = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + + # tag = Method.assign_element_tag_around_path_within_radius(model, bb_points, w_bb, tag, bachmann_bundel_right) + # el = Method.assign_element_fiber_around_path_within_radius(model, bb_points, w_bb, el, smooth=True) + + # tag[SN_ids] = sinus_node + + # for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): + # model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) + + # for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): + # model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) + + # meshNew = dsa.WrapDataObject(model) + # meshNew.CellData.append(tag, "elemTag") + # meshNew.CellData.append(el, "fiber") + # meshNew.CellData.append(sheet, "sheet") + # writer = vtk.vtkUnstructuredGridWriter() + # writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") + # writer.SetInputData(meshNew.VTKObject) + # writer.Write() + + # # Bachmann_Bundle internal connection + # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(df["LAA"]) + # la_connect_point = np.asarray(la_connect_point) + # ra_connect_point = np.asarray(ra_connect_point) + + # la_epi = Method.smart_reader("/home/luca/IBT/AtrialLDRBM_la816/LDRBM/Fiber_LA/result_RA/LA_epi_with_fiber.vtk") + # la_appendage_basis_point = np.asarray(df["LAA_basis_inf"]) + # length = len(bachmann_bundle_points_data) + # ra_bb_center = bachmann_bundle_points_data[int(length * 0.45)] + # # TODO PLAN D + # geo_filter_la_epi = vtk.vtkGeometryFilter() + # geo_filter_la_epi.SetInputData(la_epi) + # geo_filter_la_epi.Update() + # la_epi = geo_filter_la_epi.GetOutput() + + # geo_filter_ra_epi = vtk.vtkGeometryFilter() + # geo_filter_ra_epi.SetInputData(model) + # geo_filter_ra_epi.Update() + # ra_epi = geo_filter_ra_epi.GetOutput() + + # loc_la_epi = vtk.vtkPointLocator() + # loc_la_epi.SetDataSet(la_epi) + # loc_la_epi.BuildLocator() + + # loc_ra_epi = vtk.vtkPointLocator() + # loc_ra_epi.SetDataSet(ra_epi) + # loc_ra_epi.BuildLocator() + + # ra_a_id = loc_ra_epi.FindClosestPoint(ra_bb_center) + # ra_b_id = loc_ra_epi.FindClosestPoint(ra_connect_point) + # la_c_id = loc_la_epi.FindClosestPoint(la_connect_point) + # la_d_id = loc_la_epi.FindClosestPoint(la_appendage_basis_point) + # path_1 = Method.dijkstra_path(ra_epi, ra_a_id, ra_b_id) + # path_2 = Method.dijkstra_path(la_epi, la_c_id, la_d_id) + # path_all_temp = np.vstack((path_1, path_2)) + # # down sampling to smooth the path + # step = 10 + # path_all = np.asarray([path_all_temp[i] for i in range(len(path_all_temp)) if i % step == 0 or i == len(path_all_temp)-1]) + + # # save points for bb fiber + # filename = job.ID+'/bridges/bb_fiber.dat' + # f = open(filename, 'wb') + # pickle.dump(path_all, f) + # f.close() + + # # BB tube + + # bb_tube = Method.creat_tube_around_spline(path_all, 2) + # sphere_a = Method.creat_sphere(la_appendage_basis_point, 2 * 1.02) + # sphere_b = Method.creat_sphere(ra_bb_center, 2 * 1.02) + # Method.smart_bridge_writer(bb_tube, sphere_a, sphere_b, "BB_intern_bridges") + + # # tag = Method.assign_element_tag_around_path_within_radius(mesh, path_bb_ra, w_bb, tag, bachmann_bundel_right) + # # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, path_bb_ra, w_bb, fiber_endo, + # # smooth=True) + + # tag_data = vtk.util.numpy_support.numpy_to_vtk(tag, deep=True, array_type=vtk.VTK_INT) + # tag_data.SetNumberOfComponents(1) + # tag_data.SetName("elemTag") + # model.GetCellData().RemoveArray("elemTag") + # model.GetCellData().SetScalars(tag_data) + + # #model.GetCellData().AddArray(tag_data) + # abs_el = np.linalg.norm(fiber_endo, axis=1, keepdims=True) + # interpolate_arr = np.asarray([0, 0, 1]) + # index = np.argwhere(abs_el == 0) + # print('There is',len(index),'zero vector(s).') + # for var in index: + # fiber_endo[var[0]] = interpolate_arr + + # fiber_data = vtk.util.numpy_support.numpy_to_vtk(fiber_endo, deep=True, array_type=vtk.VTK_DOUBLE) + # fiber_data.SetNumberOfComponents(3) + # fiber_data.SetName("fiber") + # model.GetCellData().SetVectors(fiber_data) + + # start_time = datetime.datetime.now() + # print('Writing as RA_with_fiber... ' + str(start_time)) + # meshNew = dsa.WrapDataObject(mesh) + # writer = vtk.vtkUnstructuredGridWriter() + # writer.SetFileName(job.ID+"/result_RA/RA_with_fiber.vtk") + # writer.SetInputData(meshNew.VTKObject) + # writer.Write() + # end_time = datetime.datetime.now() + # running_time = end_time - start_time + # print('Writing as RA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') + # Pectinate muscle print("Creating Pectinate muscle 1") # the first PM is the one to the appendage - #pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) + # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) loc = vtk.vtkPointLocator() loc.SetDataSet(surface) @@ -1153,16 +1151,15 @@ def ra_generate_fiber(model, args, job): # Pectinate muscle going from the septum spurius to the RAA apex pm = Method.dijkstra_path(surface, RAA_CT_id, point_apx_id) - pm = Method.downsample_path(pm, int(len(pm)*0.1)) + pm = Method.downsample_path(pm, int(len(pm) * 0.1)) if args.debug: Method.create_pts(pm, 'pm_0_downsampled', '{}_surf/'.format(args.mesh)) - if args.mesh_type == "bilayer": - + tag_endo = Method.assign_element_tag_around_path_within_radius(endo, pm, w_pm, tag_endo, pectinate_muscle) fiber_endo = Method.assign_element_fiber_around_path_within_radius(endo, pm, w_pm, fiber_endo, smooth=False) - + elif args.mesh_type == "vol": filter_cell_centers = vtk.vtkCellCenters() @@ -1172,7 +1169,7 @@ def ra_generate_fiber(model, args, job): tree = cKDTree(centroids_array) - ii = tree.query_ball_point(pm, r = w_pm, n_jobs=-1) + ii = tree.query_ball_point(pm, r=w_pm, n_jobs=-1) ii = list(set([item for sublist in ii for item in sublist])) @@ -1180,20 +1177,18 @@ def ra_generate_fiber(model, args, job): el = Method.assign_element_fiber_around_path_within_radius(model, pm, w_pm, el, smooth=False) - for i in range(3,pm_num-1): # skip the first 3 pm as they will be in the IVC side + for i in range(3, pm_num - 1): # skip the first 3 pm as they will be in the IVC side pm_point_1 = pm_ct_id_list[(i + 1) * pm_ct_dis] pm_point_2 = pm_tv_id_list[(i + 1) * pm_tv_dis] pm = Method.dijkstra_path_on_a_plane(surface, args, pm_point_1, pm_point_2, center) - #skip first 3% of the points since they will be on the roof of the RA - pm = pm[int(len(pm)*0.03):,:] # + # skip first 3% of the points since they will be on the roof of the RA + pm = pm[int(len(pm) * 0.03):, :] # - - pm = Method.downsample_path(pm, int(len(pm)*0.065)) + pm = Method.downsample_path(pm, int(len(pm) * 0.065)) if args.debug: - Method.create_pts(pm, 'pm_'+ str(i+1) +'_downsampled', '{}_surf/'.format(args.mesh)) - + Method.create_pts(pm, 'pm_' + str(i + 1) + '_downsampled', '{}_surf/'.format(args.mesh)) print("The ", i + 1, "th pm done") if args.mesh_type == "bilayer": @@ -1205,146 +1200,145 @@ def ra_generate_fiber(model, args, job): elif args.mesh_type == "vol": - ii = tree.query_ball_point(pm, r = w_pm, n_jobs=-1) + ii = tree.query_ball_point(pm, r=w_pm, n_jobs=-1) ii = list(set([item for sublist in ii for item in sublist])) tag[ii] = pectinate_muscle el = Method.assign_element_fiber_around_path_within_radius(model, pm, w_pm, el, smooth=False) - + # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) - + # tag_endo = Method.assign_element_tag_around_path_within_radius(endo, pm, w_pm, tag_endo, pectinate_muscle) # fiber_endo = Method.assign_element_fiber_around_path_within_radius(endo, pm, w_pm, fiber_endo, smooth=True) - + # for i in range(pm_num): # pm_point_1 = pm_ct_id_list[(i + 1) * pm_ct_dis] # pm_point_2 = pm_tv_id_list[(i + 1) * pm_tv_dis] - + # pm = Method.dijkstra_path_on_a_plane(surface, args, pm_point_1, pm_point_2, center) # pm = pm[int(len(pm)*0.05):,:] # print("The ", i + 1, "th pm done") # tag_endo = Method.assign_element_tag_around_path_within_radius(endo, pm, w_pm, tag_endo, pectinate_muscle) # fiber_endo = Method.assign_element_fiber_around_path_within_radius(endo, pm, w_pm, fiber_endo, smooth=True) - + if args.mesh_type == "bilayer": print("Creating Pectinate muscle... done!") - + # Crista Terminalis print("Creating Crista Terminalis...") tag_endo[CT_ids] = tag[CT_ids] fiber_endo[CT_ids] = el[CT_ids] print("Creating Crista Terminalis... done!") - + """ overwrite the pm on the TV """ tag_endo[TV_ids] = tag[TV_ids] fiber_endo[TV_ids] = el[TV_ids] - + tag_endo[IVC_ids] = tag[IVC_ids] fiber_endo[IVC_ids] = el[IVC_ids] - + tag_endo[SN_ids] = sinus_node tag_endo[IVC_ids] = tag[IVC_ids] - - for i in range(endo.GetPointData().GetNumberOfArrays()-1, -1, -1): + + for i in range(endo.GetPointData().GetNumberOfArrays() - 1, -1, -1): endo.GetPointData().RemoveArray(endo.GetPointData().GetArrayName(i)) - - for i in range(endo.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(endo.GetCellData().GetNumberOfArrays() - 1, -1, -1): endo.GetCellData().RemoveArray(endo.GetCellData().GetArrayName(i)) - - fiber_endo = np.where(fiber_endo == [0,0,0], [1,0,0], fiber_endo).astype("float32") + + fiber_endo = np.where(fiber_endo == [0, 0, 0], [1, 0, 0], fiber_endo).astype("float32") sheet = np.cross(fiber_endo, et) - sheet = np.where(sheet == [0,0,0], [1,0,0], sheet).astype("float32") + sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") meshNew = dsa.WrapDataObject(endo) meshNew.CellData.append(tag_endo, "elemTag") meshNew.CellData.append(fiber_endo, "fiber") meshNew.CellData.append(sheet, "sheet") - + endo = meshNew.VTKObject - + writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_endo_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_endo_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtu") writer.SetInputData(endo) writer.Write() - - CT_PMs = Method.vtk_thr(endo,2,"CELLS","elemTag",pectinate_muscle, crista_terminalis) - + + CT_PMs = Method.vtk_thr(endo, 2, "CELLS", "elemTag", pectinate_muscle, crista_terminalis) + writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_CT_PMs.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_CT_PMs.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") writer.SetInputData(CT_PMs) writer.Write() elif args.mesh_type == "vol": - + print("Creating Pectinate muscle... done!") - + # Crista Terminalis print("Creating Crista Terminalis...") tag[CT_ids] = tag_old[CT_ids] el[CT_ids] = el_old[CT_ids] print("Creating Crista Terminalis... done!") - + """ overwrite the pm on the TV """ tag[TV_ids] = tag_old[TV_ids] el[TV_ids] = el_old[TV_ids] - + tag[IVC_ids] = tag_old[IVC_ids] el[IVC_ids] = el_old[IVC_ids] - + tag[SN_ids] = sinus_node tag[IVC_ids] = tag_old[IVC_ids] - + if args.debug: - for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): + for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) - - el = np.where(el == [0,0,0], [1,0,0], el).astype("float32") + + el = np.where(el == [0, 0, 0], [1, 0, 0], el).astype("float32") sheet = np.cross(el, et) - sheet = np.where(sheet == [0,0,0], [1,0,0], sheet).astype("float32") + sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") meshNew.CellData.append(sheet, "sheet") - + writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_endo_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_endo_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - - # Bachmann-Bundle - if args.mesh_type =="vol": + # Bachmann-Bundle + if args.mesh_type == "vol": geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(epi) geo_filter.Update() @@ -1353,32 +1347,33 @@ def ra_generate_fiber(model, args, job): loc = vtk.vtkPointLocator() loc.SetDataSet(RAS_S) loc.BuildLocator() - - bb_c_id = loc.FindClosestPoint((np.array(df["TV"])+np.array(df["SVC"]))/2) - + + bb_c_id = loc.FindClosestPoint((np.array(df["TV"]) + np.array(df["SVC"])) / 2) + loc = vtk.vtkPointLocator() loc.SetDataSet(surface) loc.BuildLocator() - + # Bachmann-Bundle starting point bb_1_id = loc.FindClosestPoint(SVC_CT_pt) bb_2_id = loc.FindClosestPoint(TV_lat.GetPoint(point4_id)) bb_c_id = loc.FindClosestPoint(RAS_S.GetPoint(bb_c_id)) bachmann_bundle_points_data_1 = Method.dijkstra_path(surface, bb_1_id, bb_c_id) - + bachmann_bundle_points_data_2 = Method.dijkstra_path(surface, bb_c_id, bb_2_id) - + bachmann_bundle_points_data = np.concatenate((bachmann_bundle_points_data_1, bachmann_bundle_points_data_2), axis=0) - - np.savetxt(job.ID+'/bb.txt',bachmann_bundle_points_data,fmt='%.5f') # Change directory - bb_step = int(len(bachmann_bundle_points_data)*0.1) - bb_path = np.asarray([bachmann_bundle_points_data[i] for i in range(len(bachmann_bundle_points_data)) if i % bb_step == 0 or i == len(bachmann_bundle_points_data)-1]) + np.savetxt(job.ID + '/bb.txt', bachmann_bundle_points_data, fmt='%.5f') # Change directory + + bb_step = int(len(bachmann_bundle_points_data) * 0.1) + bb_path = np.asarray([bachmann_bundle_points_data[i] for i in range(len(bachmann_bundle_points_data)) if + i % bb_step == 0 or i == len(bachmann_bundle_points_data) - 1]) spline_points = vtk.vtkPoints() for i in range(len(bb_path)): spline_points.InsertPoint(i, bb_path[i][0], bb_path[i][1], bb_path[i][2]) - + # Fit a spline to the points spline = vtk.vtkParametricSpline() spline.SetPoints(spline_points) @@ -1386,48 +1381,48 @@ def ra_generate_fiber(model, args, job): functionSource.SetParametricFunction(spline) functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) functionSource.Update() - + bb_points = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) - + tag = Method.assign_element_tag_around_path_within_radius(model, bb_points, w_bb, tag, bachmann_bundel_right) el = Method.assign_element_fiber_around_path_within_radius(model, bb_points, w_bb, el, smooth=True) - + tag[SN_ids] = sinus_node - - for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): + + for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): + + for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) - - el = np.where(el == [0,0,0], [1,0,0], el).astype("float32") + + el = np.where(el == [0, 0, 0], [1, 0, 0], el).astype("float32") sheet = np.cross(el, et) - sheet = np.where(sheet == [0,0,0], [1,0,0], sheet).astype("float32") + sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") meshNew.CellData.append(sheet, "sheet") writer = vtk.vtkUnstructuredGridWriter() - + if args.mesh_type == "bilayer": if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtu") else: if args.ofmt == 'vtk': writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_vol_with_fiber.vtk") + writer.SetFileName(job.ID + "/result_RA/RA_vol_with_fiber.vtk") writer.SetFileTypeToBinary() else: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/result_RA/RA_vol_with_fiber.vtu") + writer.SetFileName(job.ID + "/result_RA/RA_vol_with_fiber.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() - + model = meshNew.VTKObject if args.add_bridges: @@ -1435,37 +1430,37 @@ def ra_generate_fiber(model, args, job): if args.mesh_type == "bilayer": if args.ofmt == 'vtk': - la_epi = Method.smart_reader(job.ID+"/result_LA/LA_epi_with_fiber.vtk") + la_epi = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtk") else: - la_epi = Method.smart_reader(job.ID+"/result_LA/LA_epi_with_fiber.vtu") + la_epi = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") elif args.mesh_type == "vol": # extension = args.mesh.split('_RA_vol')[-1] meshname = args.mesh[:-7] if args.ofmt == 'vtk': - la = Method.smart_reader(meshname+"_LA_vol_fibers/result_LA/LA_vol_with_fiber.vtk") + la = Method.smart_reader(meshname + "_LA_vol_fibers/result_LA/LA_vol_with_fiber.vtk") else: - la = Method.smart_reader(meshname+"_LA_vol_fibers/result_LA/LA_vol_with_fiber.vtu") + la = Method.smart_reader(meshname + "_LA_vol_fibers/result_LA/LA_vol_with_fiber.vtu") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(la) geo_filter.Update() la_surf = geo_filter.GetOutput() - la_epi = Method.vtk_thr(la_surf,2,"CELLS","elemTag",left_atrial_wall_epi, 99) - - df = pd.read_csv(meshname+"_LA_vol_surf/rings_centroids.csv") + la_epi = Method.vtk_thr(la_surf, 2, "CELLS", "elemTag", left_atrial_wall_epi, 99) + + df = pd.read_csv(meshname + "_LA_vol_surf/rings_centroids.csv") la_appendage_basis_point = np.asarray(df["LAA_basis_inf"]) length = len(bachmann_bundle_points_data) ra_bb_center = bachmann_bundle_points_data[int(length * 0.45)] - + geo_filter_la_epi = vtk.vtkGeometryFilter() geo_filter_la_epi.SetInputData(la_epi) geo_filter_la_epi.Update() la_epi = geo_filter_la_epi.GetOutput() - + if args.mesh_type == "bilayer": geo_filter_ra_epi = vtk.vtkGeometryFilter() geo_filter_ra_epi.SetInputData(model) @@ -1473,50 +1468,50 @@ def ra_generate_fiber(model, args, job): ra_epi = geo_filter_ra_epi.GetOutput() else: ra_epi = surface - + loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi) loc_la_epi.BuildLocator() - + loc_ra_epi = vtk.vtkPointLocator() loc_ra_epi.SetDataSet(ra_epi) loc_ra_epi.BuildLocator() - + ra_a_id = loc_ra_epi.FindClosestPoint(ra_bb_center) la_c_id = loc_la_epi.FindClosestPoint(ra_bb_center) ra_b_id = loc_ra_epi.FindClosestPoint(la_epi.GetPoint(la_c_id)) la_d_id = loc_la_epi.FindClosestPoint(la_appendage_basis_point) - - + path_1 = Method.dijkstra_path(ra_epi, ra_a_id, ra_b_id) path_2 = Method.dijkstra_path(la_epi, la_c_id, la_d_id) path_all_temp = np.vstack((path_1, path_2)) # down sampling to smooth the path step = 20 - #step = int(len(path_all_temp)*0.1) - path_all = np.asarray([path_all_temp[i] for i in range(len(path_all_temp)) if i % step == 0 or i == len(path_all_temp)-1]) - + # step = int(len(path_all_temp)*0.1) + path_all = np.asarray( + [path_all_temp[i] for i in range(len(path_all_temp)) if i % step == 0 or i == len(path_all_temp) - 1]) + # save points for bb fiber - filename = job.ID+'/bridges/bb_fiber.dat' + filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'wb') pickle.dump(path_all, f) f.close() - + # BB tube - - bb_tube = Method.creat_tube_around_spline(path_all, 2*args.scale) - sphere_a = Method.creat_sphere(la_appendage_basis_point, 2 * 1.02*args.scale) - sphere_b = Method.creat_sphere(ra_bb_center, 2 * 1.02*args.scale) + + bb_tube = Method.creat_tube_around_spline(path_all, 2 * args.scale) + sphere_a = Method.creat_sphere(la_appendage_basis_point, 2 * 1.02 * args.scale) + sphere_b = Method.creat_sphere(ra_bb_center, 2 * 1.02 * args.scale) Method.smart_bridge_writer(bb_tube, sphere_a, sphere_b, "BB_intern_bridges", job) - - df = pd.read_csv(args.mesh+"_surf/rings_centroids.csv") + + df = pd.read_csv(args.mesh + "_surf/rings_centroids.csv") try: CS_p = np.array(df["CS"]) except KeyError: CS_p = IVC_SEPT_CT_pt print("No CS found, use last CT point instead") - + if args.mesh_type == "bilayer": add_free_bridge(args, la_epi, model, CS_p, df, job) elif args.mesh_type == "vol": diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py index 2921a36..33eb297 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py @@ -33,108 +33,108 @@ EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) + def ra_laplace(args, job, model): - meshdir = args.mesh+'_surf/RA' - surfdir ='{}_surf/'.format(args.mesh) - parfdir = os.path.join(EXAMPLE_DIR,'Parfiles') - + meshdir = args.mesh + '_surf/RA' + surfdir = '{}_surf/'.format(args.mesh) + parfdir = os.path.join(EXAMPLE_DIR, 'Parfiles') + if args.mesh_type == 'vol': #################################### - #Solver for the phi laplace soluton + # Solver for the phi laplace soluton #################################### - cmd = tools.carp_cmd(parfdir+'/ra_lps_phi.par') - simid = job.ID+'/Lp_phi' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_ENDO', - '-stimulus[1].vtx_file', surfdir+'ids_EPI'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_phi.par') + simid = job.ID + '/Lp_phi' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_ENDO', + '-stimulus[1].vtx_file', surfdir + 'ids_EPI'] + + # Run simulation job.carp(cmd) - ##################################### - #Solver for the ab laplace soluton + # Solver for the ab laplace soluton ##################################### - cmd = tools.carp_cmd(parfdir+'/ra_lps_ab.par') - simid = job.ID+'/Lp_ab' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_SVC', - '-stimulus[1].vtx_file', surfdir+'ids_IVC', - '-stimulus[2].vtx_file', surfdir+'ids_TV_S', - '-stimulus[3].vtx_file', surfdir+'ids_TV_F', - '-stimulus[4].vtx_file', surfdir+'ids_RAA'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_ab.par') + simid = job.ID + '/Lp_ab' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_SVC', + '-stimulus[1].vtx_file', surfdir + 'ids_IVC', + '-stimulus[2].vtx_file', surfdir + 'ids_TV_S', + '-stimulus[3].vtx_file', surfdir + 'ids_TV_F', + '-stimulus[4].vtx_file', surfdir + 'ids_RAA'] + + # Run simulation job.carp(cmd) - + ##################################### - #Solver for the v laplace soluton + # Solver for the v laplace soluton ##################################### - cmd = tools.carp_cmd(parfdir+'/ra_lps_v.par') - simid = job.ID+'/Lp_v' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_SVC', - '-stimulus[1].vtx_file', surfdir+'ids_RAA', - '-stimulus[2].vtx_file', surfdir+'ids_IVC'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_v.par') + simid = job.ID + '/Lp_v' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_SVC', + '-stimulus[1].vtx_file', surfdir + 'ids_RAA', + '-stimulus[2].vtx_file', surfdir + 'ids_IVC'] + + # Run simulation job.carp(cmd) - + ##################################### - #Solver for the v2 laplace soluton + # Solver for the v2 laplace soluton ##################################### - cmd = tools.carp_cmd(parfdir+'/ra_lps_phi.par') - simid = job.ID+'/Lp_v2' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_IVC', - '-stimulus[1].vtx_file', surfdir+'ids_RAA'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_phi.par') + simid = job.ID + '/Lp_v2' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_IVC', + '-stimulus[1].vtx_file', surfdir + 'ids_RAA'] + + # Run simulation job.carp(cmd) - + if args.mesh_type == 'vol': ##################################### - #Solver for the r laplace soluton + # Solver for the r laplace soluton ##################################### - cmd = tools.carp_cmd(parfdir+'/ra_lps_r_vol.par') - simid = job.ID+'/Lp_r' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_TOP_ENDO', - '-stimulus[1].vtx_file', surfdir+'ids_TOP_EPI', - '-stimulus[2].vtx_file', surfdir+'ids_TV_F', - '-stimulus[3].vtx_file', surfdir+'ids_TV_S'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_r_vol.par') + simid = job.ID + '/Lp_r' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_TOP_ENDO', + '-stimulus[1].vtx_file', surfdir + 'ids_TOP_EPI', + '-stimulus[2].vtx_file', surfdir + 'ids_TV_F', + '-stimulus[3].vtx_file', surfdir + 'ids_TV_S'] + + # Run simulation job.carp(cmd) - + else: - cmd = tools.carp_cmd(parfdir+'/ra_lps_r.par') - simid = job.ID+'/Lp_r' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_TOP_ENDO', - '-stimulus[1].vtx_file', surfdir+'ids_TV_F', - '-stimulus[2].vtx_file', surfdir+'ids_TV_S'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_r.par') + simid = job.ID + '/Lp_r' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_TOP_ENDO', + '-stimulus[1].vtx_file', surfdir + 'ids_TV_F', + '-stimulus[2].vtx_file', surfdir + 'ids_TV_S'] + + # Run simulation job.carp(cmd) - + ##################################### - #Solver for the w laplace soluton + # Solver for the w laplace soluton ##################################### - cmd = tools.carp_cmd(parfdir+'/ra_lps_w.par') - simid = job.ID+'/Lp_w' - cmd += [ '-simID', simid, - '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir+'ids_TV_S', - '-stimulus[1].vtx_file', surfdir+'ids_TV_F'] - - #Run simulation + cmd = tools.carp_cmd(parfdir + '/ra_lps_w.par') + simid = job.ID + '/Lp_w' + cmd += ['-simID', simid, + '-meshname', meshdir, + '-stimulus[0].vtx_file', surfdir + 'ids_TV_S', + '-stimulus[1].vtx_file', surfdir + 'ids_TV_F'] + + # Run simulation job.carp(cmd) """ @@ -142,35 +142,34 @@ def ra_laplace(args, job, model): """ meshNew = dsa.WrapDataObject(model) - name_list = ['r','v','v2','ab','w'] + name_list = ['r', 'v', 'v2', 'ab', 'w'] if args.mesh_type == 'vol': - name_list = ['phi','r','v','v2','ab','w'] + name_list = ['phi', 'r', 'v', 'v2', 'ab', 'w'] for var in name_list: - data = igb.IGBFile(job.ID+"/Lp_" + str(var) + "/phie.igb").data() + data = igb.IGBFile(job.ID + "/Lp_" + str(var) + "/phie.igb").data() # add the vtk array to model - meshNew.PointData.append(data, "phie_"+str(var)) - + meshNew.PointData.append(data, "phie_" + str(var)) + if args.debug == 1: # write - simid = job.ID+"/Laplace_Result" + simid = job.ID + "/Laplace_Result" try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) + print("Successfully created the directory %s " % simid) if args.mesh_type == "vol": writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid+"/RA_with_laplace.vtu") + writer.SetFileName(simid + "/RA_with_laplace.vtu") else: writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(simid+"/RA_with_laplace.vtp") + writer.SetFileName(simid + "/RA_with_laplace.vtp") writer.SetInputData(meshNew.VTKObject) writer.Write() """ calculate the gradient """ output = ra_calculate_gradient(args, meshNew.VTKObject, job) - + return output - \ No newline at end of file diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index fb1a290..f5c7380 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -37,43 +37,44 @@ import Methods_RA as Method from create_bridges import add_free_bridge + def parser(): # Generate the standard command line parser parser = tools.standard_parser() # Add arguments parser.add_argument('--mesh', - type=str, - default="", - help='path to meshname') + type=str, + default="", + help='path to meshname') parser.add_argument('--ifmt', - type=str, - default="vtk", - help='input mesh format') + type=str, + default="vtk", + help='input mesh format') parser.add_argument('--mesh_type', default='bilayer', choices=['vol', 'bilayer'], help='Mesh type') parser.add_argument('--debug', - type=int, - default=1, - help='path to meshname') + type=int, + default=1, + help='path to meshname') parser.add_argument('--scale', - type=int, - default=1, - help='normal unit is mm, set scaling factor if different') + type=int, + default=1, + help='normal unit is mm, set scaling factor if different') parser.add_argument('--ofmt', default='vtu', - choices=['vtu','vtk'], + choices=['vtu', 'vtk'], help='Output mesh format') parser.add_argument('--normals_outside', - type=int, - default=0, - help='set to 1 if surface normals are pointing outside') # expects normals to be pointing inside + type=int, + default=0, + help='set to 1 if surface normals are pointing outside') # expects normals to be pointing inside parser.add_argument('--add_bridges', - type=int, - default=1, - help='set to 1 to compute and add interatrial bridges, 0 otherwise') + type=int, + default=1, + help='set to 1 to compute and add interatrial bridges, 0 otherwise') parser.add_argument('--just_bridges', type=int, default=0, @@ -85,61 +86,65 @@ def parser(): return parser + def jobID(args): ID = '{}_fibers'.format(args.mesh) return ID + @tools.carpexample(parser, jobID) def run(args, job): - - RA_mesh = args.mesh+'_surf/RA' - + RA_mesh = args.mesh + '_surf/RA' + if args.mesh_type == "bilayer": reader = vtk.vtkPolyDataReader() else: reader = vtk.vtkUnstructuredGridReader() - reader.SetFileName(RA_mesh+'.vtk') + reader.SetFileName(RA_mesh + '.vtk') reader.Update() RA = reader.GetOutput() - + if args.normals_outside: reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() reverse.SetInputConnection(reader.GetOutputPort()) reverse.Update() - + RA = reverse.GetOutput() - + pts = numpy_support.vtk_to_numpy(RA.GetPoints().GetData()) # cells = numpy_support.vtk_to_numpy(RA.GetPolys().GetData()) # cells = cells.reshape(int(len(cells)/4),4)[:,1:] - - with open(RA_mesh+'.pts',"w") as f: + + with open(RA_mesh + '.pts', "w") as f: f.write("{}\n".format(len(pts))) for i in range(len(pts)): f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - - with open(RA_mesh+'.elem',"w") as f: - f.write("{}\n".format(RA.GetNumberOfCells())) - for i in range(RA.GetNumberOfCells()): - cell = RA.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), 1)) - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), 1)) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), 1)) - - fibers = np.zeros((RA.GetNumberOfCells(),6)) - fibers[:,0]=1 - fibers[:,4]=1 - - with open(RA_mesh+'.lon',"w") as f: + + with open(RA_mesh + '.elem', "w") as f: + f.write("{}\n".format(RA.GetNumberOfCells())) + for i in range(RA.GetNumberOfCells()): + cell = RA.GetCell(i) + if cell.GetNumberOfPoints() == 2: + f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), 1)) + elif cell.GetNumberOfPoints() == 3: + f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), 1)) + elif cell.GetNumberOfPoints() == 4: + f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), + cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), 1)) + + fibers = np.zeros((RA.GetNumberOfCells(), 6)) + fibers[:, 0] = 1 + fibers[:, 4] = 1 + + with open(RA_mesh + '.lon', "w") as f: f.write("2\n") for i in range(len(fibers)): - f.write("{} {} {} {} {} {}\n".format(fibers[i][0], fibers[i][1], fibers[i][2], fibers[i][3],fibers[i][4],fibers[i][5])) - + f.write("{} {} {} {} {} {}\n".format(fibers[i][0], fibers[i][1], fibers[i][2], fibers[i][3], fibers[i][4], + fibers[i][5])) + start_time = datetime.datetime.now() print('[Step 1] Solving laplace-dirichlet... ' + str(start_time)) if args.laplace: @@ -151,7 +156,7 @@ def run(args, job): end_time = datetime.datetime.now() running_time = end_time - start_time print('[Step 1] Solving laplace-dirichlet...done! ' + str(end_time) + '\nRunning time: ' + str(running_time) + '\n') - + start_time = datetime.datetime.now() print('[Step 2] Generating fibers... ' + str(start_time)) @@ -176,5 +181,6 @@ def run(args, job): running_time = end_time - start_time print('[Step 2] Generating fibers...done! ' + str(end_time) + '\nRunning time: ' + str(running_time) + '\n') + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/Atrial_LDRBM/README.md b/Atrial_LDRBM/README.md index 7fb326d..fcd50a2 100644 --- a/Atrial_LDRBM/README.md +++ b/Atrial_LDRBM/README.md @@ -7,21 +7,22 @@ pip install requirements.txt ##Left Atrium ### [step1]Generate Boundaries + Identifies and labels atrial openings. Run the file Generate_Boundaries/extract_rings.py ### [step2]Generate Fibers + Warning: the algorithm expects endocardium mesh with point normals pointing inside!!! after generating boundaries + 1. input the coordinate of appendage in LDRBM/Fiber_LA/la_main.py 2. run LDRBM/Fiber_LA/la_main.py ##Right Atrium same - - - ## Start form blood pool + if you have already have separated Epi- and Endocarium surface. you can: diff --git a/LICENSE.md b/LICENSE.md index 3ca3c7e..a4f0852 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,56 +1,120 @@ -The following license governs the use of AugmentA in non-commercial academic environments. Commercial use requires a commercial license (). +The following license governs the use of AugmentA in non-commercial academic environments. Commercial use requires a +commercial license (). ## ACADEMIC PUBLIC LICENSE (openCARP, v1.0) ### Preamble -This license contains the terms and conditions of using openCARP in non-commercial settings: at academic institutions for teaching and research use, and at not-for-profit research organizations. You will find that this license provides non-commercial users of openCARP with rights that are similar to the well-known GNU General Public License 2.0, yet it retains the possibility for openCARP authors to financially support the development by selling commercial licenses. In fact, if you intend to use openCARP in a "for-profit" environment, where openCARP simulations are conducted to develop or enhance a product (including commercial or industry-sponsored research at academic institutions), or to use openCARP in a commercial service offering, then you need to obtain a commercial license for openCARP. In that case, please contact to inquire about commercial licenses. -What are the rights given to non-commercial users? Similarly, to GPL 2.0, you have the right to use the software, to distribute copies, to receive source code, to change the software and distribute your modifications or the modified software. Also, similarly to the GPL 2.0, if you distribute verbatim or modified copies of this software, they must be distributed under this license. - -By modeling the GPL 2.0, this license guarantees that you’re safe when using openCARP in your work, for teaching, and research. This license guarantees that openCARP will remain available free of charge for non-profit use. You can modify openCARP to your purposes, and you can also share your modifications. Even in the unlikely case of the authors abandoning openCARP entirely, this license permits anyone to continue developing it from the last release, and to create further releases under this license. - -We believe that the combination of non-commercial open source and commercial licensing will be beneficial for the whole user community, because income from commercial licenses will enable sustained and faster development and a higher level of software quality, while further enjoying the informal, open communication and collaboration channels of open source development. +This license contains the terms and conditions of using openCARP in non-commercial settings: at academic institutions +for teaching and research use, and at not-for-profit research organizations. You will find that this license provides +non-commercial users of openCARP with rights that are similar to the well-known GNU General Public License 2.0, yet it +retains the possibility for openCARP authors to financially support the development by selling commercial licenses. In +fact, if you intend to use openCARP in a "for-profit" environment, where openCARP simulations are conducted to develop +or enhance a product (including commercial or industry-sponsored research at academic institutions), or to use openCARP +in a commercial service offering, then you need to obtain a commercial license for openCARP. In that case, please +contact to inquire about commercial licenses. + +What are the rights given to non-commercial users? Similarly, to GPL 2.0, you have the right to use the software, to +distribute copies, to receive source code, to change the software and distribute your modifications or the modified +software. Also, similarly to the GPL 2.0, if you distribute verbatim or modified copies of this software, they must be +distributed under this license. + +By modeling the GPL 2.0, this license guarantees that you’re safe when using openCARP in your work, for teaching, and +research. This license guarantees that openCARP will remain available free of charge for non-profit use. You can modify +openCARP to your purposes, and you can also share your modifications. Even in the unlikely case of the authors +abandoning openCARP entirely, this license permits anyone to continue developing it from the last release, and to create +further releases under this license. + +We believe that the combination of non-commercial open source and commercial licensing will be beneficial for the whole +user community, because income from commercial licenses will enable sustained and faster development and a higher level +of software quality, while further enjoying the informal, open communication and collaboration channels of open source +development. The precise terms and conditions for using, copying, distribution and modification follow. ### Terms and Conditions for Use, Copying, Distribution and Modification Definitions + * "Program" means a copy of openCARP, which is said to be distributed under this Academic Public License. -* "Work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) -* "Using the Program" means any act of creating executables that contain or directly use libraries that are part of the Program, running any of the tools that are part of the Program, or creating works based on the Program. +* "Work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a + work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in the term "modification".) +* "Using the Program" means any act of creating executables that contain or directly use libraries that are part of the + Program, running any of the tools that are part of the Program, or creating works based on the Program. * Each licensee is addressed as "you". -§1. Permission is hereby granted to use the Program free of charge for any non-commercial purpose, including teaching and research at universities, colleges and other educational institutions, non-commercial research at organizations that are either not-for-profit or reinvest all profits in their scientific research, and personal not-for-profit purposes. For using the Program for commercial purposes, including but not restricted to commercial research at academic institutions, industrially sponsored research at academic institutions, consulting activities, and design of commercial hardware or software products or services, you have to contact for an appropriate license. - -§2. You may copy and distribute verbatim copies of the source code of the program via any medium, provided that you add a conspicuous and appropriate copyright notice and a warranty disclaimer to each copy. Retain all notices relating to this license and the lack of any warranty. Forward a copy of this license to all other recipients of the program. - -§3. You are entitled to change your copies of the Program or a part thereof and thus create a work based on the Program. You may copy and distribute changes or work in accordance with the provisions of Section 2 provided you also meet all of the following conditions: -a) You must ensure that the changed files are provided with noticeable comments stating the author of the change and when this change was made. -b) You must ensure that all work that you distribute or publish, that contains or is derived from the Program or parts thereof, as a whole, is licensed under the conditions of this license. - -These requirements apply to the changed work as a whole. If identifiable sections of this work do not come from the Program and can be considered separate, this license and its terms do not apply to those sections if you distribute them as separate work. However, if you distribute the same sections as part of a whole that is based on the Program, the distribution of the whole must be done in accordance with the terms of this license as outlined in §2, independently of who wrote it. - -The mere merging of another work that is not based on the Program with the Program (or a work based on the Program) does not bring the other work into the scope of this license. - -§4. You may copy and distribute the Program (or a work based on it, in accordance with §3, in object code or executable form in accordance with the provisions of above Sections 2 and 3, provided that you also add the complete corresponding machine-readable source code. For an executable program, complete source code means the entire source code for all modules contained therein, as well as all associated interface definition files and scripts, with which the compilation and installation of the executable file is controlled. - -§5. Any attempt to copy, modify, sublicense or distribute the Program in any other way than specified in this license is void, and will automatically terminate your rights under this license. However, parties who have received copies or rights from you under this license will not lose their license as long as these parties fully comply with the terms. - -§6. You do not have to accept this license because you have not signed it. However, if you want to change or distribute the Program (or a work based on the Program), you automatically consent to this license and all its terms for copying, distributing or changing the program or the works based upon it. - -§7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically acquires a license from the initial licensor to copy, distribute or modify the Program in accordance with these terms and conditions. You may not impose any further restrictions on the recipient's exercise of the rights granted here. You are not responsible for ensuring that this license is enforced by third parties. - -§8. If, as a result of a court decision or violation of a patent right, or for any other reason (not limited to patent issues), conditions are imposed that conflict with the terms of this license, you will not be released from the terms of this license. If you cannot distribute the Program because you would have to meet obligations under this license and other obligations at the same time, you may not distribute the Program at all. - -§9. If the distribution and/or use of the Program in certain countries is restricted either by patents or by copyrighted interfaces, the original copyright holder who puts the Program under this license may add an explicit geographic distribution restriction that excludes these countries. In this case, this license contains the restriction as if it was written in the body of this license. +§1. Permission is hereby granted to use the Program free of charge for any non-commercial purpose, including teaching +and research at universities, colleges and other educational institutions, non-commercial research at organizations that +are either not-for-profit or reinvest all profits in their scientific research, and personal not-for-profit purposes. +For using the Program for commercial purposes, including but not restricted to commercial research at academic +institutions, industrially sponsored research at academic institutions, consulting activities, and design of commercial +hardware or software products or services, you have to contact for an appropriate license. + +§2. You may copy and distribute verbatim copies of the source code of the program via any medium, provided that you add +a conspicuous and appropriate copyright notice and a warranty disclaimer to each copy. Retain all notices relating to +this license and the lack of any warranty. Forward a copy of this license to all other recipients of the program. + +§3. You are entitled to change your copies of the Program or a part thereof and thus create a work based on the Program. +You may copy and distribute changes or work in accordance with the provisions of Section 2 provided you also meet all of +the following conditions: +a) You must ensure that the changed files are provided with noticeable comments stating the author of the change and +when this change was made. +b) You must ensure that all work that you distribute or publish, that contains or is derived from the Program or parts +thereof, as a whole, is licensed under the conditions of this license. + +These requirements apply to the changed work as a whole. If identifiable sections of this work do not come from the +Program and can be considered separate, this license and its terms do not apply to those sections if you distribute them +as separate work. However, if you distribute the same sections as part of a whole that is based on the Program, the +distribution of the whole must be done in accordance with the terms of this license as outlined in §2, independently of +who wrote it. + +The mere merging of another work that is not based on the Program with the Program (or a work based on the Program) does +not bring the other work into the scope of this license. + +§4. You may copy and distribute the Program (or a work based on it, in accordance with §3, in object code or executable +form in accordance with the provisions of above Sections 2 and 3, provided that you also add the complete corresponding +machine-readable source code. For an executable program, complete source code means the entire source code for all +modules contained therein, as well as all associated interface definition files and scripts, with which the compilation +and installation of the executable file is controlled. + +§5. Any attempt to copy, modify, sublicense or distribute the Program in any other way than specified in this license is +void, and will automatically terminate your rights under this license. However, parties who have received copies or +rights from you under this license will not lose their license as long as these parties fully comply with the terms. + +§6. You do not have to accept this license because you have not signed it. However, if you want to change or distribute +the Program (or a work based on the Program), you automatically consent to this license and all its terms for copying, +distributing or changing the program or the works based upon it. + +§7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically acquires a +license from the initial licensor to copy, distribute or modify the Program in accordance with these terms and +conditions. You may not impose any further restrictions on the recipient's exercise of the rights granted here. You are +not responsible for ensuring that this license is enforced by third parties. + +§8. If, as a result of a court decision or violation of a patent right, or for any other reason (not limited to patent +issues), conditions are imposed that conflict with the terms of this license, you will not be released from the terms of +this license. If you cannot distribute the Program because you would have to meet obligations under this license and +other obligations at the same time, you may not distribute the Program at all. + +§9. If the distribution and/or use of the Program in certain countries is restricted either by patents or by copyrighted +interfaces, the original copyright holder who puts the Program under this license may add an explicit geographic +distribution restriction that excludes these countries. In this case, this license contains the restriction as if it was +written in the body of this license. ### No Warranty -§10. Since the Program is licensed for free, there is no guarantee for the Program to the extent permitted by applicable law. Unless otherwise specified in writing, the copyright holders and/or other parties provide the Program "as is" without any expressed or implied guarantee, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. The entire risk to the quality and performance of the Program is yours. If the Program turns out to be faulty, you are responsible for the costs for all necessary maintenance, repair or correction work. +§10. Since the Program is licensed for free, there is no guarantee for the Program to the extent permitted by applicable +law. Unless otherwise specified in writing, the copyright holders and/or other parties provide the Program "as is" +without any expressed or implied guarantee, including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. The entire risk to the quality and performance of the Program is yours. If the Program +turns out to be faulty, you are responsible for the costs for all necessary maintenance, repair or correction work. -§11. Under no circumstances will a copyright holder or any other party who can modify and/or redistribute the Program as permitted above be liable for damage, including general, special, accidental or other damage, unless this is required by law or agreed in writing. The disclaimer also includes consequential damages that result from using the Program alone or in conjunction with other programs, including but not limited to the loss or corruption of data. +§11. Under no circumstances will a copyright holder or any other party who can modify and/or redistribute the Program as +permitted above be liable for damage, including general, special, accidental or other damage, unless this is required by +law or agreed in writing. The disclaimer also includes consequential damages that result from using the Program alone or +in conjunction with other programs, including but not limited to the loss or corruption of data. In case the above text differs from the license file in the source distribution, the latter is the valid one. -Initially written by Andras Varga (public domain) for OMNeT++ , adapted by the [openCARP project](https://www.openCARP.org). The adaptation is licensed under CC0 1.0 (Public Domain Dedication). +Initially written by Andras Varga (public domain) for OMNeT++ , adapted by +the [openCARP project](https://www.openCARP.org). The adaptation is licensed under CC0 1.0 (Public Domain Dedication). diff --git a/README.md b/README.md index d4449fc..54788e2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ # AugmentA: Patient-specific Augmented Atrial model Generation Tool -We propose a patient-specific Augmented Atrial model Generation Tool (AugmentA) as a highly automated framework which, starting from clinical geometrical data, provides ready-to-use atrial personalized computational models. -AugmentA consists firstly of a pre-processing step applied to the input geometry. Secondly, the atrial orifices are identified and labelled using only one reference point per atrium. If the workflow includes fitting a statistical shape model (SSM) to the input geometry, this is first rigidly aligned with the given mean shape and finally a non-rigid fitting procedure is applied. AugmentA automatically generates the fiber orientation using a Laplace-Dirichlet-Rule-based-Method. +We propose a patient-specific Augmented Atrial model Generation Tool (AugmentA) as a highly automated framework which, +starting from clinical geometrical data, provides ready-to-use atrial personalized computational models. +AugmentA consists firstly of a pre-processing step applied to the input geometry. Secondly, the atrial orifices are +identified and labelled using only one reference point per atrium. If the workflow includes fitting a statistical shape +model (SSM) to the input geometry, this is first rigidly aligned with the given mean shape and finally a non-rigid +fitting procedure is applied. AugmentA automatically generates the fiber orientation using a +Laplace-Dirichlet-Rule-based-Method. ![Pipeline](/images/pipeline.png) @@ -11,56 +16,73 @@ AugmentA consists firstly of a pre-processing step applied to the input geometry - **mesh/:** contains the exemplary mesh and the statistical shape model - **standalones/:** standalone tools used in the pipeline - **template/**: template for non-rigid fitting process -- **Atrial_LDRBM/**: Laplace-Dirichlet-Rule-based-Method to annotate anatomical regions and generate atrial fiber orientation in the atria +- **Atrial_LDRBM/**: Laplace-Dirichlet-Rule-based-Method to annotate anatomical regions and generate atrial fiber + orientation in the atria ## Setup -Create a python virtual environment to install the current requirements after installing the requirements of carputils: +Create a python virtual environment to install the current requirements after installing the requirements of carputils: + ``` python -m venv ~/myEnv source ~/myEnv/bin/activate pip install -r requirements.txt ``` + Install [PyMesh](https://pymesh.readthedocs.io/en/latest/installation.html) -Go to the carputils folder and re-install carputils' requirements (assuming that carputils was installed in the home folder): +Go to the carputils folder and re-install carputils' requirements (assuming that carputils was installed in the home +folder): + ``` cd ~/carputils pip install -r requirements.txt ``` + ## Usage Remember to source to myEnv before using the pipeline: + ``` source ~/myEnv/bin/activate ``` + Show all options: + ``` python main.py --help ``` + Example using an MRI segmentation to produce a bilayer atrial model: + ``` python main.py --mesh mesh/LA_MRI.vtp --closed_surface 0 --use_curvature_to_open 1 --atrium LA --open_orifices 1 --MRI 1 ``` + Example using a closed surface derived from a MRI segmentation to produce a volumetric atrial model: + ``` python main.py --mesh mesh/mwk05_bi.vtp --closed_surface 1 --use_curvature_to_open 0 --atrium LA_RA ``` + ## Q&A -- Selection of appendage apex: the selected point will be used as boundary condition for a Laplacian problem. Therefore, the point at the center of the appendage is the most suitable to identify the whole appendage body +- Selection of appendage apex: the selected point will be used as boundary condition for a Laplacian problem. Therefore, + the point at the center of the appendage is the most suitable to identify the whole appendage body - Fiber_LA: LAA labeling (check LPVs identification functions distinguish_Pvs and optimize_PVs in la_generate_fiber.py) -- Fiber_RA: PMs (check step in function Method.downsample_path in ra_generate_fiber.py), bridges (boolean operations and normal directions of original mesh) +- Fiber_RA: PMs (check step in function Method.downsample_path in ra_generate_fiber.py), bridges (boolean operations and + normal directions of original mesh) - If facing problems with PyMesh install it from https://github.com/PyMesh/PyMesh and follow the instructions ## Citation + When using this work, please cite > *AugmentA: Patient-specific Augmented Atrial model Generation Tool* > -> Luca Azzolin, Martin Eichenlaub, Claudia Nagel, Deborah Nairn, Jorge Sánchez, Laura Unger, Olaf Dössel, Amir Jadidi, Axel Loewe +> Luca Azzolin, Martin Eichenlaub, Claudia Nagel, Deborah Nairn, Jorge Sánchez, Laura Unger, Olaf Dössel, Amir Jadidi, +> Axel Loewe > [doi:10.1101/2022.02.13.22270835](https://doi.org/10.1101/2022.02.13.22270835) - ## License All source code is subject to the terms of the Academic Public License. diff --git a/main.py b/main.py index 72189c2..9beea8e 100644 --- a/main.py +++ b/main.py @@ -35,6 +35,7 @@ EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) + def parser(): # Generate the standard command line parser parser = argparse.ArgumentParser(description='AugmentA: Patient-specific Augmented Atrial model Generation Tool') @@ -64,7 +65,7 @@ def parser(): help='set to 1 to proceed with the fitting of a given SSM, 0 otherwise') parser.add_argument('--atrium', default="LA", - choices=['LA','RA','LA_RA'], + choices=['LA', 'RA', 'LA_RA'], help='write LA or RA') parser.add_argument('--SSM_file', type=str, @@ -96,7 +97,7 @@ def parser(): help='set to 1 to compute and add interatrial bridges, 0 otherwise') parser.add_argument('--ofmt', default='vtu', - choices=['vtu','vtk'], + choices=['vtu', 'vtk'], help='Output mesh format') parser.add_argument('--find_appendage', type=int, @@ -108,18 +109,19 @@ def parser(): help='set to 1 to debug step by step, 0 otherwise') return parser -def run(): +def run(): args = parser().parse_args() # In case both atria are given process LA first and RA later if args.atrium == 'LA_RA': - #args.atrium = 'LA' + # args.atrium = 'LA' AugmentA(args) - #args.atrium = 'RA' - #AugmentA(args) + # args.atrium = 'RA' + # AugmentA(args) else: AugmentA(args) - + + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/pipeline.py b/pipeline.py index cb19e5c..bb701fa 100644 --- a/pipeline.py +++ b/pipeline.py @@ -39,6 +39,7 @@ import numpy as np import pyvista as pv from scipy.spatial import cKDTree + sys.path.append('standalones') from open_orifices_with_curvature import open_orifices_with_curvature from open_orifices_manually import open_orifices_manually @@ -64,26 +65,26 @@ from generate_surf_id import generate_surf_id pv.set_plot_theme('dark') -n_cpu=os.cpu_count() +n_cpu = os.cpu_count() if not n_cpu % 2: - n_cpu = int(n_cpu/2) + n_cpu = int(n_cpu / 2) -def AugmentA(args): +def AugmentA(args): args.SSM_file = os.path.abspath(args.SSM_file) args.SSM_basename = os.path.abspath(args.SSM_basename) args.mesh = os.path.abspath(args.mesh) - + extension = args.mesh.split('/')[-1] mesh_dir = args.mesh[:-len(extension)] extension = args.mesh.split('.')[-1] - meshname = args.mesh[:-(len(extension)+1)] + meshname = args.mesh[:-(len(extension) + 1)] if args.closed_surface: separate_epi_endo(args.mesh, args.atrium) meshname_old = str(meshname) - meshname = meshname_old+"_{}_epi".format(args.atrium) + meshname = meshname_old + "_{}_epi".format(args.atrium) else: if args.open_orifices: @@ -91,20 +92,21 @@ def AugmentA(args): if args.use_curvature_to_open: # Opening atrial orifices using curvature print("Opening atrial orifices using curvature") - apex_id = open_orifices_with_curvature(args.mesh, args.atrium, args.MRI, scale=args.scale, debug=args.debug) + apex_id = open_orifices_with_curvature(args.mesh, args.atrium, args.MRI, scale=args.scale, + debug=args.debug) else: # Opening atrial orifices manually print("Opening atrial orifices manually") apex_id = open_orifices_manually(args.mesh, args.atrium, args.MRI, scale=args.scale, debug=args.debug) - meshname = mesh_dir + args.atrium+"_cutted" + meshname = mesh_dir + args.atrium + "_cutted" else: - if not args.resample_input and args.find_appendage: # don't open orifices and don´t resample, find appendage + if not args.resample_input and args.find_appendage: # don't open orifices and don´t resample, find appendage # Manually select the appendage apex and extract rings, these are going to be used to compute the landmarks for the fitting if SSM is selected print("Manually select the appendage apex and extract rings") mesh_data = dict() - #Make sure that the mesh is a Polydata + # Make sure that the mesh is a Polydata geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(smart_reader(args.mesh)) geo_filter.Update() @@ -113,7 +115,7 @@ def AugmentA(args): mesh_from_vtk = pv.PolyData(polydata) p = pv.Plotter(notebook=False) p.add_mesh(mesh_from_vtk, 'r') - p.add_text('Select the appendage apex and close the window',position='lower_left') + p.add_text('Select the appendage apex and close the window', position='lower_left') p.enable_point_picking(mesh_from_vtk, use_picker=True) p.show() @@ -162,11 +164,11 @@ def AugmentA(args): df = pd.DataFrame(mesh_data) df.to_csv(fname, float_format="%.2f", index=False) - #print("Labelling atrial orifices") - #label_atrial_orifices(args.mesh,LAA,RAA) + # print("Labelling atrial orifices") + # label_atrial_orifices(args.mesh,LAA,RAA) # Label atrial orifices using apex id found in the resampling algorithm - #df = pd.read_csv('{}_mesh_data.csv'.format(meshname)) + # df = pd.read_csv('{}_mesh_data.csv'.format(meshname)) # Atrial orifices already open print("Atrial orifices already open") @@ -175,48 +177,57 @@ def AugmentA(args): if args.SSM_fitting and not args.closed_surface: # Generate SSM landmarks if not present - if not os.path.isfile(args.SSM_basename+'_surf/landmarks.json'): - label_atrial_orifices(args.SSM_basename,6329,21685) # 6329 LAA apex id and 21685 RAA apex id in meanshape from Nagel et al. 2020 + if not os.path.isfile(args.SSM_basename + '_surf/landmarks.json'): + label_atrial_orifices(args.SSM_basename, 6329, + 21685) # 6329 LAA apex id and 21685 RAA apex id in meanshape from Nagel et al. 2020 get_landmarks(args.SSM_basename, 0, 1) # Rigid alignment of target mesh to SSM mean instance - prealign_meshes(mesh_dir+args.atrium+'_cutted', args.SSM_basename, args.atrium, 0) + prealign_meshes(mesh_dir + args.atrium + '_cutted', args.SSM_basename, args.atrium, 0) # Landmarks generation - get_landmarks(mesh_dir+args.atrium+'_cutted', 1, 1) + get_landmarks(mesh_dir + args.atrium + '_cutted', 1, 1) # Create Scalismo ICP-GP fitting algorithm script - with open('template/Registration_ICP_GP_template.txt','r') as f: + with open('template/Registration_ICP_GP_template.txt', 'r') as f: lines = f.readlines() lines = ''.join(lines) temp_obj = Template(lines) - SSM_fit_file = temp_obj.substitute(SSM_file=args.SSM_file,SSM_dir=args.SSM_basename+'_surf',target_dir=mesh_dir+args.atrium+'_cutted_surf') - with open(mesh_dir+args.atrium+'_cutted_surf'+'/Registration_ICP_GP.txt','w') as f: + SSM_fit_file = temp_obj.substitute(SSM_file=args.SSM_file, SSM_dir=args.SSM_basename + '_surf', + target_dir=mesh_dir + args.atrium + '_cutted_surf') + with open(mesh_dir + args.atrium + '_cutted_surf' + '/Registration_ICP_GP.txt', 'w') as f: f.write(SSM_fit_file) # Create SSM instance - if os.path.isfile(mesh_dir+args.atrium+'_cutted_surf/coefficients.txt'): - create_SSM_instance(args.SSM_file+'.h5', mesh_dir+args.atrium+'_cutted_surf/coefficients.txt',mesh_dir+args.atrium+'_cutted_surf/'+args.atrium+'_fit.obj') + if os.path.isfile(mesh_dir + args.atrium + '_cutted_surf/coefficients.txt'): + create_SSM_instance(args.SSM_file + '.h5', mesh_dir + args.atrium + '_cutted_surf/coefficients.txt', + mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit.obj') else: raise ValueError("Create coefficients.txt file including the SSM coefficients from Scalismo") if args.resample_input: # Resample surface mesh with given target average edge length - resample_surf_mesh(mesh_dir+args.atrium+'_cutted_surf/'+args.atrium+'_fit', target_mesh_resolution=args.target_mesh_resolution, find_apex_with_curv=1, scale=args.scale, apex_id=apex_id,atrium = args.atrium) - processed_mesh = mesh_dir+args.atrium+'_cutted_surf/'+args.atrium+'_fit_res' + resample_surf_mesh(mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit', + target_mesh_resolution=args.target_mesh_resolution, find_apex_with_curv=1, + scale=args.scale, apex_id=apex_id, atrium=args.atrium) + processed_mesh = mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit_res' else: - processed_mesh = mesh_dir+args.atrium+'_cutted_surf/'+args.atrium+'_fit' + processed_mesh = mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit' # Label atrial orifices using apex id found in the resampling algorithm - df = pd.read_csv('{}_mesh_data.csv'.format(mesh_dir+args.atrium+'_cutted_surf/'+args.atrium+'_fit')) + df = pd.read_csv('{}_mesh_data.csv'.format(mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit')) if args.atrium == "LA": - label_atrial_orifices(processed_mesh+'obj',LAA_id=int(df[args.atrium+"A_id"])) + label_atrial_orifices(processed_mesh + 'obj', LAA_id=int(df[args.atrium + "A_id"])) # Atrial region annotation and fiber generation using LDRBM - la_main.run(["--mesh",processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt",args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + la_main.run( + ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt", + args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) elif args.atrium == "RA": - label_atrial_orifices(processed_mesh+'obj',RAA_id=int(df[args.atrium+"A_id"])) + label_atrial_orifices(processed_mesh + 'obj', RAA_id=int(df[args.atrium + "A_id"])) # Atrial region annotation and fiber generation using LDRBM - ra_main.run(["--mesh",processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt",args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + ra_main.run( + ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt", + args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) elif not args.SSM_fitting: @@ -228,11 +239,12 @@ def AugmentA(args): meshin = pv.read('{}.vtk'.format(meshname)) pv.save_meshio('{}.obj'.format(meshname), meshin, "obj") - #if args.atrium =='LA_RA': - apex_id = -1 # Find new location with resampled mesh + # if args.atrium =='LA_RA': + apex_id = -1 # Find new location with resampled mesh # Here finds the LAA_id and/or RAA_id for the remeshed geometry - resample_surf_mesh('{}'.format(meshname), target_mesh_resolution=args.target_mesh_resolution, find_apex_with_curv=0, scale=args.scale, apex_id=apex_id, atrium = args.atrium) + resample_surf_mesh('{}'.format(meshname), target_mesh_resolution=args.target_mesh_resolution, + find_apex_with_curv=0, scale=args.scale, apex_id=apex_id, atrium=args.atrium) processed_mesh = '{}_res'.format(meshname) # Convert mesh from ply to obj @@ -274,9 +286,9 @@ def AugmentA(args): # df = pd.DataFrame(mesh_data) # df.to_csv(fname, float_format="%.2f", index=False) - elif not args.resample_input and not args.find_appendage: # do not resample and do not find appendage + elif not args.resample_input and not args.find_appendage: # do not resample and do not find appendage - processed_mesh = meshname # Provide mesh with _res in the name + processed_mesh = meshname # Provide mesh with _res in the name # if not args.closed_surface: # #Convert mesh from vtk to obj @@ -289,15 +301,16 @@ def AugmentA(args): df = pd.read_csv('{}_mesh_data.csv'.format(processed_mesh)) if args.atrium == "LA_RA": - if not os.path.exists(processed_mesh+'.obj'): + if not os.path.exists(processed_mesh + '.obj'): meshin = pv.read('{}.vtk'.format(processed_mesh)) pv.save_meshio('{}.obj'.format(processed_mesh), meshin, "obj") - label_atrial_orifices(processed_mesh+'.obj', LAA_id=int(df["LAA_id"]), RAA_id=int(df["RAA_id"])) # Label both - #Do the LA first + label_atrial_orifices(processed_mesh + '.obj', LAA_id=int(df["LAA_id"]), + RAA_id=int(df["RAA_id"])) # Label both + # Do the LA first la_main.run( ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt", - args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) args.atrium = "RA" ra_main.run( ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt", @@ -310,53 +323,69 @@ def AugmentA(args): '{}_fibers/result_RA/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium), '{}_fibers/result_RA/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium))) if args.atrium == "LA": - label_atrial_orifices(processed_mesh+'.obj',LAA_id=int(df[args.atrium+"A_id"])) + label_atrial_orifices(processed_mesh + '.obj', LAA_id=int(df[args.atrium + "A_id"])) # Atrial region annotation and fiber generation using LDRBM if args.closed_surface: - generate_mesh(meshname_old+'_{}'.format(args.atrium)) + generate_mesh(meshname_old + '_{}'.format(args.atrium)) generate_surf_id(meshname_old, args.atrium) - processed_mesh = meshname_old+"_{}_vol".format(args.atrium) - la_main.run(["--mesh",processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", "--ofmt",args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + processed_mesh = meshname_old + "_{}_vol".format(args.atrium) + la_main.run( + ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", + "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) else: - la_main.run(["--mesh",processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt",args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) - os.system("meshtool convert -imsh={} -ifmt=carp_txt -omsh={} -ofmt=carp_txt -scale={}".format('{}_fibers/result_{}/{}_bilayer_with_fiber'.format(processed_mesh, args.atrium, args.atrium), '{}_fibers/result_{}/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium, args.atrium), 1000 * args.scale)) - os.system("meshtool convert -imsh={} -ifmt=carp_txt -omsh={} -ofmt=vtk".format('{}_fibers/result_{}/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium, args.atrium), '{}_fibers/result_{}/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium, args.atrium))) + la_main.run( + ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), + "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + os.system("meshtool convert -imsh={} -ifmt=carp_txt -omsh={} -ofmt=carp_txt -scale={}".format( + '{}_fibers/result_{}/{}_bilayer_with_fiber'.format(processed_mesh, args.atrium, args.atrium), + '{}_fibers/result_{}/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium, args.atrium), + 1000 * args.scale)) + os.system("meshtool convert -imsh={} -ifmt=carp_txt -omsh={} -ofmt=vtk".format( + '{}_fibers/result_{}/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium, args.atrium), + '{}_fibers/result_{}/{}_bilayer_with_fiber_um'.format(processed_mesh, args.atrium, args.atrium))) elif args.atrium == "RA": # Atrial region annotation and fiber generation using LDRBM if args.closed_surface: - label_atrial_orifices_TOP_epi_endo(processed_mesh+'.obj',RAA_id=int(df[args.atrium+"A_id"])) - generate_mesh(meshname_old+'_{}'.format(args.atrium)) + label_atrial_orifices_TOP_epi_endo(processed_mesh + '.obj', RAA_id=int(df[args.atrium + "A_id"])) + generate_mesh(meshname_old + '_{}'.format(args.atrium)) generate_surf_id(meshname_old, args.atrium) - processed_mesh = meshname_old+"_{}_vol".format(args.atrium) - ra_main.run(["--mesh",processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", "--ofmt",args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + processed_mesh = meshname_old + "_{}_vol".format(args.atrium) + ra_main.run( + ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", + "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) else: - label_atrial_orifices(processed_mesh+'.obj',RAA_id=int(df[args.atrium+"A_id"])) - ra_main.run(["--mesh",processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), "--ofmt",args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) + label_atrial_orifices(processed_mesh + '.obj', RAA_id=int(df[args.atrium + "A_id"])) + ra_main.run( + ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(args.normals_outside), + "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) if args.debug: if args.closed_surface: - bil = pv.read('{}_fibers/result_{}/{}_vol_with_fiber.{}'.format(processed_mesh, args.atrium, args.atrium, args.ofmt)) + bil = pv.read( + '{}_fibers/result_{}/{}_vol_with_fiber.{}'.format(processed_mesh, args.atrium, args.atrium, args.ofmt)) else: if args.atrium == 'LA_RA': bil = pv.read( '{}_fibers/result_RA/{}_bilayer_with_fiber.{}'.format(processed_mesh, args.atrium, args.ofmt)) else: - bil = pv.read('{}_fibers/result_{}/{}_bilayer_with_fiber.{}'.format(processed_mesh, args.atrium, args.atrium, args.ofmt)) + bil = pv.read( + '{}_fibers/result_{}/{}_bilayer_with_fiber.{}'.format(processed_mesh, args.atrium, args.atrium, + args.ofmt)) geom = pv.Line() - mask = bil['elemTag'] >99 + mask = bil['elemTag'] > 99 bil['elemTag'][mask] = 0 - mask = bil['elemTag'] >80 + mask = bil['elemTag'] > 80 bil['elemTag'][mask] = 20 - mask = bil['elemTag'] >10 - bil['elemTag'][mask] = bil['elemTag'][mask]-10 + mask = bil['elemTag'] > 10 + bil['elemTag'][mask] = bil['elemTag'][mask] - 10 mask = bil['elemTag'] > 50 bil['elemTag'][mask] = bil['elemTag'][mask] - 50 p = pv.Plotter(notebook=False) if not args.closed_surface: - fibers = bil.glyph(orient="fiber",factor=0.5,geom=geom, scale="elemTag") - p.add_mesh(fibers,show_scalar_bar=False,cmap='tab20',line_width=10,render_lines_as_tubes=True) - p.add_mesh(bil, scalars="elemTag",show_scalar_bar=False,cmap='tab20') + fibers = bil.glyph(orient="fiber", factor=0.5, geom=geom, scale="elemTag") + p.add_mesh(fibers, show_scalar_bar=False, cmap='tab20', line_width=10, render_lines_as_tubes=True) + p.add_mesh(bil, scalars="elemTag", show_scalar_bar=False, cmap='tab20') p.show() - p.close() \ No newline at end of file + p.close() diff --git a/poetry.lock b/poetry.lock index 8dc05fc..bbb7d17 100644 --- a/poetry.lock +++ b/poetry.lock @@ -7,8 +7,8 @@ description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + { file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" }, + { file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082" }, ] [[package]] @@ -18,81 +18,81 @@ description = "The Real First Universal Charset Detector. Open, modern and activ optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + { file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96" }, + { file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1" }, + { file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1" }, + { file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706" }, + { file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9" }, + { file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80" }, + { file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6" }, ] [[package]] @@ -102,45 +102,45 @@ description = "Python library for calculating contours of 2D quadrilateral grids optional = false python-versions = ">=3.8" files = [ - {file = "contourpy-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89f06eff3ce2f4b3eb24c1055a26981bffe4e7264acd86f15b97e40530b794bc"}, - {file = "contourpy-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dffcc2ddec1782dd2f2ce1ef16f070861af4fb78c69862ce0aab801495dda6a3"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ae46595e22f93592d39a7eac3d638cda552c3e1160255258b695f7b58e5655"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17cfaf5ec9862bc93af1ec1f302457371c34e688fbd381f4035a06cd47324f48"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"}, - {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"}, - {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"}, - {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"}, - {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052cc634bf903c604ef1a00a5aa093c54f81a2612faedaa43295809ffdde885e"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9382a1c0bc46230fb881c36229bfa23d8c303b889b788b939365578d762b5c18"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"}, - {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"}, - {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"}, - {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"}, - {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62013a2cf68abc80dadfd2307299bfa8f5aa0dcaec5b2954caeb5fa094171103"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b6616375d7de55797d7a66ee7d087efe27f03d336c27cf1f32c02b8c1a5ac70"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"}, - {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"}, - {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"}, - {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"}, - {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f2931ed4741f98f74b410b16e5213f71dcccee67518970c42f64153ea9313b9"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30f511c05fab7f12e0b1b7730ebdc2ec8deedcfb505bc27eb570ff47c51a8f15"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"}, - {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"}, - {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a67259c2b493b00e5a4d0f7bfae51fb4b3371395e47d079a4446e9b0f4d70e76"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2b836d22bd2c7bb2700348e4521b25e077255ebb6ab68e351ab5aa91ca27e027"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084eaa568400cfaf7179b847ac871582199b1b44d5699198e9602ecbbb5f6104"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:911ff4fd53e26b019f898f32db0d4956c9d227d51338fb3b03ec72ff0084ee5f"}, - {file = "contourpy-1.1.0.tar.gz", hash = "sha256:e53046c3863828d21d531cc3b53786e6580eb1ba02477e8681009b6aa0870b21"}, + { file = "contourpy-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89f06eff3ce2f4b3eb24c1055a26981bffe4e7264acd86f15b97e40530b794bc" }, + { file = "contourpy-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dffcc2ddec1782dd2f2ce1ef16f070861af4fb78c69862ce0aab801495dda6a3" }, + { file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ae46595e22f93592d39a7eac3d638cda552c3e1160255258b695f7b58e5655" }, + { file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17cfaf5ec9862bc93af1ec1f302457371c34e688fbd381f4035a06cd47324f48" }, + { file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37" }, + { file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa" }, + { file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa" }, + { file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2" }, + { file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882" }, + { file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545" }, + { file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052cc634bf903c604ef1a00a5aa093c54f81a2612faedaa43295809ffdde885e" }, + { file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9382a1c0bc46230fb881c36229bfa23d8c303b889b788b939365578d762b5c18" }, + { file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e" }, + { file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a" }, + { file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e" }, + { file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256" }, + { file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed" }, + { file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae" }, + { file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62013a2cf68abc80dadfd2307299bfa8f5aa0dcaec5b2954caeb5fa094171103" }, + { file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b6616375d7de55797d7a66ee7d087efe27f03d336c27cf1f32c02b8c1a5ac70" }, + { file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94" }, + { file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f" }, + { file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1" }, + { file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4" }, + { file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9" }, + { file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a" }, + { file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f2931ed4741f98f74b410b16e5213f71dcccee67518970c42f64153ea9313b9" }, + { file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30f511c05fab7f12e0b1b7730ebdc2ec8deedcfb505bc27eb570ff47c51a8f15" }, + { file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f" }, + { file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a" }, + { file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002" }, + { file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d" }, + { file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493" }, + { file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439" }, + { file = "contourpy-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a67259c2b493b00e5a4d0f7bfae51fb4b3371395e47d079a4446e9b0f4d70e76" }, + { file = "contourpy-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2b836d22bd2c7bb2700348e4521b25e077255ebb6ab68e351ab5aa91ca27e027" }, + { file = "contourpy-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084eaa568400cfaf7179b847ac871582199b1b44d5699198e9602ecbbb5f6104" }, + { file = "contourpy-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:911ff4fd53e26b019f898f32db0d4956c9d227d51338fb3b03ec72ff0084ee5f" }, + { file = "contourpy-1.1.0.tar.gz", hash = "sha256:e53046c3863828d21d531cc3b53786e6580eb1ba02477e8681009b6aa0870b21" }, ] [package.dependencies] @@ -160,8 +160,8 @@ description = "Composable style cycles" optional = false python-versions = ">=3.6" files = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, + { file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3" }, + { file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f" }, ] [[package]] @@ -171,40 +171,40 @@ description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.42.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9c456d1f23deff64ffc8b5b098718e149279abdea4d8692dba69172fb6a0d597"}, - {file = "fonttools-4.42.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:150122ed93127a26bc3670ebab7e2add1e0983d30927733aec327ebf4255b072"}, - {file = "fonttools-4.42.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48e82d776d2e93f88ca56567509d102266e7ab2fb707a0326f032fe657335238"}, - {file = "fonttools-4.42.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58c1165f9b2662645de9b19a8c8bdd636b36294ccc07e1b0163856b74f10bafc"}, - {file = "fonttools-4.42.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2d6dc3fa91414ff4daa195c05f946e6a575bd214821e26d17ca50f74b35b0fe4"}, - {file = "fonttools-4.42.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fae4e801b774cc62cecf4a57b1eae4097903fced00c608d9e2bc8f84cd87b54a"}, - {file = "fonttools-4.42.0-cp310-cp310-win32.whl", hash = "sha256:b8600ae7dce6ec3ddfb201abb98c9d53abbf8064d7ac0c8a0d8925e722ccf2a0"}, - {file = "fonttools-4.42.0-cp310-cp310-win_amd64.whl", hash = "sha256:57b68eab183fafac7cd7d464a7bfa0fcd4edf6c67837d14fb09c1c20516cf20b"}, - {file = "fonttools-4.42.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0a1466713e54bdbf5521f2f73eebfe727a528905ff5ec63cda40961b4b1eea95"}, - {file = "fonttools-4.42.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3fb2a69870bfe143ec20b039a1c8009e149dd7780dd89554cc8a11f79e5de86b"}, - {file = "fonttools-4.42.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae881e484702efdb6cf756462622de81d4414c454edfd950b137e9a7352b3cb9"}, - {file = "fonttools-4.42.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27ec3246a088555629f9f0902f7412220c67340553ca91eb540cf247aacb1983"}, - {file = "fonttools-4.42.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ece1886d12bb36c48c00b2031518877f41abae317e3a55620d38e307d799b7e"}, - {file = "fonttools-4.42.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:10dac980f2b975ef74532e2a94bb00e97a95b4595fb7f98db493c474d5f54d0e"}, - {file = "fonttools-4.42.0-cp311-cp311-win32.whl", hash = "sha256:83b98be5d291e08501bd4fc0c4e0f8e6e05b99f3924068b17c5c9972af6fff84"}, - {file = "fonttools-4.42.0-cp311-cp311-win_amd64.whl", hash = "sha256:e35bed436726194c5e6e094fdfb423fb7afaa0211199f9d245e59e11118c576c"}, - {file = "fonttools-4.42.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c36c904ce0322df01e590ba814d5d69e084e985d7e4c2869378671d79662a7d4"}, - {file = "fonttools-4.42.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d54e600a2bcfa5cdaa860237765c01804a03b08404d6affcd92942fa7315ffba"}, - {file = "fonttools-4.42.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01cfe02416b6d416c5c8d15e30315cbcd3e97d1b50d3b34b0ce59f742ef55258"}, - {file = "fonttools-4.42.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f81ed9065b4bd3f4f3ce8e4873cd6a6b3f4e92b1eddefde35d332c6f414acc3"}, - {file = "fonttools-4.42.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:685a4dd6cf31593b50d6d441feb7781a4a7ef61e19551463e14ed7c527b86f9f"}, - {file = "fonttools-4.42.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:329341ba3d86a36e482610db56b30705384cb23bd595eac8cbb045f627778e9d"}, - {file = "fonttools-4.42.0-cp38-cp38-win32.whl", hash = "sha256:4655c480a1a4d706152ff54f20e20cf7609084016f1df3851cce67cef768f40a"}, - {file = "fonttools-4.42.0-cp38-cp38-win_amd64.whl", hash = "sha256:6bd7e4777bff1dcb7c4eff4786998422770f3bfbef8be401c5332895517ba3fa"}, - {file = "fonttools-4.42.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9b55d2a3b360e0c7fc5bd8badf1503ca1c11dd3a1cd20f2c26787ffa145a9c7"}, - {file = "fonttools-4.42.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0df8ef75ba5791e873c9eac2262196497525e3f07699a2576d3ab9ddf41cb619"}, - {file = "fonttools-4.42.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd2363ea7728496827658682d049ffb2e98525e2247ca64554864a8cc945568"}, - {file = "fonttools-4.42.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d40673b2e927f7cd0819c6f04489dfbeb337b4a7b10fc633c89bf4f34ecb9620"}, - {file = "fonttools-4.42.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c8bf88f9e3ce347c716921804ef3a8330cb128284eb6c0b6c4b3574f3c580023"}, - {file = "fonttools-4.42.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:703101eb0490fae32baf385385d47787b73d9ea55253df43b487c89ec767e0d7"}, - {file = "fonttools-4.42.0-cp39-cp39-win32.whl", hash = "sha256:f0290ea7f9945174bd4dfd66e96149037441eb2008f3649094f056201d99e293"}, - {file = "fonttools-4.42.0-cp39-cp39-win_amd64.whl", hash = "sha256:ae7df0ae9ee2f3f7676b0ff6f4ebe48ad0acaeeeaa0b6839d15dbf0709f2c5ef"}, - {file = "fonttools-4.42.0-py3-none-any.whl", hash = "sha256:dfe7fa7e607f7e8b58d0c32501a3a7cac148538300626d1b930082c90ae7f6bd"}, - {file = "fonttools-4.42.0.tar.gz", hash = "sha256:614b1283dca88effd20ee48160518e6de275ce9b5456a3134d5f235523fc5065"}, + { file = "fonttools-4.42.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9c456d1f23deff64ffc8b5b098718e149279abdea4d8692dba69172fb6a0d597" }, + { file = "fonttools-4.42.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:150122ed93127a26bc3670ebab7e2add1e0983d30927733aec327ebf4255b072" }, + { file = "fonttools-4.42.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48e82d776d2e93f88ca56567509d102266e7ab2fb707a0326f032fe657335238" }, + { file = "fonttools-4.42.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58c1165f9b2662645de9b19a8c8bdd636b36294ccc07e1b0163856b74f10bafc" }, + { file = "fonttools-4.42.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2d6dc3fa91414ff4daa195c05f946e6a575bd214821e26d17ca50f74b35b0fe4" }, + { file = "fonttools-4.42.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fae4e801b774cc62cecf4a57b1eae4097903fced00c608d9e2bc8f84cd87b54a" }, + { file = "fonttools-4.42.0-cp310-cp310-win32.whl", hash = "sha256:b8600ae7dce6ec3ddfb201abb98c9d53abbf8064d7ac0c8a0d8925e722ccf2a0" }, + { file = "fonttools-4.42.0-cp310-cp310-win_amd64.whl", hash = "sha256:57b68eab183fafac7cd7d464a7bfa0fcd4edf6c67837d14fb09c1c20516cf20b" }, + { file = "fonttools-4.42.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0a1466713e54bdbf5521f2f73eebfe727a528905ff5ec63cda40961b4b1eea95" }, + { file = "fonttools-4.42.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3fb2a69870bfe143ec20b039a1c8009e149dd7780dd89554cc8a11f79e5de86b" }, + { file = "fonttools-4.42.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae881e484702efdb6cf756462622de81d4414c454edfd950b137e9a7352b3cb9" }, + { file = "fonttools-4.42.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27ec3246a088555629f9f0902f7412220c67340553ca91eb540cf247aacb1983" }, + { file = "fonttools-4.42.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ece1886d12bb36c48c00b2031518877f41abae317e3a55620d38e307d799b7e" }, + { file = "fonttools-4.42.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:10dac980f2b975ef74532e2a94bb00e97a95b4595fb7f98db493c474d5f54d0e" }, + { file = "fonttools-4.42.0-cp311-cp311-win32.whl", hash = "sha256:83b98be5d291e08501bd4fc0c4e0f8e6e05b99f3924068b17c5c9972af6fff84" }, + { file = "fonttools-4.42.0-cp311-cp311-win_amd64.whl", hash = "sha256:e35bed436726194c5e6e094fdfb423fb7afaa0211199f9d245e59e11118c576c" }, + { file = "fonttools-4.42.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c36c904ce0322df01e590ba814d5d69e084e985d7e4c2869378671d79662a7d4" }, + { file = "fonttools-4.42.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d54e600a2bcfa5cdaa860237765c01804a03b08404d6affcd92942fa7315ffba" }, + { file = "fonttools-4.42.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01cfe02416b6d416c5c8d15e30315cbcd3e97d1b50d3b34b0ce59f742ef55258" }, + { file = "fonttools-4.42.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f81ed9065b4bd3f4f3ce8e4873cd6a6b3f4e92b1eddefde35d332c6f414acc3" }, + { file = "fonttools-4.42.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:685a4dd6cf31593b50d6d441feb7781a4a7ef61e19551463e14ed7c527b86f9f" }, + { file = "fonttools-4.42.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:329341ba3d86a36e482610db56b30705384cb23bd595eac8cbb045f627778e9d" }, + { file = "fonttools-4.42.0-cp38-cp38-win32.whl", hash = "sha256:4655c480a1a4d706152ff54f20e20cf7609084016f1df3851cce67cef768f40a" }, + { file = "fonttools-4.42.0-cp38-cp38-win_amd64.whl", hash = "sha256:6bd7e4777bff1dcb7c4eff4786998422770f3bfbef8be401c5332895517ba3fa" }, + { file = "fonttools-4.42.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9b55d2a3b360e0c7fc5bd8badf1503ca1c11dd3a1cd20f2c26787ffa145a9c7" }, + { file = "fonttools-4.42.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0df8ef75ba5791e873c9eac2262196497525e3f07699a2576d3ab9ddf41cb619" }, + { file = "fonttools-4.42.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd2363ea7728496827658682d049ffb2e98525e2247ca64554864a8cc945568" }, + { file = "fonttools-4.42.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d40673b2e927f7cd0819c6f04489dfbeb337b4a7b10fc633c89bf4f34ecb9620" }, + { file = "fonttools-4.42.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c8bf88f9e3ce347c716921804ef3a8330cb128284eb6c0b6c4b3574f3c580023" }, + { file = "fonttools-4.42.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:703101eb0490fae32baf385385d47787b73d9ea55253df43b487c89ec767e0d7" }, + { file = "fonttools-4.42.0-cp39-cp39-win32.whl", hash = "sha256:f0290ea7f9945174bd4dfd66e96149037441eb2008f3649094f056201d99e293" }, + { file = "fonttools-4.42.0-cp39-cp39-win_amd64.whl", hash = "sha256:ae7df0ae9ee2f3f7676b0ff6f4ebe48ad0acaeeeaa0b6839d15dbf0709f2c5ef" }, + { file = "fonttools-4.42.0-py3-none-any.whl", hash = "sha256:dfe7fa7e607f7e8b58d0c32501a3a7cac148538300626d1b930082c90ae7f6bd" }, + { file = "fonttools-4.42.0.tar.gz", hash = "sha256:614b1283dca88effd20ee48160518e6de275ce9b5456a3134d5f235523fc5065" }, ] [package.extras] @@ -228,26 +228,26 @@ description = "Read and write HDF5 files from Python" optional = false python-versions = ">=3.7" files = [ - {file = "h5py-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d77af42cb751ad6cc44f11bae73075a07429a5cf2094dfde2b1e716e059b3911"}, - {file = "h5py-3.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63beb8b7b47d0896c50de6efb9a1eaa81dbe211f3767e7dd7db159cea51ba37a"}, - {file = "h5py-3.7.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04e2e1e2fc51b8873e972a08d2f89625ef999b1f2d276199011af57bb9fc7851"}, - {file = "h5py-3.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f73307c876af49aa869ec5df1818e9bb0bdcfcf8a5ba773cc45a4fba5a286a5c"}, - {file = "h5py-3.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:f514b24cacdd983e61f8d371edac8c1b780c279d0acb8485639e97339c866073"}, - {file = "h5py-3.7.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:43fed4d13743cf02798a9a03a360a88e589d81285e72b83f47d37bb64ed44881"}, - {file = "h5py-3.7.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c038399ce09a58ff8d89ec3e62f00aa7cb82d14f34e24735b920e2a811a3a426"}, - {file = "h5py-3.7.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03d64fb86bb86b978928bad923b64419a23e836499ec6363e305ad28afd9d287"}, - {file = "h5py-3.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e5b7820b75f9519499d76cc708e27242ccfdd9dfb511d6deb98701961d0445aa"}, - {file = "h5py-3.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a9351d729ea754db36d175098361b920573fdad334125f86ac1dd3a083355e20"}, - {file = "h5py-3.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6776d896fb90c5938de8acb925e057e2f9f28755f67ec3edcbc8344832616c38"}, - {file = "h5py-3.7.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0a047fddbe6951bce40e9cde63373c838a978c5e05a011a682db9ba6334b8e85"}, - {file = "h5py-3.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0798a9c0ff45f17d0192e4d7114d734cac9f8b2b2c76dd1d923c4d0923f27bb6"}, - {file = "h5py-3.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:0d8de8cb619fc597da7cf8cdcbf3b7ff8c5f6db836568afc7dc16d21f59b2b49"}, - {file = "h5py-3.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f084bbe816907dfe59006756f8f2d16d352faff2d107f4ffeb1d8de126fc5dc7"}, - {file = "h5py-3.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1fcb11a2dc8eb7ddcae08afd8fae02ba10467753a857fa07a404d700a93f3d53"}, - {file = "h5py-3.7.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ed43e2cc4f511756fd664fb45d6b66c3cbed4e3bd0f70e29c37809b2ae013c44"}, - {file = "h5py-3.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e7535df5ee3dc3e5d1f408fdfc0b33b46bc9b34db82743c82cd674d8239b9ad"}, - {file = "h5py-3.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:9e2ad2aa000f5b1e73b5dfe22f358ca46bf1a2b6ca394d9659874d7fc251731a"}, - {file = "h5py-3.7.0.tar.gz", hash = "sha256:3fcf37884383c5da64846ab510190720027dca0768def34dd8dcb659dbe5cbf3"}, + { file = "h5py-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d77af42cb751ad6cc44f11bae73075a07429a5cf2094dfde2b1e716e059b3911" }, + { file = "h5py-3.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63beb8b7b47d0896c50de6efb9a1eaa81dbe211f3767e7dd7db159cea51ba37a" }, + { file = "h5py-3.7.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04e2e1e2fc51b8873e972a08d2f89625ef999b1f2d276199011af57bb9fc7851" }, + { file = "h5py-3.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f73307c876af49aa869ec5df1818e9bb0bdcfcf8a5ba773cc45a4fba5a286a5c" }, + { file = "h5py-3.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:f514b24cacdd983e61f8d371edac8c1b780c279d0acb8485639e97339c866073" }, + { file = "h5py-3.7.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:43fed4d13743cf02798a9a03a360a88e589d81285e72b83f47d37bb64ed44881" }, + { file = "h5py-3.7.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c038399ce09a58ff8d89ec3e62f00aa7cb82d14f34e24735b920e2a811a3a426" }, + { file = "h5py-3.7.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03d64fb86bb86b978928bad923b64419a23e836499ec6363e305ad28afd9d287" }, + { file = "h5py-3.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e5b7820b75f9519499d76cc708e27242ccfdd9dfb511d6deb98701961d0445aa" }, + { file = "h5py-3.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a9351d729ea754db36d175098361b920573fdad334125f86ac1dd3a083355e20" }, + { file = "h5py-3.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6776d896fb90c5938de8acb925e057e2f9f28755f67ec3edcbc8344832616c38" }, + { file = "h5py-3.7.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0a047fddbe6951bce40e9cde63373c838a978c5e05a011a682db9ba6334b8e85" }, + { file = "h5py-3.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0798a9c0ff45f17d0192e4d7114d734cac9f8b2b2c76dd1d923c4d0923f27bb6" }, + { file = "h5py-3.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:0d8de8cb619fc597da7cf8cdcbf3b7ff8c5f6db836568afc7dc16d21f59b2b49" }, + { file = "h5py-3.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f084bbe816907dfe59006756f8f2d16d352faff2d107f4ffeb1d8de126fc5dc7" }, + { file = "h5py-3.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1fcb11a2dc8eb7ddcae08afd8fae02ba10467753a857fa07a404d700a93f3d53" }, + { file = "h5py-3.7.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ed43e2cc4f511756fd664fb45d6b66c3cbed4e3bd0f70e29c37809b2ae013c44" }, + { file = "h5py-3.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e7535df5ee3dc3e5d1f408fdfc0b33b46bc9b34db82743c82cd674d8239b9ad" }, + { file = "h5py-3.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:9e2ad2aa000f5b1e73b5dfe22f358ca46bf1a2b6ca394d9659874d7fc251731a" }, + { file = "h5py-3.7.0.tar.gz", hash = "sha256:3fcf37884383c5da64846ab510190720027dca0768def34dd8dcb659dbe5cbf3" }, ] [package.dependencies] @@ -260,8 +260,8 @@ description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + { file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" }, + { file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4" }, ] [[package]] @@ -271,12 +271,12 @@ description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, - {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, + { file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf" }, + { file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" }, ] [package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} +zipp = { version = ">=3.1.0", markers = "python_version < \"3.10\"" } [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] @@ -289,8 +289,8 @@ description = "Lightweight pipelining with Python functions" optional = false python-versions = ">=3.7" files = [ - {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, - {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, + { file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9" }, + { file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1" }, ] [[package]] @@ -300,74 +300,74 @@ description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.7" files = [ - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, - {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, + { file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6" }, + { file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c" }, + { file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3" }, + { file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938" }, + { file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d" }, + { file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09" }, + { file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de" }, + { file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32" }, + { file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408" }, + { file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004" }, + { file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6" }, + { file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2" }, + { file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca" }, + { file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69" }, + { file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514" }, + { file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494" }, + { file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5" }, + { file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51" }, + { file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da" }, + { file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4" }, + { file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626" }, + { file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750" }, + { file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4" }, + { file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e" }, + { file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3" }, + { file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166" }, + { file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454" }, + { file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0" }, + { file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c" }, + { file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae" }, + { file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0" }, + { file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1" }, + { file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d" }, + { file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c" }, + { file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191" }, + { file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766" }, + { file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8" }, + { file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897" }, + { file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824" }, + { file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29" }, + { file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f" }, + { file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd" }, + { file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac" }, + { file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9" }, + { file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea" }, + { file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b" }, + { file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a" }, + { file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d" }, + { file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a" }, + { file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871" }, + { file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9" }, + { file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8" }, + { file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286" }, + { file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb" }, + { file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f" }, + { file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008" }, + { file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767" }, + { file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9" }, + { file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2" }, + { file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b" }, + { file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955" }, ] [[package]] @@ -377,8 +377,8 @@ description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, + { file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" }, + { file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1" }, ] [package.dependencies] @@ -401,54 +401,54 @@ description = "Python plotting package" optional = false python-versions = ">=3.8" files = [ - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, - {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, - {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, - {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, - {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, - {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, - {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, - {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, - {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, - {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, + { file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de" }, + { file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d" }, + { file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1" }, + { file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603" }, + { file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201" }, + { file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8" }, + { file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a" }, + { file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1" }, + { file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544" }, + { file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e" }, + { file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64" }, + { file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24" }, + { file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d" }, + { file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4" }, + { file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc" }, + { file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e" }, + { file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7" }, + { file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391" }, + { file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca" }, + { file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9" }, + { file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273" }, + { file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117" }, + { file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13" }, + { file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676" }, + { file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608" }, + { file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256" }, + { file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f" }, + { file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b" }, + { file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e" }, + { file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f" }, + { file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20" }, + { file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e" }, + { file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0" }, + { file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b" }, + { file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c" }, + { file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2" }, + { file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd" }, + { file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07" }, + { file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d" }, + { file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11" }, + { file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b" }, ] [package.dependencies] contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" -importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +importlib-resources = { version = ">=3.2.0", markers = "python_version < \"3.10\"" } kiwisolver = ">=1.0.1" numpy = ">=1.20" packaging = ">=20.0" @@ -463,8 +463,8 @@ description = "Markdown URL utilities" optional = false python-versions = ">=3.7" files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, + { file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8" }, + { file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" }, ] [[package]] @@ -474,8 +474,8 @@ description = "I/O for many mesh formats" optional = false python-versions = ">=3.7" files = [ - {file = "meshio-5.3.4-py3-none-any.whl", hash = "sha256:fbd5a7b387fdea98f4d7fed1f154f4a52b7f2e1d619762a52b8ece3df1d8aa0d"}, - {file = "meshio-5.3.4.tar.gz", hash = "sha256:e240692d7ff279c12b13c6e5d7b403629a86ad2b44e9230958b3f00c1ec369f0"}, + { file = "meshio-5.3.4-py3-none-any.whl", hash = "sha256:fbd5a7b387fdea98f4d7fed1f154f4a52b7f2e1d619762a52b8ece3df1d8aa0d" }, + { file = "meshio-5.3.4.tar.gz", hash = "sha256:e240692d7ff279c12b13c6e5d7b403629a86ad2b44e9230958b3f00c1ec369f0" }, ] [package.dependencies] @@ -492,31 +492,31 @@ description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"}, - {file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"}, - {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"}, - {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"}, - {file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"}, - {file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"}, - {file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"}, - {file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"}, - {file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"}, - {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"}, - {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"}, - {file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"}, - {file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"}, - {file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"}, - {file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"}, - {file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"}, - {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"}, - {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"}, - {file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"}, - {file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"}, - {file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"}, - {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, + { file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3" }, + { file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f" }, + { file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187" }, + { file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357" }, + { file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9" }, + { file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044" }, + { file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545" }, + { file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418" }, + { file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f" }, + { file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2" }, + { file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf" }, + { file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364" }, + { file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d" }, + { file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4" }, + { file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3" }, + { file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926" }, + { file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca" }, + { file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295" }, + { file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f" }, + { file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01" }, + { file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380" }, + { file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55" }, + { file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901" }, + { file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf" }, + { file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760" }, ] [[package]] @@ -526,8 +526,8 @@ description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + { file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61" }, + { file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" }, ] [[package]] @@ -537,40 +537,40 @@ description = "Powerful data structures for data analysis, time series, and stat optional = false python-versions = ">=3.8" files = [ - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, - {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, - {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, - {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, - {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, - {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, - {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, - {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, + { file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406" }, + { file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572" }, + { file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996" }, + { file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354" }, + { file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23" }, + { file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328" }, + { file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc" }, + { file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d" }, + { file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc" }, + { file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae" }, + { file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6" }, + { file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003" }, + { file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813" }, + { file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31" }, + { file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792" }, + { file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7" }, + { file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf" }, + { file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51" }, + { file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373" }, + { file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa" }, + { file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee" }, + { file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a" }, + { file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0" }, + { file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5" }, + { file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a" }, + { file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9" }, + { file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1" }, ] [package.dependencies] numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, - {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, + { version = ">=1.20.3", markers = "python_version < \"3.10\"" }, + { version = ">=1.21.0", markers = "python_version >= \"3.10\"" }, + { version = ">=1.23.2", markers = "python_version >= \"3.11\"" }, ] python-dateutil = ">=2.8.1" pytz = ">=2020.1" @@ -585,62 +585,62 @@ description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"}, - {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"}, - {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"}, - {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"}, - {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"}, - {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"}, - {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"}, - {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, - {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, - {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, - {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, - {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, - {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"}, - {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, - {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, - {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, - {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, - {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, - {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"}, - {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"}, - {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"}, - {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"}, - {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"}, - {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"}, - {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"}, - {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"}, - {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"}, - {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"}, + { file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891" }, + { file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614" }, + { file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b" }, + { file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c" }, + { file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1" }, + { file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf" }, + { file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3" }, + { file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992" }, + { file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de" }, + { file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485" }, + { file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f" }, + { file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3" }, + { file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d" }, + { file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd" }, + { file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629" }, + { file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538" }, + { file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d" }, + { file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f" }, + { file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37" }, + { file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883" }, + { file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e" }, + { file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640" }, + { file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568" }, + { file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223" }, + { file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff" }, + { file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551" }, + { file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5" }, + { file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199" }, + { file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca" }, + { file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3" }, + { file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3" }, + { file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43" }, + { file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d" }, + { file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530" }, + { file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51" }, + { file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86" }, + { file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7" }, + { file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0" }, + { file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa" }, + { file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90" }, + { file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967" }, + { file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d" }, + { file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3" }, + { file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba" }, + { file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3" }, + { file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017" }, + { file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6" }, + { file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0" }, + { file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba" }, + { file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3" }, + { file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334" }, + { file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2" }, + { file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed" }, + { file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684" }, + { file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3" }, + { file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396" }, ] [package.extras] @@ -654,8 +654,8 @@ description = "A small Python package for determining appropriate platform-speci optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + { file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d" }, + { file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d" }, ] [package.extras] @@ -669,8 +669,8 @@ description = "\"Pooch manages your Python library's sample data files: it autom optional = false python-versions = ">=3.7" files = [ - {file = "pooch-1.7.0-py3-none-any.whl", hash = "sha256:74258224fc33d58f53113cf955e8d51bf01386b91492927d0d1b6b341a765ad7"}, - {file = "pooch-1.7.0.tar.gz", hash = "sha256:f174a1041b6447f0eef8860f76d17f60ed2f857dc0efa387a7f08228af05d998"}, + { file = "pooch-1.7.0-py3-none-any.whl", hash = "sha256:74258224fc33d58f53113cf955e8d51bf01386b91492927d0d1b6b341a765ad7" }, + { file = "pooch-1.7.0.tar.gz", hash = "sha256:f174a1041b6447f0eef8860f76d17f60ed2f857dc0efa387a7f08228af05d998" }, ] [package.dependencies] @@ -690,8 +690,8 @@ description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + { file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692" }, + { file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" }, ] [package.extras] @@ -704,26 +704,26 @@ description = "Repairs triangular meshes" optional = false python-versions = ">=3.7" files = [ - {file = "pymeshfix-0.16.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2c8ec36e1de69139cb805489787feb6e5e83f7c54ae0c9cd0a6260fb5724d4db"}, - {file = "pymeshfix-0.16.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:62403ec6fe95cffbcf332f6a24c3ef70918234e9ea725e1f4ac3d92da59f7d7f"}, - {file = "pymeshfix-0.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:803b213eaf1a513da485160e5b78d6ad89e0d4db82debf6b2227bdf272c811ad"}, - {file = "pymeshfix-0.16.2-cp310-cp310-win_amd64.whl", hash = "sha256:6edd26e899f94544238cd82d50468e67432eb8c3102cc1a4db6fc938f9143da3"}, - {file = "pymeshfix-0.16.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:54e101ac5a3025c72da70336a078f272096a0b60dc698a0c7321754fd6e10f0c"}, - {file = "pymeshfix-0.16.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c41406bf50712014ae1f404ddb3b5e2e8fb93a884da8bd5f63b2617c2f60ccb7"}, - {file = "pymeshfix-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41300b3a9936a580ba0fd0b324d43c6d7842623bec68818474b0d32427119350"}, - {file = "pymeshfix-0.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:35216f55ec971e5502cd9e3ded6e67b2a29198420f0b0f40821a61947859e30f"}, - {file = "pymeshfix-0.16.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:16e28f5f508cfa7b2629af6a88db1ddedb36fd3d37b917877a51cc7a313d9807"}, - {file = "pymeshfix-0.16.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d54ba97d9fcfa7d0f3ba37af09fc320601824d590cd35454b9164db6c37282"}, - {file = "pymeshfix-0.16.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e21faec3d3902d8f5f8e4ebaa387324050c85692d4088dcdc8908a8896628280"}, - {file = "pymeshfix-0.16.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45bf20eb779609647681d39827e1e2b176d2b46a6299bbe4bd5ef5317cf6e2b5"}, - {file = "pymeshfix-0.16.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e511d45889d561fdbe8f7df66d0cb56290d4e7ca2af982ddb6982cb5261e3763"}, - {file = "pymeshfix-0.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d94ac59337e7ac7dd7fbfbbff542b478ecdf50ad61578c80f4d55480e3b3345"}, - {file = "pymeshfix-0.16.2-cp38-cp38-win_amd64.whl", hash = "sha256:b7ea6a251d7d78ed4dfc2f82d1a76030984be5a6a9d8c10f016d59dcc7f33480"}, - {file = "pymeshfix-0.16.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b1d0e08d633192c50e5ff02046c21f552045e66dcaf4d0dd037a17ffa634fae"}, - {file = "pymeshfix-0.16.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:461866d0a4ed276732807763de211a3264a4e42b29200c8111c9f5f350f4683f"}, - {file = "pymeshfix-0.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30acfd624caaefa4f33dffe0ad6c7eccf0d4201c82fc1e645d93e6ed56dc3bd2"}, - {file = "pymeshfix-0.16.2-cp39-cp39-win_amd64.whl", hash = "sha256:c0c02cc3be745da24402782b7face96b5bd6058afcaa23e648fef51f2426d7c1"}, - {file = "pymeshfix-0.16.2.tar.gz", hash = "sha256:774721f332b42ee1fb45a2c301c4440307674513efa0b03ea45feb2efc9daac6"}, + { file = "pymeshfix-0.16.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2c8ec36e1de69139cb805489787feb6e5e83f7c54ae0c9cd0a6260fb5724d4db" }, + { file = "pymeshfix-0.16.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:62403ec6fe95cffbcf332f6a24c3ef70918234e9ea725e1f4ac3d92da59f7d7f" }, + { file = "pymeshfix-0.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:803b213eaf1a513da485160e5b78d6ad89e0d4db82debf6b2227bdf272c811ad" }, + { file = "pymeshfix-0.16.2-cp310-cp310-win_amd64.whl", hash = "sha256:6edd26e899f94544238cd82d50468e67432eb8c3102cc1a4db6fc938f9143da3" }, + { file = "pymeshfix-0.16.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:54e101ac5a3025c72da70336a078f272096a0b60dc698a0c7321754fd6e10f0c" }, + { file = "pymeshfix-0.16.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c41406bf50712014ae1f404ddb3b5e2e8fb93a884da8bd5f63b2617c2f60ccb7" }, + { file = "pymeshfix-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41300b3a9936a580ba0fd0b324d43c6d7842623bec68818474b0d32427119350" }, + { file = "pymeshfix-0.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:35216f55ec971e5502cd9e3ded6e67b2a29198420f0b0f40821a61947859e30f" }, + { file = "pymeshfix-0.16.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:16e28f5f508cfa7b2629af6a88db1ddedb36fd3d37b917877a51cc7a313d9807" }, + { file = "pymeshfix-0.16.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d54ba97d9fcfa7d0f3ba37af09fc320601824d590cd35454b9164db6c37282" }, + { file = "pymeshfix-0.16.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e21faec3d3902d8f5f8e4ebaa387324050c85692d4088dcdc8908a8896628280" }, + { file = "pymeshfix-0.16.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45bf20eb779609647681d39827e1e2b176d2b46a6299bbe4bd5ef5317cf6e2b5" }, + { file = "pymeshfix-0.16.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e511d45889d561fdbe8f7df66d0cb56290d4e7ca2af982ddb6982cb5261e3763" }, + { file = "pymeshfix-0.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d94ac59337e7ac7dd7fbfbbff542b478ecdf50ad61578c80f4d55480e3b3345" }, + { file = "pymeshfix-0.16.2-cp38-cp38-win_amd64.whl", hash = "sha256:b7ea6a251d7d78ed4dfc2f82d1a76030984be5a6a9d8c10f016d59dcc7f33480" }, + { file = "pymeshfix-0.16.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b1d0e08d633192c50e5ff02046c21f552045e66dcaf4d0dd037a17ffa634fae" }, + { file = "pymeshfix-0.16.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:461866d0a4ed276732807763de211a3264a4e42b29200c8111c9f5f350f4683f" }, + { file = "pymeshfix-0.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30acfd624caaefa4f33dffe0ad6c7eccf0d4201c82fc1e645d93e6ed56dc3bd2" }, + { file = "pymeshfix-0.16.2-cp39-cp39-win_amd64.whl", hash = "sha256:c0c02cc3be745da24402782b7face96b5bd6058afcaa23e648fef51f2426d7c1" }, + { file = "pymeshfix-0.16.2.tar.gz", hash = "sha256:774721f332b42ee1fb45a2c301c4440307674513efa0b03ea45feb2efc9daac6" }, ] [package.dependencies] @@ -737,21 +737,21 @@ description = "A Python interface to MeshLab" optional = false python-versions = "*" files = [ - {file = "pymeshlab-2022.2.post4-cp310-cp310-macosx_10_11_x86_64.whl", hash = "sha256:8a626040b9c42ff94ceb0d4b7e3b168970dbf1da6cfac799fcb014365d0ff8f1"}, - {file = "pymeshlab-2022.2.post4-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:a3e598953d880f9692fecb3c79de81e22a0ed2f8dcae25d33baeed3dfadc7970"}, - {file = "pymeshlab-2022.2.post4-cp310-cp310-win_amd64.whl", hash = "sha256:104afd31ce5bd3ba143a8f1ca04b38360b2a768f82804635183a651ca5bd9d75"}, - {file = "pymeshlab-2022.2.post4-cp311-cp311-macosx_10_11_x86_64.whl", hash = "sha256:c5563991079c6e2f0e03af0c045c942df967a4af6a15d5c638350d1afe1f9eb6"}, - {file = "pymeshlab-2022.2.post4-cp311-cp311-manylinux_2_31_x86_64.whl", hash = "sha256:7d136ae936b0c0dc8b64abb50ad9d5adb6671985e6ef57a6b67d718fa684803f"}, - {file = "pymeshlab-2022.2.post4-cp311-cp311-win_amd64.whl", hash = "sha256:df36207ec245cd07729b7b7a22d2bc0b6f97d10b68fad06e4ac9e216500ae532"}, - {file = "pymeshlab-2022.2.post4-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:b3e1291d909f853981f2a96e2cdc9c8335047489a91723d88fec9e099cca5e14"}, - {file = "pymeshlab-2022.2.post4-cp37-cp37m-manylinux_2_31_x86_64.whl", hash = "sha256:defbf408c37a98a32c1582a146960c3999bae5966a764260b4adea1143e70c7d"}, - {file = "pymeshlab-2022.2.post4-cp37-cp37m-win_amd64.whl", hash = "sha256:154ac8b461728594bd6b947c87c6ff964ebc156273e77922403a0371d52d1643"}, - {file = "pymeshlab-2022.2.post4-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:808a650380a0b5514b433c1bb05b965a7a352a5e043a23b8b1f109819c5ab8c1"}, - {file = "pymeshlab-2022.2.post4-cp38-cp38-manylinux_2_31_x86_64.whl", hash = "sha256:c396eb4d5d86bc751c4b8e728bae50f542a278db6f199bc234f98197816f41da"}, - {file = "pymeshlab-2022.2.post4-cp38-cp38-win_amd64.whl", hash = "sha256:7ec9e9fab351f8e860521858d6976bc89ba01ace59c66ae36f05c794706129f1"}, - {file = "pymeshlab-2022.2.post4-cp39-cp39-macosx_10_11_x86_64.whl", hash = "sha256:cf3e6056a20b1a7c752be27a5a48ce31539e34e8042b3d452a519a99e4aa95f3"}, - {file = "pymeshlab-2022.2.post4-cp39-cp39-manylinux_2_31_x86_64.whl", hash = "sha256:59fdcd789b3396e518b84fdc57d23a477657406637b4ebd29308576defa539ed"}, - {file = "pymeshlab-2022.2.post4-cp39-cp39-win_amd64.whl", hash = "sha256:0a500b6823be58173b306b8a762acd04d60625976c092a496eb3b268ecfa8c85"}, + { file = "pymeshlab-2022.2.post4-cp310-cp310-macosx_10_11_x86_64.whl", hash = "sha256:8a626040b9c42ff94ceb0d4b7e3b168970dbf1da6cfac799fcb014365d0ff8f1" }, + { file = "pymeshlab-2022.2.post4-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:a3e598953d880f9692fecb3c79de81e22a0ed2f8dcae25d33baeed3dfadc7970" }, + { file = "pymeshlab-2022.2.post4-cp310-cp310-win_amd64.whl", hash = "sha256:104afd31ce5bd3ba143a8f1ca04b38360b2a768f82804635183a651ca5bd9d75" }, + { file = "pymeshlab-2022.2.post4-cp311-cp311-macosx_10_11_x86_64.whl", hash = "sha256:c5563991079c6e2f0e03af0c045c942df967a4af6a15d5c638350d1afe1f9eb6" }, + { file = "pymeshlab-2022.2.post4-cp311-cp311-manylinux_2_31_x86_64.whl", hash = "sha256:7d136ae936b0c0dc8b64abb50ad9d5adb6671985e6ef57a6b67d718fa684803f" }, + { file = "pymeshlab-2022.2.post4-cp311-cp311-win_amd64.whl", hash = "sha256:df36207ec245cd07729b7b7a22d2bc0b6f97d10b68fad06e4ac9e216500ae532" }, + { file = "pymeshlab-2022.2.post4-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:b3e1291d909f853981f2a96e2cdc9c8335047489a91723d88fec9e099cca5e14" }, + { file = "pymeshlab-2022.2.post4-cp37-cp37m-manylinux_2_31_x86_64.whl", hash = "sha256:defbf408c37a98a32c1582a146960c3999bae5966a764260b4adea1143e70c7d" }, + { file = "pymeshlab-2022.2.post4-cp37-cp37m-win_amd64.whl", hash = "sha256:154ac8b461728594bd6b947c87c6ff964ebc156273e77922403a0371d52d1643" }, + { file = "pymeshlab-2022.2.post4-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:808a650380a0b5514b433c1bb05b965a7a352a5e043a23b8b1f109819c5ab8c1" }, + { file = "pymeshlab-2022.2.post4-cp38-cp38-manylinux_2_31_x86_64.whl", hash = "sha256:c396eb4d5d86bc751c4b8e728bae50f542a278db6f199bc234f98197816f41da" }, + { file = "pymeshlab-2022.2.post4-cp38-cp38-win_amd64.whl", hash = "sha256:7ec9e9fab351f8e860521858d6976bc89ba01ace59c66ae36f05c794706129f1" }, + { file = "pymeshlab-2022.2.post4-cp39-cp39-macosx_10_11_x86_64.whl", hash = "sha256:cf3e6056a20b1a7c752be27a5a48ce31539e34e8042b3d452a519a99e4aa95f3" }, + { file = "pymeshlab-2022.2.post4-cp39-cp39-manylinux_2_31_x86_64.whl", hash = "sha256:59fdcd789b3396e518b84fdc57d23a477657406637b4ebd29308576defa539ed" }, + { file = "pymeshlab-2022.2.post4-cp39-cp39-win_amd64.whl", hash = "sha256:0a500b6823be58173b306b8a762acd04d60625976c092a496eb3b268ecfa8c85" }, ] [package.dependencies] @@ -764,8 +764,8 @@ description = "pyparsing module - Classes and methods to define and execute pars optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, + { file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" }, + { file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb" }, ] [package.extras] @@ -778,8 +778,8 @@ description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + { file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86" }, + { file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" }, ] [package.dependencies] @@ -792,8 +792,8 @@ description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, + { file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb" }, + { file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588" }, ] [[package]] @@ -803,8 +803,8 @@ description = "Easier Pythonic interface to VTK" optional = false python-versions = ">=3.8" files = [ - {file = "pyvista-0.41.1-py3-none-any.whl", hash = "sha256:320785b45432089a37d3a09828853af1edf629eca8ded0fe0002c2a661e26c77"}, - {file = "pyvista-0.41.1.tar.gz", hash = "sha256:a4d03e00d3cfb7df6c68d0be9a915435651375f6278c1d787c0903fe10701683"}, + { file = "pyvista-0.41.1-py3-none-any.whl", hash = "sha256:320785b45432089a37d3a09828853af1edf629eca8ded0fe0002c2a661e26c77" }, + { file = "pyvista-0.41.1.tar.gz", hash = "sha256:a4d03e00d3cfb7df6c68d0be9a915435651375f6278c1d787c0903fe10701683" }, ] [package.dependencies] @@ -829,8 +829,8 @@ description = "Python HTTP for Humans." optional = false python-versions = ">=3.7" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + { file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f" }, + { file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" }, ] [package.dependencies] @@ -850,8 +850,8 @@ description = "Render rich text, tables, progress bars, syntax highlighting, mar optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"}, - {file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"}, + { file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808" }, + { file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39" }, ] [package.dependencies] @@ -868,27 +868,27 @@ description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.8" files = [ - {file = "scikit-learn-1.2.2.tar.gz", hash = "sha256:8429aea30ec24e7a8c7ed8a3fa6213adf3814a6efbea09e16e0a0c71e1a1a3d7"}, - {file = "scikit_learn-1.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99cc01184e347de485bf253d19fcb3b1a3fb0ee4cea5ee3c43ec0cc429b6d29f"}, - {file = "scikit_learn-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e6e574db9914afcb4e11ade84fab084536a895ca60aadea3041e85b8ac963edb"}, - {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fe83b676f407f00afa388dd1fdd49e5c6612e551ed84f3b1b182858f09e987d"}, - {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2642baa0ad1e8f8188917423dd73994bf25429f8893ddbe115be3ca3183584"}, - {file = "scikit_learn-1.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ad66c3848c0a1ec13464b2a95d0a484fd5b02ce74268eaa7e0c697b904f31d6c"}, - {file = "scikit_learn-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfeaf8be72117eb61a164ea6fc8afb6dfe08c6f90365bde2dc16456e4bc8e45f"}, - {file = "scikit_learn-1.2.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:fe0aa1a7029ed3e1dcbf4a5bc675aa3b1bc468d9012ecf6c6f081251ca47f590"}, - {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:065e9673e24e0dc5113e2dd2b4ca30c9d8aa2fa90f4c0597241c93b63130d233"}, - {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf036ea7ef66115e0d49655f16febfa547886deba20149555a41d28f56fd6d3c"}, - {file = "scikit_learn-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8b0670d4224a3c2d596fd572fb4fa673b2a0ccfb07152688ebd2ea0b8c61025c"}, - {file = "scikit_learn-1.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9c710ff9f9936ba8a3b74a455ccf0dcf59b230caa1e9ba0223773c490cab1e51"}, - {file = "scikit_learn-1.2.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:2dd3ffd3950e3d6c0c0ef9033a9b9b32d910c61bd06cb8206303fb4514b88a49"}, - {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44b47a305190c28dd8dd73fc9445f802b6ea716669cfc22ab1eb97b335d238b1"}, - {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:953236889928d104c2ef14027539f5f2609a47ebf716b8cbe4437e85dce42744"}, - {file = "scikit_learn-1.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:7f69313884e8eb311460cc2f28676d5e400bd929841a2c8eb8742ae78ebf7c20"}, - {file = "scikit_learn-1.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8156db41e1c39c69aa2d8599ab7577af53e9e5e7a57b0504e116cc73c39138dd"}, - {file = "scikit_learn-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fe175ee1dab589d2e1033657c5b6bec92a8a3b69103e3dd361b58014729975c3"}, - {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d5312d9674bed14f73773d2acf15a3272639b981e60b72c9b190a0cffed5bad"}, - {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea061bf0283bf9a9f36ea3c5d3231ba2176221bbd430abd2603b1c3b2ed85c89"}, - {file = "scikit_learn-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6477eed40dbce190f9f9e9d0d37e020815825b300121307942ec2110302b66a3"}, + { file = "scikit-learn-1.2.2.tar.gz", hash = "sha256:8429aea30ec24e7a8c7ed8a3fa6213adf3814a6efbea09e16e0a0c71e1a1a3d7" }, + { file = "scikit_learn-1.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99cc01184e347de485bf253d19fcb3b1a3fb0ee4cea5ee3c43ec0cc429b6d29f" }, + { file = "scikit_learn-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e6e574db9914afcb4e11ade84fab084536a895ca60aadea3041e85b8ac963edb" }, + { file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fe83b676f407f00afa388dd1fdd49e5c6612e551ed84f3b1b182858f09e987d" }, + { file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2642baa0ad1e8f8188917423dd73994bf25429f8893ddbe115be3ca3183584" }, + { file = "scikit_learn-1.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ad66c3848c0a1ec13464b2a95d0a484fd5b02ce74268eaa7e0c697b904f31d6c" }, + { file = "scikit_learn-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfeaf8be72117eb61a164ea6fc8afb6dfe08c6f90365bde2dc16456e4bc8e45f" }, + { file = "scikit_learn-1.2.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:fe0aa1a7029ed3e1dcbf4a5bc675aa3b1bc468d9012ecf6c6f081251ca47f590" }, + { file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:065e9673e24e0dc5113e2dd2b4ca30c9d8aa2fa90f4c0597241c93b63130d233" }, + { file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf036ea7ef66115e0d49655f16febfa547886deba20149555a41d28f56fd6d3c" }, + { file = "scikit_learn-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8b0670d4224a3c2d596fd572fb4fa673b2a0ccfb07152688ebd2ea0b8c61025c" }, + { file = "scikit_learn-1.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9c710ff9f9936ba8a3b74a455ccf0dcf59b230caa1e9ba0223773c490cab1e51" }, + { file = "scikit_learn-1.2.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:2dd3ffd3950e3d6c0c0ef9033a9b9b32d910c61bd06cb8206303fb4514b88a49" }, + { file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44b47a305190c28dd8dd73fc9445f802b6ea716669cfc22ab1eb97b335d238b1" }, + { file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:953236889928d104c2ef14027539f5f2609a47ebf716b8cbe4437e85dce42744" }, + { file = "scikit_learn-1.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:7f69313884e8eb311460cc2f28676d5e400bd929841a2c8eb8742ae78ebf7c20" }, + { file = "scikit_learn-1.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8156db41e1c39c69aa2d8599ab7577af53e9e5e7a57b0504e116cc73c39138dd" }, + { file = "scikit_learn-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fe175ee1dab589d2e1033657c5b6bec92a8a3b69103e3dd361b58014729975c3" }, + { file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d5312d9674bed14f73773d2acf15a3272639b981e60b72c9b190a0cffed5bad" }, + { file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea061bf0283bf9a9f36ea3c5d3231ba2176221bbd430abd2603b1c3b2ed85c89" }, + { file = "scikit_learn-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6477eed40dbce190f9f9e9d0d37e020815825b300121307942ec2110302b66a3" }, ] [package.dependencies] @@ -910,27 +910,27 @@ description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.8" files = [ - {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, - {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, - {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, - {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, - {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, - {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, - {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, - {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, - {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, - {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, - {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, - {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, - {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, - {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, - {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, - {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, - {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, - {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, - {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, - {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, - {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, + { file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0" }, + { file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd" }, + { file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b" }, + { file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9" }, + { file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523" }, + { file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096" }, + { file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c" }, + { file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab" }, + { file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb" }, + { file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31" }, + { file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840" }, + { file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5" }, + { file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108" }, + { file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc" }, + { file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e" }, + { file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c" }, + { file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95" }, + { file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e" }, + { file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0" }, + { file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58" }, + { file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027" }, ] [package.dependencies] @@ -948,8 +948,8 @@ description = "A Great Dane turned Python environment detective" optional = false python-versions = ">=3.7" files = [ - {file = "scooby-0.7.2-py3-none-any.whl", hash = "sha256:75b77d22ecc22a5578fb0bb2957e8d024fa863fe905cd43447a86860afe37978"}, - {file = "scooby-0.7.2.tar.gz", hash = "sha256:6ba082ede5a82952b42538f913b3dfe3581ab79f5628e6c6efd3481f6cb5756e"}, + { file = "scooby-0.7.2-py3-none-any.whl", hash = "sha256:75b77d22ecc22a5578fb0bb2957e8d024fa863fe905cd43447a86860afe37978" }, + { file = "scooby-0.7.2.tar.gz", hash = "sha256:6ba082ede5a82952b42538f913b3dfe3581ab79f5628e6c6efd3481f6cb5756e" }, ] [package.extras] @@ -962,8 +962,8 @@ description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + { file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" }, + { file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926" }, ] [[package]] @@ -973,8 +973,8 @@ description = "threadpoolctl" optional = false python-versions = ">=3.8" files = [ - {file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032"}, - {file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355"}, + { file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032" }, + { file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355" }, ] [[package]] @@ -984,17 +984,17 @@ description = "Homogeneous Transformation Matrices and Quaternions" optional = false python-versions = ">=3.8" files = [ - {file = "transformations-2022.9.26-cp310-cp310-win32.whl", hash = "sha256:f7299b3c0e2d39a4391606e2f7548cf8692f17b25f548e34f47893bf4f8a6889"}, - {file = "transformations-2022.9.26-cp310-cp310-win_amd64.whl", hash = "sha256:875bc879820331e845033ca1f00e6fbaf13706f276fa0ad160072c89ecbe5857"}, - {file = "transformations-2022.9.26-cp311-cp311-win32.whl", hash = "sha256:dcdbac01fecd0d3566fe3b06e09fad15b7a9fbebcdafa3bf886b3bb629b42696"}, - {file = "transformations-2022.9.26-cp311-cp311-win_amd64.whl", hash = "sha256:7c5cb3d89be26c3efec12418edf3da4a0da72061463b536e72538d54a27d3b36"}, - {file = "transformations-2022.9.26-cp311-cp311-win_arm64.whl", hash = "sha256:4712412683cd318110b38acd1554e731770e23d3580daf938f9c0747786e82e6"}, - {file = "transformations-2022.9.26-cp38-cp38-win32.whl", hash = "sha256:858f0bddfa4f197b81c3cd04b730513ddf05e12dd383492e3236e3321bced3cf"}, - {file = "transformations-2022.9.26-cp38-cp38-win_amd64.whl", hash = "sha256:0b1123cd7856767ac7f58e90c5ac11f122713c0e3f2ae945a6a7d7766594b3f6"}, - {file = "transformations-2022.9.26-cp39-cp39-win32.whl", hash = "sha256:b4722965c778586073b35b7f752a8cb9270ce7165714a0308dcee155e1a2c3fa"}, - {file = "transformations-2022.9.26-cp39-cp39-win_amd64.whl", hash = "sha256:a514bb2fbef938795c260db8e8215eb7d6eab4e68ced5dbfd3ee2c3b570c72fe"}, - {file = "transformations-2022.9.26-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:adefd73a077e36553d5e88107abf7afea23b82f4fdb8942054a35a8b6d1f073c"}, - {file = "transformations-2022.9.26.tar.gz", hash = "sha256:9141233392e768eb224b73059b60f19df748bb69493dfd16db7cac9f6e93a4ba"}, + { file = "transformations-2022.9.26-cp310-cp310-win32.whl", hash = "sha256:f7299b3c0e2d39a4391606e2f7548cf8692f17b25f548e34f47893bf4f8a6889" }, + { file = "transformations-2022.9.26-cp310-cp310-win_amd64.whl", hash = "sha256:875bc879820331e845033ca1f00e6fbaf13706f276fa0ad160072c89ecbe5857" }, + { file = "transformations-2022.9.26-cp311-cp311-win32.whl", hash = "sha256:dcdbac01fecd0d3566fe3b06e09fad15b7a9fbebcdafa3bf886b3bb629b42696" }, + { file = "transformations-2022.9.26-cp311-cp311-win_amd64.whl", hash = "sha256:7c5cb3d89be26c3efec12418edf3da4a0da72061463b536e72538d54a27d3b36" }, + { file = "transformations-2022.9.26-cp311-cp311-win_arm64.whl", hash = "sha256:4712412683cd318110b38acd1554e731770e23d3580daf938f9c0747786e82e6" }, + { file = "transformations-2022.9.26-cp38-cp38-win32.whl", hash = "sha256:858f0bddfa4f197b81c3cd04b730513ddf05e12dd383492e3236e3321bced3cf" }, + { file = "transformations-2022.9.26-cp38-cp38-win_amd64.whl", hash = "sha256:0b1123cd7856767ac7f58e90c5ac11f122713c0e3f2ae945a6a7d7766594b3f6" }, + { file = "transformations-2022.9.26-cp39-cp39-win32.whl", hash = "sha256:b4722965c778586073b35b7f752a8cb9270ce7165714a0308dcee155e1a2c3fa" }, + { file = "transformations-2022.9.26-cp39-cp39-win_amd64.whl", hash = "sha256:a514bb2fbef938795c260db8e8215eb7d6eab4e68ced5dbfd3ee2c3b570c72fe" }, + { file = "transformations-2022.9.26-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:adefd73a077e36553d5e88107abf7afea23b82f4fdb8942054a35a8b6d1f073c" }, + { file = "transformations-2022.9.26.tar.gz", hash = "sha256:9141233392e768eb224b73059b60f19df748bb69493dfd16db7cac9f6e93a4ba" }, ] [package.dependencies] @@ -1007,8 +1007,8 @@ description = "HTTP library with thread-safe connection pooling, file post, and optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, - {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, + { file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" }, + { file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11" }, ] [package.extras] @@ -1024,27 +1024,27 @@ description = "VTK is an open-source toolkit for 3D computer graphics, image pro optional = false python-versions = "*" files = [ - {file = "vtk-9.2.6-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:acf8b0e0a2b51b8aa36cee1ea1ba0b73c565871efaa14cf2606d9bef36feba3a"}, - {file = "vtk-9.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ec9827287f1743c736ea9b51572d20dcd15a065170808f97408eebd404275b4"}, - {file = "vtk-9.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3473f3b3dc919d3e2ef0cc9927654731941fd7b79d3dcaa343cdaff3e4e40838"}, - {file = "vtk-9.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:37561b19b4b70c7034d9e689238560d7afec49ff89704b9bb3c9bb89a90ee54e"}, - {file = "vtk-9.2.6-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9289f6ee5432f0a00aeb7b674d7ca03054bc50fa6c74126751f8b19f931f52fc"}, - {file = "vtk-9.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b947a33a7c5562ac4d9c8dce389f4ed720cc2559389048993ae45cbed3bbeb1"}, - {file = "vtk-9.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87930115c8067a2d482beebc48a50fcacdc0154d8d7c763471a9be8b5eb76cc3"}, - {file = "vtk-9.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:6c3ca0663f251fbd6e26d93294801ceee6c3cc329f6070dccde3b68046ab9ee7"}, - {file = "vtk-9.2.6-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:86c548da22a0bd9ce9e060364925e8fa0a551064f9660ae1d486ac3118ffb770"}, - {file = "vtk-9.2.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7622e98b3590bf909f056a1bad55575760727fd673c3e8e224134d52b11d00d"}, - {file = "vtk-9.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:bb28432277136774e91eb1084a8f5f1c4c952d4e74f74626a16ac6e199eba5c5"}, - {file = "vtk-9.2.6-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:feb9d211583d7b1dd45ca6616bf2f9622d0eadf9e3084f53d20de819e5808d42"}, - {file = "vtk-9.2.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bc1123b6f2f3746d35325cf1a48630c8f49a3516c9970a5bdea15823909bbca"}, - {file = "vtk-9.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:78103568e97d947026cd39a70e6719277d7341f984c06abaec64d3429e200a6f"}, - {file = "vtk-9.2.6-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8236e00d0ad24730f4b783bbc038108426e6a78c892fd6ae9a8e8eb846f3e8e3"}, - {file = "vtk-9.2.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:affbb15762bcb6d9632a668ec53c6a3102d4f6c14c4178f01489c0b711114521"}, - {file = "vtk-9.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:f9d3450c00ced28f942a0a7dc5f27a667cf6b171d9ef5a090cb7c8e21dd1a121"}, - {file = "vtk-9.2.6-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9b396909a4372d3be4a01fde4a0af4f3e410742d73d185982c6f48a61090ebfe"}, - {file = "vtk-9.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9d41a18bbd6fac18a814bbaeeb615044da036afc2bd98cdf7ea52853fd1ef950"}, - {file = "vtk-9.2.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79991dccbc483a8e5d23e5d3ae1e358fee0526fe8f710d07868ecae58c6b9535"}, - {file = "vtk-9.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:2d905a686ee1b28dd2ac3c3595a3fbcbd171e4b1f9aabac3c8019c6f3a4f8157"}, + { file = "vtk-9.2.6-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:acf8b0e0a2b51b8aa36cee1ea1ba0b73c565871efaa14cf2606d9bef36feba3a" }, + { file = "vtk-9.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ec9827287f1743c736ea9b51572d20dcd15a065170808f97408eebd404275b4" }, + { file = "vtk-9.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3473f3b3dc919d3e2ef0cc9927654731941fd7b79d3dcaa343cdaff3e4e40838" }, + { file = "vtk-9.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:37561b19b4b70c7034d9e689238560d7afec49ff89704b9bb3c9bb89a90ee54e" }, + { file = "vtk-9.2.6-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9289f6ee5432f0a00aeb7b674d7ca03054bc50fa6c74126751f8b19f931f52fc" }, + { file = "vtk-9.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b947a33a7c5562ac4d9c8dce389f4ed720cc2559389048993ae45cbed3bbeb1" }, + { file = "vtk-9.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87930115c8067a2d482beebc48a50fcacdc0154d8d7c763471a9be8b5eb76cc3" }, + { file = "vtk-9.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:6c3ca0663f251fbd6e26d93294801ceee6c3cc329f6070dccde3b68046ab9ee7" }, + { file = "vtk-9.2.6-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:86c548da22a0bd9ce9e060364925e8fa0a551064f9660ae1d486ac3118ffb770" }, + { file = "vtk-9.2.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7622e98b3590bf909f056a1bad55575760727fd673c3e8e224134d52b11d00d" }, + { file = "vtk-9.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:bb28432277136774e91eb1084a8f5f1c4c952d4e74f74626a16ac6e199eba5c5" }, + { file = "vtk-9.2.6-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:feb9d211583d7b1dd45ca6616bf2f9622d0eadf9e3084f53d20de819e5808d42" }, + { file = "vtk-9.2.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bc1123b6f2f3746d35325cf1a48630c8f49a3516c9970a5bdea15823909bbca" }, + { file = "vtk-9.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:78103568e97d947026cd39a70e6719277d7341f984c06abaec64d3429e200a6f" }, + { file = "vtk-9.2.6-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8236e00d0ad24730f4b783bbc038108426e6a78c892fd6ae9a8e8eb846f3e8e3" }, + { file = "vtk-9.2.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:affbb15762bcb6d9632a668ec53c6a3102d4f6c14c4178f01489c0b711114521" }, + { file = "vtk-9.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:f9d3450c00ced28f942a0a7dc5f27a667cf6b171d9ef5a090cb7c8e21dd1a121" }, + { file = "vtk-9.2.6-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9b396909a4372d3be4a01fde4a0af4f3e410742d73d185982c6f48a61090ebfe" }, + { file = "vtk-9.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9d41a18bbd6fac18a814bbaeeb615044da036afc2bd98cdf7ea52853fd1ef950" }, + { file = "vtk-9.2.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79991dccbc483a8e5d23e5d3ae1e358fee0526fe8f710d07868ecae58c6b9535" }, + { file = "vtk-9.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:2d905a686ee1b28dd2ac3c3595a3fbcbd171e4b1f9aabac3c8019c6f3a4f8157" }, ] [package.dependencies] @@ -1061,8 +1061,8 @@ description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, + { file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0" }, + { file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" }, ] [package.extras] diff --git a/standalones/create_SSM_instance.py b/standalones/create_SSM_instance.py index ea0cfdf..939928d 100644 --- a/standalones/create_SSM_instance.py +++ b/standalones/create_SSM_instance.py @@ -30,8 +30,8 @@ import pyvista as pv import numpy as np -def parser(): +def parser(): parser = argparse.ArgumentParser(description='Cut veins manually') parser.add_argument('--SSM_file', type=str, @@ -45,31 +45,32 @@ def parser(): type=str, default="", help='path to output') - + return parser -def create_SSM_instance(SSM_file, coefficients_file, output_file): +def create_SSM_instance(SSM_file, coefficients_file, output_file): r = np.loadtxt(coefficients_file, delimiter=',') with h5py.File(SSM_file, "r") as f: - mean_pts = list(f["model"]["mean"])[0] mean_cells = np.vstack(list(f["representer"]["cells"])).T - mean_cells = np.c_[np.ones(len(mean_cells),dtype=int)*3,mean_cells] + mean_cells = np.c_[np.ones(len(mean_cells), dtype=int) * 3, mean_cells] pca_basisfunctions = np.vstack(list(f["model"]["pcaBasis"])).T pca_var = list(f["model"]["pcaVariance"])[0] for i in range(len(pca_basisfunctions)): - mean_pts = mean_pts + r[i]*pca_basisfunctions[i,:]*np.sqrt(pca_var[i]) + mean_pts = mean_pts + r[i] * pca_basisfunctions[i, :] * np.sqrt(pca_var[i]) - mean_pts = mean_pts.reshape(int(len(mean_pts)/3),3) + mean_pts = mean_pts.reshape(int(len(mean_pts) / 3), 3) surf = pv.PolyData(mean_pts, mean_cells) pv.save_meshio(output_file, surf, "obj") + def run(): args = parser().parse_args() create_SSM_instance(args.SSM_file, args.coefficients_file, args.output_file) + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/standalones/getmarks.py b/standalones/getmarks.py index 17e1b02..0c141e1 100644 --- a/standalones/getmarks.py +++ b/standalones/getmarks.py @@ -36,8 +36,8 @@ from sklearn.neighbors import NearestNeighbors import argparse -def parser(): +def parser(): parser = argparse.ArgumentParser(description='Generate landmarks for fitting SSM.') parser.add_argument('--mesh', type=str, @@ -54,21 +54,21 @@ def parser(): return parser -def get_landmarks(mesh, prealigned=1, scale=1): +def get_landmarks(mesh, prealigned=1, scale=1): mesh_dir = "{}_surf".format(mesh) reader = vtk.vtkPolyDataReader() if prealigned: reader.SetFileName(mesh_dir + '/LA_prealigned.vtk') - df = pd.read_csv(mesh+"_surf/rings_centroids_prealigned.csv") + df = pd.read_csv(mesh + "_surf/rings_centroids_prealigned.csv") else: reader.SetFileName(mesh_dir + '/LA_boundaries_tagged.vtk') - df = pd.read_csv(mesh+"_surf/rings_centroids.csv") + df = pd.read_csv(mesh + "_surf/rings_centroids.csv") reader.Update() model = reader.GetOutput() - + model_polydata = function.to_polydata(model) - + thr = vtk.vtkThreshold() thr.SetInputData(model) thr.AllScalarsOff() @@ -76,7 +76,7 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr.ThresholdBetween(5, 5) thr.Update() rsv = thr.GetOutput() - + thr = vtk.vtkThreshold() thr.SetInputData(model) thr.AllScalarsOff() @@ -84,7 +84,7 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr.ThresholdBetween(4, 4) thr.Update() riv = thr.GetOutput() - + thr = vtk.vtkThreshold() thr.SetInputData(model) thr.AllScalarsOff() @@ -92,7 +92,7 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr.ThresholdBetween(3, 3) thr.Update() lsv = thr.GetOutput() - + thr = vtk.vtkThreshold() thr.SetInputData(model) thr.AllScalarsOff() @@ -100,7 +100,7 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr.ThresholdBetween(2, 2) thr.Update() liv = thr.GetOutput() - + thr = vtk.vtkThreshold() thr.SetInputData(model) thr.AllScalarsOff() @@ -108,40 +108,41 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr.ThresholdBetween(1, 1) thr.Update() mv = thr.GetOutput() - + rsv_points = vtk.util.numpy_support.vtk_to_numpy(rsv.GetPoints().GetData()) riv_points = vtk.util.numpy_support.vtk_to_numpy(riv.GetPoints().GetData()) lsv_points = vtk.util.numpy_support.vtk_to_numpy(lsv.GetPoints().GetData()) liv_points = vtk.util.numpy_support.vtk_to_numpy(liv.GetPoints().GetData()) mv_points = vtk.util.numpy_support.vtk_to_numpy(mv.GetPoints().GetData()) - + # get farthest away and clostest points on PVs rs_o, ri_o = function.get_farthest_point_pair(rsv_points, riv_points) ls_o, li_o = function.get_farthest_point_pair(lsv_points, liv_points) - + rs_i, ri_i = function.get_closest_point(rsv.GetPoints(), riv.GetPoints()) ls_i, li_i = function.get_closest_point(lsv.GetPoints(), liv.GetPoints()) - + # Centroids of LPV and RPV center_lpv = function.get_mean_point(np.vstack((ls_i, li_i))) center_rpv = function.get_mean_point(np.vstack((rs_i, ri_i))) - + # mitral valve center_mv = function.get_mean_point(mv_points) - + mv_polydata = function.to_polydata(mv) mv_anterior, mv_posterior = function.cut_into_two_parts(mv_polydata, center_mv, center_rpv, center_lpv) - - mv_band = function.cut_a_band_from_model(function.to_polydata(mv_anterior), center_mv, center_rpv, center_lpv, 10*scale) + + mv_band = function.cut_a_band_from_model(function.to_polydata(mv_anterior), center_mv, center_rpv, center_lpv, + 10 * scale) mv_l_fuzzy, mv_r_fuzzy = function.get_mv_l_and_r(mv_band, center_lpv) - + # mv_anterior loc_an = vtk.vtkPointLocator() loc_an.SetDataSet(mv_anterior) loc_an.BuildLocator() mv_an_l = mv_anterior.GetPoint(loc_an.FindClosestPoint(mv_l_fuzzy)) mv_an_r = mv_anterior.GetPoint(loc_an.FindClosestPoint(mv_r_fuzzy)) - + # mv_posterior loc_po = vtk.vtkPointLocator() loc_po.SetDataSet(mv_posterior) @@ -153,95 +154,97 @@ def get_landmarks(mesh, prealigned=1, scale=1): loc_an.FindClosestPoint(mv_r_fuzzy)) path_po = function.dijkstra_path(function.to_polydata(mv_posterior), loc_po.FindClosestPoint(mv_l_fuzzy), loc_po.FindClosestPoint(mv_r_fuzzy)) - + length_an = len(path_an) mv_an_middle = path_an[int(length_an * 0.5)] length_po = len(path_po) mv_po_middle = path_po[int(length_po * 0.5)] - - + mv_l = mv_an_l mv_r = mv_an_r - - band = function.cut_a_band_from_model(model_polydata, center_mv, center_rpv, center_lpv, 10*scale) - + + band = function.cut_a_band_from_model(model_polydata, center_mv, center_rpv, center_lpv, 10 * scale) + ls_i_id = function.get_closest_point_id_from_polydata(model_polydata, ls_i) li_i_id = function.get_closest_point_id_from_polydata(model_polydata, li_i) rs_i_id = function.get_closest_point_id_from_polydata(model_polydata, rs_i) ri_i_id = function.get_closest_point_id_from_polydata(model_polydata, ri_i) - + lpv_path = function.dijkstra_path(model_polydata, ls_i_id, li_i_id) rpv_path = function.dijkstra_path(model_polydata, rs_i_id, ri_i_id) - - lpv_base_temp = function.multidim_intersect(vtk.util.numpy_support.vtk_to_numpy(band.GetPoints().GetData()), lpv_path) - rpv_base_temp = function.multidim_intersect(vtk.util.numpy_support.vtk_to_numpy(band.GetPoints().GetData()), rpv_path) - - lpv_base_fuzzy = np.asarray([np.mean(lpv_base_temp[:, 0]), np.mean(lpv_base_temp[:, 1]), np.mean(lpv_base_temp[:, 2])]) - rpv_base_fuzzy = np.asarray([np.mean(rpv_base_temp[:, 0]), np.mean(rpv_base_temp[:, 1]), np.mean(rpv_base_temp[:, 2])]) - + + lpv_base_temp = function.multidim_intersect(vtk.util.numpy_support.vtk_to_numpy(band.GetPoints().GetData()), + lpv_path) + rpv_base_temp = function.multidim_intersect(vtk.util.numpy_support.vtk_to_numpy(band.GetPoints().GetData()), + rpv_path) + + lpv_base_fuzzy = np.asarray( + [np.mean(lpv_base_temp[:, 0]), np.mean(lpv_base_temp[:, 1]), np.mean(lpv_base_temp[:, 2])]) + rpv_base_fuzzy = np.asarray( + [np.mean(rpv_base_temp[:, 0]), np.mean(rpv_base_temp[:, 1]), np.mean(rpv_base_temp[:, 2])]) + lpv_base_id = function.get_closest_point_id_from_polydata(band, lpv_base_fuzzy) rpv_base_id = function.get_closest_point_id_from_polydata(band, rpv_base_fuzzy) - + lpv_base = band.GetPoint(lpv_base_id) rpv_base = band.GetPoint(rpv_base_id) - + roof_path = function.dijkstra_path(band, lpv_base_id, rpv_base_id) - + length_roof = len(roof_path) roof_25 = roof_path[int(length_roof * 0.25)] roof_50 = roof_path[int(length_roof * 0.50)] roof_75 = roof_path[int(length_roof * 0.75)] - + septum_path = function.dijkstra_path(band, function.get_closest_point_id_from_polydata(band, mv_r), rpv_base_id) - + length_roof = len(septum_path) sep_25 = septum_path[int(length_roof * 0.25)] sep_50 = septum_path[int(length_roof * 0.50)] sep_75 = septum_path[int(length_roof * 0.75)] - + lateral_path = function.dijkstra_path(band, function.get_closest_point_id_from_polydata(band, mv_l), lpv_base_id) - + length_roof = len(lateral_path) lat_25 = lateral_path[int(length_roof * 0.25)] lat_50 = lateral_path[int(length_roof * 0.50)] lat_75 = lateral_path[int(length_roof * 0.75)] - - + ls_o_id = function.get_closest_point_id_from_polydata(model_polydata, ls_o) rs_o_id = function.get_closest_point_id_from_polydata(model_polydata, rs_o) sup_path = function.dijkstra_path(model_polydata, ls_o_id, rs_o_id) - + li_o_id = function.get_closest_point_id_from_polydata(model_polydata, li_o) ri_o_id = function.get_closest_point_id_from_polydata(model_polydata, ri_o) inf_path = function.dijkstra_path(model_polydata, li_o_id, ri_o_id) - + length_sup = len(sup_path) p1 = sup_path[int(length_sup * 0.5)] p1_25 = sup_path[int(length_sup * 0.25)] p1_75 = sup_path[int(length_sup * 0.75)] - + length_inf = len(inf_path) p2 = inf_path[int(length_inf * 0.5)] p2_25 = inf_path[int(length_inf * 0.25)] p2_75 = inf_path[int(length_inf * 0.75)] - + # p1_id = function.get_closest_point_id_from_polydata(model_polydata, p1) roof_50_id = function.get_closest_point_id_from_polydata(model_polydata, roof_50) p1_roof_path = function.dijkstra_path(model_polydata, roof_50_id, p1_id) - + p2_id = function.get_closest_point_id_from_polydata(model_polydata, p2) p2_roof_path = function.dijkstra_path(model_polydata, roof_50_id, p2_id) - + # mv_an_middle_id = function.get_closest_point_id_from_polydata(model_polydata, mv_an_middle) mv_po_middle_id = function.get_closest_point_id_from_polydata(model_polydata, mv_po_middle) - + p1_mv_path = function.dijkstra_path(model_polydata, p1_id, mv_an_middle_id) p2_mv_path = function.dijkstra_path(model_polydata, p2_id, mv_po_middle_id) - + length_p1_mv_path = len(p1_mv_path) - + p1_mv_25 = p1_mv_path[int(length_p1_mv_path * 0.25)] p1_mv_50 = p1_mv_path[int(length_p1_mv_path * 0.50)] p1_mv_75 = p1_mv_path[int(length_p1_mv_path * 0.75)] @@ -249,82 +252,98 @@ def get_landmarks(mesh, prealigned=1, scale=1): length_p2_mv_path = len(p2_mv_path) p2_mv_33 = p2_mv_path[int(length_p2_mv_path * 0.33)] p2_mv_66 = p2_mv_path[int(length_p2_mv_path * 0.66)] - - p1_mv_sep_50_path = function.dijkstra_path(model_polydata, function.get_closest_point_id_from_polydata(model_polydata, p1_mv_50), function.get_closest_point_id_from_polydata(model_polydata, sep_50)) - - p1_mv_sep_50 = p1_mv_sep_50_path[int(len(p1_mv_sep_50_path)*0.5)] - - p1_mv_sep_75_path = function.dijkstra_path(model_polydata, function.get_closest_point_id_from_polydata(model_polydata, p1_mv_75), function.get_closest_point_id_from_polydata(model_polydata, sep_25)) - - p1_mv_sep_75 = p1_mv_sep_75_path[int(len(p1_mv_sep_75_path)*0.5)] - - p2_mv_sep_50_path = function.dijkstra_path(model_polydata, function.get_closest_point_id_from_polydata(model_polydata, p2_mv_33), function.get_closest_point_id_from_polydata(model_polydata, sep_50)) - - p2_mv_sep_50 = p2_mv_sep_50_path[int(len(p2_mv_sep_50_path)*0.5)] - - p2_mv_sep_75_path = function.dijkstra_path(model_polydata, function.get_closest_point_id_from_polydata(model_polydata, p2_mv_66), function.get_closest_point_id_from_polydata(model_polydata, sep_25)) - - p2_mv_sep_75 = p2_mv_sep_75_path[int(len(p2_mv_sep_75_path)*0.5)] + + p1_mv_sep_50_path = function.dijkstra_path(model_polydata, + function.get_closest_point_id_from_polydata(model_polydata, p1_mv_50), + function.get_closest_point_id_from_polydata(model_polydata, sep_50)) + + p1_mv_sep_50 = p1_mv_sep_50_path[int(len(p1_mv_sep_50_path) * 0.5)] + + p1_mv_sep_75_path = function.dijkstra_path(model_polydata, + function.get_closest_point_id_from_polydata(model_polydata, p1_mv_75), + function.get_closest_point_id_from_polydata(model_polydata, sep_25)) + + p1_mv_sep_75 = p1_mv_sep_75_path[int(len(p1_mv_sep_75_path) * 0.5)] + + p2_mv_sep_50_path = function.dijkstra_path(model_polydata, + function.get_closest_point_id_from_polydata(model_polydata, p2_mv_33), + function.get_closest_point_id_from_polydata(model_polydata, sep_50)) + + p2_mv_sep_50 = p2_mv_sep_50_path[int(len(p2_mv_sep_50_path) * 0.5)] + + p2_mv_sep_75_path = function.dijkstra_path(model_polydata, + function.get_closest_point_id_from_polydata(model_polydata, p2_mv_66), + function.get_closest_point_id_from_polydata(model_polydata, sep_25)) + + p2_mv_sep_75 = p2_mv_sep_75_path[int(len(p2_mv_sep_75_path) * 0.5)] # Extra pts: - rspvo_p1_mv_50_path = function.dijkstra_path(model_polydata, function.get_closest_point_id_from_polydata(model_polydata, rs_o), function.get_closest_point_id_from_polydata(model_polydata, p1_mv_50)) - - rspvo_p1_mv_30 = rspvo_p1_mv_50_path[int(len(rspvo_p1_mv_50_path)*0.3)] + rspvo_p1_mv_50_path = function.dijkstra_path(model_polydata, + function.get_closest_point_id_from_polydata(model_polydata, rs_o), + function.get_closest_point_id_from_polydata(model_polydata, p1_mv_50)) + + rspvo_p1_mv_30 = rspvo_p1_mv_50_path[int(len(rspvo_p1_mv_50_path) * 0.3)] - rspvo_p1_mv_50 = rspvo_p1_mv_50_path[int(len(rspvo_p1_mv_50_path)*0.5)] + rspvo_p1_mv_50 = rspvo_p1_mv_50_path[int(len(rspvo_p1_mv_50_path) * 0.5)] - rspvo_p1_mv_70 = rspvo_p1_mv_50_path[int(len(rspvo_p1_mv_50_path)*0.7)] + rspvo_p1_mv_70 = rspvo_p1_mv_50_path[int(len(rspvo_p1_mv_50_path) * 0.7)] - rspvo_p1_mv_sep_50_path = function.dijkstra_path(model_polydata, function.get_closest_point_id_from_polydata(model_polydata, rs_o), function.get_closest_point_id_from_polydata(model_polydata, p1_mv_sep_50)) - - rspvo_p1_mv_sep_30 = rspvo_p1_mv_sep_50_path[int(len(rspvo_p1_mv_sep_50_path)*0.3)] + rspvo_p1_mv_sep_50_path = function.dijkstra_path(model_polydata, + function.get_closest_point_id_from_polydata(model_polydata, rs_o), + function.get_closest_point_id_from_polydata(model_polydata, + p1_mv_sep_50)) - rspvo_p1_mv_sep_50 = rspvo_p1_mv_sep_50_path[int(len(rspvo_p1_mv_sep_50_path)*0.5)] + rspvo_p1_mv_sep_30 = rspvo_p1_mv_sep_50_path[int(len(rspvo_p1_mv_sep_50_path) * 0.3)] - rspvo_p1_mv_sep_70 = rspvo_p1_mv_sep_50_path[int(len(rspvo_p1_mv_sep_50_path)*0.7)] + rspvo_p1_mv_sep_50 = rspvo_p1_mv_sep_50_path[int(len(rspvo_p1_mv_sep_50_path) * 0.5)] + + rspvo_p1_mv_sep_70 = rspvo_p1_mv_sep_50_path[int(len(rspvo_p1_mv_sep_50_path) * 0.7)] # write in json format - name_lst = ['lspv_o', 'lspv_i', 'lipv_i', 'lipv_o', 'rspv_o', 'rspv_i', 'ripv_i', 'ripv_o', - 'mv_l', 'mv_r','mv_an_middle', 'mv_po_middle', - 'lpv_base', 'roof_25', 'roof_50', 'roof_75','rpv_base', + name_lst = ['lspv_o', 'lspv_i', 'lipv_i', 'lipv_o', 'rspv_o', 'rspv_i', 'ripv_i', 'ripv_o', + 'mv_l', 'mv_r', 'mv_an_middle', 'mv_po_middle', + 'lpv_base', 'roof_25', 'roof_50', 'roof_75', 'rpv_base', 'lat_50', 'laa', 'sep_50', 'sep_25', - 'p1', 'p1_mv_50', + 'p1', 'p1_mv_50', 'p1_mv_sep_50', 'p1_mv_sep_75', 'p2_mv_sep_50', 'p2_mv_sep_75', - 'rspvo_p1_mv_30','rspvo_p1_mv_50','rspvo_p1_mv_70', 'rspvo_p1_mv_sep_30','rspvo_p1_mv_sep_50','rspvo_p1_mv_sep_70', + 'rspvo_p1_mv_30', 'rspvo_p1_mv_50', 'rspvo_p1_mv_70', 'rspvo_p1_mv_sep_30', 'rspvo_p1_mv_sep_50', + 'rspvo_p1_mv_sep_70', 'p2', 'p2_mv_33', 'p2_mv_66'] - + coord_lst = np.vstack((ls_o, ls_i, li_i, li_o, rs_o, rs_i, ri_i, ri_o, - mv_l, mv_r, mv_an_middle, mv_po_middle, - lpv_base, roof_25, roof_50, roof_75, rpv_base, - lat_50, - df["LAA"], - sep_50, sep_25, - p1, p1_mv_50, - p1_mv_sep_50, p1_mv_sep_75, p2_mv_sep_50, p2_mv_sep_75, - rspvo_p1_mv_30,rspvo_p1_mv_50,rspvo_p1_mv_70, rspvo_p1_mv_sep_30,rspvo_p1_mv_sep_50,rspvo_p1_mv_sep_70, - p2, p2_mv_33, p2_mv_66)) - + mv_l, mv_r, mv_an_middle, mv_po_middle, + lpv_base, roof_25, roof_50, roof_75, rpv_base, + lat_50, + df["LAA"], + sep_50, sep_25, + p1, p1_mv_50, + p1_mv_sep_50, p1_mv_sep_75, p2_mv_sep_50, p2_mv_sep_75, + rspvo_p1_mv_30, rspvo_p1_mv_50, rspvo_p1_mv_70, rspvo_p1_mv_sep_30, rspvo_p1_mv_sep_50, + rspvo_p1_mv_sep_70, + p2, p2_mv_33, p2_mv_66)) + json2 = '[' for i in range(len(name_lst)): json2 = json2 + "{\"id\":\"" + "{}".format(name_lst[i]) + "\",\"coordinates\":[" + "{},{},{}".format( coord_lst[i][0], coord_lst[i][1], coord_lst[i][2]) + "]}," json2 = json2[:-1] + ']' - + f = open("{}/landmarks.json".format(mesh_dir), "w") f.write(json2) f.close() - + # txt file to open in Paraview to check f = open("{}/landmarks.txt".format(mesh_dir), "w") for i in range(len(name_lst)): f.write("{} {} {} {}\n".format(coord_lst[i][0], coord_lst[i][1], coord_lst[i][2], name_lst[i])) + def run(): - args = parser().parse_args() get_landmarks(args.mesh, args.prealigned, args.scale) + if __name__ == '__main__': run() diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 64c793f..068c9cc 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -24,7 +24,7 @@ specific language governing permissions and limitations under the License. """ -import os,sys +import os, sys import numpy as np import pathlib from glob import glob @@ -42,6 +42,7 @@ from pymeshfix import _meshfix import pyvista as pv import collections + pv.set_plot_theme('dark') sys.path.append('../Atrial_LDRBM/Generate_Boundaries') @@ -49,13 +50,13 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + # def create_sphere(value): # radius = int(value) # sphere = pv.Sphere(center=center, radius=radius) # p.add_mesh(sphere, name='sphere', show_edges=True) # return def parser(): - parser = argparse.ArgumentParser(description='Cut veins manually') parser.add_argument('--mesh', type=str, @@ -99,8 +100,9 @@ def parser(): help='set to 1 if the input is an MRI segmentation') return parser -def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_radius=7.5, max_cutting_radius=17.5, LAA="", RAA="", debug=0): +def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_radius=7.5, max_cutting_radius=17.5, + LAA="", RAA="", debug=0): meshname = meshpath.split("/")[-1] full_path = meshpath[:-len(meshname)] @@ -109,26 +111,28 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ meshfix = pymeshfix.MeshFix(meshin) meshfix.repair() meshfix.mesh.save("{}/{}_clean.vtk".format(full_path, atrium)) - pv.save_meshio("{}/{}_clean.obj".format(full_path, atrium),meshfix.mesh, "obj") + pv.save_meshio("{}/{}_clean.obj".format(full_path, atrium), meshfix.mesh, "obj") mesh_with_data = smart_reader(meshpath) mesh_clean = smart_reader("{}/{}_clean.vtk".format(full_path, atrium)) - + # Map point data to cleaned mesh mesh = point_array_mapper(mesh_with_data, mesh_clean, "all") if atrium == "LA": - orifices = ['mitral valve', 'left inferior pulmonary vein', 'left superior pulmonary vein','right inferior pulmonary vein','right superior pulmonary vein'] + orifices = ['mitral valve', 'left inferior pulmonary vein', 'left superior pulmonary vein', + 'right inferior pulmonary vein', 'right superior pulmonary vein'] else: - orifices = ['tricuspid valve', 'inferior vena cava', 'superior vena cava','coronary sinus'] + orifices = ['tricuspid valve', 'inferior vena cava', 'superior vena cava', 'coronary sinus'] for r in orifices: picked_pt = None while picked_pt is None: p = pv.Plotter(notebook=False) - p.add_mesh(meshfix.mesh,'r') - p.add_text('Select the center of the {} and close the window to cut, otherwise just close'.format(r),position='lower_left') + p.add_mesh(meshfix.mesh, 'r') + p.add_text('Select the center of the {} and close the window to cut, otherwise just close'.format(r), + position='lower_left') p.enable_point_picking(meshfix.mesh, use_mesh=True) p.show() @@ -141,11 +145,11 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ model_new_el = vtk.vtkIdList() cell_id_all = list(range(mesh.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - + el_diff = list(set(cell_id_all).difference(el_to_del_tot)) + for var in el_diff: model_new_el.InsertNextId(var) - + extract = vtk.vtkExtractCells() extract.SetInputData(mesh) extract.SetCellList(model_new_el) @@ -154,7 +158,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(extract.GetOutputPort()) geo_filter.Update() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(geo_filter.GetOutputPort()) cleaner.Update() @@ -167,7 +171,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ writer.SetFileName("{}/{}_cutted.vtk".format(full_path, atrium)) writer.SetInputData(model) writer.Write() - + p = pv.Plotter(notebook=False) mesh_from_vtk = pv.PolyData("{}/{}_cutted.vtk".format(full_path, atrium)) p.add_mesh(mesh_from_vtk, 'r') @@ -191,18 +195,19 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ RAA = apex_id meshpath = "{}/{}_cutted".format(full_path, atrium) - extract_rings.run(["--mesh",meshpath,"--LAA",str(LAA),"--RAA",str(RAA)]) + extract_rings.run(["--mesh", meshpath, "--LAA", str(LAA), "--RAA", str(RAA)]) return apex_id -def run(): +def run(): args = parser().parse_args() - - apex_id = open_orifices_manually(args.mesh, args.atrium, args.MRI, args.scale, args.size, args.min_cutting_radius, args.max_cutting_radius, args.LAA, args.RAA, args.debug) - -def smart_reader(path): + apex_id = open_orifices_manually(args.mesh, args.atrium, args.MRI, args.scale, args.size, args.min_cutting_radius, + args.max_cutting_radius, args.LAA, args.RAA, args.debug) + + +def smart_reader(path): extension = str(path).split(".")[-1] if extension == "vtk": @@ -230,31 +235,33 @@ def smart_reader(path): return output -def vtk_thr(model,mode,points_cells,array,thr1,thr2="None"): + +def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thresh = vtk.vtkThreshold() thresh.SetInputData(model) if mode == 0: thresh.ThresholdByUpper(thr1) elif mode == 1: thresh.ThresholdByLower(thr1) - elif mode ==2: + elif mode == 2: if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1,thr2) + thresh.ThresholdBetween(thr1, thr2) else: thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() thr = thresh.GetOutput() thresh = vtk.vtkThreshold() thresh.SetInputData(thr) thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() - + output = thresh.GetOutput() - + return output + def find_elements_within_radius(mesh, points_data, radius): locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -276,6 +283,7 @@ def find_elements_within_radius(mesh, points_data, radius): return id_set + def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) @@ -295,39 +303,41 @@ def extract_largest_region(mesh): return res + def point_array_mapper(mesh1, mesh2, idat): - pts1 = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPoints().GetData()) pts2 = vtk.util.numpy_support.vtk_to_numpy(mesh2.GetPoints().GetData()) - + tree = cKDTree(pts1) dd, ii = tree.query(pts2, n_jobs=-1) - + meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) + data = vtk.util.numpy_support.vtk_to_numpy( + mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] data2 = np.where(np.isnan(data2), 10000, data2) - + meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] meshNew.PointData.append(data2, idat) - + return meshNew.VTKObject + if __name__ == '__main__': run() diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 5b936a3..b7a2ed0 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -24,7 +24,7 @@ specific language governing permissions and limitations under the License. """ -import os,sys +import os, sys import numpy as np import pathlib from glob import glob @@ -42,6 +42,7 @@ from pymeshfix import _meshfix import pyvista as pv import collections + pv.set_plot_theme('dark') sys.path.append('./Atrial_LDRBM/Generate_Boundaries') @@ -49,8 +50,8 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] -def parser(): +def parser(): parser = argparse.ArgumentParser(description='Cut veins detected as high curvature areas') parser.add_argument('--mesh', type=str, @@ -95,8 +96,9 @@ def parser(): return parser -def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cutting_radius=7.5, max_cutting_radius=17.5, LAA="", RAA="", debug=0): +def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cutting_radius=7.5, + max_cutting_radius=17.5, LAA="", RAA="", debug=0): meshname = meshpath.split("/")[-1] full_path = meshpath[:-len(meshname)] @@ -105,22 +107,22 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu meshfix = pymeshfix.MeshFix(meshin) meshfix.repair() meshfix.mesh.save("{}/{}_clean.vtk".format(full_path, atrium)) - pv.save_meshio("{}/{}_clean.obj".format(full_path, atrium),meshfix.mesh, "obj") + pv.save_meshio("{}/{}_clean.obj".format(full_path, atrium), meshfix.mesh, "obj") # Compute surface curvature - os.system("meshtool query curvature -msh={}/{}_clean.obj -size={}".format(full_path, atrium, size*scale)) + os.system("meshtool query curvature -msh={}/{}_clean.obj -size={}".format(full_path, atrium, size * scale)) # Verify if the mesh curvature is not nan mesh_with_data = smart_reader(meshpath) - + curv = np.loadtxt('{}/{}_clean.curv.dat'.format(full_path, atrium)) mesh_clean = smart_reader("{}/{}_clean.vtk".format(full_path, atrium)) - + # Map point data to cleaned mesh mesh = point_array_mapper(mesh_with_data, mesh_clean, "all") - + model = dsa.WrapDataObject(mesh) model.PointData.append(curv, "curv") @@ -136,7 +138,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu apex = None if not MRI: - valve = vtk_thr(model,0,"POINTS","valve",0.5) + valve = vtk_thr(model, 0, "POINTS", "valve", 0.5) valve = extract_largest_region(valve) centerOfMassFilter = vtk.vtkCenterOfMass() @@ -149,20 +151,20 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve_pts = vtk.util.numpy_support.vtk_to_numpy(valve.GetPoints().GetData()) max_dist = 0 for l in range(len(valve_pts)): - if np.sqrt(np.sum((valve_center-valve_pts[l])**2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((valve_center-valve_pts[l])**2, axis=0)) - - if max_dist > max_cutting_radius*2: - print("Valve bigger than {} cm".format(max_cutting_radius*2)) - el_to_del_tot = find_elements_within_radius(model,valve_center,max_cutting_radius) + if np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) > max_dist: + max_dist = np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) + + if max_dist > max_cutting_radius * 2: + print("Valve bigger than {} cm".format(max_cutting_radius * 2)) + el_to_del_tot = find_elements_within_radius(model, valve_center, max_cutting_radius) model_new_el = vtk.vtkIdList() cell_id_all = list(range(model.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - + el_diff = list(set(cell_id_all).difference(el_to_del_tot)) + for var in el_diff: model_new_el.InsertNextId(var) - + extract = vtk.vtkExtractCells() extract.SetInputData(model) extract.SetCellList(model_new_el) @@ -171,7 +173,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(extract.GetOutputPort()) geo_filter.Update() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(geo_filter.GetOutputPort()) cleaner.Update() @@ -179,10 +181,10 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model = cleaner.GetOutput() else: - valve = vtk_thr(model,0,"POINTS","curv",0.05) + valve = vtk_thr(model, 0, "POINTS", "curv", 0.05) valve = extract_largest_region(valve) - if debug and atrium =='RA': + if debug and atrium == 'RA': writer_vtk(valve, "{}/{}_clean_with_curv_".format(full_path, atrium) + "valve.vtk") centerOfMassFilter = vtk.vtkCenterOfMass() @@ -195,19 +197,19 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve_pts = vtk.util.numpy_support.vtk_to_numpy(valve.GetPoints().GetData()) max_dist = 0 for l in range(len(valve_pts)): - if np.sqrt(np.sum((valve_center-valve_pts[l])**2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((valve_center-valve_pts[l])**2, axis=0)) - + if np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) > max_dist: + max_dist = np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) + # Cutting valve with fixed radius to ensure that it is the biggest ring - el_to_del_tot = find_elements_within_radius(model,valve_center,max_cutting_radius) + el_to_del_tot = find_elements_within_radius(model, valve_center, max_cutting_radius) model_new_el = vtk.vtkIdList() cell_id_all = list(range(model.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - + el_diff = list(set(cell_id_all).difference(el_to_del_tot)) + for var in el_diff: model_new_el.InsertNextId(var) - + extract = vtk.vtkExtractCells() extract.SetInputData(model) extract.SetCellList(model_new_el) @@ -216,7 +218,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(extract.GetOutputPort()) geo_filter.Update() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(geo_filter.GetOutputPort()) cleaner.Update() @@ -226,7 +228,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu # model = smart_reader("{}/{}_valve.vtk".format(full_path, atrium)) cellid = vtk.vtkIdFilter() cellid.CellIdsOn() - cellid.SetInputData(model) + cellid.SetInputData(model) cellid.PointIdsOn() if int(vtk_version) >= 9: cellid.SetPointIdsArrayName('Ids') @@ -234,9 +236,9 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu else: cellid.SetIdsArrayName('Ids') cellid.Update() - + model = cellid.GetOutput() - + writer = vtk.vtkPolyDataWriter() writer.SetFileName("{}/{}_curv.vtk".format(full_path, atrium)) writer.SetInputData(model) @@ -244,18 +246,18 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu writer.Write() curv = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('curv')) - + Gl_pt_id = list(vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('Ids'))) Gl_cell_id = list(vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('Ids'))) - + if not MRI: - low_v = vtk_thr(model,1,"POINTS","bi",0.5) + low_v = vtk_thr(model, 1, "POINTS", "bi", 0.5) pts_low_v = set(list(vtk.util.numpy_support.vtk_to_numpy(low_v.GetPointData().GetArray('Ids')))) - high_v = vtk_thr(model,0,"POINTS","bi",0.5001) + high_v = vtk_thr(model, 0, "POINTS", "bi", 0.5001) - high_c = vtk_thr(model,0,"POINTS","curv",np.median(curv)*1.15)#(np.min(curv)+np.max(curv))/2) + high_c = vtk_thr(model, 0, "POINTS", "curv", np.median(curv) * 1.15) # (np.min(curv)+np.max(curv))/2) writer = vtk.vtkUnstructuredGridWriter() writer.SetFileName("{}/{}_h_curv.vtk".format(full_path, atrium)) @@ -268,21 +270,21 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu connect.SetExtractionModeToAllRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(high_c) connect.SetExtractionModeToSpecifiedRegions() - + rings = [] - + el_to_del_tot = set() old_max = 0 - if MRI: + if MRI: cc = pv.PolyData(valve_center) p = pv.Plotter(notebook=False) p.add_mesh(meshfix.mesh, 'r') - p.add_text('Select the appendage apex and close the window',position='lower_left') + p.add_text('Select the appendage apex and close the window', position='lower_left') p.add_mesh(cc, color='w', point_size=30., render_points_as_spheres=True) p.enable_point_picking(meshfix.mesh, use_mesh=True) @@ -304,7 +306,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p = pv.Plotter(notebook=False) mesh_from_vtk = pv.PolyData("{}/{}_clean.vtk".format(full_path, atrium)) p.add_mesh(mesh_from_vtk, 'r') - p.add_text('Select the transeptal punture and close the window',position='lower_left') + p.add_text('Select the transeptal punture and close the window', position='lower_left') p.enable_point_picking(meshfix.mesh, use_mesh=True) p.show() @@ -313,31 +315,32 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu loc = vtk.vtkPointLocator() loc.SetDataSet(model) loc.BuildLocator() - transeptal_punture_id = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('Ids'))[loc.FindClosestPoint(p.picked_point)] + transeptal_punture_id = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('Ids'))[ + loc.FindClosestPoint(p.picked_point)] p.close() for i in range(num): connect.AddSpecifiedRegion(i) connect.Update() surface = connect.GetOutput() - + # Clean unused points geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(surface) geo_filter.Update() surface = geo_filter.GetOutput() - + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() surface = cln.GetOutput() - + pt_high_c = list(vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray('Ids'))) curv_s = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray('curv')) - + if not MRI: if transeptal_punture_id not in pt_high_c: - if len(set(pt_high_c).intersection(pts_low_v))>0: # the region is both high curvature and low voltage + if len(set(pt_high_c).intersection(pts_low_v)) > 0: # the region is both high curvature and low voltage pt_max_curv = np.asarray(model.GetPoint(Gl_pt_id.index(pt_high_c[np.argmax(curv_s)]))) el_low_vol = set() connect2 = vtk.vtkConnectivityFilter() @@ -345,14 +348,14 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu connect2.SetExtractionModeToAllRegions() connect2.Update() num2 = connect2.GetNumberOfExtractedRegions() - + connect2.SetExtractionModeToSpecifiedRegions() - + for ii in range(num2): connect2.AddSpecifiedRegion(ii) connect2.Update() surface2 = connect2.GetOutput() - + # Clean unused points geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(surface2) @@ -364,7 +367,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu cln.Update() surface2 = cln.GetOutput() pt_surf_2 = list(vtk.util.numpy_support.vtk_to_numpy(surface2.GetPointData().GetArray('Ids'))) - if len(set(pt_high_c).intersection(pt_surf_2))>0: + if len(set(pt_high_c).intersection(pt_surf_2)) > 0: for el in vtk.util.numpy_support.vtk_to_numpy(surface2.GetCellData().GetArray('Ids')): el_low_vol.add(Gl_cell_id.index(el)) @@ -373,10 +376,10 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu connect2.Update() model_new_el = vtk.vtkIdList() - + for var in el_low_vol: model_new_el.InsertNextId(var) - + extract = vtk.vtkExtractCells() extract.SetInputData(model) extract.SetCellList(model_new_el) @@ -385,30 +388,30 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(extract.GetOutputPort()) geo_filter.Update() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(geo_filter.GetOutputPort()) cleaner.Update() loc_low_V = cleaner.GetOutput() # local low voltage area - + loc_low_V = extract_largest_region(loc_low_V) - + loc_low_V_pts = vtk.util.numpy_support.vtk_to_numpy(loc_low_V.GetPoints().GetData()) max_dist = 0 for l in range(len(loc_low_V_pts)): - if np.sqrt(np.sum((pt_max_curv-loc_low_V_pts[l])**2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((pt_max_curv-loc_low_V_pts[l])**2, axis=0)) + if np.sqrt(np.sum((pt_max_curv - loc_low_V_pts[l]) ** 2, axis=0)) > max_dist: + max_dist = np.sqrt(np.sum((pt_max_curv - loc_low_V_pts[l]) ** 2, axis=0)) - el_to_del = find_elements_within_radius(model,pt_max_curv,min_cutting_radius*2*scale) + el_to_del = find_elements_within_radius(model, pt_max_curv, min_cutting_radius * 2 * scale) el_to_del_tot = el_to_del_tot.union(set(el_to_del)) - - - else: # Possible appendage - if np.max(curv_s) > old_max: # The max curvature without low voltage should be the appendage + + else: # Possible appendage + + if np.max(curv_s) > old_max: # The max curvature without low voltage should be the appendage old_max = np.max(curv_s) apex = np.asarray(model.GetPoint(Gl_pt_id.index(pt_high_c[np.argmax(curv_s)]))) else: @@ -421,11 +424,11 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model_new_el = vtk.vtkIdList() cell_id_all = list(range(model.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - + el_diff = list(set(cell_id_all).difference(el_to_del_tot)) + for var in el_diff: model_new_el.InsertNextId(var) - + extract = vtk.vtkExtractCells() extract.SetInputData(model) extract.SetCellList(model_new_el) @@ -434,20 +437,20 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(extract.GetOutputPort()) geo_filter.Update() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(geo_filter.GetOutputPort()) cleaner.Update() model = cleaner.GetOutput() - + model = extract_largest_region(model) writer = vtk.vtkPolyDataWriter() writer.SetFileName("{}/{}_cutted.vtk".format(full_path, atrium)) writer.SetInputData(model) writer.Write() - + if debug: if apex is not None: point_cloud = pv.PolyData(apex) @@ -457,7 +460,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p.add_mesh(mesh_from_vtk, 'r') p.add_mesh(point_cloud, color='w', point_size=30., render_points_as_spheres=True) p.enable_point_picking(meshfix.mesh, use_mesh=True) - p.add_text('Select the appendage apex and close the window',position='lower_left') + p.add_text('Select the appendage apex and close the window', position='lower_left') p.show() if p.picked_point is not None: @@ -468,7 +471,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu mesh_from_vtk = pv.PolyData("{}/{}_cutted.vtk".format(full_path, atrium)) p.add_mesh(mesh_from_vtk, 'r') p.enable_point_picking(meshfix.mesh, use_mesh=True) - p.add_text('Select the appendage apex and close the window',position='lower_left') + p.add_text('Select the appendage apex and close the window', position='lower_left') p.show() if p.picked_point is not None: @@ -484,19 +487,21 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu LAA = apex_id elif atrium == "RA": RAA = apex_id - - label_atrial_orifices("{}/{}_cutted.vtk".format(full_path, atrium),LAA,RAA) + + label_atrial_orifices("{}/{}_cutted.vtk".format(full_path, atrium), LAA, RAA) return apex_id -def run(): +def run(): args = parser().parse_args() - apex_id = open_orifices_with_curvature(args.mesh, args.atrium, args.MRI, args.scale, args.size, args.min_cutting_radius, args.max_cutting_radius, args.LAA, args.RAA, args.debug) - -def smart_reader(path): + apex_id = open_orifices_with_curvature(args.mesh, args.atrium, args.MRI, args.scale, args.size, + args.min_cutting_radius, args.max_cutting_radius, args.LAA, args.RAA, + args.debug) + +def smart_reader(path): extension = str(path).split(".")[-1] if extension == "vtk": @@ -524,31 +529,33 @@ def smart_reader(path): return output -def vtk_thr(model,mode,points_cells,array,thr1,thr2="None"): + +def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thresh = vtk.vtkThreshold() thresh.SetInputData(model) if mode == 0: thresh.ThresholdByUpper(thr1) elif mode == 1: thresh.ThresholdByLower(thr1) - elif mode ==2: + elif mode == 2: if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1,thr2) + thresh.ThresholdBetween(thr1, thr2) else: thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() thr = thresh.GetOutput() thresh = vtk.vtkThreshold() thresh.SetInputData(thr) thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() - + output = thresh.GetOutput() - + return output + def find_elements_within_radius(mesh, points_data, radius): locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -570,6 +577,7 @@ def find_elements_within_radius(mesh, points_data, radius): return id_set + def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) @@ -589,47 +597,50 @@ def extract_largest_region(mesh): return res + def point_array_mapper(mesh1, mesh2, idat): - pts1 = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPoints().GetData()) pts2 = vtk.util.numpy_support.vtk_to_numpy(mesh2.GetPoints().GetData()) - + tree = cKDTree(pts1) dd, ii = tree.query(pts2, n_jobs=-1) - + meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) + data = vtk.util.numpy_support.vtk_to_numpy( + mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] data2 = np.where(np.isnan(data2), 10000, data2) - + meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) if isinstance(data[0], collections.Sized): - data2 = np.zeros((len(pts2),len(data[0])), dtype=data.dtype) + data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) - + data2 = data[ii] meshNew.PointData.append(data2, idat) - + return meshNew.VTKObject -def create_pts(array_points,array_name,mesh_dir): - f = open("{}{}.pts".format(mesh_dir,array_name), "w") + +def create_pts(array_points, array_name, mesh_dir): + f = open("{}{}.pts".format(mesh_dir, array_name), "w") f.write("0 0 0\n") for i in range(len(array_points)): f.write("{} {} {}\n".format(array_points[i][0], array_points[i][1], array_points[i][2])) f.close() + def to_polydata(mesh): geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(mesh) @@ -637,11 +648,13 @@ def to_polydata(mesh): polydata = geo_filter.GetOutput() return polydata -def writer_vtk(mesh,filename): + +def writer_vtk(mesh, filename): writer = vtk.vtkPolyDataWriter() writer.SetFileName(filename) writer.SetInputData(to_polydata(mesh)) writer.Write() + if __name__ == '__main__': run() diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index 7f61988..8c9c87b 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -36,6 +36,7 @@ import argparse + def parser(): parser = argparse.ArgumentParser(description='Prealign meshes using landmarks.') parser.add_argument('--mesh1', @@ -57,8 +58,8 @@ def parser(): return parser -def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): +def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): # Landmarks to use to prealign both meshes if case == "both": names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV", "TV", "SVC", "IVC"] @@ -75,63 +76,66 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): mesh1 = extract_surf.GetOutput() elif case == "LA": - names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV"] # Prealign MRI + names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV"] # Prealign MRI mesh1 = vtkreader("{}_surf/LA_boundaries_tagged".format(mesh1_name)) else: names = ["TV", "SVC", "IVC"] mesh1 = vtkreader("{}_surf/RA_boundaries_tagged".format(mesh1_name)) - + df_tot = pd.read_csv("{}_surf/rings_centroids.csv".format(mesh1_name)) A_tot = df_tot.to_numpy() df1 = pd.read_csv("{}_surf/rings_centroids.csv".format(mesh1_name), usecols=names) df2 = pd.read_csv("{}_surf/rings_centroids.csv".format(mesh2_name), usecols=names) df2 = df2[df1.columns] - + A = df1.to_numpy() B = df2.to_numpy() - + if scale: - M=tf.transformations.superimposition_matrix(A, B, scale=True, usesvd=True) + M = tf.transformations.superimposition_matrix(A, B, scale=True, usesvd=True) else: - M=tf.transformations.superimposition_matrix(A, B, scale=False, usesvd=True) - ret_R = M[:3,:3] - ret_t = M[:3,3].reshape(3,1) - - new_pts = (ret_R@A) + ret_t - new_centroids = (ret_R@A_tot) + ret_t + M = tf.transformations.superimposition_matrix(A, B, scale=False, usesvd=True) + ret_R = M[:3, :3] + ret_t = M[:3, 3].reshape(3, 1) + + new_pts = (ret_R @ A) + ret_t + new_centroids = (ret_R @ A_tot) + ret_t # Write the prealigned landmarks as .json files df_new = pd.DataFrame(data=new_pts, columns=df1.columns) df_new_tot = pd.DataFrame(data=new_centroids, columns=df_tot.columns) - + df_new_tot.to_csv("{}_surf/rings_centroids_prealigned.csv".format(mesh1_name), index=False) json1 = '[' json2 = '[' for i in df_new.columns: - json1 = json1 + "{\"id\":\""+"{}".format(i)+"\",\"coordinates\":["+"{},{},{}".format(df_new[i][0],df_new[i][1],df_new[i][2])+"]}," + json1 = json1 + "{\"id\":\"" + "{}".format(i) + "\",\"coordinates\":[" + "{},{},{}".format(df_new[i][0], + df_new[i][1], + df_new[i][2]) + "]}," json1 = json1[:-1] + ']' for i in df2.columns: - json2 = json2 + "{\"id\":\""+"{}".format(i)+"\",\"coordinates\":["+"{},{},{}".format(df2[i][0],df2[i][1],df2[i][2])+"]}," + json2 = json2 + "{\"id\":\"" + "{}".format(i) + "\",\"coordinates\":[" + "{},{},{}".format(df2[i][0], df2[i][1], + df2[i][2]) + "]}," json2 = json2[:-1] + ']' - + f = open("{}_surf/prealigned_landmarks.json".format(mesh1_name), "w") f.write(json1) f.close() f = open("{}_surf/landmarks_to_prealign.json".format(mesh2_name), "w") f.write(json2) f.close() - - M_l=list(M.flatten()) + + M_l = list(M.flatten()) transformFilter = vtk.vtkTransform() transformFilter.SetMatrix(M_l) - + transform_poly = vtk.vtkTransformPolyDataFilter() transform_poly.SetInputData(mesh1) transform_poly.SetTransform(transformFilter) transform_poly.Update() - + writer = vtk.vtkSTLWriter() writer.SetInputConnection(transform_poly.GetOutputPort()) if case == "both": @@ -153,14 +157,14 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): writer.SetInputData(meshNew.VTKObject) writer.Write() + def run(): - args = parser().parse_args() prealign_meshes(args.mesh1, args.mesh2, args.case, args.scale) -def vtkreader(meshname): +def vtkreader(meshname): reader = vtk.vtkPolyDataReader() reader.SetFileName('{}.vtk'.format(meshname)) @@ -169,9 +173,10 @@ def vtkreader(meshname): geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(reader.GetOutputPort()) geo_filter.Update() - + polydata = geo_filter.GetOutput() return polydata + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 28484ca..fd38ff6 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -34,11 +34,12 @@ import os import numpy as np import pandas as pd + pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] -def parser(): +def parser(): parser = argparse.ArgumentParser(description='Generate boundaries.') parser.add_argument('--mesh', type=str, @@ -63,6 +64,7 @@ def parser(): return parser + def find_elements_around_path_within_radius(mesh, points_data, radius): locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -88,26 +90,26 @@ def find_elements_around_path_within_radius(mesh, points_data, radius): return id_set -def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv=0, scale=1, size=30, apex_id=-1, atrium='LA'): +def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv=0, scale=1, size=30, apex_id=-1, + atrium='LA'): mesh_data = dict() ms = pymeshlab.MeshSet() ms.load_new_mesh('{}.obj'.format(meshname)) - #ms.apply_filter('turn_into_a_pure_triangular_mesh') # if polygonal mesh - #ms.save_current_mesh('{}.obj'.format(meshname)) + # ms.apply_filter('turn_into_a_pure_triangular_mesh') # if polygonal mesh + # ms.save_current_mesh('{}.obj'.format(meshname)) ms.select_self_intersecting_faces() m = ms.current_mesh() - if apex_id>-1: - apex = m.vertex_matrix()[apex_id,:] + if apex_id > -1: + apex = m.vertex_matrix()[apex_id, :] self_intersecting_faces = m.selected_face_number() - if self_intersecting_faces: reader = vtk.vtkOBJReader() reader.SetFileName('{}.obj'.format(meshname)) @@ -125,11 +127,11 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv # Clean the mesh from holes and self intersecting triangles meshin = pv.read('{}.obj'.format(meshname)) - meshfix = pymeshfix.MeshFix(meshin) # Be careful with biatrial geometries as it might delete one chamber + meshfix = pymeshfix.MeshFix(meshin) # Be careful with biatrial geometries as it might delete one chamber meshfix.repair() vol = meshfix.mesh.volume - - pv.save_meshio('{}_meshfix.obj'.format(meshname),meshfix.mesh, "obj") + + pv.save_meshio('{}_meshfix.obj'.format(meshname), meshfix.mesh, "obj") reader = vtk.vtkOBJReader() reader.SetFileName('{}_meshfix.obj'.format(meshname)) @@ -137,12 +139,12 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv Mass = vtk.vtkMassProperties() Mass.SetInputData(reader.GetOutput()) - Mass.Update() + Mass.Update() print("Volume = ", Mass.GetVolume()) print("Surface = ", Mass.GetSurfaceArea()) - bd_ids = find_elements_around_path_within_radius(reader.GetOutput(), boundary_pts, 0.5*scale) + bd_ids = find_elements_around_path_within_radius(reader.GetOutput(), boundary_pts, 0.5 * scale) tot_cells = set(list(range(reader.GetOutput().GetNumberOfCells()))) cells_no_bd = tot_cells - bd_ids @@ -153,12 +155,12 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv extract.SetInputData(reader.GetOutput()) extract.SetCellList(cell_ids_no_bd) extract.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(extract.GetOutput()) geo_filter.Update() earth = geo_filter.GetOutput() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(earth) cleaner.Update() @@ -177,7 +179,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv writer.SetFileName('{}_cleaned.obj'.format(meshname)) writer.Write() - mesh_data["vol"]=[vol] + mesh_data["vol"] = [vol] ms = pymeshlab.MeshSet() @@ -189,7 +191,6 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv ms.load_new_mesh('{}.obj'.format(meshname)) - # compute the geometric measures of the current mesh # and save the results in the out_dict dictionary out_dict = ms.compute_geometric_measures() @@ -197,59 +198,59 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv # get the average edge length from the dictionary avg_edge_length = out_dict['avg_edge_length'] - tgt_edge_length = target_mesh_resolution*scale + tgt_edge_length = target_mesh_resolution * scale - loc_tgt_edge_length = target_mesh_resolution*scale + loc_tgt_edge_length = target_mesh_resolution * scale it = 1 - print("Current resolution: {} mm".format(avg_edge_length/scale)) - print("Target resolution: {} mm".format(tgt_edge_length/scale)) - while avg_edge_length > tgt_edge_length*1.05 or avg_edge_length < tgt_edge_length*0.95 or it < 3 : - + print("Current resolution: {} mm".format(avg_edge_length / scale)) + print("Target resolution: {} mm".format(tgt_edge_length / scale)) + while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: + ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=loc_tgt_edge_length) if it == 1: ms.laplacian_smooth() out_dict = ms.compute_geometric_measures() avg_edge_length = out_dict['avg_edge_length'] - print("Current resolution: {} mm".format(avg_edge_length/scale)) - if avg_edge_length > tgt_edge_length*1.05: - loc_tgt_edge_length = tgt_edge_length*0.95 - print("New target resolution: {} mm".format(loc_tgt_edge_length/scale)) - elif avg_edge_length < tgt_edge_length*0.95: - loc_tgt_edge_length = tgt_edge_length*1.05 - print("New target resolution: {} mm".format(loc_tgt_edge_length/scale)) + print("Current resolution: {} mm".format(avg_edge_length / scale)) + if avg_edge_length > tgt_edge_length * 1.05: + loc_tgt_edge_length = tgt_edge_length * 0.95 + print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) + elif avg_edge_length < tgt_edge_length * 0.95: + loc_tgt_edge_length = tgt_edge_length * 1.05 + print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) else: break it += 1 - mesh_data["avg_edge_length"] = [out_dict['avg_edge_length']] - mesh_data["surf"]=[out_dict['surface_area']] + mesh_data["surf"] = [out_dict['surface_area']] # Better to save as .ply - ms.save_current_mesh('{}_res.ply'.format(meshname), save_vertex_color=False, save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) + ms.save_current_mesh('{}_res.ply'.format(meshname), save_vertex_color=False, save_vertex_normal=False, + save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) meshin = pv.read('{}_res.ply'.format(meshname)) - if find_apex_with_curv and apex_id==-1: + if find_apex_with_curv and apex_id == -1: if self_intersecting_faces: - os.system("meshtool query curvature -msh={}_cleaned.obj -size={}".format(meshname, size*scale)) + os.system("meshtool query curvature -msh={}_cleaned.obj -size={}".format(meshname, size * scale)) curv = np.loadtxt('{}_cleaned.curv.dat'.format(meshname)) mesh_curv = pv.read('{}_cleaned.obj'.format(meshname)) else: - os.system("meshtool query curvature -msh={}.obj -size={}".format(meshname, size*scale)) + os.system("meshtool query curvature -msh={}.obj -size={}".format(meshname, size * scale)) curv = np.loadtxt('{}.curv.dat'.format(meshname)) mesh_curv = pv.read('{}.obj'.format(meshname)) - apex = mesh_curv.points[np.argmax(curv),:] + apex = mesh_curv.points[np.argmax(curv), :] point_cloud = pv.PolyData(apex) p = pv.Plotter(notebook=False) - p.add_mesh(meshin,color='r') - p.add_mesh(point_cloud, color='w', point_size=30.*scale, render_points_as_spheres=True) + p.add_mesh(meshin, color='r') + p.add_mesh(point_cloud, color='w', point_size=30. * scale, render_points_as_spheres=True) p.enable_point_picking(meshin, use_mesh=True) - p.add_text('Select the appendage apex and close the window',position='lower_left') + p.add_text('Select the appendage apex and close the window', position='lower_left') p.show() @@ -257,30 +258,30 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv print("Please pick a point as apex") else: apex = p.picked_point - print("Apex coordinates: ",apex) + print("Apex coordinates: ", apex) - elif find_apex_with_curv==0 and apex_id==-1: + elif find_apex_with_curv == 0 and apex_id == -1: p = pv.Plotter(notebook=False) - p.add_mesh(meshin,color='r') + p.add_mesh(meshin, color='r') p.enable_point_picking(meshin, use_mesh=True) - p.add_text('Select the appendage apex and close the window',position='lower_left') # Select the LAA first + p.add_text('Select the appendage apex and close the window', position='lower_left') # Select the LAA first p.show() if p.picked_point is None: print("Please pick a point as apex") else: apex = p.picked_point - print("Apex coordinates: ",apex) + print("Apex coordinates: ", apex) tree = cKDTree(meshin.points.astype(np.double)) dist, apex_id = tree.query(apex) if atrium == 'LA_RA': - mesh_data["LAA_id"] = [apex_id] # change accordingly + mesh_data["LAA_id"] = [apex_id] # change accordingly else: - mesh_data["{}A_id".format(atrium)] = [apex_id] # change accordingly + mesh_data["{}A_id".format(atrium)] = [apex_id] # change accordingly if atrium == 'LA_RA': atrium = 'RA' @@ -312,18 +313,17 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv print("Volume = ", Mass.GetVolume()) print("Surface = ", Mass.GetSurfaceArea()) - mesh_data["vol_bi"] = Mass.GetVolume() # Biatrial volume - - + mesh_data["vol_bi"] = Mass.GetVolume() # Biatrial volume fname = '{}_res_mesh_data.csv'.format(meshname) df = pd.DataFrame(mesh_data) df.to_csv(fname, float_format="%.2f", index=False) -def run(): +def run(): args = parser().parse_args() resample_surf_mesh(args.mesh, target_mesh_resolution, find_apex_with_curv, scale, size) + if __name__ == '__main__': - run() \ No newline at end of file + run() diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 6e96ead..bd847f0 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -35,10 +35,10 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] -def low_vol_LAT(args, path): +def low_vol_LAT(args, path): # Read mesh - meshname = '{}_fibers/result_LA/LA_bilayer_with_fiber_with_data_um'.format(args.mesh) # in um + meshname = '{}_fibers/result_LA/LA_bilayer_with_fiber_with_data_um'.format(args.mesh) # in um model = smart_reader('{}.vtk'.format(meshname)) bilayer_n_cells = model.GetNumberOfCells() @@ -69,15 +69,15 @@ def low_vol_LAT(args, path): cellid.Update() model = cellid.GetOutput() - + # Compute elements centroids filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(model) filter_cell_centers.Update() centroids = vtk.util.numpy_support.vtk_to_numpy(filter_cell_centers.GetOutput().GetPoints().GetData()) - + # Low voltage in the model - low_vol = vtk_thr(model,1,"CELLS","bi",args.low_vol_thr) + low_vol = vtk_thr(model, 1, "CELLS", "bi", args.low_vol_thr) low_vol_ids = vtk.util.numpy_support.vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) if args.debug: @@ -100,9 +100,9 @@ def low_vol_LAT(args, path): geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) - geo_filter.Update() + geo_filter.Update() - endo = vtk_thr(geo_filter.GetOutput(),1,"CELLS","elemTag",10) + endo = vtk_thr(geo_filter.GetOutput(), 1, "CELLS", "elemTag", 10) if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() @@ -119,10 +119,11 @@ def low_vol_LAT(args, path): LAT_map = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('lat')) # Extract "healthy" high voltage endocardium - not_low_volt_endo = vtk_thr(endo,0,"POINTS","bi", 0.5+0.01) + not_low_volt_endo = vtk_thr(endo, 0, "POINTS", "bi", 0.5 + 0.01) LAT_not_low_volt = vtk.util.numpy_support.vtk_to_numpy(not_low_volt_endo.GetPointData().GetArray('lat')) not_low_volt_endo_pts = vtk.util.numpy_support.vtk_to_numpy(not_low_volt_endo.GetPoints().GetData()) - not_low_volt_ids = vtk.util.numpy_support.vtk_to_numpy(not_low_volt_endo.GetPointData().GetArray('Global_ids')).astype(int) + not_low_volt_ids = vtk.util.numpy_support.vtk_to_numpy( + not_low_volt_endo.GetPointData().GetArray('Global_ids')).astype(int) if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() @@ -141,7 +142,7 @@ def low_vol_LAT(args, path): reader.Update() LA_fit = reader.GetOutput() - LA_fit_wall_pts = vtk.util.numpy_support.vtk_to_numpy(LA_fit.GetPoints().GetData())[LA_wall_pt_ids,:]*1000 + LA_fit_wall_pts = vtk.util.numpy_support.vtk_to_numpy(LA_fit.GetPoints().GetData())[LA_wall_pt_ids, :] * 1000 tree = cKDTree(not_low_volt_endo_pts) @@ -150,12 +151,10 @@ def low_vol_LAT(args, path): tree = cKDTree(not_low_volt_endo_pts) dd, ii = tree.query(endo_pts) - - healthy_endo = not_low_volt_endo# vtk_thr(not_low_volt_endo,0,"POINTS","CV_mag", args.low_CV_thr) + healthy_endo = not_low_volt_endo # vtk_thr(not_low_volt_endo,0,"POINTS","CV_mag", args.low_CV_thr) LAT_healthy = vtk.util.numpy_support.vtk_to_numpy(healthy_endo.GetPointData().GetArray('lat')) healthy_ids = vtk.util.numpy_support.vtk_to_numpy(healthy_endo.GetPointData().GetArray('Global_ids')).astype(int) - if args.max_LAT_pt == "max": # Selecting the location of earliest/latest activation as the very first activated map point @@ -163,10 +162,10 @@ def low_vol_LAT(args, path): # Latest activated point is the center of mass of the 97.5 percentile of LAT perc_975 = np.percentile(LAT_not_low_volt[ii], 97.5) - - ids=np.where(LAT_not_low_volt[ii]>=perc_975)[0] - max_pt = np.mean(not_low_volt_endo_pts[ii][ids],axis=0) + ids = np.where(LAT_not_low_volt[ii] >= perc_975)[0] + + max_pt = np.mean(not_low_volt_endo_pts[ii][ids], axis=0) loc = vtk.vtkPointLocator() loc.SetDataSet(not_low_volt_endo) @@ -177,10 +176,10 @@ def low_vol_LAT(args, path): # Earliest activated point is the center of mass of the 2.5 percentile of LAT perc_25 = np.percentile(LAT_not_low_volt[ii], 2.5) - - ids = np.where(LAT_not_low_volt[ii]<=perc_25)[0] - stim_pt = np.mean(not_low_volt_endo_pts[ii][ids],axis=0) + ids = np.where(LAT_not_low_volt[ii] <= perc_25)[0] + + stim_pt = np.mean(not_low_volt_endo_pts[ii][ids], axis=0) loc = vtk.vtkPointLocator() loc.SetDataSet(not_low_volt_endo) @@ -193,57 +192,57 @@ def low_vol_LAT(args, path): fit_LAT = [] steps = list(np.arange(min_LAT, args.LaAT, args.step)) for i in range(1, len(steps)): - fit_LAT.append(steps[i]-min_LAT) + fit_LAT.append(steps[i] - min_LAT) - fit_LAT.append(args.LaAT-min_LAT) + fit_LAT.append(args.LaAT - min_LAT) # Before proceeding with the iterative fitting of the clinical LAT, we detect the nodes # with an earlier activation than the neighboring vertices and mark them as wrong annotations el_to_clean, el_border = areas_to_clean(endo, args, min_LAT, stim_pt) - return bilayer_n_cells, low_vol_ids, endo, endo_ids, centroids, LAT_map-min_LAT, min_LAT, el_to_clean, el_border, stim_pt, fit_LAT, healthy_endo + return bilayer_n_cells, low_vol_ids, endo, endo_ids, centroids, LAT_map - min_LAT, min_LAT, el_to_clean, el_border, stim_pt, fit_LAT, healthy_endo -def areas_to_clean(endo, args, min_LAT, stim_pt): +def areas_to_clean(endo, args, min_LAT, stim_pt): # Really fine LAT bands with time step of 5 ms steps = list(np.arange(min_LAT, args.LaAT, 5)) steps.append(args.LaAT) el_to_clean = [] el_border = [] - tot_el_to_clean = np.array([],dtype=int) - + tot_el_to_clean = np.array([], dtype=int) + meshNew = dsa.WrapDataObject(endo) print("Starting creation of bands ... ") for i in range(1, len(steps)): # Extract LAT band from min LAT to step i and remove all areas not connected with EAP - band = vtk_thr(endo,2,"CELLS","lat", min_LAT, steps[i]) - + band = vtk_thr(endo, 2, "CELLS", "lat", min_LAT, steps[i]) + b_ids = vtk.util.numpy_support.vtk_to_numpy(band.GetCellData().GetArray('Global_ids')).astype(int) - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(band) connect.SetExtractionModeToClosestPointRegion() connect.SetClosestPoint(stim_pt) connect.Update() largest_band = connect.GetOutput() - + l_b_ids = vtk.util.numpy_support.vtk_to_numpy(largest_band.GetCellData().GetArray('Global_ids')).astype(int) - + if len(b_ids) > len(l_b_ids): cell_diff = set() - + # Find all elements which are not belonging to the clean band - el_diff = np.setdiff1d(b_ids,l_b_ids) + el_diff = np.setdiff1d(b_ids, l_b_ids) b_ids = list(b_ids) for el in el_diff: cell_diff.add(b_ids.index(el)) - + model_new_el = vtk.vtkIdList() - + for var in cell_diff: model_new_el.InsertNextId(var) - + extract = vtk.vtkExtractCells() extract.SetInputData(band) extract.SetCellList(model_new_el) @@ -252,23 +251,23 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(extract.GetOutputPort()) geo_filter.Update() - + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(geo_filter.GetOutputPort()) cleaner.Update() # Mesh of all elements which are not belonging to the clean band el_removed = cleaner.GetOutput() - + # Compute centroids of all elements which are not belonging to the clean band filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(largest_band) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() pts = vtk.util.numpy_support.vtk_to_numpy(centroids2.GetData()) - + tree = cKDTree(pts) - + connect = vtk.vtkConnectivityFilter() connect.SetInputData(el_removed) connect.SetExtractionModeToSpecifiedRegions() @@ -277,7 +276,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): for n in range(num): connect.AddSpecifiedRegion(n) connect.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(connect.GetOutputPort()) geo_filter.Update() @@ -286,47 +285,47 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): cln.SetInputConnection(geo_filter.GetOutputPort()) cln.Update() surface = cln.GetOutput() - + filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(surface) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() centroids1_array = vtk.util.numpy_support.vtk_to_numpy(centroids1.GetData()) - + dd, ii = tree.query(centroids1_array, n_jobs=-1) - + # Set as elements to clean only if they are at least 1 um away from the biggest band if np.min(dd) > 1: - - loc_el_to_clean = vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('Global_ids')).astype(int) - - tot_el_to_clean = np.union1d(tot_el_to_clean,loc_el_to_clean) - + loc_el_to_clean = vtk.util.numpy_support.vtk_to_numpy( + surface.GetCellData().GetArray('Global_ids')).astype(int) + + tot_el_to_clean = np.union1d(tot_el_to_clean, loc_el_to_clean) + # delete added region id connect.DeleteSpecifiedRegion(n) connect.Update() print("Bands to clean ready ... ") - idss = np.zeros((endo.GetNumberOfCells(),)) + idss = np.zeros((endo.GetNumberOfCells(),)) idss[tot_el_to_clean] = 1 - + meshNew.CellData.append(idss, "idss") - - endo_clean = vtk_thr(meshNew.VTKObject,1,"CELLS","idss", 0) - + + endo_clean = vtk_thr(meshNew.VTKObject, 1, "CELLS", "idss", 0) + el_cleaned = vtk.util.numpy_support.vtk_to_numpy(endo_clean.GetCellData().GetArray('Global_ids')).astype(int) - - endo_to_interpolate = vtk_thr(meshNew.VTKObject,0,"CELLS","idss", 1) - + + endo_to_interpolate = vtk_thr(meshNew.VTKObject, 0, "CELLS", "idss", 1) + filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(endo_clean) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() pts = vtk.util.numpy_support.vtk_to_numpy(centroids2.GetData()) - + tree = cKDTree(pts) - + # Find elements at the boundary of the areas to clean, which are gonna be used for the fitting of the conductivities connect = vtk.vtkConnectivityFilter() connect.SetInputData(endo_to_interpolate) @@ -336,7 +335,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): for n in range(num): connect.AddSpecifiedRegion(n) connect.Update() - + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(connect.GetOutputPort()) geo_filter.Update() @@ -345,20 +344,20 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): cln.SetInputConnection(geo_filter.GetOutputPort()) cln.Update() surface = cln.GetOutput() - + loc_el_to_clean = vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('Global_ids')).astype(int) - + el_to_clean.append(np.unique(loc_el_to_clean)) - + filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(surface) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() centroids1_array = vtk.util.numpy_support.vtk_to_numpy(centroids1.GetData()) - - dd, ii = tree.query(centroids1_array, n_jobs=-1) # Find distance to endo_clean pts - - el_border.append(np.unique(el_cleaned[ii])) # Give id of the closest point to the endo_clean + + dd, ii = tree.query(centroids1_array, n_jobs=-1) # Find distance to endo_clean pts + + el_border.append(np.unique(el_cleaned[ii])) # Give id of the closest point to the endo_clean # delete added region id connect.DeleteSpecifiedRegion(n) @@ -375,7 +374,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): else: print("Successfully created the directory %s " % debug_dir) - el_border_array = np.concatenate(el_border) # convert to linear array + el_border_array = np.concatenate(el_border) # convert to linear array border = np.zeros((endo.GetNumberOfCells(),)) border[el_border_array] = 1 meshNew.CellData.append(border, "border") @@ -387,7 +386,8 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): return el_to_clean, el_border -def create_regele(endo,args): + +def create_regele(endo, args): # Low voltage in the model low_vol = vtk_thr(endo, 1, "CELLS", "bi", args.low_vol_thr) low_vol_ids = vtk.util.numpy_support.vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) @@ -409,36 +409,38 @@ def create_regele(endo,args): print('Regele file done ...') -def low_CV(model, low_CV_thr, meshfold): - low_CV = vtk_thr(model,1,"CELLS","CV_mag",low_CV_thr) +def low_CV(model, low_CV_thr, meshfold): + low_CV = vtk_thr(model, 1, "CELLS", "CV_mag", low_CV_thr) low_CV_ids = vtk.util.numpy_support.vtk_to_numpy(low_CV.GetCellData().GetArray('Global_ids')).astype(int) - low_CV_c = vtk.util.numpy_support.vtk_to_numpy(low_CV.GetCellData().GetArray('CV_mag'))/1000 + low_CV_c = vtk.util.numpy_support.vtk_to_numpy(low_CV.GetCellData().GetArray('CV_mag')) / 1000 - low_sigma = low_CV_c**2 + low_sigma = low_CV_c ** 2 sigma = np.ones((model.GetNumberOfCells(),)) - sigma[low_CV_ids] = 0.6**2#low_sigma + sigma[low_CV_ids] = 0.6 ** 2 # low_sigma - f = open(meshfold + '/low_CV.dat','w') + f = open(meshfold + '/low_CV.dat', 'w') for i in sigma: f.write("{:.4f}\n".format(i)) f.close() -def low_CV(args, job, meas_LAT, new_endo, meshfold): +def low_CV(args, job, meas_LAT, new_endo, meshfold): lats = np.loadtxt(job.ID + '/init_acts_ACTs-thresh.dat') meshNew = dsa.WrapDataObject(new_endo) meshNew.PointData.append(lats, "LAT_s") - healthy_endo = Methods.vtk_thr(meshNew.VTKObject,1,"CELLS","elemTag",7) - active = Methods.vtk_thr(healthy_endo,0,"POINTS","LAT_s",0) + healthy_endo = Methods.vtk_thr(meshNew.VTKObject, 1, "CELLS", "elemTag", 7) + active = Methods.vtk_thr(healthy_endo, 0, "POINTS", "LAT_s", 0) max_active_LAT = np.max(vtk.util.numpy_support.vtk_to_numpy(active.GetPointData().GetArray('LAT_s'))) - max_active_band = Methods.vtk_thr(healthy_endo,2,"POINTS","LAT_s",max_active_LAT-args.tol, max_active_LAT) - active_cells = list(set(vtk.util.numpy_support.vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int)).difference(low_CV_ids)) + max_active_band = Methods.vtk_thr(healthy_endo, 2, "POINTS", "LAT_s", max_active_LAT - args.tol, max_active_LAT) + active_cells = list( + set(vtk.util.numpy_support.vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int)).difference( + low_CV_ids)) def dijkstra_path(polydata, StartVertex, EndVertex): @@ -452,11 +454,11 @@ def dijkstra_path(polydata, StartVertex, EndVertex): points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) return points_data + def get_EAP(path_mod, path_fib): - model = smart_reader(path_mod) mod_fib = smart_reader(path_fib) - + cellid = vtk.vtkIdFilter() cellid.CellIdsOn() cellid.SetInputData(mod_fib) @@ -470,16 +472,17 @@ def get_EAP(path_mod, path_fib): cellid.Update() mod_fib = cellid.GetOutput() - LA_MV = vtk_thr(mod_fib,1,"CELLS","elemTag",2) + LA_MV = vtk_thr(mod_fib, 1, "CELLS", "elemTag", 2) LAT_map = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('LAT')) - + LA_MV_ids = vtk.util.numpy_support.vtk_to_numpy(LA_MV.GetPointData().GetArray('Global_ids')).astype(int) - + print(LA_MV_ids[np.argmin(LAT_map[LA_MV_ids])]) stim_pt = model.GetPoint(LA_MV_ids[np.argmin(LAT_map[LA_MV_ids])]) return stim_pt + def smart_reader_old(path): data_checker = vtk.vtkDataSetReader() data_checker.SetFileName(str(path)) @@ -496,6 +499,7 @@ def smart_reader_old(path): return output + def smart_reader(path): extension = str(path).split(".")[-1] @@ -524,31 +528,33 @@ def smart_reader(path): return output -def vtk_thr(model,mode,points_cells,array,thr1,thr2="None"): + +def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thresh = vtk.vtkThreshold() thresh.SetInputData(model) if mode == 0: thresh.ThresholdByUpper(thr1) elif mode == 1: thresh.ThresholdByLower(thr1) - elif mode ==2: + elif mode == 2: if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1,thr2) + thresh.ThresholdBetween(thr1, thr2) else: thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() thr = thresh.GetOutput() thresh = vtk.vtkThreshold() thresh.SetInputData(thr) thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_"+points_cells, array) + thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) thresh.Update() - + output = thresh.GetOutput() - + return output + def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index a031562..e35a19c 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -48,22 +48,25 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] + def parser(): # Generate the standard command line parser parser = tools.standard_parser() # Add arguments - parser.add_argument('--giL', type=float, default=0.4, help='intracellular longitudinal conductivity to fit CV=0.714 m/s with dx=0.3 mm and dt=20') - parser.add_argument('--geL', type=float, default=1.1, help='extracellular longitudinal conductivity to fit CV=0.714 m/s with dx=0.3 mm and dt=20') + parser.add_argument('--giL', type=float, default=0.4, + help='intracellular longitudinal conductivity to fit CV=0.714 m/s with dx=0.3 mm and dt=20') + parser.add_argument('--geL', type=float, default=1.1, + help='extracellular longitudinal conductivity to fit CV=0.714 m/s with dx=0.3 mm and dt=20') parser.add_argument('--model', type=str, default='COURTEMANCHE', help='input ionic model') parser.add_argument('--low_vol_thr', - type=float, + type=float, default=0.5, help='bipolar voltage threshold to define low voltage region') parser.add_argument('--low_CV_thr', - type=float, + type=float, default=300, help='CV threshold to define low CV region in mm/s') parser.add_argument('--LaAT', @@ -104,7 +107,7 @@ def parser(): default='../data', help='path to initialization state folder') parser.add_argument('--fibrotic_tissue', - type=int, + type=int, default=1, help='set 1 for mesh with fibrotic tissue, 0 otherwise') parser.add_argument('--M_lump', @@ -123,7 +126,7 @@ def parser(): type=str, default="mesh/meanshape", help='statistical shape model basename') - #---------------------------------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------------------------------- parser.add_argument('--dt', type=float, default=20.0, help='[microsec]') @@ -139,35 +142,38 @@ def parser(): help='stimulation transmembrane current in uA/cm^2 (2Dcurrent) or uA/cm^3 (3Dcurrent)') # Single cell prepace parser.add_argument('--cell_bcl', - type=float, - default=1000.0, - help='Specify the basic cycle length (ms) to initialize cells') + type=float, + default=1000.0, + help='Specify the basic cycle length (ms) to initialize cells') parser.add_argument('--numstim', - type=int, - default=50, - help='Specify the number of single cell stimuli with the given bcl') + type=int, + default=50, + help='Specify the number of single cell stimuli with the given bcl') parser.add_argument('--prebeats', - type = int, - default = 4, + type=int, + default=4, help='Number of beats to prepace the tissue') parser.add_argument('--debug', type=int, default=1, help='set to 1 to debug step by step, 0 otherwise') -#---------------------------------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------------------------------- return parser + def jobID(args): today = date.today() - mesh= args.mesh.split('/')[-1] - ID = '{}/{}_converge_band_{}_prebeats_{}_bcl_{}_fib_{}_max_LAT_pt_{}_voltage_{}_CV_{}_meth_{}_fib_p_{}_step_{}_thr_{}'.format(args.results_dir,today.isoformat(),mesh, - args.prebeats, args.bcl, args.fibrotic_tissue, args.max_LAT_pt, args.low_vol_thr, args.low_CV_thr, args.meth, args.fib_perc, args.step, args.thr) + mesh = args.mesh.split('/')[-1] + ID = '{}/{}_converge_band_{}_prebeats_{}_bcl_{}_fib_{}_max_LAT_pt_{}_voltage_{}_CV_{}_meth_{}_fib_p_{}_step_{}_thr_{}'.format( + args.results_dir, today.isoformat(), mesh, + args.prebeats, args.bcl, args.fibrotic_tissue, args.max_LAT_pt, args.low_vol_thr, args.low_CV_thr, args.meth, + args.fib_perc, args.step, args.thr) return ID -def single_cell_initialization(args,job, steady_state_dir, to_do): +def single_cell_initialization(args, job, steady_state_dir, to_do): g_CaL_reg = [0.45, 0.7515, 0.7515, 0.3015, 0.3015, 0.4770, 0.4770, 0.45, 0.3375] g_K1_reg = [2, 2, 2, 2, 2, 2, 2, 2, 1.34] blf_g_Kur_reg = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5] @@ -179,24 +185,33 @@ def single_cell_initialization(args,job, steady_state_dir, to_do): n_regions = len(g_CaL_reg) - duration = args.numstim*args.cell_bcl + duration = args.numstim * args.cell_bcl for k in range(n_regions): - init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, k,args.numstim) + init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, k, + args.numstim) cmd = [settings.execs.BENCH, - '--imp', args.model, - '--imp-par', 'g_CaL*{},g_K1*{},blf_i_Kur*{},g_to*{},g_Ks*{},maxI_pCa*{},maxI_NaCa*{},g_Kr*{}'.format(g_CaL_reg[k],g_K1_reg[k],blf_g_Kur_reg[k],g_to_reg[k],g_Ks_reg[k],maxI_pCa_reg[k],maxI_NaCa_reg[k],g_Kr_reg[k]), - '--bcl', args.cell_bcl, - '--dt-out', 1, # Temporal granularity in ms (if --dt-out= duration it saves only last value) - '--stim-curr', 9.5, - '--stim-dur', args.stim_duration, - '--numstim', args.numstim, - '--duration', duration, - '--stim-start', 0, - '--dt', args.dt/1000, - '--fout=' + steady_state_dir + '/{}_numstim_{}_bcl_ms_{}'.format(args.numstim,args.cell_bcl,k), - '-S', duration, - '-F', init_file, - '--trace-no', k] + '--imp', args.model, + '--imp-par', + 'g_CaL*{},g_K1*{},blf_i_Kur*{},g_to*{},g_Ks*{},maxI_pCa*{},maxI_NaCa*{},g_Kr*{}'.format(g_CaL_reg[k], + g_K1_reg[k], + blf_g_Kur_reg[k], + g_to_reg[k], + g_Ks_reg[k], + maxI_pCa_reg[k], + maxI_NaCa_reg[k], + g_Kr_reg[k]), + '--bcl', args.cell_bcl, + '--dt-out', 1, # Temporal granularity in ms (if --dt-out= duration it saves only last value) + '--stim-curr', 9.5, + '--stim-dur', args.stim_duration, + '--numstim', args.numstim, + '--duration', duration, + '--stim-start', 0, + '--dt', args.dt / 1000, + '--fout=' + steady_state_dir + '/{}_numstim_{}_bcl_ms_{}'.format(args.numstim, args.cell_bcl, k), + '-S', duration, + '-F', init_file, + '--trace-no', k] if to_do: job.bash(cmd) @@ -213,84 +228,96 @@ def single_cell_initialization(args,job, steady_state_dir, to_do): n_regions += len(g_CaL_fib) for kk in range(len(g_CaL_fib)): - init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, k+1+kk,args.numstim) + init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, + k + 1 + kk, + args.numstim) cmd = [settings.execs.BENCH, - '--imp', args.model, - '--imp-par', 'g_CaL*{},g_Na*{},blf_i_Kur*{},g_to*{},g_Ks*{},maxI_pCa*{},maxI_NaCa*{}'.format(g_CaL_fib[kk],g_Na_fib[kk],blf_g_Kur_fib[kk],g_to_fib[kk],g_Ks_fib[kk],maxI_pCa_fib[kk],maxI_NaCa_fib[kk]), - '--bcl', args.cell_bcl, - '--dt-out', 1, # Temporal granularity in ms (if --dt-out= duration it saves only last value) - '--stim-curr', 9.5, - '--stim-dur', args.stim_duration, - '--numstim', args.numstim, - '--duration', duration, - '--stim-start', 0, - '--dt', args.dt/1000, - '--fout=' + steady_state_dir + '/{}_numstim_{}_bcl_ms_{}'.format(args.numstim,args.cell_bcl,k+1+kk), - '-S', duration, - '-F', init_file, - '--trace-no', k+1+kk] + '--imp', args.model, + '--imp-par', + 'g_CaL*{},g_Na*{},blf_i_Kur*{},g_to*{},g_Ks*{},maxI_pCa*{},maxI_NaCa*{}'.format(g_CaL_fib[kk], + g_Na_fib[kk], + blf_g_Kur_fib[kk], + g_to_fib[kk], + g_Ks_fib[kk], + maxI_pCa_fib[kk], + maxI_NaCa_fib[kk]), + '--bcl', args.cell_bcl, + '--dt-out', 1, # Temporal granularity in ms (if --dt-out= duration it saves only last value) + '--stim-curr', 9.5, + '--stim-dur', args.stim_duration, + '--numstim', args.numstim, + '--duration', duration, + '--stim-start', 0, + '--dt', args.dt / 1000, + '--fout=' + steady_state_dir + '/{}_numstim_{}_bcl_ms_{}'.format(args.numstim, args.cell_bcl, + k + 1 + kk), + '-S', duration, + '-F', init_file, + '--trace-no', k + 1 + kk] if to_do: job.bash(cmd) tissue_init = [] for k in range(n_regions): - init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, k, args.numstim) + init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, k, + args.numstim) tissue_init += ['-imp_region[{}].im_sv_init'.format(k), init_file] - if to_do: # Move trace files to steady_state_dir + if to_do: # Move trace files to steady_state_dir for file in os.listdir(os.getcwd()): if file.startswith("Trace") or file.startswith("{}_trace".format(args.model)): old_file = os.getcwd() + '/' + file new_file = steady_state_dir + '/' + file os.rename(old_file, new_file) - return tissue_init def remove_trash2(simid): - for f in os.listdir(simid): - if f.startswith("init_") or f.startswith("Trace_"): - if os.path.isfile(os.path.join(simid,f)): - os.remove(os.path.join(simid,f)) + for f in os.listdir(simid): + if f.startswith("init_") or f.startswith("Trace_"): + if os.path.isfile(os.path.join(simid, f)): + os.remove(os.path.join(simid, f)) + + +def tagregopt(reg, field, val): + return ['-tagreg[' + str(reg) + '].' + field, val] -def tagregopt( reg, field, val ) : - return ['-tagreg['+str(reg)+'].'+field, val ] def tri_centroid(nodes, element): - x1 = nodes[element[0],0] - x2 = nodes[element[1],0] - x3 = nodes[element[2],0] + x1 = nodes[element[0], 0] + x2 = nodes[element[1], 0] + x3 = nodes[element[2], 0] + + y1 = nodes[element[0], 1] + y2 = nodes[element[1], 1] + y3 = nodes[element[2], 1] - y1 = nodes[element[0],1] - y2 = nodes[element[1],1] - y3 = nodes[element[2],1] + z1 = nodes[element[0], 2] + z2 = nodes[element[1], 2] + z3 = nodes[element[2], 2] - z1 = nodes[element[0],2] - z2 = nodes[element[1],2] - z3 = nodes[element[2],2] + return [(x1 + x2 + x3) / 3, (y1 + y2 + y3) / 3, (z1 + z2 + z3) / 3] - return [(x1+x2+x3)/3, (y1+y2+y3)/3, (z1+z2+z3)/3] @tools.carpexample(parser, jobID) def run(args, job): - # Polyfit of the CVs # p = np.poly1d([0.67278584, 0.17556362, 0.01718574]) - meshname = '{}_fibers/result_LA/LA_bilayer_with_fiber'.format(args.mesh) # um + meshname = '{}_fibers/result_LA/LA_bilayer_with_fiber'.format(args.mesh) # um meshbasename = meshname.split('/')[-4] - meshfold = '{}/{}'.format(args.init_state_dir,meshbasename) - + meshfold = '{}/{}'.format(args.init_state_dir, meshbasename) + steady_state_dir = '{}/{}/cell_state'.format(args.init_state_dir, meshbasename) try: os.makedirs(steady_state_dir) except OSError: - print ("Creation of the directory %s failed" % steady_state_dir) + print("Creation of the directory %s failed" % steady_state_dir) else: - print ("Successfully created the directory %s " % steady_state_dir) + print("Successfully created the directory %s " % steady_state_dir) if not os.path.isfile( steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, 0, args.numstim)): @@ -303,22 +330,23 @@ def run(args, job): try: os.makedirs(simid) except OSError: - print ("Creation of the directory %s failed" % simid) + print("Creation of the directory %s failed" % simid) else: - print ("Successfully created the directory %s " % simid) + print("Successfully created the directory %s " % simid) - bilayer_n_cells, elements_in_fibrotic_reg, endo, endo_ids, centroids, LAT_map, min_LAT, el_to_clean, el_border, stim_pt, fit_LAT, healthy_endo = Methods_fit_to_clinical_LAT.low_vol_LAT(args, meshname+'_with_data_um.vtk') + bilayer_n_cells, elements_in_fibrotic_reg, endo, endo_ids, centroids, LAT_map, min_LAT, el_to_clean, el_border, stim_pt, fit_LAT, healthy_endo = Methods_fit_to_clinical_LAT.low_vol_LAT( + args, meshname + '_with_data_um.vtk') - with open("{}/{}/clinical_stim_pt.txt".format(args.init_state_dir, meshbasename),"w") as f: - f.write("{} {} {}".format(stim_pt[0],stim_pt[1],stim_pt[2])) + with open("{}/{}/clinical_stim_pt.txt".format(args.init_state_dir, meshbasename), "w") as f: + f.write("{} {} {}".format(stim_pt[0], stim_pt[1], stim_pt[2])) # Set to 1 every LAT <= 1 - LAT_map = np.where(LAT_map<=1, 1, LAT_map) + LAT_map = np.where(LAT_map <= 1, 1, LAT_map) args.LaAT = args.LaAT - min_LAT # Set to max_LAT every LAT >= max_LAT - LAT_map = np.where(LAT_map>args.LaAT, args.LaAT, LAT_map) + LAT_map = np.where(LAT_map > args.LaAT, args.LaAT, LAT_map) print("Wanted LAT: {}".format(args.LaAT)) print("Max LAT point id: {}".format(args.max_LAT_id)) @@ -327,15 +355,15 @@ def run(args, job): # Find all not conductive elements belonging to the fibrotic tissue and not use them in the fitting tag = {} if not os.path.isfile('{}/elems_slow_conductive.regele'.format(meshfold)): - Methods_fit_to_clinical_LAT.create_regele(endo,args) + Methods_fit_to_clinical_LAT.create_regele(endo, args) - print ('Reading regele file ...') + print('Reading regele file ...') elems_not_conductive = np.loadtxt('{}/elems_slow_conductive.regele'.format(meshfold), skiprows=1, dtype=int) endo_etag = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('elemTag')) - elems_not_conductive = elems_not_conductive[np.where(elems_not_conductivebridges - reg_2 = tag['crista_terminalis'] # CT 60 - reg_3 = tag['pectinate_muscle'] # PM 59 - reg_4 = [tag['bachmann_bundel_left'], tag['bachmann_bundel_right'], tag['bachmann_bundel_internal']] # BB 81,82,83 - - if args.fibrotic_tissue == 1: # append regions 101,102,103 - reg_1 = [1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 17, 51, 52, 55, 56, 58, 61, 62, 63, 66, 68, 84, 86, 88, 101, 102, 103] - - lat = ['-num_LATs', 1, - '-lats[0].ID', 'ACTs', - '-lats[0].all', 0, - '-lats[0].measurand', 0, - '-lats[0].mode', 0, - '-lats[0].threshold', -50] + reg_0 = [tag['sinus_node'], 54, 65, 70] # SN 69, ICB_endo 54, ICB_epi 65, CS 70 + reg_1 = [1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 66, 67, 68, + 84, 86, + 88] # LA endo 1-7, LA epi 11-17, RA endo 51-58 , RA epi 61-68, 84 MPB, 86 UPB, CSB 88 RA endo 51-58 ->bridges + reg_2 = tag['crista_terminalis'] # CT 60 + reg_3 = tag['pectinate_muscle'] # PM 59 + reg_4 = [tag['bachmann_bundel_left'], tag['bachmann_bundel_right'], tag['bachmann_bundel_internal']] # BB 81,82,83 + + if args.fibrotic_tissue == 1: # append regions 101,102,103 + reg_1 = [1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 17, 51, 52, 55, 56, 58, 61, 62, 63, 66, 68, 84, 86, 88, 101, + 102, 103] + + lat = ['-num_LATs', 1, + '-lats[0].ID', 'ACTs', + '-lats[0].all', 0, + '-lats[0].measurand', 0, + '-lats[0].mode', 0, + '-lats[0].threshold', -50] slow_CV = np.ones((len(endo_ids),)) slow_CV_old = np.ones((len(endo_ids),)) # Create the conductivity scale map with ones factors as initial condition - f = open(simid + '/low_CV.dat','w') + f = open(simid + '/low_CV.dat', 'w') for i in slow_CV: f.write("{:.4f}\n".format(i)) f.close() - - f = open(simid + '/low_CV_old.dat','w') + + f = open(simid + '/low_CV_old.dat', 'w') for i in slow_CV: f.write("{:.4f}\n".format(i)) f.close() - + final_diff = [] - old_cells = np.array([],dtype=int) + old_cells = np.array([], dtype=int) lats_to_fit = np.array([]) - active_cells_old = np.array([],dtype=int) - active_cells_band = np.array([],dtype=int) + active_cells_old = np.array([], dtype=int) + active_cells_band = np.array([], dtype=int) for l in range(len(fit_LAT)): @@ -437,7 +471,7 @@ def run(args, job): it = 1 - while RMSE>args.tol: + while RMSE > args.tol: cmd = tools.carp_cmd('stimulation.par') @@ -522,7 +556,7 @@ def run(args, job): '-gregion[5].g_en ', sigma_L] g_scale = ['-ge_scale_vec', simid + '/low_CV.dat', - '-gi_scale_vec', simid + '/low_CV.dat'] + '-gi_scale_vec', simid + '/low_CV.dat'] # Set different tissue properties cmd += tissue_0 @@ -556,11 +590,11 @@ def run(args, job): '-stimulus[0].duration', args.stim_duration, '-stimulus[0].npls', 1, '-stimulus[0].ctr_def', 1, - '-stimulus[0].x0', stim_pt[0] , + '-stimulus[0].x0', stim_pt[0], '-stimulus[0].xd', 3000, - '-stimulus[0].y0', stim_pt[1] , + '-stimulus[0].y0', stim_pt[1], '-stimulus[0].yd', 3000, - '-stimulus[0].z0', stim_pt[2] , + '-stimulus[0].z0', stim_pt[2], '-stimulus[0].zd', 3000] cmd += lat @@ -590,13 +624,13 @@ def run(args, job): pt_cell.CategoricalDataOff() pt_cell.ProcessAllArraysOff() pt_cell.Update() - + model = pt_cell.GetOutput() meshNew = dsa.WrapDataObject(model) # Extract all not fibrotic tissue (103 is not conductive) - healthy_endo = Methods_fit_to_clinical_LAT.vtk_thr(model,1,"CELLS","elemTag",102) + healthy_endo = Methods_fit_to_clinical_LAT.vtk_thr(model, 1, "CELLS", "elemTag", 102) # Extract all cells which are activated - active = Methods_fit_to_clinical_LAT.vtk_thr(healthy_endo,0,"POINTS","lat_s",0) + active = Methods_fit_to_clinical_LAT.vtk_thr(healthy_endo, 0, "POINTS", "lat_s", 0) active_cells = vtk.util.numpy_support.vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int) print("active_cells: {}".format(len(active_cells))) @@ -613,11 +647,11 @@ def run(args, job): lats_to_fit_old = np.array(lats_to_fit) lats_to_fit = vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('lat_s')) - - if len(lats_to_fit_old)>0: + + if len(lats_to_fit_old) > 0: meshNew.CellData.append(lats_to_fit_old, "LATs_old") meshNew.CellData.append(LAT_map, "LAT_to_clean") - + # Find all active areas (border = 2 and core = 1) marked as wrong annotation, we give to the core the mean of the active border active_to_interpolate = [] active_border = [] @@ -626,13 +660,13 @@ def run(args, job): for k in range(len(el_to_clean)): idss[el_to_clean[k]] = 1 idss[el_border[k]] = 2 - current_active_to_interp = np.setdiff1d(np.intersect1d(el_to_clean[k],active_cells_band),old_cells) - if len(current_active_to_interp>0): + current_active_to_interp = np.setdiff1d(np.intersect1d(el_to_clean[k], active_cells_band), old_cells) + if len(current_active_to_interp > 0): active_to_interpolate.append(current_active_to_interp) - active_border.append(np.setdiff1d(np.intersect1d(el_border[k], active_cells_band),old_cells)) + active_border.append(np.setdiff1d(np.intersect1d(el_border[k], active_cells_band), old_cells)) l_idss[current_active_to_interp] = 1 - l_idss[np.setdiff1d(np.intersect1d(el_border[k], active_cells_band),old_cells)] = 2 - + l_idss[np.setdiff1d(np.intersect1d(el_border[k], active_cells_band), old_cells)] = 2 + meshNew.CellData.append(idss, "idss") meshNew.CellData.append(l_idss, "l_idss") @@ -643,113 +677,115 @@ def run(args, job): print("old_cells: {}".format(len(old_cells))) # Compute RMSE between simulated and clinical LAT excluding elements to clean (marked as wrong annotation) - if len(lats_to_fit[active_cells_band])>0: - if len(active_border)>0: + if len(lats_to_fit[active_cells_band]) > 0: + if len(active_border) > 0: print("Active border") current_active_to_interp = np.array([], dtype=int) for k in range(len(active_to_interpolate)): current_active_to_interp = np.union1d(current_active_to_interp, active_to_interpolate[k]) active_cleaned_cells = np.setdiff1d(active_cells_band, current_active_to_interp) - RMSE = mean_squared_error(LAT_map[active_cleaned_cells], lats_to_fit[active_cleaned_cells], squared=False) + RMSE = mean_squared_error(LAT_map[active_cleaned_cells], lats_to_fit[active_cleaned_cells], + squared=False) else: RMSE = mean_squared_error(LAT_map[active_cells_band], lats_to_fit[active_cells_band], squared=False) - print("RMSE: ",RMSE) + print("RMSE: ", RMSE) print("err: ", err) - if RMSE>args.tol and RMSE + args.tol*0.25 < err: # Stopping criteria: RMSE< tol or new RMSE + 0.25*tol > old RMSE + if RMSE > args.tol and RMSE + args.tol * 0.25 < err: # Stopping criteria: RMSE< tol or new RMSE + 0.25*tol > old RMSE meshNew.CellData.append(slow_CV_old, "slow_CV_old") slow_CV_old[:] = slow_CV[:] active_cells_old_old = np.array(active_cells_old, dtype=int) - if len(active_border)>0: # Elements to clean + if len(active_border) > 0: # Elements to clean # For each area to clean, give to the active core the mean of conductivity of the active border - slow_CV[active_cleaned_cells] = slow_CV[active_cleaned_cells]*((lats_to_fit[active_cleaned_cells]/(LAT_map[active_cleaned_cells]))**2) + slow_CV[active_cleaned_cells] = slow_CV[active_cleaned_cells] * ( + (lats_to_fit[active_cleaned_cells] / (LAT_map[active_cleaned_cells])) ** 2) for k in range(len(active_to_interpolate)): - if len(active_border[k])>0: + if len(active_border[k]) > 0: slow_CV[active_to_interpolate[k]] = np.mean(slow_CV[active_border[k]]) - else: # No elements to clean + else: # No elements to clean # sigma_new = sigma_old*(lat_simulated/lat_clinical)^2 for sigma = CV^2 see https://opencarp.org/documentation/examples/02_ep_tissue/03a_study_prep_tunecv - slow_CV[active_cells_band] = slow_CV[active_cells_band]*((lats_to_fit[active_cells_band]/(LAT_map[active_cells_band]))**2) - - slow_CV = np.where(slow_CV>3.5, 3.5, slow_CV) # Set an upper bound in CV of 2.15 m/s - slow_CV = np.where(slow_CV<0.15, 0.15, slow_CV) # Set a lower bound in CV of 0.35 m/s - + slow_CV[active_cells_band] = slow_CV[active_cells_band] * ( + (lats_to_fit[active_cells_band] / (LAT_map[active_cells_band])) ** 2) + + slow_CV = np.where(slow_CV > 3.5, 3.5, slow_CV) # Set an upper bound in CV of 2.15 m/s + slow_CV = np.where(slow_CV < 0.15, 0.15, slow_CV) # Set a lower bound in CV of 0.35 m/s + meshNew.CellData.append(slow_CV, "slow_CV") writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/endo_cleaned_{}.vtu".format(l)) + writer.SetFileName(job.ID + "/endo_cleaned_{}.vtu".format(l)) writer.SetInputData(meshNew.VTKObject) - #writer.SetFileTypeToBinary() + # writer.SetFileTypeToBinary() writer.Write() LAT_diff = RMSE - os.rename(simid + '/low_CV.dat',simid + '/low_CV_old.dat') - f = open(simid + '/low_CV.dat','w') + os.rename(simid + '/low_CV.dat', simid + '/low_CV_old.dat') + f = open(simid + '/low_CV.dat', 'w') for i in slow_CV: f.write("{:.4f}\n".format(i)) f.close() - it +=1 + it += 1 else: old_cells = np.union1d(old_cells, active_cells_old_old) slow_CV[:] = slow_CV_old[:] LATs_diff = np.zeros((model.GetNumberOfCells(),)) - LATs_diff[old_cells] = lats_to_fit_old[old_cells]-LAT_map[old_cells] + LATs_diff[old_cells] = lats_to_fit_old[old_cells] - LAT_map[old_cells] meshNew.CellData.append(slow_CV, "slow_CV") meshNew.CellData.append(LATs_diff, "LATs_diff") meshNew.CellData.append(slow_CV_old, "slow_CV_old") final_diff.append(LAT_diff) writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/endo_cleaned_{}.vtu".format(l)) + writer.SetFileName(job.ID + "/endo_cleaned_{}.vtu".format(l)) writer.SetInputData(meshNew.VTKObject) - #writer.SetFileTypeToBinary() + # writer.SetFileTypeToBinary() writer.Write() break - + err = RMSE - cmd = tools.carp_cmd('stimulation.par') - g_scale = ['-ge_scale_vec', simid+'/low_CV_old.dat', - '-gi_scale_vec', simid+'/low_CV_old.dat'] + g_scale = ['-ge_scale_vec', simid + '/low_CV_old.dat', + '-gi_scale_vec', simid + '/low_CV_old.dat'] # Set different tissue properties - cmd += tissue_0 - cmd += tissue_1 + cmd += tissue_0 + cmd += tissue_1 cmd += tissue_2 cmd += tissue_3 cmd += tissue_4 + bilayer + g_scale - - #cmd += fibrotic_tissue + + # cmd += fibrotic_tissue cmd += lat # Setting the stimulus at the sinus node - prepace = ['-num_stim', 1, - '-write_statef', writestatef, - '-num_tsav', 1, - '-tsav[0]', tsav_state, - '-stimulus[0].stimtype', 0, - '-stimulus[0].strength', 30.0, - '-stimulus[0].duration', 2.0, - '-stimulus[0].npls', 1, - '-stimulus[0].ctr_def', 1, - '-stimulus[0].x0', stim_pt[0], - '-stimulus[0].xd', 3000, - '-stimulus[0].y0', stim_pt[1], - '-stimulus[0].yd', 3000, - '-stimulus[0].z0', stim_pt[2], - '-stimulus[0].zd', 3000] + prepace = ['-num_stim', 1, + '-write_statef', writestatef, + '-num_tsav', 1, + '-tsav[0]', tsav_state, + '-stimulus[0].stimtype', 0, + '-stimulus[0].strength', 30.0, + '-stimulus[0].duration', 2.0, + '-stimulus[0].npls', 1, + '-stimulus[0].ctr_def', 1, + '-stimulus[0].x0', stim_pt[0], + '-stimulus[0].xd', 3000, + '-stimulus[0].y0', stim_pt[1], + '-stimulus[0].yd', 3000, + '-stimulus[0].z0', stim_pt[2], + '-stimulus[0].zd', 3000] cmd += tissue_init + prepace cmd += ['-simID', simid, - '-dt', 20, + '-dt', 20, '-spacedt', 1, '-mass_lumping', args.M_lump, '-timedt', 10, '-num_tsav', 1, '-tsav[0]', tsav_state, - '-tend', tsav_state+2*args.step+0.1, + '-tend', tsav_state + 2 * args.step + 0.1, '-meshname', meshname_e] - #Run simulation + # Run simulation remove_trash2(simid) job.carp(cmd) - model_cleaned = Methods_fit_to_clinical_LAT.vtk_thr(meshNew.VTKObject, 2, "CELLS", "idss", 0,0) + model_cleaned = Methods_fit_to_clinical_LAT.vtk_thr(meshNew.VTKObject, 2, "CELLS", "idss", 0, 0) cleaned_ids = vtk.util.numpy_support.vtk_to_numpy(model_cleaned.GetPointData().GetArray('Global_ids')).astype(int) @@ -766,25 +802,25 @@ def run(args, job): print("Final last ACT: {}".format(last_ACT)) print("Final giL: {}".format(args.giL)) print("Final geL: {}".format(args.geL)) - f = open(job.ID + '/err.dat','w') + f = open(job.ID + '/err.dat', 'w') for i in final_diff: f.write("{:.4f}\n".format(i)) f.close() if os.path.exists('RMSE_patients.txt'): - append_write = 'a' # append if already exists + append_write = 'a' # append if already exists else: - append_write = 'w' # make a new file if not - f=open('RMSE_patients.txt', append_write) + append_write = 'w' # make a new file if not + f = open('RMSE_patients.txt', append_write) f.write("{} {} {} {:.2f}\n".format(args.mesh, args.step, args.thr, RMSE)) f.close() - slow_CV = np.loadtxt(simid+'/low_CV_old.dat') + slow_CV = np.loadtxt(simid + '/low_CV_old.dat') slow_CV_bil = np.ones((bilayer_n_cells,)) slow_CV_bil[endo_ids] = slow_CV - slow_CV_bil[endo_ids+len(endo_ids)] = slow_CV + slow_CV_bil[endo_ids + len(endo_ids)] = slow_CV - f = open(meshfold + '/low_CV_3_{}_{}.dat'.format(args.step,args.thr),'w') + f = open(meshfold + '/low_CV_3_{}_{}.dat'.format(args.step, args.thr), 'w') for i in slow_CV_bil: f.write("{:.4f}\n".format(i)) f.close() @@ -800,15 +836,16 @@ def run(args, job): pt_cell.Update() meshNew.CellData.append(LAT_map, "LAT_to_clean") - LATs_diff = vtk.util.numpy_support.vtk_to_numpy(pt_cell.GetOutput().GetCellData().GetArray('lat_s'))-LAT_map + LATs_diff = vtk.util.numpy_support.vtk_to_numpy(pt_cell.GetOutput().GetCellData().GetArray('lat_s')) - LAT_map meshNew.CellData.append(slow_CV, "slow_CV") meshNew.CellData.append(LATs_diff, "LATs_diff") writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID+"/endo_final.vtu") + writer.SetFileName(job.ID + "/endo_final.vtu") writer.SetInputData(meshNew.VTKObject) - #writer.SetFileTypeToBinary() + # writer.SetFileTypeToBinary() writer.Write() + if __name__ == '__main__': run() From 68bdc8c9e3b21acea4a544a5e25cb5072d25903f Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 15:44:29 +0100 Subject: [PATCH 02/70] Used flynt to reformat .format into f-string for better readability and performance --- .../Generate_Boundaries/extract_rings.py | 70 +++++++++--------- .../extract_rings_TOP_epi_endo.py | 66 ++++++++--------- .../Generate_Boundaries/generate_surf_id.py | 22 +++--- .../Generate_Boundaries/separate_epi_endo.py | 6 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 10 +-- Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py | 2 +- .../LDRBM/Fiber_LA/la_calculate_gradient.py | 4 +- .../LDRBM/Fiber_LA/la_generate_fiber.py | 38 +++++----- Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py | 16 ++-- Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py | 10 +-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 14 ++-- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 10 +-- .../LDRBM/Fiber_RA/create_bridges_test.py | 10 +-- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 8 +- .../LDRBM/Fiber_RA/ra_calculate_gradient.py | 4 +- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 62 ++++++++-------- Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py | 6 +- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 10 +-- pipeline.py | 34 ++++----- standalones/getmarks.py | 10 +-- standalones/open_orifices_manually.py | 16 ++-- standalones/open_orifices_with_curvature.py | 36 ++++----- standalones/prealign_meshes.py | 38 +++++----- standalones/resample_surf_mesh.py | 50 ++++++------- .../Methods_fit_to_clinical_LAT.py | 30 ++++---- ...tune_conductivities_to_fit_clinical_LAT.py | 74 +++++++++---------- 26 files changed, 328 insertions(+), 328 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index f05c8b5..79810c8 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -125,7 +125,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i mesh = mesh[:-(len(extension) + 1)] meshname = mesh.split("/")[-1] - outdir = "{}_surf".format(mesh) + outdir = f"{mesh}_surf" if not os.path.exists(outdir): os.makedirs(outdir) @@ -411,13 +411,13 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_{}.vtx'.format(r.name) + fname = outdir + f'/ids_{r.name}.vtx' if os.path.exists(fname): id_vec = id_vec[0:len(id_vec) - 1] f = open(fname, 'a') else: f = open(fname, 'w') - f.write('{}\n'.format(len(id_vec))) + f.write(f'{len(id_vec)}\n') f.write('extra\n') if r.name == "MV": @@ -436,32 +436,32 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): RPV = RPV + list(id_vec) for i in id_vec: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() centroids[r.name] = r.center fname = outdir + '/ids_LAA.vtx' f = open(fname, 'w') - f.write('{}\n'.format(1)) + f.write(f'{1}\n') f.write('extra\n') - f.write('{}\n'.format(LAA_id)) + f.write(f'{LAA_id}\n') f.close() fname = outdir + '/ids_LPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(LPV))) + f.write(f'{len(LPV)}\n') f.write('extra\n') for i in LPV: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() fname = outdir + '/ids_RPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(RPV))) + f.write(f'{len(RPV)}\n') f.write('extra\n') for i in RPV: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() return b_tag, centroids @@ -507,10 +507,10 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_{}.vtx'.format(r.name) + fname = outdir + f'/ids_{r.name}.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(id_vec))) + f.write(f'{len(id_vec)}\n') f.write('extra\n') if r.name == "TV": @@ -523,7 +523,7 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): b_tag[id_vec] = 9 for i in id_vec: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() @@ -531,9 +531,9 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): fname = outdir + '/ids_RAA.vtx' f = open(fname, 'w') - f.write('{}\n'.format(1)) + f.write(f'{1}\n') f.write('extra\n') - f.write('{}\n'.format(RAA_id)) + f.write(f'{RAA_id}\n') f.close() return b_tag, centroids, rings @@ -628,18 +628,18 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_MV_ant.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(MV_ant))) + f.write(f'{len(MV_ant)}\n') f.write('extra\n') for i in MV_ant: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() fname = outdir + '/ids_MV_post.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(MV_post))) + f.write(f'{len(MV_post)}\n') f.write('extra\n') for i in MV_post: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() loc = vtk.vtkPointLocator() @@ -671,10 +671,10 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_MV_LPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(mv_lpv))) + f.write(f'{len(mv_lpv)}\n') f.write('extra\n') for i in mv_lpv: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() path = vtk.vtkDijkstraGraphGeodesicPath() @@ -691,10 +691,10 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_MV_RPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(mv_rpv))) + f.write(f'{len(mv_rpv)}\n') f.write('extra\n') for i in mv_rpv: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() path = vtk.vtkDijkstraGraphGeodesicPath() @@ -711,10 +711,10 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_RPV_LPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(rpv_lpv))) + f.write(f'{len(rpv_lpv)}\n') f.write('extra\n') for i in rpv_lpv: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() @@ -821,10 +821,10 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): tv_f_ids = vtk.util.numpy_support.vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(tv_f_ids))) + f.write(f'{len(tv_f_ids)}\n') f.write('extra\n') for i in tv_f_ids: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() geo_filter2 = vtk.vtkGeometryFilter() @@ -835,10 +835,10 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): tv_s_ids = vtk.util.numpy_support.vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(tv_s_ids))) + f.write(f'{len(tv_s_ids)}\n') f.write('extra\n') for i in tv_s_ids: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() svc_points = svc.GetPoints().GetData() @@ -859,7 +859,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): surface = connect.GetOutput() if debug: - vtkWrite(surface, outdir + '/gamma_top_{}.vtk'.format(str(i))) + vtkWrite(surface, outdir + f'/gamma_top_{str(i)}.vtk') # Clean unused points cln = vtk.vtkCleanPolyData() @@ -871,7 +871,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): points = points.tolist() if debug: - create_pts(points, '/border_points_{}'.format(str(i)), outdir) + create_pts(points, f'/border_points_{str(i)}', outdir) in_ivc = False in_svc = False @@ -971,18 +971,18 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): top_endo = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(top_endo))) + f.write(f'{len(top_endo)}\n') f.write('extra\n') for i in top_endo: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() def create_pts(array_points, array_name, mesh_dir): - f = open("{}{}.pts".format(mesh_dir, array_name), "w") + f = open(f"{mesh_dir}{array_name}.pts", "w") f.write("0 0 0\n") for i in range(len(array_points)): - f.write("{} {} {}\n".format(array_points[i][0], array_points[i][1], array_points[i][2])) + f.write(f"{array_points[i][0]} {array_points[i][1]} {array_points[i][2]}\n") f.close() diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 7018bf0..c83ffa6 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -121,7 +121,7 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" mesh = mesh[:-(len(extension) + 1)] meshname = mesh.split("/")[-1] - outdir = "{}_surf".format(mesh) + outdir = f"{mesh}_surf" if not os.path.exists(outdir): os.makedirs(outdir) @@ -402,12 +402,12 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_{}.vtx'.format(r.name) + fname = outdir + f'/ids_{r.name}.vtx' if os.path.exists(fname): f = open(fname, 'a') else: f = open(fname, 'w') - f.write('{}\n'.format(len(id_vec))) + f.write(f'{len(id_vec)}\n') f.write('extra\n') if r.name == "MV": @@ -426,32 +426,32 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): RPV = RPV + list(id_vec) for i in id_vec: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() centroids[r.name] = r.center fname = outdir + '/ids_LAA.vtx' f = open(fname, 'w') - f.write('{}\n'.format(1)) + f.write(f'{1}\n') f.write('extra\n') - f.write('{}\n'.format(LAA_id)) + f.write(f'{LAA_id}\n') f.close() fname = outdir + '/ids_LPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(LPV))) + f.write(f'{len(LPV)}\n') f.write('extra\n') for i in LPV: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() fname = outdir + '/ids_RPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(RPV))) + f.write(f'{len(RPV)}\n') f.write('extra\n') for i in RPV: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() return b_tag, centroids @@ -480,10 +480,10 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): for r in rings: id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_{}.vtx'.format(r.name) + fname = outdir + f'/ids_{r.name}.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(id_vec))) + f.write(f'{len(id_vec)}\n') f.write('extra\n') if r.name == "TV": @@ -496,7 +496,7 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): b_tag[id_vec] = 9 for i in id_vec: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() @@ -504,9 +504,9 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): fname = outdir + '/ids_RAA.vtx' f = open(fname, 'w') - f.write('{}\n'.format(1)) + f.write(f'{1}\n') f.write('extra\n') - f.write('{}\n'.format(RAA_id)) + f.write(f'{RAA_id}\n') f.close() return b_tag, centroids, rings @@ -608,18 +608,18 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_MV_ant.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(MV_ant))) + f.write(f'{len(MV_ant)}\n') f.write('extra\n') for i in MV_ant: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() fname = outdir + '/ids_MV_post.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(MV_post))) + f.write(f'{len(MV_post)}\n') f.write('extra\n') for i in MV_post: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() loc = vtk.vtkPointLocator() @@ -651,10 +651,10 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_MV_LPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(mv_lpv))) + f.write(f'{len(mv_lpv)}\n') f.write('extra\n') for i in mv_lpv: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() path = vtk.vtkDijkstraGraphGeodesicPath() @@ -671,10 +671,10 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_MV_RPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(mv_rpv))) + f.write(f'{len(mv_rpv)}\n') f.write('extra\n') for i in mv_rpv: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() path = vtk.vtkDijkstraGraphGeodesicPath() @@ -691,10 +691,10 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): fname = outdir + '/ids_RPV_LPV.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(rpv_lpv))) + f.write(f'{len(rpv_lpv)}\n') f.write('extra\n') for i in rpv_lpv: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() @@ -834,10 +834,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): tv_f_ids = vtk.util.numpy_support.vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(tv_f_ids))) + f.write(f'{len(tv_f_ids)}\n') f.write('extra\n') for i in tv_f_ids: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() geo_filter2 = vtk.vtkGeometryFilter() @@ -848,10 +848,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): tv_s_ids = vtk.util.numpy_support.vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(tv_s_ids))) + f.write(f'{len(tv_s_ids)}\n') f.write('extra\n') for i in tv_s_ids: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() svc_points = svc.GetPoints().GetData() @@ -1039,10 +1039,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): top_epi = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_EPI.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(top_epi))) + f.write(f'{len(top_epi)}\n') f.write('extra\n') for i in top_epi: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() to_delete = np.zeros((len(pts_in_top_endo),), dtype=int) @@ -1103,10 +1103,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): top_endo = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(top_endo))) + f.write(f'{len(top_endo)}\n') f.write('extra\n') for i in top_endo: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py index 1ca6db3..609a266 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py @@ -37,49 +37,49 @@ def write_surf_ids(outdir, name, ii): - fname = outdir + '/ids_{}.vtx'.format(name) + fname = outdir + f'/ids_{name}.vtx' f = open(fname, 'w') if isinstance(ii, int): f.write('1\n') f.write('extra\n') - f.write('{}\n'.format(ii)) + f.write(f'{ii}\n') else: - f.write('{}\n'.format(len(ii))) + f.write(f'{len(ii)}\n') f.write('extra\n') for i in ii: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() def generate_surf_id(meshname, atrium): """The whole model""" - vol = smart_reader(meshname + "_{}_vol.vtk".format(atrium)) + vol = smart_reader(meshname + f"_{atrium}_vol.vtk") whole_model_points_coordinate = vtk.util.numpy_support.vtk_to_numpy(vol.GetPoints().GetData()) tree = cKDTree(whole_model_points_coordinate) epi_pts = vtk.util.numpy_support.vtk_to_numpy( - smart_reader(meshname + '_{}_epi.obj'.format(atrium)).GetPoints().GetData()) + smart_reader(meshname + f'_{atrium}_epi.obj').GetPoints().GetData()) dd, ii = tree.query(epi_pts) epi_ids = np.array(ii) - outdir = meshname + "_{}_vol_surf".format(atrium) + outdir = meshname + f"_{atrium}_vol_surf" if not os.path.exists(outdir): os.makedirs(outdir) - shutil.copyfile(meshname + "_{}_vol.vtk".format(atrium), outdir + '/{}.vtk'.format(atrium)) - shutil.copyfile(meshname + "_{}_epi_surf/rings_centroids.csv".format(atrium), outdir + '/rings_centroids.csv') + shutil.copyfile(meshname + f"_{atrium}_vol.vtk", outdir + f'/{atrium}.vtk') + shutil.copyfile(meshname + f"_{atrium}_epi_surf/rings_centroids.csv", outdir + '/rings_centroids.csv') write_surf_ids(outdir, "EPI", ii) dd, ii = tree.query(vtk.util.numpy_support.vtk_to_numpy( - smart_reader(meshname + '_{}_endo.obj'.format(atrium)).GetPoints().GetData())) + smart_reader(meshname + f'_{atrium}_endo.obj').GetPoints().GetData())) ii = np.setdiff1d(ii, epi_ids) write_surf_ids(outdir, "ENDO", ii) - fol_name = meshname + '_{}_epi_surf'.format(atrium) + fol_name = meshname + f'_{atrium}_epi_surf' ids_files = glob(fol_name + '/ids_*') diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index 63d9180..c8931e1 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -42,7 +42,7 @@ def separate_epi_endo(path, atrium): geo_filter.Update() writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname + "_{}.obj".format(atrium)) + writer.SetFileName(meshname + f"_{atrium}.obj") writer.SetInputData(geo_filter.GetOutput()) writer.Write() @@ -61,7 +61,7 @@ def separate_epi_endo(path, atrium): la_epi = geo_filter.GetOutput() writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname + "_{}_epi.obj".format(atrium)) + writer.SetFileName(meshname + f"_{atrium}_epi.obj") writer.SetInputData(la_epi) writer.Write() @@ -80,6 +80,6 @@ def separate_epi_endo(path, atrium): la_endo = geo_filter.GetOutput() writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname + "_{}_endo.obj".format(atrium)) + writer.SetFileName(meshname + f"_{atrium}_endo.obj") writer.SetInputData(la_endo) writer.Write() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index ac50213..fff3b83 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -246,18 +246,18 @@ def write_bilayer(bilayer, args, job): pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_bilayer_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) with open(job.ID + '/result_LA/LA_bilayer_with_fiber.elem', "w") as f: - f.write("{}\n".format(bilayer.GetNumberOfCells())) + f.write(f"{bilayer.GetNumberOfCells()}\n") for i in range(bilayer.GetNumberOfCells()): cell = bilayer.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) @@ -877,7 +877,7 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): writer = vtk.vtkUnstructuredGridWriter() writer.SetFileName( - "{}_with_data.vtk".format(mesh2_name.split('.vtk')[0])) # It can happen that the relative directory is given + f"{mesh2_name.split('.vtk')[0]}_with_data.vtk") # It can happen that the relative directory is given writer.SetFileTypeToBinary() writer.SetInputData(meshNew.VTKObject) writer.Write() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py b/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py index d3de781..9c5376e 100755 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py @@ -60,7 +60,7 @@ def parser(): def jobID(args): - ID = '{}_fibers'.format(args.mesh1.split('/')[-1]) + ID = f"{args.mesh1.split('/')[-1]}_fibers" return ID diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py index 2137b55..126253a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py @@ -80,9 +80,9 @@ def la_calculate_gradient(args, model, job): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") # write the file as vtk writer = vtk.vtkUnstructuredGridWriter() writer.SetFileName(simid + "/LA_with_lp_res_gradient.vtk") diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index ba9b032..61bd2e9 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -48,9 +48,9 @@ def la_generate_fiber(model, args, job): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") with open(os.path.join(EXAMPLE_DIR, '../../element_tag.csv')) as f: tag_dict = {} @@ -408,23 +408,23 @@ def la_generate_fiber(model, args, job): LAA_bb_ids = vtk.util.numpy_support.vtk_to_numpy(LAA_bb.GetPointData().GetArray('Global_ids')) - MV_ring_ids = np.loadtxt('{}_surf/ids_MV.vtx'.format(args.mesh), skiprows=2, dtype=int) + MV_ring_ids = np.loadtxt(f'{args.mesh}_surf/ids_MV.vtx', skiprows=2, dtype=int) LAA_bb_ids = np.append(LAA_bb_ids, MV_ring_ids) - fname = '{}_surf/ids_LAA_bb.vtx'.format(args.mesh) + fname = f'{args.mesh}_surf/ids_LAA_bb.vtx' f = open(fname, 'w') - f.write('{}\n'.format(len(LAA_bb_ids))) + f.write(f'{len(LAA_bb_ids)}\n') f.write('extra\n') for i in LAA_bb_ids: - f.write('{}\n'.format(i)) + f.write(f'{i}\n') f.close() LAA_s = laplace_0_1(args, job, model, "LAA", "LAA_bb", "phie_ab3") LAA_s = Method.vtk_thr(LAA_s, 1, "POINTS", "phie_ab3", 0.95) - ring_ids = np.loadtxt('{}_surf/'.format(args.mesh) + 'ids_MV.vtx', skiprows=2, dtype=int) + ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_MV.vtx', skiprows=2, dtype=int) rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] @@ -614,17 +614,17 @@ def la_generate_fiber(model, args, job): pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_endo_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") with open(job.ID + '/result_LA/LA_endo_with_fiber.elem', "w") as f: - f.write("{}\n".format(endo.GetNumberOfCells())) + f.write(f"{endo.GetNumberOfCells()}\n") for i in range(endo.GetNumberOfCells()): cell = endo.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write( - "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_endo[i])) + f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_endo[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_endo[i])) @@ -826,17 +826,17 @@ def la_generate_fiber(model, args, job): pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_epi_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") with open(job.ID + '/result_LA/LA_epi_with_fiber.elem', "w") as f: - f.write("{}\n".format(epi.GetNumberOfCells())) + f.write(f"{epi.GetNumberOfCells()}\n") for i in range(epi.GetNumberOfCells()): cell = epi.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write( - "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) @@ -894,16 +894,16 @@ def la_generate_fiber(model, args, job): pts = numpy_support.vtk_to_numpy(model.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_vol_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") with open(job.ID + '/result_LA/LA_vol_with_fiber.elem', "w") as f: - f.write("{}\n".format(model.GetNumberOfCells())) + f.write(f"{model.GetNumberOfCells()}\n") for i in range(model.GetNumberOfCells()): cell = model.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag[i])) + f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag[i])) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py index c3da5e1..4f881b9 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py @@ -41,7 +41,7 @@ def la_laplace(args, job, model): meshdir = args.mesh + '_surf/LA' - surfdir = '{}_surf/'.format(args.mesh) + surfdir = f'{args.mesh}_surf/' parfdir = os.path.join(EXAMPLE_DIR, 'Parfiles') if args.mesh_type == 'vol': @@ -135,9 +135,9 @@ def la_laplace(args, job, model): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") if args.mesh_type == "vol": writer = vtk.vtkXMLUnstructuredGridWriter() writer.SetFileName(simid + "/LA_with_laplace.vtu") @@ -156,7 +156,7 @@ def la_laplace(args, job, model): def laplace_0_1(args, job, model, name1, name2, outname): meshdir = args.mesh + '_surf/LA' - surfdir = '{}_surf/'.format(args.mesh) + surfdir = f'{args.mesh}_surf/' parfdir = os.path.join(EXAMPLE_DIR, 'Parfiles') ##################################### # Solver for the ab laplace solution @@ -165,8 +165,8 @@ def laplace_0_1(args, job, model, name1, name2, outname): simid = job.ID + '/Lp_ab' cmd += ['-simID', simid, '-meshname', meshdir, - '-stimulus[0].vtx_file', surfdir + 'ids_{}'.format(name1), - '-stimulus[1].vtx_file', surfdir + 'ids_{}'.format(name2)] + '-stimulus[0].vtx_file', surfdir + f'ids_{name1}', + '-stimulus[1].vtx_file', surfdir + f'ids_{name2}'] if name1 == "4": cmd = tools.carp_cmd(parfdir + '/la_lps_phi_0_1_4.par') @@ -190,9 +190,9 @@ def laplace_0_1(args, job, model, name1, name2, outname): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") writer = vtk.vtkXMLUnstructuredGridWriter() writer.SetFileName(simid + "/LA_with_laplace.vtu") diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py index 3402426..e436bbf 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py @@ -76,7 +76,7 @@ def parser(): def jobID(args): - ID = '{}_fibers'.format(args.mesh) + ID = f'{args.mesh}_fibers' return ID @@ -105,16 +105,16 @@ def run(args, job): pts = numpy_support.vtk_to_numpy(LA.GetPoints().GetData()) with open(LA_mesh + '.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") with open(LA_mesh + '.elem', "w") as f: - f.write("{}\n".format(LA.GetNumberOfCells())) + f.write(f"{LA.GetNumberOfCells()}\n") for i in range(LA.GetNumberOfCells()): cell = LA.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), 1)) + f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {1}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), 1)) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 464c9b2..b115f5a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -219,18 +219,18 @@ def write_bilayer(args, job): pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.elem', "w") as f: - f.write("{}\n".format(bilayer.GetNumberOfCells())) + f.write(f"{bilayer.GetNumberOfCells()}\n") for i in range(bilayer.GetNumberOfCells()): cell = bilayer.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) @@ -520,7 +520,7 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point band = cln.GetOutput() if args.debug: - writer_vtk(band, '{}_surf/'.format(args.mesh) + "band_" + str(StartVertex) + "_" + str(EndVertex) + ".vtk") + writer_vtk(band, f'{args.mesh}_surf/' + "band_" + str(StartVertex) + "_" + str(EndVertex) + ".vtk") loc = vtk.vtkPointLocator() loc.SetDataSet(band) @@ -1154,10 +1154,10 @@ def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): def create_pts(array_points, array_name, mesh_dir): - f = open("{}{}.pts".format(mesh_dir, array_name), "w") + f = open(f"{mesh_dir}{array_name}.pts", "w") f.write("0 0 0\n") for i in range(len(array_points)): - f.write("{} {} {}\n".format(array_points[i][0], array_points[i][1], array_points[i][2])) + f.write(f"{array_points[i][0]} {array_points[i][1]} {array_points[i][2]}\n") f.close() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index a808f01..6b0fa65 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -98,7 +98,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): SVC_IVC_septum_path = Method.dijkstra_path_coord(ra_epi_surface, point_septum_SVC, point_septum_IVC) if args.debug: - Method.create_pts(SVC_IVC_septum_path, 'SVC_IVC_septum_path', '{}_surf/'.format(args.mesh)) + Method.create_pts(SVC_IVC_septum_path, 'SVC_IVC_septum_path', f'{args.mesh}_surf/') middle_posterior_bridge_point = SVC_IVC_septum_path[int(len(SVC_IVC_septum_path) * 0.6), :] # Can happen that the 0.6 is where the BB is @@ -792,19 +792,19 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', "w") as f: - f.write("{}\n".format(epi.GetNumberOfCells())) + f.write(f"{epi.GetNumberOfCells()}\n") for i in range(epi.GetNumberOfCells()): cell = epi.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write( - "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 5d2c568..f3371d4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -75,7 +75,7 @@ def parser(): def jobID(args): - ID = '{}_fibers'.format(args.mesh) + ID = f'{args.mesh}_fibers' return ID @@ -669,19 +669,19 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', "w") as f: - f.write("{}\n".format(epi.GetNumberOfCells())) + f.write(f"{epi.GetNumberOfCells()}\n") for i in range(epi.GetNumberOfCells()): cell = epi.GetCell(i) if cell.GetNumberOfPoints() == 2: f.write( - "Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index 8d6cff2..c09fa5a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -168,18 +168,18 @@ def write_bilayer(bilayer): pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) with open(args.mesh + '/RA_bilayer_with_fiber.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) with open(args.mesh + '/RA_bilayer_with_fiber.elem', "w") as f: - f.write("{}\n".format(bilayer.GetNumberOfCells())) + f.write(f"{bilayer.GetNumberOfCells()}\n") for i in range(bilayer.GetNumberOfCells()): cell = bilayer.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_epi[i])) + f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_epi[i])) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py index d8d8eb7..ccee8d4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py @@ -80,9 +80,9 @@ def ra_calculate_gradient(args, model, job): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") # write the file as vtk writer = vtk.vtkXMLUnstructuredGridWriter() writer.SetFileName(simid + "/RA_with_lp_res_gradient.vtu") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 78ea2e5..ede3a6b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -48,17 +48,17 @@ def ra_generate_fiber(model, args, job): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") simid = job.ID + "/bridges" try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") # Riunet tao_tv = 0.9 @@ -184,12 +184,12 @@ def ra_generate_fiber(model, args, job): # Use fixed thickness - ring_ids = np.loadtxt('{}_surf/'.format(args.mesh) + 'ids_TV.vtx', skiprows=2, dtype=int) + ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_TV.vtx', skiprows=2, dtype=int) rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] if args.debug: - Method.create_pts(rings_pts, 'TV_ring', '{}_surf/'.format(args.mesh)) + Method.create_pts(rings_pts, 'TV_ring', f'{args.mesh}_surf/') TV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) @@ -220,8 +220,8 @@ def ra_generate_fiber(model, args, job): # To check if TV was correctly identified if args.debug: - Method.writer_vtk(TV_s, '{}_surf/'.format(args.mesh) + "tv_s.vtk") - Method.writer_vtk(no_TV_s, '{}_surf/'.format(args.mesh) + "no_tv_s.vtk") + Method.writer_vtk(TV_s, f'{args.mesh}_surf/' + "tv_s.vtk") + Method.writer_vtk(no_TV_s, f'{args.mesh}_surf/' + "no_tv_s.vtk") # del ra_TV, ra_diff, ra_no_TV @@ -244,11 +244,11 @@ def ra_generate_fiber(model, args, job): SVC_s = Method.extract_largest_region(SVC_s) if args.debug: # CHECK - Method.writer_vtk(IVC_s, '{}_surf/'.format(args.mesh) + "ivc_s.vtk") - Method.writer_vtk(no_IVC_s, '{}_surf/'.format(args.mesh) + "no_ivc_s.vtk") - Method.writer_vtk(SVC_s, '{}_surf/'.format(args.mesh) + "svc_s.vtk") - Method.writer_vtk(no_SVC_s, '{}_surf/'.format(args.mesh) + "no_svc_s.vtk") - Method.writer_vtk(RAW_s, '{}_surf/'.format(args.mesh) + "raw_s.vtk") + Method.writer_vtk(IVC_s, f'{args.mesh}_surf/' + "ivc_s.vtk") + Method.writer_vtk(no_IVC_s, f'{args.mesh}_surf/' + "no_ivc_s.vtk") + Method.writer_vtk(SVC_s, f'{args.mesh}_surf/' + "svc_s.vtk") + Method.writer_vtk(no_SVC_s, f'{args.mesh}_surf/' + "no_svc_s.vtk") + Method.writer_vtk(RAW_s, f'{args.mesh}_surf/' + "raw_s.vtk") tao_ct_plus = np.min(vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetCellData().GetArray('phie_w'))) @@ -275,8 +275,8 @@ def ra_generate_fiber(model, args, job): CT_ub = Method.extract_largest_region(CT_ub) if args.debug: - Method.writer_vtk(CT_band, '{}_surf/'.format(args.mesh) + "ct_band.vtk") - Method.writer_vtk(CT_ub, '{}_surf/'.format(args.mesh) + "ct_ub.vtk") + Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band.vtk") + Method.writer_vtk(CT_ub, f'{args.mesh}_surf/' + "ct_ub.vtk") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(CT_band) @@ -318,7 +318,7 @@ def ra_generate_fiber(model, args, job): # IVC_max_r_CT_pt = CT_band.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetPointData().GetArray('phie_r')))) # optional choice for pm, be careful as it overwrites if args.debug: - Method.writer_vtk(CT_band, '{}_surf/'.format(args.mesh) + "ct_band_2.vtk") + Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band_2.vtk") CT_band_ids = vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) @@ -396,9 +396,9 @@ def ra_generate_fiber(model, args, job): tag[IB_ids] = inter_caval_bundle_epi # Change to 68 if args.debug: - Method.writer_vtk(IB, '{}_surf/'.format(args.mesh) + "ib.vtk") - Method.writer_vtk(RAW_S, '{}_surf/'.format(args.mesh) + "raw_s.vtk") - Method.writer_vtk(CT_plus, '{}_surf/'.format(args.mesh) + "ct_plus.vtk") + Method.writer_vtk(IB, f'{args.mesh}_surf/' + "ib.vtk") + Method.writer_vtk(RAW_S, f'{args.mesh}_surf/' + "raw_s.vtk") + Method.writer_vtk(CT_plus, f'{args.mesh}_surf/' + "ct_plus.vtk") k[IB_ids] = v_grad[IB_ids] @@ -427,8 +427,8 @@ def ra_generate_fiber(model, args, job): RAS_S = Method.vtk_thr(RAS_S, 0, "CELLS", "phie_r", 0.05) # grad_r or w if args.debug: - Method.writer_vtk(septal_surf, '{}_surf/'.format(args.mesh) + "septal_surf.vtk") - Method.writer_vtk(RAS_S, '{}_surf/'.format(args.mesh) + "ras_s.vtk") + Method.writer_vtk(septal_surf, f'{args.mesh}_surf/' + "septal_surf.vtk") + Method.writer_vtk(RAS_S, f'{args.mesh}_surf/' + "ras_s.vtk") RAS_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAS_S.GetCellData().GetArray('Global_ids')) @@ -480,12 +480,12 @@ def ra_generate_fiber(model, args, job): septal_surf = meshExtractFilter.GetOutput() if args.debug: - Method.writer_vtk(septal_surf, '{}_surf/'.format(args.mesh) + "septal_surf_2.vtk") + Method.writer_vtk(septal_surf, f'{args.mesh}_surf/' + "septal_surf_2.vtk") CS_ids = vtk.util.numpy_support.vtk_to_numpy(septal_surf.GetCellData().GetArray('Global_ids')) # if len(CS_ids) == 0: - ring_ids = np.loadtxt('{}_surf/'.format(args.mesh) + 'ids_CS.vtx', skiprows=2, dtype=int) + ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_CS.vtx', skiprows=2, dtype=int) rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] @@ -498,9 +498,9 @@ def ra_generate_fiber(model, args, job): RAA_s = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_v2", tao_RAA) if args.debug: - Method.writer_vtk(RAS_low, '{}_surf/'.format(args.mesh) + "ras_low.vtk") - Method.writer_vtk(RAA_s, '{}_surf/'.format(args.mesh) + "raa_s.vtk") # Check here if RAA is correctly tagged - Method.writer_vtk(RAW_low, '{}_surf/'.format(args.mesh) + "raw_low.vtk") + Method.writer_vtk(RAS_low, f'{args.mesh}_surf/' + "ras_low.vtk") + Method.writer_vtk(RAA_s, f'{args.mesh}_surf/' + "raa_s.vtk") # Check here if RAA is correctly tagged + Method.writer_vtk(RAW_low, f'{args.mesh}_surf/' + "raw_low.vtk") RAA_ids = vtk.util.numpy_support.vtk_to_numpy(RAA_s.GetCellData().GetArray('Global_ids')) @@ -886,7 +886,7 @@ def ra_generate_fiber(model, args, job): TV_lat = cln.GetOutput() if args.debug: - Method.writer_vtk(TV_lat, '{}_surf/'.format(args.mesh) + "TV_lat.vtk") + Method.writer_vtk(TV_lat, f'{args.mesh}_surf/' + "TV_lat.vtk") # writer = vtk.vtkPolyDataWriter() # writer.SetFileName("TV_lat.vtk") @@ -898,7 +898,7 @@ def ra_generate_fiber(model, args, job): # np.savetxt("ct_points_data.txt", ct_points_data, fmt='%.4f') if args.debug: - Method.create_pts(ct_points_data, 'ct_points_data', '{}_surf/'.format(args.mesh)) + Method.create_pts(ct_points_data, 'ct_points_data', f'{args.mesh}_surf/') loc = vtk.vtkPointLocator() loc.SetDataSet(TV_lat) @@ -911,7 +911,7 @@ def ra_generate_fiber(model, args, job): tv_points_data = Method.dijkstra_path(TV_lat, point3_id, point4_id) if args.debug: - Method.create_pts(tv_points_data, 'tv_points_data', '{}_surf/'.format(args.mesh)) + Method.create_pts(tv_points_data, 'tv_points_data', f'{args.mesh}_surf/') # np.savetxt("tv_points_data.txt", tv_points_data, fmt='%.4f') # np.savetxt("point3_id_new.txt", TV_lat.GetPoint(point3_id), fmt='%.4f') @@ -1153,7 +1153,7 @@ def ra_generate_fiber(model, args, job): pm = Method.downsample_path(pm, int(len(pm) * 0.1)) if args.debug: - Method.create_pts(pm, 'pm_0_downsampled', '{}_surf/'.format(args.mesh)) + Method.create_pts(pm, 'pm_0_downsampled', f'{args.mesh}_surf/') if args.mesh_type == "bilayer": @@ -1188,7 +1188,7 @@ def ra_generate_fiber(model, args, job): pm = Method.downsample_path(pm, int(len(pm) * 0.065)) if args.debug: - Method.create_pts(pm, 'pm_' + str(i + 1) + '_downsampled', '{}_surf/'.format(args.mesh)) + Method.create_pts(pm, 'pm_' + str(i + 1) + '_downsampled', f'{args.mesh}_surf/') print("The ", i + 1, "th pm done") if args.mesh_type == "bilayer": diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py index 33eb297..47009cd 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py @@ -36,7 +36,7 @@ def ra_laplace(args, job, model): meshdir = args.mesh + '_surf/RA' - surfdir = '{}_surf/'.format(args.mesh) + surfdir = f'{args.mesh}_surf/' parfdir = os.path.join(EXAMPLE_DIR, 'Parfiles') if args.mesh_type == 'vol': @@ -156,9 +156,9 @@ def ra_laplace(args, job, model): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") if args.mesh_type == "vol": writer = vtk.vtkXMLUnstructuredGridWriter() writer.SetFileName(simid + "/RA_with_laplace.vtu") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index f5c7380..3fae5bf 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -88,7 +88,7 @@ def parser(): def jobID(args): - ID = '{}_fibers'.format(args.mesh) + ID = f'{args.mesh}_fibers' return ID @@ -118,16 +118,16 @@ def run(args, job): # cells = cells.reshape(int(len(cells)/4),4)[:,1:] with open(RA_mesh + '.pts', "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") with open(RA_mesh + '.elem', "w") as f: - f.write("{}\n".format(RA.GetNumberOfCells())) + f.write(f"{RA.GetNumberOfCells()}\n") for i in range(RA.GetNumberOfCells()): cell = RA.GetCell(i) if cell.GetNumberOfPoints() == 2: - f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), 1)) + f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {1}\n") elif cell.GetNumberOfPoints() == 3: f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), 1)) diff --git a/pipeline.py b/pipeline.py index bb701fa..18c6dd0 100644 --- a/pipeline.py +++ b/pipeline.py @@ -84,7 +84,7 @@ def AugmentA(args): if args.closed_surface: separate_epi_endo(args.mesh, args.atrium) meshname_old = str(meshname) - meshname = meshname_old + "_{}_epi".format(args.atrium) + meshname = meshname_old + f"_{args.atrium}_epi" else: if args.open_orifices: @@ -160,7 +160,7 @@ def AugmentA(args): mesh_data["RAA_id"] = [apex_id] - fname = '{}_mesh_data.csv'.format(meshname) + fname = f'{meshname}_mesh_data.csv' df = pd.DataFrame(mesh_data) df.to_csv(fname, float_format="%.2f", index=False) @@ -215,7 +215,7 @@ def AugmentA(args): processed_mesh = mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit' # Label atrial orifices using apex id found in the resampling algorithm - df = pd.read_csv('{}_mesh_data.csv'.format(mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit')) + df = pd.read_csv(f"{mesh_dir + args.atrium + '_cutted_surf/' + args.atrium + '_fit'}_mesh_data.csv") if args.atrium == "LA": label_atrial_orifices(processed_mesh + 'obj', LAA_id=int(df[args.atrium + "A_id"])) # Atrial region annotation and fiber generation using LDRBM @@ -236,20 +236,20 @@ def AugmentA(args): # Make sure there is an .obj mesh file # Convert mesh from vtk to obj - meshin = pv.read('{}.vtk'.format(meshname)) - pv.save_meshio('{}.obj'.format(meshname), meshin, "obj") + meshin = pv.read(f'{meshname}.vtk') + pv.save_meshio(f'{meshname}.obj', meshin, "obj") # if args.atrium =='LA_RA': apex_id = -1 # Find new location with resampled mesh # Here finds the LAA_id and/or RAA_id for the remeshed geometry - resample_surf_mesh('{}'.format(meshname), target_mesh_resolution=args.target_mesh_resolution, + resample_surf_mesh(f'{meshname}', target_mesh_resolution=args.target_mesh_resolution, find_apex_with_curv=0, scale=args.scale, apex_id=apex_id, atrium=args.atrium) - processed_mesh = '{}_res'.format(meshname) + processed_mesh = f'{meshname}_res' # Convert mesh from ply to obj - meshin = pv.read('{}.ply'.format(processed_mesh)) - pv.save_meshio('{}.obj'.format(processed_mesh), meshin, "obj") + meshin = pv.read(f'{processed_mesh}.ply') + pv.save_meshio(f'{processed_mesh}.obj', meshin, "obj") # p = pv.Plotter(notebook=False) # @@ -298,12 +298,12 @@ def AugmentA(args): # meshin = pv.read('{}.obj'.format(meshname)) # Label atrial orifices using apex id found in the resampling algorithm - df = pd.read_csv('{}_mesh_data.csv'.format(processed_mesh)) + df = pd.read_csv(f'{processed_mesh}_mesh_data.csv') if args.atrium == "LA_RA": if not os.path.exists(processed_mesh + '.obj'): - meshin = pv.read('{}.vtk'.format(processed_mesh)) - pv.save_meshio('{}.obj'.format(processed_mesh), meshin, "obj") + meshin = pv.read(f'{processed_mesh}.vtk') + pv.save_meshio(f'{processed_mesh}.obj', meshin, "obj") label_atrial_orifices(processed_mesh + '.obj', LAA_id=int(df["LAA_id"]), RAA_id=int(df["RAA_id"])) # Label both @@ -326,9 +326,9 @@ def AugmentA(args): label_atrial_orifices(processed_mesh + '.obj', LAA_id=int(df[args.atrium + "A_id"])) # Atrial region annotation and fiber generation using LDRBM if args.closed_surface: - generate_mesh(meshname_old + '_{}'.format(args.atrium)) + generate_mesh(meshname_old + f'_{args.atrium}') generate_surf_id(meshname_old, args.atrium) - processed_mesh = meshname_old + "_{}_vol".format(args.atrium) + processed_mesh = meshname_old + f"_{args.atrium}_vol" la_main.run( ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) @@ -348,9 +348,9 @@ def AugmentA(args): # Atrial region annotation and fiber generation using LDRBM if args.closed_surface: label_atrial_orifices_TOP_epi_endo(processed_mesh + '.obj', RAA_id=int(df[args.atrium + "A_id"])) - generate_mesh(meshname_old + '_{}'.format(args.atrium)) + generate_mesh(meshname_old + f'_{args.atrium}') generate_surf_id(meshname_old, args.atrium) - processed_mesh = meshname_old + "_{}_vol".format(args.atrium) + processed_mesh = meshname_old + f"_{args.atrium}_vol" ra_main.run( ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) @@ -363,7 +363,7 @@ def AugmentA(args): if args.debug: if args.closed_surface: bil = pv.read( - '{}_fibers/result_{}/{}_vol_with_fiber.{}'.format(processed_mesh, args.atrium, args.atrium, args.ofmt)) + f'{processed_mesh}_fibers/result_{args.atrium}/{args.atrium}_vol_with_fiber.{args.ofmt}') else: if args.atrium == 'LA_RA': bil = pv.read( diff --git a/standalones/getmarks.py b/standalones/getmarks.py index 0c141e1..b97c024 100644 --- a/standalones/getmarks.py +++ b/standalones/getmarks.py @@ -56,7 +56,7 @@ def parser(): def get_landmarks(mesh, prealigned=1, scale=1): - mesh_dir = "{}_surf".format(mesh) + mesh_dir = f"{mesh}_surf" reader = vtk.vtkPolyDataReader() if prealigned: reader.SetFileName(mesh_dir + '/LA_prealigned.vtk') @@ -326,18 +326,18 @@ def get_landmarks(mesh, prealigned=1, scale=1): json2 = '[' for i in range(len(name_lst)): - json2 = json2 + "{\"id\":\"" + "{}".format(name_lst[i]) + "\",\"coordinates\":[" + "{},{},{}".format( + json2 = json2 + "{\"id\":\"" + f"{name_lst[i]}" + "\",\"coordinates\":[" + "{},{},{}".format( coord_lst[i][0], coord_lst[i][1], coord_lst[i][2]) + "]}," json2 = json2[:-1] + ']' - f = open("{}/landmarks.json".format(mesh_dir), "w") + f = open(f"{mesh_dir}/landmarks.json", "w") f.write(json2) f.close() # txt file to open in Paraview to check - f = open("{}/landmarks.txt".format(mesh_dir), "w") + f = open(f"{mesh_dir}/landmarks.txt", "w") for i in range(len(name_lst)): - f.write("{} {} {} {}\n".format(coord_lst[i][0], coord_lst[i][1], coord_lst[i][2], name_lst[i])) + f.write(f"{coord_lst[i][0]} {coord_lst[i][1]} {coord_lst[i][2]} {name_lst[i]}\n") def run(): diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 068c9cc..400781b 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -110,12 +110,12 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ meshin = pv.read(meshpath) meshfix = pymeshfix.MeshFix(meshin) meshfix.repair() - meshfix.mesh.save("{}/{}_clean.vtk".format(full_path, atrium)) - pv.save_meshio("{}/{}_clean.obj".format(full_path, atrium), meshfix.mesh, "obj") + meshfix.mesh.save(f"{full_path}/{atrium}_clean.vtk") + pv.save_meshio(f"{full_path}/{atrium}_clean.obj", meshfix.mesh, "obj") mesh_with_data = smart_reader(meshpath) - mesh_clean = smart_reader("{}/{}_clean.vtk".format(full_path, atrium)) + mesh_clean = smart_reader(f"{full_path}/{atrium}_clean.vtk") # Map point data to cleaned mesh mesh = point_array_mapper(mesh_with_data, mesh_clean, "all") @@ -131,7 +131,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ while picked_pt is None: p = pv.Plotter(notebook=False) p.add_mesh(meshfix.mesh, 'r') - p.add_text('Select the center of the {} and close the window to cut, otherwise just close'.format(r), + p.add_text(f'Select the center of the {r} and close the window to cut, otherwise just close', position='lower_left') p.enable_point_picking(meshfix.mesh, use_mesh=True) p.show() @@ -168,12 +168,12 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ model = extract_largest_region(mesh) writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName("{}/{}_cutted.vtk".format(full_path, atrium)) + writer.SetFileName(f"{full_path}/{atrium}_cutted.vtk") writer.SetInputData(model) writer.Write() p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData("{}/{}_cutted.vtk".format(full_path, atrium)) + mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") p.add_mesh(mesh_from_vtk, 'r') p.add_text('Select the atrial appendage apex', position='lower_left') p.enable_point_picking(meshfix.mesh, use_mesh=True) @@ -184,7 +184,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ apex = p.picked_point p.close() - model = smart_reader("{}/{}_cutted.vtk".format(full_path, atrium)) + model = smart_reader(f"{full_path}/{atrium}_cutted.vtk") loc = vtk.vtkPointLocator() loc.SetDataSet(model) loc.BuildLocator() @@ -194,7 +194,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ elif atrium == "RA": RAA = apex_id - meshpath = "{}/{}_cutted".format(full_path, atrium) + meshpath = f"{full_path}/{atrium}_cutted" extract_rings.run(["--mesh", meshpath, "--LAA", str(LAA), "--RAA", str(RAA)]) return apex_id diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index b7a2ed0..833fb27 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -106,19 +106,19 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu meshin = pv.read(meshpath) meshfix = pymeshfix.MeshFix(meshin) meshfix.repair() - meshfix.mesh.save("{}/{}_clean.vtk".format(full_path, atrium)) - pv.save_meshio("{}/{}_clean.obj".format(full_path, atrium), meshfix.mesh, "obj") + meshfix.mesh.save(f"{full_path}/{atrium}_clean.vtk") + pv.save_meshio(f"{full_path}/{atrium}_clean.obj", meshfix.mesh, "obj") # Compute surface curvature - os.system("meshtool query curvature -msh={}/{}_clean.obj -size={}".format(full_path, atrium, size * scale)) + os.system(f"meshtool query curvature -msh={full_path}/{atrium}_clean.obj -size={size * scale}") # Verify if the mesh curvature is not nan mesh_with_data = smart_reader(meshpath) - curv = np.loadtxt('{}/{}_clean.curv.dat'.format(full_path, atrium)) + curv = np.loadtxt(f'{full_path}/{atrium}_clean.curv.dat') - mesh_clean = smart_reader("{}/{}_clean.vtk".format(full_path, atrium)) + mesh_clean = smart_reader(f"{full_path}/{atrium}_clean.vtk") # Map point data to cleaned mesh mesh = point_array_mapper(mesh_with_data, mesh_clean, "all") @@ -131,7 +131,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu if debug: writer = vtk.vtkPolyDataWriter() - writer.SetFileName("{}/{}_clean_with_curv.vtk".format(full_path, atrium)) + writer.SetFileName(f"{full_path}/{atrium}_clean_with_curv.vtk") writer.SetInputData(model) writer.Write() @@ -155,7 +155,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu max_dist = np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) if max_dist > max_cutting_radius * 2: - print("Valve bigger than {} cm".format(max_cutting_radius * 2)) + print(f"Valve bigger than {max_cutting_radius * 2} cm") el_to_del_tot = find_elements_within_radius(model, valve_center, max_cutting_radius) model_new_el = vtk.vtkIdList() @@ -185,7 +185,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve = extract_largest_region(valve) if debug and atrium == 'RA': - writer_vtk(valve, "{}/{}_clean_with_curv_".format(full_path, atrium) + "valve.vtk") + writer_vtk(valve, f"{full_path}/{atrium}_clean_with_curv_" + "valve.vtk") centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(valve) @@ -240,7 +240,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model = cellid.GetOutput() writer = vtk.vtkPolyDataWriter() - writer.SetFileName("{}/{}_curv.vtk".format(full_path, atrium)) + writer.SetFileName(f"{full_path}/{atrium}_curv.vtk") writer.SetInputData(model) writer.SetFileTypeToBinary() writer.Write() @@ -260,7 +260,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu high_c = vtk_thr(model, 0, "POINTS", "curv", np.median(curv) * 1.15) # (np.min(curv)+np.max(curv))/2) writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName("{}/{}_h_curv.vtk".format(full_path, atrium)) + writer.SetFileName(f"{full_path}/{atrium}_h_curv.vtk") writer.SetInputData(high_c) writer.SetFileTypeToBinary() writer.Write() @@ -304,7 +304,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu else: transeptal_punture_id = -1 p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData("{}/{}_clean.vtk".format(full_path, atrium)) + mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_clean.vtk") p.add_mesh(mesh_from_vtk, 'r') p.add_text('Select the transeptal punture and close the window', position='lower_left') p.enable_point_picking(meshfix.mesh, use_mesh=True) @@ -447,7 +447,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model = extract_largest_region(model) writer = vtk.vtkPolyDataWriter() - writer.SetFileName("{}/{}_cutted.vtk".format(full_path, atrium)) + writer.SetFileName(f"{full_path}/{atrium}_cutted.vtk") writer.SetInputData(model) writer.Write() @@ -456,7 +456,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu point_cloud = pv.PolyData(apex) p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData("{}/{}_cutted.vtk".format(full_path, atrium)) + mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") p.add_mesh(mesh_from_vtk, 'r') p.add_mesh(point_cloud, color='w', point_size=30., render_points_as_spheres=True) p.enable_point_picking(meshfix.mesh, use_mesh=True) @@ -468,7 +468,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p.close() else: p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData("{}/{}_cutted.vtk".format(full_path, atrium)) + mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") p.add_mesh(mesh_from_vtk, 'r') p.enable_point_picking(meshfix.mesh, use_mesh=True) p.add_text('Select the appendage apex and close the window', position='lower_left') @@ -478,7 +478,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu apex = p.picked_point p.close() - model = smart_reader("{}/{}_cutted.vtk".format(full_path, atrium)) + model = smart_reader(f"{full_path}/{atrium}_cutted.vtk") loc = vtk.vtkPointLocator() loc.SetDataSet(model) loc.BuildLocator() @@ -488,7 +488,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu elif atrium == "RA": RAA = apex_id - label_atrial_orifices("{}/{}_cutted.vtk".format(full_path, atrium), LAA, RAA) + label_atrial_orifices(f"{full_path}/{atrium}_cutted.vtk", LAA, RAA) return apex_id @@ -634,10 +634,10 @@ def point_array_mapper(mesh1, mesh2, idat): def create_pts(array_points, array_name, mesh_dir): - f = open("{}{}.pts".format(mesh_dir, array_name), "w") + f = open(f"{mesh_dir}{array_name}.pts", "w") f.write("0 0 0\n") for i in range(len(array_points)): - f.write("{} {} {}\n".format(array_points[i][0], array_points[i][1], array_points[i][2])) + f.write(f"{array_points[i][0]} {array_points[i][1]} {array_points[i][2]}\n") f.close() diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index 8c9c87b..8793b1d 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -63,8 +63,8 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): # Landmarks to use to prealign both meshes if case == "both": names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV", "TV", "SVC", "IVC"] - meshLA = vtkreader("{}_surf/LA_boundaries_tagged".format(mesh1_name)) - meshRA = vtkreader("{}_surf/RA_boundaries_tagged".format(mesh1_name)) + meshLA = vtkreader(f"{mesh1_name}_surf/LA_boundaries_tagged") + meshRA = vtkreader(f"{mesh1_name}_surf/RA_boundaries_tagged") appendFilter = vtk.vtkAppendFilter() appendFilter.AddInputData(meshLA) appendFilter.AddInputData(meshRA) @@ -77,16 +77,16 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): elif case == "LA": names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV"] # Prealign MRI - mesh1 = vtkreader("{}_surf/LA_boundaries_tagged".format(mesh1_name)) + mesh1 = vtkreader(f"{mesh1_name}_surf/LA_boundaries_tagged") else: names = ["TV", "SVC", "IVC"] - mesh1 = vtkreader("{}_surf/RA_boundaries_tagged".format(mesh1_name)) + mesh1 = vtkreader(f"{mesh1_name}_surf/RA_boundaries_tagged") - df_tot = pd.read_csv("{}_surf/rings_centroids.csv".format(mesh1_name)) + df_tot = pd.read_csv(f"{mesh1_name}_surf/rings_centroids.csv") A_tot = df_tot.to_numpy() - df1 = pd.read_csv("{}_surf/rings_centroids.csv".format(mesh1_name), usecols=names) - df2 = pd.read_csv("{}_surf/rings_centroids.csv".format(mesh2_name), usecols=names) + df1 = pd.read_csv(f"{mesh1_name}_surf/rings_centroids.csv", usecols=names) + df2 = pd.read_csv(f"{mesh2_name}_surf/rings_centroids.csv", usecols=names) df2 = df2[df1.columns] A = df1.to_numpy() @@ -106,23 +106,23 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): df_new = pd.DataFrame(data=new_pts, columns=df1.columns) df_new_tot = pd.DataFrame(data=new_centroids, columns=df_tot.columns) - df_new_tot.to_csv("{}_surf/rings_centroids_prealigned.csv".format(mesh1_name), index=False) + df_new_tot.to_csv(f"{mesh1_name}_surf/rings_centroids_prealigned.csv", index=False) json1 = '[' json2 = '[' for i in df_new.columns: - json1 = json1 + "{\"id\":\"" + "{}".format(i) + "\",\"coordinates\":[" + "{},{},{}".format(df_new[i][0], + json1 = json1 + "{\"id\":\"" + f"{i}" + "\",\"coordinates\":[" + "{},{},{}".format(df_new[i][0], df_new[i][1], df_new[i][2]) + "]}," json1 = json1[:-1] + ']' for i in df2.columns: - json2 = json2 + "{\"id\":\"" + "{}".format(i) + "\",\"coordinates\":[" + "{},{},{}".format(df2[i][0], df2[i][1], + json2 = json2 + "{\"id\":\"" + f"{i}" + "\",\"coordinates\":[" + "{},{},{}".format(df2[i][0], df2[i][1], df2[i][2]) + "]}," json2 = json2[:-1] + ']' - f = open("{}_surf/prealigned_landmarks.json".format(mesh1_name), "w") + f = open(f"{mesh1_name}_surf/prealigned_landmarks.json", "w") f.write(json1) f.close() - f = open("{}_surf/landmarks_to_prealign.json".format(mesh2_name), "w") + f = open(f"{mesh2_name}_surf/landmarks_to_prealign.json", "w") f.write(json2) f.close() @@ -139,21 +139,21 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): writer = vtk.vtkSTLWriter() writer.SetInputConnection(transform_poly.GetOutputPort()) if case == "both": - writer.SetFileName('{}_surf/LA_RA_prealigned.stl'.format(mesh1_name)) + writer.SetFileName(f'{mesh1_name}_surf/LA_RA_prealigned.stl') elif case == "LA": - writer.SetFileName('{}_surf/LA_prealigned.stl'.format(mesh1_name)) + writer.SetFileName(f'{mesh1_name}_surf/LA_prealigned.stl') else: - writer.SetFileName('{}_surf/RA_prealigned.stl'.format(mesh1_name)) + writer.SetFileName(f'{mesh1_name}_surf/RA_prealigned.stl') writer.Write() meshNew = dsa.WrapDataObject(transform_poly.GetOutput()) writer = vtk.vtkPolyDataWriter() if case == "both": - writer.SetFileName('{}_surf/LA_RA_prealigned.vtk'.format(mesh1_name)) + writer.SetFileName(f'{mesh1_name}_surf/LA_RA_prealigned.vtk') elif case == "LA": - writer.SetFileName('{}_surf/LA_prealigned.vtk'.format(mesh1_name)) + writer.SetFileName(f'{mesh1_name}_surf/LA_prealigned.vtk') else: - writer.SetFileName('{}_surf/RA_prealigned.vtk'.format(mesh1_name)) + writer.SetFileName(f'{mesh1_name}_surf/RA_prealigned.vtk') writer.SetInputData(meshNew.VTKObject) writer.Write() @@ -167,7 +167,7 @@ def run(): def vtkreader(meshname): reader = vtk.vtkPolyDataReader() - reader.SetFileName('{}.vtk'.format(meshname)) + reader.SetFileName(f'{meshname}.vtk') reader.Update() geo_filter = vtk.vtkGeometryFilter() diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index fd38ff6..642c8f8 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -97,7 +97,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv ms = pymeshlab.MeshSet() - ms.load_new_mesh('{}.obj'.format(meshname)) + ms.load_new_mesh(f'{meshname}.obj') # ms.apply_filter('turn_into_a_pure_triangular_mesh') # if polygonal mesh # ms.save_current_mesh('{}.obj'.format(meshname)) @@ -112,7 +112,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv if self_intersecting_faces: reader = vtk.vtkOBJReader() - reader.SetFileName('{}.obj'.format(meshname)) + reader.SetFileName(f'{meshname}.obj') reader.Update() boundaryEdges = vtk.vtkFeatureEdges() @@ -126,15 +126,15 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv boundary_pts = vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData()) # Clean the mesh from holes and self intersecting triangles - meshin = pv.read('{}.obj'.format(meshname)) + meshin = pv.read(f'{meshname}.obj') meshfix = pymeshfix.MeshFix(meshin) # Be careful with biatrial geometries as it might delete one chamber meshfix.repair() vol = meshfix.mesh.volume - pv.save_meshio('{}_meshfix.obj'.format(meshname), meshfix.mesh, "obj") + pv.save_meshio(f'{meshname}_meshfix.obj', meshfix.mesh, "obj") reader = vtk.vtkOBJReader() - reader.SetFileName('{}_meshfix.obj'.format(meshname)) + reader.SetFileName(f'{meshname}_meshfix.obj') reader.Update() Mass = vtk.vtkMassProperties() @@ -176,20 +176,20 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv writer = vtk.vtkOBJWriter() writer.SetInputData(cleaner.GetOutput()) - writer.SetFileName('{}_cleaned.obj'.format(meshname)) + writer.SetFileName(f'{meshname}_cleaned.obj') writer.Write() mesh_data["vol"] = [vol] ms = pymeshlab.MeshSet() - ms.load_new_mesh('{}_cleaned.obj'.format(meshname)) + ms.load_new_mesh(f'{meshname}_cleaned.obj') else: ms = pymeshlab.MeshSet() - ms.load_new_mesh('{}.obj'.format(meshname)) + ms.load_new_mesh(f'{meshname}.obj') # compute the geometric measures of the current mesh # and save the results in the out_dict dictionary @@ -202,8 +202,8 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv loc_tgt_edge_length = target_mesh_resolution * scale it = 1 - print("Current resolution: {} mm".format(avg_edge_length / scale)) - print("Target resolution: {} mm".format(tgt_edge_length / scale)) + print(f"Current resolution: {avg_edge_length / scale} mm") + print(f"Target resolution: {tgt_edge_length / scale} mm") while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=loc_tgt_edge_length) @@ -212,13 +212,13 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv out_dict = ms.compute_geometric_measures() avg_edge_length = out_dict['avg_edge_length'] - print("Current resolution: {} mm".format(avg_edge_length / scale)) + print(f"Current resolution: {avg_edge_length / scale} mm") if avg_edge_length > tgt_edge_length * 1.05: loc_tgt_edge_length = tgt_edge_length * 0.95 - print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) + print(f"New target resolution: {loc_tgt_edge_length / scale} mm") elif avg_edge_length < tgt_edge_length * 0.95: loc_tgt_edge_length = tgt_edge_length * 1.05 - print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) + print(f"New target resolution: {loc_tgt_edge_length / scale} mm") else: break it += 1 @@ -227,19 +227,19 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv mesh_data["surf"] = [out_dict['surface_area']] # Better to save as .ply - ms.save_current_mesh('{}_res.ply'.format(meshname), save_vertex_color=False, save_vertex_normal=False, + ms.save_current_mesh(f'{meshname}_res.ply', save_vertex_color=False, save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) - meshin = pv.read('{}_res.ply'.format(meshname)) + meshin = pv.read(f'{meshname}_res.ply') if find_apex_with_curv and apex_id == -1: if self_intersecting_faces: - os.system("meshtool query curvature -msh={}_cleaned.obj -size={}".format(meshname, size * scale)) - curv = np.loadtxt('{}_cleaned.curv.dat'.format(meshname)) - mesh_curv = pv.read('{}_cleaned.obj'.format(meshname)) + os.system(f"meshtool query curvature -msh={meshname}_cleaned.obj -size={size * scale}") + curv = np.loadtxt(f'{meshname}_cleaned.curv.dat') + mesh_curv = pv.read(f'{meshname}_cleaned.obj') else: - os.system("meshtool query curvature -msh={}.obj -size={}".format(meshname, size * scale)) - curv = np.loadtxt('{}.curv.dat'.format(meshname)) - mesh_curv = pv.read('{}.obj'.format(meshname)) + os.system(f"meshtool query curvature -msh={meshname}.obj -size={size * scale}") + curv = np.loadtxt(f'{meshname}.curv.dat') + mesh_curv = pv.read(f'{meshname}.obj') apex = mesh_curv.points[np.argmax(curv), :] @@ -281,7 +281,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv if atrium == 'LA_RA': mesh_data["LAA_id"] = [apex_id] # change accordingly else: - mesh_data["{}A_id".format(atrium)] = [apex_id] # change accordingly + mesh_data[f"{atrium}A_id"] = [apex_id] # change accordingly if atrium == 'LA_RA': atrium = 'RA' @@ -301,10 +301,10 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv tree = cKDTree(meshin.points.astype(np.double)) dist, apex_id = tree.query(apex) - mesh_data["{}A_id".format(atrium)] = [apex_id] # change accordingly + mesh_data[f"{atrium}A_id"] = [apex_id] # change accordingly reader = vtk.vtkPLYReader() - reader.SetFileName('{}_res.ply'.format(meshname)) + reader.SetFileName(f'{meshname}_res.ply') reader.Update() Mass = vtk.vtkMassProperties() @@ -315,7 +315,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv print("Surface = ", Mass.GetSurfaceArea()) mesh_data["vol_bi"] = Mass.GetVolume() # Biatrial volume - fname = '{}_res_mesh_data.csv'.format(meshname) + fname = f'{meshname}_res_mesh_data.csv' df = pd.DataFrame(mesh_data) df.to_csv(fname, float_format="%.2f", index=False) diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index bd847f0..43b36bb 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -38,8 +38,8 @@ def low_vol_LAT(args, path): # Read mesh - meshname = '{}_fibers/result_LA/LA_bilayer_with_fiber_with_data_um'.format(args.mesh) # in um - model = smart_reader('{}.vtk'.format(meshname)) + meshname = f'{args.mesh}_fibers/result_LA/LA_bilayer_with_fiber_with_data_um' # in um + model = smart_reader(f'{meshname}.vtk') bilayer_n_cells = model.GetNumberOfCells() @@ -83,16 +83,16 @@ def low_vol_LAT(args, path): if args.debug: meshbasename = args.mesh.split("/")[-1] - debug_dir = '{}/{}/debug'.format(args.init_state_dir, meshbasename) + debug_dir = f'{args.init_state_dir}/{meshbasename}/debug' try: os.makedirs(debug_dir) except OSError: - print("Creation of the directory %s failed" % debug_dir) + print(f"Creation of the directory {debug_dir} failed") else: - print("Successfully created the directory %s " % debug_dir) + print(f"Successfully created the directory {debug_dir} ") writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName('{}/low_vol.vtu'.format(debug_dir)) + writer.SetFileName(f'{debug_dir}/low_vol.vtu') writer.SetInputData(low_vol) writer.Write() @@ -106,7 +106,7 @@ def low_vol_LAT(args, path): if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName('{}/endo.vtu'.format(debug_dir)) + writer.SetFileName(f'{debug_dir}/endo.vtu') writer.SetInputData(endo) writer.Write() @@ -127,7 +127,7 @@ def low_vol_LAT(args, path): if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName('{}/not_low_volt_endo.vtu'.format(debug_dir)) + writer.SetFileName(f'{debug_dir}/not_low_volt_endo.vtu') writer.SetInputData(not_low_volt_endo) writer.Write() @@ -138,7 +138,7 @@ def low_vol_LAT(args, path): # See create_SSM_instance standalone to create LA_fit.obj reader = vtk.vtkOBJReader() - reader.SetFileName('{}/LA_fit.obj'.format(args.mesh)) + reader.SetFileName(f'{args.mesh}/LA_fit.obj') reader.Update() LA_fit = reader.GetOutput() @@ -366,13 +366,13 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): if args.debug: meshbasename = args.mesh.split("/")[-1] - debug_dir = '{}/{}/debug'.format(args.init_state_dir, meshbasename) + debug_dir = f'{args.init_state_dir}/{meshbasename}/debug' try: os.makedirs(debug_dir) except OSError: - print("Creation of the directory %s failed" % debug_dir) + print(f"Creation of the directory {debug_dir} failed") else: - print("Successfully created the directory %s " % debug_dir) + print(f"Successfully created the directory {debug_dir} ") el_border_array = np.concatenate(el_border) # convert to linear array border = np.zeros((endo.GetNumberOfCells(),)) @@ -380,7 +380,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): meshNew.CellData.append(border, "border") writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName('{}/endo_with_clean_tag.vtu'.format(debug_dir)) + writer.SetFileName(f'{debug_dir}/endo_with_clean_tag.vtu') writer.SetInputData(meshNew.VTKObject) writer.Write() @@ -400,7 +400,7 @@ def create_regele(endo, args): # file.write(str(i) + '\n') # file.close() - f_slow_conductive = '{}/{}/elems_slow_conductive'.format(args.init_state_dir, args.mesh.split("/")[-1]) + f_slow_conductive = f"{args.init_state_dir}/{args.mesh.split('/')[-1]}/elems_slow_conductive" file = open(f_slow_conductive + '.regele', 'w') file.write(str(len(low_vol_ids)) + '\n') for i in low_vol_ids: @@ -425,7 +425,7 @@ def low_CV(model, low_CV_thr, meshfold): f = open(meshfold + '/low_CV.dat', 'w') for i in sigma: - f.write("{:.4f}\n".format(i)) + f.write(f"{i:.4f}\n") f.close() diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index e35a19c..d6b7eb4 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -208,7 +208,7 @@ def single_cell_initialization(args, job, steady_state_dir, to_do): '--duration', duration, '--stim-start', 0, '--dt', args.dt / 1000, - '--fout=' + steady_state_dir + '/{}_numstim_{}_bcl_ms_{}'.format(args.numstim, args.cell_bcl, k), + '--fout=' + steady_state_dir + f'/{args.numstim}_numstim_{args.cell_bcl}_bcl_ms_{k}', '-S', duration, '-F', init_file, '--trace-no', k] @@ -261,11 +261,11 @@ def single_cell_initialization(args, job, steady_state_dir, to_do): for k in range(n_regions): init_file = steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, k, args.numstim) - tissue_init += ['-imp_region[{}].im_sv_init'.format(k), init_file] + tissue_init += [f'-imp_region[{k}].im_sv_init', init_file] if to_do: # Move trace files to steady_state_dir for file in os.listdir(os.getcwd()): - if file.startswith("Trace") or file.startswith("{}_trace".format(args.model)): + if file.startswith("Trace") or file.startswith(f"{args.model}_trace"): old_file = os.getcwd() + '/' + file new_file = steady_state_dir + '/' + file os.rename(old_file, new_file) @@ -306,21 +306,21 @@ def run(args, job): # p = np.poly1d([0.67278584, 0.17556362, 0.01718574]) - meshname = '{}_fibers/result_LA/LA_bilayer_with_fiber'.format(args.mesh) # um + meshname = f'{args.mesh}_fibers/result_LA/LA_bilayer_with_fiber' # um meshbasename = meshname.split('/')[-4] - meshfold = '{}/{}'.format(args.init_state_dir, meshbasename) + meshfold = f'{args.init_state_dir}/{meshbasename}' - steady_state_dir = '{}/{}/cell_state'.format(args.init_state_dir, meshbasename) + steady_state_dir = f'{args.init_state_dir}/{meshbasename}/cell_state' try: os.makedirs(steady_state_dir) except OSError: - print("Creation of the directory %s failed" % steady_state_dir) + print(f"Creation of the directory {steady_state_dir} failed") else: - print("Successfully created the directory %s " % steady_state_dir) + print(f"Successfully created the directory {steady_state_dir} ") if not os.path.isfile( - steady_state_dir + '/init_values_stab_bcl_{}_reg_{}_numstim_{}.sv'.format(args.cell_bcl, 0, args.numstim)): + steady_state_dir + f'/init_values_stab_bcl_{args.cell_bcl}_reg_{0}_numstim_{args.numstim}.sv'): tissue_init = single_cell_initialization(args, job, steady_state_dir, 1) else: tissue_init = single_cell_initialization(args, job, steady_state_dir, 0) @@ -330,15 +330,15 @@ def run(args, job): try: os.makedirs(simid) except OSError: - print("Creation of the directory %s failed" % simid) + print(f"Creation of the directory {simid} failed") else: - print("Successfully created the directory %s " % simid) + print(f"Successfully created the directory {simid} ") bilayer_n_cells, elements_in_fibrotic_reg, endo, endo_ids, centroids, LAT_map, min_LAT, el_to_clean, el_border, stim_pt, fit_LAT, healthy_endo = Methods_fit_to_clinical_LAT.low_vol_LAT( args, meshname + '_with_data_um.vtk') - with open("{}/{}/clinical_stim_pt.txt".format(args.init_state_dir, meshbasename), "w") as f: - f.write("{} {} {}".format(stim_pt[0], stim_pt[1], stim_pt[2])) + with open(f"{args.init_state_dir}/{meshbasename}/clinical_stim_pt.txt", "w") as f: + f.write(f"{stim_pt[0]} {stim_pt[1]} {stim_pt[2]}") # Set to 1 every LAT <= 1 LAT_map = np.where(LAT_map <= 1, 1, LAT_map) @@ -348,18 +348,18 @@ def run(args, job): # Set to max_LAT every LAT >= max_LAT LAT_map = np.where(LAT_map > args.LaAT, args.LaAT, LAT_map) - print("Wanted LAT: {}".format(args.LaAT)) - print("Max LAT point id: {}".format(args.max_LAT_id)) + print(f"Wanted LAT: {args.LaAT}") + print(f"Max LAT point id: {args.max_LAT_id}") print(fit_LAT) # Find all not conductive elements belonging to the fibrotic tissue and not use them in the fitting tag = {} - if not os.path.isfile('{}/elems_slow_conductive.regele'.format(meshfold)): + if not os.path.isfile(f'{meshfold}/elems_slow_conductive.regele'): Methods_fit_to_clinical_LAT.create_regele(endo, args) print('Reading regele file ...') - elems_not_conductive = np.loadtxt('{}/elems_slow_conductive.regele'.format(meshfold), skiprows=1, dtype=int) + elems_not_conductive = np.loadtxt(f'{meshfold}/elems_slow_conductive.regele', skiprows=1, dtype=int) endo_etag = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('elemTag')) @@ -373,18 +373,18 @@ def run(args, job): meshNew.CellData.append(endo_etag, "elemTag") writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName("{}/LA_endo_with_fiber_30_um.vtu".format(meshfold)) + writer.SetFileName(f"{meshfold}/LA_endo_with_fiber_30_um.vtu") writer.SetInputData(meshNew.VTKObject) writer.Write() pts = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetPoints().GetData()) with open(meshfold + "/LA_endo_with_fiber_30_um.pts", "w") as f: - f.write("{}\n".format(len(pts))) + f.write(f"{len(pts)}\n") for i in range(len(pts)): - f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) + f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") with open(meshfold + "/LA_endo_with_fiber_30_um.elem", "w") as f: - f.write("{}\n".format(meshNew.VTKObject.GetNumberOfCells())) + f.write(f"{meshNew.VTKObject.GetNumberOfCells()}\n") for i in range(meshNew.VTKObject.GetNumberOfCells()): cell = meshNew.VTKObject.GetCell(i) f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), @@ -449,12 +449,12 @@ def run(args, job): # Create the conductivity scale map with ones factors as initial condition f = open(simid + '/low_CV.dat', 'w') for i in slow_CV: - f.write("{:.4f}\n".format(i)) + f.write(f"{i:.4f}\n") f.close() f = open(simid + '/low_CV_old.dat', 'w') for i in slow_CV: - f.write("{:.4f}\n".format(i)) + f.write(f"{i:.4f}\n") f.close() final_diff = [] @@ -633,7 +633,7 @@ def run(args, job): active = Methods_fit_to_clinical_LAT.vtk_thr(healthy_endo, 0, "POINTS", "lat_s", 0) active_cells = vtk.util.numpy_support.vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int) - print("active_cells: {}".format(len(active_cells))) + print(f"active_cells: {len(active_cells)}") act_cls_old = np.zeros((model.GetNumberOfCells(),)) act_cls = np.zeros((model.GetNumberOfCells(),)) meshNew.CellData.append(act_cls, "act_cls") @@ -672,9 +672,9 @@ def run(args, job): last_ACT = np.mean(lats_to_fit[active_cells_band]) - print("ACT to fit: {}".format(fit_LAT[l])) - print("last ACT: {}".format(last_ACT)) - print("old_cells: {}".format(len(old_cells))) + print(f"ACT to fit: {fit_LAT[l]}") + print(f"last ACT: {last_ACT}") + print(f"old_cells: {len(old_cells)}") # Compute RMSE between simulated and clinical LAT excluding elements to clean (marked as wrong annotation) if len(lats_to_fit[active_cells_band]) > 0: @@ -713,7 +713,7 @@ def run(args, job): meshNew.CellData.append(slow_CV, "slow_CV") writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/endo_cleaned_{}.vtu".format(l)) + writer.SetFileName(job.ID + f"/endo_cleaned_{l}.vtu") writer.SetInputData(meshNew.VTKObject) # writer.SetFileTypeToBinary() writer.Write() @@ -721,7 +721,7 @@ def run(args, job): os.rename(simid + '/low_CV.dat', simid + '/low_CV_old.dat') f = open(simid + '/low_CV.dat', 'w') for i in slow_CV: - f.write("{:.4f}\n".format(i)) + f.write(f"{i:.4f}\n") f.close() it += 1 else: @@ -734,7 +734,7 @@ def run(args, job): meshNew.CellData.append(slow_CV_old, "slow_CV_old") final_diff.append(LAT_diff) writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/endo_cleaned_{}.vtu".format(l)) + writer.SetFileName(job.ID + f"/endo_cleaned_{l}.vtu") writer.SetInputData(meshNew.VTKObject) # writer.SetFileTypeToBinary() writer.Write() @@ -799,12 +799,12 @@ def run(args, job): print(RMSE) - print("Final last ACT: {}".format(last_ACT)) - print("Final giL: {}".format(args.giL)) - print("Final geL: {}".format(args.geL)) + print(f"Final last ACT: {last_ACT}") + print(f"Final giL: {args.giL}") + print(f"Final geL: {args.geL}") f = open(job.ID + '/err.dat', 'w') for i in final_diff: - f.write("{:.4f}\n".format(i)) + f.write(f"{i:.4f}\n") f.close() if os.path.exists('RMSE_patients.txt'): @@ -812,7 +812,7 @@ def run(args, job): else: append_write = 'w' # make a new file if not f = open('RMSE_patients.txt', append_write) - f.write("{} {} {} {:.2f}\n".format(args.mesh, args.step, args.thr, RMSE)) + f.write(f"{args.mesh} {args.step} {args.thr} {RMSE:.2f}\n") f.close() slow_CV = np.loadtxt(simid + '/low_CV_old.dat') @@ -820,9 +820,9 @@ def run(args, job): slow_CV_bil[endo_ids] = slow_CV slow_CV_bil[endo_ids + len(endo_ids)] = slow_CV - f = open(meshfold + '/low_CV_3_{}_{}.dat'.format(args.step, args.thr), 'w') + f = open(meshfold + f'/low_CV_3_{args.step}_{args.thr}.dat', 'w') for i in slow_CV_bil: - f.write("{:.4f}\n".format(i)) + f.write(f"{i:.4f}\n") f.close() meshNew = dsa.WrapDataObject(new_endo) From a779d4230d989d88af13f0cf33719333b5d4c142 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 15:48:21 +0100 Subject: [PATCH 03/70] Fixed collection.size import --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 8 ++++---- standalones/open_orifices_manually.py | 4 ++-- standalones/open_orifices_with_curvature.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index fff3b83..4a56c32 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -853,7 +853,7 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): for i in range(mesh1.GetPointData().GetNumberOfArrays()): data = vtk.util.numpy_support.vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) @@ -867,7 +867,7 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) @@ -906,7 +906,7 @@ def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): for i in range(mesh1.GetCellData().GetNumberOfArrays()): data = vtk.util.numpy_support.vtk_to_numpy( mesh1.GetCellData().GetArray(mesh1.GetCellData().GetArrayName(i))) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) @@ -915,7 +915,7 @@ def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): meshNew.PointData.append(data2, mesh1.GetCellData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetCellData().GetArray(idat)) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 400781b..ed1bad3 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -317,7 +317,7 @@ def point_array_mapper(mesh1, mesh2, idat): for i in range(mesh1.GetPointData().GetNumberOfArrays()): data = vtk.util.numpy_support.vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) @@ -328,7 +328,7 @@ def point_array_mapper(mesh1, mesh2, idat): meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 833fb27..d405279 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -604,14 +604,14 @@ def point_array_mapper(mesh1, mesh2, idat): tree = cKDTree(pts1) - dd, ii = tree.query(pts2, n_jobs=-1) + dd, ii = tree.query(pts2, workers=-1) meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): data = vtk.util.numpy_support.vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) @@ -622,7 +622,7 @@ def point_array_mapper(mesh1, mesh2, idat): meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) - if isinstance(data[0], collections.Sized): + if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: data2 = np.zeros((len(pts2),), dtype=data.dtype) From ecc5cd2619c14fb05c614d9024b201260c1953c8 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 15:50:49 +0100 Subject: [PATCH 04/70] Default to manual orifices labeling if with curvature not working --- standalones/open_orifices_manually.py | 25 ++++------- standalones/open_orifices_with_curvature.py | 49 +++++++++------------ 2 files changed, 30 insertions(+), 44 deletions(-) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index ed1bad3..d2c7eb6 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -24,29 +24,22 @@ specific language governing permissions and limitations under the License. """ -import os, sys -import numpy as np -import pathlib -from glob import glob -import pandas as pd -import vtk -from vtk.util import numpy_support -import scipy.spatial as spatial -from vtk.numpy_interface import dataset_adapter as dsa -import datetime -from sklearn.cluster import KMeans import argparse -from scipy.spatial import cKDTree +import numpy as np import pymeshfix -from pymeshfix import _meshfix import pyvista as pv -import collections +import vtk +from scipy.spatial import cKDTree +from vtk.numpy_interface import dataset_adapter as dsa + +from Atrial_LDRBM.Generate_Boundaries import extract_rings +from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper pv.set_plot_theme('dark') -sys.path.append('../Atrial_LDRBM/Generate_Boundaries') -import extract_rings +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import extract_largest_region vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index d405279..f5e17b6 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -25,6 +25,8 @@ under the License. """ import os, sys +import warnings + import numpy as np import pathlib from glob import glob @@ -43,6 +45,10 @@ import pyvista as pv import collections +import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations +from standalones.open_orifices_manually import open_orifices_manually +from vtk_opencarp_helper_methods.vtk_methods import filters + pv.set_plot_theme('dark') sys.path.append('./Atrial_LDRBM/Generate_Boundaries') @@ -139,6 +145,12 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu if not MRI: valve = vtk_thr(model, 0, "POINTS", "valve", 0.5) + if valve.GetPoints() is None or valve.GetNumberOfPoints() == 0: + # do manually orifice opening when automatically does not find valves + warnings.warn("No points for valve found. Should default to manual assignment") + return open_orifices_manually(meshpath, atrium, MRI, scale, size, min_cutting_radius, max_cutting_radius, + LAA, RAA, + debug) valve = extract_largest_region(valve) centerOfMassFilter = vtk.vtkCenterOfMass() @@ -183,16 +195,19 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu else: valve = vtk_thr(model, 0, "POINTS", "curv", 0.05) valve = extract_largest_region(valve) + if valve.GetPoints() is None or valve.GetNumberOfPoints() == 0: + # do manually orifice opening when automatically does not find valves + warnings.warn("No points for valve found. Should default to manual assignment") + return open_orifices_manually(meshpath, atrium, MRI, scale, size, min_cutting_radius, max_cutting_radius, + LAA, RAA, + debug) if debug and atrium == 'RA': writer_vtk(valve, f"{full_path}/{atrium}_clean_with_curv_" + "valve.vtk") - centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(valve) - centerOfMassFilter.SetUseScalarsAsWeights(False) - centerOfMassFilter.Update() + center_of_mass = filters.get_center_of_mass(valve, False) - valve_center = np.array(centerOfMassFilter.GetCenter()) + valve_center = np.array(center_of_mass) valve_pts = vtk.util.numpy_support.vtk_to_numpy(valve.GetPoints().GetData()) max_dist = 0 @@ -531,29 +546,7 @@ def smart_reader(path): def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - if mode == 0: - thresh.ThresholdByUpper(thr1) - elif mode == 1: - thresh.ThresholdByLower(thr1) - elif mode == 2: - if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1, thr2) - else: - thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - thr = thresh.GetOutput() - thresh = vtk.vtkThreshold() - thresh.SetInputData(thr) - thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - - output = thresh.GetOutput() - - return output + return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, thr2) def find_elements_within_radius(mesh, points_data, radius): From 87a5572a7be6f642f09d6dd6d80606b5c9c85d54 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 15:55:55 +0100 Subject: [PATCH 05/70] Replaced use_mesh with use_picker for appendage picking --- pipeline.py | 2 +- standalones/open_orifices_manually.py | 7 ++++--- standalones/open_orifices_with_curvature.py | 8 ++++---- standalones/resample_surf_mesh.py | 6 +++--- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pipeline.py b/pipeline.py index 18c6dd0..67a8f74 100644 --- a/pipeline.py +++ b/pipeline.py @@ -266,7 +266,7 @@ def AugmentA(args): # p.add_mesh(point_cloud, color='w', point_size=30.*args.scale, render_points_as_spheres=True) # # p.add_mesh(meshin,color='r') - # p.enable_point_picking(meshin, use_mesh=True) + # p.enable_point_picking(meshin, use_picker=True) # p.add_text('Select the appendage apex and close the window',position='lower_left') # # p.show() diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index d2c7eb6..3c6a271 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -25,6 +25,7 @@ under the License. """ import argparse +import collections import numpy as np import pymeshfix @@ -126,7 +127,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ p.add_mesh(meshfix.mesh, 'r') p.add_text(f'Select the center of the {r} and close the window to cut, otherwise just close', position='lower_left') - p.enable_point_picking(meshfix.mesh, use_mesh=True) + p.enable_point_picking(meshfix.mesh, use_picker=True) p.show() picked_pt = p.picked_point @@ -169,7 +170,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") p.add_mesh(mesh_from_vtk, 'r') p.add_text('Select the atrial appendage apex', position='lower_left') - p.enable_point_picking(meshfix.mesh, use_mesh=True) + p.enable_point_picking(meshfix.mesh, use_picker=True) p.show() @@ -303,7 +304,7 @@ def point_array_mapper(mesh1, mesh2, idat): tree = cKDTree(pts1) - dd, ii = tree.query(pts2, n_jobs=-1) + dd, ii = tree.query(pts2, workers=-1) meshNew = dsa.WrapDataObject(mesh2) if idat == "all": diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index f5e17b6..c73de3e 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -301,7 +301,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p.add_mesh(meshfix.mesh, 'r') p.add_text('Select the appendage apex and close the window', position='lower_left') p.add_mesh(cc, color='w', point_size=30., render_points_as_spheres=True) - p.enable_point_picking(meshfix.mesh, use_mesh=True) + p.enable_point_picking(meshfix.mesh, use_picker=True) p.show() @@ -322,7 +322,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_clean.vtk") p.add_mesh(mesh_from_vtk, 'r') p.add_text('Select the transeptal punture and close the window', position='lower_left') - p.enable_point_picking(meshfix.mesh, use_mesh=True) + p.enable_point_picking(meshfix.mesh, use_picker=True) p.show() @@ -474,7 +474,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") p.add_mesh(mesh_from_vtk, 'r') p.add_mesh(point_cloud, color='w', point_size=30., render_points_as_spheres=True) - p.enable_point_picking(meshfix.mesh, use_mesh=True) + p.enable_point_picking(meshfix.mesh, use_picker=True) p.add_text('Select the appendage apex and close the window', position='lower_left') p.show() @@ -485,7 +485,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p = pv.Plotter(notebook=False) mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") p.add_mesh(mesh_from_vtk, 'r') - p.enable_point_picking(meshfix.mesh, use_mesh=True) + p.enable_point_picking(meshfix.mesh, use_picker=True) p.add_text('Select the appendage apex and close the window', position='lower_left') p.show() diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 642c8f8..ab63498 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -249,7 +249,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv p.add_mesh(meshin, color='r') p.add_mesh(point_cloud, color='w', point_size=30. * scale, render_points_as_spheres=True) - p.enable_point_picking(meshin, use_mesh=True) + p.enable_point_picking(meshin, use_picker=True) p.add_text('Select the appendage apex and close the window', position='lower_left') p.show() @@ -265,7 +265,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv p = pv.Plotter(notebook=False) p.add_mesh(meshin, color='r') - p.enable_point_picking(meshin, use_mesh=True) + p.enable_point_picking(meshin, use_picker=True) p.add_text('Select the appendage apex and close the window', position='lower_left') # Select the LAA first p.show() @@ -288,7 +288,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv p = pv.Plotter(notebook=False) p.add_mesh(meshin, color='r') - p.enable_point_picking(meshin, use_mesh=True) + p.enable_point_picking(meshin, use_picker=True) p.add_text('Select the RA appendage apex and close the window', position='lower_left') p.show() From 04e9a011555c52a7fcdcf4f5e968bee7a0b8ffec Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 16:00:00 +0100 Subject: [PATCH 06/70] Cleaned parts of open_orifices_manually.py --- standalones/open_orifices_manually.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 3c6a271..2350a17 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -35,6 +35,8 @@ from vtk.numpy_interface import dataset_adapter as dsa from Atrial_LDRBM.Generate_Boundaries import extract_rings +from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper pv.set_plot_theme('dark') @@ -161,23 +163,12 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ model = extract_largest_region(mesh) - writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(f"{full_path}/{atrium}_cutted.vtk") - writer.SetInputData(model) - writer.Write() + vtk_polydata_writer(f"{full_path}/{atrium}_cutted.vtk", model) - p = pv.Plotter(notebook=False) mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") - p.add_mesh(mesh_from_vtk, 'r') - p.add_text('Select the atrial appendage apex', position='lower_left') - p.enable_point_picking(meshfix.mesh, use_picker=True) - p.show() + apex = pick_point(mesh_from_vtk, "atrial appendage apex") - if p.picked_point is not None: - apex = p.picked_point - - p.close() model = smart_reader(f"{full_path}/{atrium}_cutted.vtk") loc = vtk.vtkPointLocator() loc.SetDataSet(model) From 1953543eaf61fc7bebb68841e93952238469a1b0 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 16:22:29 +0100 Subject: [PATCH 07/70] Changed reference of smart_readers only to the encapsulated method --- .../Generate_Boundaries/extract_rings.py | 38 ++----- .../extract_rings_TOP_epi_endo.py | 31 +----- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 55 ----------- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 29 ------ standalones/open_orifices_manually.py | 34 +------ standalones/open_orifices_with_curvature.py | 30 +----- .../Methods_fit_to_clinical_LAT.py | 99 ++----------------- 7 files changed, 21 insertions(+), 295 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 79810c8..403b1a4 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -36,6 +36,8 @@ import argparse from scipy.spatial import cKDTree +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader + vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -78,35 +80,6 @@ def parser(): return parser -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_id="", debug=1): """Extrating Rings""" print('Extracting rings...') @@ -295,8 +268,11 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i df.to_csv(outdir + "/rings_centroids.csv", float_format="%.2f", index=False) -def run(): - args = parser().parse_args() +def run(args=None): + if args is None: + args = parser().parse_args() + else: + args = parser().parse_args(args) label_atrial_orifices(args.mesh, args.LAA, args.RAA, args.LAA_base, args.RAA_base, args.debug) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index c83ffa6..d72bdc3 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -36,6 +36,8 @@ import argparse from scipy.spatial import cKDTree +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader + vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -74,35 +76,6 @@ def parser(): return parser -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_id=""): """Extrating Rings""" print('Extracting rings...') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 4a56c32..2b1746a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -36,61 +36,6 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - -def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - if mode == 0: - thresh.ThresholdByUpper(thr1) - elif mode == 1: - thresh.ThresholdByLower(thr1) - elif mode == 2: - if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1, thr2) - else: - thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - thr = thresh.GetOutput() - thresh = vtk.vtkThreshold() - thresh.SetInputData(thr) - thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - - output = thresh.GetOutput() - - return output - - def mark_LA_endo_elemTag(model, tag, tao_mv, tao_lpv, tao_rpv, max_phie_ab_tau_lpv, max_phie_r2_tau_lpv): thresh = vtk.vtkThreshold() thresh.SetInputData(model) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index b115f5a..8e6688a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -33,35 +33,6 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - def downsample_path(points_data, step): # down sampling path_all = np.asarray( diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 2350a17..bd0a669 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -180,7 +180,10 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ RAA = apex_id meshpath = f"{full_path}/{atrium}_cutted" - extract_rings.run(["--mesh", meshpath, "--LAA", str(LAA), "--RAA", str(RAA)]) + + command = ["--mesh", meshpath, "--LAA", str(LAA), "--RAA", str(RAA)] + print(f"extract rings with:{command}") + extract_rings.run(command) return apex_id @@ -192,35 +195,6 @@ def run(): args.max_cutting_radius, args.LAA, args.RAA, args.debug) -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thresh = vtk.vtkThreshold() thresh.SetInputData(model) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index c73de3e..5374d6b 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -48,6 +48,7 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from standalones.open_orifices_manually import open_orifices_manually from vtk_opencarp_helper_methods.vtk_methods import filters +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader pv.set_plot_theme('dark') @@ -516,35 +517,6 @@ def run(): args.debug) -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, thr2) diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 43b36bb..7154ab8 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -25,13 +25,15 @@ under the License. """ -import vtk import os -from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util.numpy_support import vtk_to_numpy -from scipy.spatial import cKDTree + import numpy as np -from sklearn.metrics import mean_squared_error +import vtk +from scipy.spatial import cKDTree +from vtk.numpy_interface import dataset_adapter as dsa + +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -428,21 +430,6 @@ def low_CV(model, low_CV_thr, meshfold): f.write(f"{i:.4f}\n") f.close() - -def low_CV(args, job, meas_LAT, new_endo, meshfold): - lats = np.loadtxt(job.ID + '/init_acts_ACTs-thresh.dat') - meshNew = dsa.WrapDataObject(new_endo) - meshNew.PointData.append(lats, "LAT_s") - - healthy_endo = Methods.vtk_thr(meshNew.VTKObject, 1, "CELLS", "elemTag", 7) - active = Methods.vtk_thr(healthy_endo, 0, "POINTS", "LAT_s", 0) - max_active_LAT = np.max(vtk.util.numpy_support.vtk_to_numpy(active.GetPointData().GetArray('LAT_s'))) - max_active_band = Methods.vtk_thr(healthy_endo, 2, "POINTS", "LAT_s", max_active_LAT - args.tol, max_active_LAT) - active_cells = list( - set(vtk.util.numpy_support.vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int)).difference( - low_CV_ids)) - - def dijkstra_path(polydata, StartVertex, EndVertex): path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(polydata) @@ -483,78 +470,6 @@ def get_EAP(path_mod, path_fib): return stim_pt -def smart_reader_old(path): - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - -def smart_reader(path): - extension = str(path).split(".")[-1] - - if extension == "vtk": - data_checker = vtk.vtkDataSetReader() - data_checker.SetFileName(str(path)) - data_checker.Update() - - if data_checker.IsFilePolyData(): - reader = vtk.vtkPolyDataReader() - elif data_checker.IsFileUnstructuredGrid(): - reader = vtk.vtkUnstructuredGridReader() - - elif extension == "vtp": - reader = vtk.vtkXMLPolyDataReader() - elif extension == "vtu": - reader = vtk.vtkXMLUnstructuredGridReader() - elif extension == "obj": - reader = vtk.vtkOBJReader() - else: - print("No polydata or unstructured grid") - - reader.SetFileName(str(path)) - reader.Update() - output = reader.GetOutput() - - return output - - -def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - if mode == 0: - thresh.ThresholdByUpper(thr1) - elif mode == 1: - thresh.ThresholdByLower(thr1) - elif mode == 2: - if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1, thr2) - else: - thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - thr = thresh.GetOutput() - thresh = vtk.vtkThreshold() - thresh.SetInputData(thr) - thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - - output = thresh.GetOutput() - - return output - - def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) From 1f33883f1d7bddf3fac1266a6c6a1f61d58c9b00 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 16:44:07 +0100 Subject: [PATCH 08/70] Fixed missing extension bug in open_orifices_manually.py --- standalones/open_orifices_manually.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index bd0a669..557489d 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -179,7 +179,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ elif atrium == "RA": RAA = apex_id - meshpath = f"{full_path}/{atrium}_cutted" + meshpath = f"{full_path}/{atrium}_cutted.vtk" command = ["--mesh", meshpath, "--LAA", str(LAA), "--RAA", str(RAA)] print(f"extract rings with:{command}") From 6a72e7ab748bca6adfc384acd8d094df2d2e9e48 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 17:06:56 +0100 Subject: [PATCH 09/70] Updated pymeshlab filters to new api --- standalones/resample_surf_mesh.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index ab63498..2bd4a5c 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -101,7 +101,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv # ms.apply_filter('turn_into_a_pure_triangular_mesh') # if polygonal mesh # ms.save_current_mesh('{}.obj'.format(meshname)) - ms.select_self_intersecting_faces() + ms.compute_selection_by_self_intersections_per_face() m = ms.current_mesh() @@ -193,7 +193,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv # compute the geometric measures of the current mesh # and save the results in the out_dict dictionary - out_dict = ms.compute_geometric_measures() + out_dict = ms.get_geometric_measures() # get the average edge length from the dictionary avg_edge_length = out_dict['avg_edge_length'] @@ -206,10 +206,10 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv print(f"Target resolution: {tgt_edge_length / scale} mm") while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: - ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=loc_tgt_edge_length) + ms.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(loc_tgt_edge_length)) if it == 1: - ms.laplacian_smooth() - out_dict = ms.compute_geometric_measures() + ms.apply_coord_laplacian_smoothing() + out_dict = ms.get_geometric_measures() avg_edge_length = out_dict['avg_edge_length'] print(f"Current resolution: {avg_edge_length / scale} mm") From 433a875388d88a00aa3ddf8ecc1a70fb12979247 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 17:36:11 +0100 Subject: [PATCH 10/70] Replaced all threshold definitions with newer vtk thresholds --- .../Generate_Boundaries/extract_rings.py | 7 +- .../extract_rings_TOP_epi_endo.py | 13 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 79 ++-------- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 27 +--- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 143 ------------------ standalones/open_orifices_manually.py | 26 +--- 6 files changed, 26 insertions(+), 269 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 403b1a4..776da3d 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -37,6 +37,7 @@ from scipy.spatial import cKDTree from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -896,11 +897,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): meshNew = dsa.WrapDataObject(top_cut) meshNew.PointData.append(to_delete, "delete") - thresh = vtk.vtkThreshold() - thresh.SetInputData(meshNew.VTKObject) - thresh.ThresholdByLower(0) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - thresh.Update() + thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index d72bdc3..c8f8638 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -37,6 +37,7 @@ from scipy.spatial import cKDTree from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -964,11 +965,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): meshNew = dsa.WrapDataObject(top_cut_epi) meshNew.PointData.append(to_delete, "delete") - thresh = vtk.vtkThreshold() - thresh.SetInputData(meshNew.VTKObject) - thresh.ThresholdByLower(0) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - thresh.Update() + thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) @@ -1026,11 +1023,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): meshNew = dsa.WrapDataObject(top_cut_endo) meshNew.PointData.append(to_delete, "delete") - thresh = vtk.vtkThreshold() - thresh.SetInputData(meshNew.VTKObject) - thresh.ThresholdByLower(0) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - thresh.Update() + thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thresh.GetOutputPort()) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 2b1746a..91bab8b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -33,45 +33,30 @@ from scipy.spatial.distance import cosine import collections +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ + get_threshold_between + vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] def mark_LA_endo_elemTag(model, tag, tao_mv, tao_lpv, tao_rpv, max_phie_ab_tau_lpv, max_phie_r2_tau_lpv): - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - thresh.ThresholdByUpper(tao_mv) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r") - thresh.Update() + thresh = get_upper_threshold(model, tao_mv, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r") MV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - thresh.ThresholdByUpper(max_phie_r2_tau_lpv + 0.01) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r2") - thresh.Update() + thresh2 = get_upper_threshold(model, max_phie_r2_tau_lpv + 0.01, "vtkDataObject::FIELD_ASSOCIATION_CELLS", + "phie_r2") - thresh = vtk.vtkThreshold() - thresh.SetInputConnection(thresh.GetOutputPort()) - thresh.ThresholdByLower(max_phie_ab_tau_lpv + 0.01) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_ab") - thresh.Update() + thresh = get_lower_threshold(thresh2.GetOutputPort(), max_phie_ab_tau_lpv + 0.01, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_ab", source_is_input_connection=True) LAA_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - thresh.ThresholdByLower(tao_lpv) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") - thresh.Update() + thresh = get_lower_threshold(model, tao_lpv, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") LPV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - thresh.ThresholdByUpper(tao_rpv) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") - thresh.Update() + thresh = get_upper_threshold(model, tao_rpv, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") RPV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) @@ -991,40 +976,8 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e # bb_mv_id = int(MV.GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(epi.GetPoint(bb_mv_id)))[0]) bb_mv = MV.GetPoint(loc.FindClosestPoint(bb_mv_laa)) - - if int(vtk_version) >= 9: - thresh = vtk.vtkThreshold() - thresh.SetInputData(epi) - thresh.ThresholdBetween(left_atrial_appendage_epi, left_atrial_appendage_epi) - thresh.InvertOn() - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") - thresh.Update() - else: - thresh = vtk.vtkThreshold() - thresh.SetInputData(epi) - thresh.ThresholdByLower(left_atrial_appendage_epi - 1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") - thresh.Update() - - low_LAA = thresh.GetOutput() - - thresh = vtk.vtkThreshold() - thresh.SetInputData(epi) - thresh.ThresholdByUpper(left_atrial_appendage_epi + 1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") - thresh.Update() - - up_LAA = thresh.GetOutput() - - thresh = vtk.vtkAppendFilter() - thresh.AddInputData(low_LAA) - thresh.AddInputData(up_LAA) - thresh.MergePointsOn() - thresh.Update() - - # inf_appendage_basis_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, inf_appendage_basis_id) - # sup_appendage_basis_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, sup_appendage_basis_id) - # bb_mv_id = get_in_surf1_closest_point_in_surf2(thresh.GetOutput(), epi, bb_mv_id) + thresh = get_threshold_between(epi, left_atrial_appendage_epi, left_atrial_appendage_epi, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") loc = vtk.vtkPointLocator() loc.SetDataSet(thresh.GetOutput()) @@ -1172,14 +1125,10 @@ def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): def find_tau(model, ub, lb, low_up, scalar): k = 1 while ub - lb > 0.01: - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) if low_up == "low": - thresh.ThresholdByLower((ub + lb) / 2) + thresh = get_lower_threshold(model, (ub + lb) / 2, "vtkDataObject::FIELD_ASSOCIATION_CELLS", scalar) else: - thresh.ThresholdByUpper((ub + lb) / 2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", scalar) - thresh.Update() + thresh = get_upper_threshold(model, (ub + lb) / 2, "vtkDataObject::FIELD_ASSOCIATION_CELLS", scalar) connect = vtk.vtkConnectivityFilter() connect.SetInputData(thresh.GetOutput()) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 8e6688a..cfd539b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -30,6 +30,8 @@ from vtk.numpy_interface import dataset_adapter as dsa from scipy.spatial import cKDTree +import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations + vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -337,29 +339,8 @@ def generate_sheet_dir(args, model, job): def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - if mode == 0: - thresh.ThresholdByUpper(thr1) - elif mode == 1: - thresh.ThresholdByLower(thr1) - elif mode == 2: - if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1, thr2) - else: - thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - thr = thresh.GetOutput() - thresh = vtk.vtkThreshold() - thresh.SetInputData(thr) - thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - - output = thresh.GetOutput() - - return output + return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, + thr2) def creat_tube_around_spline(points_data, radius): diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index ede3a6b..8b7dcff 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -562,149 +562,6 @@ def ra_generate_fiber(model, args, job): tag[SN_ids] = sinus_node - # meshNew = dsa.WrapDataObject(model) - # meshNew.CellData.append(tag, "elemTag") - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - - # print('Region growing...to get the tao_ct_minus...') - # # extract septum - # thresh = vtk.vtkThreshold() - # thresh.SetInputData(model) - # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r") - # thresh.ThresholdByLower(0.6) - # thresh.Update() - # septum = thresh.GetOutput() - # points_data = septum.GetPoints().GetData() - # septum_points = vtk.util.numpy_support.vtk_to_numpy(points_data) - - # # extract ICV form septum - # thresh = vtk.vtkThreshold() - # thresh.SetInputData(septum) - # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") - # thresh.ThresholdByUpper(tao_icv) - # thresh.Update() - # ICV = thresh.GetOutput() - # ICV = Method.extract_largest_region(ICV) - # points_data = ICV.GetPoints().GetData() - # ICV_points = vtk.util.numpy_support.vtk_to_numpy(points_data) - - # # extract SCV form septum - # thresh = vtk.vtkThreshold() - # thresh.SetInputData(septum) - # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") - # thresh.ThresholdByLower(tao_scv) - # thresh.Update() - # SCV = thresh.GetOutput() - # SCV = Method.extract_largest_region(SCV) - # points_data = SCV.GetPoints().GetData() - # SCV_points = vtk.util.numpy_support.vtk_to_numpy(points_data) - - # """ - # region growing to get tao_ct_minus - # """ - # # tao_ct_minus and tao_ct_plus - # value = -0.25 - # step = 0.005 - # touch_icv = 0 - # touch_scv = 0 - # k = 1 - - # while touch_icv == 0 or touch_scv == 0: - # thresh = vtk.vtkThreshold() - # thresh.SetInputData(septum) - # thresh.ThresholdByLower(value) - # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_w") - # thresh.Update() - # temp = thresh.GetOutput() - # points_data = temp.GetPoints().GetData() - # temp = vtk.util.numpy_support.vtk_to_numpy(points_data) - - # touch_icv = Method.multidim_intersect_bool(ICV_points, temp) - # touch_scv = Method.multidim_intersect_bool(SCV_points, temp) - # print("touch_icv: ", touch_icv) - # print("touch_scv: ", touch_scv) - # if touch_icv == 0 or touch_scv == 0: - # value += step - # print("Iteration: ", k) - # print("Value of tao_ct_minus: ", value) - # k += 1 - # tao_ct_minus = value + 0.001 - # print('Region growing...to get the tao_ct_minus...done') - # print("Final tao_ct_minus: ", tao_ct_minus) - # tao_ct_plus = tao_ct_minus + 0.02 - # print("Final tao_ct_plus: ", tao_ct_plus) - # tag = np.zeros(len(w)) - # print('Bundles selection...') - # #### Bundles selection #### - # for i in range(len(ab_grad)): - # if r[i] >= tao_tv: - # ab_grad[i] = r_grad[i] - # tag[i] = tricuspid_valve_epi - # else: - # if r[i] < tao_raw: - # if w[i] >= tao_ct_minus and w[i] <= tao_ct_plus: - # # ab_grad[i] = w_grad[i] - # tag[i] = crista_terminalis - # elif w[i] <= tao_ct_minus: - # if v[i] >= tao_icv or v[i] <= tao_scv: - # ab_grad[i] = v_grad[i] - # if v[i] >= tao_icv: - # tag[i] = inferior_vena_cava_epi - # if v[i] <= tao_scv: - # tag[i] = superior_vena_cava_epi - # else: - # tag[i] = right_atrial_lateral_wall_epi - # else: - # if v[i] >= tao_icv or v[i] <= tao_scv: - # ab_grad[i] = v_grad[i] - # if v[i] >= tao_icv: - # tag[i] = inferior_vena_cava_epi - # if v[i] <= tao_scv: - # tag[i] = superior_vena_cava_epi - # else: - # if w[i] < tao_ib: - # ab_grad[i] = v_grad[i] - # tag[i] = inter_caval_bundle_epi - # elif w[i] > tao_ras: - # ab_grad[i] = r_grad[i] #right_atrial_septum_lower_epi - # tag[i] = right_atrial_septum_epi - # # tag[i] =120 - # else: - # ab_grad[i] = r_grad[i] #right_atrial_septum_upper_epi - # tag[i] = right_atrial_septum_epi - # # tag[i] = 130 - # else: - # if v[i] >= tao_icv or v[i] <= tao_scv: - # ab_grad[i] = v_grad[i] - # if v[i] >= tao_icv: - # tag[i] = inferior_vena_cava_epi - # if v[i] <= tao_scv: - # tag[i] = superior_vena_cava_epi - # else: - # if w[i] >= 0: - # ab_grad[i] = r_grad[i] #right_atrial_septum_lower_epi - # tag[i] = right_atrial_septum_epi - # # tag[i] = 140 - # else: - # tag[i] = right_atrial_lateral_wall_epi - # if v[i] >= tao_icv or v[i] <= tao_scv: - # ab_grad[i] = v_grad[i] - # if v[i] >= tao_icv: - # tag[i] = inferior_vena_cava_epi - # if v[i] <= tao_scv: - # tag[i] = superior_vena_cava_epi - # # tag = Method.assign_ra_appendage(model, SCV, ra_appex_point, tag, right_atrial_appendage_epi) - - # meshNew = dsa.WrapDataObject(model) - # meshNew.CellData.append(tag, "elemTag") - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/RA_Tianbao_epi_with_fiber.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - print('Bundles selection...done') # normalize the gradient phie abs_phie_grad = np.linalg.norm(phie_grad, axis=1, keepdims=True) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 557489d..be4e3a3 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -34,6 +34,7 @@ from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa +import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from Atrial_LDRBM.Generate_Boundaries import extract_rings from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer @@ -196,29 +197,8 @@ def run(): def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) - if mode == 0: - thresh.ThresholdByUpper(thr1) - elif mode == 1: - thresh.ThresholdByLower(thr1) - elif mode == 2: - if int(vtk_version) >= 9: - thresh.ThresholdBetween(thr1, thr2) - else: - thresh.ThresholdByUpper(thr1) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - thr = thresh.GetOutput() - thresh = vtk.vtkThreshold() - thresh.SetInputData(thr) - thresh.ThresholdByLower(thr2) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_" + points_cells, array) - thresh.Update() - - output = thresh.GetOutput() - - return output + return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, + thr2) def find_elements_within_radius(mesh, points_data, radius): From c9d49f869302320639e6ad5ffdcd548e8f51fa9a Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 17:50:01 +0100 Subject: [PATCH 11/70] Replaced all calls of Methods.vtk_thr with mock version to newer thresholding function --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 1 + .../LDRBM/Fiber_LA/la_generate_fiber.py | 220 ++---------------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 109 +-------- .../LDRBM/Fiber_RA/create_bridges_test.py | 22 +- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 55 ++--- 5 files changed, 57 insertions(+), 350 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 91bab8b..7b73af2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -33,6 +33,7 @@ from scipy.spatial.distance import cosine import collections +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ get_threshold_between diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 61bd2e9..d2a0222 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -35,6 +35,8 @@ from la_laplace import laplace_0_1 import os +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -135,7 +137,7 @@ def la_generate_fiber(model, args, job): tao_lpv = Method.find_tau(model, ub, lb, "low", "phie_v") print('Calculating tao_lpv done! tap_lpv = ', tao_lpv) - thr = Method.vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) + thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) connect = vtk.vtkConnectivityFilter() connect.SetInputData(thr) connect.SetExtractionModeToAllRegions() @@ -147,12 +149,8 @@ def la_generate_fiber(model, args, job): model = laplace_0_1(args, job, model, "RPV", "LAA", "phie_ab2") - thr = Method.vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) - # thr = Method.vtk_thr(model, 1, "CELLS","phie_v", 0.35) - # found, val = Method.optimize_shape_PV(thr, 10, 0) - # print('Calculating opt_tao_lpv done! tap_lpv = ', val) - # if val!=0.35: - # thr = Method.vtk_thr(model, 1, "CELLS","phie_v",val) + thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) + phie_r2_tau_lpv = vtk.util.numpy_support.vtk_to_numpy(thr.GetCellData().GetArray('phie_r2')) max_phie_r2_tau_lpv = np.max(phie_r2_tau_lpv) @@ -169,7 +167,7 @@ def la_generate_fiber(model, args, job): tao_rpv = Method.find_tau(model, ub, lb, "up", "phie_v") print('Calculating tao_rpv done! tap_rpv = ', tao_rpv) - thr = Method.vtk_thr(model, 0, "CELLS", "phie_v", tao_rpv) + thr = vtk_thr(model, 0, "CELLS", "phie_v", tao_rpv) connect = vtk.vtkConnectivityFilter() connect.SetInputData(thr) @@ -182,198 +180,6 @@ def la_generate_fiber(model, args, job): start_time = datetime.datetime.now() print('Calculating fibers... ' + str(start_time)) - #### Bundles selection #### - # # Volume mesh - # if 0:# args.mesh_type == 'vol': - # tag = np.zeros(len(r)) - - # for i in range(len(ab_grad)): - # # tagging endo-layer - # if phie[i] <= 0.5: - # if r[i] >= tao_mv: - # tag[i] = mitral_valve_endo - # elif ab[i] < max_phie_ab_tau_lpv+0.01 and r2[i]>max_phie_r2_tau_lpv+0.01: - # tag[i] = left_atrial_appendage_endo - # elif v[i] <= tao_lpv and i in PVs["LIPV"]: - # tag[i] = inferior_left_pulmonary_vein_endo - # elif v[i] <= tao_lpv and i in PVs["LSPV"]: - # tag[i] = superior_left_pulmonary_vein_endo - # elif v[i] >= tao_rpv and i in PVs["RIPV"]: - # tag[i] = inferior_right_pulmonary_vein_endo - # elif v[i] >= tao_rpv and i in PVs["RSPV"]: - # tag[i] = superior_right_pulmonary_vein_endo - # else: - # tag[i] = left_atrial_wall_endo - # # tagging epi-layer - # else: - # if r[i] >= tao_mv: - # ab_grad[i] = r_grad[i] - # tag[i] = mitral_valve_epi - # elif ab[i] < max_phie_ab_tau_lpv+0.01 and r2[i]>max_phie_r2_tau_lpv+0.01: - # tag[i] = left_atrial_appendage_epi - # elif v[i] <= tao_lpv and i in PVs["LIPV"]: - # ab_grad[i] = v_grad[i] - # tag[i] = inferior_left_pulmonary_vein_epi - # elif v[i] <= tao_lpv and i in PVs["LSPV"]: - # ab_grad[i] = v_grad[i] - # tag[i] = superior_left_pulmonary_vein_epi - # elif v[i] >= tao_rpv and i in PVs["RIPV"]: - # ab_grad[i] = v_grad[i] - # tag[i] = inferior_right_pulmonary_vein_epi - # elif v[i] >= tao_rpv and i in PVs["RSPV"]: - # ab_grad[i] = v_grad[i] - # tag[i] = superior_right_pulmonary_vein_epi - # else: - # tag[i] = left_atrial_wall_epi - - # meshNew = dsa.WrapDataObject(model) - # meshNew.CellData.append(tag, "elemTag") - # model = meshNew.VTKObject - - # # normlize the gradient phie - # abs_phie_grad = np.linalg.norm(phie_grad, axis=1, keepdims=True) - # abs_phie_grad = np.where(abs_phie_grad != 0, abs_phie_grad, 1) - # phie_grad_norm = phie_grad / abs_phie_grad - - # ##### Local coordinate system ##### - # # et - # et = phie_grad_norm - # print('############### et ###############') - # print(et) - - # # k - # k = ab_grad - # print('############### k ###############') - # print(k) - - # # en - # en = ab_grad - # #for i in range(len(k)): - # # en[i] = k[i] - np.dot(k[i], et[i]) * et[i] - - # en = k - np.dot(k, et) * et - # # normalize the en - # abs_en = np.linalg.norm(en, axis=1, keepdims=True) - # abs_en = np.where(abs_en != 0, abs_en, 1) - # en = en / abs_en - # print('############### en ###############') - # print(en) - - # # el - # el = np.cross(en, et) - # print('############### el ###############') - # print(el) - - # abs_v_grad = np.linalg.norm(v_grad, axis=1, keepdims=True) - # abs_v_grad = np.where(abs_v_grad != 0, abs_v_grad, 1) - # v_grad_norm = v_grad / abs_v_grad - # ### Subendo bundle selection - # for i in range(len(v_grad_norm)): - # if phie[i] < 0.5 and v[i] <= 0.2: - # el[i] = v_grad_norm[i] - - # end_time = datetime.datetime.now() - # running_time = end_time - start_time - # print('Calculating fibers... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - - # reader = vtk.vtkUnstructuredGridReader() - # reader.SetFileName('Mesh/LA_mesh.vtk') - # reader.Update() - # model = reader.GetOutput() - - # print("Creating bachmann bundles...") - - # # Extract surface - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(model) - # geo_filter.PassThroughPointIdsOn() - # geo_filter.Update() - # # Get only epi - # thr = Method.vtk_thr(geo_filter.GetOutput(), 2, "CELLS","elemTag",mitral_valve_epi, left_atrial_roof_epi) - # # Bachmann Bundle - - # # Get ending point of wide BB - # # Extract the MV - # thr = Method.vtk_thr(thr, 2, "CELLS","elemTag",mitral_valve_epi, mitral_valve_epi) - - # # Get the closest point to the inferior appendage base in the MV - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(thr) - # loc.BuildLocator() - - # bb_mv_id = int(model.GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(model.GetPoint(inf_appendage_basis_id)))[0]) - - # thresh = vtk.vtkThreshold() - # thresh.SetInputData(model) - # thresh.ThresholdBetween(max_phie_ab_tau_lpv-0.1, max_phie_ab_tau_lpv+0.1) - # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_ab") - # thresh.Update() - - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(thresh.GetOutput()) - # loc.BuildLocator() - - # inf_appendage_basis_id = int(thresh.GetOutput().GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(df["MV"].to_numpy()))[0]) - - # thresh = vtk.vtkThreshold() - # thresh.SetInputData(thresh.GetOutput()) - # thresh.ThresholdBetween(max_phie_r2_tau_lpv-0.1, max_phie_r2_tau_lpv+0.1) - # thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r2") - # thresh.Update() - - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(thresh.GetOutput()) - # loc.BuildLocator() - - # sup_appendage_basis_id = int(thresh.GetOutput().GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(df["LAA"].to_numpy()))[0]) - - # bb_left = Method.get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id) - - # tag = Method.assign_element_tag_around_path_within_radius(model, bb_left, 2, tag, bachmann_bundel_left) - # el = Method.assign_element_fiber_around_path_within_radius(model, bb_left, 2, el, smooth=True) - - # # # Bachmann_Bundle internal connection - # # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(la_appex_point) - # # la_connect_point = np.asarray(la_connect_point) - # # - # # path_start_end = np.vstack((appendage_basis, la_connect_point)) - # # path_bb_ra = Method.creat_center_line(path_start_end) - # # tag = Method.assign_element_tag_around_path_within_radius(model, path_bb_ra, 2, tag, bachmann_bundel_left) - # # el = Method.assign_element_fiber_around_path_within_radius(model, path_bb_ra, 2, el, smooth=True) - - # print("Creating bachmann bundles... done") - # abs_el = np.linalg.norm(el, axis=1, keepdims=True) - # interpolate_arr = np.asarray([0, 0, 1]) - # index = np.argwhere(abs_el == 0) - # print('There is',len(index),'zero vector(s).') - # for var in index: - # el[var[0]] = interpolate_arr - - # #### save the result into vtk #### - # start_time = datetime.datetime.now() - # print('Writinga as LA_with_fiber... ' + str(start_time)) - - # # fiber_data = vtk.util.numpy_support.numpy_to_vtk(el, deep=True, array_type=vtk.VTK_DOUBLE) - # # fiber_data.SetNumberOfComponents(3) - # # fiber_data.SetName("fiber") - # # model.GetCellData().SetVectors(fiber_data) # AddArray(fiber_data) - - # # tag_data = vtk.util.numpy_support.numpy_to_vtk(tag, deep=True, array_type=vtk.VTK_DOUBLE) - # # tag_data.SetNumberOfComponents(1) - # # tag_data.SetName("elemTag") - # # model.GetCellData().RemoveArray("Cell_ids") - # # model.GetCellData().RemoveArray("elemTag") - # # model.GetCellData().SetScalars(tag_data) - - # meshNew = dsa.WrapDataObject(model) - # meshNew.CellData.append(tag, "elemTag") - # meshNew.CellData.append(el, "fiber") - - # model = meshNew.VTKObject - - # end_time = datetime.datetime.now() - # running_time = end_time - start_time - # print('Writing as LA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') # Bilayer mesh if args.mesh_type == 'bilayer': @@ -388,7 +194,7 @@ def la_generate_fiber(model, args, job): else: # Volume mesh tag = np.ones(len(r), dtype=int) * left_atrial_wall_epi - epi = Method.vtk_thr(model, 0, "CELLS", "phie_phi", 0.5) + epi = vtk_thr(model, 0, "CELLS", "phie_phi", 0.5) epi_ids = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('Global_ids')) @@ -398,13 +204,13 @@ def la_generate_fiber(model, args, job): tag[endo_ids] = left_atrial_wall_endo - LAA_s = Method.vtk_thr(model, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv + 0.01) + LAA_s = vtk_thr(model, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv + 0.01) - LAA_s = Method.vtk_thr(LAA_s, 0, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03) + LAA_s = vtk_thr(LAA_s, 0, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03) ## Optimize shape of LAA solving a laplacian with 0 in LAA and 1 in the boundary of LAA_s - LAA_bb = Method.vtk_thr(model, 2, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03, max_phie_ab_tau_lpv + 0.01) + LAA_bb = vtk_thr(model, 2, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03, max_phie_ab_tau_lpv + 0.01) LAA_bb_ids = vtk.util.numpy_support.vtk_to_numpy(LAA_bb.GetPointData().GetArray('Global_ids')) @@ -422,7 +228,7 @@ def la_generate_fiber(model, args, job): LAA_s = laplace_0_1(args, job, model, "LAA", "LAA_bb", "phie_ab3") - LAA_s = Method.vtk_thr(LAA_s, 1, "POINTS", "phie_ab3", 0.95) + LAA_s = vtk_thr(LAA_s, 1, "POINTS", "phie_ab3", 0.95) ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_MV.vtx', skiprows=2, dtype=int) @@ -516,7 +322,7 @@ def la_generate_fiber(model, args, job): norm = norm / np.linalg.norm(norm) - band_s = Method.vtk_thr(epi, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv) + band_s = vtk_thr(epi, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv) plane = vtk.vtkPlane() plane.SetNormal(norm[0], norm[1], norm[2]) @@ -742,7 +548,7 @@ def la_generate_fiber(model, args, job): geo_filter.SetInputData(model) geo_filter.Update() surf = geo_filter.GetOutput() - epi_surf = Method.vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) + epi_surf = vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) epi_surf_ids = vtk.util.numpy_support.vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) # epi_surf_id_list = vtk.vtkIdList() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 6b0fa65..bb9db6a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -38,6 +38,8 @@ import pickle from numpy.linalg import norm +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -65,14 +67,11 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): mitral_valve_epi = int(tag_dict["mitral_valve_epi"]) tricuspid_valve_epi = int(tag_dict["tricuspid_valve_epi"]) - # la_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) geo_filter_la = vtk.vtkGeometryFilter() geo_filter_la.SetInputData(la_epi) geo_filter_la.Update() la_epi_surface = geo_filter_la.GetOutput() - # ra_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) - geo_filter_ra = vtk.vtkGeometryFilter() geo_filter_ra.SetInputData(ra_epi) geo_filter_ra.Update() @@ -82,10 +81,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): IVC_p = np.array(df["IVC"]) TV_p = np.array(df["TV"]) - ra_septum = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", right_atrial_septum_epi, right_atrial_septum_epi) - la_wall = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", left_atrial_wall_epi, left_atrial_wall_epi) - mv_la = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", mitral_valve_epi, mitral_valve_epi) - tv_ra = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) + ra_septum = vtk_thr(ra_epi, 2, "CELLS", "elemTag", right_atrial_septum_epi, right_atrial_septum_epi) + la_wall = vtk_thr(la_epi, 2, "CELLS", "elemTag", left_atrial_wall_epi, left_atrial_wall_epi) + mv_la = vtk_thr(la_epi, 2, "CELLS", "elemTag", mitral_valve_epi, mitral_valve_epi) + tv_ra = vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) # Find middle and upper posterior bridges points @@ -225,102 +224,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): "-surf=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj", "-outmsh=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.vtk"]) - # if args.mesh_type == "vol": - - # la_ra_usg = append_filter.GetOutput() - # print('reading done!') - - # bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] - # earth_cell_ids_list = [] - # for var in bridge_list: - # reader = vtk.vtkUnstructuredGridReader() - # reader.SetFileName(job.ID+"/bridges/"+str(var)+'_bridge_resampled.vtk') - # reader.Update() - # bridge_usg = reader.GetOutput() - - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(bridge_usg) - # geo_filter.Update() - # bridge = geo_filter.GetOutput() - - # locator = vtk.vtkStaticPointLocator() - # locator.SetDataSet(la_ra_usg) - # locator.BuildLocator() - - # intersection_points = bridge_usg.GetPoints().GetData() - # intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) - - # earth_point_ids_temp = vtk.vtkIdList() - # earth_point_ids = vtk.vtkIdList() - # for i in range(len(intersection_points)): - # locator.FindPointsWithinRadius(0.7*args.scale, intersection_points[i], earth_point_ids_temp) - # for j in range(earth_point_ids_temp.GetNumberOfIds()): - # earth_point_ids.InsertNextId(earth_point_ids_temp.GetId(j)) - - # earth_cell_ids_temp = vtk.vtkIdList() - # earth_cell_ids = vtk.vtkIdList() - # for i in range(earth_point_ids.GetNumberOfIds()): - # la_ra_usg.GetPointCells(earth_point_ids.GetId(i),earth_cell_ids_temp) - # for j in range(earth_cell_ids_temp.GetNumberOfIds()): - # earth_cell_ids.InsertNextId(earth_cell_ids_temp.GetId(j)) - # earth_cell_ids_list += [earth_cell_ids_temp.GetId(j)] - # extract = vtk.vtkExtractCells() - # extract.SetInputData(la_ra_usg) - # extract.SetCellList(earth_cell_ids) - # extract.Update() - - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(extract.GetOutput()) - # geo_filter.Update() - # earth = geo_filter.GetOutput() - - # cleaner = vtk.vtkCleanPolyData() - # cleaner.SetInputData(earth) - # cleaner.Update() - - # # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) - # writer = vtk.vtkOBJWriter() - # writer.SetFileName(job.ID+"/bridges/"+str(var)+"_earth.obj") - # writer.SetInputData(cleaner.GetOutput()) - # writer.Write() - - # print("Extracted earth") - # cell_id_all = [] - # for i in range(la_ra_usg.GetNumberOfCells()): - # cell_id_all.append(i) - - # la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) - # la_ra_new = vtk.vtkIdList() - # for var in la_diff: - # la_ra_new.InsertNextId(var) - - # extract = vtk.vtkExtractCells() - # extract.SetInputData(la_ra_usg) - # extract.SetCellList(la_ra_new) - # extract.Update() - - # append_filter = vtk.vtkAppendFilter() - # append_filter.MergePointsOn() - # #append_filter.SetTolerance(0.01*args.scale) - # append_filter.AddInputData(extract.GetOutput()) - - # elif args.mesh_type == "bilayer": - - # if args.mesh_type == "bilayer": - # la_ra_usg = append_filter.GetOutput() - # else: - # la_ra_usg_vol = append_filter.GetOutput() - # ra_epi = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 11,18) - # ra_BB = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_right,bachmann_bundel_right) - # la_epi = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 61,70) - # la_BB = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_left,bachmann_bundel_left) - - # append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(la_epi) - # append_filter.AddInputData(ra_epi) - # append_filter.AddInputData(la_BB) - # append_filter.AddInputData(ra_BB) - # append_filter.Update() la_ra_usg = append_filter.GetOutput() # this has already elemTag if args.debug: diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index f3371d4..0815bfd 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -46,6 +46,8 @@ import Methods_RA as Method import pandas as pd +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -120,13 +122,13 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): mitral_valve_epi = int(tag_dict["mitral_valve_epi"]) tricuspid_valve_epi = int(tag_dict["tricuspid_valve_epi"]) - # la_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) + # la_epi = vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) geo_filter_la = vtk.vtkGeometryFilter() geo_filter_la.SetInputData(la_epi) geo_filter_la.Update() la_epi_surface = geo_filter_la.GetOutput() - # ra_epi = Method.vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) + # ra_epi = vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) geo_filter_ra = vtk.vtkGeometryFilter() geo_filter_ra.SetInputData(ra_epi) @@ -137,10 +139,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): IVC_p = np.array(df["IVC"]) TV_p = np.array(df["TV"]) - ra_septum = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", right_atrial_septum_epi, right_atrial_septum_epi) - la_wall = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", left_atrial_wall_epi, left_atrial_wall_epi) - mv_la = Method.vtk_thr(la_epi, 2, "CELLS", "elemTag", mitral_valve_epi, mitral_valve_epi) - tv_ra = Method.vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) + ra_septum = vtk_thr(ra_epi, 2, "CELLS", "elemTag", right_atrial_septum_epi, right_atrial_septum_epi) + la_wall = vtk_thr(la_epi, 2, "CELLS", "elemTag", left_atrial_wall_epi, left_atrial_wall_epi) + mv_la = vtk_thr(la_epi, 2, "CELLS", "elemTag", mitral_valve_epi, mitral_valve_epi) + tv_ra = vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) # Find middle and upper posterior bridges points @@ -361,10 +363,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # la_ra_usg = append_filter.GetOutput() # else: # la_ra_usg_vol = append_filter.GetOutput() - # ra_epi = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 11,18) - # ra_BB = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_right,bachmann_bundel_right) - # la_epi = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 61,70) - # la_BB = Method.vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_left,bachmann_bundel_left) + # ra_epi = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 11,18) + # ra_BB = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_right,bachmann_bundel_right) + # la_epi = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 61,70) + # la_BB = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_left,bachmann_bundel_left) # append_filter = vtk.vtkAppendFilter() # append_filter.AddInputData(la_epi) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 8b7dcff..7aa638c 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -36,6 +36,8 @@ import os from scipy.spatial import cKDTree +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) from create_bridges import add_free_bridge @@ -175,13 +177,6 @@ def ra_generate_fiber(model, args, job): k = np.copy(ab_grad) # # # Get valve using Laplacian solutions - - # TV_s = Method.vtk_thr(model,0,"CELLS","phie_r",tao_tv) # grad_r - - # TV_ids = vtk.util.numpy_support.vtk_to_numpy(TV_s.GetCellData().GetArray('Global_ids')) - - # no_TV_s = Method.vtk_thr(model, 1,"CELLS","phie_r",tao_tv) - # Use fixed thickness ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_TV.vtx', skiprows=2, dtype=int) @@ -229,17 +224,17 @@ def ra_generate_fiber(model, args, job): k[TV_ids] = r_grad[TV_ids] - IVC_s = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_v", tao_icv) # Changed 0-1 because ICV and SVC are inverted - no_IVC_s = Method.vtk_thr(no_TV_s, 1, "CELLS", "phie_v", tao_icv) # Changed 1-0 + IVC_s = vtk_thr(no_TV_s, 0, "CELLS", "phie_v", tao_icv) # Changed 0-1 because ICV and SVC are inverted + no_IVC_s = vtk_thr(no_TV_s, 1, "CELLS", "phie_v", tao_icv) # Changed 1-0 IVC_s = Method.extract_largest_region(IVC_s) # Added max_phie_r_ivc = np.max(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_r'))) + 0.2 - RAW_s = Method.vtk_thr(no_TV_s, 1, "CELLS", "phie_r", max_phie_r_ivc) # Added +0.03 fro dk01 + RAW_s = vtk_thr(no_TV_s, 1, "CELLS", "phie_r", max_phie_r_ivc) # Added +0.03 fro dk01 - SVC_s = Method.vtk_thr(RAW_s, 1, "CELLS", "phie_v", tao_scv) # Changed 1->0 - no_SVC_s = Method.vtk_thr(RAW_s, 0, "CELLS", "phie_v", tao_scv) # Changed 0->1 + SVC_s = vtk_thr(RAW_s, 1, "CELLS", "phie_v", tao_scv) # Changed 1->0 + no_SVC_s = vtk_thr(RAW_s, 0, "CELLS", "phie_v", tao_scv) # Changed 0->1 SVC_s = Method.extract_largest_region(SVC_s) @@ -267,10 +262,10 @@ def ra_generate_fiber(model, args, job): # thr_min = 0.150038 # thr_max = 0.38518 - # CT_band = Method.vtk_thr(RAW_s, 2,"CELLS","phie_w", thr_min, thr_max) # dk01 fit_both - CT_band = Method.vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w + # CT_band = vtk_thr(RAW_s, 2,"CELLS","phie_w", thr_min, thr_max) # dk01 fit_both + CT_band = vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w CT_band = Method.extract_largest_region(CT_band) - CT_ub = Method.vtk_thr(RAW_s, 2, "CELLS", "phie_w", tao_ct_plus - 0.02, tao_ct_plus) # grad_w + CT_ub = vtk_thr(RAW_s, 2, "CELLS", "phie_w", tao_ct_plus - 0.02, tao_ct_plus) # grad_w CT_ub = Method.extract_largest_region(CT_ub) @@ -357,7 +352,7 @@ def ra_generate_fiber(model, args, job): # SVC_CT_pt_id = loc.FindClosestPoint(SVC_CT_pt) - CT_minus = Method.vtk_thr(RAW_s, 1, "CELLS", "phie_w", tao_ct_plus) # grad_ab + CT_minus = vtk_thr(RAW_s, 1, "CELLS", "phie_w", tao_ct_plus) # grad_ab RAW_I_ids = vtk.util.numpy_support.vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) @@ -378,9 +373,9 @@ def ra_generate_fiber(model, args, job): k[TV_ids] = r_grad[TV_ids] - CT_plus = Method.vtk_thr(RAW_s, 0, "CELLS", "phie_w", tao_ct_plus) + CT_plus = vtk_thr(RAW_s, 0, "CELLS", "phie_w", tao_ct_plus) - RAW_S = Method.vtk_thr(CT_plus, 2, "CELLS", "phie_v", tao_scv, + RAW_S = vtk_thr(CT_plus, 2, "CELLS", "phie_v", tao_scv, tao_icv) # IB_S grad_v Changed order tao_scv, tao_icv RAW_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_S.GetCellData().GetArray('Global_ids')) @@ -389,7 +384,7 @@ def ra_generate_fiber(model, args, job): k[RAW_S_ids] = ab_grad[RAW_S_ids] - IB = Method.vtk_thr(RAW_S, 1, "CELLS", "phie_r", 0.05) # grad_r or w + IB = vtk_thr(RAW_S, 1, "CELLS", "phie_r", 0.05) # grad_r or w IB_ids = vtk.util.numpy_support.vtk_to_numpy(IB.GetCellData().GetArray('Global_ids')) @@ -423,8 +418,8 @@ def ra_generate_fiber(model, args, job): meshExtractFilter.Update() septal_surf = meshExtractFilter.GetOutput() - RAS_S = Method.vtk_thr(septal_surf, 0, "CELLS", "phie_w", tao_ct_plus) - RAS_S = Method.vtk_thr(RAS_S, 0, "CELLS", "phie_r", 0.05) # grad_r or w + RAS_S = vtk_thr(septal_surf, 0, "CELLS", "phie_w", tao_ct_plus) + RAS_S = vtk_thr(RAS_S, 0, "CELLS", "phie_r", 0.05) # grad_r or w if args.debug: Method.writer_vtk(septal_surf, f'{args.mesh}_surf/' + "septal_surf.vtk") @@ -436,7 +431,7 @@ def ra_generate_fiber(model, args, job): k[RAS_S_ids] = r_grad[RAS_S_ids] - RAW_low = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_r", max_phie_r_ivc) + RAW_low = vtk_thr(no_TV_s, 0, "CELLS", "phie_r", max_phie_r_ivc) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(RAW_low) @@ -444,7 +439,7 @@ def ra_generate_fiber(model, args, job): meshExtractFilter.Update() RAS_low = meshExtractFilter.GetOutput() - RAS_low = Method.vtk_thr(RAS_low, 0, "CELLS", "phie_w", 0) # grad_r overwrites the previous + RAS_low = vtk_thr(RAS_low, 0, "CELLS", "phie_w", 0) # grad_r overwrites the previous RAS_low_ids = vtk.util.numpy_support.vtk_to_numpy(RAS_low.GetCellData().GetArray('Global_ids')) @@ -452,7 +447,7 @@ def ra_generate_fiber(model, args, job): k[RAS_low_ids] = r_grad[RAS_low_ids] - RAW_low = Method.vtk_thr(RAW_low, 1, "CELLS", "phie_w", 0) # grad_ab + RAW_low = vtk_thr(RAW_low, 1, "CELLS", "phie_w", 0) # grad_ab RAW_low_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_low.GetCellData().GetArray('Global_ids')) @@ -495,7 +490,7 @@ def ra_generate_fiber(model, args, job): k[CS_ids] = ab_grad[CS_ids] # tag = Method.assign_ra_appendage(model, SVC_s, np.array(df["RAA"]), tag, right_atrial_appendage_epi) - RAA_s = Method.vtk_thr(no_TV_s, 0, "CELLS", "phie_v2", tao_RAA) + RAA_s = vtk_thr(no_TV_s, 0, "CELLS", "phie_v2", tao_RAA) if args.debug: Method.writer_vtk(RAS_low, f'{args.mesh}_surf/' + "ras_low.vtk") @@ -655,7 +650,7 @@ def ra_generate_fiber(model, args, job): endo = vtk.vtkUnstructuredGrid() endo.DeepCopy(model) - CT = Method.vtk_thr(model, 2, "CELLS", "elemTag", crista_terminalis, crista_terminalis) + CT = vtk_thr(model, 2, "CELLS", "elemTag", crista_terminalis, crista_terminalis) CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) @@ -787,9 +782,9 @@ def ra_generate_fiber(model, args, job): geo_filter.Update() surface = geo_filter.GetOutput() - epi = Method.vtk_thr(surface, 0, "POINTS", "phie_phi", 0.5) + epi = vtk_thr(surface, 0, "POINTS", "phie_phi", 0.5) - endo = Method.vtk_thr(surface, 1, "POINTS", "phie_phi", 0.5) + endo = vtk_thr(surface, 1, "POINTS", "phie_phi", 0.5) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(endo) @@ -1131,7 +1126,7 @@ def ra_generate_fiber(model, args, job): writer.SetInputData(endo) writer.Write() - CT_PMs = Method.vtk_thr(endo, 2, "CELLS", "elemTag", pectinate_muscle, crista_terminalis) + CT_PMs = vtk_thr(endo, 2, "CELLS", "elemTag", pectinate_muscle, crista_terminalis) writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': @@ -1305,7 +1300,7 @@ def ra_generate_fiber(model, args, job): geo_filter.Update() la_surf = geo_filter.GetOutput() - la_epi = Method.vtk_thr(la_surf, 2, "CELLS", "elemTag", left_atrial_wall_epi, 99) + la_epi = vtk_thr(la_surf, 2, "CELLS", "elemTag", left_atrial_wall_epi, 99) df = pd.read_csv(meshname + "_LA_vol_surf/rings_centroids.csv") From 5341014a569a0f382514359209d680f39cf2367f Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 18:18:32 +0100 Subject: [PATCH 12/70] Replaced all calls of threshold between with newer version of vtk in helper methods package --- .../Generate_Boundaries/extract_rings.py | 16 +++++--- .../extract_rings_TOP_epi_endo.py | 15 ++++--- .../Generate_Boundaries/separate_epi_endo.py | 38 +++++++++--------- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 23 ++--------- standalones/getmarks.py | 39 +++++-------------- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 776da3d..3f23a46 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -25,6 +25,8 @@ under the License. """ import os +from logging import warning + import numpy as np from glob import glob import pandas as pd @@ -37,7 +39,7 @@ from scipy.spatial import cKDTree from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader -from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -140,10 +142,14 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] - thr = vtk.vtkThreshold() - thr.SetInputData(mesh_conn) - thr.ThresholdBetween(LA_tag, LA_tag) - thr.Update() + #thr = vtk.vtkThreshold() + #thr.SetInputData(mesh_conn) + #thr.ThresholdBetween(LA_tag, LA_tag) + #thr.Update() + + warning("WARNING: Should be checkt for functionality extract_rings l151") + thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thr.GetOutputPort()) geo_filter.Update() diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index c8f8638..a9f59be 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -25,6 +25,8 @@ under the License. """ import os +from logging import warning + import numpy as np from glob import glob import pandas as pd @@ -37,7 +39,7 @@ from scipy.spatial import cKDTree from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader -from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -135,10 +137,13 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] - thr = vtk.vtkThreshold() - thr.SetInputData(mesh_conn) - thr.ThresholdBetween(LA_tag, LA_tag) - thr.Update() + # thr = vtk.vtkThreshold() + # thr.SetInputData(mesh_conn) + # thr.ThresholdBetween(LA_tag, LA_tag) + # thr.Update() + warning("WARNING: Should be checkt for functionality extract_rings_TOP_epi_endo l145") + thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") + geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputConnection(thr.GetOutputPort()) geo_filter.Update() diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index c8931e1..a986d34 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -6,6 +6,8 @@ import csv import sys +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between + sys.path.append('Atrial_LDRBM/Generate_Boundaries') from extract_rings import smart_reader @@ -28,14 +30,14 @@ def separate_epi_endo(path, atrium): model = smart_reader(path) - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) if atrium == "LA": - thresh.ThresholdBetween(left_atrial_wall_endo, left_atrial_wall_epi) + thresh = get_threshold_between(model, left_atrial_wall_endo, left_atrial_wall_epi, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") elif atrium == "RA": - thresh.ThresholdBetween(right_atrial_wall_endo, right_atrial_wall_epi) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") - thresh.Update() + thresh = get_threshold_between(model, right_atrial_wall_endo, right_atrial_wall_epi, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") + else: + raise ValueError("Atrium has to be LA or RA") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(thresh.GetOutput()) @@ -46,14 +48,14 @@ def separate_epi_endo(path, atrium): writer.SetInputData(geo_filter.GetOutput()) writer.Write() - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) if atrium == "LA": - thresh.ThresholdBetween(left_atrial_wall_epi, left_atrial_wall_epi) + thresh = get_threshold_between(model, left_atrial_wall_epi, left_atrial_wall_epi, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") elif atrium == "RA": - thresh.ThresholdBetween(right_atrial_wall_epi, right_atrial_wall_epi) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") - thresh.Update() + thresh = get_threshold_between(right_atrial_wall_epi, right_atrial_wall_epi, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") + else: + raise ValueError("Atrium has to be LA or RA") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(thresh.GetOutput()) @@ -65,14 +67,14 @@ def separate_epi_endo(path, atrium): writer.SetInputData(la_epi) writer.Write() - thresh = vtk.vtkThreshold() - thresh.SetInputData(model) if atrium == "LA": - thresh.ThresholdBetween(left_atrial_wall_endo, left_atrial_wall_endo) + thresh = get_threshold_between(model, left_atrial_wall_endo, left_atrial_wall_endo, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") elif atrium == "RA": - thresh.ThresholdBetween(right_atrial_wall_endo, right_atrial_wall_endo) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") - thresh.Update() + thresh = get_threshold_between(model, right_atrial_wall_endo, right_atrial_wall_endo, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") + else: + raise ValueError("Atrium has to be LA or RA") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(thresh.GetOutput()) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 7b73af2..b532c75 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -898,11 +898,8 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_epi): # Extract the LAA - thresh = vtk.vtkThreshold() - thresh.SetInputData(epi) - thresh.ThresholdBetween(left_atrial_appendage_epi, left_atrial_appendage_epi) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") - thresh.Update() + thresh = get_threshold_between(epi, left_atrial_appendage_epi, left_atrial_appendage_epi, + "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") LAA = thresh.GetOutput() @@ -954,28 +951,16 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e LAA_pt_far_from_LIPV = LAA_pts_border[i] # Extract the MV - thresh = vtk.vtkThreshold() - thresh.SetInputData(epi) - thresh.ThresholdBetween(mitral_valve_epi, mitral_valve_epi) - thresh.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") - thresh.Update() + thresh = get_threshold_between(epi, mitral_valve_epi, mitral_valve_epi, "vtkDataObject::FIELD_ASSOCIATION_CELLS", + "elemTag") MV = thresh.GetOutput() - # MV_pts = vtk.util.numpy_support.vtk_to_numpy(MV.GetPoints().GetData()) - - # tree = cKDTree(LAA_pts) - # max_dist = np.sqrt(np.sum((df["MV"].to_numpy()-df["LAA"].to_numpy())**2, axis=0)) - # dd, ii = tree.query(MV_pts, distance_upper_bound=max_dist) - - # inf_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ii[np.argmin(dd)])[0]) # Get the closest point to the inferior appendage base in the MV loc = vtk.vtkPointLocator() loc.SetDataSet(MV) loc.BuildLocator() - # bb_mv_id = int(MV.GetPointData().GetArray('Global_ids').GetTuple(loc.FindClosestPoint(epi.GetPoint(bb_mv_id)))[0]) - bb_mv = MV.GetPoint(loc.FindClosestPoint(bb_mv_laa)) thresh = get_threshold_between(epi, left_atrial_appendage_epi, left_atrial_appendage_epi, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") diff --git a/standalones/getmarks.py b/standalones/getmarks.py index b97c024..c2f87ae 100644 --- a/standalones/getmarks.py +++ b/standalones/getmarks.py @@ -36,6 +36,8 @@ from sklearn.neighbors import NearestNeighbors import argparse +from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between + def parser(): parser = argparse.ArgumentParser(description='Generate landmarks for fitting SSM.') @@ -69,44 +71,21 @@ def get_landmarks(mesh, prealigned=1, scale=1): model_polydata = function.to_polydata(model) - thr = vtk.vtkThreshold() - thr.SetInputData(model) - thr.AllScalarsOff() - thr.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") - thr.ThresholdBetween(5, 5) - thr.Update() + thr = get_threshold_between(model, 5, 5, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") rsv = thr.GetOutput() - thr = vtk.vtkThreshold() - thr.SetInputData(model) - thr.AllScalarsOff() - thr.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") - thr.ThresholdBetween(4, 4) - thr.Update() + thr = get_threshold_between(model, 4, 4,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag" ) riv = thr.GetOutput() - thr = vtk.vtkThreshold() - thr.SetInputData(model) - thr.AllScalarsOff() - thr.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") - thr.ThresholdBetween(3, 3) - thr.Update() + + thr=get_threshold_between(model,3,3,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") lsv = thr.GetOutput() - thr = vtk.vtkThreshold() - thr.SetInputData(model) - thr.AllScalarsOff() - thr.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") - thr.ThresholdBetween(2, 2) - thr.Update() + + thr=get_threshold_between(model,2,2,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") liv = thr.GetOutput() - thr = vtk.vtkThreshold() - thr.SetInputData(model) - thr.AllScalarsOff() - thr.SetInputArrayToProcess(0, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") - thr.ThresholdBetween(1, 1) - thr.Update() + thr=get_threshold_between(model,1,1,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") mv = thr.GetOutput() rsv_points = vtk.util.numpy_support.vtk_to_numpy(rsv.GetPoints().GetData()) From d5037af4b14f85f471b9df5c71abf4c8c3f1c825 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Mon, 25 Nov 2024 19:24:39 +0100 Subject: [PATCH 13/70] First replacement of all vtk writers by regex search --- .../Generate_Boundaries/extract_rings.py | 14 ++-- .../extract_rings_TOP_epi_endo.py | 6 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 37 +++------ .../LDRBM/Fiber_LA/la_calculate_gradient.py | 6 +- .../LDRBM/Fiber_LA/la_generate_fiber.py | 35 +++----- Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py | 17 ++-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 23 ++---- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 54 +++---------- .../LDRBM/Fiber_RA/create_bridges_test.py | 56 +++---------- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 12 +-- .../LDRBM/Fiber_RA/ra_calculate_gradient.py | 6 +- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 79 ++++++------------- Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py | 11 ++- standalones/open_orifices_with_curvature.py | 33 ++------ standalones/prealign_meshes.py | 18 ++--- .../Methods_fit_to_clinical_LAT.py | 24 +----- ...tune_conductivities_to_fit_clinical_LAT.py | 6 +- 17 files changed, 115 insertions(+), 322 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 3f23a46..6a54d92 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -38,6 +38,7 @@ import argparse from scipy.spatial import cKDTree +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -142,10 +143,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] - #thr = vtk.vtkThreshold() - #thr.SetInputData(mesh_conn) - #thr.ThresholdBetween(LA_tag, LA_tag) - #thr.Update() + # thr = vtk.vtkThreshold() + # thr.SetInputData(mesh_conn) + # thr.ThresholdBetween(LA_tag, LA_tag) + # thr.Update() warning("WARNING: Should be checkt for functionality extract_rings l151") thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") @@ -974,10 +975,7 @@ def to_polydata(mesh): def vtkWrite(input_data, name): - writer = vtk.vtkPolyDataWriter() - writer.SetInputData(input_data) - writer.SetFileName(name) - writer.Write() + vtk_polydata_writer(name, input_data) if __name__ == '__main__': diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index a9f59be..c185a15 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -38,6 +38,7 @@ import argparse from scipy.spatial import cKDTree +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -492,10 +493,7 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): def vtkWrite(input_data, name): - writer = vtk.vtkXMLPolyDataWriter() - writer.SetInputData(input_data) - writer.SetFileName(name) - writer.Write() + vtk_polydata_writer(name, input_data, store_xml=True) def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index b532c75..cc8d210 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -34,6 +34,9 @@ import collections from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ + vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ get_threshold_between @@ -166,15 +169,9 @@ def generate_bilayer(endo, epi): def write_bilayer(bilayer, args, job): if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_bilayer_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_bilayer_with_fiber.vtk", bilayer, store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_bilayer_with_fiber.vtu") - writer.SetInputData(bilayer) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_bilayer_with_fiber.vtu", bilayer) pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_bilayer_with_fiber.pts', "w") as f: f.write(f"{len(pts)}\n") @@ -806,12 +803,7 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): data2 = data[ii] meshNew.PointData.append(data2, idat) - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName( - f"{mesh2_name.split('.vtk')[0]}_with_data.vtk") # It can happen that the relative directory is given - writer.SetFileTypeToBinary() - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_unstructured_grid_writer(f"{mesh2_name.split('.vtk')[0]}_with_data.vtk", meshNew.VTKObject, store_binary=True) return meshNew.VTKObject @@ -1090,22 +1082,11 @@ def creat_center_line(start_end_point): def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): meshNew = dsa.WrapDataObject(tube.GetOutput()) - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(job.ID + "/bridges/" + str(name) + "_tube.vtk") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_polydata_writer(job.ID + "/bridges/" + str(name) + "_tube.vtk", meshNew.VTKObject) meshNew = dsa.WrapDataObject(sphere_1.GetOutput()) - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_1.vtk") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_polydata_writer(job.ID + "/bridges/" + str(name) + "_sphere_1.vtk", meshNew.VTKObject) meshNew = dsa.WrapDataObject(sphere_2.GetOutput()) - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_2.vtk") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_polydata_writer(job.ID + "/bridges/" + str(name) + "_sphere_2.vtk", meshNew.VTKObject) def find_tau(model, ub, lb, low_up, scalar): diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py index 126253a..aa4fb3b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py @@ -84,9 +84,5 @@ def la_calculate_gradient(args, model, job): else: print(f"Successfully created the directory {simid} ") # write the file as vtk - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(simid + "/LA_with_lp_res_gradient.vtk") - writer.SetInputData(output) - writer.Write() - + vtk_unstructured_grid_writer(simid + "/LA_with_lp_res_gradient.vtk", output) return output diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index d2a0222..2584c1b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -36,6 +36,8 @@ import os from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ + vtk_xml_unstructured_grid_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -151,7 +153,6 @@ def la_generate_fiber(model, args, job): thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) - phie_r2_tau_lpv = vtk.util.numpy_support.vtk_to_numpy(thr.GetCellData().GetArray('phie_r2')) max_phie_r2_tau_lpv = np.max(phie_r2_tau_lpv) @@ -180,7 +181,6 @@ def la_generate_fiber(model, args, job): start_time = datetime.datetime.now() print('Calculating fibers... ' + str(start_time)) - # Bilayer mesh if args.mesh_type == 'bilayer': epi = vtk.vtkUnstructuredGrid() @@ -409,15 +409,10 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(el_endo, "fiber") meshNew.CellData.append(sheet_endo, "sheet") if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_endo_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_endo_with_fiber.vtk", meshNew.VTKObject, + store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_endo_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_endo_with_fiber.vtu", meshNew.VTKObject) pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_endo_with_fiber.pts', "w") as f: f.write(f"{len(pts)}\n") @@ -621,15 +616,9 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(el_epi, "fiber") meshNew.CellData.append(sheet_epi, "sheet") if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_epi_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_epi_with_fiber.vtk", meshNew.VTKObject, store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_epi_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_epi_with_fiber.vtu", meshNew.VTKObject) pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_epi_with_fiber.pts', "w") as f: f.write(f"{len(pts)}\n") @@ -689,15 +678,9 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(el, "fiber") meshNew.CellData.append(sheet, "sheet") if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_vol_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_vol_with_fiber.vtk", meshNew.VTKObject, store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_LA/LA_vol_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_vol_with_fiber.vtu", meshNew.VTKObject) pts = numpy_support.vtk_to_numpy(model.GetPoints().GetData()) with open(job.ID + '/result_LA/LA_vol_with_fiber.pts', "w") as f: f.write(f"{len(pts)}\n") diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py index 4f881b9..9136368 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py @@ -27,6 +27,8 @@ import os import sys +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_polydata_writer + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) from carputils.carpio import igb @@ -139,13 +141,10 @@ def la_laplace(args, job, model): else: print(f"Successfully created the directory {simid} ") if args.mesh_type == "vol": - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid + "/LA_with_laplace.vtu") + vtk_xml_unstructured_grid_writer(simid + "/LA_with_laplace.vtu", meshNew.VTKObject) else: - writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(simid + "/LA_with_laplace.vtp") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_polydata_writer(simid + "/LA_with_laplace.vtp", meshNew.VTKObject, store_xml=True) + """ calculate the gradient """ @@ -194,9 +193,5 @@ def laplace_0_1(args, job, model, name1, name2, outname): else: print(f"Successfully created the directory {simid} ") - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid + "/LA_with_laplace.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(simid + "/LA_with_laplace.vtu", meshNew.VTKObject) return meshNew.VTKObject diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index cfd539b..8b93443 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -31,6 +31,9 @@ from scipy.spatial import cKDTree import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ + vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -138,7 +141,6 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): if args.debug: writer = vtk.vtkXMLUnstructuredGridWriter() writer.SetFileName(job.ID + "/result_RA/test_LA_RA_bilayer.vtu") # Has three arrays :) - # writer.SetFileTypeToBinary() # 'vtkmodules.vtkIOXML.vtkXMLUnstructuredGridWriter' object has no attribute 'SetFileTypeToBinary' writer.SetInputData(bilayer_1) writer.Write() @@ -157,14 +159,9 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): bilayer = appendFilter.GetOutput() if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtk", bilayer, store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :) - writer.SetInputData(bilayer) - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :, bilayer) reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :) @@ -329,10 +326,7 @@ def generate_sheet_dir(args, model, job): meshNew.CellData.append(fiber, "fiber") meshNew.CellData.append(sheet_norm, "sheet") if args.debug: - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/model_with_sheet.vtk") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_unstructured_grid_writer(job.ID + "/result_RA/model_with_sheet.vtk", meshNew.VTKObject) print('writing... done!') return meshNew.VTKObject @@ -1122,7 +1116,4 @@ def to_polydata(mesh): def writer_vtk(mesh, filename): - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(filename) - writer.SetInputData(to_polydata(mesh)) - writer.Write() + vtk_polydata_writer(filename, to_polydata(mesh)) \ No newline at end of file diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index bb9db6a..d9f52bf 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -39,6 +39,7 @@ from numpy.linalg import norm from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -154,10 +155,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(meshNew.VTKObject) append_filter.Update() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_res.vtu") - writer.SetInputData(append_filter.GetOutput()) - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", append_filter.GetOutput()) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") @@ -227,11 +225,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): la_ra_usg = append_filter.GetOutput() # this has already elemTag if args.debug: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_usg.vtu") - writer.SetInputData(la_ra_usg) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_usg.vtu", la_ra_usg) print('reading done!') bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] @@ -585,11 +579,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.Update() bridges = append_filter.GetOutput() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :) - writer.SetInputData(bridges) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :, bridges) # # Append all the bridges first # if var == bridge_list[0]: # just define append_filter in the first iteration # append_filter = vtk.vtkAppendFilter() @@ -634,25 +624,13 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.Update() epi = append_filter.GetOutput() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_with_bundles.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_bundles.vtu", epi) epi = Method.generate_sheet_dir(args, epi, job) - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_with_sheets.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_sheets.vtu", epi) if args.mesh_type == "bilayer": - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu") # Has elemTag! :) - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu") # Has elemTag! :, epi) reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") # Has elemTag! :) reader.Update() @@ -669,30 +647,18 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(ra_endo) append_filter.Update() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :) - writer.SetInputData(append_filter.GetOutput()) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :, append_filter.GetOutput()) endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_endo.vtu") # Has elemTag! :) - writer.SetInputData(endo) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu") # Has elemTag! :, endo) bilayer = Method.generate_bilayer(args, job, endo, epi, 0.12 * args.scale) # Does not have elemTag :(! Method.write_bilayer(args, job) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu", epi) pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: f.write(f"{len(pts)}\n") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 0815bfd..df52eba 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -47,6 +47,8 @@ import pandas as pd from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ + vtk_unstructured_grid_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -208,11 +210,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(meshNew.VTKObject) append_filter.Update() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_res.vtu") - writer.SetInputData(append_filter.GetOutput()) - writer.Write() - elif args.mesh_type == "bilayer": + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", append_filter.GetOutput()) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") geo_filter_la_epi = vtk.vtkGeometryFilter() @@ -475,11 +473,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(extract.GetOutput()) if args.debug: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu") - writer.SetInputData(append_filter.AddInputData(extract.GetOutput())) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", append_filter.AddInputData(extract.GetOutput())) # append_filter = vtk.vtkAppendFilter() # append_filter.MergePointsOn() # append_filter.SetTolerance(0.2*args.scale) @@ -600,36 +594,20 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): meshNew = dsa.WrapDataObject(bridge_union) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(fiber, "fiber") - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/bridges/" + str(var) + "_union_mesh.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag + vtk_unstructured_grid_writer(job.ID + "/bridges/" + str(var) + "_union_mesh.vtu", meshNew.VTKObject) append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag append_filter.MergePointsOn() # here we lose the tags append_filter.Update() epi = append_filter.GetOutput() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_with_bundles.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_bundles.vtu", epi) epi = Method.generate_sheet_dir(args, epi, job) - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_with_sheets.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_sheets.vtu", epi) if args.mesh_type == "bilayer": - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu", epi) reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") reader.Update() @@ -645,30 +623,18 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(ra_endo) append_filter.Update() - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") - writer.SetInputData(append_filter.GetOutput()) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", append_filter.GetOutput()) endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/la_ra_endo.vtu") - writer.SetInputData(endo) - writer.Write() - + vtk_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu", endo) bilayer = Method.generate_bilayer(endo, epi, 0.12 * args.scale) Method.write_bilayer(bilayer, args, job) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu") - writer.SetInputData(epi) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu", epi) pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: f.write(f"{len(pts)}\n") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index c09fa5a..79afda9 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -47,11 +47,7 @@ def run(args): endo = move_surf_along_normals(ra_endo, 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(args.mesh + "/RA_endo_with_fiber_moved.vtk") - writer.SetInputData(endo) - writer.Write() - + vtk_unstructured_grid_writer(args.mesh + "/RA_endo_with_fiber_moved.vtk", endo) bilayer = generate_bilayer(endo, ra_epi, 0.12 * args.scale) # bilayer = generate_bilayer(ra_endo, ra_epi) @@ -160,11 +156,7 @@ def generate_bilayer(endo, epi, max_dist=np.inf): # Creates VTK and CARP files: .pts, .lon, .elem def write_bilayer(bilayer): - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(args.mesh + "/RA_bilayer_with_fiber.vtk") - writer.SetFileTypeToBinary() - writer.SetInputData(bilayer) - writer.Write() + vtk_unstructured_grid_writer(args.mesh + "/RA_bilayer_with_fiber.vtk", bilayer, store_binary=True) pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) with open(args.mesh + '/RA_bilayer_with_fiber.pts', "w") as f: diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py index ccee8d4..08b97a2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py @@ -84,9 +84,5 @@ def ra_calculate_gradient(args, model, job): else: print(f"Successfully created the directory {simid} ") # write the file as vtk - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid + "/RA_with_lp_res_gradient.vtu") - writer.SetInputData(output) - writer.Write() - + vtk_xml_unstructured_grid_writer(simid + "/RA_with_lp_res_gradient.vtu", output) return output diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 7aa638c..6c44ecd 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -37,6 +37,8 @@ from scipy.spatial import cKDTree from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ + vtk_xml_unstructured_grid_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -376,7 +378,7 @@ def ra_generate_fiber(model, args, job): CT_plus = vtk_thr(RAW_s, 0, "CELLS", "phie_w", tao_ct_plus) RAW_S = vtk_thr(CT_plus, 2, "CELLS", "phie_v", tao_scv, - tao_icv) # IB_S grad_v Changed order tao_scv, tao_icv + tao_icv) # IB_S grad_v Changed order tao_scv, tao_icv RAW_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_S.GetCellData().GetArray('Global_ids')) @@ -618,18 +620,11 @@ def ra_generate_fiber(model, args, job): meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") meshNew.CellData.append(sheet, "sheet") - - writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtk", meshNew.VTKObject, + store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtu", meshNew.VTKObject) """ PM and CT """ @@ -678,15 +673,10 @@ def ra_generate_fiber(model, args, job): writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtk", meshNew.VTKObject, + store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtu", meshNew.VTKObject) center = np.asarray((np.array(df["SVC"]) + np.array(df["IVC"])) / 2) loc = vtk.vtkPointLocator() @@ -1114,30 +1104,21 @@ def ra_generate_fiber(model, args, job): endo = meshNew.VTKObject - writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtk") - writer.SetFileTypeToBinary() + + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_endo_with_fiber.vtk", endo, store_binary=True) + else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtu") - writer.SetInputData(endo) - writer.Write() + + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_endo_with_fiber.vtu", endo) CT_PMs = vtk_thr(endo, 2, "CELLS", "elemTag", pectinate_muscle, crista_terminalis) - writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_CT_PMs.vtk", CT_PMs, store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") - writer.SetInputData(CT_PMs) - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_CT_PMs.vtu", CT_PMs) elif args.mesh_type == "vol": @@ -1180,14 +1161,10 @@ def ra_generate_fiber(model, args, job): writer = vtk.vtkUnstructuredGridWriter() if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_endo_with_fiber.vtk", meshNew.VTKObject, + store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_endo_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_endo_with_fiber.vtu", meshNew.VTKObject) # Bachmann-Bundle if args.mesh_type == "vol": @@ -1254,26 +1231,18 @@ def ra_generate_fiber(model, args, job): meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") meshNew.CellData.append(sheet, "sheet") - writer = vtk.vtkUnstructuredGridWriter() if args.mesh_type == "bilayer": if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtk", meshNew.VTKObject, True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_epi_with_fiber.vtu") + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtu", meshNew.VTKObject) else: if args.ofmt == 'vtk': - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_vol_with_fiber.vtk") - writer.SetFileTypeToBinary() + vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_vol_with_fiber.vtk", meshNew.VTKObject, + store_binary=True) else: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/RA_vol_with_fiber.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_vol_with_fiber.vtu", meshNew.VTKObject) model = meshNew.VTKObject diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py index 47009cd..0995448 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py @@ -31,6 +31,8 @@ from carputils.carpio import igb from vtk.numpy_interface import dataset_adapter as dsa +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_polydata_writer + EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -160,13 +162,10 @@ def ra_laplace(args, job, model): else: print(f"Successfully created the directory {simid} ") if args.mesh_type == "vol": - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(simid + "/RA_with_laplace.vtu") + vtk_xml_unstructured_grid_writer(simid + "/RA_with_laplace.vtu", meshNew.VTKObject) else: - writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(simid + "/RA_with_laplace.vtp") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_polydata_writer(simid + "/RA_with_laplace.vtp", meshNew.VTKObject) + """ calculate the gradient """ diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 5374d6b..19de8b3 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -48,6 +48,7 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from standalones.open_orifices_manually import open_orifices_manually from vtk_opencarp_helper_methods.vtk_methods import filters +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader pv.set_plot_theme('dark') @@ -137,11 +138,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model = model.VTKObject if debug: - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(f"{full_path}/{atrium}_clean_with_curv.vtk") - writer.SetInputData(model) - writer.Write() - + vtk_polydata_writer(f"{full_path}/{atrium}_clean_with_curv.vtk", model) apex = None if not MRI: @@ -255,11 +252,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model = cellid.GetOutput() - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(f"{full_path}/{atrium}_curv.vtk") - writer.SetInputData(model) - writer.SetFileTypeToBinary() - writer.Write() + vtk_polydata_writer(f"{full_path}/{atrium}_curv.vtk", model, True) curv = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('curv')) @@ -275,11 +268,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu high_c = vtk_thr(model, 0, "POINTS", "curv", np.median(curv) * 1.15) # (np.min(curv)+np.max(curv))/2) - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(f"{full_path}/{atrium}_h_curv.vtk") - writer.SetInputData(high_c) - writer.SetFileTypeToBinary() - writer.Write() + vtk_unstructured_grid_writer(f"{full_path}/{atrium}_h_curv.vtk", high_c, True) connect = vtk.vtkConnectivityFilter() connect.SetInputData(high_c) @@ -462,11 +451,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu model = extract_largest_region(model) - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(f"{full_path}/{atrium}_cutted.vtk") - writer.SetInputData(model) - writer.Write() - + vtk_polydata_writer(f"{full_path}/{atrium}_cutted.vtk", model) if debug: if apex is not None: point_cloud = pv.PolyData(apex) @@ -518,7 +503,8 @@ def run(): def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, thr2) + return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, + thr2) def find_elements_within_radius(mesh, points_data, radius): @@ -615,10 +601,7 @@ def to_polydata(mesh): def writer_vtk(mesh, filename): - writer = vtk.vtkPolyDataWriter() - writer.SetFileName(filename) - writer.SetInputData(to_polydata(mesh)) - writer.Write() + vtk_polydata_writer(filename, to_polydata(mesh)) if __name__ == '__main__': diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index 8793b1d..08cc8a9 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -36,6 +36,8 @@ import argparse +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer + def parser(): parser = argparse.ArgumentParser(description='Prealign meshes using landmarks.') @@ -111,12 +113,12 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): json2 = '[' for i in df_new.columns: json1 = json1 + "{\"id\":\"" + f"{i}" + "\",\"coordinates\":[" + "{},{},{}".format(df_new[i][0], - df_new[i][1], - df_new[i][2]) + "]}," + df_new[i][1], + df_new[i][2]) + "]}," json1 = json1[:-1] + ']' for i in df2.columns: json2 = json2 + "{\"id\":\"" + f"{i}" + "\",\"coordinates\":[" + "{},{},{}".format(df2[i][0], df2[i][1], - df2[i][2]) + "]}," + df2[i][2]) + "]}," json2 = json2[:-1] + ']' f = open(f"{mesh1_name}_surf/prealigned_landmarks.json", "w") @@ -147,15 +149,13 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): writer.Write() meshNew = dsa.WrapDataObject(transform_poly.GetOutput()) - writer = vtk.vtkPolyDataWriter() if case == "both": - writer.SetFileName(f'{mesh1_name}_surf/LA_RA_prealigned.vtk') + vtk_polydata_writer(f'{mesh1_name}_surf/LA_RA_prealigned.vtk', meshNew.VTKObject) elif case == "LA": - writer.SetFileName(f'{mesh1_name}_surf/LA_prealigned.vtk') + vtk_polydata_writer(f'{mesh1_name}_surf/LA_prealigned.vtk', meshNew.VTKObject) else: - writer.SetFileName(f'{mesh1_name}_surf/RA_prealigned.vtk') - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_polydata_writer(f'{mesh1_name}_surf/RA_prealigned.vtk', meshNew.VTKObject) + def run(): diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 7154ab8..3f9d2a4 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -93,11 +93,7 @@ def low_vol_LAT(args, path): else: print(f"Successfully created the directory {debug_dir} ") - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(f'{debug_dir}/low_vol.vtu') - writer.SetInputData(low_vol) - writer.Write() - + vtk_xml_unstructured_grid_writer(f'{debug_dir}/low_vol.vtu', low_vol) # Endo geo_filter = vtk.vtkGeometryFilter() @@ -107,11 +103,7 @@ def low_vol_LAT(args, path): endo = vtk_thr(geo_filter.GetOutput(), 1, "CELLS", "elemTag", 10) if args.debug: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(f'{debug_dir}/endo.vtu') - writer.SetInputData(endo) - writer.Write() - + vtk_xml_unstructured_grid_writer(f'{debug_dir}/endo.vtu', endo) # Get point LAT map in endocardium LAT_endo = vtk.util.numpy_support.vtk_to_numpy(endo.GetPointData().GetArray('lat')) endo_ids = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('Global_ids')).astype(int) @@ -128,11 +120,7 @@ def low_vol_LAT(args, path): not_low_volt_endo.GetPointData().GetArray('Global_ids')).astype(int) if args.debug: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(f'{debug_dir}/not_low_volt_endo.vtu') - writer.SetInputData(not_low_volt_endo) - writer.Write() - + vtk_xml_unstructured_grid_writer(f'{debug_dir}/not_low_volt_endo.vtu', not_low_volt_endo) # Extract LA wall from SSM to be sure that no veins or LAA is included when selecting the earliest activated point if args.SSM_fitting: LA_wall = smart_reader(args.SSM_basename + '/LA_wall.vtk') @@ -381,11 +369,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): border[el_border_array] = 1 meshNew.CellData.append(border, "border") - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(f'{debug_dir}/endo_with_clean_tag.vtu') - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(f'{debug_dir}/endo_with_clean_tag.vtu', meshNew.VTKObject) return el_to_clean, el_border diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index d6b7eb4..86faa8d 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -372,11 +372,7 @@ def run(args, job): meshNew = dsa.WrapDataObject(endo) meshNew.CellData.append(endo_etag, "elemTag") - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(f"{meshfold}/LA_endo_with_fiber_30_um.vtu") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_xml_unstructured_grid_writer(f"{meshfold}/LA_endo_with_fiber_30_um.vtu", meshNew.VTKObject) pts = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetPoints().GetData()) with open(meshfold + "/LA_endo_with_fiber_30_um.pts", "w") as f: f.write(f"{len(pts)}\n") From 26733fdd2c0f3eb3d8d613848809b961c4871072 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 09:27:25 +0100 Subject: [PATCH 14/70] Replaced all vtk writers with encapsulated methods --- .../Generate_Boundaries/separate_epi_endo.py | 17 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 5 - .../LDRBM/Fiber_LA/la_generate_fiber.py | 48 ----- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 42 +--- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 110 ++--------- .../LDRBM/Fiber_RA/create_bridges_test.py | 177 ++--------------- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 183 ------------------ standalones/resample_surf_mesh.py | 9 +- ...tune_conductivities_to_fit_clinical_LAT.py | 26 +-- 9 files changed, 51 insertions(+), 566 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index a986d34..948b4d4 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -43,11 +43,7 @@ def separate_epi_endo(path, atrium): geo_filter.SetInputData(thresh.GetOutput()) geo_filter.Update() - writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname + f"_{atrium}.obj") - writer.SetInputData(geo_filter.GetOutput()) - writer.Write() - + vtk_obj_writer(meshname + f"_{atrium}.obj", geo_filter.GetOutput()) if atrium == "LA": thresh = get_threshold_between(model, left_atrial_wall_epi, left_atrial_wall_epi, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") @@ -62,11 +58,7 @@ def separate_epi_endo(path, atrium): geo_filter.Update() la_epi = geo_filter.GetOutput() - writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname + f"_{atrium}_epi.obj") - writer.SetInputData(la_epi) - writer.Write() - + vtk_obj_writer(meshname + f"_{atrium}_epi.obj", la_epi) if atrium == "LA": thresh = get_threshold_between(model, left_atrial_wall_endo, left_atrial_wall_endo, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") @@ -81,7 +73,4 @@ def separate_epi_endo(path, atrium): geo_filter.Update() la_endo = geo_filter.GetOutput() - writer = vtk.vtkOBJWriter() - writer.SetFileName(meshname + f"_{atrium}_endo.obj") - writer.SetInputData(la_endo) - writer.Write() + vtk_obj_writer(meshname + f"_{atrium}_endo.obj", la_endo) \ No newline at end of file diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index cc8d210..4171b44 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -846,11 +846,6 @@ def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): data2 = data[ii] meshNew.CellData.append(data2, idat) - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName("{}_with_data.vtk".format(mesh2_name.split('.')[0])) - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - return meshNew.VTKObject diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 2584c1b..9a0a405 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -481,10 +481,6 @@ def la_generate_fiber(model, args, job): el[LIPV_ids_endo] = v_grad_norm[LIPV_ids_endo] el[LSPV_ids_endo] = v_grad_norm[LSPV_ids_endo] - # for i in range(len(v_grad_norm)): - # if v[i] <= 0.2: - # el_endo[i] = v_grad_norm[i] - end_time = datetime.datetime.now() meshNew = dsa.WrapDataObject(model) @@ -492,42 +488,6 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(el, "fiber") model = meshNew.VTKObject - # meshNew = dsa.WrapDataObject(endo) - # meshNew.CellData.append(tag_endo, "elemTag") - # meshNew.CellData.append(el_endo, "fiber") - # meshNew.CellData.append(sheet_endo, "sheet") - # if args.ofmt == 'vtk': - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtk") - # writer.SetFileTypeToBinary() - # else: - # writer = vtk.vtkXMLUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_LA/LA_endo_with_fiber.vtu") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - - # pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) - # with open(job.ID+'/result_LA/LA_endo_with_fiber.pts',"w") as f: - # f.write("{}\n".format(len(pts))) - # for i in range(len(pts)): - # f.write("{} {} {}\n".format(pts[i][0], pts[i][1], pts[i][2])) - - # with open(job.ID+'/result_LA/LA_endo_with_fiber.elem',"w") as f: - # f.write("{}\n".format(endo.GetNumberOfCells())) - # for i in range(endo.GetNumberOfCells()): - # cell = endo.GetCell(i) - # if cell.GetNumberOfPoints() == 2: - # f.write("Ln {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), tag_endo[i])) - # elif cell.GetNumberOfPoints() == 3: - # f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), tag_endo[i])) - # elif cell.GetNumberOfPoints() == 4: - # f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), tag_endo[i])) - - # with open(job.ID+'/result_LA/LA_endo_with_fiber.lon',"w") as f: - # f.write("2\n") - # for i in range(len(el_endo)): - # f.write("{} {} {} {} {} {}\n".format(el_endo[i][0], el_endo[i][1], el_endo[i][2], sheet_endo[i][0], sheet_endo[i][1], sheet_endo[i][2])) - running_time = end_time - start_time print('Calculating fibers... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') @@ -546,16 +506,8 @@ def la_generate_fiber(model, args, job): epi_surf = vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) epi_surf_ids = vtk.util.numpy_support.vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) - # epi_surf_id_list = vtk.vtkIdList() - # for i in epi_surf_ids: - # epi_surf_id_list.InsertNextId(i) - # extract = vtk.vtkExtractCells() - # extract.SetInputData(surf) - # extract.SetCellList(epi_surf_id_list) - # extract.Update() geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(epi_surf) - # geo_filter.PassThroughCellIdsOn() geo_filter.Update() epi_surf = geo_filter.GetOutput() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 8b93443..b705d6c 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -32,7 +32,7 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ - vtk_xml_unstructured_grid_writer + vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -139,10 +139,7 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): bilayer_1 = meshNew.VTKObject if args.debug: - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/test_LA_RA_bilayer.vtu") # Has three arrays :) - writer.SetInputData(bilayer_1) - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/test_LA_RA_bilayer.vtu", bilayer_1) reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/test_LA_RA_bilayer.vtu") # @@ -172,16 +169,6 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): def write_bilayer(args, job): - # if args.ofmt == 'vtk': - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/LA_RA_bilayer_with_fiber.vtk") - # writer.SetFileTypeToBinary() - # else: - # writer = vtk.vtkXMLUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/LA_RA_bilayer_with_fiber.vtu") - # writer.SetInputData(bilayer) - # writer.Write() - reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # reader.Update() @@ -243,12 +230,6 @@ def generate_sheet_dir(args, model, job): cleaner.Update() cln_surface = cleaner.GetOutput() - # meshNew = dsa.WrapDataObject(cln_surface) - # writer = vtk.vtkPolyDataWriter() - # writer.SetFileName("test_model_surface.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - ''' calculate normals of surface cells ''' @@ -1081,22 +1062,11 @@ def creat_center_line(start_end_point): def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): meshNew = dsa.WrapDataObject(tube.GetOutput()) - writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID + "/bridges/" + str(name) + "_tube.obj") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_obj_writer(job.ID + "/bridges/" + str(name) + "_tube.obj", meshNew.VTKObject) meshNew = dsa.WrapDataObject(sphere_1.GetOutput()) - writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_1.obj") - writer.SetInputData(meshNew.VTKObject) - writer.Write() - + vtk_obj_writer(job.ID + "/bridges/" + str(name) + "_sphere_1.obj", meshNew.VTKObject) meshNew = dsa.WrapDataObject(sphere_2.GetOutput()) - writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID + "/bridges/" + str(name) + "_sphere_2.obj") - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_obj_writer(job.ID + "/bridges/" + str(name) + "_sphere_2.obj", meshNew.VTKObject) def create_pts(array_points, array_name, mesh_dir): @@ -1116,4 +1086,4 @@ def to_polydata(mesh): def writer_vtk(mesh, filename): - vtk_polydata_writer(filename, to_polydata(mesh)) \ No newline at end of file + vtk_polydata_writer(filename, to_polydata(mesh)) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index d9f52bf..ae0cc02 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -24,22 +24,21 @@ specific language governing permissions and limitations under the License. """ -import numpy as np -import vtk -from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util.numpy_support import vtk_to_numpy -import datetime -import Methods_RA as Method import csv import os +import pickle import subprocess + +import numpy as np import pymesh import pymeshlab -import pickle -from numpy.linalg import norm +import vtk +from vtk.numpy_interface import dataset_adapter as dsa +import Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr -from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ + vtk_unstructured_grid_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -175,23 +174,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(ra_e) append_filter.Update() # la_ra_usg - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu") # Good till here! - writer.SetInputData(append_filter.GetOutput()) - writer.Write() - - # append_filter = vtk.vtkAppendFilter() # same as above but names changed to avoid overwriting - # append_filter.AddInputData(la_epi) - # append_filter.AddInputData(ra_epi) - # append_filter.Update() - # - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(append_filter.GetOutput()) - # geo_filter.Update() - # writer = vtk.vtkOBJWriter() - # writer.SetFileName(job.ID+"/result_RA/la_ra_res.obj") - # writer.SetInputData(geo_filter.GetOutput()) - # writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -296,11 +279,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): earth = cleaner.GetOutput() # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) - writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID + "/bridges/" + str(var) + "_earth.obj") - writer.SetInputData(earth) - writer.Write() - + vtk_obj_writer(job.ID + "/bridges/" + str(var) + "_earth.obj", earth) # Here print("Extracted earth") @@ -327,10 +306,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): la_ra_epi = append_filter.GetOutput() # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") # Still has element Tag - writer.SetInputData(la_ra_epi) - writer.Write() + # Still has element Tag + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu", la_ra_epi) # Now extract earth from LA_endo as well @@ -409,16 +386,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): la_endo_final = append_filter.GetOutput() # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_endo_with_holes.vtu") # Still has element Tag - writer.SetInputData(la_endo_final) - writer.Write() - - # append_filter = vtk.vtkAppendFilter() - # append_filter.MergePointsOn() - # append_filter.SetTolerance(0.2*args.scale) - # append_filter.AddInputData(append_filter.GetOutput()) - # meshNew = dsa.WrapDataObject(extract.GetOutput()) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_endo_with_holes.vtu", la_endo_final) filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') @@ -459,24 +427,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): else: output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) - - # reader = vtk.vtkOBJReader() - # reader.SetFileName(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - # reader.Update() - - # output_mesh_2 = Method.extract_largest_region(reader.GetOutput()) - - # writer = vtk.vtkOBJWriter() - # writer.SetFileName(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - # writer.SetInputData(output_mesh_2) - # writer.Write() - - # mesh_D = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - - # output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - - # pymesh.save_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj", output_mesh_2, ascii=True) - print("Union between earth and bridges in " + var) ms = pymeshlab.MeshSet() @@ -537,10 +487,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(fiber, "fiber") - writer = vtk.vtkUnstructuredGridWriter() - writer.SetFileName(job.ID + "/bridges/" + str(var) + "_union_mesh.vtk") # we have the elemTags here - writer.SetInputData(meshNew.VTKObject) - writer.Write() + vtk_unstructured_grid_writer(job.ID + "/bridges/" + str(var) + "_union_mesh.vtk", + meshNew.VTKObject) # we have the elemTags here if var == 'BB_intern_bridges': bb = meshNew.VTKObject @@ -580,31 +528,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): bridges = append_filter.GetOutput() vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :, bridges) - # # Append all the bridges first - # if var == bridge_list[0]: # just define append_filter in the first iteration - # append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(meshNew.VTKObject) - # append_filter.Update() - # temp = append_filter.GetOutput() - # else: - # append_filter.AddInputData(temp) - # append_filter.AddInputData(meshNew.VTKObject) - # append_filter.Update() - # temp = append_filter.GetOutput() - # - # if args.debug and var == bridge_list[-1]: - # writer = vtk.vtkXMLUnstructuredGridWriter() - # writer.SetFileName(job.ID + "/result_RA/append_bridges_with_tag.vtu") - # writer.SetInputData(temp) - # writer.Write() - - # append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag - # append_filter.Update() - - # writer = vtk.vtkXMLUnstructuredGridWriter() - # writer.SetFileName(job.ID + "/result_RA/LA_RA_with_bundles_with_" + str(var) + ".vtu") # Here we lose the elemTag - # writer.SetInputData(append_filter.GetOutput()) - # writer.Write() reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") @@ -647,7 +570,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(ra_endo) append_filter.Update() - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :, append_filter.GetOutput()) + vtk_xml_unstructured_grid_writer( + job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :, append_filter.GetOutput()) endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index df52eba..04e3351 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -48,7 +48,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ - vtk_unstructured_grid_writer + vtk_unstructured_grid_writer, vtk_obj_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -210,7 +210,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(meshNew.VTKObject) append_filter.Update() - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", append_filter.GetOutput()) elif args.mesh_type == "bilayer": + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", + append_filter.GetOutput()) + elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") geo_filter_la_epi = vtk.vtkGeometryFilter() @@ -229,23 +231,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(ra_e) append_filter.Update() # la_ra_usg - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu") # Good till here! - writer.SetInputData(append_filter.GetOutput()) - writer.Write() - - # append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(la_epi) - # append_filter.AddInputData(ra_epi) - # append_filter.Update() - # - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(append_filter.GetOutput()) - # geo_filter.Update() - # writer = vtk.vtkOBJWriter() - # writer.SetFileName(job.ID+"/result_RA/la_ra_res.obj") - # writer.SetInputData(geo_filter.GetOutput()) - # writer.Write() + # Good till here! + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -276,102 +263,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): "-surf=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj", "-outmsh=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.vtk"]) - # if args.mesh_type == "vol": - - # la_ra_usg = append_filter.GetOutput() - # print('reading done!') - - # bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] - # earth_cell_ids_list = [] - # for var in bridge_list: - # reader = vtk.vtkUnstructuredGridReader() - # reader.SetFileName(job.ID+"/bridges/"+str(var)+'_bridge_resampled.vtk') - # reader.Update() - # bridge_usg = reader.GetOutput() - - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(bridge_usg) - # geo_filter.Update() - # bridge = geo_filter.GetOutput() - - # locator = vtk.vtkStaticPointLocator() - # locator.SetDataSet(la_ra_usg) - # locator.BuildLocator() - - # intersection_points = bridge_usg.GetPoints().GetData() - # intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) - - # earth_point_ids_temp = vtk.vtkIdList() - # earth_point_ids = vtk.vtkIdList() - # for i in range(len(intersection_points)): - # locator.FindPointsWithinRadius(0.7*args.scale, intersection_points[i], earth_point_ids_temp) - # for j in range(earth_point_ids_temp.GetNumberOfIds()): - # earth_point_ids.InsertNextId(earth_point_ids_temp.GetId(j)) - - # earth_cell_ids_temp = vtk.vtkIdList() - # earth_cell_ids = vtk.vtkIdList() - # for i in range(earth_point_ids.GetNumberOfIds()): - # la_ra_usg.GetPointCells(earth_point_ids.GetId(i),earth_cell_ids_temp) - # for j in range(earth_cell_ids_temp.GetNumberOfIds()): - # earth_cell_ids.InsertNextId(earth_cell_ids_temp.GetId(j)) - # earth_cell_ids_list += [earth_cell_ids_temp.GetId(j)] - # extract = vtk.vtkExtractCells() - # extract.SetInputData(la_ra_usg) - # extract.SetCellList(earth_cell_ids) - # extract.Update() - - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(extract.GetOutput()) - # geo_filter.Update() - # earth = geo_filter.GetOutput() - - # cleaner = vtk.vtkCleanPolyData() - # cleaner.SetInputData(earth) - # cleaner.Update() - - # # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) - # writer = vtk.vtkOBJWriter() - # writer.SetFileName(job.ID+"/bridges/"+str(var)+"_earth.obj") - # writer.SetInputData(cleaner.GetOutput()) - # writer.Write() - - # print("Extracted earth") - # cell_id_all = [] - # for i in range(la_ra_usg.GetNumberOfCells()): - # cell_id_all.append(i) - - # la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) - # la_ra_new = vtk.vtkIdList() - # for var in la_diff: - # la_ra_new.InsertNextId(var) - - # extract = vtk.vtkExtractCells() - # extract.SetInputData(la_ra_usg) - # extract.SetCellList(la_ra_new) - # extract.Update() - - # append_filter = vtk.vtkAppendFilter() - # append_filter.MergePointsOn() - # #append_filter.SetTolerance(0.01*args.scale) - # append_filter.AddInputData(extract.GetOutput()) - - # elif args.mesh_type == "bilayer": - - # if args.mesh_type == "bilayer": - # la_ra_usg = append_filter.GetOutput() - # else: - # la_ra_usg_vol = append_filter.GetOutput() - # ra_epi = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 11,18) - # ra_BB = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_right,bachmann_bundel_right) - # la_epi = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", 61,70) - # la_BB = vtk_thr(append_filter.GetOutput(), 2, "CELLS", "elemTag", bachmann_bundel_left,bachmann_bundel_left) - - # append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(la_epi) - # append_filter.AddInputData(ra_epi) - # append_filter.AddInputData(la_BB) - # append_filter.AddInputData(ra_BB) - # append_filter.Update() la_ra_usg = append_filter.GetOutput() # this has already elemTag print('reading done!') @@ -386,31 +277,11 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() bridge_usg = reader.GetOutput() - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(bridge_usg) - # geo_filter.Update() - # bridge = geo_filter.GetOutput() - - # reverse = vtk.vtkReverseSense() - # reverse.ReverseCellsOn() - # reverse.ReverseNormalsOn() - # reverse.SetInputConnection(cleaner.GetOutputPort()) - # reverse.Update() - - # earth = reverse.GetOutput() - - # vbool = vtk.vtkBooleanOperationPolyDataFilter() - # vbool.SetOperationToDifference() - # vbool.SetInputData( 0, epi_surf ) - # vbool.SetInputData( 1, bridge ) - - # vbool.Update() locator = vtk.vtkStaticPointLocator() locator.SetDataSet(la_ra_usg) locator.BuildLocator() - # intersection_points = vbool.GetOutput().GetPoints().GetData() intersection_points = bridge_usg.GetPoints().GetData() intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) @@ -444,11 +315,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): earth = cleaner.GetOutput() # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) - writer = vtk.vtkOBJWriter() - writer.SetFileName(job.ID + "/bridges/" + str(var) + "_earth.obj") - writer.SetInputData(earth) - writer.Write() - + vtk_obj_writer(job.ID + "/bridges/" + str(var) + "_earth.obj", earth) # Here print("Extracted earth") @@ -473,7 +340,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.AddInputData(extract.GetOutput()) if args.debug: - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", append_filter.AddInputData(extract.GetOutput())) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", + append_filter.AddInputData(extract.GetOutput())) # append_filter = vtk.vtkAppendFilter() # append_filter.MergePointsOn() # append_filter.SetTolerance(0.2*args.scale) @@ -501,12 +369,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): print("Union between earth and bridges") for var in bridge_list: - # if args.mesh_type == "vol": - # mesh_D = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_bridge_resampled.obj") - # mesh_E = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_earth.obj") - # output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="igl") - # elif args.mesh_type == "bilayer": - # Here + mesh_D = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj") mesh_E = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_earth.obj") # # Warning: set -1 if pts normals are pointing outside @@ -520,23 +383,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) - # reader = vtk.vtkOBJReader() - # reader.SetFileName(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - # reader.Update() - - # output_mesh_2 = Method.extract_largest_region(reader.GetOutput()) - - # writer = vtk.vtkOBJWriter() - # writer.SetFileName(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - # writer.SetInputData(output_mesh_2) - # writer.Write() - - # mesh_D = pymesh.load_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj") - - # output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - - # pymesh.save_mesh(job.ID+"/bridges/"+str(var)+"_union_to_resample.obj", output_mesh_2, ascii=True) - print("Union between earth and bridges in " + var) ms = pymeshlab.MeshSet() @@ -594,7 +440,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): meshNew = dsa.WrapDataObject(bridge_union) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(fiber, "fiber") - vtk_unstructured_grid_writer(job.ID + "/bridges/" + str(var) + "_union_mesh.vtu", meshNew.VTKObject) append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag + vtk_unstructured_grid_writer(job.ID + "/bridges/" + str(var) + "_union_mesh.vtu", meshNew.VTKObject) + append_filter.AddInputData(meshNew.VTKObject) # Check here if we still have the element tag append_filter.MergePointsOn() # here we lose the tags append_filter.Update() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 6c44ecd..4e62c45 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -730,14 +730,9 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.writer_vtk(TV_lat, f'{args.mesh}_surf/' + "TV_lat.vtk") - # writer = vtk.vtkPolyDataWriter() - # writer.SetFileName("TV_lat.vtk") - # writer.SetInputData(TV_lat) - # writer.Write() ct_points_data = Method.dijkstra_path(CT, point1_id, point2_id) - # np.savetxt("ct_points_data.txt", ct_points_data, fmt='%.4f') if args.debug: Method.create_pts(ct_points_data, 'ct_points_data', f'{args.mesh}_surf/') @@ -754,10 +749,6 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.create_pts(tv_points_data, 'tv_points_data', f'{args.mesh}_surf/') - # np.savetxt("tv_points_data.txt", tv_points_data, fmt='%.4f') - - # np.savetxt("point3_id_new.txt", TV_lat.GetPoint(point3_id), fmt='%.4f') - # np.savetxt("point4_id_new.txt", TV_lat.GetPoint(point4_id), fmt='%.4f') print("Creating Pectinate muscle...") @@ -806,180 +797,6 @@ def ra_generate_fiber(model, args, job): pm_ct_dis = int(len(ct_points_data) / pm_num) pm_tv_dis = int(len(tv_points_data) / pm_num) - # the first PM is the one to the appendage - - # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) - - # tag = Method.assign_element_tag_around_path_within_radius(mesh, pm, w_pm, tag, pectinate_muscle) - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, pm, w_pm, fiber_endo, smooth=True) - - # for i in range(pm_num): - # pm_point_1 = pm_ct_id_list[(i + 1) * pm_ct_dis] - # pm_point_2 = pm_tv_id_list[(i + 1) * pm_tv_dis] - # pm = Method.dijkstra_path_on_a_plane(surface, args, pm_point_1, pm_point_2, center) - # # pm = Method.dijkstra_path(surface, pm_point_1, pm_point_2) - # # if i == 0: - # # pm = Method.dijkstra_path(surface, pm_point_1, pm_point_2) - # # else: - # # pm = Method.dijkstra_path_on_a_plane(surface, pm_point_1, pm_point_2, center) - # print("The ", i + 1, "th pm done") - # tag = Method.assign_element_tag_around_path_within_radius(mesh, pm, w_pm, tag, pectinate_muscle) - # print("The ", i + 1, "th pm's tag is done") - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, pm, w_pm, fiber_endo, smooth=True) - # print("The ", i + 1, "th pm's fiber is done") - - # print("Creating Pectinate muscle... done!") - - # # Crista Terminalis - # print("Creating Crista Terminalis...") - # tag = Method.assign_element_tag_around_path_within_radius(mesh, ct_points_data, w_ct, tag, crista_terminalis) - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, ct_points_data, w_ct, fiber_endo, smooth=True) - # print("Creating Crista Terminalis... done!") - - # """ - # over write the pm on the TV - # """ - # for i in range(len(ab_grad)): - # if r[i] >= tao_tv: - # fiber_endo[i] = el[i] - # if phie[i] <= 0.5: - # tag[i] = tricuspid_valve_endo - # else: - # tag[i] = tricuspid_valve_epi - - # # Bachmann-Bundle - - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(surface) - # loc.BuildLocator() - - # # Bachmann-Bundle starting point - # bb_1_id = loc.FindClosestPoint(SVC_CT_pt) - # bb_2_id = loc.FindClosestPoint(TV_s.GetPoint(point4_id)) - - # bachmann_bundle_points_data = Method.dijkstra_path(surface, bb_1_id, bb_2_id) - # bb_step = 10 - # bb_path = np.asarray([bachmann_bundle_points_data[i] for i in range(len(bachmann_bundle_points_data)) if i % bb_step == 0 or i == len(bachmann_bundle_points_data)-1]) - # spline_points = vtk.vtkPoints() - # for i in range(len(bb_path)): - # spline_points.InsertPoint(i, bb_path[i][0], bb_path[i][1], bb_path[i][2]) - - # # Fit a spline to the points - # spline = vtk.vtkParametricSpline() - # spline.SetPoints(spline_points) - # functionSource = vtk.vtkParametricFunctionSource() - # functionSource.SetParametricFunction(spline) - # functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - # functionSource.Update() - - # bb_points = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) - - # tag = Method.assign_element_tag_around_path_within_radius(model, bb_points, w_bb, tag, bachmann_bundel_right) - # el = Method.assign_element_fiber_around_path_within_radius(model, bb_points, w_bb, el, smooth=True) - - # tag[SN_ids] = sinus_node - - # for i in range(model.GetPointData().GetNumberOfArrays()-1, -1, -1): - # model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - # for i in range(model.GetCellData().GetNumberOfArrays()-1, -1, -1): - # model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) - - # meshNew = dsa.WrapDataObject(model) - # meshNew.CellData.append(tag, "elemTag") - # meshNew.CellData.append(el, "fiber") - # meshNew.CellData.append(sheet, "sheet") - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/RA_epi_with_fiber.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - - # # Bachmann_Bundle internal connection - # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(df["LAA"]) - # la_connect_point = np.asarray(la_connect_point) - # ra_connect_point = np.asarray(ra_connect_point) - - # la_epi = Method.smart_reader("/home/luca/IBT/AtrialLDRBM_la816/LDRBM/Fiber_LA/result_RA/LA_epi_with_fiber.vtk") - # la_appendage_basis_point = np.asarray(df["LAA_basis_inf"]) - # length = len(bachmann_bundle_points_data) - # ra_bb_center = bachmann_bundle_points_data[int(length * 0.45)] - # # TODO PLAN D - # geo_filter_la_epi = vtk.vtkGeometryFilter() - # geo_filter_la_epi.SetInputData(la_epi) - # geo_filter_la_epi.Update() - # la_epi = geo_filter_la_epi.GetOutput() - - # geo_filter_ra_epi = vtk.vtkGeometryFilter() - # geo_filter_ra_epi.SetInputData(model) - # geo_filter_ra_epi.Update() - # ra_epi = geo_filter_ra_epi.GetOutput() - - # loc_la_epi = vtk.vtkPointLocator() - # loc_la_epi.SetDataSet(la_epi) - # loc_la_epi.BuildLocator() - - # loc_ra_epi = vtk.vtkPointLocator() - # loc_ra_epi.SetDataSet(ra_epi) - # loc_ra_epi.BuildLocator() - - # ra_a_id = loc_ra_epi.FindClosestPoint(ra_bb_center) - # ra_b_id = loc_ra_epi.FindClosestPoint(ra_connect_point) - # la_c_id = loc_la_epi.FindClosestPoint(la_connect_point) - # la_d_id = loc_la_epi.FindClosestPoint(la_appendage_basis_point) - # path_1 = Method.dijkstra_path(ra_epi, ra_a_id, ra_b_id) - # path_2 = Method.dijkstra_path(la_epi, la_c_id, la_d_id) - # path_all_temp = np.vstack((path_1, path_2)) - # # down sampling to smooth the path - # step = 10 - # path_all = np.asarray([path_all_temp[i] for i in range(len(path_all_temp)) if i % step == 0 or i == len(path_all_temp)-1]) - - # # save points for bb fiber - # filename = job.ID+'/bridges/bb_fiber.dat' - # f = open(filename, 'wb') - # pickle.dump(path_all, f) - # f.close() - - # # BB tube - - # bb_tube = Method.creat_tube_around_spline(path_all, 2) - # sphere_a = Method.creat_sphere(la_appendage_basis_point, 2 * 1.02) - # sphere_b = Method.creat_sphere(ra_bb_center, 2 * 1.02) - # Method.smart_bridge_writer(bb_tube, sphere_a, sphere_b, "BB_intern_bridges") - - # # tag = Method.assign_element_tag_around_path_within_radius(mesh, path_bb_ra, w_bb, tag, bachmann_bundel_right) - # # fiber_endo = Method.assign_element_fiber_around_path_within_radius(mesh, path_bb_ra, w_bb, fiber_endo, - # # smooth=True) - - # tag_data = vtk.util.numpy_support.numpy_to_vtk(tag, deep=True, array_type=vtk.VTK_INT) - # tag_data.SetNumberOfComponents(1) - # tag_data.SetName("elemTag") - # model.GetCellData().RemoveArray("elemTag") - # model.GetCellData().SetScalars(tag_data) - - # #model.GetCellData().AddArray(tag_data) - # abs_el = np.linalg.norm(fiber_endo, axis=1, keepdims=True) - # interpolate_arr = np.asarray([0, 0, 1]) - # index = np.argwhere(abs_el == 0) - # print('There is',len(index),'zero vector(s).') - # for var in index: - # fiber_endo[var[0]] = interpolate_arr - - # fiber_data = vtk.util.numpy_support.numpy_to_vtk(fiber_endo, deep=True, array_type=vtk.VTK_DOUBLE) - # fiber_data.SetNumberOfComponents(3) - # fiber_data.SetName("fiber") - # model.GetCellData().SetVectors(fiber_data) - - # start_time = datetime.datetime.now() - # print('Writing as RA_with_fiber... ' + str(start_time)) - # meshNew = dsa.WrapDataObject(mesh) - # writer = vtk.vtkUnstructuredGridWriter() - # writer.SetFileName(job.ID+"/result_RA/RA_with_fiber.vtk") - # writer.SetInputData(meshNew.VTKObject) - # writer.Write() - # end_time = datetime.datetime.now() - # running_time = end_time - start_time - # print('Writing as RA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') - # Pectinate muscle print("Creating Pectinate muscle 1") # the first PM is the one to the appendage diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 2bd4a5c..2f78d08 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -30,11 +30,14 @@ import vtk import argparse from scipy.spatial import cKDTree +from urllib3.filepost import writer from vtk.util import numpy_support import os import numpy as np import pandas as pd +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer + pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -174,11 +177,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv cleaner.SetInputData(connect.GetOutput()) cleaner.Update() - writer = vtk.vtkOBJWriter() - writer.SetInputData(cleaner.GetOutput()) - writer.SetFileName(f'{meshname}_cleaned.obj') - writer.Write() - + vtk_obj_writer(f'{meshname}_cleaned.obj', cleaner.GetOutput()) mesh_data["vol"] = [vol] ms = pymeshlab.MeshSet() diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index 86faa8d..10ff4d8 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -24,6 +24,7 @@ specific language governing permissions and limitations under the License. """ +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer EXAMPLE_DESCRIPTIVE_NAME = 'Tune conductivities to fit clinical LAT map' EXAMPLE_AUTHOR = 'Luca Azzolin ' @@ -695,24 +696,22 @@ def run(args, job): if len(active_border) > 0: # Elements to clean # For each area to clean, give to the active core the mean of conductivity of the active border slow_CV[active_cleaned_cells] = slow_CV[active_cleaned_cells] * ( - (lats_to_fit[active_cleaned_cells] / (LAT_map[active_cleaned_cells])) ** 2) + (lats_to_fit[active_cleaned_cells] / (LAT_map[active_cleaned_cells])) ** 2) for k in range(len(active_to_interpolate)): if len(active_border[k]) > 0: slow_CV[active_to_interpolate[k]] = np.mean(slow_CV[active_border[k]]) else: # No elements to clean # sigma_new = sigma_old*(lat_simulated/lat_clinical)^2 for sigma = CV^2 see https://opencarp.org/documentation/examples/02_ep_tissue/03a_study_prep_tunecv slow_CV[active_cells_band] = slow_CV[active_cells_band] * ( - (lats_to_fit[active_cells_band] / (LAT_map[active_cells_band])) ** 2) + (lats_to_fit[active_cells_band] / (LAT_map[active_cells_band])) ** 2) slow_CV = np.where(slow_CV > 3.5, 3.5, slow_CV) # Set an upper bound in CV of 2.15 m/s slow_CV = np.where(slow_CV < 0.15, 0.15, slow_CV) # Set a lower bound in CV of 0.35 m/s meshNew.CellData.append(slow_CV, "slow_CV") - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + f"/endo_cleaned_{l}.vtu") - writer.SetInputData(meshNew.VTKObject) - # writer.SetFileTypeToBinary() - writer.Write() + + vtk_xml_unstructured_grid_writer(job.ID + f"/endo_cleaned_{l}.vtu", meshNew.VTKObject) + LAT_diff = RMSE os.rename(simid + '/low_CV.dat', simid + '/low_CV_old.dat') f = open(simid + '/low_CV.dat', 'w') @@ -729,11 +728,8 @@ def run(args, job): meshNew.CellData.append(LATs_diff, "LATs_diff") meshNew.CellData.append(slow_CV_old, "slow_CV_old") final_diff.append(LAT_diff) - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + f"/endo_cleaned_{l}.vtu") - writer.SetInputData(meshNew.VTKObject) - # writer.SetFileTypeToBinary() - writer.Write() + + vtk.vtkXMLUnstructuredGridWriter(job.ID + f"/endo_cleaned_{l}.vtu", meshNew.VTKObject) break err = RMSE @@ -836,11 +832,7 @@ def run(args, job): meshNew.CellData.append(slow_CV, "slow_CV") meshNew.CellData.append(LATs_diff, "LATs_diff") - writer = vtk.vtkXMLUnstructuredGridWriter() - writer.SetFileName(job.ID + "/endo_final.vtu") - writer.SetInputData(meshNew.VTKObject) - # writer.SetFileTypeToBinary() - writer.Write() + vtk_xml_unstructured_grid_writer(job.ID + "/endo_final.vtu", meshNew.VTKObject) if __name__ == '__main__': From e6c4d8d565ca8950a17008be84f784c4e6927bef Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 10:24:13 +0100 Subject: [PATCH 15/70] Extracted all writing to openCARP files to helper_methods --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 37 ++----- .../LDRBM/Fiber_LA/la_generate_fiber.py | 104 ++++-------------- Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py | 30 ++--- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 62 ++++------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 31 +----- .../LDRBM/Fiber_RA/create_bridges_test.py | 35 +----- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 34 ++---- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 34 ++---- ...tune_conductivities_to_fit_clinical_LAT.py | 25 +---- 9 files changed, 93 insertions(+), 299 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 4171b44..dae2fcc 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -26,6 +26,7 @@ """ import vtk import numpy as np +from carputils.job.serialise import filename from vtk.numpy_interface import dataset_adapter as dsa from vtk.numpy_interface import algorithms as algs from scipy.spatial import cKDTree @@ -34,6 +35,7 @@ import collections from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -168,41 +170,20 @@ def generate_bilayer(endo, epi): def write_bilayer(bilayer, args, job): + file_name = job.ID + "/result_LA/LA_bilayer_with_fiber" if args.ofmt == 'vtk': - vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_bilayer_with_fiber.vtk", bilayer, store_binary=True) + vtk_unstructured_grid_writer(f"{filename}.vtk", bilayer, store_binary=True) else: - vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_bilayer_with_fiber.vtu", bilayer) - pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - with open(job.ID + '/result_LA/LA_bilayer_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") + vtk_xml_unstructured_grid_writer(f"{filename}.vtu", bilayer) + pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - - with open(job.ID + '/result_LA/LA_bilayer_with_fiber.elem', "w") as f: - f.write(f"{bilayer.GetNumberOfCells()}\n") - for i in range(bilayer.GetNumberOfCells()): - cell = bilayer.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_epi[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_epi[i])) - el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - with open(job.ID + '/result_LA/LA_bilayer_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) + write_to_pts(f'{filename}.pts', pts) + write_to_elem(f'{filename}.elem', bilayer, tag_epi) + write_to_lon(f'{filename}.lon', el_epi, sheet_epi) print('Done..') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 9a0a405..ab7c502 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -36,6 +36,7 @@ import os from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer @@ -414,31 +415,11 @@ def la_generate_fiber(model, args, job): else: vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_endo_with_fiber.vtu", meshNew.VTKObject) pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) - with open(job.ID + '/result_LA/LA_endo_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - with open(job.ID + '/result_LA/LA_endo_with_fiber.elem', "w") as f: - f.write(f"{endo.GetNumberOfCells()}\n") - for i in range(endo.GetNumberOfCells()): - cell = endo.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write( - f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_endo[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_endo[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_endo[i])) - - with open(job.ID + '/result_LA/LA_endo_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_endo)): - f.write("{} {} {} {} {} {}\n".format(el_endo[i][0], el_endo[i][1], el_endo[i][2], sheet_endo[i][0], - sheet_endo[i][1], sheet_endo[i][2])) + write_to_pts(job.ID + '/result_LA/LA_endo_with_fiber.pts', pts) + + write_to_elem(job.ID + '/result_LA/LA_endo_with_fiber.elem', endo, tag_endo) + + write_to_lon(job.ID + '/result_LA/LA_endo_with_fiber.lon', el_endo, sheet_endo) running_time = end_time - start_time @@ -496,9 +477,6 @@ def la_generate_fiber(model, args, job): # Bachmann Bundle if args.mesh_type == "vol": # Extract epicardial surface - - # epi_surf = Method.smart_reader(args.mesh[:-4]+'_epi.obj') - # epi_surf = Method.cell_array_mapper(model, epi_surf, "elemTag", "all") geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) geo_filter.Update() @@ -568,36 +546,17 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(el_epi, "fiber") meshNew.CellData.append(sheet_epi, "sheet") if args.ofmt == 'vtk': - vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_epi_with_fiber.vtk", meshNew.VTKObject, store_binary=True) + vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_epi_with_fiber.vtk", meshNew.VTKObject, + store_binary=True) else: vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_epi_with_fiber.vtu", meshNew.VTKObject) pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - with open(job.ID + '/result_LA/LA_epi_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - with open(job.ID + '/result_LA/LA_epi_with_fiber.elem', "w") as f: - f.write(f"{epi.GetNumberOfCells()}\n") - for i in range(epi.GetNumberOfCells()): - cell = epi.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write( - f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_epi[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_epi[i])) - - with open(job.ID + '/result_LA/LA_epi_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) + + write_to_pts(job.ID + '/result_LA/LA_epi_with_fiber.pts', pts) + + write_to_elem(job.ID + '/result_LA/LA_epi_with_fiber.elem', epi, tag_epi) + + write_to_lon(job.ID + '/result_LA/LA_epi_with_fiber.lon', el_epi, sheet_epi) end_time = datetime.datetime.now() running_time = end_time - start_time @@ -629,35 +588,18 @@ def la_generate_fiber(model, args, job): meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") meshNew.CellData.append(sheet, "sheet") + filename = job.ID + "/result_LA/LA_vol_with_fiber" if args.ofmt == 'vtk': - vtk_unstructured_grid_writer(job.ID + "/result_LA/LA_vol_with_fiber.vtk", meshNew.VTKObject, store_binary=True) + vtk_unstructured_grid_writer(filename + ".vtk", meshNew.VTKObject, + store_binary=True) else: - vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_vol_with_fiber.vtu", meshNew.VTKObject) + vtk_xml_unstructured_grid_writer(filename + ".vtu", meshNew.VTKObject) pts = numpy_support.vtk_to_numpy(model.GetPoints().GetData()) - with open(job.ID + '/result_LA/LA_vol_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - with open(job.ID + '/result_LA/LA_vol_with_fiber.elem', "w") as f: - f.write(f"{model.GetNumberOfCells()}\n") - for i in range(model.GetNumberOfCells()): - cell = model.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag[i])) - - with open(job.ID + '/result_LA/LA_vol_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el[i][0], el[i][1], el[i][2], sheet[i][0], - sheet[i][1], sheet[i][2])) + + write_to_pts(filename + '.pts', pts) + write_to_elem(filename + '.elem', model, tag) + write_to_lon(filename + '.lon', el, sheet) + end_time = datetime.datetime.now() running_time = end_time - start_time diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py index e436bbf..6a2e79a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py @@ -27,6 +27,8 @@ import os import subprocess as sp import datetime +import warnings + import vtk import numpy as np from vtk.util import numpy_support @@ -36,6 +38,7 @@ from la_laplace import la_laplace from la_generate_fiber import la_generate_fiber import Methods_LA +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon def parser(): @@ -104,33 +107,16 @@ def run(args, job): pts = numpy_support.vtk_to_numpy(LA.GetPoints().GetData()) - with open(LA_mesh + '.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - with open(LA_mesh + '.elem', "w") as f: - f.write(f"{LA.GetNumberOfCells()}\n") - for i in range(LA.GetNumberOfCells()): - cell = LA.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {1}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), 1)) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), 1)) + write_to_pts(LA_mesh + '.pts', pts) + + write_to_elem( LA_mesh + '.elem', LA, np.ones(LA.GetNumberOfCells(), dtype=int)) fibers = np.zeros((LA.GetNumberOfCells(), 6)) fibers[:, 0] = 1 fibers[:, 4] = 1 - with open(LA_mesh + '.lon', "w") as f: - f.write("2\n") - for i in range(len(fibers)): - f.write("{} {} {} {} {} {}\n".format(fibers[i][0], fibers[i][1], fibers[i][2], fibers[i][3], fibers[i][4], - fibers[i][5])) + warnings.warn("Test if lon is storred correctly la_main.py l116 ff.") + write_to_lon(LA_mesh + '.lon', fibers, [fiber[3:6] for fiber in fibers], precession=1) start_time = datetime.datetime.now() init_start_time = datetime.datetime.now() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index b705d6c..86b0c5c 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -31,6 +31,8 @@ from scipy.spatial import cKDTree import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_elem, write_to_pts, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -168,45 +170,25 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): return bilayer -def write_bilayer(args, job): - reader = vtk.vtkXMLUnstructuredGridReader() - reader.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # - reader.Update() - bilayer = reader.GetOutput() +def write_bilayer(bilayer, args, job): + file_name = job.ID + "/result_RA/LA_RA_bilayer_with_fiber" + if args.ofmt == 'vtk': + vtk_unstructured_grid_writer(f"{file_name}.vtk", bilayer, True) + else: + vtk_xml_unstructured_grid_writer(f"{file_name}.vtu", bilayer) - pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - - with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.elem', "w") as f: - f.write(f"{bilayer.GetNumberOfCells()}\n") - for i in range(bilayer.GetNumberOfCells()): - cell = bilayer.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_epi[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_epi[i])) - else: - print("strange " + str(cell.GetNumberOfPoints())) - el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) + pts = vtk_to_numpy(bilayer.GetPoints().GetData()) + + write_to_pts(f'{file_name}.pts', pts) + + tag_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) + + write_to_elem(f'{file_name}.elem', bilayer, tag_epi) + + el_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) + sheet_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - with open(job.ID + '/result_RA/LA_RA_bilayer_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) - print('Done...') + write_to_lon(f'{file_name}.lon', el_epi, sheet_epi) def generate_sheet_dir(args, model, job): @@ -1070,11 +1052,7 @@ def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): def create_pts(array_points, array_name, mesh_dir): - f = open(f"{mesh_dir}{array_name}.pts", "w") - f.write("0 0 0\n") - for i in range(len(array_points)): - f.write(f"{array_points[i][0]} {array_points[i][1]} {array_points[i][2]}\n") - f.close() + write_to_pts(f"{mesh_dir}{array_name}.pts", array_points) def to_polydata(mesh): diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index ae0cc02..7a085b2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -37,6 +37,7 @@ import Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer @@ -584,35 +585,11 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu", epi) pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") + write_to_pts(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', pts) tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) + write_to_elem(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', epi, tag_epi) - with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', "w") as f: - f.write(f"{epi.GetNumberOfCells()}\n") - for i in range(epi.GetNumberOfCells()): - cell = epi.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write( - f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_epi[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_epi[i])) - else: - print("strange " + str(cell.GetNumberOfPoints())) el_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('sheet')) - - with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) + write_to_lon(job.ID + '/result_RA/LA_RA_vol_with_fiber.lon', el_epi, sheet_epi) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 04e3351..234e58b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -47,6 +47,7 @@ import pandas as pd from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ vtk_unstructured_grid_writer, vtk_obj_writer @@ -277,7 +278,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() bridge_usg = reader.GetOutput() - locator = vtk.vtkStaticPointLocator() locator.SetDataSet(la_ra_usg) locator.BuildLocator() @@ -369,7 +369,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): print("Union between earth and bridges") for var in bridge_list: - mesh_D = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj") mesh_E = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_earth.obj") # # Warning: set -1 if pts normals are pointing outside @@ -480,41 +479,19 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): Method.write_bilayer(bilayer, args, job) else: + file_name = job.ID + "/result_RA/LA_RA_vol_with_fiber" + vtk_xml_unstructured_grid_writer(f"{file_name}.vtu", epi) - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu", epi) pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) - with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) - with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', "w") as f: - f.write(f"{epi.GetNumberOfCells()}\n") - for i in range(epi.GetNumberOfCells()): - cell = epi.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write( - f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_epi[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_epi[i])) - else: - print("strange " + str(cell.GetNumberOfPoints())) el_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('sheet')) - with open(job.ID + '/result_RA/LA_RA_vol_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) + write_to_pts(f'{file_name}.pts', pts) + write_to_elem(f'{file_name}.elem', epi, tag_epi) + write_to_lon(f'{file_name}.lon', el_epi, sheet_epi) if __name__ == '__main__': diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index 79afda9..538328a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -14,6 +14,9 @@ # from sklearn.neighbors import NearestNeighbors import argparse +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer + parser = argparse.ArgumentParser(description='Create Right Atrium.') parser.add_argument('--mesh', @@ -156,40 +159,19 @@ def generate_bilayer(endo, epi, max_dist=np.inf): # Creates VTK and CARP files: .pts, .lon, .elem def write_bilayer(bilayer): - vtk_unstructured_grid_writer(args.mesh + "/RA_bilayer_with_fiber.vtk", bilayer, store_binary=True) + file_name=args.mesh + "/RA_bilayer_with_fiber" + vtk_unstructured_grid_writer(f"{file_name}.vtk", bilayer, store_binary=True) pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - with open(args.mesh + '/RA_bilayer_with_fiber.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - with open(args.mesh + '/RA_bilayer_with_fiber.elem', "w") as f: - f.write(f"{bilayer.GetNumberOfCells()}\n") - for i in range(bilayer.GetNumberOfCells()): - cell = bilayer.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {tag_epi[i]}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), tag_epi[i])) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), - tag_epi[i])) - else: - print("strange " + str(cell.GetNumberOfPoints())) el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - with open(args.mesh + '/RA_bilayer_with_fiber.lon', "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) + write_to_pts(f'{file_name}.pts', pts) + write_to_elem(f'{file_name}.elem', bilayer, tag_epi) + write_to_lon(f'{file_name}.lon', el_epi, sheet_epi) print('Generated Bilayer RA') diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index 3fae5bf..14a439e 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -25,6 +25,8 @@ under the License. """ import os +import warnings + import numpy as np import vtk import pandas as pd @@ -36,6 +38,7 @@ from ra_generate_fiber import ra_generate_fiber import Methods_RA as Method from create_bridges import add_free_bridge +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon def parser(): @@ -114,36 +117,17 @@ def run(args, job): RA = reverse.GetOutput() pts = numpy_support.vtk_to_numpy(RA.GetPoints().GetData()) - # cells = numpy_support.vtk_to_numpy(RA.GetPolys().GetData()) - # cells = cells.reshape(int(len(cells)/4),4)[:,1:] - - with open(RA_mesh + '.pts', "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - with open(RA_mesh + '.elem', "w") as f: - f.write(f"{RA.GetNumberOfCells()}\n") - for i in range(RA.GetNumberOfCells()): - cell = RA.GetCell(i) - if cell.GetNumberOfPoints() == 2: - f.write(f"Ln {cell.GetPointIds().GetId(0)} {cell.GetPointIds().GetId(1)} {1}\n") - elif cell.GetNumberOfPoints() == 3: - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), 1)) - elif cell.GetNumberOfPoints() == 4: - f.write("Tt {} {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), cell.GetPointIds().GetId(3), 1)) + + write_to_pts(RA_mesh + '.pts', pts) + + write_to_elem(RA_mesh + '.elem', RA, np.ones(RA.GetNumberOfCells(), dtype=int)) fibers = np.zeros((RA.GetNumberOfCells(), 6)) fibers[:, 0] = 1 fibers[:, 4] = 1 - with open(RA_mesh + '.lon', "w") as f: - f.write("2\n") - for i in range(len(fibers)): - f.write("{} {} {} {} {} {}\n".format(fibers[i][0], fibers[i][1], fibers[i][2], fibers[i][3], fibers[i][4], - fibers[i][5])) + write_to_lon(RA_mesh + '.lon', fibers, [fiber[3:6] for fiber in fibers]) + warnings.warn("Test if lon is storred correctly ra_main.py l120 ff.") start_time = datetime.datetime.now() print('[Step 1] Solving laplace-dirichlet... ' + str(start_time)) diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index 10ff4d8..0accbad 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -24,6 +24,7 @@ specific language governing permissions and limitations under the License. """ +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer EXAMPLE_DESCRIPTIVE_NAME = 'Tune conductivities to fit clinical LAT map' @@ -375,32 +376,18 @@ def run(args, job): vtk_xml_unstructured_grid_writer(f"{meshfold}/LA_endo_with_fiber_30_um.vtu", meshNew.VTKObject) pts = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetPoints().GetData()) - with open(meshfold + "/LA_endo_with_fiber_30_um.pts", "w") as f: - f.write(f"{len(pts)}\n") - for i in range(len(pts)): - f.write(f"{pts[i][0]} {pts[i][1]} {pts[i][2]}\n") - - with open(meshfold + "/LA_endo_with_fiber_30_um.elem", "w") as f: - f.write(f"{meshNew.VTKObject.GetNumberOfCells()}\n") - for i in range(meshNew.VTKObject.GetNumberOfCells()): - cell = meshNew.VTKObject.GetCell(i) - f.write("Tr {} {} {} {}\n".format(cell.GetPointIds().GetId(0), cell.GetPointIds().GetId(1), - cell.GetPointIds().GetId(2), endo_etag[i])) el_epi = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetCellData().GetArray('sheet')) el_epi = el_epi / 1000 sheet_epi = sheet_epi / 1000 + file_name = meshfold + "/LA_endo_with_fiber_30_um" + write_to_pts(f"{file_name}.pts", pts) + write_to_elem(f"{file_name}.elem", meshNew.VTKObject, endo_etag) + write_to_lon(f"{file_name}.lon", el_epi, sheet_epi) - with open(meshfold + "/LA_endo_with_fiber_30_um.lon", "w") as f: - f.write("2\n") - for i in range(len(el_epi)): - f.write("{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(el_epi[i][0], el_epi[i][1], el_epi[i][2], - sheet_epi[i][0], sheet_epi[i][1], - sheet_epi[i][2])) - - meshname_e = meshfold + "/LA_endo_with_fiber_30_um" + meshname_e = file_name new_endo = Methods_fit_to_clinical_LAT.smart_reader(meshname_e + '.vtu') cellid = vtk.vtkIdFilter() From 182c2d1b70f197bdc9f7fdaebc980956edcfd478 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 11:34:03 +0100 Subject: [PATCH 16/70] Fixed bug where files were wrongly named. Introduced two commits before --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 21 +++++++++---------- .../LDRBM/Fiber_LA/la_calculate_gradient.py | 7 ++++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index dae2fcc..b21aea6 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -24,15 +24,14 @@ specific language governing permissions and limitations under the License. """ -import vtk +import collections + import numpy as np -from carputils.job.serialise import filename -from vtk.numpy_interface import dataset_adapter as dsa -from vtk.numpy_interface import algorithms as algs +import vtk from scipy.spatial import cKDTree -from vtk.util import numpy_support from scipy.spatial.distance import cosine -import collections +from vtk.numpy_interface import dataset_adapter as dsa +from vtk.util import numpy_support from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon @@ -172,18 +171,18 @@ def generate_bilayer(endo, epi): def write_bilayer(bilayer, args, job): file_name = job.ID + "/result_LA/LA_bilayer_with_fiber" if args.ofmt == 'vtk': - vtk_unstructured_grid_writer(f"{filename}.vtk", bilayer, store_binary=True) + vtk_unstructured_grid_writer(f"{file_name}.vtk", bilayer, store_binary=True) else: - vtk_xml_unstructured_grid_writer(f"{filename}.vtu", bilayer) + vtk_xml_unstructured_grid_writer(f"{file_name}.vtu", bilayer) pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) - write_to_pts(f'{filename}.pts', pts) - write_to_elem(f'{filename}.elem', bilayer, tag_epi) - write_to_lon(f'{filename}.lon', el_epi, sheet_epi) + write_to_pts(f'{file_name}.pts', pts) + write_to_elem(f'{file_name}.elem', bilayer, tag_epi) + write_to_lon(f'{file_name}.lon', el_epi, sheet_epi) print('Done..') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py index aa4fb3b..10a5728 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py @@ -24,11 +24,12 @@ specific language governing permissions and limitations under the License. """ -import numpy as np -import vtk -from vtk.numpy_interface import dataset_adapter as dsa import os +import vtk + +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer + def la_calculate_gradient(args, model, job): name_list = ['phi', 'r', 'v', 'ab'] From 55453ae8655a9ed61284139aadf7d31314d6520c Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 11:34:58 +0100 Subject: [PATCH 17/70] Fixed bug where ids for labeling atrial orifices did not match ids of vtk files. Present in all AugmentA branches --- Atrial_LDRBM/Generate_Boundaries/extract_rings.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 6a54d92..dfd1aff 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -231,8 +231,12 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i vtkWrite(geo_filter.GetOutput(), outdir + '/LA.vtk'.format(mesh)) LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) centroids["LAA"] = LA_ap_point + array_name = "Ids" + if mesh_surf.GetPointData().GetArray(array_name) is not None: + #Remove previouse id so they match with indices + mesh_surf.GetPointData().RemoveArray(array_name) idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) + idFilter.SetInputData(mesh_surf) if int(vtk_version) >= 9: idFilter.SetPointIdsArrayName('Ids') idFilter.SetCellIdsArrayName('Ids') @@ -240,6 +244,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i idFilter.SetIdsArrayName('Ids') idFilter.Update() LA = idFilter.GetOutput() + LA_rings = detect_and_mark_rings(LA, LA_ap_point, outdir, debug) b_tag = np.zeros((LA.GetNumberOfPoints(),)) b_tag, centroids = mark_LA_rings(LAA_id, LA_rings, b_tag, centroids, outdir, LA) From ffdd13daaa49a956137fd7145c1d5319dcc25e5d Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 13:15:24 +0100 Subject: [PATCH 18/70] Removed multiline commented code --- .../Generate_Boundaries/extract_rings.py | 5 - .../extract_rings_TOP_epi_endo.py | 4 - Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 92 +------------------ .../LDRBM/Fiber_LA/la_generate_fiber.py | 14 --- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 24 ----- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 25 ----- .../LDRBM/Fiber_RA/create_bridges_test.py | 10 -- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 12 --- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 63 +------------ pipeline.py | 48 ---------- .../Methods_fit_to_clinical_LAT.py | 8 +- ...tune_conductivities_to_fit_clinical_LAT.py | 12 --- 12 files changed, 3 insertions(+), 314 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index dfd1aff..723a5ee 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -143,11 +143,6 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] - # thr = vtk.vtkThreshold() - # thr.SetInputData(mesh_conn) - # thr.ThresholdBetween(LA_tag, LA_tag) - # thr.Update() - warning("WARNING: Should be checkt for functionality extract_rings l151") thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index c185a15..ae3c3b5 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -942,10 +942,6 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): tv_id_epi = np.intersect1d(pts_in_tv_epi, pts_in_top_epi) - # pts_in_top_endo = vtk.util.numpy_support.vtk_to_numpy(top_cut_endo.GetPoints().GetData()) - # pts_in_svc = vtk.util.numpy_support.vtk_to_numpy(svc.GetPoints().GetData()) - # pts_in_ivc = vtk.util.numpy_support.vtk_to_numpy(ivc.GetPoints().GetData()) - endo_ids = vtk.util.numpy_support.vtk_to_numpy(endo.GetPointData().GetArray("Ids")) tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(endo.GetPoints().GetData())) dd, ii = tree.query(svc_points) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index b21aea6..024cae4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -75,13 +75,6 @@ def move_surf_along_normals(mesh, eps, direction): extract_surf.SetInputData(mesh) extract_surf.Update() - # reverse = vtk.vtkReverseSense() - # reverse.ReverseCellsOn() - # reverse.ReverseNormalsOn() - # reverse.SetInputConnection(extract_surf.GetOutputPort()) - # reverse.Update() - - # polydata = reverse.GetOutput() polydata = extract_surf.GetOutput() normalGenerator = vtk.vtkPolyDataNormals() @@ -503,26 +496,6 @@ def get_ct_end_points_id(endo, ct, scv, icv): def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, ra_tv_surface): - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_tv_s_surface.vtk') - # reader.Update() - # tv_s = reader.GetOutput() - - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_ivc_surface.vtk') - # reader.Update() - # tv_ivc = reader.GetOutput() - - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_svc_surface.vtk') - # reader.Update() - # tv_svc = reader.GetOutput() - - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_tv_surface.vtk') - # reader.Update() - # tv = reader.GetOutput() - tv_center = get_mean_point(ra_tv_surface) tv_ivc_center = get_mean_point(ra_ivc_surface) tv_svc_center = get_mean_point(ra_svc_surface) @@ -943,73 +916,10 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e bb_left = get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) - # bb_left = get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) - # bb_left = savgol_filter(bb_left, 5, 2, mode='interp', axis =0) - - # new = [] - # diff = 1000 - # for n in range(len(bb_left)): - # if not new or np.sqrt(np.sum((np.array(bb_left[n])-np.array(new[-1]))**2, axis=0)) >= diff: - # new.append(bb_left[n]) - # new = np.array(new) - - # tck, u = interpolate.splprep([new[:,0],new[:,1],new[:,2]], s=100) - # x_knots, y_knots, z_knots = interpolate.splev(tck[0], tck) - - # u_fine = np.linspace(0,1,len(bb_left)) - # x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) - - # bb_left = np.array([x_knots, y_knots, z_knots]).T - # bb_left = np.array([x_fine, y_fine, z_fine]).T - - # u_fine = np.linspace(0,1,len(bb_left)) - # x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck) - # new_points = splev(u, tck) - # window_width = 1000 - # cumsum_vec = np.cumsum(np.insert(data, 0, 0)) - # ma_vec = (cumsum_vec[window_width:] - cumsum_vec[:-window_width]) / window_width - - # pts = vtk.vtkPoints() - # for n in range(len(bb_left)): - # pts.InsertNextPoint(bb_left[n]) - - # smoothingIterations = 15 - # passBand = 0.001 - # featureAngle = 120.0 - - # smoother = vtk.vtkWindowedSincPolyDataFilter() - # smoother.SetInputConnection(discrete->GetOutputPort()) - # smoother.SetNumberOfIterations(smoothingIterations) - # smoother.BoundarySmoothingOff() - # smoother.FeatureEdgeSmoothingOff() - # smoother.SetFeatureAngle(featureAngle) - # smoother.SetPassBand(passBand) - # smoother.NonManifoldSmoothingOn() - # smoother.NormalizeCoordinatesOn() - # smoother.Update() - - # Smooth the path fitting a spline? - # new = [] - # diff = 1000 - # for n in range(len(bb_left)): - # if not new or np.sqrt(np.sum((np.array(bb_left[n])-np.array(new[-1]))**2, axis=0)) >= diff: - # new.append(bb_left[n]) - # new = np.array(new) - # bb_left = np.array(new) - # n = bb_left.shape[0] - # new = [] # change dtype if you need to - # tree = cKDTree(bb_left) - # for i in range(n): - # neighbors = tree.query_ball_point(bb_left[i], 1000) - # temp = [bb_left[k] for k in neighbors] - # new.append(np.mean(temp, axis =0)) - - # # mesh.VPos = final - # bb_left = np.array(new) + return bb_left, thresh.GetOutput().GetPoint(inf_appendage_basis_id), thresh.GetOutput().GetPoint( sup_appendage_basis_id), thresh.GetOutput().GetPoint(LAA_pt_far_from_LIPV_id) - # return bb_left, epi.GetPoint(inf_appendage_basis_id), epi.GetPoint(sup_appendage_basis_id), epi.GetPoint(LAA_pt_far_from_LIPV_id) def get_in_surf1_closest_point_in_surf2(surf1, surf2, pt_id_in_surf2): diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index ab7c502..e74f7ca 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -388,10 +388,6 @@ def la_generate_fiber(model, args, job): el_endo[PVs["LIPV"]] = v_grad_norm[PVs["LIPV"]] el_endo[PVs["LSPV"]] = v_grad_norm[PVs["LSPV"]] - # for i in range(len(v_grad_norm)): - # if v[i] <= 0.2: - # el_endo[i] = v_grad_norm[i] - end_time = datetime.datetime.now() el_endo = np.where(el_endo == [0, 0, 0], [1, 0, 0], el_endo).astype("float32") @@ -515,16 +511,6 @@ def la_generate_fiber(model, args, job): df["LAA_far_from_LIPV"] = LAA_far_from_LIPV df.to_csv(args.mesh + "_surf/rings_centroids.csv", float_format="%.2f", index=False) - - # # Bachmann_Bundle internal connection - # la_connect_point, ra_connect_point = Method.get_connection_point_la_and_ra(la_appex_point) - # la_connect_point = np.asarray(la_connect_point) - # - # path_start_end = np.vstack((appendage_basis, la_connect_point)) - # path_bb_ra = Method.creat_center_line(path_start_end) - # tag = Method.assign_element_tag_around_path_within_radius(model, path_bb_ra, 2, tag, bachmann_bundel_left) - # el = Method.assign_element_fiber_around_path_within_radius(model, path_bb_ra, 2, el, smooth=True) - print("Creating bachmann bundles... done") if args.mesh_type == "bilayer": el_epi = np.where(el_epi == [0, 0, 0], [1, 0, 0], el_epi).astype("float32") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 86b0c5c..417a7e4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -280,10 +280,6 @@ def generate_sheet_dir(args, model, job): writing ''' print('writing...') - # sheet_data = vtk.util.numpy_support.numpy_to_vtk(sheet_norm, deep=True, array_type=vtk.VTK_DOUBLE) - # sheet_data.SetNumberOfComponents(3) - # sheet_data.SetName("sheet") - # model.GetCellData().AddArray(sheet_data) meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(fiber, "fiber") @@ -667,26 +663,6 @@ def get_ct_end_points_id(endo, ct, scv, icv): def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, ra_tv_surface): - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_tv_s_surface.vtk') - # reader.Update() - # tv_s = reader.GetOutput() - - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_ivc_surface.vtk') - # reader.Update() - # tv_ivc = reader.GetOutput() - - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_svc_surface.vtk') - # reader.Update() - # tv_svc = reader.GetOutput() - - # reader = vtk.vtkPolyDataReader() - # reader.SetFileName('model_pm/ra_tv_surface.vtk') - # reader.Update() - # tv = reader.GetOutput() - tv_center = get_mean_point(ra_tv_surface) tv_ivc_center = get_mean_point(ra_ivc_surface) tv_svc_center = get_mean_point(ra_svc_surface) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 7a085b2..6d5b51d 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -124,10 +124,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): loc.BuildLocator() point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p + TV_p * 0.1)) # adapt this value if CS is too low - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(la_wall) - # loc.BuildLocator() - # point_CS_on_MV = la_wall.GetPoint(loc.FindClosestPoint(CS_p+TV_p*0.1)) loc = vtk.vtkPointLocator() loc.SetDataSet(ra_septum) @@ -222,31 +218,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() bridge_usg = reader.GetOutput() - # geo_filter = vtk.vtkGeometryFilter() - # geo_filter.SetInputData(bridge_usg) - # geo_filter.Update() - # bridge = geo_filter.GetOutput() - - # reverse = vtk.vtkReverseSense() - # reverse.ReverseCellsOn() - # reverse.ReverseNormalsOn() - # reverse.SetInputConnection(cleaner.GetOutputPort()) - # reverse.Update() - - # earth = reverse.GetOutput() - - # vbool = vtk.vtkBooleanOperationPolyDataFilter() - # vbool.SetOperationToDifference() - # vbool.SetInputData( 0, epi_surf ) - # vbool.SetInputData( 1, bridge ) - - # vbool.Update() - locator = vtk.vtkStaticPointLocator() locator.SetDataSet(la_ra_usg) locator.BuildLocator() - # intersection_points = vbool.GetOutput().GetPoints().GetData() intersection_points = bridge_usg.GetPoints().GetData() intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 234e58b..0977ab2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -180,11 +180,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): loc.BuildLocator() point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p + TV_p * 0.1)) - # loc = vtk.vtkPointLocator() - # loc.SetDataSet(la_wall) - # loc.BuildLocator() - # point_CS_on_MV = la_wall.GetPoint(loc.FindClosestPoint(CS_p+TV_p*0.1)) - loc = vtk.vtkPointLocator() loc.SetDataSet(ra_septum) loc.BuildLocator() @@ -342,11 +337,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): if args.debug: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", append_filter.AddInputData(extract.GetOutput())) - # append_filter = vtk.vtkAppendFilter() - # append_filter.MergePointsOn() - # append_filter.SetTolerance(0.2*args.scale) - # append_filter.AddInputData(append_filter.GetOutput()) - # meshNew = dsa.WrapDataObject(extract.GetOutput()) filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index 538328a..c195556 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -37,10 +37,6 @@ def run(args): reader.Update() ra_endo = reader.GetOutput() - # reader = vtk.vtkUnstructuredGridReader() - # reader.SetFileName(args.mesh + "/RA_endo_with_fiber.vtk") - # reader.Update() - # ra_endo = reader.GetOutput() reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(args.mesh + "/RA_epi_with_fiber.vtk") @@ -62,13 +58,6 @@ def move_surf_along_normals(mesh, eps, direction): extract_surf.SetInputData(mesh) extract_surf.Update() - # reverse = vtk.vtkReverseSense() - # reverse.ReverseCellsOn() - # reverse.ReverseNormalsOn() - # reverse.SetInputConnection(extract_surf.GetOutputPort()) - # reverse.Update() - - # polydata = reverse.GetOutput() polydata = extract_surf.GetOutput() normalGenerator = vtk.vtkPolyDataNormals() @@ -76,7 +65,6 @@ def move_surf_along_normals(mesh, eps, direction): normalGenerator.ComputeCellNormalsOff() normalGenerator.ComputePointNormalsOn() normalGenerator.ConsistencyOn() - # normalGenerator.AutoOrientNormalsOn() normalGenerator.SplittingOff() normalGenerator.Update() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 4e62c45..943c947 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -261,10 +261,6 @@ def ra_generate_fiber(model, args, job): IVC_max_r_CT_pt = IVC_s.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy( IVC_s.GetPointData().GetArray('phie_r')))) # not always the best choice for pm1 - # thr_min = 0.150038 - # thr_max = 0.38518 - - # CT_band = vtk_thr(RAW_s, 2,"CELLS","phie_w", thr_min, thr_max) # dk01 fit_both CT_band = vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w CT_band = Method.extract_largest_region(CT_band) CT_ub = vtk_thr(RAW_s, 2, "CELLS", "phie_w", tao_ct_plus - 0.02, tao_ct_plus) # grad_w @@ -312,21 +308,12 @@ def ra_generate_fiber(model, args, job): CT_band = extract.GetOutput() - # IVC_max_r_CT_pt = CT_band.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetPointData().GetArray('phie_r')))) # optional choice for pm, be careful as it overwrites - if args.debug: Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band_2.vtk") CT_band_ids = vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) tao_RAA = np.max(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('phie_v2'))) - # tao_RAA = 0.45 # for patient 20220203 - - # CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) - - # tag[CT_ids] = crista_terminalis - - # CT part from IVC to septum loc = vtk.vtkPointLocator() loc.SetDataSet(CT_band) @@ -509,26 +496,6 @@ def ra_generate_fiber(model, args, job): RAA_CT_pt = CT_band.GetPoint(loc.FindClosestPoint(np.array(df["RAA"]))) - # # calculate the norm vector - # v1 = np.array(SVC_CT_pt) - np.array(RAA_CT_pt) - # v2 = np.array(SVC_CT_pt) - np.array(df["TV"]) - # norm = np.cross(v1, v2) - - # #normalize norm - # n = np.linalg.norm(norm) - # norm_1 = norm/n - - # plane = vtk.vtkPlane() - # plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) - # plane.SetOrigin(SVC_CT_pt[0], SVC_CT_pt[1], SVC_CT_pt[2]) - - # meshExtractFilter = vtk.vtkExtractGeometry() - # meshExtractFilter.SetInputData(CT_band) - # meshExtractFilter.SetImplicitFunction(plane) - # meshExtractFilter.Update() - # CT = meshExtractFilter.GetOutput() - - # CT = Method.extract_largest_region(CT) CT = CT_band CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) @@ -574,26 +541,13 @@ def ra_generate_fiber(model, args, job): # k # k = ab_grad print('############### k ###############') - # print(k) - - # en - # en = ab_grad - # for i in range(len(k)): - # en[i] = k[i] - np.dot(k[i], et[i]) * et[i] en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) - # normlize the en - # abs_en = np.linalg.norm(en, axis=1, keepdims=True) - # for i in range(len(abs_en)): - # if abs_en[i] == 0: - # abs_en[i] =1 - # en = en/abs_en + abs_en = np.linalg.norm(en, axis=1, keepdims=True) abs_en = np.where(abs_en != 0, abs_en, 1) en = en / abs_en print('############### en ###############') - # print(en) - # el el = np.cross(en, et) @@ -867,21 +821,6 @@ def ra_generate_fiber(model, args, job): el = Method.assign_element_fiber_around_path_within_radius(model, pm, w_pm, el, smooth=False) - # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) - - # tag_endo = Method.assign_element_tag_around_path_within_radius(endo, pm, w_pm, tag_endo, pectinate_muscle) - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(endo, pm, w_pm, fiber_endo, smooth=True) - - # for i in range(pm_num): - # pm_point_1 = pm_ct_id_list[(i + 1) * pm_ct_dis] - # pm_point_2 = pm_tv_id_list[(i + 1) * pm_tv_dis] - - # pm = Method.dijkstra_path_on_a_plane(surface, args, pm_point_1, pm_point_2, center) - # pm = pm[int(len(pm)*0.05):,:] - # print("The ", i + 1, "th pm done") - # tag_endo = Method.assign_element_tag_around_path_within_radius(endo, pm, w_pm, tag_endo, pectinate_muscle) - # fiber_endo = Method.assign_element_fiber_around_path_within_radius(endo, pm, w_pm, fiber_endo, smooth=True) - if args.mesh_type == "bilayer": print("Creating Pectinate muscle... done!") diff --git a/pipeline.py b/pipeline.py index 67a8f74..6141969 100644 --- a/pipeline.py +++ b/pipeline.py @@ -164,12 +164,6 @@ def AugmentA(args): df = pd.DataFrame(mesh_data) df.to_csv(fname, float_format="%.2f", index=False) - # print("Labelling atrial orifices") - # label_atrial_orifices(args.mesh,LAA,RAA) - - # Label atrial orifices using apex id found in the resampling algorithm - # df = pd.read_csv('{}_mesh_data.csv'.format(meshname)) - # Atrial orifices already open print("Atrial orifices already open") processed_mesh = meshname @@ -251,52 +245,10 @@ def AugmentA(args): meshin = pv.read(f'{processed_mesh}.ply') pv.save_meshio(f'{processed_mesh}.obj', meshin, "obj") - # p = pv.Plotter(notebook=False) - # - # if args.use_curvature_to_open: - # print("Propose appendage apex location using surface curvature") - # os.system("meshtool query curvature -msh={}.obj -size={}".format(meshname, 30*args.scale)) - # curv = np.loadtxt('{}.curv.dat'.format(meshname)) - # mesh_curv = pv.read('{}.obj'.format(meshname)) - # - # apex = mesh_curv.points[np.argmax(curv),:] - # - # point_cloud = pv.PolyData(apex) - # - # p.add_mesh(point_cloud, color='w', point_size=30.*args.scale, render_points_as_spheres=True) - # - # p.add_mesh(meshin,color='r') - # p.enable_point_picking(meshin, use_picker=True) - # p.add_text('Select the appendage apex and close the window',position='lower_left') - # - # p.show() - # - # if p.picked_point is not None: - # apex = p.picked_point - # - # print("Apex coordinates: ", apex) - # p.close() - # mesh_data = dict() - # tree = cKDTree(meshin.points.astype(np.double)) - # dist, apex_id = tree.query(apex) - # - # mesh_data[args.atrium+"A_id"] = [apex_id] - # - # fname = '{}_mesh_data.csv'.format(meshname) - # df = pd.DataFrame(mesh_data) - # df.to_csv(fname, float_format="%.2f", index=False) - elif not args.resample_input and not args.find_appendage: # do not resample and do not find appendage processed_mesh = meshname # Provide mesh with _res in the name - # if not args.closed_surface: - # #Convert mesh from vtk to obj - # meshin = pv.read('{}.vtk'.format(meshname)) - # pv.save_meshio('{}.obj'.format(meshname), meshin, "obj") - # else: - # meshin = pv.read('{}.obj'.format(meshname)) - # Label atrial orifices using apex id found in the resampling algorithm df = pd.read_csv(f'{processed_mesh}_mesh_data.csv') diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 3f9d2a4..34f35e4 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -33,6 +33,7 @@ from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -379,13 +380,6 @@ def create_regele(endo, args): low_vol_ids = vtk.util.numpy_support.vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) not_low_volt_endo = vtk_thr(endo, 0, "POINTS", "bi", 0.5 + 0.01) - # f_not_conductive = job.ID + '/elems_not_conductive' - # file = open(f_not_conductive + '.regele', 'w') - # file.write(str(len(elems_not_conductive)) + '\n') - # for i in elems_not_conductive: - # file.write(str(i) + '\n') - # file.close() - f_slow_conductive = f"{args.init_state_dir}/{args.mesh.split('/')[-1]}/elems_slow_conductive" file = open(f_slow_conductive + '.regele', 'w') file.write(str(len(low_vol_ids)) + '\n') diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index 0accbad..7831349 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -549,18 +549,6 @@ def run(args, job): cmd += tissue_3 cmd += tissue_4 + bilayer cmd += g_scale - # if args.fibrotic_tissue == 1: - # fib_reg = [103] - # sigma = 0.000001 - # fibrotic_tissue = ['-gregion[6].num_IDs ', 1, #tianbao - # '-gregion[6].ID ', 103, - # '-gregion[6].g_il ', sigma, - # '-gregion[6].g_it ', sigma, - # '-gregion[6].g_in ', sigma, - # '-gregion[6].g_el ', sigma, - # '-gregion[6].g_et ', sigma, - # '-gregion[6].g_en ', sigma] - # cmd += fibrotic_tissue writestatef = 'state' tsav_state = fit_LAT[l] From ccc2130379485272a3c905f17468969792d53f4a Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 13:30:20 +0100 Subject: [PATCH 19/70] Encapsulated vtk numpy support to avoid import errors --- .../Generate_Boundaries/extract_rings.py | 61 ++++++------ .../extract_rings_TOP_epi_endo.py | 77 ++++++++------- .../Generate_Boundaries/generate_surf_id.py | 16 +-- .../Generate_Boundaries/separate_epi_endo.py | 7 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 91 +++++++++-------- .../LDRBM/Fiber_LA/la_generate_fiber.py | 47 +++++---- Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py | 5 - Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py | 14 +-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 55 ++++++----- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 19 ++-- .../LDRBM/Fiber_RA/create_bridges_test.py | 39 +++----- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 21 ++-- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 97 +++++++++---------- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 14 +-- pipeline.py | 9 +- standalones/function.py | 20 ++-- standalones/getmarks.py | 15 +-- standalones/open_orifices_manually.py | 14 +-- standalones/open_orifices_with_curvature.py | 35 +++---- standalones/resample_surf_mesh.py | 3 +- .../Methods_fit_to_clinical_LAT.py | 58 +++++------ ...tune_conductivities_to_fit_clinical_LAT.py | 23 ++--- 22 files changed, 354 insertions(+), 386 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 723a5ee..ce1afc8 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -24,20 +24,19 @@ specific language governing permissions and limitations under the License. """ +import argparse import os +from glob import glob from logging import warning import numpy as np -from glob import glob import pandas as pd import vtk -from vtk.util import numpy_support -from vtk.numpy_interface import dataset_adapter as dsa -import datetime -from sklearn.cluster import KMeans -import argparse from scipy.spatial import cKDTree +from sklearn.cluster import KMeans +from vtk.numpy_interface import dataset_adapter as dsa +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -131,7 +130,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i connect.Update() mesh_conn = connect.GetOutput() mesh_conn.GetPointData().GetArray("RegionId").SetName("RegionID") - id_vec = numpy_support.vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) + id_vec = vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) # It can happen that the connectivity filter changes the ids loc = vtk.vtkPointLocator() @@ -394,7 +393,7 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): rings[pvs[i]].name = "RSPV" for r in rings: - id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) + id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) fname = outdir + f'/ids_{r.name}.vtx' if os.path.exists(fname): id_vec = id_vec[0:len(id_vec) - 1] @@ -490,7 +489,7 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): rings[list(set(other) - set([IVC, SVC]))[0]].name = "CS" for r in rings: - id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) + id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) fname = outdir + f'/ids_{r.name}.vtx' f = open(fname, 'w') @@ -543,7 +542,7 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): appendFilter = vtk.vtkAppendPolyData() for r in [rings[i] for i in RPVs]: - tag_data = vtk.util.numpy_support.numpy_to_vtk(np.ones((r.np,)) * r.id, deep=True, array_type=vtk.VTK_INT) + tag_data = numpy_to_vtk(np.ones((r.np,)) * r.id, deep=True, array_type=vtk.VTK_INT) tag_data.SetNumberOfComponents(1) tag_data.SetName("id") temp = vtk.vtkPolyData() @@ -557,7 +556,7 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - RSPV_id = int(vtk.util.numpy_support.vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) + RSPV_id = int(vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) return RSPV_id @@ -601,11 +600,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) - ids = vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) + tree = cKDTree(vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) + ids = vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) MV_ring = [r for r in rings if r.name == "MV"] - MV_ids = set(numpy_support.vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) + MV_ids = set(vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) MV_ant = set(ids).intersection(MV_ids) MV_post = MV_ids - MV_ant @@ -647,11 +646,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): path.SetEndVertex(lpv_mv) path.Update() - p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) + p = vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_lpv = set(ids[ii]) for r in rings: - mv_lpv = mv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) + mv_lpv = mv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) fname = outdir + '/ids_MV_LPV.vtx' f = open(fname, 'w') @@ -667,11 +666,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): path.SetEndVertex(rpv_mv) path.Update() - p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) + p = vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_rpv = set(ids[ii]) for r in rings: - mv_rpv = mv_rpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) + mv_rpv = mv_rpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) fname = outdir + '/ids_MV_RPV.vtx' f = open(fname, 'w') @@ -687,11 +686,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): path.SetEndVertex(rpv_bb) path.Update() - p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) + p = vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) rpv_lpv = set(ids[ii]) for r in rings: - rpv_lpv = rpv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) + rpv_lpv = rpv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) fname = outdir + '/ids_RPV_LPV.vtx' f = open(fname, 'w') @@ -802,7 +801,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): geo_filter.Update() tv_f = geo_filter.GetOutput() - tv_f_ids = vtk.util.numpy_support.vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) + tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' f = open(fname, 'w') f.write(f'{len(tv_f_ids)}\n') @@ -816,7 +815,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): geo_filter2.Update() tv_s = geo_filter2.GetOutput() - tv_s_ids = vtk.util.numpy_support.vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) + tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' f = open(fname, 'w') f.write(f'{len(tv_s_ids)}\n') @@ -826,10 +825,10 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): f.close() svc_points = svc.GetPoints().GetData() - svc_points = vtk.util.numpy_support.vtk_to_numpy(svc_points) + svc_points = vtk_to_numpy(svc_points) ivc_points = svc.GetPoints().GetData() # Changed - ivc_points = vtk.util.numpy_support.vtk_to_numpy(ivc_points) + ivc_points = vtk_to_numpy(ivc_points) connect = vtk.vtkConnectivityFilter() connect.SetInputData(gamma_top) @@ -851,7 +850,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): cln.Update() surface = cln.GetOutput() points = surface.GetPoints().GetData() - points = vtk.util.numpy_support.vtk_to_numpy(points) + points = vtk_to_numpy(points) points = points.tolist() if debug: @@ -891,9 +890,9 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): if debug: vtkWrite(top_cut, outdir + '/top_endo_epi.vtk') # If this is the CS, then change top_endo_id in 877 - pts_in_top = vtk.util.numpy_support.vtk_to_numpy(top_cut.GetPointData().GetArray("Ids")) - pts_in_svc = vtk.util.numpy_support.vtk_to_numpy(svc.GetPointData().GetArray("Ids")) - pts_in_ivc = vtk.util.numpy_support.vtk_to_numpy(ivc.GetPointData().GetArray("Ids")) + pts_in_top = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids")) + pts_in_svc = vtk_to_numpy(svc.GetPointData().GetArray("Ids")) + pts_in_ivc = vtk_to_numpy(ivc.GetPointData().GetArray("Ids")) to_delete = np.zeros((len(pts_in_top),), dtype=int) @@ -910,7 +909,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): geo_filter.SetInputConnection(thresh.GetOutputPort()) geo_filter.Update() - mv_id = vtk.util.numpy_support.vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] + mv_id = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] connect = vtk.vtkConnectivityFilter() connect.SetInputData(geo_filter.GetOutput()) @@ -929,7 +928,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): cln.Update() surface = cln.GetOutput() - pts_surf = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray("Ids")) + pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) if mv_id not in pts_surf: found_id = i @@ -948,7 +947,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): cln.SetInputData(surface) cln.Update() - top_endo = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) + top_endo = vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') f.write(f'{len(top_endo)}\n') diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index ae3c3b5..8cbd5e9 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -24,20 +24,19 @@ specific language governing permissions and limitations under the License. """ +import argparse import os +from glob import glob from logging import warning import numpy as np -from glob import glob import pandas as pd import vtk -from vtk.util import numpy_support -from vtk.numpy_interface import dataset_adapter as dsa -import datetime -from sklearn.cluster import KMeans -import argparse from scipy.spatial import cKDTree +from sklearn.cluster import KMeans +from vtk.numpy_interface import dataset_adapter as dsa +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -127,7 +126,7 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" connect.Update() mesh_conn = connect.GetOutput() mesh_conn.GetPointData().GetArray("RegionId").SetName("RegionID") - id_vec = numpy_support.vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) + id_vec = vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) # It can happen that the connectivity filter changes the ids loc = vtk.vtkPointLocator() @@ -381,7 +380,7 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): rings[pvs[i]].name = "RSPV" for r in rings: - id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) + id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) fname = outdir + f'/ids_{r.name}.vtx' if os.path.exists(fname): f = open(fname, 'a') @@ -459,7 +458,7 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): rings[list(set(other) - set([IVC, SVC]))[0]].name = "CS" for r in rings: - id_vec = numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) + id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) fname = outdir + f'/ids_{r.name}.vtx' f = open(fname, 'w') @@ -516,7 +515,7 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): appendFilter = vtk.vtkAppendPolyData() for r in [rings[i] for i in RPVs]: - tag_data = vtk.util.numpy_support.numpy_to_vtk(np.ones((r.np,)) * r.id, deep=True, array_type=vtk.VTK_INT) + tag_data = numpy_to_vtk(np.ones((r.np,)) * r.id, deep=True, array_type=vtk.VTK_INT) tag_data.SetNumberOfComponents(1) tag_data.SetName("id") temp = vtk.vtkPolyData() @@ -530,7 +529,7 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - RSPV_id = int(vtk.util.numpy_support.vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) + RSPV_id = int(vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) return RSPV_id @@ -574,11 +573,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) - ids = vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) + tree = cKDTree(vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) + ids = vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) MV_ring = [r for r in rings if r.name == "MV"] - MV_ids = set(numpy_support.vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) + MV_ids = set(vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) MV_ant = set(ids).intersection(MV_ids) MV_post = MV_ids - MV_ant @@ -620,11 +619,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): path.SetEndVertex(lpv_mv) path.Update() - p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) + p = vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_lpv = set(ids[ii]) for r in rings: - mv_lpv = mv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) + mv_lpv = mv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) fname = outdir + '/ids_MV_LPV.vtx' f = open(fname, 'w') @@ -640,11 +639,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): path.SetEndVertex(rpv_mv) path.Update() - p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) + p = vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) mv_rpv = set(ids[ii]) for r in rings: - mv_rpv = mv_rpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) + mv_rpv = mv_rpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) fname = outdir + '/ids_MV_RPV.vtx' f = open(fname, 'w') @@ -660,11 +659,11 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): path.SetEndVertex(rpv_bb) path.Update() - p = vtk.util.numpy_support.vtk_to_numpy(path.GetOutput().GetPoints().GetData()) + p = vtk_to_numpy(path.GetOutput().GetPoints().GetData()) dd, ii = tree.query(p) rpv_lpv = set(ids[ii]) for r in rings: - rpv_lpv = rpv_lpv - set(numpy_support.vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) + rpv_lpv = rpv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) fname = outdir + '/ids_RPV_LPV.vtx' f = open(fname, 'w') @@ -808,7 +807,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): geo_filter.Update() tv_f = geo_filter.GetOutput() - tv_f_ids = vtk.util.numpy_support.vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) + tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' f = open(fname, 'w') f.write(f'{len(tv_f_ids)}\n') @@ -822,7 +821,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): geo_filter2.Update() tv_s = geo_filter2.GetOutput() - tv_s_ids = vtk.util.numpy_support.vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) + tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' f = open(fname, 'w') f.write(f'{len(tv_s_ids)}\n') @@ -832,10 +831,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): f.close() svc_points = svc.GetPoints().GetData() - svc_points = vtk.util.numpy_support.vtk_to_numpy(svc_points) + svc_points = vtk_to_numpy(svc_points) ivc_points = ivc.GetPoints().GetData() - ivc_points = vtk.util.numpy_support.vtk_to_numpy(ivc_points) + ivc_points = vtk_to_numpy(ivc_points) connect = vtk.vtkConnectivityFilter() connect.SetInputData(gamma_top_epi) @@ -852,7 +851,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.Update() surface = cln.GetOutput() points = surface.GetPoints().GetData() - points = vtk.util.numpy_support.vtk_to_numpy(points) + points = vtk_to_numpy(points) points = points.tolist() in_ivc = False @@ -885,7 +884,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): top_cut_epi = cln.GetOutput() - pts_in_top_epi = vtk.util.numpy_support.vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) + pts_in_top_epi = vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) connect = vtk.vtkConnectivityFilter() connect.SetInputData(gamma_top_endo) @@ -902,7 +901,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.Update() surface = cln.GetOutput() points = surface.GetPoints().GetData() - points = vtk.util.numpy_support.vtk_to_numpy(points) + points = vtk_to_numpy(points) points = points.tolist() in_ivc = False @@ -935,20 +934,20 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): top_cut_endo = cln.GetOutput() - pts_in_top_endo = vtk.util.numpy_support.vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids")) - pts_in_svc_epi = vtk.util.numpy_support.vtk_to_numpy(svc.GetPointData().GetArray("Ids")) - pts_in_ivc_epi = vtk.util.numpy_support.vtk_to_numpy(ivc.GetPointData().GetArray("Ids")) - pts_in_tv_epi = vtk.util.numpy_support.vtk_to_numpy(tv.GetPointData().GetArray("Ids")) + pts_in_top_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids")) + pts_in_svc_epi = vtk_to_numpy(svc.GetPointData().GetArray("Ids")) + pts_in_ivc_epi = vtk_to_numpy(ivc.GetPointData().GetArray("Ids")) + pts_in_tv_epi = vtk_to_numpy(tv.GetPointData().GetArray("Ids")) tv_id_epi = np.intersect1d(pts_in_tv_epi, pts_in_top_epi) - endo_ids = vtk.util.numpy_support.vtk_to_numpy(endo.GetPointData().GetArray("Ids")) - tree = cKDTree(vtk.util.numpy_support.vtk_to_numpy(endo.GetPoints().GetData())) + endo_ids = vtk_to_numpy(endo.GetPointData().GetArray("Ids")) + tree = cKDTree(vtk_to_numpy(endo.GetPoints().GetData())) dd, ii = tree.query(svc_points) pts_in_svc_endo = endo_ids[ii] dd, ii = tree.query(ivc_points) pts_in_ivc_endo = endo_ids[ii] - dd, ii = tree.query(vtk.util.numpy_support.vtk_to_numpy(tv.GetPoints().GetData())) + dd, ii = tree.query(vtk_to_numpy(tv.GetPoints().GetData())) pts_in_tv_endo = endo_ids[ii] tv_id_endo = np.intersect1d(pts_in_tv_endo, pts_in_top_endo) @@ -986,7 +985,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.Update() surface = cln.GetOutput() - pts_surf = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray("Ids")) + pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) if tv_id_epi not in pts_surf: found_id = i @@ -1005,7 +1004,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.SetInputData(surface) cln.Update() - top_epi = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) + top_epi = vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_EPI.vtx' f = open(fname, 'w') f.write(f'{len(top_epi)}\n') @@ -1028,7 +1027,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): geo_filter.SetInputConnection(thresh.GetOutputPort()) geo_filter.Update() - mv_id_endo = vtk.util.numpy_support.vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] + mv_id_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] connect = vtk.vtkConnectivityFilter() connect.SetInputData(geo_filter.GetOutput()) @@ -1046,7 +1045,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.Update() surface = cln.GetOutput() - pts_surf = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray("Ids")) + pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) if tv_id_endo not in pts_surf: found_id = i @@ -1065,7 +1064,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): cln.SetInputData(surface) cln.Update() - top_endo = vtk.util.numpy_support.vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) + top_endo = vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') f.write(f'{len(top_endo)}\n') diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py index 609a266..cf1ad2a 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py @@ -24,13 +24,15 @@ specific language governing permissions and limitations under the License. """ -import vtk -from vtk.util.numpy_support import vtk_to_numpy +import os import shutil -import os, sys +import sys from glob import glob -from scipy.spatial import cKDTree + import numpy as np +from scipy.spatial import cKDTree + +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy sys.path.append('Atrial_LDRBM/Generate_Boundaries') from extract_rings import smart_reader @@ -55,10 +57,10 @@ def generate_surf_id(meshname, atrium): """The whole model""" vol = smart_reader(meshname + f"_{atrium}_vol.vtk") - whole_model_points_coordinate = vtk.util.numpy_support.vtk_to_numpy(vol.GetPoints().GetData()) + whole_model_points_coordinate = vtk_to_numpy(vol.GetPoints().GetData()) tree = cKDTree(whole_model_points_coordinate) - epi_pts = vtk.util.numpy_support.vtk_to_numpy( + epi_pts = vtk_to_numpy( smart_reader(meshname + f'_{atrium}_epi.obj').GetPoints().GetData()) dd, ii = tree.query(epi_pts) @@ -73,7 +75,7 @@ def generate_surf_id(meshname, atrium): write_surf_ids(outdir, "EPI", ii) - dd, ii = tree.query(vtk.util.numpy_support.vtk_to_numpy( + dd, ii = tree.query(vtk_to_numpy( smart_reader(meshname + f'_{atrium}_endo.obj').GetPoints().GetData())) ii = np.setdiff1d(ii, epi_ids) diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index 948b4d4..6ac2b0e 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -1,11 +1,8 @@ -import os -import numpy as np -import vtk -from vtk.util.numpy_support import vtk_to_numpy -import math import csv import sys +import vtk + from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between sys.path.append('Atrial_LDRBM/Generate_Boundaries') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 024cae4..8937a7f 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -31,10 +31,10 @@ from scipy.spatial import cKDTree from scipy.spatial.distance import cosine from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util import numpy_support from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -47,7 +47,7 @@ def mark_LA_endo_elemTag(model, tag, tao_mv, tao_lpv, tao_rpv, max_phie_ab_tau_lpv, max_phie_r2_tau_lpv): thresh = get_upper_threshold(model, tao_mv, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r") - MV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) + MV_ids = vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) thresh2 = get_upper_threshold(model, max_phie_r2_tau_lpv + 0.01, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_r2") @@ -55,15 +55,15 @@ def mark_LA_endo_elemTag(model, tag, tao_mv, tao_lpv, tao_rpv, max_phie_ab_tau_l thresh = get_lower_threshold(thresh2.GetOutputPort(), max_phie_ab_tau_lpv + 0.01, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_ab", source_is_input_connection=True) - LAA_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) + LAA_ids = vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) thresh = get_lower_threshold(model, tao_lpv, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") - LPV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) + LPV_ids = vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) thresh = get_upper_threshold(model, tao_rpv, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "phie_v") - RPV_ids = vtk.util.numpy_support.vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) + RPV_ids = vtk_to_numpy(thresh.GetOutput().GetCellData().GetArray('Global_ids')) meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") @@ -86,13 +86,13 @@ def move_surf_along_normals(mesh, eps, direction): normalGenerator.SplittingOff() normalGenerator.Update() - PointNormalArray = numpy_support.vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) - atrial_points = numpy_support.vtk_to_numpy(polydata.GetPoints().GetData()) + PointNormalArray = vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) + atrial_points = vtk_to_numpy(polydata.GetPoints().GetData()) atrial_points = atrial_points + eps * direction * PointNormalArray vtkPts = vtk.vtkPoints() - vtkPts.SetData(numpy_support.numpy_to_vtk(atrial_points)) + vtkPts.SetData(numpy_to_vtk(atrial_points)) polydata.SetPoints(vtkPts) mesh = vtk.vtkUnstructuredGrid() @@ -115,8 +115,8 @@ def generate_bilayer(endo, epi): epi = vtk.vtkUnstructuredGrid() epi.DeepCopy(reverse.GetOutput()) - endo_pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) - epi_pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) + endo_pts = vtk_to_numpy(endo.GetPoints().GetData()) + epi_pts = vtk_to_numpy(epi.GetPoints().GetData()) tree = cKDTree(endo_pts) dd, ii = tree.query(epi_pts) @@ -132,7 +132,7 @@ def generate_bilayer(endo, epi): points = np.concatenate((endo_pts, epi_pts[ii, :]), axis=0) polydata = vtk.vtkUnstructuredGrid() vtkPts = vtk.vtkPoints() - vtkPts.SetData(numpy_support.numpy_to_vtk(points)) + vtkPts.SetData(numpy_to_vtk(points)) polydata.SetPoints(vtkPts) polydata.SetCells(3, lines) @@ -168,10 +168,10 @@ def write_bilayer(bilayer, args, job): else: vtk_xml_unstructured_grid_writer(f"{file_name}.vtu", bilayer) - pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) - tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) + pts = vtk_to_numpy(bilayer.GetPoints().GetData()) + tag_epi = vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) + el_epi = vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) + sheet_epi = vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) write_to_pts(f'{file_name}.pts', pts) write_to_elem(f'{file_name}.elem', bilayer, tag_epi) @@ -244,7 +244,7 @@ def dijkstra_path(polydata, StartVertex, EndVertex): path.SetEndVertex(StartVertex) path.Update() points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) + points_data = vtk_to_numpy(points_data) return points_data @@ -321,7 +321,7 @@ def creat_tube(center1, center2, radius): def get_element_ids_around_path_within_radius(mesh, points_data, radius): - gl_ids = vtk.util.numpy_support.vtk_to_numpy(mesh.GetCellData().GetArray('Global_ids')) + gl_ids = vtk_to_numpy(mesh.GetCellData().GetArray('Global_ids')) locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -433,7 +433,7 @@ def assign_element_fiber_around_path_within_radius(mesh, points_data, radius, fi def get_mean_point(data): ring_points = data.GetPoints().GetData() - ring_points = vtk.util.numpy_support.vtk_to_numpy(ring_points) + ring_points = vtk_to_numpy(ring_points) center_point = [np.mean(ring_points[:, 0]), np.mean(ring_points[:, 1]), np.mean(ring_points[:, 2])] center_point = np.array(center_point) return center_point @@ -460,19 +460,19 @@ def multidim_intersect_bool(arr1, arr2): def get_ct_end_points_id(endo, ct, scv, icv): # endo points_data = endo.GetPoints().GetData() - endo_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + endo_points = vtk_to_numpy(points_data) # ct points_data = ct.GetPoints().GetData() - ct_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + ct_points = vtk_to_numpy(points_data) # scv points_data = scv.GetPoints().GetData() - scv_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + scv_points = vtk_to_numpy(points_data) # icv points_data = icv.GetPoints().GetData() - icv_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + icv_points = vtk_to_numpy(points_data) # intersection # inter_ct_endo = multidim_intersect(endo_points, ct_points) @@ -535,7 +535,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, cln.SetInputData(surface) cln.Update() points_data = cln.GetOutput().GetPoints().GetData() - ring = vtk.util.numpy_support.vtk_to_numpy(points_data) + ring = vtk_to_numpy(points_data) center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) connect.DeleteSpecifiedRegion(1) @@ -552,7 +552,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, cln.SetInputData(surface) cln.Update() points_data = cln.GetOutput().GetPoints().GetData() - ring = vtk.util.numpy_support.vtk_to_numpy(points_data) + ring = vtk_to_numpy(points_data) center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) dis_1 = np.linalg.norm(center_point_1 - tv_ivc_center) dis_2 = np.linalg.norm(center_point_1 - tv_svc_center) @@ -627,10 +627,10 @@ def assign_ra_appendage(model, SCV, appex_point, tag): def get_endo_ct_intersection_cells(endo, ct): points_data = ct.GetPoints().GetData() - ct_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + ct_points = vtk_to_numpy(points_data) points_data = endo.GetPoints().GetData() - endo_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + endo_points = vtk_to_numpy(points_data) intersection = multidim_intersect(ct_points, endo_points) @@ -722,8 +722,8 @@ def get_connection_point_la_and_ra(appen_point): def point_array_mapper(mesh1, mesh2, mesh2_name, idat): - pts1 = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPoints().GetData()) - pts2 = vtk.util.numpy_support.vtk_to_numpy(mesh2.GetPoints().GetData()) + pts1 = vtk_to_numpy(mesh1.GetPoints().GetData()) + pts2 = vtk_to_numpy(mesh2.GetPoints().GetData()) tree = cKDTree(pts1) @@ -732,7 +732,7 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy( + data = vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) @@ -747,7 +747,7 @@ def point_array_mapper(mesh1, mesh2, mesh2_name, idat): # assert algs.make_point_mask_from_NaNs(meshNew, data2)[1] == vtk.vtkDataSetAttributes.DUPLICATEPOINT | vtk.vtkDataSetAttributes.HIDDENPOINT meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) + data = vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: @@ -765,13 +765,13 @@ def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): filter_cell_centers.SetInputData(mesh1) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() - centroids1_array = vtk.util.numpy_support.vtk_to_numpy(centroids1.GetData()) + centroids1_array = vtk_to_numpy(centroids1.GetData()) filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(mesh2) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() - pts2 = vtk.util.numpy_support.vtk_to_numpy(centroids2.GetData()) + pts2 = vtk_to_numpy(centroids2.GetData()) tree = cKDTree(centroids1_array) @@ -780,7 +780,7 @@ def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetCellData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy( + data = vtk_to_numpy( mesh1.GetCellData().GetArray(mesh1.GetCellData().GetArrayName(i))) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) @@ -790,7 +790,7 @@ def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): data2 = data[ii] meshNew.PointData.append(data2, mesh1.GetCellData().GetArrayName(i)) else: - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetCellData().GetArray(idat)) + data = vtk_to_numpy(mesh1.GetCellData().GetArray(idat)) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: @@ -843,7 +843,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e LAA = thresh.GetOutput() - min_r2_cell_LAA = np.argmin(vtk.util.numpy_support.vtk_to_numpy(LAA.GetCellData().GetArray('phie_r2'))) + min_r2_cell_LAA = np.argmin(vtk_to_numpy(LAA.GetCellData().GetArray('phie_r2'))) ptIds = vtk.vtkIdList() @@ -851,7 +851,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e # sup_appendage_basis_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) sup_appendage_basis = LAA.GetPoint(ptIds.GetId(0)) - max_r2_cell_LAA = np.argmax(vtk.util.numpy_support.vtk_to_numpy(LAA.GetCellData().GetArray('phie_r2'))) + max_r2_cell_LAA = np.argmax(vtk_to_numpy(LAA.GetCellData().GetArray('phie_r2'))) ptIds = vtk.vtkIdList() @@ -859,7 +859,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e # bb_mv_id = int(LAA.GetPointData().GetArray('Global_ids').GetTuple(ptIds.GetId(0))[0]) bb_mv_laa = LAA.GetPoint(ptIds.GetId(0)) - max_v_cell_LAA = np.argmax(vtk.util.numpy_support.vtk_to_numpy(LAA.GetCellData().GetArray('phie_v'))) + max_v_cell_LAA = np.argmax(vtk_to_numpy(LAA.GetCellData().GetArray('phie_v'))) ptIds = vtk.vtkIdList() @@ -883,7 +883,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e boundaryEdges.Update() LAA_border = boundaryEdges.GetOutput() - LAA_pts_border = vtk.util.numpy_support.vtk_to_numpy(LAA_border.GetPoints().GetData()) + LAA_pts_border = vtk_to_numpy(LAA_border.GetPoints().GetData()) max_dist = 0 for i in range(len(LAA_pts_border)): if np.sqrt(np.sum((LAA_pts_border[i] - df["LIPV"].to_numpy()) ** 2, axis=0)) > max_dist: @@ -917,7 +917,6 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e bb_left = get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) - return bb_left, thresh.GetOutput().GetPoint(inf_appendage_basis_id), thresh.GetOutput().GetPoint( sup_appendage_basis_id), thresh.GetOutput().GetPoint(LAA_pt_far_from_LIPV_id) @@ -960,7 +959,7 @@ def creat_center_line(start_end_point): functionSource.Update() tubePolyData = functionSource.GetOutput() points = tubePolyData.GetPoints().GetData() - points = vtk.util.numpy_support.vtk_to_numpy(points) + points = vtk_to_numpy(points) return points @@ -1035,9 +1034,9 @@ def distinguish_PVs(connect, PVs, df, name1, name2): surface = cln.GetOutput() if name1.startswith("L"): - phie_v = np.max(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) + phie_v = np.max(vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) elif name1.startswith("R"): - phie_v = np.min(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) + phie_v = np.min(vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) if name1.startswith("L") and phie_v > 0.04: # 0.025 found, val = optimize_shape_PV(surface, 10, 0) @@ -1067,9 +1066,9 @@ def distinguish_PVs(connect, PVs, df, name1, name2): centroid2_d = np.sqrt(np.sum((np.array(centroid2) - np.array(c_mass)) ** 2, axis=0)) if centroid1_d < centroid2_d: - PVs[name1] = vtk.util.numpy_support.vtk_to_numpy(single_PV.GetCellData().GetArray('Global_ids')) + PVs[name1] = vtk_to_numpy(single_PV.GetCellData().GetArray('Global_ids')) else: - PVs[name2] = vtk.util.numpy_support.vtk_to_numpy(single_PV.GetCellData().GetArray('Global_ids')) + PVs[name2] = vtk_to_numpy(single_PV.GetCellData().GetArray('Global_ids')) connect.DeleteSpecifiedRegion(i) connect.Update() @@ -1079,9 +1078,9 @@ def distinguish_PVs(connect, PVs, df, name1, name2): def optimize_shape_PV(surface, num, bound): if bound == 0: - phie_v = np.max(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) + phie_v = np.max(vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) else: - phie_v = np.min(vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) + phie_v = np.min(vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) arr = np.linspace(bound, phie_v, num) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index e74f7ca..71d2fb0 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -27,7 +27,6 @@ import numpy as np import vtk from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util import numpy_support import Methods_LA as Method import csv import datetime @@ -37,6 +36,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer @@ -92,32 +92,32 @@ def la_generate_fiber(model, args, job): # ab ab = model.GetCellData().GetArray('phie_ab') ab_grad = model.GetCellData().GetArray('grad_ab') - ab = vtk.util.numpy_support.vtk_to_numpy(ab) - ab_grad = vtk.util.numpy_support.vtk_to_numpy(ab_grad) + ab = vtk_to_numpy(ab) + ab_grad = vtk_to_numpy(ab_grad) # v v = model.GetCellData().GetArray('phie_v') v_grad = model.GetCellData().GetArray('grad_v') - v = vtk.util.numpy_support.vtk_to_numpy(v) - v_grad = vtk.util.numpy_support.vtk_to_numpy(v_grad) + v = vtk_to_numpy(v) + v_grad = vtk_to_numpy(v_grad) # r r = model.GetCellData().GetArray('phie_r') r_grad = model.GetCellData().GetArray('grad_r') - r = vtk.util.numpy_support.vtk_to_numpy(r) - r_grad = vtk.util.numpy_support.vtk_to_numpy(r_grad) + r = vtk_to_numpy(r) + r_grad = vtk_to_numpy(r_grad) # r2 r2 = model.GetCellData().GetArray('phie_r2') - r2 = vtk.util.numpy_support.vtk_to_numpy(r2) + r2 = vtk_to_numpy(r2) # phie if args.mesh_type == "vol": phie = model.GetCellData().GetArray('phie_phi') - phie = vtk.util.numpy_support.vtk_to_numpy(phie) + phie = vtk_to_numpy(phie) phie_grad = model.GetCellData().GetArray('grad_phi') - phie_grad = vtk.util.numpy_support.vtk_to_numpy(phie_grad) + phie_grad = vtk_to_numpy(phie_grad) cellid = vtk.vtkIdFilter() cellid.CellIdsOn() @@ -154,10 +154,10 @@ def la_generate_fiber(model, args, job): thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) - phie_r2_tau_lpv = vtk.util.numpy_support.vtk_to_numpy(thr.GetCellData().GetArray('phie_r2')) + phie_r2_tau_lpv = vtk_to_numpy(thr.GetCellData().GetArray('phie_r2')) max_phie_r2_tau_lpv = np.max(phie_r2_tau_lpv) - phie_ab_tau_lpv = vtk.util.numpy_support.vtk_to_numpy(thr.GetPointData().GetArray('phie_ab2')) + phie_ab_tau_lpv = vtk_to_numpy(thr.GetPointData().GetArray('phie_ab2')) max_phie_ab_tau_lpv = np.max(phie_ab_tau_lpv) print("max_phie_r2_tau_lpv ", max_phie_r2_tau_lpv) @@ -197,7 +197,7 @@ def la_generate_fiber(model, args, job): epi = vtk_thr(model, 0, "CELLS", "phie_phi", 0.5) - epi_ids = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('Global_ids')) + epi_ids = vtk_to_numpy(epi.GetCellData().GetArray('Global_ids')) endo_ids = np.arange(len(r)).astype(int) @@ -213,7 +213,7 @@ def la_generate_fiber(model, args, job): LAA_bb = vtk_thr(model, 2, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03, max_phie_ab_tau_lpv + 0.01) - LAA_bb_ids = vtk.util.numpy_support.vtk_to_numpy(LAA_bb.GetPointData().GetArray('Global_ids')) + LAA_bb_ids = vtk_to_numpy(LAA_bb.GetPointData().GetArray('Global_ids')) MV_ring_ids = np.loadtxt(f'{args.mesh}_surf/ids_MV.vtx', skiprows=2, dtype=int) @@ -233,11 +233,11 @@ def la_generate_fiber(model, args, job): ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_MV.vtx', skiprows=2, dtype=int) - rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] + rings_pts = vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] MV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) - LAA_ids = vtk.util.numpy_support.vtk_to_numpy(LAA_s.GetCellData().GetArray('Global_ids')) + LAA_ids = vtk_to_numpy(LAA_s.GetCellData().GetArray('Global_ids')) # tagging endo-layer if args.mesh_type == 'bilayer': @@ -334,7 +334,7 @@ def la_generate_fiber(model, args, job): meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - band_cell_ids = vtk.util.numpy_support.vtk_to_numpy( + band_cell_ids = vtk_to_numpy( meshExtractFilter.GetOutput().GetCellData().GetArray('Global_ids')) if args.mesh_type == "bilayer": @@ -410,7 +410,7 @@ def la_generate_fiber(model, args, job): store_binary=True) else: vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_endo_with_fiber.vtu", meshNew.VTKObject) - pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) + pts = vtk_to_numpy(endo.GetPoints().GetData()) write_to_pts(job.ID + '/result_LA/LA_endo_with_fiber.pts', pts) write_to_elem(job.ID + '/result_LA/LA_endo_with_fiber.elem', endo, tag_endo) @@ -478,7 +478,7 @@ def la_generate_fiber(model, args, job): geo_filter.Update() surf = geo_filter.GetOutput() epi_surf = vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) - epi_surf_ids = vtk.util.numpy_support.vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) + epi_surf_ids = vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(epi_surf) @@ -497,12 +497,12 @@ def la_generate_fiber(model, args, job): left_atrial_appendage_epi, mitral_valve_epi) tag[epi_surf_ids] = Method.assign_element_tag_around_path_within_radius(epi_surf, bb_left, w_bb, - vtk.util.numpy_support.vtk_to_numpy( + vtk_to_numpy( epi_surf.GetCellData().GetArray( 'elemTag')), bachmann_bundel_left) el[epi_surf_ids] = Method.assign_element_fiber_around_path_within_radius(epi_surf, bb_left, w_bb, - vtk.util.numpy_support.vtk_to_numpy( + vtk_to_numpy( epi_surf.GetCellData().GetArray( 'fiber')), smooth=True) @@ -536,7 +536,7 @@ def la_generate_fiber(model, args, job): store_binary=True) else: vtk_xml_unstructured_grid_writer(job.ID + "/result_LA/LA_epi_with_fiber.vtu", meshNew.VTKObject) - pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) + pts = vtk_to_numpy(epi.GetPoints().GetData()) write_to_pts(job.ID + '/result_LA/LA_epi_with_fiber.pts', pts) @@ -580,13 +580,12 @@ def la_generate_fiber(model, args, job): store_binary=True) else: vtk_xml_unstructured_grid_writer(filename + ".vtu", meshNew.VTKObject) - pts = numpy_support.vtk_to_numpy(model.GetPoints().GetData()) + pts = vtk_to_numpy(model.GetPoints().GetData()) write_to_pts(filename + '.pts', pts) write_to_elem(filename + '.elem', model, tag) write_to_lon(filename + '.lon', el, sheet) - end_time = datetime.datetime.now() running_time = end_time - start_time print('Writing as LA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py index 9136368..cb08dce 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py @@ -25,7 +25,6 @@ under the License. """ import os -import sys from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_polydata_writer @@ -34,10 +33,6 @@ from carputils.carpio import igb from carputils import tools from la_calculate_gradient import la_calculate_gradient -import vtk -from vtk.util.numpy_support import vtk_to_numpy -from vtk.util.numpy_support import numpy_to_vtk -import numpy as np from vtk.numpy_interface import dataset_adapter as dsa diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py index 6a2e79a..b29bf39 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py @@ -24,21 +24,17 @@ specific language governing permissions and limitations under the License. """ -import os -import subprocess as sp import datetime import warnings -import vtk import numpy as np -from vtk.util import numpy_support -from carputils import settings +import vtk from carputils import tools -from carputils import mesh -from la_laplace import la_laplace + from la_generate_fiber import la_generate_fiber -import Methods_LA +from la_laplace import la_laplace from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy def parser(): @@ -105,7 +101,7 @@ def run(args, job): LA = reverse.GetOutput() - pts = numpy_support.vtk_to_numpy(LA.GetPoints().GetData()) + pts = vtk_to_numpy(LA.GetPoints().GetData()) write_to_pts(LA_mesh + '.pts', pts) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 417a7e4..3b729df 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -24,15 +24,14 @@ specific language governing permissions and limitations under the License. """ -import vtk import numpy as np -from vtk.util import numpy_support -from vtk.numpy_interface import dataset_adapter as dsa +import vtk from scipy.spatial import cKDTree +from vtk.numpy_interface import dataset_adapter as dsa import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from vtk_opencarp_helper_methods.openCARP.exporting import write_to_elem, write_to_pts, write_to_lon -from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -55,7 +54,7 @@ def downsample_path(points_data, step): functionSource.SetParametricFunction(spline) functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) functionSource.Update() - points_data = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + points_data = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) return points_data @@ -73,13 +72,13 @@ def move_surf_along_normals(mesh, eps, direction): normalGenerator.SplittingOff() normalGenerator.Update() - PointNormalArray = numpy_support.vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) - atrial_points = numpy_support.vtk_to_numpy(polydata.GetPoints().GetData()) + PointNormalArray = vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) + atrial_points = vtk_to_numpy(polydata.GetPoints().GetData()) atrial_points = atrial_points + eps * direction * PointNormalArray vtkPts = vtk.vtkPoints() - vtkPts.SetData(numpy_support.numpy_to_vtk(atrial_points)) + vtkPts.SetData(numpy_to_vtk(atrial_points)) polydata.SetPoints(vtkPts) mesh = vtk.vtkUnstructuredGrid() @@ -103,8 +102,8 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): endo.DeepCopy(reverse.GetOutput()) # endo.DeepCopy(extract_surf.GetOutputPort()) - endo_pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) - epi_pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) + endo_pts = vtk_to_numpy(endo.GetPoints().GetData()) + epi_pts = vtk_to_numpy(epi.GetPoints().GetData()) tree = cKDTree(epi_pts) dd, ii = tree.query(endo_pts, distance_upper_bound=max_dist) # , n_jobs=-1) @@ -122,7 +121,7 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): points = np.vstack((endo_pts[endo_ids], epi_pts[epi_ids])) polydata = vtk.vtkUnstructuredGrid() vtkPts = vtk.vtkPoints() - vtkPts.SetData(numpy_support.numpy_to_vtk(points)) + vtkPts.SetData(numpy_to_vtk(points)) polydata.SetPoints(vtkPts) polydata.SetCells(3, lines) @@ -193,7 +192,7 @@ def write_bilayer(bilayer, args, job): def generate_sheet_dir(args, model, job): fiber = model.GetCellData().GetArray('fiber') - fiber = vtk.util.numpy_support.vtk_to_numpy(fiber) + fiber = vtk_to_numpy(fiber) fiber = np.where(fiber == [0, 0, 0], [1, 0, 0], fiber).astype("float32") @@ -221,7 +220,7 @@ def generate_sheet_dir(args, model, job): normals.ComputePointNormalsOff() normals.Update() normal_vectors = normals.GetOutput().GetCellData().GetArray('Normals') - normal_vectors = vtk.util.numpy_support.vtk_to_numpy(normal_vectors) + normal_vectors = vtk_to_numpy(normal_vectors) # print('Normal vectors: \n', normal_vectors, '\n') print('Number of normals: ', len(normal_vectors)) @@ -236,7 +235,7 @@ def generate_sheet_dir(args, model, job): filter_cell_centers.SetInputData(cln_surface) filter_cell_centers.Update() center_surface = filter_cell_centers.GetOutput().GetPoints() - center_surface_array = vtk.util.numpy_support.vtk_to_numpy(center_surface.GetData()) + center_surface_array = vtk_to_numpy(center_surface.GetData()) print('Number of center_surface: ', len(center_surface_array), '\n') ''' @@ -246,7 +245,7 @@ def generate_sheet_dir(args, model, job): filter_cell_centers.SetInputData(model) filter_cell_centers.Update() center_volume = filter_cell_centers.GetOutput().GetPoints().GetData() - center_volume = vtk.util.numpy_support.vtk_to_numpy(center_volume) + center_volume = vtk_to_numpy(center_volume) print('Number of center_volume: ', len(center_volume), '\n') ''' @@ -361,7 +360,7 @@ def dijkstra_path(polydata, StartVertex, EndVertex): path.SetEndVertex(StartVertex) path.Update() points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) + points_data = vtk_to_numpy(points_data) return points_data @@ -379,7 +378,7 @@ def dijkstra_path_coord(polydata, StartVertex, EndVertex): path.SetEndVertex(StartVertex) path.Update() points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) + points_data = vtk_to_numpy(points_data) return points_data @@ -488,7 +487,7 @@ def find_elements_around_path_within_radius(mesh, points_data, radius): def get_element_ids_around_path_within_radius(mesh, points_data, radius): - gl_ids = vtk.util.numpy_support.vtk_to_numpy(mesh.GetCellData().GetArray('Global_ids')) + gl_ids = vtk_to_numpy(mesh.GetCellData().GetArray('Global_ids')) locator = vtk.vtkStaticPointLocator() locator.SetDataSet(mesh) @@ -600,7 +599,7 @@ def assign_element_fiber_around_path_within_radius(mesh, points_data, radius, fi def get_mean_point(data): ring_points = data.GetPoints().GetData() - ring_points = vtk.util.numpy_support.vtk_to_numpy(ring_points) + ring_points = vtk_to_numpy(ring_points) center_point = [np.mean(ring_points[:, 0]), np.mean(ring_points[:, 1]), np.mean(ring_points[:, 2])] center_point = np.array(center_point) return center_point @@ -627,19 +626,19 @@ def multidim_intersect_bool(arr1, arr2): def get_ct_end_points_id(endo, ct, scv, icv): # endo points_data = endo.GetPoints().GetData() - endo_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + endo_points = vtk_to_numpy(points_data) # ct points_data = ct.GetPoints().GetData() - ct_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + ct_points = vtk_to_numpy(points_data) # scv points_data = scv.GetPoints().GetData() - scv_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + scv_points = vtk_to_numpy(points_data) # icv points_data = icv.GetPoints().GetData() - icv_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + icv_points = vtk_to_numpy(points_data) # intersection # inter_ct_endo = multidim_intersect(endo_points, ct_points) @@ -702,7 +701,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, cln.SetInputData(surface) cln.Update() points_data = cln.GetOutput().GetPoints().GetData() - ring = vtk.util.numpy_support.vtk_to_numpy(points_data) + ring = vtk_to_numpy(points_data) center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) connect.DeleteSpecifiedRegion(1) @@ -719,7 +718,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, cln.SetInputData(surface) cln.Update() points_data = cln.GetOutput().GetPoints().GetData() - ring = vtk.util.numpy_support.vtk_to_numpy(points_data) + ring = vtk_to_numpy(points_data) center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) dis_1 = np.linalg.norm(center_point_1 - tv_ivc_center) dis_2 = np.linalg.norm(center_point_1 - tv_svc_center) @@ -794,10 +793,10 @@ def assign_ra_appendage(model, SCV, appex_point, tag, elemTag): def get_endo_ct_intersection_cells(endo, ct): points_data = ct.GetPoints().GetData() - ct_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + ct_points = vtk_to_numpy(points_data) points_data = endo.GetPoints().GetData() - endo_points = vtk.util.numpy_support.vtk_to_numpy(points_data) + endo_points = vtk_to_numpy(points_data) intersection = multidim_intersect(ct_points, endo_points) @@ -1013,7 +1012,7 @@ def creat_center_line(start_end_point): functionSource.Update() tubePolyData = functionSource.GetOutput() points = tubePolyData.GetPoints().GetData() - points = vtk.util.numpy_support.vtk_to_numpy(points) + points = vtk_to_numpy(points) return points diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 6d5b51d..b88fae2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -38,6 +38,7 @@ import Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer @@ -143,8 +144,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.Update() tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) - tag[:la_epi.GetNumberOfCells()] = vtk.util.numpy_support.vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) - tag[la_epi.GetNumberOfCells():] = vtk.util.numpy_support.vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) + tag[:la_epi.GetNumberOfCells()] = vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) + tag[la_epi.GetNumberOfCells():] = vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) meshNew = dsa.WrapDataObject(append_filter.GetOutput()) meshNew.CellData.append(tag, "elemTag") @@ -223,7 +224,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): locator.BuildLocator() intersection_points = bridge_usg.GetPoints().GetData() - intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) + intersection_points = vtk_to_numpy(intersection_points) earth_point_ids_temp = vtk.vtkIdList() earth_point_ids = vtk.vtkIdList() @@ -307,7 +308,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): locator.BuildLocator() intersection_points = bridge_usg.GetPoints().GetData() - intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) + intersection_points = vtk_to_numpy(intersection_points) earth_point_ids_temp = vtk.vtkIdList() earth_point_ids = vtk.vtkIdList() @@ -380,7 +381,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): functionSource.SetParametricFunction(spline) functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) functionSource.Update() - bb_fiber_points_data = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + bb_fiber_points_data = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) print("Union between earth and bridges") for var in bridge_list: @@ -559,12 +560,12 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): else: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_vol_with_fiber.vtu", epi) - pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) + pts = vtk_to_numpy(epi.GetPoints().GetData()) write_to_pts(job.ID + '/result_RA/LA_RA_vol_with_fiber.pts', pts) - tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) + tag_epi = vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) write_to_elem(job.ID + '/result_RA/LA_RA_vol_with_fiber.elem', epi, tag_epi) - el_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('sheet')) + el_epi = vtk_to_numpy(epi.GetCellData().GetArray('fiber')) + sheet_epi = vtk_to_numpy(epi.GetCellData().GetArray('sheet')) write_to_lon(job.ID + '/result_RA/LA_RA_vol_with_fiber.lon', el_epi, sheet_epi) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 0977ab2..eafb032 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -24,28 +24,21 @@ specific language governing permissions and limitations under the License. """ -import numpy as np -import vtk -from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util.numpy_support import vtk_to_numpy -import datetime -import Methods_RA as Method import csv import os +import pickle import subprocess + +import numpy as np +import pandas as pd import pymesh import pymeshlab -import pickle -from numpy.linalg import norm - -from vtk.util import numpy_support -import subprocess as sp +import vtk from carputils import tools -from ra_laplace import ra_laplace -from ra_generate_fiber import ra_generate_fiber -import Methods_RA as Method -import pandas as pd +from vtk.numpy_interface import dataset_adapter as dsa +from vtk.util.numpy_support import vtk_to_numpy +import Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ @@ -198,8 +191,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): append_filter.Update() tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) - tag[:la_epi.GetNumberOfCells()] = vtk.util.numpy_support.vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) - tag[la_epi.GetNumberOfCells():] = vtk.util.numpy_support.vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) + tag[:la_epi.GetNumberOfCells()] = vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) + tag[la_epi.GetNumberOfCells():] = vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) meshNew = dsa.WrapDataObject(append_filter.GetOutput()) meshNew.CellData.append(tag, "elemTag") @@ -278,7 +271,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): locator.BuildLocator() intersection_points = bridge_usg.GetPoints().GetData() - intersection_points = vtk.util.numpy_support.vtk_to_numpy(intersection_points) + intersection_points = vtk_to_numpy(intersection_points) earth_point_ids_temp = vtk.vtkIdList() earth_point_ids = vtk.vtkIdList() @@ -354,7 +347,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): functionSource.SetParametricFunction(spline) functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) functionSource.Update() - bb_fiber_points_data = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + bb_fiber_points_data = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) print("Union between earth and bridges") for var in bridge_list: @@ -472,12 +465,12 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): file_name = job.ID + "/result_RA/LA_RA_vol_with_fiber" vtk_xml_unstructured_grid_writer(f"{file_name}.vtu", epi) - pts = vtk.util.numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) + pts = vtk_to_numpy(epi.GetPoints().GetData()) - tag_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) + tag_epi = vtk_to_numpy(epi.GetCellData().GetArray('elemTag')) - el_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.numpy_support.vtk_to_numpy(epi.GetCellData().GetArray('sheet')) + el_epi = vtk_to_numpy(epi.GetCellData().GetArray('fiber')) + sheet_epi = vtk_to_numpy(epi.GetCellData().GetArray('sheet')) write_to_pts(f'{file_name}.pts', pts) write_to_elem(f'{file_name}.elem', epi, tag_epi) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index c195556..ad821d7 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -15,6 +15,7 @@ import argparse from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer parser = argparse.ArgumentParser(description='Create Right Atrium.') @@ -68,13 +69,13 @@ def move_surf_along_normals(mesh, eps, direction): normalGenerator.SplittingOff() normalGenerator.Update() - PointNormalArray = numpy_support.vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) - atrial_points = numpy_support.vtk_to_numpy(polydata.GetPoints().GetData()) + PointNormalArray = vtk_to_numpy(normalGenerator.GetOutput().GetPointData().GetNormals()) + atrial_points = vtk_to_numpy(polydata.GetPoints().GetData()) atrial_points = atrial_points + eps * direction * PointNormalArray vtkPts = vtk.vtkPoints() - vtkPts.SetData(numpy_support.numpy_to_vtk(atrial_points)) + vtkPts.SetData(numpy_to_vtk(atrial_points)) polydata.SetPoints(vtkPts) mesh = vtk.vtkUnstructuredGrid() @@ -97,8 +98,8 @@ def generate_bilayer(endo, epi, max_dist=np.inf): endo = vtk.vtkUnstructuredGrid() endo.DeepCopy(reverse.GetOutput()) - endo_pts = numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) - epi_pts = numpy_support.vtk_to_numpy(epi.GetPoints().GetData()) + endo_pts = vtk_to_numpy(endo.GetPoints().GetData()) + epi_pts = vtk_to_numpy(epi.GetPoints().GetData()) tree = cKDTree(epi_pts) dd, ii = tree.query(endo_pts, distance_upper_bound=max_dist, n_jobs=-1) @@ -116,7 +117,7 @@ def generate_bilayer(endo, epi, max_dist=np.inf): points = np.vstack((endo_pts[endo_ids], epi_pts[epi_ids])) polydata = vtk.vtkUnstructuredGrid() vtkPts = vtk.vtkPoints() - vtkPts.SetData(numpy_support.numpy_to_vtk(points)) + vtkPts.SetData(numpy_to_vtk(points)) polydata.SetPoints(vtkPts) polydata.SetCells(3, lines) @@ -150,12 +151,12 @@ def write_bilayer(bilayer): file_name=args.mesh + "/RA_bilayer_with_fiber" vtk_unstructured_grid_writer(f"{file_name}.vtk", bilayer, store_binary=True) - pts = numpy_support.vtk_to_numpy(bilayer.GetPoints().GetData()) + pts = vtk_to_numpy(bilayer.GetPoints().GetData()) - tag_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) + tag_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) - el_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.numpy_support.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) + el_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) + sheet_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) write_to_pts(f'{file_name}.pts', pts) write_to_elem(f'{file_name}.elem', bilayer, tag_epi) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 943c947..57b7eb2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -24,19 +24,19 @@ specific language governing permissions and limitations under the License. """ +import csv +import datetime +import os +import pickle + import numpy as np -import vtk import pandas as pd +import vtk +from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util.numpy_support import vtk_to_numpy -import datetime import Methods_RA as Method -import csv -import pickle -import os -from scipy.spatial import cKDTree - from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer @@ -128,33 +128,33 @@ def ra_generate_fiber(model, args, job): # ab ab = model.GetCellData().GetArray('phie_ab') ab_grad = model.GetCellData().GetArray('grad_ab') - ab = vtk.util.numpy_support.vtk_to_numpy(ab) - ab_grad = vtk.util.numpy_support.vtk_to_numpy(ab_grad) + ab = vtk_to_numpy(ab) + ab_grad = vtk_to_numpy(ab_grad) # v v = model.GetCellData().GetArray('phie_v') v_grad = model.GetCellData().GetArray('grad_v') - v = vtk.util.numpy_support.vtk_to_numpy(v) - v_grad = vtk.util.numpy_support.vtk_to_numpy(v_grad) + v = vtk_to_numpy(v) + v_grad = vtk_to_numpy(v_grad) # r r = model.GetCellData().GetArray('phie_r') r_grad = model.GetCellData().GetArray('grad_r') - r = vtk.util.numpy_support.vtk_to_numpy(r) - r_grad = vtk.util.numpy_support.vtk_to_numpy(r_grad) + r = vtk_to_numpy(r) + r_grad = vtk_to_numpy(r_grad) # w w = model.GetCellData().GetArray('phie_w') w_grad = model.GetCellData().GetArray('grad_w') - w = vtk.util.numpy_support.vtk_to_numpy(w) - w_grad = vtk.util.numpy_support.vtk_to_numpy(w_grad) + w = vtk_to_numpy(w) + w_grad = vtk_to_numpy(w_grad) # phie if args.mesh_type == "vol": phie = model.GetCellData().GetArray('phie_phi') - phie = vtk.util.numpy_support.vtk_to_numpy(phie) + phie = vtk_to_numpy(phie) phie_grad = model.GetCellData().GetArray('grad_phi') - phie_grad = vtk.util.numpy_support.vtk_to_numpy(phie_grad) + phie_grad = vtk_to_numpy(phie_grad) start_time = datetime.datetime.now() print('Calculating fibers... ' + str(start_time)) @@ -183,7 +183,7 @@ def ra_generate_fiber(model, args, job): ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_TV.vtx', skiprows=2, dtype=int) - rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] + rings_pts = vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] if args.debug: Method.create_pts(rings_pts, 'TV_ring', f'{args.mesh}_surf/') @@ -202,7 +202,7 @@ def ra_generate_fiber(model, args, job): TV_s = extract.GetOutput() ra_diff = list( - set(list(vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('Global_ids')))).difference( + set(list(vtk_to_numpy(model.GetCellData().GetArray('Global_ids')))).difference( set(TV_ids))) ra_no_TV = vtk.vtkIdList() for var in ra_diff: @@ -231,7 +231,7 @@ def ra_generate_fiber(model, args, job): IVC_s = Method.extract_largest_region(IVC_s) # Added - max_phie_r_ivc = np.max(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_r'))) + 0.2 + max_phie_r_ivc = np.max(vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_r'))) + 0.2 RAW_s = vtk_thr(no_TV_s, 1, "CELLS", "phie_r", max_phie_r_ivc) # Added +0.03 fro dk01 @@ -247,18 +247,18 @@ def ra_generate_fiber(model, args, job): Method.writer_vtk(no_SVC_s, f'{args.mesh}_surf/' + "no_svc_s.vtk") Method.writer_vtk(RAW_s, f'{args.mesh}_surf/' + "raw_s.vtk") - tao_ct_plus = np.min(vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetCellData().GetArray('phie_w'))) + tao_ct_plus = np.min(vtk_to_numpy(SVC_s.GetCellData().GetArray('phie_w'))) - SVC_CT_pt = SVC_s.GetPoint(np.argmin(vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetPointData().GetArray('phie_w')))) + SVC_CT_pt = SVC_s.GetPoint(np.argmin(vtk_to_numpy(SVC_s.GetPointData().GetArray('phie_w')))) - tao_ct_minus = np.min(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_w'))) + tao_ct_minus = np.min(vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_w'))) - IVC_CT_pt = IVC_s.GetPoint(np.argmin(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) + IVC_CT_pt = IVC_s.GetPoint(np.argmin(vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) IVC_SEPT_CT_pt = IVC_s.GetPoint( - np.argmax(vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) + np.argmax(vtk_to_numpy(IVC_s.GetPointData().GetArray('phie_w')))) - IVC_max_r_CT_pt = IVC_s.GetPoint(np.argmax(vtk.util.numpy_support.vtk_to_numpy( + IVC_max_r_CT_pt = IVC_s.GetPoint(np.argmax(vtk_to_numpy( IVC_s.GetPointData().GetArray('phie_r')))) # not always the best choice for pm1 CT_band = vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w @@ -290,7 +290,7 @@ def ra_generate_fiber(model, args, job): filter_cell_centers.SetInputData(CT_band) filter_cell_centers.Update() centroids = filter_cell_centers.GetOutput().GetPoints() - centroids_array = vtk.util.numpy_support.vtk_to_numpy(centroids.GetData()) + centroids_array = vtk_to_numpy(centroids.GetData()) tree = cKDTree(centroids_array) @@ -311,9 +311,9 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band_2.vtk") - CT_band_ids = vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) + CT_band_ids = vtk_to_numpy(CT_band.GetCellData().GetArray('Global_ids')) - tao_RAA = np.max(vtk.util.numpy_support.vtk_to_numpy(CT_band.GetCellData().GetArray('phie_v2'))) + tao_RAA = np.max(vtk_to_numpy(CT_band.GetCellData().GetArray('phie_v2'))) loc = vtk.vtkPointLocator() loc.SetDataSet(CT_band) @@ -343,7 +343,7 @@ def ra_generate_fiber(model, args, job): CT_minus = vtk_thr(RAW_s, 1, "CELLS", "phie_w", tao_ct_plus) # grad_ab - RAW_I_ids = vtk.util.numpy_support.vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) + RAW_I_ids = vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) ii = set(RAW_I_ids) - set(CT_SEPT_ids) - set(CT_band_ids) cell_ids = vtk.vtkIdList() @@ -356,7 +356,7 @@ def ra_generate_fiber(model, args, job): CT_minus = extract.GetOutput() - RAW_I_ids = vtk.util.numpy_support.vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) + RAW_I_ids = vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) tag[RAW_I_ids] = right_atrial_lateral_wall_epi @@ -367,7 +367,7 @@ def ra_generate_fiber(model, args, job): RAW_S = vtk_thr(CT_plus, 2, "CELLS", "phie_v", tao_scv, tao_icv) # IB_S grad_v Changed order tao_scv, tao_icv - RAW_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_S.GetCellData().GetArray('Global_ids')) + RAW_S_ids = vtk_to_numpy(RAW_S.GetCellData().GetArray('Global_ids')) tag[RAW_S_ids] = right_atrial_lateral_wall_epi @@ -375,7 +375,7 @@ def ra_generate_fiber(model, args, job): IB = vtk_thr(RAW_S, 1, "CELLS", "phie_r", 0.05) # grad_r or w - IB_ids = vtk.util.numpy_support.vtk_to_numpy(IB.GetCellData().GetArray('Global_ids')) + IB_ids = vtk_to_numpy(IB.GetCellData().GetArray('Global_ids')) tag[IB_ids] = inter_caval_bundle_epi # Change to 68 @@ -414,7 +414,7 @@ def ra_generate_fiber(model, args, job): Method.writer_vtk(septal_surf, f'{args.mesh}_surf/' + "septal_surf.vtk") Method.writer_vtk(RAS_S, f'{args.mesh}_surf/' + "ras_s.vtk") - RAS_S_ids = vtk.util.numpy_support.vtk_to_numpy(RAS_S.GetCellData().GetArray('Global_ids')) + RAS_S_ids = vtk_to_numpy(RAS_S.GetCellData().GetArray('Global_ids')) tag[RAS_S_ids] = right_atrial_septum_epi @@ -430,7 +430,7 @@ def ra_generate_fiber(model, args, job): RAS_low = vtk_thr(RAS_low, 0, "CELLS", "phie_w", 0) # grad_r overwrites the previous - RAS_low_ids = vtk.util.numpy_support.vtk_to_numpy(RAS_low.GetCellData().GetArray('Global_ids')) + RAS_low_ids = vtk_to_numpy(RAS_low.GetCellData().GetArray('Global_ids')) tag[RAS_low_ids] = right_atrial_septum_epi @@ -438,7 +438,7 @@ def ra_generate_fiber(model, args, job): RAW_low = vtk_thr(RAW_low, 1, "CELLS", "phie_w", 0) # grad_ab - RAW_low_ids = vtk.util.numpy_support.vtk_to_numpy(RAW_low.GetCellData().GetArray('Global_ids')) + RAW_low_ids = vtk_to_numpy(RAW_low.GetCellData().GetArray('Global_ids')) tag[RAW_low_ids] = right_atrial_lateral_wall_epi @@ -466,12 +466,12 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.writer_vtk(septal_surf, f'{args.mesh}_surf/' + "septal_surf_2.vtk") - CS_ids = vtk.util.numpy_support.vtk_to_numpy(septal_surf.GetCellData().GetArray('Global_ids')) + CS_ids = vtk_to_numpy(septal_surf.GetCellData().GetArray('Global_ids')) # if len(CS_ids) == 0: ring_ids = np.loadtxt(f'{args.mesh}_surf/' + 'ids_CS.vtx', skiprows=2, dtype=int) - rings_pts = vtk.util.numpy_support.vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] + rings_pts = vtk_to_numpy(model.GetPoints().GetData())[ring_ids, :] CS_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) @@ -486,7 +486,7 @@ def ra_generate_fiber(model, args, job): Method.writer_vtk(RAA_s, f'{args.mesh}_surf/' + "raa_s.vtk") # Check here if RAA is correctly tagged Method.writer_vtk(RAW_low, f'{args.mesh}_surf/' + "raw_low.vtk") - RAA_ids = vtk.util.numpy_support.vtk_to_numpy(RAA_s.GetCellData().GetArray('Global_ids')) + RAA_ids = vtk_to_numpy(RAA_s.GetCellData().GetArray('Global_ids')) tag[RAA_ids] = right_atrial_appendage_epi @@ -498,7 +498,7 @@ def ra_generate_fiber(model, args, job): CT = CT_band - CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) + CT_ids = vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) CT_ids = np.setdiff1d(CT_ids, RAA_ids, assume_unique=True) @@ -508,13 +508,13 @@ def ra_generate_fiber(model, args, job): tag[CT_SEPT_ids] = crista_terminalis - SVC_ids = vtk.util.numpy_support.vtk_to_numpy(SVC_s.GetCellData().GetArray('Global_ids')) + SVC_ids = vtk_to_numpy(SVC_s.GetCellData().GetArray('Global_ids')) tag[SVC_ids] = superior_vena_cava_epi k[SVC_ids] = v_grad[SVC_ids] - IVC_ids = vtk.util.numpy_support.vtk_to_numpy(IVC_s.GetCellData().GetArray('Global_ids')) + IVC_ids = vtk_to_numpy(IVC_s.GetCellData().GetArray('Global_ids')) tag[IVC_ids] = inferior_vena_cava_epi @@ -601,7 +601,7 @@ def ra_generate_fiber(model, args, job): CT = vtk_thr(model, 2, "CELLS", "elemTag", crista_terminalis, crista_terminalis) - CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) + CT_ids = vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) elif args.mesh_type == "vol": @@ -617,7 +617,7 @@ def ra_generate_fiber(model, args, job): extract.Update() CT = extract.GetOutput() - CT_ids = vtk.util.numpy_support.vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) + CT_ids = vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) if args.debug: @@ -684,10 +684,8 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.writer_vtk(TV_lat, f'{args.mesh}_surf/' + "TV_lat.vtk") - ct_points_data = Method.dijkstra_path(CT, point1_id, point2_id) - if args.debug: Method.create_pts(ct_points_data, 'ct_points_data', f'{args.mesh}_surf/') @@ -778,7 +776,7 @@ def ra_generate_fiber(model, args, job): filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(model) filter_cell_centers.Update() - centroids_array = vtk.util.numpy_support.vtk_to_numpy(filter_cell_centers.GetOutput().GetPoints().GetData()) + centroids_array = vtk_to_numpy(filter_cell_centers.GetOutput().GetPoints().GetData()) tree = cKDTree(centroids_array) @@ -860,7 +858,6 @@ def ra_generate_fiber(model, args, job): endo = meshNew.VTKObject - if args.ofmt == 'vtk': vtk_unstructured_grid_writer(job.ID + "/result_RA/RA_endo_with_fiber.vtk", endo, store_binary=True) @@ -967,7 +964,7 @@ def ra_generate_fiber(model, args, job): functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) functionSource.Update() - bb_points = vtk.util.numpy_support.vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + bb_points = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) tag = Method.assign_element_tag_around_path_within_radius(model, bb_points, w_bb, tag, bachmann_bundel_right) el = Method.assign_element_fiber_around_path_within_radius(model, bb_points, w_bb, el, smooth=True) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index 14a439e..b766b13 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -24,21 +24,21 @@ specific language governing permissions and limitations under the License. """ +import datetime import os import warnings import numpy as np -import vtk import pandas as pd -from vtk.util import numpy_support -import subprocess as sp -import datetime +import vtk from carputils import tools -from ra_laplace import ra_laplace -from ra_generate_fiber import ra_generate_fiber + import Methods_RA as Method from create_bridges import add_free_bridge +from ra_generate_fiber import ra_generate_fiber +from ra_laplace import ra_laplace from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy def parser(): @@ -116,7 +116,7 @@ def run(args, job): RA = reverse.GetOutput() - pts = numpy_support.vtk_to_numpy(RA.GetPoints().GetData()) + pts = vtk_to_numpy(RA.GetPoints().GetData()) write_to_pts(RA_mesh + '.pts', pts) diff --git a/pipeline.py b/pipeline.py index 6141969..7ac7d7b 100644 --- a/pipeline.py +++ b/pipeline.py @@ -28,15 +28,12 @@ EXAMPLE_DESCRIPTIVE_NAME = 'AugmentA: Patient-specific Augmented Atrial model Generation Tool' EXAMPLE_AUTHOR = 'Luca Azzolin ' -import sys -from glob import glob -from shutil import copyfile -import pandas as pd import os +import sys from string import Template -import argparse import numpy as np +import pandas as pd import pyvista as pv from scipy.spatial import cKDTree @@ -49,8 +46,6 @@ from resample_surf_mesh import resample_surf_mesh import vtk -from vtk.util import numpy_support -from vtk.numpy_interface import dataset_adapter as dsa sys.path.append('Atrial_LDRBM/Generate_Boundaries') sys.path.append('Atrial_LDRBM/LDRBM/Fiber_LA') diff --git a/standalones/function.py b/standalones/function.py index 22e7630..b0d860b 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -26,12 +26,10 @@ """ import numpy as np -from glob import glob -import pandas as pd -import vtk -from vtk.util import numpy_support import scipy.spatial as spatial -from vtk.numpy_interface import dataset_adapter as dsa +import vtk + +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy def to_polydata(mesh): @@ -66,8 +64,8 @@ def get_farthest_point_pair(point_array_1, point_array_2): def get_closest_point(vtk_points_1, vtk_points_2): - points_array_1 = vtk.util.numpy_support.vtk_to_numpy(vtk_points_1.GetData()) - points_array_2 = vtk.util.numpy_support.vtk_to_numpy(vtk_points_2.GetData()) + points_array_1 = vtk_to_numpy(vtk_points_1.GetData()) + points_array_2 = vtk_to_numpy(vtk_points_2.GetData()) center_1 = get_mean_point(points_array_1) center_2 = get_mean_point(points_array_2) @@ -89,7 +87,7 @@ def get_closest_point(vtk_points_1, vtk_points_2): def find_points_on_mv(mv_points, center_lpv): - mv_points_array_1 = vtk.util.numpy_support.vtk_to_numpy(mv_points.GetData()) + mv_points_array_1 = vtk_to_numpy(mv_points.GetData()) kDTree = vtk.vtkKdTree() kDTree.BuildLocatorFromPoints(mv_points) id_list = vtk.vtkIdList() @@ -197,7 +195,7 @@ def dijkstra_path(polydata, StartVertex, EndVertex): path.SetEndVertex(StartVertex) path.Update() points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) + points_data = vtk_to_numpy(points_data) return points_data @@ -216,7 +214,7 @@ def get_mv_l_and_r(mv_band, center_lpv): cln.SetInputData(surface) cln.Update() points_data = cln.GetOutput().GetPoints().GetData() - ring = vtk.util.numpy_support.vtk_to_numpy(points_data) + ring = vtk_to_numpy(points_data) center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) connect.DeleteSpecifiedRegion(1) @@ -229,7 +227,7 @@ def get_mv_l_and_r(mv_band, center_lpv): cln.SetInputData(surface) cln.Update() points_data = cln.GetOutput().GetPoints().GetData() - ring = vtk.util.numpy_support.vtk_to_numpy(points_data) + ring = vtk_to_numpy(points_data) center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) dis_1 = np.linalg.norm(center_point_1 - center_lpv) dis_2 = np.linalg.norm(center_point_2 - center_lpv) diff --git a/standalones/getmarks.py b/standalones/getmarks.py index c2f87ae..dd38eab 100644 --- a/standalones/getmarks.py +++ b/standalones/getmarks.py @@ -36,6 +36,7 @@ from sklearn.neighbors import NearestNeighbors import argparse +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between @@ -88,11 +89,11 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr=get_threshold_between(model,1,1,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") mv = thr.GetOutput() - rsv_points = vtk.util.numpy_support.vtk_to_numpy(rsv.GetPoints().GetData()) - riv_points = vtk.util.numpy_support.vtk_to_numpy(riv.GetPoints().GetData()) - lsv_points = vtk.util.numpy_support.vtk_to_numpy(lsv.GetPoints().GetData()) - liv_points = vtk.util.numpy_support.vtk_to_numpy(liv.GetPoints().GetData()) - mv_points = vtk.util.numpy_support.vtk_to_numpy(mv.GetPoints().GetData()) + rsv_points = vtk_to_numpy(rsv.GetPoints().GetData()) + riv_points = vtk_to_numpy(riv.GetPoints().GetData()) + lsv_points = vtk_to_numpy(lsv.GetPoints().GetData()) + liv_points = vtk_to_numpy(liv.GetPoints().GetData()) + mv_points = vtk_to_numpy(mv.GetPoints().GetData()) # get farthest away and clostest points on PVs rs_o, ri_o = function.get_farthest_point_pair(rsv_points, riv_points) @@ -152,9 +153,9 @@ def get_landmarks(mesh, prealigned=1, scale=1): lpv_path = function.dijkstra_path(model_polydata, ls_i_id, li_i_id) rpv_path = function.dijkstra_path(model_polydata, rs_i_id, ri_i_id) - lpv_base_temp = function.multidim_intersect(vtk.util.numpy_support.vtk_to_numpy(band.GetPoints().GetData()), + lpv_base_temp = function.multidim_intersect(vtk_to_numpy(band.GetPoints().GetData()), lpv_path) - rpv_base_temp = function.multidim_intersect(vtk.util.numpy_support.vtk_to_numpy(band.GetPoints().GetData()), + rpv_base_temp = function.multidim_intersect(vtk_to_numpy(band.GetPoints().GetData()), rpv_path) lpv_base_fuzzy = np.asarray( diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index be4e3a3..142aeec 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -37,6 +37,7 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from Atrial_LDRBM.Generate_Boundaries import extract_rings from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper @@ -48,11 +49,6 @@ vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] -# def create_sphere(value): -# radius = int(value) -# sphere = pv.Sphere(center=center, radius=radius) -# p.add_mesh(sphere, name='sphere', show_edges=True) -# return def parser(): parser = argparse.ArgumentParser(description='Cut veins manually') parser.add_argument('--mesh', @@ -244,8 +240,8 @@ def extract_largest_region(mesh): def point_array_mapper(mesh1, mesh2, idat): - pts1 = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPoints().GetData()) - pts2 = vtk.util.numpy_support.vtk_to_numpy(mesh2.GetPoints().GetData()) + pts1 = vtk_to_numpy(mesh1.GetPoints().GetData()) + pts2 = vtk_to_numpy(mesh2.GetPoints().GetData()) tree = cKDTree(pts1) @@ -254,7 +250,7 @@ def point_array_mapper(mesh1, mesh2, idat): meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy( + data = vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) @@ -266,7 +262,7 @@ def point_array_mapper(mesh1, mesh2, idat): meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) + data = vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 19de8b3..393049a 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -48,6 +48,7 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from standalones.open_orifices_manually import open_orifices_manually from vtk_opencarp_helper_methods.vtk_methods import filters +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -158,7 +159,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve_center = np.array(centerOfMassFilter.GetCenter()) - valve_pts = vtk.util.numpy_support.vtk_to_numpy(valve.GetPoints().GetData()) + valve_pts = vtk_to_numpy(valve.GetPoints().GetData()) max_dist = 0 for l in range(len(valve_pts)): if np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) > max_dist: @@ -207,7 +208,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve_center = np.array(center_of_mass) - valve_pts = vtk.util.numpy_support.vtk_to_numpy(valve.GetPoints().GetData()) + valve_pts = vtk_to_numpy(valve.GetPoints().GetData()) max_dist = 0 for l in range(len(valve_pts)): if np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) > max_dist: @@ -254,15 +255,15 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu vtk_polydata_writer(f"{full_path}/{atrium}_curv.vtk", model, True) - curv = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('curv')) + curv = vtk_to_numpy(model.GetPointData().GetArray('curv')) - Gl_pt_id = list(vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('Ids'))) - Gl_cell_id = list(vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('Ids'))) + Gl_pt_id = list(vtk_to_numpy(model.GetPointData().GetArray('Ids'))) + Gl_cell_id = list(vtk_to_numpy(model.GetCellData().GetArray('Ids'))) if not MRI: low_v = vtk_thr(model, 1, "POINTS", "bi", 0.5) - pts_low_v = set(list(vtk.util.numpy_support.vtk_to_numpy(low_v.GetPointData().GetArray('Ids')))) + pts_low_v = set(list(vtk_to_numpy(low_v.GetPointData().GetArray('Ids')))) high_v = vtk_thr(model, 0, "POINTS", "bi", 0.5001) @@ -320,7 +321,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu loc = vtk.vtkPointLocator() loc.SetDataSet(model) loc.BuildLocator() - transeptal_punture_id = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('Ids'))[ + transeptal_punture_id = vtk_to_numpy(model.GetPointData().GetArray('Ids'))[ loc.FindClosestPoint(p.picked_point)] p.close() @@ -340,8 +341,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu cln.Update() surface = cln.GetOutput() - pt_high_c = list(vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray('Ids'))) - curv_s = vtk.util.numpy_support.vtk_to_numpy(surface.GetPointData().GetArray('curv')) + pt_high_c = list(vtk_to_numpy(surface.GetPointData().GetArray('Ids'))) + curv_s = vtk_to_numpy(surface.GetPointData().GetArray('curv')) if not MRI: if transeptal_punture_id not in pt_high_c: @@ -371,10 +372,10 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu cln.SetInputData(surface2) cln.Update() surface2 = cln.GetOutput() - pt_surf_2 = list(vtk.util.numpy_support.vtk_to_numpy(surface2.GetPointData().GetArray('Ids'))) + pt_surf_2 = list(vtk_to_numpy(surface2.GetPointData().GetArray('Ids'))) if len(set(pt_high_c).intersection(pt_surf_2)) > 0: - for el in vtk.util.numpy_support.vtk_to_numpy(surface2.GetCellData().GetArray('Ids')): + for el in vtk_to_numpy(surface2.GetCellData().GetArray('Ids')): el_low_vol.add(Gl_cell_id.index(el)) connect2.DeleteSpecifiedRegion(ii) @@ -402,7 +403,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu loc_low_V = extract_largest_region(loc_low_V) - loc_low_V_pts = vtk.util.numpy_support.vtk_to_numpy(loc_low_V.GetPoints().GetData()) + loc_low_V_pts = vtk_to_numpy(loc_low_V.GetPoints().GetData()) max_dist = 0 for l in range(len(loc_low_V_pts)): @@ -421,7 +422,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu apex = np.asarray(model.GetPoint(Gl_pt_id.index(pt_high_c[np.argmax(curv_s)]))) else: if not apex_id in pt_high_c: - for el in vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('Ids')): + for el in vtk_to_numpy(surface.GetCellData().GetArray('Ids')): el_to_del_tot.add(Gl_cell_id.index(el)) connect.DeleteSpecifiedRegion(i) @@ -550,8 +551,8 @@ def extract_largest_region(mesh): def point_array_mapper(mesh1, mesh2, idat): - pts1 = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPoints().GetData()) - pts2 = vtk.util.numpy_support.vtk_to_numpy(mesh2.GetPoints().GetData()) + pts1 = vtk_to_numpy(mesh1.GetPoints().GetData()) + pts2 = vtk_to_numpy(mesh2.GetPoints().GetData()) tree = cKDTree(pts1) @@ -560,7 +561,7 @@ def point_array_mapper(mesh1, mesh2, idat): meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk.util.numpy_support.vtk_to_numpy( + data = vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) @@ -572,7 +573,7 @@ def point_array_mapper(mesh1, mesh2, idat): meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: - data = vtk.util.numpy_support.vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) + data = vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) if isinstance(data[0], collections.abc.Sized): data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) else: diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 2f78d08..c5facf2 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -36,6 +36,7 @@ import numpy as np import pandas as pd +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer pv.set_plot_theme('dark') @@ -126,7 +127,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv boundaryEdges.NonManifoldEdgesOff() boundaryEdges.Update() - boundary_pts = vtk.util.numpy_support.vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData()) + boundary_pts = vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData()) # Clean the mesh from holes and self intersecting triangles meshin = pv.read(f'{meshname}.obj') diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 34f35e4..288e082 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -33,6 +33,7 @@ from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -77,11 +78,11 @@ def low_vol_LAT(args, path): filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(model) filter_cell_centers.Update() - centroids = vtk.util.numpy_support.vtk_to_numpy(filter_cell_centers.GetOutput().GetPoints().GetData()) + centroids = vtk_to_numpy(filter_cell_centers.GetOutput().GetPoints().GetData()) # Low voltage in the model low_vol = vtk_thr(model, 1, "CELLS", "bi", args.low_vol_thr) - low_vol_ids = vtk.util.numpy_support.vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) + low_vol_ids = vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) if args.debug: @@ -106,18 +107,18 @@ def low_vol_LAT(args, path): if args.debug: vtk_xml_unstructured_grid_writer(f'{debug_dir}/endo.vtu', endo) # Get point LAT map in endocardium - LAT_endo = vtk.util.numpy_support.vtk_to_numpy(endo.GetPointData().GetArray('lat')) - endo_ids = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('Global_ids')).astype(int) - endo_pts = vtk.util.numpy_support.vtk_to_numpy(endo.GetPoints().GetData()) + LAT_endo = vtk_to_numpy(endo.GetPointData().GetArray('lat')) + endo_ids = vtk_to_numpy(endo.GetCellData().GetArray('Global_ids')).astype(int) + endo_pts = vtk_to_numpy(endo.GetPoints().GetData()) # Get elements LAT map in endocardium - LAT_map = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('lat')) + LAT_map = vtk_to_numpy(endo.GetCellData().GetArray('lat')) # Extract "healthy" high voltage endocardium not_low_volt_endo = vtk_thr(endo, 0, "POINTS", "bi", 0.5 + 0.01) - LAT_not_low_volt = vtk.util.numpy_support.vtk_to_numpy(not_low_volt_endo.GetPointData().GetArray('lat')) - not_low_volt_endo_pts = vtk.util.numpy_support.vtk_to_numpy(not_low_volt_endo.GetPoints().GetData()) - not_low_volt_ids = vtk.util.numpy_support.vtk_to_numpy( + LAT_not_low_volt = vtk_to_numpy(not_low_volt_endo.GetPointData().GetArray('lat')) + not_low_volt_endo_pts = vtk_to_numpy(not_low_volt_endo.GetPoints().GetData()) + not_low_volt_ids = vtk_to_numpy( not_low_volt_endo.GetPointData().GetArray('Global_ids')).astype(int) if args.debug: @@ -125,7 +126,7 @@ def low_vol_LAT(args, path): # Extract LA wall from SSM to be sure that no veins or LAA is included when selecting the earliest activated point if args.SSM_fitting: LA_wall = smart_reader(args.SSM_basename + '/LA_wall.vtk') - LA_wall_pt_ids = vtk.util.numpy_support.vtk_to_numpy(LA_wall.GetPointData().GetArray('PointIds')) + LA_wall_pt_ids = vtk_to_numpy(LA_wall.GetPointData().GetArray('PointIds')) # See create_SSM_instance standalone to create LA_fit.obj reader = vtk.vtkOBJReader() @@ -133,7 +134,7 @@ def low_vol_LAT(args, path): reader.Update() LA_fit = reader.GetOutput() - LA_fit_wall_pts = vtk.util.numpy_support.vtk_to_numpy(LA_fit.GetPoints().GetData())[LA_wall_pt_ids, :] * 1000 + LA_fit_wall_pts = vtk_to_numpy(LA_fit.GetPoints().GetData())[LA_wall_pt_ids, :] * 1000 tree = cKDTree(not_low_volt_endo_pts) @@ -143,8 +144,8 @@ def low_vol_LAT(args, path): dd, ii = tree.query(endo_pts) healthy_endo = not_low_volt_endo # vtk_thr(not_low_volt_endo,0,"POINTS","CV_mag", args.low_CV_thr) - LAT_healthy = vtk.util.numpy_support.vtk_to_numpy(healthy_endo.GetPointData().GetArray('lat')) - healthy_ids = vtk.util.numpy_support.vtk_to_numpy(healthy_endo.GetPointData().GetArray('Global_ids')).astype(int) + LAT_healthy = vtk_to_numpy(healthy_endo.GetPointData().GetArray('lat')) + healthy_ids = vtk_to_numpy(healthy_endo.GetPointData().GetArray('Global_ids')).astype(int) if args.max_LAT_pt == "max": @@ -209,7 +210,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): # Extract LAT band from min LAT to step i and remove all areas not connected with EAP band = vtk_thr(endo, 2, "CELLS", "lat", min_LAT, steps[i]) - b_ids = vtk.util.numpy_support.vtk_to_numpy(band.GetCellData().GetArray('Global_ids')).astype(int) + b_ids = vtk_to_numpy(band.GetCellData().GetArray('Global_ids')).astype(int) connect = vtk.vtkConnectivityFilter() connect.SetInputData(band) @@ -218,7 +219,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): connect.Update() largest_band = connect.GetOutput() - l_b_ids = vtk.util.numpy_support.vtk_to_numpy(largest_band.GetCellData().GetArray('Global_ids')).astype(int) + l_b_ids = vtk_to_numpy(largest_band.GetCellData().GetArray('Global_ids')).astype(int) if len(b_ids) > len(l_b_ids): cell_diff = set() @@ -255,7 +256,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): filter_cell_centers.SetInputData(largest_band) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() - pts = vtk.util.numpy_support.vtk_to_numpy(centroids2.GetData()) + pts = vtk_to_numpy(centroids2.GetData()) tree = cKDTree(pts) @@ -281,13 +282,13 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): filter_cell_centers.SetInputData(surface) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() - centroids1_array = vtk.util.numpy_support.vtk_to_numpy(centroids1.GetData()) + centroids1_array = vtk_to_numpy(centroids1.GetData()) dd, ii = tree.query(centroids1_array, n_jobs=-1) # Set as elements to clean only if they are at least 1 um away from the biggest band if np.min(dd) > 1: - loc_el_to_clean = vtk.util.numpy_support.vtk_to_numpy( + loc_el_to_clean = vtk_to_numpy( surface.GetCellData().GetArray('Global_ids')).astype(int) tot_el_to_clean = np.union1d(tot_el_to_clean, loc_el_to_clean) @@ -305,7 +306,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): endo_clean = vtk_thr(meshNew.VTKObject, 1, "CELLS", "idss", 0) - el_cleaned = vtk.util.numpy_support.vtk_to_numpy(endo_clean.GetCellData().GetArray('Global_ids')).astype(int) + el_cleaned = vtk_to_numpy(endo_clean.GetCellData().GetArray('Global_ids')).astype(int) endo_to_interpolate = vtk_thr(meshNew.VTKObject, 0, "CELLS", "idss", 1) @@ -313,7 +314,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): filter_cell_centers.SetInputData(endo_clean) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() - pts = vtk.util.numpy_support.vtk_to_numpy(centroids2.GetData()) + pts = vtk_to_numpy(centroids2.GetData()) tree = cKDTree(pts) @@ -336,7 +337,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): cln.Update() surface = cln.GetOutput() - loc_el_to_clean = vtk.util.numpy_support.vtk_to_numpy(surface.GetCellData().GetArray('Global_ids')).astype(int) + loc_el_to_clean = vtk_to_numpy(surface.GetCellData().GetArray('Global_ids')).astype(int) el_to_clean.append(np.unique(loc_el_to_clean)) @@ -344,7 +345,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): filter_cell_centers.SetInputData(surface) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() - centroids1_array = vtk.util.numpy_support.vtk_to_numpy(centroids1.GetData()) + centroids1_array = vtk_to_numpy(centroids1.GetData()) dd, ii = tree.query(centroids1_array, n_jobs=-1) # Find distance to endo_clean pts @@ -377,7 +378,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): def create_regele(endo, args): # Low voltage in the model low_vol = vtk_thr(endo, 1, "CELLS", "bi", args.low_vol_thr) - low_vol_ids = vtk.util.numpy_support.vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) + low_vol_ids = vtk_to_numpy(low_vol.GetCellData().GetArray('Global_ids')).astype(int) not_low_volt_endo = vtk_thr(endo, 0, "POINTS", "bi", 0.5 + 0.01) f_slow_conductive = f"{args.init_state_dir}/{args.mesh.split('/')[-1]}/elems_slow_conductive" @@ -393,9 +394,9 @@ def create_regele(endo, args): def low_CV(model, low_CV_thr, meshfold): low_CV = vtk_thr(model, 1, "CELLS", "CV_mag", low_CV_thr) - low_CV_ids = vtk.util.numpy_support.vtk_to_numpy(low_CV.GetCellData().GetArray('Global_ids')).astype(int) + low_CV_ids = vtk_to_numpy(low_CV.GetCellData().GetArray('Global_ids')).astype(int) - low_CV_c = vtk.util.numpy_support.vtk_to_numpy(low_CV.GetCellData().GetArray('CV_mag')) / 1000 + low_CV_c = vtk_to_numpy(low_CV.GetCellData().GetArray('CV_mag')) / 1000 low_sigma = low_CV_c ** 2 @@ -408,6 +409,7 @@ def low_CV(model, low_CV_thr, meshfold): f.write(f"{i:.4f}\n") f.close() + def dijkstra_path(polydata, StartVertex, EndVertex): path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(polydata) @@ -416,7 +418,7 @@ def dijkstra_path(polydata, StartVertex, EndVertex): path.SetEndVertex(StartVertex) path.Update() points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk.util.numpy_support.vtk_to_numpy(points_data) + points_data = vtk_to_numpy(points_data) return points_data @@ -438,9 +440,9 @@ def get_EAP(path_mod, path_fib): mod_fib = cellid.GetOutput() LA_MV = vtk_thr(mod_fib, 1, "CELLS", "elemTag", 2) - LAT_map = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('LAT')) + LAT_map = vtk_to_numpy(model.GetPointData().GetArray('LAT')) - LA_MV_ids = vtk.util.numpy_support.vtk_to_numpy(LA_MV.GetPointData().GetArray('Global_ids')).astype(int) + LA_MV_ids = vtk_to_numpy(LA_MV.GetPointData().GetArray('Global_ids')).astype(int) print(LA_MV_ids[np.argmin(LAT_map[LA_MV_ids])]) stim_pt = model.GetPoint(LA_MV_ids[np.argmin(LAT_map[LA_MV_ids])]) diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index 7831349..692331b 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -25,13 +25,13 @@ under the License. """ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer EXAMPLE_DESCRIPTIVE_NAME = 'Tune conductivities to fit clinical LAT map' EXAMPLE_AUTHOR = 'Luca Azzolin ' import os -import sys import vtk from datetime import date @@ -39,10 +39,7 @@ from carputils import tools import numpy as np -from carputils.carpio import igb -from scipy.spatial import cKDTree import csv -import random from vtk.numpy_interface import dataset_adapter as dsa import Methods_fit_to_clinical_LAT @@ -363,7 +360,7 @@ def run(args, job): elems_not_conductive = np.loadtxt(f'{meshfold}/elems_slow_conductive.regele', skiprows=1, dtype=int) - endo_etag = vtk.util.numpy_support.vtk_to_numpy(endo.GetCellData().GetArray('elemTag')) + endo_etag = vtk_to_numpy(endo.GetCellData().GetArray('elemTag')) elems_not_conductive = elems_not_conductive[np.where(elems_not_conductive < len(endo_etag))] @@ -375,10 +372,10 @@ def run(args, job): meshNew.CellData.append(endo_etag, "elemTag") vtk_xml_unstructured_grid_writer(f"{meshfold}/LA_endo_with_fiber_30_um.vtu", meshNew.VTKObject) - pts = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetPoints().GetData()) + pts = vtk_to_numpy(meshNew.VTKObject.GetPoints().GetData()) - el_epi = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.numpy_support.vtk_to_numpy(meshNew.VTKObject.GetCellData().GetArray('sheet')) + el_epi = vtk_to_numpy(meshNew.VTKObject.GetCellData().GetArray('fiber')) + sheet_epi = vtk_to_numpy(meshNew.VTKObject.GetCellData().GetArray('sheet')) el_epi = el_epi / 1000 sheet_epi = sheet_epi / 1000 @@ -604,7 +601,7 @@ def run(args, job): # Extract all cells which are activated active = Methods_fit_to_clinical_LAT.vtk_thr(healthy_endo, 0, "POINTS", "lat_s", 0) - active_cells = vtk.util.numpy_support.vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int) + active_cells = vtk_to_numpy(active.GetCellData().GetArray('Global_ids')).astype(int) print(f"active_cells: {len(active_cells)}") act_cls_old = np.zeros((model.GetNumberOfCells(),)) act_cls = np.zeros((model.GetNumberOfCells(),)) @@ -618,7 +615,7 @@ def run(args, job): act_cls[active_cells] = 1 lats_to_fit_old = np.array(lats_to_fit) - lats_to_fit = vtk.util.numpy_support.vtk_to_numpy(model.GetCellData().GetArray('lat_s')) + lats_to_fit = vtk_to_numpy(model.GetCellData().GetArray('lat_s')) if len(lats_to_fit_old) > 0: meshNew.CellData.append(lats_to_fit_old, "LATs_old") @@ -754,11 +751,11 @@ def run(args, job): model_cleaned = Methods_fit_to_clinical_LAT.vtk_thr(meshNew.VTKObject, 2, "CELLS", "idss", 0, 0) - cleaned_ids = vtk.util.numpy_support.vtk_to_numpy(model_cleaned.GetPointData().GetArray('Global_ids')).astype(int) + cleaned_ids = vtk_to_numpy(model_cleaned.GetPointData().GetArray('Global_ids')).astype(int) lats = np.loadtxt(simid + '/init_acts_ACTs-thresh.dat') - lats_to_fit = vtk.util.numpy_support.vtk_to_numpy(model.GetPointData().GetArray('lat')) - min_LAT + lats_to_fit = vtk_to_numpy(model.GetPointData().GetArray('lat')) - min_LAT RMSE = mean_squared_error(lats[cleaned_ids], lats_to_fit[cleaned_ids], squared=False) @@ -803,7 +800,7 @@ def run(args, job): pt_cell.Update() meshNew.CellData.append(LAT_map, "LAT_to_clean") - LATs_diff = vtk.util.numpy_support.vtk_to_numpy(pt_cell.GetOutput().GetCellData().GetArray('lat_s')) - LAT_map + LATs_diff = vtk_to_numpy(pt_cell.GetOutput().GetCellData().GetArray('lat_s')) - LAT_map meshNew.CellData.append(slow_CV, "slow_CV") meshNew.CellData.append(LATs_diff, "LATs_diff") From 7b0c060df8e6879062e8a6e302d2ce3457813375 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 13:36:10 +0100 Subject: [PATCH 20/70] Used get maximum distance of points in AugmentA --- standalones/open_orifices_with_curvature.py | 42 ++++++--------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 393049a..08a8d29 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -24,32 +24,25 @@ specific language governing permissions and limitations under the License. """ -import os, sys +import argparse +import collections +import os +import sys import warnings import numpy as np -import pathlib -from glob import glob -import pandas as pd -import vtk -from vtk.util import numpy_support -import scipy.spatial as spatial -from vtk.numpy_interface import dataset_adapter as dsa -import datetime -from sklearn.cluster import KMeans -import argparse -from scipy.spatial import cKDTree - import pymeshfix -from pymeshfix import _meshfix import pyvista as pv -import collections +import vtk +from scipy.spatial import cKDTree +from vtk.numpy_interface import dataset_adapter as dsa import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from standalones.open_orifices_manually import open_orifices_manually from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader pv.set_plot_theme('dark') @@ -159,11 +152,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve_center = np.array(centerOfMassFilter.GetCenter()) - valve_pts = vtk_to_numpy(valve.GetPoints().GetData()) - max_dist = 0 - for l in range(len(valve_pts)): - if np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) + max_dist = get_maximum_distance_of_points(valve, valve_center) if max_dist > max_cutting_radius * 2: print(f"Valve bigger than {max_cutting_radius * 2} cm") @@ -208,11 +197,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu valve_center = np.array(center_of_mass) - valve_pts = vtk_to_numpy(valve.GetPoints().GetData()) - max_dist = 0 - for l in range(len(valve_pts)): - if np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((valve_center - valve_pts[l]) ** 2, axis=0)) + max_dist = get_maximum_distance_of_points(valve, valve_center) # Cutting valve with fixed radius to ensure that it is the biggest ring el_to_del_tot = find_elements_within_radius(model, valve_center, max_cutting_radius) @@ -403,12 +388,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu loc_low_V = extract_largest_region(loc_low_V) - loc_low_V_pts = vtk_to_numpy(loc_low_V.GetPoints().GetData()) - - max_dist = 0 - for l in range(len(loc_low_V_pts)): - if np.sqrt(np.sum((pt_max_curv - loc_low_V_pts[l]) ** 2, axis=0)) > max_dist: - max_dist = np.sqrt(np.sum((pt_max_curv - loc_low_V_pts[l]) ** 2, axis=0)) + max_dist = get_maximum_distance_of_points(loc_low_V, pt_max_curv) el_to_del = find_elements_within_radius(model, pt_max_curv, min_cutting_radius * 2 * scale) From 6be9111b0b1bb8f3b2372e0f61c18f102cf13454 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 13:44:32 +0100 Subject: [PATCH 21/70] Used mesh cutting from helper methods --- standalones/open_orifices_manually.py | 23 +------ standalones/open_orifices_with_curvature.py | 72 ++------------------- 2 files changed, 7 insertions(+), 88 deletions(-) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 142aeec..28d254b 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -39,6 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_elements_from_mesh from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper pv.set_plot_theme('dark') @@ -136,27 +137,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ else: el_to_del_tot = find_elements_within_radius(mesh, picked_pt, min_cutting_radius) - model_new_el = vtk.vtkIdList() - cell_id_all = list(range(mesh.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - - for var in el_diff: - model_new_el.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(mesh) - extract.SetCellList(model_new_el) - extract.Update() - - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(extract.GetOutputPort()) - geo_filter.Update() - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_filter.GetOutputPort()) - cleaner.Update() - - mesh = cleaner.GetOutput() + mesh = cut_elements_from_mesh(mesh, el_to_del_tot) model = extract_largest_region(mesh) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 08a8d29..c7d99cc 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -42,7 +42,8 @@ from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points +from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ + cut_elements_from_mesh from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader pv.set_plot_theme('dark') @@ -156,29 +157,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu if max_dist > max_cutting_radius * 2: print(f"Valve bigger than {max_cutting_radius * 2} cm") - el_to_del_tot = find_elements_within_radius(model, valve_center, max_cutting_radius) - model_new_el = vtk.vtkIdList() - cell_id_all = list(range(model.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - - for var in el_diff: - model_new_el.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(model_new_el) - extract.Update() - - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(extract.GetOutputPort()) - geo_filter.Update() - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_filter.GetOutputPort()) - cleaner.Update() - - model = cleaner.GetOutput() + model = cut_mesh_with_radius(model, valve_center, max_cutting_radius) else: valve = vtk_thr(model, 0, "POINTS", "curv", 0.05) @@ -200,29 +180,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu max_dist = get_maximum_distance_of_points(valve, valve_center) # Cutting valve with fixed radius to ensure that it is the biggest ring - el_to_del_tot = find_elements_within_radius(model, valve_center, max_cutting_radius) - - model_new_el = vtk.vtkIdList() - cell_id_all = list(range(model.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - - for var in el_diff: - model_new_el.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(model_new_el) - extract.Update() - - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(extract.GetOutputPort()) - geo_filter.Update() - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_filter.GetOutputPort()) - cleaner.Update() - - model = cleaner.GetOutput() + model = cut_mesh_with_radius(model, valve_center, max_cutting_radius) # model = smart_reader("{}/{}_valve.vtk".format(full_path, atrium)) cellid = vtk.vtkIdFilter() @@ -408,27 +366,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu connect.DeleteSpecifiedRegion(i) connect.Update() - model_new_el = vtk.vtkIdList() - cell_id_all = list(range(model.GetNumberOfCells())) - el_diff = list(set(cell_id_all).difference(el_to_del_tot)) - - for var in el_diff: - model_new_el.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(model_new_el) - extract.Update() - - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(extract.GetOutputPort()) - geo_filter.Update() - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_filter.GetOutputPort()) - cleaner.Update() - - model = cleaner.GetOutput() + model = cut_elements_from_mesh(model, el_to_del_tot) model = extract_largest_region(model) From cb799b9f6d86d2dbe6faa2a3e5fc961a95aa7e82 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 13:47:33 +0100 Subject: [PATCH 22/70] Fixed cutting size in open orifices manually --- standalones/open_orifices_manually.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 28d254b..a56bde5 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -39,7 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_elements_from_mesh +from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_elements_from_mesh, cut_mesh_with_radius from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper pv.set_plot_theme('dark') @@ -95,8 +95,8 @@ def parser(): return parser -def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_radius=7.5, max_cutting_radius=17.5, - LAA="", RAA="", debug=0): +def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, vessels_cutting_radius=7.5, + valve_cutting_radius=17.5, LAA="", RAA="", debug=0): meshname = meshpath.split("/")[-1] full_path = meshpath[:-len(meshname)] @@ -133,11 +133,11 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, min_cutting_ picked_pt = p.picked_point p.close() if r == 'mitral valve' or r == 'tricuspid valve': - el_to_del_tot = find_elements_within_radius(mesh, picked_pt, max_cutting_radius) + selected_radius = valve_cutting_radius else: - el_to_del_tot = find_elements_within_radius(mesh, picked_pt, min_cutting_radius) + selected_radius = vessels_cutting_radius - mesh = cut_elements_from_mesh(mesh, el_to_del_tot) + mesh = cut_mesh_with_radius(mesh, picked_pt, selected_radius) model = extract_largest_region(mesh) From fe5c0d39a5e2c45315cf762219136075b28963e5 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 13:55:10 +0100 Subject: [PATCH 23/70] Fully included helper_methods into AugmentA --- standalones/open_orifices_manually.py | 24 +----------------- standalones/open_orifices_with_curvature.py | 25 +----------------- standalones/resample_surf_mesh.py | 28 +-------------------- 3 files changed, 3 insertions(+), 74 deletions(-) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index a56bde5..85cb3af 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -39,7 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_elements_from_mesh, cut_mesh_with_radius +from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_mesh_with_radius from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper pv.set_plot_theme('dark') @@ -178,28 +178,6 @@ def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thr2) -def find_elements_within_radius(mesh, points_data, radius): - locator = vtk.vtkStaticPointLocator() - locator.SetDataSet(mesh) - locator.BuildLocator() - - mesh_id_list = vtk.vtkIdList() - locator.FindPointsWithinRadius(radius, points_data, mesh_id_list) - - mesh_cell_id_list = vtk.vtkIdList() - mesh_cell_temp_id_list = vtk.vtkIdList() - for i in range(mesh_id_list.GetNumberOfIds()): - mesh.GetPointCells(mesh_id_list.GetId(i), mesh_cell_temp_id_list) - for j in range(mesh_cell_temp_id_list.GetNumberOfIds()): - mesh_cell_id_list.InsertNextId(mesh_cell_temp_id_list.GetId(j)) - - id_set = set() - for i in range(mesh_cell_id_list.GetNumberOfIds()): - id_set.add(mesh_cell_id_list.GetId(i)) - - return id_set - - def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index c7d99cc..57fcb1d 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ - cut_elements_from_mesh + cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader pv.set_plot_theme('dark') @@ -425,29 +425,6 @@ def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, thr2) - -def find_elements_within_radius(mesh, points_data, radius): - locator = vtk.vtkStaticPointLocator() - locator.SetDataSet(mesh) - locator.BuildLocator() - - mesh_id_list = vtk.vtkIdList() - locator.FindPointsWithinRadius(radius, points_data, mesh_id_list) - - mesh_cell_id_list = vtk.vtkIdList() - mesh_cell_temp_id_list = vtk.vtkIdList() - for i in range(mesh_id_list.GetNumberOfIds()): - mesh.GetPointCells(mesh_id_list.GetId(i), mesh_cell_temp_id_list) - for j in range(mesh_cell_temp_id_list.GetNumberOfIds()): - mesh_cell_id_list.InsertNextId(mesh_cell_temp_id_list.GetId(j)) - - id_set = set() - for i in range(mesh_cell_id_list.GetNumberOfIds()): - id_set.add(mesh_cell_id_list.GetId(i)) - - return id_set - - def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index c5facf2..3da313c 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -36,6 +36,7 @@ import numpy as np import pandas as pd +from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer @@ -68,33 +69,6 @@ def parser(): return parser - -def find_elements_around_path_within_radius(mesh, points_data, radius): - locator = vtk.vtkStaticPointLocator() - locator.SetDataSet(mesh) - locator.BuildLocator() - - mesh_id_list = vtk.vtkIdList() - for i in range(len(points_data)): - temp_result = vtk.vtkIdList() - locator.FindPointsWithinRadius(radius, points_data[i], temp_result) - for j in range(temp_result.GetNumberOfIds()): - mesh_id_list.InsertNextId(temp_result.GetId(j)) - - mesh_cell_id_list = vtk.vtkIdList() - mesh_cell_temp_id_list = vtk.vtkIdList() - for i in range(mesh_id_list.GetNumberOfIds()): - mesh.GetPointCells(mesh_id_list.GetId(i), mesh_cell_temp_id_list) - for j in range(mesh_cell_temp_id_list.GetNumberOfIds()): - mesh_cell_id_list.InsertNextId(mesh_cell_temp_id_list.GetId(j)) - - id_set = set() - for i in range(mesh_cell_id_list.GetNumberOfIds()): - id_set.add(mesh_cell_id_list.GetId(i)) - - return id_set - - def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv=0, scale=1, size=30, apex_id=-1, atrium='LA'): mesh_data = dict() From 861195e767d28e7e5d32e91b4c076732aee8593b Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 14:28:59 +0100 Subject: [PATCH 24/70] Fully included vtkPlane encapsulation into AugmentA --- .../Generate_Boundaries/extract_rings.py | 56 +++---------------- .../extract_rings_TOP_epi_endo.py | 56 +++---------------- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 32 +++-------- .../LDRBM/Fiber_LA/la_generate_fiber.py | 22 +++----- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 30 +++------- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 17 ++---- standalones/function.py | 40 ++++--------- 7 files changed, 58 insertions(+), 195 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index ce1afc8..d797166 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -36,8 +36,10 @@ from sklearn.cluster import KMeans from vtk.numpy_interface import dataset_adapter as dsa +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -227,7 +229,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i centroids["LAA"] = LA_ap_point array_name = "Ids" if mesh_surf.GetPointData().GetArray(array_name) is not None: - #Remove previouse id so they match with indices + # Remove previouse id so they match with indices mesh_surf.GetPointData().RemoveArray(array_name) idFilter = vtk.vtkIdFilter() idFilter.SetInputData(mesh_surf) @@ -529,16 +531,7 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - v1 = rpv_mean - mv_mean - v2 = lpv_mean - mv_mean - norm = np.cross(v1, v2) - - # # normalize vector - norm = norm / np.linalg.norm(norm) - - plane = vtk.vtkPlane() - plane.SetNormal(norm[0], norm[1], norm[2]) - plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) + plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) appendFilter = vtk.vtkAppendPolyData() for r in [rings[i] for i in RPVs]: @@ -568,16 +561,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - v1 = rpv_mean - mv_mean - v2 = lpv_mean - mv_mean - norm = np.cross(v1, v2) - - # # normalize vector - norm = norm / np.linalg.norm(norm) - - plane = vtk.vtkPlane() - plane.SetNormal(norm[0], norm[1], norm[2]) - plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) + plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(LA) @@ -713,18 +697,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): ivc_center = np.array(r.center) ivc = r.vtk_polydata - # calculate the norm vector - v1 = tv_center - svc_center - v2 = tv_center - ivc_center - norm = np.cross(v1, v2) - - # normalize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n - - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) + plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) @@ -767,23 +740,12 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): """ separate the tv into tv tv-f and tv-f """ - # calculate the norm vector - v1 = svc_center - tv_center - v2 = ivc_center - tv_center - norm = np.cross(v2, v1) - - # normalize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n + norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) norm_2 = - norm_1 - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) + plane = initialize_plane(norm_1[0], tv_center) - plane2 = vtk.vtkPlane() - plane2.SetNormal(norm_2[0][0], norm_2[0][1], norm_2[0][2]) - plane2.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) + plane2=initialize_plane(norm_2[0], tv_center) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(tv) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 8cbd5e9..9915446 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -36,8 +36,10 @@ from sklearn.cluster import KMeans from vtk.numpy_interface import dataset_adapter as dsa +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -502,16 +504,7 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - v1 = rpv_mean - mv_mean - v2 = lpv_mean - mv_mean - norm = np.cross(v1, v2) - - # # normalize vector - norm = norm / np.linalg.norm(norm) - - plane = vtk.vtkPlane() - plane.SetNormal(norm[0], norm[1], norm[2]) - plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) + plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) appendFilter = vtk.vtkAppendPolyData() for r in [rings[i] for i in RPVs]: @@ -541,16 +534,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_mean = np.mean(RPVs_c, axis=0) mv_mean = rings[np.argmax([r.np for r in rings])].center - v1 = rpv_mean - mv_mean - v2 = lpv_mean - mv_mean - norm = np.cross(v1, v2) - - # # normalize vector - norm = norm / np.linalg.norm(norm) - - plane = vtk.vtkPlane() - plane.SetNormal(norm[0], norm[1], norm[2]) - plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) + plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(LA) @@ -686,18 +670,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): ivc_center = np.array(r.center) ivc = r.vtk_polydata - # calculate the norm vector - v1 = tv_center - svc_center - v2 = tv_center - ivc_center - norm = np.cross(v1, v2) - - # normalize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n - - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) + initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) geo_filter = vtk.vtkGeometryFilter() geo_filter.SetInputData(model) @@ -773,23 +746,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): """ separate the tv into tv tv-f and tv-f """ - # calculate the norm vector - v1 = svc_center - tv_center - v2 = ivc_center - tv_center - norm = np.cross(v2, v1) - - # normalize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n - norm_2 = - norm_1 - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) + norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) + norm_2 = - norm_1 - plane2 = vtk.vtkPlane() - plane2.SetNormal(norm_2[0][0], norm_2[0][1], norm_2[0][2]) - plane2.SetOrigin(tv_center[0], tv_center[1], tv_center[2]) + plane = initialize_plane(norm_1[0], tv_center) + plane2 = initialize_plane(norm_2[0], tv_center) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(tv) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 8937a7f..ef12987 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -32,11 +32,12 @@ from scipy.spatial.distance import cosine from vtk.numpy_interface import dataset_adapter as dsa -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, get_normalized_cross_product from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ get_threshold_between @@ -253,17 +254,9 @@ def dijkstra_path_on_a_plane(polydata, StartVertex, EndVertex, plane_point): point_end = np.asarray(polydata.GetPoint(EndVertex)) point_third = plane_point - v1 = point_start - point_end - v2 = point_start - point_third - norm = np.cross(v1, v2) - # - # # normlize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n + norm_1 = get_normalized_cross_product(point_start, point_end, point_third) - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(point_start[0], point_start[1], point_start[2]) + plane = initialize_plane(norm_1[0], point_start) meshExtractFilter1 = vtk.vtkExtractGeometry() meshExtractFilter1.SetInputData(polydata) @@ -271,10 +264,8 @@ def dijkstra_path_on_a_plane(polydata, StartVertex, EndVertex, plane_point): meshExtractFilter1.Update() point_moved = point_start - 1.5 * norm_1 - # print(point_moved[0][0]) - plane2 = vtk.vtkPlane() - plane2.SetNormal(-norm_1[0][0], -norm_1[0][1], -norm_1[0][2]) - plane2.SetOrigin(point_moved[0][0], point_moved[0][1], point_moved[0][2]) + + plane2 = initialize_plane(-norm_1[0], point_moved[0]) meshExtractFilter2 = vtk.vtkExtractGeometry() meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) @@ -500,17 +491,10 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, tv_ivc_center = get_mean_point(ra_ivc_surface) tv_svc_center = get_mean_point(ra_svc_surface) - v1 = tv_center - tv_ivc_center - v2 = tv_center - tv_svc_center - norm = np.cross(v1, v2) - - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n + norm_1 = get_normalized_cross_product(tv_center, tv_ivc_center, tv_svc_center) moved_center = tv_center - norm_1 * 5 - plane = vtk.vtkPlane() - plane.SetNormal(-norm_1[0][0], -norm_1[0][1], -norm_1[0][2]) - plane.SetOrigin(moved_center[0][0], moved_center[0][1], moved_center[0][2]) + plane = initialize_plane(-norm_1[0], moved_center[0]) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(ra_tv_s_surface) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 71d2fb0..a56ca74 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -24,21 +24,23 @@ specific language governing permissions and limitations under the License. """ +import csv +import datetime +import os + import numpy as np +import pandas as pd import vtk from vtk.numpy_interface import dataset_adapter as dsa + import Methods_LA as Method -import csv -import datetime -import pandas as pd from la_laplace import laplace_0_1 -import os - from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -317,18 +319,10 @@ def la_generate_fiber(model, args, job): rpv_mean = np.mean([df["RIPV"].to_numpy(), df["RSPV"].to_numpy()], axis=0) mv_mean = df["MV"].to_numpy() - v1 = rpv_mean - mv_mean - v2 = lpv_mean - mv_mean - norm = np.cross(v2, v1) - - norm = norm / np.linalg.norm(norm) + plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) band_s = vtk_thr(epi, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv) - plane = vtk.vtkPlane() - plane.SetNormal(norm[0], norm[1], norm[2]) - plane.SetOrigin(mv_mean[0], mv_mean[1], mv_mean[2]) - meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(band_s) meshExtractFilter.SetImplicitFunction(plane) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 3b729df..986ce5a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -30,10 +30,12 @@ from vtk.numpy_interface import dataset_adapter as dsa import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.openCARP.exporting import write_to_elem, write_to_pts, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -387,17 +389,9 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point point_end = np.asarray(polydata.GetPoint(EndVertex)) point_third = plane_point - v1 = point_start - point_end - v2 = point_start - point_third - norm = np.cross(v1, v2) - # - # # normlize norm - n = np.linalg.norm(norm) - norm_1 = norm / n + norm_1 = get_normalized_cross_product(point_start, point_end, point_third) - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) - plane.SetOrigin(point_start[0], point_start[1], point_start[2]) + plane = initialize_plane(norm_1, point_start) meshExtractFilter1 = vtk.vtkExtractGeometry() meshExtractFilter1.SetInputData(polydata) @@ -405,9 +399,8 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point meshExtractFilter1.Update() point_moved = point_start - 2 * args.scale * norm_1 - plane2 = vtk.vtkPlane() - plane2.SetNormal(-norm_1[0], -norm_1[1], -norm_1[2]) - plane2.SetOrigin(point_moved[0], point_moved[1], point_moved[2]) + + plane2 = initialize_plane(-norm_1, point_moved) meshExtractFilter2 = vtk.vtkExtractGeometry() meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) @@ -666,17 +659,10 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, tv_ivc_center = get_mean_point(ra_ivc_surface) tv_svc_center = get_mean_point(ra_svc_surface) - v1 = tv_center - tv_ivc_center - v2 = tv_center - tv_svc_center - norm = np.cross(v1, v2) - - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n + norm_1 = get_normalized_cross_product(tv_center, tv_ivc_center, tv_svc_center) moved_center = tv_center - norm_1 * 5 - plane = vtk.vtkPlane() - plane.SetNormal(-norm_1[0][0], -norm_1[0][1], -norm_1[0][2]) - plane.SetOrigin(moved_center[0][0], moved_center[0][1], moved_center[0][2]) + plane = initialize_plane(-norm_1[0], moved_center[0]) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(ra_tv_s_surface) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 57b7eb2..b221f80 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -34,11 +34,13 @@ import vtk from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa + import Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -397,9 +399,7 @@ def ra_generate_fiber(model, args, job): n = np.linalg.norm(norm) norm_1 = norm / n # Changed sign - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) # changed - plane.SetOrigin(df["TV"][0], df["TV"][1], df["TV"][2]) + plane = initialize_plane(norm_1, df["TV"]) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(Method.to_polydata(RAW_S)) @@ -445,17 +445,12 @@ def ra_generate_fiber(model, args, job): k[RAW_low_ids] = ab_grad[RAW_low_ids] # calculate the norm vector - # v1 = np.array(IVC_SEPT_CT_pt) - np.array(IVC_CT_pt) - # v2 = np.array(df["TV"]) - np.array(df["IVC"]) - # norm = np.cross(v1, v2) norm = np.array(df["SVC"]) - np.array(df["IVC"]) # normalize norm n = np.linalg.norm(norm) norm_1 = norm / n - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) - plane.SetOrigin(IVC_SEPT_CT_pt[0], IVC_SEPT_CT_pt[1], IVC_SEPT_CT_pt[2]) + plane = initialize_plane(norm_1, IVC_SEPT_CT_pt) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(no_TV_s) @@ -661,9 +656,7 @@ def ra_generate_fiber(model, args, job): n = np.linalg.norm(norm) norm_1 = norm / n - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0], norm_1[1], norm_1[2]) - plane.SetOrigin(df["TV"][0], df["TV"][1], df["TV"][2]) + initialize_plane(norm_1, df["TV"]) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(TV_s) diff --git a/standalones/function.py b/standalones/function.py index b0d860b..dafdcb7 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -29,7 +29,9 @@ import scipy.spatial as spatial import vtk +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane def to_polydata(mesh): @@ -117,18 +119,11 @@ def find_points_on_mv(mv_points, center_lpv): def cut_a_band_from_model(polydata, point_1, point_2, point_3, width): - v1 = point_2 - point_1 - v2 = point_3 - point_1 - norm = np.cross(v1, v2) - # - # # normlize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n + norm_1 = get_normalized_cross_product(point_1, point_2, point_3) point_pass = point_1 + 0.5 * width * norm_1 - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(point_pass[0][0], point_pass[0][1], point_pass[0][2]) + + plane = initialize_plane(norm_1[0], point_pass[0]) meshExtractFilter1 = vtk.vtkExtractGeometry() meshExtractFilter1.SetInputData(polydata) @@ -136,10 +131,8 @@ def cut_a_band_from_model(polydata, point_1, point_2, point_3, width): meshExtractFilter1.Update() point_moved = point_1 - 0.5 * width * norm_1 - # print(point_moved[0][0]) - plane2 = vtk.vtkPlane() - plane2.SetNormal(-norm_1[0][0], -norm_1[0][1], -norm_1[0][2]) - plane2.SetOrigin(point_moved[0][0], point_moved[0][1], point_moved[0][2]) + + plane2 = initialize_plane(-norm_1[0], point_moved[0]) meshExtractFilter2 = vtk.vtkExtractGeometry() meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) @@ -155,21 +148,10 @@ def cut_a_band_from_model(polydata, point_1, point_2, point_3, width): def cut_into_two_parts(polydata, point_1, point_2, point_3): - v1 = point_2 - point_1 - v2 = point_3 - point_1 - norm = np.cross(v1, v2) - # - # # normlize norm - n = np.linalg.norm([norm], axis=1, keepdims=True) - norm_1 = norm / n - - plane = vtk.vtkPlane() - plane.SetNormal(norm_1[0][0], norm_1[0][1], norm_1[0][2]) - plane.SetOrigin(point_1[0], point_1[1], point_1[2]) - - plane2 = vtk.vtkPlane() - plane2.SetNormal(-norm_1[0][0], -norm_1[0][1], -norm_1[0][2]) - plane2.SetOrigin(point_1[0], point_1[1], point_1[2]) + norm_1 = get_normalized_cross_product(point_1, point_2, point_3) + + plane = initialize_plane(norm_1[0], point_1) + plane2 = initialize_plane(-norm_1[0], point_1) meshExtractFilter1 = vtk.vtkExtractGeometry() meshExtractFilter1.SetInputData(polydata) From 1f10fc8a67d96d1363a787c0dbf3fc0c47256276 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 14:45:43 +0100 Subject: [PATCH 25/70] Included point to cell data into AugmentA --- .../LDRBM/Fiber_LA/la_calculate_gradient.py | 11 ++++----- .../LDRBM/Fiber_RA/ra_calculate_gradient.py | 18 +++++++------- .../Methods_fit_to_clinical_LAT.py | 13 ++-------- ...tune_conductivities_to_fit_clinical_LAT.py | 24 +++++-------------- 4 files changed, 22 insertions(+), 44 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py index 10a5728..eefa46e 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_calculate_gradient.py @@ -28,6 +28,7 @@ import vtk +from vtk_opencarp_helper_methods.vtk_methods.converters import convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer @@ -35,10 +36,8 @@ def la_calculate_gradient(args, model, job): name_list = ['phi', 'r', 'v', 'ab'] # change the result of Laplace from points data to cell data - pointDataToCellData = vtk.vtkPointDataToCellData() - pointDataToCellData.PassPointDataOn() - pointDataToCellData.SetInputData(model) - pointDataToCellData.Update() + + model_cell_data = convert_point_to_cell_data(model, None) for var in name_list: print('Calculating the gradient of ' + str(var) + '...') @@ -46,7 +45,7 @@ def la_calculate_gradient(args, model, job): # using the vtkGradientFilter to calculate the gradient if args.mesh_type == "vol": gradientFilter = vtk.vtkGradientFilter() - gradientFilter.SetInputConnection(pointDataToCellData.GetOutputPort()) + gradientFilter.SetInputData(model_cell_data) gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "phie_" + str(var)) gradientFilter.SetResultArrayName('grad_' + str(var)) @@ -54,7 +53,7 @@ def la_calculate_gradient(args, model, job): LA_gradient = gradientFilter.GetOutput() else: normalFilter = vtk.vtkPolyDataNormals() - normalFilter.SetInputConnection(pointDataToCellData.GetOutputPort()) + normalFilter.SetInputData(model_cell_data) normalFilter.ComputeCellNormalsOn() normalFilter.ComputePointNormalsOff() normalFilter.SplittingOff() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py index 08b97a2..77513a0 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_calculate_gradient.py @@ -24,20 +24,20 @@ specific language governing permissions and limitations under the License. """ -import numpy as np -import vtk -from vtk.numpy_interface import dataset_adapter as dsa import os +import vtk + +from vtk_opencarp_helper_methods.vtk_methods.converters import convert_point_to_cell_data +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer + def ra_calculate_gradient(args, model, job): name_list = ['phi', 'r', 'v', 'ab', 'w'] # change the result of Laplace from points data to cell data - pointDataToCellData = vtk.vtkPointDataToCellData() - pointDataToCellData.PassPointDataOn() - pointDataToCellData.SetInputData(model) - pointDataToCellData.Update() + + model_with_cell_data = convert_point_to_cell_data(model) for var in name_list: print('Calculating the gradient of ' + str(var) + '...') @@ -45,7 +45,7 @@ def ra_calculate_gradient(args, model, job): # using the vtkGradientFilter to calculate the gradient if args.mesh_type == "vol": gradientFilter = vtk.vtkGradientFilter() - gradientFilter.SetInputData(pointDataToCellData.GetOutput()) + gradientFilter.SetInputData(model_with_cell_data) gradientFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "phie_" + str(var)) gradientFilter.SetResultArrayName('grad_' + str(var)) @@ -53,7 +53,7 @@ def ra_calculate_gradient(args, model, job): RA_gradient = gradientFilter.GetOutput() else: normalFilter = vtk.vtkPolyDataNormals() - normalFilter.SetInputConnection(pointDataToCellData.GetOutputPort()) + normalFilter.SetInputData(model_with_cell_data) normalFilter.ComputeCellNormalsOn() normalFilter.ComputePointNormalsOff() normalFilter.SplittingOff() diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 288e082..02be8ce 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -33,7 +33,7 @@ from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr -from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -48,16 +48,7 @@ def low_vol_LAT(args, path): bilayer_n_cells = model.GetNumberOfCells() # Transfer lat and bipolar voltage from points to elements - pt_cell = vtk.vtkPointDataToCellData() - pt_cell.SetInputData(model) - pt_cell.AddPointDataArray("bi") - pt_cell.AddPointDataArray("lat") - pt_cell.PassPointDataOn() - pt_cell.CategoricalDataOff() - pt_cell.ProcessAllArraysOff() - pt_cell.Update() - - model = pt_cell.GetOutput() + model = convert_point_to_cell_data(model, ["bi"], ["lat"]) # Create Points and Cells ids cellid = vtk.vtkIdFilter() diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index 692331b..6353dd4 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -25,7 +25,7 @@ under the License. """ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon -from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer EXAMPLE_DESCRIPTIVE_NAME = 'Tune conductivities to fit clinical LAT map' @@ -586,15 +586,8 @@ def run(args, job): meshNew = dsa.WrapDataObject(new_endo) # Convert point to cell data meshNew.PointData.append(lats, "lat_s") - pt_cell = vtk.vtkPointDataToCellData() - pt_cell.SetInputData(meshNew.VTKObject) - pt_cell.AddPointDataArray("lat_s") - pt_cell.PassPointDataOn() - pt_cell.CategoricalDataOff() - pt_cell.ProcessAllArraysOff() - pt_cell.Update() - - model = pt_cell.GetOutput() + + model = convert_point_to_cell_data(meshNew.VTKObject, ["lat_s"]) meshNew = dsa.WrapDataObject(model) # Extract all not fibrotic tissue (103 is not conductive) healthy_endo = Methods_fit_to_clinical_LAT.vtk_thr(model, 1, "CELLS", "elemTag", 102) @@ -791,16 +784,11 @@ def run(args, job): meshNew = dsa.WrapDataObject(new_endo) meshNew.PointData.append(lats, "lat_s") - pt_cell = vtk.vtkPointDataToCellData() - pt_cell.SetInputData(meshNew.VTKObject) - pt_cell.AddPointDataArray("lat_s") - pt_cell.PassPointDataOn() - pt_cell.CategoricalDataOff() - pt_cell.ProcessAllArraysOff() - pt_cell.Update() + + mesh_with_cell_data = convert_point_to_cell_data(meshNew.VTKObject, ["lat_s"]) meshNew.CellData.append(LAT_map, "LAT_to_clean") - LATs_diff = vtk_to_numpy(pt_cell.GetOutput().GetCellData().GetArray('lat_s')) - LAT_map + LATs_diff = vtk_to_numpy(mesh_with_cell_data.GetCellData().GetArray('lat_s')) - LAT_map meshNew.CellData.append(slow_CV, "slow_CV") meshNew.CellData.append(LATs_diff, "LATs_diff") From 990983a7dc3b1732d56e47336e520fcea7cc451a Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 15:07:51 +0100 Subject: [PATCH 26/70] Included geometry filter encapsulation --- .../Generate_Boundaries/extract_rings.py | 40 ++++------- .../extract_rings_TOP_epi_endo.py | 20 ++---- .../Generate_Boundaries/separate_epi_endo.py | 1 + Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 43 +++++------- .../LDRBM/Fiber_LA/la_generate_fiber.py | 7 +- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 49 +++++--------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 25 +++---- .../LDRBM/Fiber_RA/create_bridges_test.py | 27 +++----- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 67 +++++++------------ standalones/function.py | 13 ++-- standalones/open_orifices_manually.py | 7 +- standalones/open_orifices_with_curvature.py | 25 +++---- .../Methods_fit_to_clinical_LAT.py | 7 +- 13 files changed, 119 insertions(+), 212 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index d797166..b092225 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -39,6 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -90,12 +91,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i print('Extracting rings...') mesh_surf = smart_reader(mesh) - - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(mesh_surf) - geo_filter.Update() - - mesh_surf = geo_filter.GetOutput() + mesh_surf = apply_vtk_geom_filter(mesh_surf) centroids = dict() @@ -126,7 +122,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i centroids["RAA_base"] = RA_bs_point connect = vtk.vtkConnectivityFilter() - connect.SetInputConnection(geo_filter.GetOutputPort()) + connect.SetInputData(mesh_surf) connect.SetExtractionModeToAllRegions() connect.ColorRegionsOn() connect.Update() @@ -224,7 +220,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) elif RAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir + '/LA.vtk'.format(mesh)) + vtkWrite(mesh_surf, outdir + '/LA.vtk'.format(mesh)) LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) centroids["LAA"] = LA_ap_point array_name = "Ids" @@ -251,10 +247,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) elif LAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir + '/RA.vtk'.format(mesh)) + vtkWrite(mesh_surf, outdir + '/RA.vtk'.format(mesh)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) + idFilter.SetInputData(mesh_surf) if int(vtk_version) >= 9: idFilter.SetPointIdsArrayName('Ids') idFilter.SetCellIdsArrayName('Ids') @@ -313,10 +309,8 @@ def detect_and_mark_rings(surf, ap_point, outdir, debug): surface = connect.GetOutput() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -699,10 +693,8 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(model) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(model) + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(surface) @@ -731,10 +723,8 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): gamma_top = boundaryEdges.GetOutput() if debug: - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(gamma_top) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(gamma_top) + vtkWrite(surface, outdir + '/gamma_top.vtk') """ @@ -928,10 +918,8 @@ def create_pts(array_points, array_name, mesh_dir): def to_polydata(mesh): - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(mesh) - geo_filter.Update() - polydata = geo_filter.GetOutput() + polydata = apply_vtk_geom_filter(mesh) + return polydata diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 9915446..eda1b37 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -39,6 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -304,10 +305,7 @@ def detect_and_mark_rings(surf, ap_point): surface = connect.GetOutput() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -670,12 +668,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): ivc_center = np.array(r.center) ivc = r.vtk_polydata - initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) + plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) + + surface = apply_vtk_geom_filter(model) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(model) - geo_filter.Update() - surface = geo_filter.GetOutput() meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(surface) @@ -715,10 +711,8 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): endo = idFilter.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(endo) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(endo) + meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(surface) diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index 6ac2b0e..7cc31b1 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -3,6 +3,7 @@ import vtk +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between sys.path.append('Atrial_LDRBM/Generate_Boundaries') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index ef12987..2f5a645 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -37,6 +37,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -272,10 +273,8 @@ def dijkstra_path_on_a_plane(polydata, StartVertex, EndVertex, plane_point): meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() band = meshExtractFilter2.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(band) - geo_filter.Update() - band = geo_filter.GetOutput() + band = apply_vtk_geom_filter(band) + # print(band) loc = vtk.vtkPointLocator() loc.SetDataSet(band) @@ -565,10 +564,8 @@ def extract_largest_region(mesh): connect.Update() surface = connect.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -678,15 +675,11 @@ def get_connection_point_la_and_ra(appen_point): la_connect_point = bb_aux_l_points[int(length * 0.5)] # ra - geo_filter_la = vtk.vtkGeometryFilter() - geo_filter_la.SetInputData(la_epi_surface) - geo_filter_la.Update() - la_epi_surface = geo_filter_la.GetOutput() + la_epi_surface = apply_vtk_geom_filter(la_epi_surface) + + + ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - geo_filter_ra = vtk.vtkGeometryFilter() - geo_filter_ra.SetInputData(ra_epi_surface) - geo_filter_ra.Update() - ra_epi_surface = geo_filter_ra.GetOutput() loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi_surface) @@ -1007,10 +1000,8 @@ def distinguish_PVs(connect, PVs, df, name1, name2): single_PV = connect.GetOutput() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(single_PV) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(single_PV) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -1026,18 +1017,14 @@ def distinguish_PVs(connect, PVs, df, name1, name2): found, val = optimize_shape_PV(surface, 10, 0) if found: single_PV = vtk_thr(single_PV, 1, "CELLS", "phie_v", val) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(single_PV) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(single_PV) + elif name1.startswith("R") and phie_v < 0.9: # 0.975 found, val = optimize_shape_PV(surface, 10, 1) if found: single_PV = vtk_thr(single_PV, 0, "CELLS", "phie_v", val) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(single_PV) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(single_PV) + centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(surface) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index a56ca74..821683a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -40,6 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -467,10 +468,8 @@ def la_generate_fiber(model, args, job): # Bachmann Bundle if args.mesh_type == "vol": # Extract epicardial surface - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(model) - geo_filter.Update() - surf = geo_filter.GetOutput() + surf = apply_vtk_geom_filter(model) + epi_surf = vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) epi_surf_ids = vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 986ce5a..9b69173 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -35,6 +35,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -61,10 +62,8 @@ def downsample_path(points_data, step): def move_surf_along_normals(mesh, eps, direction): - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(mesh) - extract_surf.Update() - polydata = extract_surf.GetOutput() + polydata = apply_vtk_geom_filter(mesh) + normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) @@ -203,10 +202,8 @@ def generate_sheet_dir(args, model, job): ''' extract the surface ''' - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(model) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(model) + cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(surface) @@ -733,10 +730,8 @@ def extract_largest_region(mesh): connect.Update() surface = connect.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -840,15 +835,11 @@ def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_in la_connect_point = bb_aux_l_points[int(length * 0.5)] # ra - geo_filter_la = vtk.vtkGeometryFilter() - geo_filter_la.SetInputData(la_epi_surface) - geo_filter_la.Update() - la_epi_surface = geo_filter_la.GetOutput() + la_epi_surface = apply_vtk_geom_filter(la_epi_surface) + + + ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - geo_filter_ra = vtk.vtkGeometryFilter() - geo_filter_ra.SetInputData(ra_epi_surface) - geo_filter_ra.Update() - ra_epi_surface = geo_filter_ra.GetOutput() loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi_surface) @@ -903,15 +894,11 @@ def get_connection_point_la_and_ra(appen_point): la_connect_point = bb_aux_l_points[int(length * 0.5)] # ra - geo_filter_la = vtk.vtkGeometryFilter() - geo_filter_la.SetInputData(la_epi_surface) - geo_filter_la.Update() - la_epi_surface = geo_filter_la.GetOutput() + la_epi_surface = apply_vtk_geom_filter(la_epi_surface) + + + ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - geo_filter_ra = vtk.vtkGeometryFilter() - geo_filter_ra.SetInputData(ra_epi_surface) - geo_filter_ra.Update() - ra_epi_surface = geo_filter_ra.GetOutput() loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi_surface) @@ -1017,10 +1004,8 @@ def create_pts(array_points, array_name, mesh_dir): def to_polydata(mesh): - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(mesh) - geo_filter.Update() - polydata = geo_filter.GetOutput() + polydata = apply_vtk_geom_filter(mesh) + return polydata diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index b88fae2..5f9b005 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -41,6 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -69,15 +70,11 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): mitral_valve_epi = int(tag_dict["mitral_valve_epi"]) tricuspid_valve_epi = int(tag_dict["tricuspid_valve_epi"]) - geo_filter_la = vtk.vtkGeometryFilter() - geo_filter_la.SetInputData(la_epi) - geo_filter_la.Update() - la_epi_surface = geo_filter_la.GetOutput() + la_epi_surface = apply_vtk_geom_filter(la_epi) + + + ra_epi_surface = apply_vtk_geom_filter(ra_epi) - geo_filter_ra = vtk.vtkGeometryFilter() - geo_filter_ra.SetInputData(ra_epi) - geo_filter_ra.Update() - ra_epi_surface = geo_filter_ra.GetOutput() SVC_p = np.array(df["SVC"]) IVC_p = np.array(df["IVC"]) @@ -156,16 +153,12 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") - geo_filter_la_epi = vtk.vtkGeometryFilter() - geo_filter_la_epi.SetInputData(la_e) - geo_filter_la_epi.Update() - la_e = geo_filter_la_epi.GetOutput() + la_e = apply_vtk_geom_filter(la_e) + ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") - geo_filter_ra_epi = vtk.vtkGeometryFilter() - geo_filter_ra_epi.SetInputData(ra_e) - geo_filter_ra_epi.Update() - ra_e = geo_filter_ra_epi.GetOutput() + ra_e = apply_vtk_geom_filter(ra_e) + append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_e) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index eafb032..f6d47f1 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -36,13 +36,14 @@ import vtk from carputils import tools from vtk.numpy_interface import dataset_adapter as dsa -from vtk.util.numpy_support import vtk_to_numpy import Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon +from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ vtk_unstructured_grid_writer, vtk_obj_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -119,17 +120,13 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): tricuspid_valve_epi = int(tag_dict["tricuspid_valve_epi"]) # la_epi = vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) - geo_filter_la = vtk.vtkGeometryFilter() - geo_filter_la.SetInputData(la_epi) - geo_filter_la.Update() - la_epi_surface = geo_filter_la.GetOutput() + la_epi_surface = apply_vtk_geom_filter(la_epi) + # ra_epi = vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) - geo_filter_ra = vtk.vtkGeometryFilter() - geo_filter_ra.SetInputData(ra_epi) - geo_filter_ra.Update() - ra_epi_surface = geo_filter_ra.GetOutput() + ra_epi_surface = apply_vtk_geom_filter(ra_epi) + SVC_p = np.array(df["SVC"]) IVC_p = np.array(df["IVC"]) @@ -204,16 +201,12 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") - geo_filter_la_epi = vtk.vtkGeometryFilter() - geo_filter_la_epi.SetInputData(la_e) - geo_filter_la_epi.Update() - la_e = geo_filter_la_epi.GetOutput() + la_e = apply_vtk_geom_filter(la_e) + ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") - geo_filter_ra_epi = vtk.vtkGeometryFilter() - geo_filter_ra_epi.SetInputData(ra_e) - geo_filter_ra_epi.Update() - ra_e = geo_filter_ra_epi.GetOutput() + ra_e = apply_vtk_geom_filter(ra_e) + append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_e) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index b221f80..974896a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -40,6 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -273,10 +274,8 @@ def ra_generate_fiber(model, args, job): Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band.vtk") Method.writer_vtk(CT_ub, f'{args.mesh}_surf/' + "ct_ub.vtk") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(CT_band) - geo_filter.Update() - mesh_surf = geo_filter.GetOutput() + mesh_surf = apply_vtk_geom_filter(CT_band) + loc = vtk.vtkPointLocator() loc.SetDataSet(mesh_surf) @@ -323,10 +322,8 @@ def ra_generate_fiber(model, args, job): IVC_CT_pt_id = loc.FindClosestPoint(np.array(IVC_CT_pt)) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(no_IVC_s) - geo_filter.Update() - no_IVC_s = geo_filter.GetOutput() + no_IVC_s = apply_vtk_geom_filter(no_IVC_s) + loc = vtk.vtkPointLocator() loc.SetDataSet(no_IVC_s) @@ -642,10 +639,8 @@ def ra_generate_fiber(model, args, job): point3_id = loc.FindClosestPoint(IVC_max_r_CT_pt) point4_id = loc.FindClosestPoint(np.array(df["RAA"])) # this is also the id for Bachmann-Bundle on the right atrium - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(CT) - geo_filter.Update() - CT = geo_filter.GetOutput() + CT = apply_vtk_geom_filter(CT) + # calculate the norm vector v1 = np.array(df["IVC"]) - np.array(df["SVC"]) @@ -664,10 +659,8 @@ def ra_generate_fiber(model, args, job): meshExtractFilter.Update() TV_lat = meshExtractFilter.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(TV_lat) - geo_filter.Update() - TV_lat = geo_filter.GetOutput() + TV_lat = apply_vtk_geom_filter(TV_lat) + cln = vtk.vtkCleanPolyData() cln.SetInputData(TV_lat) @@ -703,29 +696,23 @@ def ra_generate_fiber(model, args, job): tag_old = np.array(tag, dtype=int) el_old = np.array(el) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(model) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(model) + epi = vtk_thr(surface, 0, "POINTS", "phie_phi", 0.5) endo = vtk_thr(surface, 1, "POINTS", "phie_phi", 0.5) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(endo) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(endo) + elif args.mesh_type == "bilayer": fiber_endo = el.copy() tag_endo = np.copy(tag) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(endo) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(endo) + loc = vtk.vtkPointLocator() loc.SetDataSet(surface) @@ -914,10 +901,8 @@ def ra_generate_fiber(model, args, job): # Bachmann-Bundle if args.mesh_type == "vol": - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(epi) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(epi) + loc = vtk.vtkPointLocator() loc.SetDataSet(RAS_S) @@ -1010,10 +995,8 @@ def ra_generate_fiber(model, args, job): else: la = Method.smart_reader(meshname + "_LA_vol_fibers/result_LA/LA_vol_with_fiber.vtu") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(la) - geo_filter.Update() - la_surf = geo_filter.GetOutput() + la_surf = apply_vtk_geom_filter(la) + la_epi = vtk_thr(la_surf, 2, "CELLS", "elemTag", left_atrial_wall_epi, 99) @@ -1023,16 +1006,12 @@ def ra_generate_fiber(model, args, job): length = len(bachmann_bundle_points_data) ra_bb_center = bachmann_bundle_points_data[int(length * 0.45)] - geo_filter_la_epi = vtk.vtkGeometryFilter() - geo_filter_la_epi.SetInputData(la_epi) - geo_filter_la_epi.Update() - la_epi = geo_filter_la_epi.GetOutput() + la_epi = apply_vtk_geom_filter(la_epi) + if args.mesh_type == "bilayer": - geo_filter_ra_epi = vtk.vtkGeometryFilter() - geo_filter_ra_epi.SetInputData(model) - geo_filter_ra_epi.Update() - ra_epi = geo_filter_ra_epi.GetOutput() + ra_epi = apply_vtk_geom_filter(model) + else: ra_epi = surface diff --git a/standalones/function.py b/standalones/function.py index dafdcb7..31987c6 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -31,14 +31,13 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane def to_polydata(mesh): - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(mesh) - geo_filter.Update() - polydata = geo_filter.GetOutput() + polydata = apply_vtk_geom_filter(mesh) + return polydata @@ -139,10 +138,8 @@ def cut_a_band_from_model(polydata, point_1, point_2, point_3, width): meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() band = meshExtractFilter2.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(band) - geo_filter.Update() - band = geo_filter.GetOutput() + band = apply_vtk_geom_filter(band) + return band diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 85cb3af..194d366 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -39,6 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_mesh_with_radius from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper @@ -185,10 +186,8 @@ def extract_largest_region(mesh): connect.Update() surface = connect.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 57fcb1d..9955441 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -42,6 +42,7 @@ from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -274,10 +275,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu surface = connect.GetOutput() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -306,10 +305,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu surface2 = connect2.GetOutput() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface2) - geo_filter.Update() - surface2 = geo_filter.GetOutput() + surface2 = apply_vtk_geom_filter(surface2) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface2) @@ -432,10 +429,8 @@ def extract_largest_region(mesh): connect.Update() surface = connect.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -489,10 +484,8 @@ def create_pts(array_points, array_name, mesh_dir): def to_polydata(mesh): - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(mesh) - geo_filter.Update() - polydata = geo_filter.GetOutput() + polydata = apply_vtk_geom_filter(mesh) + return polydata diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 02be8ce..43531a4 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -35,6 +35,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -448,10 +449,8 @@ def extract_largest_region(mesh): connect.Update() surface = connect.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(surface) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(surface) + cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) From c1b4b1e940b650d0576ea0a4613d78cc1724072a Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 15:24:06 +0100 Subject: [PATCH 27/70] Further included geometry filter encapsulation --- .../Generate_Boundaries/extract_rings.py | 24 ++++++------- .../extract_rings_TOP_epi_endo.py | 34 +++++++++---------- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 12 ++----- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 15 ++------ pipeline.py | 6 ++-- standalones/open_orifices_with_curvature.py | 10 +++--- standalones/prealign_meshes.py | 9 ++--- .../Methods_fit_to_clinical_LAT.py | 32 ++++++++--------- 8 files changed, 56 insertions(+), 86 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index b092225..d185fff 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -39,7 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -143,12 +143,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i warning("WARNING: Should be checkt for functionality extract_rings l151") thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thr.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) + idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: idFilter.SetPointIdsArrayName('Ids') idFilter.SetCellIdsArrayName('Ids') @@ -182,12 +180,12 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thr.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) + + idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) + idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: idFilter.SetPointIdsArrayName('Ids') idFilter.SetCellIdsArrayName('Ids') @@ -857,14 +855,14 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thresh.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(thresh.GetOutputPort(), True) + + mv_id = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] connect = vtk.vtkConnectivityFilter() - connect.SetInputData(geo_filter.GetOutput()) + connect.SetInputData(geo_port) connect.SetExtractionModeToSpecifiedRegions() connect.Update() diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index eda1b37..e745028 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -39,7 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -147,12 +147,12 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" warning("WARNING: Should be checkt for functionality extract_rings_TOP_epi_endo l145") thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thr.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) + + idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) + idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: idFilter.SetPointIdsArrayName('Ids') idFilter.SetCellIdsArrayName('Ids') @@ -186,12 +186,12 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thr.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) + + idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) + idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: idFilter.SetPointIdsArrayName('Ids') idFilter.SetCellIdsArrayName('Ids') @@ -921,12 +921,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thresh.GetOutputPort()) - geo_filter.Update() + thresh_geo=apply_vtk_geom_filter(thresh.GetOutputPort(), True) + + connect = vtk.vtkConnectivityFilter() - connect.SetInputData(geo_filter.GetOutput()) + connect.SetInputData(thresh_geo) connect.SetExtractionModeToSpecifiedRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() @@ -979,14 +979,14 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thresh.GetOutputPort()) - geo_filter.Update() + thresh_geo = get_vtk_geom_filter_port(thresh.GetOutputPort(), True) + + mv_id_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] connect = vtk.vtkConnectivityFilter() - connect.SetInputData(geo_filter.GetOutput()) + connect.SetInputData(thresh_geo) connect.SetExtractionModeToSpecifiedRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 2f5a645..af8260f 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -37,7 +37,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -566,7 +566,6 @@ def extract_largest_region(mesh): surface = apply_vtk_geom_filter(surface) - cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() @@ -677,10 +676,8 @@ def get_connection_point_la_and_ra(appen_point): # ra la_epi_surface = apply_vtk_geom_filter(la_epi_surface) - ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi_surface) loc_la_epi.BuildLocator() @@ -847,12 +844,9 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e inf_appendage_basis = LAA.GetPoint(ptIds.GetId(0)) # Extract the border of the LAA - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(thresh.GetOutputPort()) - geo_filter.Update() boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(geo_filter.GetOutput()) + boundaryEdges.SetInputData(apply_vtk_geom_filter(thresh.GetOutputPort(), True)) boundaryEdges.BoundaryEdgesOn() boundaryEdges.FeatureEdgesOff() boundaryEdges.ManifoldEdgesOff() @@ -1002,7 +996,6 @@ def distinguish_PVs(connect, PVs, df, name1, name2): # Clean unused points surface = apply_vtk_geom_filter(single_PV) - cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() @@ -1025,7 +1018,6 @@ def distinguish_PVs(connect, PVs, df, name1, name2): single_PV = vtk_thr(single_PV, 0, "CELLS", "phie_v", val) surface = apply_vtk_geom_filter(single_PV) - centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(surface) centerOfMassFilter.SetUseScalarsAsWeights(False) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 9b69173..659f0e6 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -35,7 +35,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -64,7 +64,6 @@ def downsample_path(points_data, step): def move_surf_along_normals(mesh, eps, direction): polydata = apply_vtk_geom_filter(mesh) - normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) normalGenerator.ComputeCellNormalsOff() @@ -89,14 +88,12 @@ def move_surf_along_normals(mesh, eps, direction): def generate_bilayer(args, job, endo, epi, max_dist=np.inf): - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(endo) - extract_surf.Update() + geo_port, _geo_filter=get_vtk_geom_filter_port(endo) reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() - reverse.SetInputConnection(extract_surf.GetOutputPort()) + reverse.SetInputConnection(geo_port) reverse.Update() endo = vtk.vtkUnstructuredGrid() @@ -204,7 +201,6 @@ def generate_sheet_dir(args, model, job): ''' surface = apply_vtk_geom_filter(model) - cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(surface) cleaner.Update() @@ -732,7 +728,6 @@ def extract_largest_region(mesh): surface = apply_vtk_geom_filter(surface) - cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() @@ -837,10 +832,8 @@ def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_in # ra la_epi_surface = apply_vtk_geom_filter(la_epi_surface) - ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi_surface) loc_la_epi.BuildLocator() @@ -896,10 +889,8 @@ def get_connection_point_la_and_ra(appen_point): # ra la_epi_surface = apply_vtk_geom_filter(la_epi_surface) - ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - loc_la_epi = vtk.vtkPointLocator() loc_la_epi.SetDataSet(la_epi_surface) loc_la_epi.BuildLocator() diff --git a/pipeline.py b/pipeline.py index 7ac7d7b..dd23587 100644 --- a/pipeline.py +++ b/pipeline.py @@ -24,6 +24,7 @@ specific language governing permissions and limitations under the License. """ +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter EXAMPLE_DESCRIPTIVE_NAME = 'AugmentA: Patient-specific Augmented Atrial model Generation Tool' EXAMPLE_AUTHOR = 'Luca Azzolin ' @@ -102,10 +103,7 @@ def AugmentA(args): mesh_data = dict() # Make sure that the mesh is a Polydata - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(smart_reader(args.mesh)) - geo_filter.Update() - polydata = geo_filter.GetOutput() + polydata = apply_vtk_geom_filter(smart_reader(args.mesh)) mesh_from_vtk = pv.PolyData(polydata) p = pv.Plotter(notebook=False) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 9955441..6b8ef98 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -42,7 +42,7 @@ from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -331,12 +331,12 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu extract.SetCellList(model_new_el) extract.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(extract.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(extract.GetOutputPort(), True) + + cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_filter.GetOutputPort()) + cleaner.SetInputConnection(geo_port) cleaner.Update() loc_low_V = cleaner.GetOutput() # local low voltage area diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index 08cc8a9..f9c36ad 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -37,6 +37,7 @@ import argparse from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter def parser(): @@ -169,13 +170,7 @@ def vtkreader(meshname): reader.SetFileName(f'{meshname}.vtk') reader.Update() - - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(reader.GetOutputPort()) - geo_filter.Update() - - polydata = geo_filter.GetOutput() - return polydata + return apply_vtk_geom_filter(reader.GetOutputPort(), True) if __name__ == '__main__': diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 43531a4..00ab234 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -35,7 +35,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -90,11 +90,7 @@ def low_vol_LAT(args, path): vtk_xml_unstructured_grid_writer(f'{debug_dir}/low_vol.vtu', low_vol) # Endo - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(model) - geo_filter.Update() - - endo = vtk_thr(geo_filter.GetOutput(), 1, "CELLS", "elemTag", 10) + endo = vtk_thr(apply_vtk_geom_filter(model), 1, "CELLS", "elemTag", 10) if args.debug: vtk_xml_unstructured_grid_writer(f'{debug_dir}/endo.vtu', endo) @@ -232,12 +228,12 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): extract.SetCellList(model_new_el) extract.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(extract.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(extract.GetOutputPort(), True) + + cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_filter.GetOutputPort()) + cleaner.SetInputConnection(geo_port) cleaner.Update() # Mesh of all elements which are not belonging to the clean band @@ -261,12 +257,12 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): connect.AddSpecifiedRegion(n) connect.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(connect.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(connect.GetOutputPort(), True) + + # Clean unused points cln = vtk.vtkCleanPolyData() - cln.SetInputConnection(geo_filter.GetOutputPort()) + cln.SetInputConnection(geo_port) cln.Update() surface = cln.GetOutput() @@ -320,12 +316,12 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): connect.AddSpecifiedRegion(n) connect.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputConnection(connect.GetOutputPort()) - geo_filter.Update() + geo_port, _geo_filter = get_vtk_geom_filter_port(connect.GetOutputPort(), True) + + # Clean unused points cln = vtk.vtkCleanPolyData() - cln.SetInputConnection(geo_filter.GetOutputPort()) + cln.SetInputConnection(geo_port) cln.Update() surface = cln.GetOutput() From 33e255156bd49ce80ab3b700ab4ea4801d7523ce Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 15:34:32 +0100 Subject: [PATCH 28/70] Optimized imports --- .../Generate_Boundaries/generate_mesh.py | 1 - Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py | 5 +-- .../LDRBM/Fiber_LA/la_generate_fiber.py | 4 +- Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py | 2 +- Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py | 4 +- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 2 +- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 14 +++---- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 4 +- Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py | 4 +- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 8 ++-- main.py | 4 +- pipeline.py | 37 ++++++++----------- standalones/getmarks.py | 10 ++--- standalones/open_orifices_with_curvature.py | 2 +- standalones/prealign_meshes.py | 11 ++---- standalones/resample_surf_mesh.py | 15 ++++---- 16 files changed, 53 insertions(+), 74 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py b/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py index 3d9c2ba..b98ae31 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_mesh.py @@ -24,7 +24,6 @@ specific language governing permissions and limitations under the License. """ -import os import subprocess diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py b/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py index 9c5376e..02c6a42 100755 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/array_mapper.py @@ -24,10 +24,9 @@ specific language governing permissions and limitations under the License. """ -import vtk -import Methods_LA as Method from carputils import tools -from vtk.numpy_interface import dataset_adapter as dsa + +import Methods_LA as Method def parser(): diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 821683a..fec6a60 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -33,8 +33,8 @@ import vtk from vtk.numpy_interface import dataset_adapter as dsa -import Methods_LA as Method -from la_laplace import laplace_0_1 +import Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA as Method +from Atrial_LDRBM.LDRBM.Fiber_LA.la_laplace import laplace_0_1 from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py index cb08dce..bc464b3 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_laplace.py @@ -32,7 +32,7 @@ from carputils.carpio import igb from carputils import tools -from la_calculate_gradient import la_calculate_gradient +from Atrial_LDRBM.LDRBM.Fiber_LA.la_calculate_gradient import la_calculate_gradient from vtk.numpy_interface import dataset_adapter as dsa diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py index b29bf39..2dd179b 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py @@ -31,8 +31,8 @@ import vtk from carputils import tools -from la_generate_fiber import la_generate_fiber -from la_laplace import la_laplace +from Atrial_LDRBM.LDRBM.Fiber_LA.la_generate_fiber import la_generate_fiber +from Atrial_LDRBM.LDRBM.Fiber_LA.la_laplace import la_laplace from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 5f9b005..9e5f54f 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -35,7 +35,7 @@ import vtk from vtk.numpy_interface import dataset_adapter as dsa -import Methods_RA as Method +import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index ad821d7..8473826 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -1,18 +1,16 @@ #!/usr/bin/env python3 -import os -import sys +# from scipy import spatial +# import function +# from sklearn.neighbors import NearestNeighbors +import argparse + import numpy as np # from glob import glob # import pandas as pd import vtk -from vtk.util import numpy_support -from vtk.numpy_interface import dataset_adapter as dsa from scipy.spatial import cKDTree -# from scipy import spatial -# import function -# from sklearn.neighbors import NearestNeighbors -import argparse +from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 974896a..7d7f850 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -35,7 +35,7 @@ from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa -import Methods_RA as Method +import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ @@ -45,7 +45,7 @@ EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) -from create_bridges import add_free_bridge +from Atrial_LDRBM.LDRBM.Fiber_RA.create_bridges import add_free_bridge vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py index 0995448..e779089 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py @@ -25,12 +25,12 @@ under the License. """ import os + from carputils import tools -from ra_calculate_gradient import ra_calculate_gradient -import vtk from carputils.carpio import igb from vtk.numpy_interface import dataset_adapter as dsa +from Atrial_LDRBM.LDRBM.Fiber_RA.ra_calculate_gradient import ra_calculate_gradient from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_polydata_writer EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index b766b13..2dbb9a8 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -33,10 +33,10 @@ import vtk from carputils import tools -import Methods_RA as Method -from create_bridges import add_free_bridge -from ra_generate_fiber import ra_generate_fiber -from ra_laplace import ra_laplace +import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method +from Atrial_LDRBM.LDRBM.Fiber_RA.create_bridges import add_free_bridge +from Atrial_LDRBM.LDRBM.Fiber_RA.ra_generate_fiber import ra_generate_fiber +from Atrial_LDRBM.LDRBM.Fiber_RA.ra_laplace import ra_laplace from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy diff --git a/main.py b/main.py index 9beea8e..5e77a6d 100644 --- a/main.py +++ b/main.py @@ -28,9 +28,9 @@ EXAMPLE_DESCRIPTIVE_NAME = 'AugmentA: Patient-specific Augmented Atrial model Generation Tool' EXAMPLE_AUTHOR = 'Luca Azzolin ' -import sys -import os import argparse +import os + from pipeline import AugmentA EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) diff --git a/pipeline.py b/pipeline.py index dd23587..c91ff9c 100644 --- a/pipeline.py +++ b/pipeline.py @@ -24,13 +24,15 @@ specific language governing permissions and limitations under the License. """ +from Atrial_LDRBM.LDRBM.Fiber_LA import la_main +from Atrial_LDRBM.LDRBM.Fiber_RA import ra_main from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader EXAMPLE_DESCRIPTIVE_NAME = 'AugmentA: Patient-specific Augmented Atrial model Generation Tool' EXAMPLE_AUTHOR = 'Luca Azzolin ' import os -import sys from string import Template import numpy as np @@ -38,27 +40,18 @@ import pyvista as pv from scipy.spatial import cKDTree -sys.path.append('standalones') -from open_orifices_with_curvature import open_orifices_with_curvature -from open_orifices_manually import open_orifices_manually -from prealign_meshes import prealign_meshes -from getmarks import get_landmarks -from create_SSM_instance import create_SSM_instance -from resample_surf_mesh import resample_surf_mesh - -import vtk - -sys.path.append('Atrial_LDRBM/Generate_Boundaries') -sys.path.append('Atrial_LDRBM/LDRBM/Fiber_LA') -sys.path.append('Atrial_LDRBM/LDRBM/Fiber_RA') -import la_main -import ra_main -from extract_rings import label_atrial_orifices -from extract_rings import smart_reader -from extract_rings_TOP_epi_endo import label_atrial_orifices_TOP_epi_endo -from separate_epi_endo import separate_epi_endo -from generate_mesh import generate_mesh -from generate_surf_id import generate_surf_id +from standalones.open_orifices_with_curvature import open_orifices_with_curvature +from standalones.open_orifices_manually import open_orifices_manually +from standalones.prealign_meshes import prealign_meshes +from standalones.getmarks import get_landmarks +from standalones.create_SSM_instance import create_SSM_instance +from standalones.resample_surf_mesh import resample_surf_mesh + +from Atrial_LDRBM.Generate_Boundaries.extract_rings import label_atrial_orifices +from Atrial_LDRBM.Generate_Boundaries.extract_rings_TOP_epi_endo import label_atrial_orifices_TOP_epi_endo +from Atrial_LDRBM.Generate_Boundaries.separate_epi_endo import separate_epi_endo +from Atrial_LDRBM.Generate_Boundaries.generate_mesh import generate_mesh +from Atrial_LDRBM.Generate_Boundaries.generate_surf_id import generate_surf_id pv.set_plot_theme('dark') n_cpu = os.cpu_count() diff --git a/standalones/getmarks.py b/standalones/getmarks.py index dd38eab..8b5ae2d 100644 --- a/standalones/getmarks.py +++ b/standalones/getmarks.py @@ -25,17 +25,13 @@ under the License. """ +import argparse + import numpy as np -from glob import glob import pandas as pd import vtk -from vtk.util import numpy_support -from vtk.numpy_interface import dataset_adapter as dsa -from scipy import spatial -import function -from sklearn.neighbors import NearestNeighbors -import argparse +import standalones.function as function from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 6b8ef98..0073094 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -50,7 +50,7 @@ pv.set_plot_theme('dark') sys.path.append('./Atrial_LDRBM/Generate_Boundaries') -from extract_rings import label_atrial_orifices +from Atrial_LDRBM.Generate_Boundaries.extract_rings import label_atrial_orifices vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index f9c36ad..a00fc8a 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -24,17 +24,12 @@ specific language governing permissions and limitations under the License. """ -import os -import numpy as np -from glob import glob +import argparse + import pandas as pd +import transformations as tf import vtk -from vtk.util import numpy_support from vtk.numpy_interface import dataset_adapter as dsa -import datetime -import transformations as tf - -import argparse from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 3da313c..0aa3f33 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -24,17 +24,16 @@ specific language governing permissions and limitations under the License. """ -import pymeshlab -import pymeshfix -import pyvista as pv -import vtk import argparse -from scipy.spatial import cKDTree -from urllib3.filepost import writer -from vtk.util import numpy_support import os + import numpy as np import pandas as pd +import pymeshfix +import pymeshlab +import pyvista as pv +import vtk +from scipy.spatial import cKDTree from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy @@ -296,7 +295,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv def run(): args = parser().parse_args() - resample_surf_mesh(args.mesh, target_mesh_resolution, find_apex_with_curv, scale, size) + resample_surf_mesh(args.mesh, args.target_mesh_resolution, args.find_apex_with_curv, args.scale, args.size) if __name__ == '__main__': From a63e21a38e902e15efab2ca5e6c6cf0e8f8eaf32 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 15:53:51 +0100 Subject: [PATCH 29/70] Further replaced vtkGeometryFilter with encapsulated version --- .../Generate_Boundaries/extract_rings.py | 28 ++-------- .../extract_rings_TOP_epi_endo.py | 44 +++------------- .../Generate_Boundaries/separate_epi_endo.py | 21 ++------ Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 52 +++++-------------- .../LDRBM/Fiber_LA/la_generate_fiber.py | 6 +-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 38 ++++---------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 15 +----- .../LDRBM/Fiber_RA/create_bridges_test.py | 9 +--- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 17 ++---- standalones/prealign_meshes.py | 5 +- standalones/resample_surf_mesh.py | 7 ++- 11 files changed, 53 insertions(+), 189 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index d185fff..e14f427 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -182,8 +182,6 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i thr.Update() geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) - - idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: @@ -309,7 +307,6 @@ def detect_and_mark_rings(surf, ap_point, outdir, debug): # Clean unused points surface = apply_vtk_geom_filter(surface) - cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) cln.Update() @@ -560,10 +557,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) """ here we will extract the feature edge @@ -693,16 +687,12 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): surface = apply_vtk_geom_filter(model) - meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(surface) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) if debug: vtkWrite(surface, outdir + '/cutted_RA.vtk') @@ -733,7 +723,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): plane = initialize_plane(norm_1[0], tv_center) - plane2=initialize_plane(norm_2[0], tv_center) + plane2 = initialize_plane(norm_2[0], tv_center) meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(tv) @@ -746,10 +736,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - tv_f = geo_filter.GetOutput() + tv_f = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' @@ -760,10 +747,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): f.write(f'{i}\n') f.close() - geo_filter2 = vtk.vtkGeometryFilter() - geo_filter2.SetInputData(meshExtractFilter2.GetOutput()) - geo_filter2.Update() - tv_s = geo_filter2.GetOutput() + tv_s = apply_vtk_geom_filter(meshExtractFilter2.GetOutput()) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' @@ -857,8 +841,6 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): geo_port, _geo_filter = get_vtk_geom_filter_port(thresh.GetOutputPort(), True) - - mv_id = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] connect = vtk.vtkConnectivityFilter() diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index e745028..eb84e9f 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -86,13 +86,8 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" """Extrating Rings""" print('Extracting rings...') - mesh_surf = smart_reader(mesh) + mesh_surf = apply_vtk_geom_filter(smart_reader(mesh)) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(mesh_surf) - geo_filter.Update() - - mesh_surf = geo_filter.GetOutput() centroids = dict() @@ -149,8 +144,6 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) - - idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: @@ -188,8 +181,6 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" thr.Update() geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) - - idFilter = vtk.vtkIdFilter() idFilter.SetInputConnection(geo_port) if int(vtk_version) >= 9: @@ -539,10 +530,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) """ here we will extract the feature edge @@ -672,16 +660,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = apply_vtk_geom_filter(model) - meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(surface) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) """ here we will extract the feature edge @@ -713,16 +697,12 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = apply_vtk_geom_filter(endo) - meshExtractFilter = vtk.vtkExtractGeometry() meshExtractFilter.SetInputData(surface) meshExtractFilter.SetImplicitFunction(plane) meshExtractFilter.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) """ here we will extract the feature edge @@ -758,10 +738,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): meshExtractFilter2.SetImplicitFunction(plane2) meshExtractFilter2.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(meshExtractFilter.GetOutput()) - geo_filter.Update() - tv_f = geo_filter.GetOutput() + tv_f = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' @@ -772,10 +749,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): f.write(f'{i}\n') f.close() - geo_filter2 = vtk.vtkGeometryFilter() - geo_filter2.SetInputData(meshExtractFilter2.GetOutput()) - geo_filter2.Update() - tv_s = geo_filter2.GetOutput() + tv_s = apply_vtk_geom_filter(meshExtractFilter2.GetOutput()) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' @@ -921,9 +895,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - thresh_geo=apply_vtk_geom_filter(thresh.GetOutputPort(), True) - - + thresh_geo = apply_vtk_geom_filter(thresh.GetOutputPort(), True) connect = vtk.vtkConnectivityFilter() connect.SetInputData(thresh_geo) @@ -981,8 +953,6 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): thresh_geo = get_vtk_geom_filter_port(thresh.GetOutputPort(), True) - - mv_id_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] connect = vtk.vtkConnectivityFilter() diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index 7cc31b1..37fb6e6 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -1,9 +1,8 @@ import csv import sys -import vtk - from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between sys.path.append('Atrial_LDRBM/Generate_Boundaries') @@ -37,11 +36,7 @@ def separate_epi_endo(path, atrium): else: raise ValueError("Atrium has to be LA or RA") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(thresh.GetOutput()) - geo_filter.Update() - - vtk_obj_writer(meshname + f"_{atrium}.obj", geo_filter.GetOutput()) + vtk_obj_writer(meshname + f"_{atrium}.obj", apply_vtk_geom_filter(thresh.GetOutput())) if atrium == "LA": thresh = get_threshold_between(model, left_atrial_wall_epi, left_atrial_wall_epi, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") @@ -51,10 +46,7 @@ def separate_epi_endo(path, atrium): else: raise ValueError("Atrium has to be LA or RA") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(thresh.GetOutput()) - geo_filter.Update() - la_epi = geo_filter.GetOutput() + la_epi = apply_vtk_geom_filter(thresh.GetOutput()) vtk_obj_writer(meshname + f"_{atrium}_epi.obj", la_epi) if atrium == "LA": @@ -66,9 +58,6 @@ def separate_epi_endo(path, atrium): else: raise ValueError("Atrium has to be LA or RA") - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(thresh.GetOutput()) - geo_filter.Update() - la_endo = geo_filter.GetOutput() + la_endo = apply_vtk_geom_filter(thresh.GetOutput()) - vtk_obj_writer(meshname + f"_{atrium}_endo.obj", la_endo) \ No newline at end of file + vtk_obj_writer(meshname + f"_{atrium}_endo.obj", la_endo) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index af8260f..5b5b2db 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -73,11 +73,7 @@ def mark_LA_endo_elemTag(model, tag, tao_mv, tao_lpv, tao_rpv, max_phie_ab_tau_l def move_surf_along_normals(mesh, eps, direction): - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(mesh) - extract_surf.Update() - - polydata = extract_surf.GetOutput() + polydata = apply_vtk_geom_filter(mesh) normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) @@ -104,14 +100,11 @@ def move_surf_along_normals(mesh, eps, direction): def generate_bilayer(endo, epi): - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(epi) - extract_surf.Update() - + geo_port, _geo_filter = get_vtk_geom_filter_port(epi) reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() - reverse.SetInputConnection(extract_surf.GetOutputPort()) + reverse.SetInputConnection(geo_port) reverse.Update() epi = vtk.vtkUnstructuredGrid() @@ -509,10 +502,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, connect.Update() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(connect.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(connect.GetOutput()) cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -526,10 +516,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, connect.Update() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(connect.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(connect.GetOutput()) cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -665,11 +652,7 @@ def get_connection_point_la_and_ra(appen_point): point_1_id_endo = loc_endo.FindClosestPoint(point_1) point_2_id_endo = loc_endo.FindClosestPoint(point_2) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(endo) - geo_filter.Update() - - bb_aux_l_points = dijkstra_path(geo_filter.GetOutput(), point_1_id_endo, point_2_id_endo) + bb_aux_l_points = dijkstra_path(apply_vtk_geom_filter(endo), point_1_id_endo, point_2_id_endo) length = len(bb_aux_l_points) la_connect_point = bb_aux_l_points[int(length * 0.5)] @@ -798,12 +781,8 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): point_l1 = la_mv_surface.GetPoint(point_l1_id) bb_mv_id = loc_epi.FindClosestPoint(point_l1) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(epi) - geo_filter.Update() - - bb_1_points = dijkstra_path(geo_filter.GetOutput(), lpv_sup_basis_id, appendage_basis_id) - bb_2_points = dijkstra_path(geo_filter.GetOutput(), appendage_basis_id, bb_mv_id) + bb_1_points = dijkstra_path(apply_vtk_geom_filter(epi), lpv_sup_basis_id, appendage_basis_id) + bb_2_points = dijkstra_path(apply_vtk_geom_filter(epi), appendage_basis_id, bb_mv_id) np.delete(bb_1_points, -1) bb_left = np.concatenate((bb_1_points, bb_2_points), axis=0) @@ -900,13 +879,11 @@ def get_in_surf1_closest_point_in_surf2(surf1, surf2, pt_id_in_surf2): def get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id): - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(epi) - geo_filter.Update() + poly_mesh_epi = apply_vtk_geom_filter(epi) - bb_1_points = dijkstra_path(geo_filter.GetOutput(), sup_appendage_basis_id, LAA_pt_far_from_LIPV_id) - bb_2_points = dijkstra_path(geo_filter.GetOutput(), LAA_pt_far_from_LIPV_id, inf_appendage_basis_id) - bb_3_points = dijkstra_path(geo_filter.GetOutput(), inf_appendage_basis_id, bb_mv_id) + bb_1_points = dijkstra_path(poly_mesh_epi, sup_appendage_basis_id, LAA_pt_far_from_LIPV_id) + bb_2_points = dijkstra_path(poly_mesh_epi, LAA_pt_far_from_LIPV_id, inf_appendage_basis_id) + bb_3_points = dijkstra_path(poly_mesh_epi, inf_appendage_basis_id, bb_mv_id) np.delete(bb_1_points, -1) bb_left = np.concatenate((bb_1_points, bb_2_points, bb_3_points), axis=0) @@ -1054,12 +1031,9 @@ def optimize_shape_PV(surface, num, bound): out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l], arr[l + 1]) else: out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l + 1], arr[l]) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(out) - geo_filter.Update() centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(geo_filter.GetOutput()) + centerOfMassFilter.SetInputData(apply_vtk_geom_filter(out)) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index fec6a60..e5c9fca 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -473,11 +473,7 @@ def la_generate_fiber(model, args, job): epi_surf = vtk_thr(surf, 0, "CELLS", "phie_phi", 0.5) epi_surf_ids = vtk_to_numpy(epi_surf.GetCellData().GetArray('Global_ids')) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(epi_surf) - geo_filter.Update() - - epi_surf = geo_filter.GetOutput() + epi_surf = apply_vtk_geom_filter(epi_surf) if args.mesh_type == "bilayer": bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi, df, diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 659f0e6..2565b30 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -88,7 +88,7 @@ def move_surf_along_normals(mesh, eps, direction): def generate_bilayer(args, job, endo, epi, max_dist=np.inf): - geo_port, _geo_filter=get_vtk_geom_filter_port(endo) + geo_port, _geo_filter = get_vtk_geom_filter_port(endo) reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() @@ -401,11 +401,9 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point meshExtractFilter2.Update() band = meshExtractFilter2.GetOutput() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(band) - geo_filter.Update() + cln = vtk.vtkCleanPolyData() - cln.SetInputData(geo_filter.GetOutput()) + cln.SetInputData(apply_vtk_geom_filter(band)) cln.Update() band = cln.GetOutput() @@ -671,10 +669,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, connect.Update() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(connect.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(connect.GetOutput()) cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -688,10 +683,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, connect.Update() # Clean unused points - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(connect.GetOutput()) - geo_filter.Update() - surface = geo_filter.GetOutput() + surface = apply_vtk_geom_filter(connect.GetOutput()) cln = vtk.vtkCleanPolyData() cln.SetInputData(surface) @@ -821,11 +813,7 @@ def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_in point_1_id = loc.FindClosestPoint(point_1) point_2_id = loc.FindClosestPoint(point_2) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(la_epi_surface) - geo_filter.Update() - - bb_aux_l_points = dijkstra_path(geo_filter.GetOutput(), point_1_id, point_2_id) + bb_aux_l_points = dijkstra_path(apply_vtk_geom_filter(la_epi_surface), point_1_id, point_2_id) length = len(bb_aux_l_points) la_connect_point = bb_aux_l_points[int(length * 0.5)] @@ -878,11 +866,7 @@ def get_connection_point_la_and_ra(appen_point): point_1_id_endo = loc_endo.FindClosestPoint(point_1) point_2_id_endo = loc_endo.FindClosestPoint(point_2) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(endo) - geo_filter.Update() - - bb_aux_l_points = dijkstra_path(geo_filter.GetOutput(), point_1_id_endo, point_2_id_endo) + bb_aux_l_points = dijkstra_path(apply_vtk_geom_filter(endo), point_1_id_endo, point_2_id_endo) length = len(bb_aux_l_points) la_connect_point = bb_aux_l_points[int(length * 0.5)] @@ -930,12 +914,10 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): point_l1 = la_mv_surface.GetPoint(point_l1_id) bb_mv_id = loc_epi.FindClosestPoint(point_l1) - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(epi) - geo_filter.Update() + epi_polydata = apply_vtk_geom_filter(epi) - bb_1_points = dijkstra_path(geo_filter.GetOutput(), lpv_sup_basis_id, appendage_basis_id) - bb_2_points = dijkstra_path(geo_filter.GetOutput(), appendage_basis_id, bb_mv_id) + bb_1_points = dijkstra_path(epi_polydata, lpv_sup_basis_id, appendage_basis_id) + bb_2_points = dijkstra_path(epi_polydata, appendage_basis_id, bb_mv_id) np.delete(bb_1_points, -1) bb_left = np.concatenate((bb_1_points, bb_2_points), axis=0) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 9e5f54f..e0bc1c4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -72,10 +72,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): la_epi_surface = apply_vtk_geom_filter(la_epi) - ra_epi_surface = apply_vtk_geom_filter(ra_epi) - SVC_p = np.array(df["SVC"]) IVC_p = np.array(df["IVC"]) TV_p = np.array(df["TV"]) @@ -122,7 +120,6 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): loc.BuildLocator() point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p + TV_p * 0.1)) # adapt this value if CS is too low - loc = vtk.vtkPointLocator() loc.SetDataSet(ra_septum) loc.BuildLocator() @@ -155,11 +152,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") la_e = apply_vtk_geom_filter(la_e) - ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_e) append_filter.AddInputData(ra_e) @@ -238,10 +233,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(earth_cell_ids) extract.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(extract.GetOutput()) - geo_filter.Update() - earth = geo_filter.GetOutput() + earth = apply_vtk_geom_filter(extract.GetOutput()) cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(earth) @@ -322,10 +314,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(earth_cell_ids) extract.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(extract.GetOutput()) - geo_filter.Update() - earth = geo_filter.GetOutput() + earth = apply_vtk_geom_filter(extract.GetOutput()) cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(earth) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index f6d47f1..ed19a30 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -122,12 +122,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # la_epi = vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) la_epi_surface = apply_vtk_geom_filter(la_epi) - # ra_epi = vtk_thr(la, 0 "CELLS", "elemTag", left_atrial_wall_epi) ra_epi_surface = apply_vtk_geom_filter(ra_epi) - SVC_p = np.array(df["SVC"]) IVC_p = np.array(df["IVC"]) TV_p = np.array(df["TV"]) @@ -203,11 +201,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") la_e = apply_vtk_geom_filter(la_e) - ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - append_filter = vtk.vtkAppendFilter() append_filter.AddInputData(la_e) append_filter.AddInputData(ra_e) @@ -285,10 +281,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(earth_cell_ids) extract.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(extract.GetOutput()) - geo_filter.Update() - earth = geo_filter.GetOutput() + earth = apply_vtk_geom_filter(extract.GetOutput()) cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(earth) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index 8473826..7e504da 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -15,6 +15,7 @@ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port parser = argparse.ArgumentParser(description='Create Right Atrium.') @@ -36,7 +37,6 @@ def run(args): reader.Update() ra_endo = reader.GetOutput() - reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(args.mesh + "/RA_epi_with_fiber.vtk") reader.Update() @@ -53,11 +53,7 @@ def run(args): def move_surf_along_normals(mesh, eps, direction): - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(mesh) - extract_surf.Update() - - polydata = extract_surf.GetOutput() + polydata = apply_vtk_geom_filter(mesh) normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputData(polydata) @@ -83,14 +79,11 @@ def move_surf_along_normals(mesh, eps, direction): def generate_bilayer(endo, epi, max_dist=np.inf): - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(endo) - extract_surf.Update() - + geo_port, _geo_filter = get_vtk_geom_filter_port(endo) reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() - reverse.SetInputConnection(extract_surf.GetOutputPort()) + reverse.SetInputConnection(geo_port) reverse.Update() endo = vtk.vtkUnstructuredGrid() @@ -146,7 +139,7 @@ def generate_bilayer(endo, epi, max_dist=np.inf): # Creates VTK and CARP files: .pts, .lon, .elem def write_bilayer(bilayer): - file_name=args.mesh + "/RA_bilayer_with_fiber" + file_name = args.mesh + "/RA_bilayer_with_fiber" vtk_unstructured_grid_writer(f"{file_name}.vtk", bilayer, store_binary=True) pts = vtk_to_numpy(bilayer.GetPoints().GetData()) diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index a00fc8a..54c53d7 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -67,11 +67,8 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): appendFilter.AddInputData(meshLA) appendFilter.AddInputData(meshRA) appendFilter.Update() - extract_surf = vtk.vtkGeometryFilter() - extract_surf.SetInputData(appendFilter.GetOutput()) - extract_surf.Update() - mesh1 = extract_surf.GetOutput() + mesh1 = apply_vtk_geom_filter(appendFilter.GetOutput()) elif case == "LA": names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV"] # Prealign MRI diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 0aa3f33..df25c1b 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -38,6 +38,7 @@ from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -68,6 +69,7 @@ def parser(): return parser + def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv=0, scale=1, size=30, apex_id=-1, atrium='LA'): mesh_data = dict() @@ -133,10 +135,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv extract.SetCellList(cell_ids_no_bd) extract.Update() - geo_filter = vtk.vtkGeometryFilter() - geo_filter.SetInputData(extract.GetOutput()) - geo_filter.Update() - earth = geo_filter.GetOutput() + earth = apply_vtk_geom_filter(extract.GetOutput()) cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(earth) From 279c1e44738f58ea5c9274049826cc56fd2ce714 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 16:20:12 +0100 Subject: [PATCH 30/70] Added new method to encapsulate cleanPolydata and replaced with vtk implementation --- .../Generate_Boundaries/extract_rings.py | 35 ++++-------- .../extract_rings_TOP_epi_endo.py | 54 ++++--------------- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 26 +++------ Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 33 +++--------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 14 ++--- .../LDRBM/Fiber_RA/create_bridges_test.py | 8 +-- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 6 +-- standalones/function.py | 14 ++--- standalones/open_orifices_manually.py | 10 +--- standalones/open_orifices_with_curvature.py | 35 +++--------- standalones/resample_surf_mesh.py | 14 ++--- .../Methods_fit_to_clinical_LAT.py | 32 +++-------- 12 files changed, 61 insertions(+), 220 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index e14f427..bc5edd9 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -39,7 +39,8 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ + clean_polydata from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -306,11 +307,7 @@ def detect_and_mark_rings(surf, ap_point, outdir, debug): # Clean unused points surface = apply_vtk_geom_filter(surface) - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) # be careful overwrite previous rings if debug: @@ -779,10 +776,8 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): vtkWrite(surface, outdir + f'/gamma_top_{str(i)}.vtk') # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) + points = surface.GetPoints().GetData() points = vtk_to_numpy(points) points = points.tolist() @@ -815,11 +810,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - - top_cut = cln.GetOutput() + top_cut = clean_polydata(surface) if debug: vtkWrite(top_cut, outdir + '/top_endo_epi.vtk') # If this is the CS, then change top_endo_id in 877 @@ -855,10 +846,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): connect.Update() surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) @@ -872,14 +860,9 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): connect.AddSpecifiedRegion(found_id) connect.Update() - surface = connect.GetOutput() - - # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() + surface = clean_polydata(connect.GetOutput()) - top_endo = vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) + top_endo = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') f.write(f'{len(top_endo)}\n') diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index eb84e9f..7e1f21d 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -39,7 +39,8 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ + clean_polydata from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -88,7 +89,6 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" mesh_surf = apply_vtk_geom_filter(smart_reader(mesh)) - centroids = dict() extension = mesh.split('.')[-1] @@ -297,11 +297,7 @@ def detect_and_mark_rings(surf, ap_point): # Clean unused points surface = apply_vtk_geom_filter(surface) - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) ring_surf = vtk.vtkPolyData() ring_surf.DeepCopy(surface) @@ -776,10 +772,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): connect.Update() surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) points = surface.GetPoints().GetData() points = vtk_to_numpy(points) points = points.tolist() @@ -808,11 +801,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - - top_cut_epi = cln.GetOutput() + top_cut_epi = clean_polydata(surface) pts_in_top_epi = vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) @@ -826,10 +815,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): connect.Update() surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) points = surface.GetPoints().GetData() points = vtk_to_numpy(points) points = points.tolist() @@ -858,11 +844,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - - top_cut_endo = cln.GetOutput() + top_cut_endo = clean_polydata(surface) pts_in_top_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids")) pts_in_svc_epi = vtk_to_numpy(svc.GetPointData().GetArray("Ids")) @@ -908,10 +890,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): connect.Update() surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) @@ -928,11 +907,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - - top_epi = vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) + top_epi = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_EPI.vtx' f = open(fname, 'w') f.write(f'{len(top_epi)}\n') @@ -966,10 +941,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): connect.Update() surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) @@ -986,11 +958,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = connect.GetOutput() # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - - top_endo = vtk_to_numpy(cln.GetOutput().GetPointData().GetArray("Ids")) + top_endo = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) fname = outdir + '/ids_TOP_ENDO.vtx' f = open(fname, 'w') f.write(f'{len(top_endo)}\n') diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 5b5b2db..da497b8 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -37,7 +37,8 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ + clean_polydata from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -504,10 +505,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, # Clean unused points surface = apply_vtk_geom_filter(connect.GetOutput()) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - points_data = cln.GetOutput().GetPoints().GetData() + points_data = clean_polydata(surface).GetPoints().GetData() ring = vtk_to_numpy(points_data) center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) @@ -518,10 +516,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, # Clean unused points surface = apply_vtk_geom_filter(connect.GetOutput()) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - points_data = cln.GetOutput().GetPoints().GetData() + points_data = clean_polydata(surface).GetPoints().GetData() ring = vtk_to_numpy(points_data) center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) dis_1 = np.linalg.norm(center_point_1 - tv_ivc_center) @@ -553,12 +548,7 @@ def extract_largest_region(mesh): surface = apply_vtk_geom_filter(surface) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - res = cln.GetOutput() - - return res + return clean_polydata(surface) def assign_ra_appendage(model, SCV, appex_point, tag): @@ -972,11 +962,7 @@ def distinguish_PVs(connect, PVs, df, name1, name2): # Clean unused points surface = apply_vtk_geom_filter(single_PV) - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) if name1.startswith("L"): phie_v = np.max(vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 2565b30..c5c6623 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -35,7 +35,8 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ + clean_polydata from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -200,11 +201,7 @@ def generate_sheet_dir(args, model, job): extract the surface ''' surface = apply_vtk_geom_filter(model) - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputData(surface) - cleaner.Update() - cln_surface = cleaner.GetOutput() + cln_surface = clean_polydata(surface) ''' calculate normals of surface cells @@ -401,11 +398,7 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point meshExtractFilter2.Update() band = meshExtractFilter2.GetOutput() - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(apply_vtk_geom_filter(band)) - cln.Update() - band = cln.GetOutput() + band = clean_polydata(apply_vtk_geom_filter(band)) if args.debug: writer_vtk(band, f'{args.mesh}_surf/' + "band_" + str(StartVertex) + "_" + str(EndVertex) + ".vtk") @@ -670,11 +663,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, # Clean unused points surface = apply_vtk_geom_filter(connect.GetOutput()) - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - points_data = cln.GetOutput().GetPoints().GetData() + points_data = clean_polydata(surface).GetPoints().GetData() ring = vtk_to_numpy(points_data) center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) @@ -685,10 +674,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, # Clean unused points surface = apply_vtk_geom_filter(connect.GetOutput()) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - points_data = cln.GetOutput().GetPoints().GetData() + points_data = clean_polydata(surface).GetPoints().GetData() ring = vtk_to_numpy(points_data) center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) dis_1 = np.linalg.norm(center_point_1 - tv_ivc_center) @@ -720,12 +706,7 @@ def extract_largest_region(mesh): surface = apply_vtk_geom_filter(surface) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - res = cln.GetOutput() - - return res + return clean_polydata(surface) def assign_ra_appendage(model, SCV, appex_point, tag, elemTag): diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index e0bc1c4..deabba5 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -41,7 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -234,11 +234,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.Update() earth = apply_vtk_geom_filter(extract.GetOutput()) - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputData(earth) - cleaner.Update() - earth = cleaner.GetOutput() + earth = clean_polydata(earth) # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) vtk_obj_writer(job.ID + "/bridges/" + str(var) + "_earth.obj", earth) @@ -315,11 +311,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.Update() earth = apply_vtk_geom_filter(extract.GetOutput()) - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputData(earth) - cleaner.Update() - earth = cleaner.GetOutput() + earth = clean_polydata(earth) print("Extracted earth") cell_id_all = [] diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index ed19a30..209abf3 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ vtk_unstructured_grid_writer, vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -282,11 +282,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.Update() earth = apply_vtk_geom_filter(extract.GetOutput()) - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputData(earth) - cleaner.Update() - earth = cleaner.GetOutput() + earth = clean_polydata(earth) # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) vtk_obj_writer(job.ID + "/bridges/" + str(var) + "_earth.obj", earth) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 7d7f850..4b2f200 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -661,11 +661,7 @@ def ra_generate_fiber(model, args, job): TV_lat = apply_vtk_geom_filter(TV_lat) - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(TV_lat) - cln.Update() - TV_lat = cln.GetOutput() + TV_lat = clean_polydata(TV_lat) if args.debug: Method.writer_vtk(TV_lat, f'{args.mesh}_surf/' + "TV_lat.vtk") diff --git a/standalones/function.py b/standalones/function.py index 31987c6..02e59be 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -31,7 +31,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane @@ -140,7 +140,6 @@ def cut_a_band_from_model(polydata, point_1, point_2, point_3, width): band = meshExtractFilter2.GetOutput() band = apply_vtk_geom_filter(band) - return band @@ -189,10 +188,8 @@ def get_mv_l_and_r(mv_band, center_lpv): # Clean unused points surface = to_polydata(connect.GetOutput()) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - points_data = cln.GetOutput().GetPoints().GetData() + + points_data = clean_polydata(surface).GetPoints().GetData() ring = vtk_to_numpy(points_data) center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) @@ -202,10 +199,7 @@ def get_mv_l_and_r(mv_band, center_lpv): # Clean unused points surface = to_polydata(connect.GetOutput()) - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - points_data = cln.GetOutput().GetPoints().GetData() + points_data = clean_polydata(surface).GetPoints().GetData() ring = vtk_to_numpy(points_data) center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) dis_1 = np.linalg.norm(center_point_1 - center_lpv) diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 194d366..476ec86 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -39,7 +39,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_mesh_with_radius from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper @@ -188,13 +188,7 @@ def extract_largest_region(mesh): surface = apply_vtk_geom_filter(surface) - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - res = cln.GetOutput() - - return res + return clean_polydata(surface) def point_array_mapper(mesh1, mesh2, idat): diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 0073094..d6952d3 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -42,7 +42,8 @@ from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ + clean_polydata from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -276,12 +277,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu # Clean unused points surface = apply_vtk_geom_filter(surface) - - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(surface) pt_high_c = list(vtk_to_numpy(surface.GetPointData().GetArray('Ids'))) curv_s = vtk_to_numpy(surface.GetPointData().GetArray('curv')) @@ -306,12 +302,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu # Clean unused points surface2 = apply_vtk_geom_filter(surface2) - - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface2) - cln.Update() - surface2 = cln.GetOutput() + surface2 = clean_polydata(surface2) pt_surf_2 = list(vtk_to_numpy(surface2.GetPointData().GetArray('Ids'))) if len(set(pt_high_c).intersection(pt_surf_2)) > 0: @@ -333,13 +324,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu geo_port, _geo_filter = get_vtk_geom_filter_port(extract.GetOutputPort(), True) - - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_port) - cleaner.Update() - - loc_low_V = cleaner.GetOutput() # local low voltage area + loc_low_V = clean_polydata(geo_port, input_is_connection=True) # local low voltage area loc_low_V = extract_largest_region(loc_low_V) @@ -422,6 +407,7 @@ def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, thr2) + def extract_largest_region(mesh): connect = vtk.vtkConnectivityFilter() connect.SetInputData(mesh) @@ -430,14 +416,7 @@ def extract_largest_region(mesh): surface = connect.GetOutput() surface = apply_vtk_geom_filter(surface) - - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - res = cln.GetOutput() - - return res + return clean_polydata(surface) def point_array_mapper(mesh1, mesh2, idat): diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index df25c1b..2d94b9f 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -38,7 +38,7 @@ from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -137,20 +137,12 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv earth = apply_vtk_geom_filter(extract.GetOutput()) - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputData(earth) - cleaner.Update() - connect = vtk.vtkConnectivityFilter() - connect.SetInputConnection(cleaner.GetOutputPort()) + connect.SetInputData(clean_polydata(earth)) connect.SetExtractionModeToLargestRegion() connect.Update() - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputData(connect.GetOutput()) - cleaner.Update() - - vtk_obj_writer(f'{meshname}_cleaned.obj', cleaner.GetOutput()) + vtk_obj_writer(f'{meshname}_cleaned.obj', clean_polydata(connect.GetOutput())) mesh_data["vol"] = [vol] ms = pymeshlab.MeshSet() diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 00ab234..2e2b646 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -35,7 +35,8 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ + clean_polydata from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -230,14 +231,8 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): geo_port, _geo_filter = get_vtk_geom_filter_port(extract.GetOutputPort(), True) - - - cleaner = vtk.vtkCleanPolyData() - cleaner.SetInputConnection(geo_port) - cleaner.Update() - # Mesh of all elements which are not belonging to the clean band - el_removed = cleaner.GetOutput() + el_removed = clean_polydata(geo_port, input_is_connection=True) # Compute centroids of all elements which are not belonging to the clean band filter_cell_centers = vtk.vtkCellCenters() @@ -259,12 +254,8 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): geo_port, _geo_filter = get_vtk_geom_filter_port(connect.GetOutputPort(), True) - # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputConnection(geo_port) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(geo_port, input_is_connection=True) filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(surface) @@ -318,12 +309,8 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): geo_port, _geo_filter = get_vtk_geom_filter_port(connect.GetOutputPort(), True) - # Clean unused points - cln = vtk.vtkCleanPolyData() - cln.SetInputConnection(geo_port) - cln.Update() - surface = cln.GetOutput() + surface = clean_polydata(geo_port, input_is_connection=True) loc_el_to_clean = vtk_to_numpy(surface.GetCellData().GetArray('Global_ids')).astype(int) @@ -446,11 +433,4 @@ def extract_largest_region(mesh): surface = connect.GetOutput() surface = apply_vtk_geom_filter(surface) - - - cln = vtk.vtkCleanPolyData() - cln.SetInputData(surface) - cln.Update() - res = cln.GetOutput() - - return res + return clean_polydata(surface) From b1ed9d93cd7efe23a50f21c38be9a1a52a6a53d9 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 17:03:10 +0100 Subject: [PATCH 31/70] Included vtk_append from the helper methods and fixed bug from refactoring where mesh data got lost while auto replace --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 11 +-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 14 +--- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 76 ++++++------------- .../LDRBM/Fiber_RA/create_bridges_test.py | 43 +++-------- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 11 +-- standalones/prealign_meshes.py | 11 +-- 6 files changed, 46 insertions(+), 120 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index da497b8..0775074 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -38,7 +38,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, vtk_append from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -145,14 +145,7 @@ def generate_bilayer(endo, epi): fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(endo) - appendFilter.AddInputData(epi) - appendFilter.AddInputData(meshNew.VTKObject) - appendFilter.MergePointsOn() - appendFilter.Update() - - bilayer = appendFilter.GetOutput() + bilayer = vtk_append([endo, epi, meshNew.VTKObject], merge_points=True) return bilayer diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index c5c6623..2263fbb 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -36,7 +36,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, vtk_append from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -146,19 +146,13 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): reader.Update() test = reader.GetOutput() - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(endo) - appendFilter.AddInputData(epi) - appendFilter.AddInputData(test) - appendFilter.MergePointsOn() - appendFilter.Update() - - bilayer = appendFilter.GetOutput() + bilayer = vtk_append([endo, epi, test], True) if args.ofmt == 'vtk': vtk_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtk", bilayer, store_binary=True) else: - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :, bilayer) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu", + bilayer) # Has elemTag! reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index deabba5..ce617dc 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -41,7 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -132,21 +132,17 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): Method.smart_bridge_writer(csb_tube, csb_sphere_1, csb_sphere_2, "coronary_sinus_bridge", job) if args.mesh_type == "vol": - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_epi) - append_filter.AddInputData(ra_epi) - append_filter.Update() - tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) + biatrial_epi = vtk_append([la_epi, ra_epi]) + + tag = np.zeros((biatrial_epi.GetNumberOfCells(),), dtype=int) tag[:la_epi.GetNumberOfCells()] = vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) tag[la_epi.GetNumberOfCells():] = vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) - meshNew = dsa.WrapDataObject(append_filter.GetOutput()) + meshNew = dsa.WrapDataObject(biatrial_epi) meshNew.CellData.append(tag, "elemTag") - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(meshNew.VTKObject) - append_filter.Update() - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", append_filter.GetOutput()) + + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", vtk_append([meshNew.VTKObject])) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") @@ -155,12 +151,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_e) - append_filter.AddInputData(ra_e) - append_filter.Update() # la_ra_usg - - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) + biatrial_e = vtk_append([la_e, ra_e]) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_e) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -255,13 +247,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(la_ra_new) extract.Update() - append_filter = vtk.vtkAppendFilter() - append_filter.MergePointsOn() - # append_filter.SetTolerance(0.01*args.scale) - - append_filter.AddInputData(extract.GetOutput()) - append_filter.Update() # added - la_ra_epi = append_filter.GetOutput() # we lose this mesh, when defining the append filter later + la_ra_epi = vtk_append([extract.GetOutput()], + merge_points=True) # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': # Still has element Tag @@ -328,13 +315,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(la_endo_new) extract.Update() - append_filter = vtk.vtkAppendFilter() - append_filter.MergePointsOn() - # append_filter.SetTolerance(0.01*args.scale) - - append_filter.AddInputData(extract.GetOutput()) - append_filter.Update() # added - la_endo_final = append_filter.GetOutput() # we lose this mesh, when defining the append filter later + la_endo_final = vtk_append([extract.GetOutput()], + merge_points=True) # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_endo_with_holes.vtu", la_endo_final) @@ -470,15 +452,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() up = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(bb) - append_filter.AddInputData(cs) - append_filter.AddInputData(mp) - append_filter.AddInputData(up) - append_filter.Update() - bridges = append_filter.GetOutput() + bridges = vtk_append([bb, cs, mp, up]) - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :, bridges) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_bridges_2.vtu", bridges) # Has elementTag! reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") @@ -490,13 +466,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() bridges = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(la_ra_epi) - append_filter.AddInputData(epi_new) - append_filter.AddInputData(bridges) - # append_filter.MergePointsOn() - append_filter.Update() - epi = append_filter.GetOutput() + epi = vtk_append([epi_new, bridges]) vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_bundles.vtu", epi) epi = Method.generate_sheet_dir(args, epi, job) @@ -504,7 +474,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_sheets.vtu", epi) if args.mesh_type == "bilayer": - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu") # Has elemTag! :, epi) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu", epi) # Has elemTag! reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") # Has elemTag! :) reader.Update() @@ -516,17 +486,15 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() la_endo = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_endo) - append_filter.AddInputData(ra_endo) - append_filter.Update() + bilayer_endo = vtk_append([la_endo, ra_endo]) vtk_xml_unstructured_grid_writer( - job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :, append_filter.GetOutput()) - endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, + job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", bilayer_endo) + # Has elemTag! + endo = Method.move_surf_along_normals(bilayer_endo, 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu") # Has elemTag! :, endo) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu",endo) # Has elemTag! :, bilayer = Method.generate_bilayer(args, job, endo, epi, 0.12 * args.scale) # Does not have elemTag :(! Method.write_bilayer(args, job) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 209abf3..4b41b6a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ vtk_unstructured_grid_writer, vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -180,22 +180,16 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): Method.smart_bridge_writer(csb_tube, csb_sphere_1, csb_sphere_2, "coronary_sinus_bridge", job) if args.mesh_type == "vol": - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_epi) - append_filter.AddInputData(ra_epi) - append_filter.Update() + bilayer_epi = vtk_append([la_epi, ra_epi]) - tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) + tag = np.zeros((bilayer_epi.GetNumberOfCells(),), dtype=int) tag[:la_epi.GetNumberOfCells()] = vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) tag[la_epi.GetNumberOfCells():] = vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) - meshNew = dsa.WrapDataObject(append_filter.GetOutput()) + meshNew = dsa.WrapDataObject(bilayer_epi) meshNew.CellData.append(tag, "elemTag") - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(meshNew.VTKObject) - append_filter.Update() - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", - append_filter.GetOutput()) + + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", vtk_append([meshNew.VTKObject])) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") @@ -204,13 +198,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_e) - append_filter.AddInputData(ra_e) - append_filter.Update() # la_ra_usg + biatrial_e = vtk_append([la_e, ra_e]) # Good till here! - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_e) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -302,16 +293,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetInputData(la_ra_usg) extract.SetCellList(la_ra_new) extract.Update() - - append_filter = vtk.vtkAppendFilter() - append_filter.MergePointsOn() - # append_filter.SetTolerance(0.01*args.scale) - - append_filter.AddInputData(extract.GetOutput()) - if args.debug: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", - append_filter.AddInputData(extract.GetOutput())) + vtk_append(extract.GetOutput(), True)) filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') @@ -429,13 +413,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() la_endo = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_endo) - append_filter.AddInputData(ra_endo) - append_filter.Update() + biatrial_endo = vtk_append([la_endo, ra_endo]) - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", append_filter.GetOutput()) - endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", biatrial_endo) + endo = Method.move_surf_along_normals(biatrial_endo, 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside vtk_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu", endo) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index 7e504da..bef7183 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -15,7 +15,7 @@ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, vtk_append parser = argparse.ArgumentParser(description='Create Right Atrium.') @@ -125,14 +125,7 @@ def generate_bilayer(endo, epi, max_dist=np.inf): fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(endo) - appendFilter.AddInputData(epi) - appendFilter.AddInputData(meshNew.VTKObject) - appendFilter.MergePointsOn() - appendFilter.Update() - - bilayer = appendFilter.GetOutput() + bilayer = vtk_append([endo, epi, meshNew.VTKObject], True) return bilayer diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index 54c53d7..93ed0b4 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -32,7 +32,7 @@ from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, vtk_append def parser(): @@ -63,12 +63,10 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV", "TV", "SVC", "IVC"] meshLA = vtkreader(f"{mesh1_name}_surf/LA_boundaries_tagged") meshRA = vtkreader(f"{mesh1_name}_surf/RA_boundaries_tagged") - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(meshLA) - appendFilter.AddInputData(meshRA) - appendFilter.Update() - mesh1 = apply_vtk_geom_filter(appendFilter.GetOutput()) + biatrial_mesh = vtk_append([meshLA, meshRA]) + + mesh1 = apply_vtk_geom_filter(biatrial_mesh) elif case == "LA": names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV"] # Prealign MRI @@ -150,7 +148,6 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): vtk_polydata_writer(f'{mesh1_name}_surf/RA_prealigned.vtk', meshNew.VTKObject) - def run(): args = parser().parse_args() From ff2138f08100ff01329650e71f9e34ca889e335e Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 26 Nov 2024 17:03:10 +0100 Subject: [PATCH 32/70] Included vtk_append from the helper methods and fixed bug from refactoring where mesh data got lost while auto replace --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 11 +-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 14 +--- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 76 ++++++------------- .../LDRBM/Fiber_RA/create_bridges_test.py | 43 +++-------- .../LDRBM/Fiber_RA/generate_RA_bilayer.py | 11 +-- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 2 +- standalones/prealign_meshes.py | 11 +-- 7 files changed, 47 insertions(+), 121 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index da497b8..0775074 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -38,7 +38,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, vtk_append from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -145,14 +145,7 @@ def generate_bilayer(endo, epi): fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(endo) - appendFilter.AddInputData(epi) - appendFilter.AddInputData(meshNew.VTKObject) - appendFilter.MergePointsOn() - appendFilter.Update() - - bilayer = appendFilter.GetOutput() + bilayer = vtk_append([endo, epi, meshNew.VTKObject], merge_points=True) return bilayer diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index c5c6623..2263fbb 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -36,7 +36,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, vtk_append from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -146,19 +146,13 @@ def generate_bilayer(args, job, endo, epi, max_dist=np.inf): reader.Update() test = reader.GetOutput() - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(endo) - appendFilter.AddInputData(epi) - appendFilter.AddInputData(test) - appendFilter.MergePointsOn() - appendFilter.Update() - - bilayer = appendFilter.GetOutput() + bilayer = vtk_append([endo, epi, test], True) if args.ofmt == 'vtk': vtk_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtk", bilayer, store_binary=True) else: - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :, bilayer) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu", + bilayer) # Has elemTag! reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_bilayer_with_fiber.vtu") # Has elemTag! :) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index deabba5..ce617dc 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -41,7 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -132,21 +132,17 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): Method.smart_bridge_writer(csb_tube, csb_sphere_1, csb_sphere_2, "coronary_sinus_bridge", job) if args.mesh_type == "vol": - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_epi) - append_filter.AddInputData(ra_epi) - append_filter.Update() - tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) + biatrial_epi = vtk_append([la_epi, ra_epi]) + + tag = np.zeros((biatrial_epi.GetNumberOfCells(),), dtype=int) tag[:la_epi.GetNumberOfCells()] = vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) tag[la_epi.GetNumberOfCells():] = vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) - meshNew = dsa.WrapDataObject(append_filter.GetOutput()) + meshNew = dsa.WrapDataObject(biatrial_epi) meshNew.CellData.append(tag, "elemTag") - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(meshNew.VTKObject) - append_filter.Update() - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", append_filter.GetOutput()) + + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", vtk_append([meshNew.VTKObject])) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") @@ -155,12 +151,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_e) - append_filter.AddInputData(ra_e) - append_filter.Update() # la_ra_usg - - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) + biatrial_e = vtk_append([la_e, ra_e]) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_e) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -255,13 +247,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(la_ra_new) extract.Update() - append_filter = vtk.vtkAppendFilter() - append_filter.MergePointsOn() - # append_filter.SetTolerance(0.01*args.scale) - - append_filter.AddInputData(extract.GetOutput()) - append_filter.Update() # added - la_ra_epi = append_filter.GetOutput() # we lose this mesh, when defining the append filter later + la_ra_epi = vtk_append([extract.GetOutput()], + merge_points=True) # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': # Still has element Tag @@ -328,13 +315,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetCellList(la_endo_new) extract.Update() - append_filter = vtk.vtkAppendFilter() - append_filter.MergePointsOn() - # append_filter.SetTolerance(0.01*args.scale) - - append_filter.AddInputData(extract.GetOutput()) - append_filter.Update() # added - la_endo_final = append_filter.GetOutput() # we lose this mesh, when defining the append filter later + la_endo_final = vtk_append([extract.GetOutput()], + merge_points=True) # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_endo_with_holes.vtu", la_endo_final) @@ -470,15 +452,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() up = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(bb) - append_filter.AddInputData(cs) - append_filter.AddInputData(mp) - append_filter.AddInputData(up) - append_filter.Update() - bridges = append_filter.GetOutput() + bridges = vtk_append([bb, cs, mp, up]) - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_bridges_2.vtu") # Has elementTag! :, bridges) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_bridges_2.vtu", bridges) # Has elementTag! reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/LA_RA_epi_with_holes.vtu") @@ -490,13 +466,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() bridges = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - # append_filter.AddInputData(la_ra_epi) - append_filter.AddInputData(epi_new) - append_filter.AddInputData(bridges) - # append_filter.MergePointsOn() - append_filter.Update() - epi = append_filter.GetOutput() + epi = vtk_append([epi_new, bridges]) vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_bundles.vtu", epi) epi = Method.generate_sheet_dir(args, epi, job) @@ -504,7 +474,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_RA_with_sheets.vtu", epi) if args.mesh_type == "bilayer": - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu") # Has elemTag! :, epi) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_epi_with_sheets.vtu", epi) # Has elemTag! reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(job.ID + "/result_RA/RA_CT_PMs.vtu") # Has elemTag! :) reader.Update() @@ -516,17 +486,15 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() la_endo = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_endo) - append_filter.AddInputData(ra_endo) - append_filter.Update() + bilayer_endo = vtk_append([la_endo, ra_endo]) vtk_xml_unstructured_grid_writer( - job.ID + "/result_RA/append_LA_endo_RA_endo.vtu") # Has elemTag! :, append_filter.GetOutput()) - endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, + job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", bilayer_endo) + # Has elemTag! + endo = Method.move_surf_along_normals(bilayer_endo, 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu") # Has elemTag! :, endo) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu",endo) # Has elemTag! :, bilayer = Method.generate_bilayer(args, job, endo, epi, 0.12 * args.scale) # Does not have elemTag :(! Method.write_bilayer(args, job) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 209abf3..4b41b6a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ vtk_unstructured_grid_writer, vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -180,22 +180,16 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): Method.smart_bridge_writer(csb_tube, csb_sphere_1, csb_sphere_2, "coronary_sinus_bridge", job) if args.mesh_type == "vol": - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_epi) - append_filter.AddInputData(ra_epi) - append_filter.Update() + bilayer_epi = vtk_append([la_epi, ra_epi]) - tag = np.zeros((append_filter.GetOutput().GetNumberOfCells(),), dtype=int) + tag = np.zeros((bilayer_epi.GetNumberOfCells(),), dtype=int) tag[:la_epi.GetNumberOfCells()] = vtk_to_numpy(la_epi.GetCellData().GetArray('elemTag')) tag[la_epi.GetNumberOfCells():] = vtk_to_numpy(ra_epi.GetCellData().GetArray('elemTag')) - meshNew = dsa.WrapDataObject(append_filter.GetOutput()) + meshNew = dsa.WrapDataObject(bilayer_epi) meshNew.CellData.append(tag, "elemTag") - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(meshNew.VTKObject) - append_filter.Update() - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", - append_filter.GetOutput()) + + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", vtk_append([meshNew.VTKObject])) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") @@ -204,13 +198,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_e) - append_filter.AddInputData(ra_e) - append_filter.Update() # la_ra_usg + biatrial_e = vtk_append([la_e, ra_e]) # Good till here! - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_e) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -302,16 +293,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): extract.SetInputData(la_ra_usg) extract.SetCellList(la_ra_new) extract.Update() - - append_filter = vtk.vtkAppendFilter() - append_filter.MergePointsOn() - # append_filter.SetTolerance(0.01*args.scale) - - append_filter.AddInputData(extract.GetOutput()) - if args.debug: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", - append_filter.AddInputData(extract.GetOutput())) + vtk_append(extract.GetOutput(), True)) filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') @@ -429,13 +413,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): reader.Update() la_endo = reader.GetOutput() - append_filter = vtk.vtkAppendFilter() - append_filter.AddInputData(la_endo) - append_filter.AddInputData(ra_endo) - append_filter.Update() + biatrial_endo = vtk_append([la_endo, ra_endo]) - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", append_filter.GetOutput()) - endo = Method.move_surf_along_normals(append_filter.GetOutput(), 0.1 * args.scale, + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/append_LA_endo_RA_endo.vtu", biatrial_endo) + endo = Method.move_surf_along_normals(biatrial_endo, 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside vtk_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu", endo) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py index 7e504da..bef7183 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/generate_RA_bilayer.py @@ -15,7 +15,7 @@ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, vtk_append parser = argparse.ArgumentParser(description='Create Right Atrium.') @@ -125,14 +125,7 @@ def generate_bilayer(endo, epi, max_dist=np.inf): fibers[:, 1] = 1 meshNew.CellData.append(fibers, "sheet") - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(endo) - appendFilter.AddInputData(epi) - appendFilter.AddInputData(meshNew.VTKObject) - appendFilter.MergePointsOn() - appendFilter.Update() - - bilayer = appendFilter.GetOutput() + bilayer = vtk_append([endo, epi, meshNew.VTKObject], True) return bilayer diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 4b2f200..3654d3e 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) diff --git a/standalones/prealign_meshes.py b/standalones/prealign_meshes.py index 54c53d7..93ed0b4 100755 --- a/standalones/prealign_meshes.py +++ b/standalones/prealign_meshes.py @@ -32,7 +32,7 @@ from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, vtk_append def parser(): @@ -63,12 +63,10 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV", "TV", "SVC", "IVC"] meshLA = vtkreader(f"{mesh1_name}_surf/LA_boundaries_tagged") meshRA = vtkreader(f"{mesh1_name}_surf/RA_boundaries_tagged") - appendFilter = vtk.vtkAppendFilter() - appendFilter.AddInputData(meshLA) - appendFilter.AddInputData(meshRA) - appendFilter.Update() - mesh1 = apply_vtk_geom_filter(appendFilter.GetOutput()) + biatrial_mesh = vtk_append([meshLA, meshRA]) + + mesh1 = apply_vtk_geom_filter(biatrial_mesh) elif case == "LA": names = ["MV", "RSPV", "LSPV", "RIPV", "LIPV"] # Prealign MRI @@ -150,7 +148,6 @@ def prealign_meshes(mesh1_name, mesh2_name, case="LA", scale=0): vtk_polydata_writer(f'{mesh1_name}_surf/RA_prealigned.vtk', meshNew.VTKObject) - def run(): args = parser().parse_args() From 10952dc4020c29220e1d7f241335696572f6f353 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 09:38:18 +0100 Subject: [PATCH 33/70] Replaced link to vtkIDFilter for whole AugmentA --- .../Generate_Boundaries/extract_rings.py | 50 +++----------- .../extract_rings_TOP_epi_endo.py | 67 ++++--------------- .../LDRBM/Fiber_LA/la_generate_fiber.py | 15 +---- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 36 +--------- standalones/open_orifices_with_curvature.py | 16 +---- .../Methods_fit_to_clinical_LAT.py | 30 +-------- ...tune_conductivities_to_fit_clinical_LAT.py | 18 ++--- 7 files changed, 37 insertions(+), 195 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index bc5edd9..f9abf8f 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, generate_ids from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -144,18 +144,9 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i warning("WARNING: Should be checkt for functionality extract_rings l151") thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") - geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) + mesh_poly = apply_vtk_geom_filter(thr.GetOutputPort(), True) - idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_port) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() - - LA = idFilter.GetOutput() + LA = generate_ids(mesh_poly, "Ids", "Ids") vtkWrite(LA, outdir + '/LA.vtk') @@ -181,18 +172,9 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() - geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) - - idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_port) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() + RA_poly = apply_vtk_geom_filter(thr.GetOutputPort(), True) - RA = idFilter.GetOutput() + RA = generate_ids(RA_poly, "Ids", "Ids") loc = vtk.vtkPointLocator() loc.SetDataSet(RA) @@ -224,15 +206,8 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i if mesh_surf.GetPointData().GetArray(array_name) is not None: # Remove previouse id so they match with indices mesh_surf.GetPointData().RemoveArray(array_name) - idFilter = vtk.vtkIdFilter() - idFilter.SetInputData(mesh_surf) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() - LA = idFilter.GetOutput() + + LA = generate_ids(mesh_surf, "Ids", "Ids") LA_rings = detect_and_mark_rings(LA, LA_ap_point, outdir, debug) b_tag = np.zeros((LA.GetNumberOfPoints(),)) @@ -246,16 +221,9 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i elif LAA_id == "": vtkWrite(mesh_surf, outdir + '/RA.vtk'.format(mesh)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) - idFilter = vtk.vtkIdFilter() - idFilter.SetInputData(mesh_surf) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() + centroids["RAA"] = RA_ap_point - RA = idFilter.GetOutput() + RA = generate_ids(mesh_surf, "Ids", "Ids") RA_rings = detect_and_mark_rings(RA, RA_ap_point, outdir, debug) b_tag = np.zeros((RA.GetNumberOfPoints(),)) b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 7e1f21d..5b882e2 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, generate_ids from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -118,7 +118,7 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" centroids["RAA_base"] = RA_bs_point connect = vtk.vtkConnectivityFilter() - connect.SetInputConnection(geo_filter.GetOutputPort()) + connect.SetInputData(mesh_surf) connect.SetExtractionModeToAllRegions() connect.ColorRegionsOn() connect.Update() @@ -142,18 +142,9 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" warning("WARNING: Should be checkt for functionality extract_rings_TOP_epi_endo l145") thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") - geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) + LA_poly = apply_vtk_geom_filter(thr.GetOutputPort(), True) - idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_port) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() - - LA = idFilter.GetOutput() + LA = generate_ids(LA_poly, "Ids", "Ids") vtkWrite(LA, outdir + '/LA.vtp') @@ -179,18 +170,9 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() - geo_port, _geo_filter = get_vtk_geom_filter_port(thr.GetOutputPort(), True) + RA_poly = apply_vtk_geom_filter(thr.GetOutputPort(), True) - idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_port) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() - - RA = idFilter.GetOutput() + RA = generate_ids(RA_poly, "Ids", "Ids") loc = vtk.vtkPointLocator() loc.SetDataSet(RA) @@ -215,18 +197,11 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtp'.format(mesh)) elif RAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir + '/LA.vtp'.format(mesh)) + vtkWrite(mesh_surf, outdir + '/LA.vtp'.format(mesh)) LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) centroids["LAA"] = LA_ap_point - idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() - LA = idFilter.GetOutput() + + LA = generate_ids(mesh_surf, "Ids", "Ids") LA_rings = detect_and_mark_rings(LA, LA_ap_point) b_tag = np.zeros((LA.GetNumberOfPoints(),)) b_tag, centroids = mark_LA_rings(LAA_id, LA_rings, b_tag, centroids, outdir, LA) @@ -237,18 +212,11 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtp'.format(mesh)) elif LAA_id == "": - vtkWrite(geo_filter.GetOutput(), outdir + '/RA.vtp'.format(mesh)) + vtkWrite(mesh_surf, outdir + '/RA.vtp'.format(mesh)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) - idFilter = vtk.vtkIdFilter() - idFilter.SetInputConnection(geo_filter.GetOutputPort()) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() + centroids["RAA"] = RA_ap_point - RA = idFilter.GetOutput() + RA = generate_ids(mesh_surf, "Ids", "Ids") RA_rings = detect_and_mark_rings(RA, RA_ap_point) b_tag = np.zeros((RA.GetNumberOfPoints(),)) b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) @@ -680,16 +648,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): endo = smart_reader(mesh[:-3] + 'endo.obj') - idFilter = vtk.vtkIdFilter() - idFilter.SetInputData(endo) - if int(vtk_version) >= 9: - idFilter.SetPointIdsArrayName('Ids') - idFilter.SetCellIdsArrayName('Ids') - else: - idFilter.SetIdsArrayName('Ids') - idFilter.Update() - - endo = idFilter.GetOutput() + endo = generate_ids(endo, "Ids", "Ids") surface = apply_vtk_geom_filter(endo) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index e5c9fca..47a9636 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, generate_ids from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -122,18 +122,7 @@ def la_generate_fiber(model, args, job): phie_grad = model.GetCellData().GetArray('grad_phi') phie_grad = vtk_to_numpy(phie_grad) - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(model) - cellid.PointIdsOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Global_ids') - cellid.SetCellIdsArrayName('Global_ids') - else: - cellid.SetIdsArrayName('Global_ids') - cellid.Update() - - model = cellid.GetOutput() + model = generate_ids(model, "Global_ids", "Global_ids") df = pd.read_csv(args.mesh + "_surf/rings_centroids.csv") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 3654d3e..22f5f75 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, generate_ids from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -162,18 +162,7 @@ def ra_generate_fiber(model, args, job): start_time = datetime.datetime.now() print('Calculating fibers... ' + str(start_time)) - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(model) # vtkPolyData() - cellid.PointIdsOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Global_ids') - cellid.SetCellIdsArrayName('Global_ids') - else: - cellid.SetIdsArrayName('Global_ids') - cellid.Update() - - model = cellid.GetOutput() + model = generate_ids(model, "Global_ids", "Global_ids") # TV @@ -276,7 +265,6 @@ def ra_generate_fiber(model, args, job): mesh_surf = apply_vtk_geom_filter(CT_band) - loc = vtk.vtkPointLocator() loc.SetDataSet(mesh_surf) loc.BuildLocator() @@ -324,7 +312,6 @@ def ra_generate_fiber(model, args, job): no_IVC_s = apply_vtk_geom_filter(no_IVC_s) - loc = vtk.vtkPointLocator() loc.SetDataSet(no_IVC_s) loc.BuildLocator() @@ -575,18 +562,7 @@ def ra_generate_fiber(model, args, job): PM and CT """ - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(meshNew.VTKObject) # vtkPolyData() - cellid.PointIdsOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Global_ids') - cellid.SetCellIdsArrayName('Global_ids') - else: - cellid.SetIdsArrayName('Global_ids') - cellid.Update() - - model = cellid.GetOutput() + model = generate_ids(meshNew.VTKObject, "Global_ids", "Global_ids") endo = vtk.vtkUnstructuredGrid() endo.DeepCopy(model) @@ -641,7 +617,6 @@ def ra_generate_fiber(model, args, job): CT = apply_vtk_geom_filter(CT) - # calculate the norm vector v1 = np.array(df["IVC"]) - np.array(df["SVC"]) v2 = np.array(df["TV"]) - np.array(df["IVC"]) @@ -694,7 +669,6 @@ def ra_generate_fiber(model, args, job): surface = apply_vtk_geom_filter(model) - epi = vtk_thr(surface, 0, "POINTS", "phie_phi", 0.5) endo = vtk_thr(surface, 1, "POINTS", "phie_phi", 0.5) @@ -709,7 +683,6 @@ def ra_generate_fiber(model, args, job): surface = apply_vtk_geom_filter(endo) - loc = vtk.vtkPointLocator() loc.SetDataSet(surface) loc.BuildLocator() @@ -899,7 +872,6 @@ def ra_generate_fiber(model, args, job): if args.mesh_type == "vol": surface = apply_vtk_geom_filter(epi) - loc = vtk.vtkPointLocator() loc.SetDataSet(RAS_S) loc.BuildLocator() @@ -993,7 +965,6 @@ def ra_generate_fiber(model, args, job): la_surf = apply_vtk_geom_filter(la) - la_epi = vtk_thr(la_surf, 2, "CELLS", "elemTag", left_atrial_wall_epi, 99) df = pd.read_csv(meshname + "_LA_vol_surf/rings_centroids.csv") @@ -1004,7 +975,6 @@ def ra_generate_fiber(model, args, job): la_epi = apply_vtk_geom_filter(la_epi) - if args.mesh_type == "bilayer": ra_epi = apply_vtk_geom_filter(model) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index d6952d3..81f3530 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, generate_ids from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -184,19 +184,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu # Cutting valve with fixed radius to ensure that it is the biggest ring model = cut_mesh_with_radius(model, valve_center, max_cutting_radius) - # model = smart_reader("{}/{}_valve.vtk".format(full_path, atrium)) - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(model) - cellid.PointIdsOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Ids') - cellid.SetCellIdsArrayName('Ids') - else: - cellid.SetIdsArrayName('Ids') - cellid.Update() - - model = cellid.GetOutput() + model = generate_ids(model, "Ids", "Ids") vtk_polydata_writer(f"{full_path}/{atrium}_curv.vtk", model, True) diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 2e2b646..69385a3 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -36,7 +36,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata + clean_polydata, generate_ids from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -53,19 +53,7 @@ def low_vol_LAT(args, path): model = convert_point_to_cell_data(model, ["bi"], ["lat"]) # Create Points and Cells ids - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(model) - cellid.PointIdsOn() - cellid.FieldDataOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Global_ids') - cellid.SetCellIdsArrayName('Global_ids') - else: - cellid.SetIdsArrayName('Global_ids') - cellid.Update() - - model = cellid.GetOutput() + model = generate_ids(model, "Global_ids", "Global_ids", True) # Compute elements centroids filter_cell_centers = vtk.vtkCellCenters() @@ -401,19 +389,7 @@ def get_EAP(path_mod, path_fib): model = smart_reader(path_mod) mod_fib = smart_reader(path_fib) - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(mod_fib) - cellid.PointIdsOn() - cellid.FieldDataOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Global_ids') - cellid.SetCellIdsArrayName('Global_ids') - else: - cellid.SetIdsArrayName('Global_ids') - cellid.Update() - - mod_fib = cellid.GetOutput() + mod_fib = generate_ids(mod_fib, "Global_ids", "Global_ids", True) LA_MV = vtk_thr(mod_fib, 1, "CELLS", "elemTag", 2) LAT_map = vtk_to_numpy(model.GetPointData().GetArray('LAT')) diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index 6353dd4..f457a04 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -27,6 +27,8 @@ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer +from vtk_opencarp_helper_methods.vtk_methods.filters import generate_ids +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader EXAMPLE_DESCRIPTIVE_NAME = 'Tune conductivities to fit clinical LAT map' EXAMPLE_AUTHOR = 'Luca Azzolin ' @@ -386,19 +388,9 @@ def run(args, job): meshname_e = file_name - new_endo = Methods_fit_to_clinical_LAT.smart_reader(meshname_e + '.vtu') - cellid = vtk.vtkIdFilter() - cellid.CellIdsOn() - cellid.SetInputData(new_endo) - cellid.PointIdsOn() - cellid.FieldDataOn() - if int(vtk_version) >= 9: - cellid.SetPointIdsArrayName('Global_ids') - cellid.SetCellIdsArrayName('Global_ids') - else: - cellid.SetIdsArrayName('Global_ids') - cellid.Update() - new_endo = cellid.GetOutput() + new_endo = smart_reader(meshname_e + '.vtu') + + new_endo = generate_ids(new_endo, "Global_ids", "Global_ids", True) with open('element_tag.csv') as f: reader = csv.DictReader(f) From 3ccd722a258fe47e10aaba9ac942f771a59f8f12 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 10:03:34 +0100 Subject: [PATCH 34/70] Used newly added apply_extract_cell_filter method for AugmentA --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 9 ++-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 9 +--- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 37 +++----------- .../LDRBM/Fiber_RA/create_bridges_test.py | 20 ++------ .../LDRBM/Fiber_RA/ra_generate_fiber.py | 49 +++---------------- standalones/open_orifices_with_curvature.py | 14 +----- standalones/resample_surf_mesh.py | 13 ++--- .../Methods_fit_to_clinical_LAT.py | 14 +----- 8 files changed, 31 insertions(+), 134 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 0775074..8165d8c 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -38,7 +38,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, vtk_append + clean_polydata, vtk_append, apply_extract_cell_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -598,11 +598,8 @@ def get_endo_ct_intersection_cells(endo, ct): for j in range(endo_cell_temp_id_list.GetNumberOfIds()): endo_cell_id_list.InsertNextId(endo_cell_temp_id_list.GetId(j)) print(endo_cell_id_list.GetNumberOfIds()) - extract = vtk.vtkExtractCells() - extract.SetInputData(endo) - extract.SetCellList(endo_cell_id_list) - extract.Update() - endo_ct = extract.GetOutput() + + endo_ct = apply_extract_cell_filter(endo, endo_cell_id_list) return endo_ct diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 2263fbb..913a557 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -36,7 +36,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, vtk_append + clean_polydata, vtk_append, apply_extract_cell_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -757,13 +757,8 @@ def get_endo_ct_intersection_cells(endo, ct): for j in range(endo_cell_temp_id_list.GetNumberOfIds()): endo_cell_id_list.InsertNextId(endo_cell_temp_id_list.GetId(j)) print(endo_cell_id_list.GetNumberOfIds()) - extract = vtk.vtkExtractCells() - extract.SetInputData(endo) - extract.SetCellList(endo_cell_id_list) - extract.Update() - endo_ct = extract.GetOutput() - return endo_ct + return apply_extract_cell_filter(endo, endo_cell_id_list) def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_inf_surface, la_epi_surface, diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index ce617dc..ef2a7f3 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -41,7 +41,8 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, vtk_obj_writer, \ vtk_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append, \ + apply_extract_cell_filter, get_cells_with_ids EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -220,12 +221,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): for j in range(earth_cell_ids_temp.GetNumberOfIds()): earth_cell_ids.InsertNextId(earth_cell_ids_temp.GetId(j)) earth_cell_ids_list += [earth_cell_ids_temp.GetId(j)] - extract = vtk.vtkExtractCells() - extract.SetInputData(la_ra_usg) - extract.SetCellList(earth_cell_ids) - extract.Update() - earth = apply_vtk_geom_filter(extract.GetOutput()) + earth = apply_vtk_geom_filter(apply_extract_cell_filter(la_ra_usg, earth_cell_ids)) earth = clean_polydata(earth) # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) @@ -238,16 +235,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): cell_id_all.append(i) la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) - la_ra_new = vtk.vtkIdList() - for item in la_diff: - la_ra_new.InsertNextId(item) - extract = vtk.vtkExtractCells() - extract.SetInputData(la_ra_usg) - extract.SetCellList(la_ra_new) - extract.Update() - - la_ra_epi = vtk_append([extract.GetOutput()], + la_ra_epi = vtk_append([get_cells_with_ids(la_ra_usg, la_diff)], merge_points=True) # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': @@ -292,12 +281,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): for j in range(earth_cell_ids_temp.GetNumberOfIds()): earth_cell_ids.InsertNextId(earth_cell_ids_temp.GetId(j)) earth_cell_ids_list += [earth_cell_ids_temp.GetId(j)] - extract = vtk.vtkExtractCells() - extract.SetInputData(la_endo) - extract.SetCellList(earth_cell_ids) - extract.Update() - earth = apply_vtk_geom_filter(extract.GetOutput()) + earth = apply_vtk_geom_filter(apply_extract_cell_filter(la_endo, earth_cell_ids)) earth = clean_polydata(earth) print("Extracted earth") @@ -306,16 +291,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): cell_id_all.append(i) la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) - la_endo_new = vtk.vtkIdList() - for item in la_diff: - la_endo_new.InsertNextId(item) - - extract = vtk.vtkExtractCells() - extract.SetInputData(la_endo) - extract.SetCellList(la_endo_new) - extract.Update() - la_endo_final = vtk_append([extract.GetOutput()], + la_endo_final = vtk_append([get_cells_with_ids(la_endo, la_diff)], merge_points=True) # we lose this mesh, when defining the append filter later if args.debug and var == 'upper_posterior_bridge': @@ -494,7 +471,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): endo = Method.move_surf_along_normals(bilayer_endo, 0.1 * args.scale, 1) # # Warning: set -1 if pts normals are pointing outside - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu",endo) # Has elemTag! :, + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu", endo) # Has elemTag! :, bilayer = Method.generate_bilayer(args, job, endo, epi, 0.12 * args.scale) # Does not have elemTag :(! Method.write_bilayer(args, job) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 4b41b6a..5bad05a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -43,7 +43,8 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer, \ vtk_unstructured_grid_writer, vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append, \ + apply_extract_cell_filter, get_cells_with_ids EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -267,12 +268,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): for j in range(earth_cell_ids_temp.GetNumberOfIds()): earth_cell_ids.InsertNextId(earth_cell_ids_temp.GetId(j)) earth_cell_ids_list += [earth_cell_ids_temp.GetId(j)] - extract = vtk.vtkExtractCells() - extract.SetInputData(la_ra_usg) - extract.SetCellList(earth_cell_ids) - extract.Update() - earth = apply_vtk_geom_filter(extract.GetOutput()) + earth = apply_vtk_geom_filter(apply_extract_cell_filter(la_ra_usg, earth_cell_ids)) earth = clean_polydata(earth) # meshNew = dsa.WrapDataObject(cleaner.GetOutput()) @@ -285,17 +282,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): cell_id_all.append(i) la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) - la_ra_new = vtk.vtkIdList() - for item in la_diff: - la_ra_new.InsertNextId(item) - - extract = vtk.vtkExtractCells() - extract.SetInputData(la_ra_usg) - extract.SetCellList(la_ra_new) - extract.Update() + if args.debug: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", - vtk_append(extract.GetOutput(), True)) + vtk_append(get_cells_with_ids(la_ra_usg, la_diff), True)) filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 22f5f75..29b8f88 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -40,7 +40,8 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, generate_ids +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, generate_ids, \ + get_cells_with_ids, apply_extract_cell_filter from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -182,30 +183,13 @@ def ra_generate_fiber(model, args, job): TV_ids = Method.get_element_ids_around_path_within_radius(model, rings_pts, 4 * args.scale) - ra_TV = vtk.vtkIdList() - for var in TV_ids: - ra_TV.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(ra_TV) - extract.Update() - - TV_s = extract.GetOutput() + TV_s = get_cells_with_ids(model, TV_ids) ra_diff = list( set(list(vtk_to_numpy(model.GetCellData().GetArray('Global_ids')))).difference( set(TV_ids))) - ra_no_TV = vtk.vtkIdList() - for var in ra_diff: - ra_no_TV.InsertNextId(var) - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(ra_no_TV) - extract.Update() - - no_TV_s = extract.GetOutput() + no_TV_s = get_cells_with_ids(model, ra_diff) # To check if TV was correctly identified if args.debug: @@ -287,15 +271,7 @@ def ra_generate_fiber(model, args, job): ii = set([item for sublist in ii for item in sublist]) - cell_ids = vtk.vtkIdList() - for i in ii: - cell_ids.InsertNextId(i) - extract = vtk.vtkExtractCells() - extract.SetInputData(CT_band) - extract.SetCellList(cell_ids) - extract.Update() - - CT_band = extract.GetOutput() + CT_band = get_cells_with_ids(CT_band, ii) if args.debug: Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band_2.vtk") @@ -332,15 +308,8 @@ def ra_generate_fiber(model, args, job): RAW_I_ids = vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) ii = set(RAW_I_ids) - set(CT_SEPT_ids) - set(CT_band_ids) - cell_ids = vtk.vtkIdList() - for i in ii: - cell_ids.InsertNextId(i) - extract = vtk.vtkExtractCells() - extract.SetInputData(CT_minus) - extract.SetCellList(cell_ids) - extract.Update() - CT_minus = extract.GetOutput() + CT_minus = get_cells_with_ids(CT_minus, ii) RAW_I_ids = vtk_to_numpy(CT_minus.GetCellData().GetArray('Global_ids')) @@ -579,11 +548,7 @@ def ra_generate_fiber(model, args, job): for var in CT_SEPT_ids: CT_id_list.InsertNextId(var) - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(CT_id_list) - extract.Update() - CT = extract.GetOutput() + CT = apply_extract_cell_filter(model, CT_id_list) CT_ids = vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 81f3530..9bc445c 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids + clean_polydata, generate_ids, get_cells_with_ids from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -300,17 +300,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu connect2.DeleteSpecifiedRegion(ii) connect2.Update() - model_new_el = vtk.vtkIdList() - - for var in el_low_vol: - model_new_el.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(model) - extract.SetCellList(model_new_el) - extract.Update() - - geo_port, _geo_filter = get_vtk_geom_filter_port(extract.GetOutputPort(), True) + geo_port, _geo_filter = get_vtk_geom_filter_port(get_cells_with_ids(model, el_low_vol)) loc_low_V = clean_polydata(geo_port, input_is_connection=True) # local low voltage area diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 2d94b9f..e49c19b 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -38,7 +38,7 @@ from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, get_cells_with_ids pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -127,15 +127,8 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv tot_cells = set(list(range(reader.GetOutput().GetNumberOfCells()))) cells_no_bd = tot_cells - bd_ids - cell_ids_no_bd = vtk.vtkIdList() - for i in cells_no_bd: - cell_ids_no_bd.InsertNextId(i) - extract = vtk.vtkExtractCells() - extract.SetInputData(reader.GetOutput()) - extract.SetCellList(cell_ids_no_bd) - extract.Update() - - earth = apply_vtk_geom_filter(extract.GetOutput()) + + earth = apply_vtk_geom_filter(get_cells_with_ids(reader.GetOutput(), cells_no_bd)) connect = vtk.vtkConnectivityFilter() connect.SetInputData(clean_polydata(earth)) diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 69385a3..e02dd00 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -36,7 +36,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, convert_point_to_cell_data from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids + clean_polydata, generate_ids, get_cells_with_ids from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -207,17 +207,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): for el in el_diff: cell_diff.add(b_ids.index(el)) - model_new_el = vtk.vtkIdList() - - for var in cell_diff: - model_new_el.InsertNextId(var) - - extract = vtk.vtkExtractCells() - extract.SetInputData(band) - extract.SetCellList(model_new_el) - extract.Update() - - geo_port, _geo_filter = get_vtk_geom_filter_port(extract.GetOutputPort(), True) + geo_port, _geo_filter = get_vtk_geom_filter_port(get_cells_with_ids(band, cell_diff)) # Mesh of all elements which are not belonging to the clean band el_removed = clean_polydata(geo_port, input_is_connection=True) From af870201efb753a0a6133bbafa517ddb5ff0d3de Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 10:08:52 +0100 Subject: [PATCH 35/70] Fixed bug in create_bridges_test.py --- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 5bad05a..ec66717 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -199,10 +199,13 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - biatrial_e = vtk_append([la_e, ra_e]) + append_filter = vtk.vtkAppendFilter() + append_filter.AddInputData(la_e) + append_filter.AddInputData(ra_e) + append_filter.Update() # la_ra_usg # Good till here! - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_e) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", append_filter.GetOutput()) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -282,10 +285,15 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): cell_id_all.append(i) la_diff = list(set(cell_id_all).difference(set(earth_cell_ids_list))) + append_filter = vtk.vtkAppendFilter() + append_filter.MergePointsOn() + # append_filter.SetTolerance(0.01*args.scale) + + append_filter.AddInputData(get_cells_with_ids(la_ra_usg, la_diff)) if args.debug: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/" + str(var) + "_append_earth.vtu", - vtk_append(get_cells_with_ids(la_ra_usg, la_diff), True)) + append_filter.GetOutput()) filename = job.ID + '/bridges/bb_fiber.dat' f = open(filename, 'rb') From 801a08517d33bf829bdb3de3b002437c097790c2 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 10:36:08 +0100 Subject: [PATCH 36/70] Used get_feature_edges from helper methods in AugmentA --- .../Generate_Boundaries/extract_rings.py | 58 +++++----------- .../extract_rings_TOP_epi_endo.py | 66 ++++++------------- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 30 +++------ standalones/open_orifices_with_curvature.py | 9 +-- standalones/resample_surf_mesh.py | 15 ++--- 5 files changed, 54 insertions(+), 124 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index f9abf8f..58aa9c1 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids + clean_polydata, generate_ids, get_center_of_mass, get_feature_edges from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -248,18 +248,11 @@ def run(args=None): def detect_and_mark_rings(surf, ap_point, outdir, debug): - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surf) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - + boundary_edges = get_feature_edges(surf, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) "Splitting rings" - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(boundaryEdges.GetOutput()) + connect.SetInputData(boundary_edges) connect.SetExtractionModeToAllRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() @@ -284,12 +277,7 @@ def detect_and_mark_rings(surf, ap_point, outdir, debug): ring_surf = vtk.vtkPolyData() ring_surf.DeepCopy(surface) - centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(surface) - centerOfMassFilter.SetUseScalarsAsWeights(False) - centerOfMassFilter.Update() - - c_mass = centerOfMassFilter.GetCenter() + c_mass = get_center_of_mass(surface, False) ring = Ring(i, "", surface.GetNumberOfPoints(), c_mass, np.sqrt(np.sum((np.array(ap_point) - \ np.array(c_mass)) ** 2, axis=0)), @@ -527,16 +515,12 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): """ here we will extract the feature edge """ - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surface) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - - tree = cKDTree(vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) - ids = vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) + + boundary_edges = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) + + tree = cKDTree(vtk_to_numpy(boundary_edges.GetPoints().GetData())) + ids = vtk_to_numpy(boundary_edges.GetPointData().GetArray('Ids')) MV_ring = [r for r in rings if r.name == "MV"] MV_ids = set(vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) @@ -568,7 +552,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_mv = loc.FindClosestPoint(rpv_mean) loc = vtk.vtkPointLocator() - loc.SetDataSet(boundaryEdges.GetOutput()) + loc.SetDataSet(boundary_edges) loc.BuildLocator() lpv_bb = loc.FindClosestPoint(lpv_mean) rpv_bb = loc.FindClosestPoint(rpv_mean) @@ -576,7 +560,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(boundaryEdges.GetOutput()) + path.SetInputData(boundary_edges) path.SetStartVertex(lpv_bb) path.SetEndVertex(lpv_mv) path.Update() @@ -596,7 +580,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): f.close() path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(boundaryEdges.GetOutput()) + path.SetInputData(boundary_edges) path.SetStartVertex(rpv_bb) path.SetEndVertex(rpv_mv) path.Update() @@ -616,7 +600,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): f.close() path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(boundaryEdges.GetOutput()) + path.SetInputData(boundary_edges) path.SetStartVertex(lpv_bb) path.SetEndVertex(rpv_bb) path.Update() @@ -665,15 +649,9 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): """ here we will extract the feature edge """ - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surface) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - - gamma_top = boundaryEdges.GetOutput() + + gamma_top = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) if debug: surface = apply_vtk_geom_filter(gamma_top) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 5b882e2..32a45c9 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids + clean_polydata, generate_ids, get_center_of_mass, get_feature_edges from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -238,18 +238,13 @@ def run(): def detect_and_mark_rings(surf, ap_point): - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surf) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() + boundary_edges = get_feature_edges(surf, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) "Splitting rings" connect = vtk.vtkConnectivityFilter() - connect.SetInputData(boundaryEdges.GetOutput()) + connect.SetInputData(boundary_edges) connect.SetExtractionModeToAllRegions() connect.Update() num = connect.GetNumberOfExtractedRegions() @@ -270,12 +265,7 @@ def detect_and_mark_rings(surf, ap_point): ring_surf = vtk.vtkPolyData() ring_surf.DeepCopy(surface) - centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(surface) - centerOfMassFilter.SetUseScalarsAsWeights(False) - centerOfMassFilter.Update() - - c_mass = centerOfMassFilter.GetCenter() + c_mass = get_center_of_mass(surface, False) ring = Ring(i, "", surface.GetNumberOfPoints(), c_mass, np.sqrt(np.sum((np.array(ap_point) - \ np.array(c_mass)) ** 2, axis=0)), @@ -499,16 +489,12 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): """ here we will extract the feature edge """ - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surface) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - - tree = cKDTree(vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData())) - ids = vtk_to_numpy(boundaryEdges.GetOutput().GetPointData().GetArray('Ids')) + + boundary_edges = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) + + tree = cKDTree(vtk_to_numpy(boundary_edges.GetPoints().GetData())) + ids = vtk_to_numpy(boundary_edges.GetPointData().GetArray('Ids')) MV_ring = [r for r in rings if r.name == "MV"] MV_ids = set(vtk_to_numpy(MV_ring[0].vtk_polydata.GetPointData().GetArray("Ids"))) @@ -540,7 +526,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_mv = loc.FindClosestPoint(rpv_mean) loc = vtk.vtkPointLocator() - loc.SetDataSet(boundaryEdges.GetOutput()) + loc.SetDataSet(boundary_edges) loc.BuildLocator() lpv_bb = loc.FindClosestPoint(lpv_mean) rpv_bb = loc.FindClosestPoint(rpv_mean) @@ -548,7 +534,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): rpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(boundaryEdges.GetOutput()) + path.SetInputData(boundary_edges) path.SetStartVertex(lpv_bb) path.SetEndVertex(lpv_mv) path.Update() @@ -568,7 +554,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): f.close() path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(boundaryEdges.GetOutput()) + path.SetInputData(boundary_edges) path.SetStartVertex(rpv_bb) path.SetEndVertex(rpv_mv) path.Update() @@ -588,7 +574,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): f.close() path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(boundaryEdges.GetOutput()) + path.SetInputData(boundary_edges) path.SetStartVertex(lpv_bb) path.SetEndVertex(rpv_bb) path.Update() @@ -634,15 +620,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): """ here we will extract the feature edge """ - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surface) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - gamma_top_epi = boundaryEdges.GetOutput() + gamma_top_epi = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) # Endo @@ -662,15 +642,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): """ here we will extract the feature edge """ - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(surface) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - - gamma_top_endo = boundaryEdges.GetOutput() + + gamma_top_endo = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) """ separate the tv into tv tv-f and tv-f diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 8165d8c..7cc56e9 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -38,7 +38,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, vtk_append, apply_extract_cell_filter + clean_polydata, vtk_append, apply_extract_cell_filter, get_center_of_mass, get_feature_edges from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -803,16 +803,11 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e inf_appendage_basis = LAA.GetPoint(ptIds.GetId(0)) # Extract the border of the LAA + threshold_poly_mesh = apply_vtk_geom_filter(thresh.GetOutputPort(), True) + LAA_border = get_feature_edges(threshold_poly_mesh, boundary_edges_on=True, feature_edges_on=False, + manifold_edges_on=False, + non_manifold_edges_on=False) - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(apply_vtk_geom_filter(thresh.GetOutputPort(), True)) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() - - LAA_border = boundaryEdges.GetOutput() LAA_pts_border = vtk_to_numpy(LAA_border.GetPoints().GetData()) max_dist = 0 for i in range(len(LAA_pts_border)): @@ -971,12 +966,7 @@ def distinguish_PVs(connect, PVs, df, name1, name2): single_PV = vtk_thr(single_PV, 0, "CELLS", "phie_v", val) surface = apply_vtk_geom_filter(single_PV) - centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(surface) - centerOfMassFilter.SetUseScalarsAsWeights(False) - centerOfMassFilter.Update() - - c_mass = centerOfMassFilter.GetCenter() + c_mass = get_center_of_mass(surface, False) centroid1_d = np.sqrt(np.sum((np.array(centroid1) - np.array(c_mass)) ** 2, axis=0)) centroid2_d = np.sqrt(np.sum((np.array(centroid2) - np.array(c_mass)) ** 2, axis=0)) @@ -1008,12 +998,8 @@ def optimize_shape_PV(surface, num, bound): else: out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l + 1], arr[l]) - centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(apply_vtk_geom_filter(out)) - centerOfMassFilter.SetUseScalarsAsWeights(False) - centerOfMassFilter.Update() - - c_mass_l.append(centerOfMassFilter.GetCenter()) + center = get_center_of_mass(apply_vtk_geom_filter(out), False) + c_mass_l.append(center) v1 = np.array(c_mass_l[0]) - np.array(c_mass_l[1]) for l in range(1, num - 2): diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 9bc445c..7c58745 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -43,7 +43,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids, get_cells_with_ids + clean_polydata, generate_ids, get_cells_with_ids, get_center_of_mass from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -148,12 +148,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu debug) valve = extract_largest_region(valve) - centerOfMassFilter = vtk.vtkCenterOfMass() - centerOfMassFilter.SetInputData(valve) - centerOfMassFilter.SetUseScalarsAsWeights(False) - centerOfMassFilter.Update() - - valve_center = np.array(centerOfMassFilter.GetCenter()) + valve_center = np.array(get_center_of_mass(valve, False)) max_dist = get_maximum_distance_of_points(valve, valve_center) diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index e49c19b..b43b7ea 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -38,7 +38,8 @@ from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, get_cells_with_ids +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, get_cells_with_ids, \ + get_feature_edges pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -94,15 +95,11 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv reader.SetFileName(f'{meshname}.obj') reader.Update() - boundaryEdges = vtk.vtkFeatureEdges() - boundaryEdges.SetInputData(reader.GetOutput()) - boundaryEdges.BoundaryEdgesOn() - boundaryEdges.FeatureEdgesOff() - boundaryEdges.ManifoldEdgesOff() - boundaryEdges.NonManifoldEdgesOff() - boundaryEdges.Update() + boundary_edges = get_feature_edges(reader.GetOutput(), boundary_edges_on=True, feature_edges_on=False, + manifold_edges_on=False, + non_manifold_edges_on=False) - boundary_pts = vtk_to_numpy(boundaryEdges.GetOutput().GetPoints().GetData()) + boundary_pts = vtk_to_numpy(boundary_edges.GetPoints().GetData()) # Clean the mesh from holes and self intersecting triangles meshin = pv.read(f'{meshname}.obj') From 698ce70d12eb17d0623f4488030ab910686c576d Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 11:17:20 +0100 Subject: [PATCH 37/70] Implemented get_elements_above plane in AugmentA code --- .../Generate_Boundaries/extract_rings.py | 38 +++------------- .../extract_rings_TOP_epi_endo.py | 45 ++++--------------- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 22 +++------ .../LDRBM/Fiber_LA/la_generate_fiber.py | 11 ++--- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 22 +++------ .../LDRBM/Fiber_RA/ra_generate_fiber.py | 26 +++-------- standalones/function.py | 29 +++--------- 7 files changed, 40 insertions(+), 153 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 58aa9c1..17a65e2 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids, get_center_of_mass, get_feature_edges + clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -486,12 +486,9 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): appendFilter.AddInputData(temp) appendFilter.Update() - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(appendFilter.GetOutput()) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() + extracted_mesh = get_elements_above_plane(appendFilter.GetOutput(), plane) - RSPV_id = int(vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) + RSPV_id = int(vtk_to_numpy(extracted_mesh.GetPointData().GetArray('id'))[0]) return RSPV_id @@ -505,12 +502,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(LA) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + surface = apply_vtk_geom_filter(get_elements_above_plane(LA, plane)) """ here we will extract the feature edge @@ -636,12 +628,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): surface = apply_vtk_geom_filter(model) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(surface) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + surface = apply_vtk_geom_filter(get_elements_above_plane(surface, plane)) if debug: vtkWrite(surface, outdir + '/cutted_RA.vtk') @@ -668,18 +655,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): plane2 = initialize_plane(norm_2[0], tv_center) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(tv) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - meshExtractFilter2 = vtk.vtkExtractGeometry() - meshExtractFilter2.SetInputData(tv) - meshExtractFilter2.ExtractBoundaryCellsOn() - meshExtractFilter2.SetImplicitFunction(plane2) - meshExtractFilter2.Update() - - tv_f = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, plane)) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' @@ -690,7 +666,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): f.write(f'{i}\n') f.close() - tv_s = apply_vtk_geom_filter(meshExtractFilter2.GetOutput()) + tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, plane2, extract_boundary_cells_on=True)) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 32a45c9..cc52a0b 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -40,7 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids, get_center_of_mass, get_feature_edges + clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -460,12 +460,9 @@ def cutting_plane_to_identify_RSPV(LPVs, RPVs, rings): appendFilter.AddInputData(temp) appendFilter.Update() - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(appendFilter.GetOutput()) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() + extracted_mesh = get_elements_above_plane(appendFilter.GetOutput(), plane) - RSPV_id = int(vtk_to_numpy(meshExtractFilter.GetOutput().GetPointData().GetArray('id'))[0]) + RSPV_id = int(vtk_to_numpy(extracted_mesh.GetPointData().GetArray('id'))[0]) return RSPV_id @@ -479,12 +476,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(LA) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + surface = apply_vtk_geom_filter(get_elements_above_plane(LA, plane)) """ here we will extract the feature edge @@ -610,12 +602,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = apply_vtk_geom_filter(model) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(surface) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + surface = apply_vtk_geom_filter(get_elements_above_plane(surface, plane)) """ here we will extract the feature edge @@ -632,12 +619,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = apply_vtk_geom_filter(endo) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(surface) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - surface = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + surface = apply_vtk_geom_filter(get_elements_above_plane(surface, plane)) """ here we will extract the feature edge @@ -656,18 +638,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): plane = initialize_plane(norm_1[0], tv_center) plane2 = initialize_plane(norm_2[0], tv_center) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(tv) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - - meshExtractFilter2 = vtk.vtkExtractGeometry() - meshExtractFilter2.SetInputData(tv) - meshExtractFilter2.ExtractBoundaryCellsOn() - meshExtractFilter2.SetImplicitFunction(plane2) - meshExtractFilter2.Update() - - tv_f = apply_vtk_geom_filter(meshExtractFilter.GetOutput()) + tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, plane)) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_F.vtx' @@ -678,7 +649,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): f.write(f'{i}\n') f.close() - tv_s = apply_vtk_geom_filter(meshExtractFilter2.GetOutput()) + tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, plane2, extract_boundary_cells_on=True)) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) fname = outdir + '/ids_TV_S.vtx' diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 7cc56e9..89e31f0 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -38,7 +38,8 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, vtk_append, apply_extract_cell_filter, get_center_of_mass, get_feature_edges + clean_polydata, vtk_append, apply_extract_cell_filter, get_center_of_mass, get_feature_edges, \ + get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -246,21 +247,13 @@ def dijkstra_path_on_a_plane(polydata, StartVertex, EndVertex, plane_point): plane = initialize_plane(norm_1[0], point_start) - meshExtractFilter1 = vtk.vtkExtractGeometry() - meshExtractFilter1.SetInputData(polydata) - meshExtractFilter1.SetImplicitFunction(plane) - meshExtractFilter1.Update() + extracted_mesh_1 = get_elements_above_plane(polydata, plane) point_moved = point_start - 1.5 * norm_1 plane2 = initialize_plane(-norm_1[0], point_moved[0]) - meshExtractFilter2 = vtk.vtkExtractGeometry() - meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) - meshExtractFilter2.SetImplicitFunction(plane2) - meshExtractFilter2.Update() - band = meshExtractFilter2.GetOutput() - band = apply_vtk_geom_filter(band) + band = apply_vtk_geom_filter(get_elements_above_plane(extracted_mesh_1, plane2)) # print(band) loc = vtk.vtkPointLocator() @@ -482,13 +475,8 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, plane = initialize_plane(-norm_1[0], moved_center[0]) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(ra_tv_s_surface) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(meshExtractFilter.GetOutput()) + connect.SetInputData(get_elements_above_plane(ra_tv_surface, plane)) connect.SetExtractionModeToAllRegions() connect.Update() connect.SetExtractionModeToSpecifiedRegions() diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 47a9636..74c525c 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -40,7 +40,8 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, generate_ids +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, generate_ids, \ + get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -313,13 +314,9 @@ def la_generate_fiber(model, args, job): band_s = vtk_thr(epi, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(band_s) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() + extracted_mesh = get_elements_above_plane(band_s, plane) - band_cell_ids = vtk_to_numpy( - meshExtractFilter.GetOutput().GetCellData().GetArray('Global_ids')) + band_cell_ids = vtk_to_numpy(extracted_mesh.GetCellData().GetArray('Global_ids')) if args.mesh_type == "bilayer": ab_grad_epi[band_cell_ids] = r_grad[band_cell_ids] diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 913a557..1281737 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -36,7 +36,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, vtk_append, apply_extract_cell_filter + clean_polydata, vtk_append, apply_extract_cell_filter, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -377,22 +377,13 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point plane = initialize_plane(norm_1, point_start) - meshExtractFilter1 = vtk.vtkExtractGeometry() - meshExtractFilter1.SetInputData(polydata) - meshExtractFilter1.SetImplicitFunction(plane) - meshExtractFilter1.Update() + extracted_mesh_1 = get_elements_above_plane(polydata, plane) point_moved = point_start - 2 * args.scale * norm_1 plane2 = initialize_plane(-norm_1, point_moved) - meshExtractFilter2 = vtk.vtkExtractGeometry() - meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) - meshExtractFilter2.SetImplicitFunction(plane2) - meshExtractFilter2.Update() - - band = meshExtractFilter2.GetOutput() - band = clean_polydata(apply_vtk_geom_filter(band)) + band = clean_polydata(apply_vtk_geom_filter(get_elements_above_plane(extracted_mesh_1, plane2))) if args.debug: writer_vtk(band, f'{args.mesh}_surf/' + "band_" + str(StartVertex) + "_" + str(EndVertex) + ".vtk") @@ -642,13 +633,10 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, plane = initialize_plane(-norm_1[0], moved_center[0]) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(ra_tv_s_surface) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() + extracted_mesh = get_elements_above_plane(ra_tv_s_surface, plane) connect = vtk.vtkConnectivityFilter() - connect.SetInputData(meshExtractFilter.GetOutput()) + connect.SetInputData(extracted_mesh) connect.SetExtractionModeToAllRegions() connect.Update() connect.SetExtractionModeToSpecifiedRegions() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 29b8f88..b546c48 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -41,7 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, generate_ids, \ - get_cells_with_ids, apply_extract_cell_filter + get_cells_with_ids, apply_extract_cell_filter, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -354,11 +354,7 @@ def ra_generate_fiber(model, args, job): plane = initialize_plane(norm_1, df["TV"]) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(Method.to_polydata(RAW_S)) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - septal_surf = meshExtractFilter.GetOutput() + septal_surf = get_elements_above_plane(apply_vtk_geom_filter(RAW_S), plane) RAS_S = vtk_thr(septal_surf, 0, "CELLS", "phie_w", tao_ct_plus) RAS_S = vtk_thr(RAS_S, 0, "CELLS", "phie_r", 0.05) # grad_r or w @@ -375,11 +371,7 @@ def ra_generate_fiber(model, args, job): RAW_low = vtk_thr(no_TV_s, 0, "CELLS", "phie_r", max_phie_r_ivc) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(RAW_low) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - RAS_low = meshExtractFilter.GetOutput() + RAS_low = get_elements_above_plane(RAW_low, plane) RAS_low = vtk_thr(RAS_low, 0, "CELLS", "phie_w", 0) # grad_r overwrites the previous @@ -405,11 +397,7 @@ def ra_generate_fiber(model, args, job): plane = initialize_plane(norm_1, IVC_SEPT_CT_pt) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(no_TV_s) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - septal_surf = meshExtractFilter.GetOutput() + septal_surf = get_elements_above_plane(no_TV_s, plane) if args.debug: Method.writer_vtk(septal_surf, f'{args.mesh}_surf/' + "septal_surf_2.vtk") @@ -593,11 +581,7 @@ def ra_generate_fiber(model, args, job): initialize_plane(norm_1, df["TV"]) - meshExtractFilter = vtk.vtkExtractGeometry() - meshExtractFilter.SetInputData(TV_s) - meshExtractFilter.SetImplicitFunction(plane) - meshExtractFilter.Update() - TV_lat = meshExtractFilter.GetOutput() + TV_lat = get_elements_above_plane(TV_s, plane) TV_lat = apply_vtk_geom_filter(TV_lat) diff --git a/standalones/function.py b/standalones/function.py index 02e59be..6e872d5 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -31,7 +31,8 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, \ + get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane @@ -124,21 +125,13 @@ def cut_a_band_from_model(polydata, point_1, point_2, point_3, width): plane = initialize_plane(norm_1[0], point_pass[0]) - meshExtractFilter1 = vtk.vtkExtractGeometry() - meshExtractFilter1.SetInputData(polydata) - meshExtractFilter1.SetImplicitFunction(plane) - meshExtractFilter1.Update() + extract_mesh_1 = get_elements_above_plane(polydata, plane) point_moved = point_1 - 0.5 * width * norm_1 plane2 = initialize_plane(-norm_1[0], point_moved[0]) - meshExtractFilter2 = vtk.vtkExtractGeometry() - meshExtractFilter2.SetInputData(meshExtractFilter1.GetOutput()) - meshExtractFilter2.SetImplicitFunction(plane2) - meshExtractFilter2.Update() - band = meshExtractFilter2.GetOutput() - band = apply_vtk_geom_filter(band) + band = apply_vtk_geom_filter(get_elements_above_plane(extract_mesh_1, plane2)) return band @@ -149,18 +142,8 @@ def cut_into_two_parts(polydata, point_1, point_2, point_3): plane = initialize_plane(norm_1[0], point_1) plane2 = initialize_plane(-norm_1[0], point_1) - meshExtractFilter1 = vtk.vtkExtractGeometry() - meshExtractFilter1.SetInputData(polydata) - meshExtractFilter1.SetImplicitFunction(plane) - meshExtractFilter1.Update() - sub_1 = meshExtractFilter1.GetOutput() - - meshExtractFilter2 = vtk.vtkExtractGeometry() - meshExtractFilter2.SetInputData(polydata) - meshExtractFilter2.ExtractBoundaryCellsOn() - meshExtractFilter2.SetImplicitFunction(plane2) - meshExtractFilter2.Update() - sub_2 = meshExtractFilter2.GetOutput() + sub_1 = get_elements_above_plane(polydata, plane) + sub_2 = get_elements_above_plane(polydata, plane2, extract_boundary_cells_on=True) return sub_1, sub_2 From b9859309e0ad103a3339f8a283ab22faca50fdec Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 13:35:56 +0100 Subject: [PATCH 38/70] Implemented find_closest_point into AugmentA code --- .../Generate_Boundaries/extract_rings.py | 47 ++------ .../extract_rings_TOP_epi_endo.py | 45 ++----- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 95 ++++----------- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 114 ++++-------------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 20 +-- .../LDRBM/Fiber_RA/create_bridges_test.py | 20 +-- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 95 ++++----------- standalones/function.py | 6 +- standalones/getmarks.py | 35 +++--- standalones/open_orifices_manually.py | 7 +- standalones/open_orifices_with_curvature.py | 18 +-- .../Methods_fit_to_clinical_LAT.py | 11 +- 12 files changed, 141 insertions(+), 372 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 17a65e2..240b96f 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -41,6 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -132,11 +133,8 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i id_vec = vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) # It can happen that the connectivity filter changes the ids - loc = vtk.vtkPointLocator() - loc.SetDataSet(mesh_conn) - loc.BuildLocator() - LAA_id = loc.FindClosestPoint(LA_ap_point) - RAA_id = loc.FindClosestPoint(RA_ap_point) + LAA_id = find_closest_point(mesh_conn, LA_ap_point) + RAA_id = find_closest_point(mesh_conn, RA_ap_point) LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] @@ -150,16 +148,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i vtkWrite(LA, outdir + '/LA.vtk') - loc = vtk.vtkPointLocator() - loc.SetDataSet(LA) - loc.BuildLocator() - LAA_id = loc.FindClosestPoint(LA_ap_point) + LAA_id = find_closest_point(LA, LA_ap_point) if LAA_base_id != "": - loc = vtk.vtkPointLocator() - loc.SetDataSet(LA) - loc.BuildLocator() - LAA_base_id = loc.FindClosestPoint(LA_bs_point) + LAA_base_id = find_closest_point(LA, LA_bs_point) b_tag = np.zeros((LA.GetNumberOfPoints(),)) @@ -176,16 +168,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i RA = generate_ids(RA_poly, "Ids", "Ids") - loc = vtk.vtkPointLocator() - loc.SetDataSet(RA) - loc.BuildLocator() - RAA_id = loc.FindClosestPoint(RA_ap_point) + RAA_id = find_closest_point(RA, RA_ap_point) if LAA_base_id != "": - loc = vtk.vtkPointLocator() - loc.SetDataSet(RA) - loc.BuildLocator() - RAA_base_id = loc.FindClosestPoint(RA_bs_point) + RAA_base_id = find_closest_point(RA, RA_bs_point) vtkWrite(RA, outdir + '/RA.vtk') b_tag = np.zeros((RA.GetNumberOfPoints(),)) @@ -536,20 +522,13 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): f.write(f'{i}\n') f.close() - loc = vtk.vtkPointLocator() - loc.SetDataSet(MV_ring[0].vtk_polydata) - loc.BuildLocator() + lpv_mv = find_closest_point(MV_ring[0].vtk_polydata, lpv_mean) + rpv_mv = find_closest_point(MV_ring[0].vtk_polydata, rpv_mean) - lpv_mv = loc.FindClosestPoint(lpv_mean) - rpv_mv = loc.FindClosestPoint(rpv_mean) - - loc = vtk.vtkPointLocator() - loc.SetDataSet(boundary_edges) - loc.BuildLocator() - lpv_bb = loc.FindClosestPoint(lpv_mean) - rpv_bb = loc.FindClosestPoint(rpv_mean) - lpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(lpv_mv)) - rpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) + lpv_bb = find_closest_point(boundary_edges, lpv_mean) + rpv_bb = find_closest_point(boundary_edges, rpv_mean) + lpv_mv = find_closest_point(boundary_edges, MV_ring[0].vtk_polydata.GetPoint(lpv_mv)) + rpv_mv = find_closest_point(boundary_edges, MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundary_edges) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index cc52a0b..ed0caa0 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -41,6 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -127,10 +128,7 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" id_vec = vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) # It can happen that the connectivity filter changes the ids - loc = vtk.vtkPointLocator() - loc.SetDataSet(mesh_conn) - loc.BuildLocator() - LAA_id = loc.FindClosestPoint(LA_ap_point) + LAA_id = find_closest_point(mesh_conn, LA_ap_point) LA_tag = id_vec[int(LAA_id)] RA_tag = id_vec[int(RAA_id)] @@ -148,16 +146,10 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" vtkWrite(LA, outdir + '/LA.vtp') - loc = vtk.vtkPointLocator() - loc.SetDataSet(LA) - loc.BuildLocator() - LAA_id = loc.FindClosestPoint(LA_ap_point) + LAA_id = find_closest_point(LA, LA_ap_point) if LAA_base_id != "": - loc = vtk.vtkPointLocator() - loc.SetDataSet(LA) - loc.BuildLocator() - LAA_base_id = loc.FindClosestPoint(LA_bs_point) + LAA_base_id = find_closest_point(LA, LA_bs_point) b_tag = np.zeros((LA.GetNumberOfPoints(),)) @@ -174,16 +166,10 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" RA = generate_ids(RA_poly, "Ids", "Ids") - loc = vtk.vtkPointLocator() - loc.SetDataSet(RA) - loc.BuildLocator() - RAA_id = loc.FindClosestPoint(RA_ap_point) + RAA_id = find_closest_point(RA, RA_ap_point) if LAA_base_id != "": - loc = vtk.vtkPointLocator() - loc.SetDataSet(RA) - loc.BuildLocator() - RAA_base_id = loc.FindClosestPoint(RA_bs_point) + RAA_base_id = find_closest_point(RA, RA_bs_point) vtkWrite(RA, outdir + '/RA.vtp') b_tag = np.zeros((RA.GetNumberOfPoints(),)) @@ -510,20 +496,13 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): f.write(f'{i}\n') f.close() - loc = vtk.vtkPointLocator() - loc.SetDataSet(MV_ring[0].vtk_polydata) - loc.BuildLocator() + lpv_mv = find_closest_point(MV_ring[0].vtk_polydata, lpv_mean) + rpv_mv = find_closest_point(MV_ring[0].vtk_polydata, rpv_mean) - lpv_mv = loc.FindClosestPoint(lpv_mean) - rpv_mv = loc.FindClosestPoint(rpv_mean) - - loc = vtk.vtkPointLocator() - loc.SetDataSet(boundary_edges) - loc.BuildLocator() - lpv_bb = loc.FindClosestPoint(lpv_mean) - rpv_bb = loc.FindClosestPoint(rpv_mean) - lpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(lpv_mv)) - rpv_mv = loc.FindClosestPoint(MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) + lpv_bb = find_closest_point(boundary_edges, lpv_mean) + rpv_bb = find_closest_point(boundary_edges, rpv_mean) + lpv_mv = find_closest_point(boundary_edges, MV_ring[0].vtk_polydata.GetPoint(lpv_mv)) + rpv_mv = find_closest_point(boundary_edges, MV_ring[0].vtk_polydata.GetPoint(rpv_mv)) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundary_edges) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 89e31f0..86f0883 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -40,6 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, vtk_append, apply_extract_cell_filter, get_center_of_mass, get_feature_edges, \ get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ @@ -255,12 +256,8 @@ def dijkstra_path_on_a_plane(polydata, StartVertex, EndVertex, plane_point): band = apply_vtk_geom_filter(get_elements_above_plane(extracted_mesh_1, plane2)) - # print(band) - loc = vtk.vtkPointLocator() - loc.SetDataSet(band) - loc.BuildLocator() - StartVertex = loc.FindClosestPoint(point_start) - EndVertex = loc.FindClosestPoint(point_end) + StartVertex = find_closest_point(band, point_start) + EndVertex = find_closest_point(band, point_end) points_data = dijkstra_path(band, StartVertex, EndVertex) return points_data @@ -455,12 +452,8 @@ def get_ct_end_points_id(endo, ct, scv, icv): path_icv = np.asarray([np.mean(inter_icv[:, 0]), np.mean(inter_icv[:, 1]), np.mean(inter_icv[:, 2])]) path_scv = np.asarray([np.mean(inter_scv[:, 0]), np.mean(inter_scv[:, 1]), np.mean(inter_scv[:, 2])]) - loc = vtk.vtkPointLocator() - loc.SetDataSet(endo) - loc.BuildLocator() - - path_ct_id_icv = loc.FindClosestPoint(path_icv) - path_ct_id_scv = loc.FindClosestPoint(path_scv) + path_ct_id_icv = find_closest_point(endo, path_icv) + path_ct_id_scv = find_closest_point(endo, path_scv) return path_ct_id_icv, path_ct_id_scv @@ -510,12 +503,9 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, else: center_point_icv = center_point_2 center_point_scv = center_point_1 - loc = vtk.vtkPointLocator() - loc.SetDataSet(endo) - loc.BuildLocator() - path_tv_id_icv = loc.FindClosestPoint(center_point_icv) - path_tv_id_scv = loc.FindClosestPoint(center_point_scv) + path_tv_id_icv = find_closest_point(endo, center_point_icv) + path_tv_id_scv = find_closest_point(endo, center_point_scv) return path_tv_id_icv, path_tv_id_scv @@ -600,25 +590,14 @@ def get_connection_point_la_and_ra(appen_point): la_epi_surface = smart_reader('../../Generate_Boundaries/LA/result/la_epi_surface.vtk') ra_epi_surface = smart_reader('../../Generate_Boundaries/RA/result/ra_epi_surface.vtk') - loc_mv = vtk.vtkPointLocator() - loc_mv.SetDataSet(la_mv_surface) - loc_mv.BuildLocator() - - point_1_id = loc_mv.FindClosestPoint(appen_point) + point_1_id = find_closest_point(la_mv_surface, appen_point) point_1 = la_mv_surface.GetPoint(point_1_id) - loc_rpv_inf = vtk.vtkPointLocator() - loc_rpv_inf.SetDataSet(la_rpv_inf_surface) - loc_rpv_inf.BuildLocator() - point_2_id = loc_rpv_inf.FindClosestPoint(appen_point) + point_2_id = find_closest_point(la_rpv_inf_surface, appen_point) point_2 = la_rpv_inf_surface.GetPoint(point_2_id) - loc_endo = vtk.vtkPointLocator() - loc_endo.SetDataSet(endo) - loc_endo.BuildLocator() - - point_1_id_endo = loc_endo.FindClosestPoint(point_1) - point_2_id_endo = loc_endo.FindClosestPoint(point_2) + point_1_id_endo = find_closest_point(endo, point_1) + point_2_id_endo = find_closest_point(endo, point_2) bb_aux_l_points = dijkstra_path(apply_vtk_geom_filter(endo), point_1_id_endo, point_2_id_endo) length = len(bb_aux_l_points) @@ -629,18 +608,10 @@ def get_connection_point_la_and_ra(appen_point): ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - loc_la_epi = vtk.vtkPointLocator() - loc_la_epi.SetDataSet(la_epi_surface) - loc_la_epi.BuildLocator() - - loc_ra_epi = vtk.vtkPointLocator() - loc_ra_epi.SetDataSet(ra_epi_surface) - loc_ra_epi.BuildLocator() - - la_connect_point_id = loc_la_epi.FindClosestPoint(la_connect_point) + la_connect_point_id = find_closest_point(la_epi_surface, la_connect_point) la_connect_point = la_epi_surface.GetPoint(la_connect_point_id) - ra_connect_point_id = loc_ra_epi.FindClosestPoint(la_connect_point) + ra_connect_point_id = find_closest_point(ra_epi_surface, la_connect_point) ra_connect_point = ra_epi_surface.GetPoint(ra_connect_point_id) return la_connect_point, ra_connect_point @@ -733,21 +704,14 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): endo = smart_reader('../../Generate_Boundaries/LA/result/la_endo_surface.vtk') epi = smart_reader('../../Generate_Boundaries/LA/result/la_epi_surface.vtk') - loc_mv = vtk.vtkPointLocator() - loc_mv.SetDataSet(la_mv_surface) - loc_mv.BuildLocator() - - loc_epi = vtk.vtkPointLocator() - loc_epi.SetDataSet(epi) - loc_epi.BuildLocator() - - appendage_basis_id = loc_epi.FindClosestPoint(appendage_basis) - lpv_sup_basis_id = loc_epi.FindClosestPoint(lpv_sup_basis) + appendage_basis_id = find_closest_point(epi, appendage_basis) + lpv_sup_basis_id = find_closest_point(epi, lpv_sup_basis) left_inf_pv_center = get_mean_point(la_lpv_inf_surface) - point_l1_id = loc_mv.FindClosestPoint(left_inf_pv_center) + point_l1_id = find_closest_point(la_mv_surface, left_inf_pv_center) point_l1 = la_mv_surface.GetPoint(point_l1_id) - bb_mv_id = loc_epi.FindClosestPoint(point_l1) + + bb_mv_id = find_closest_point(epi, point_l1) bb_1_points = dijkstra_path(apply_vtk_geom_filter(epi), lpv_sup_basis_id, appendage_basis_id) bb_2_points = dijkstra_path(apply_vtk_geom_filter(epi), appendage_basis_id, bb_mv_id) @@ -810,22 +774,14 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e MV = thresh.GetOutput() # Get the closest point to the inferior appendage base in the MV - loc = vtk.vtkPointLocator() - loc.SetDataSet(MV) - loc.BuildLocator() - - bb_mv = MV.GetPoint(loc.FindClosestPoint(bb_mv_laa)) + bb_mv = MV.GetPoint(find_closest_point(MV, bb_mv_laa)) thresh = get_threshold_between(epi, left_atrial_appendage_epi, left_atrial_appendage_epi, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "elemTag") - loc = vtk.vtkPointLocator() - loc.SetDataSet(thresh.GetOutput()) - # loc.SetDataSet(epi) - loc.BuildLocator() - LAA_pt_far_from_LIPV_id = loc.FindClosestPoint(LAA_pt_far_from_LIPV) - inf_appendage_basis_id = loc.FindClosestPoint(inf_appendage_basis) - sup_appendage_basis_id = loc.FindClosestPoint(sup_appendage_basis) - bb_mv_id = loc.FindClosestPoint(bb_mv) + LAA_pt_far_from_LIPV_id = find_closest_point(thresh.GetOutput(), LAA_pt_far_from_LIPV) + inf_appendage_basis_id = find_closest_point(thresh.GetOutput(), inf_appendage_basis) + sup_appendage_basis_id = find_closest_point(thresh.GetOutput(), sup_appendage_basis) + bb_mv_id = find_closest_point(thresh.GetOutput(), bb_mv) bb_left = get_wide_bachmann_path_left(thresh.GetOutput(), inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id) @@ -835,10 +791,7 @@ def compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_e def get_in_surf1_closest_point_in_surf2(surf1, surf2, pt_id_in_surf2): - loc = vtk.vtkPointLocator() - loc.SetDataSet(surf1) - loc.BuildLocator() - return loc.FindClosestPoint(surf2.GetPoint(pt_id_in_surf2)) + return find_closest_point(surf1, surf2.GetPoint(pt_id_in_surf2)) def get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis_id, bb_mv_id, LAA_pt_far_from_LIPV_id): diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 1281737..aca1912 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -37,6 +37,7 @@ vtk_xml_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, vtk_append, apply_extract_cell_filter, get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -351,11 +352,8 @@ def dijkstra_path(polydata, StartVertex, EndVertex): def dijkstra_path_coord(polydata, StartVertex, EndVertex): - loc = vtk.vtkPointLocator() - loc.SetDataSet(polydata) - loc.BuildLocator() - StartVertex = loc.FindClosestPoint(StartVertex) - EndVertex = loc.FindClosestPoint(EndVertex) + StartVertex = find_closest_point(polydata, StartVertex) + EndVertex = find_closest_point(polydata, EndVertex) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(polydata) @@ -388,11 +386,8 @@ def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point if args.debug: writer_vtk(band, f'{args.mesh}_surf/' + "band_" + str(StartVertex) + "_" + str(EndVertex) + ".vtk") - loc = vtk.vtkPointLocator() - loc.SetDataSet(band) - loc.BuildLocator() - StartVertex = loc.FindClosestPoint(point_start) - EndVertex = loc.FindClosestPoint(point_end) + StartVertex = find_closest_point(band, point_start) + EndVertex = find_closest_point(band, point_end) points_data = dijkstra_path(band, StartVertex, EndVertex) return points_data @@ -613,12 +608,8 @@ def get_ct_end_points_id(endo, ct, scv, icv): path_icv = np.asarray([np.mean(inter_icv[:, 0]), np.mean(inter_icv[:, 1]), np.mean(inter_icv[:, 2])]) path_scv = np.asarray([np.mean(inter_scv[:, 0]), np.mean(inter_scv[:, 1]), np.mean(inter_scv[:, 2])]) - loc = vtk.vtkPointLocator() - loc.SetDataSet(endo) - loc.BuildLocator() - - path_ct_id_icv = loc.FindClosestPoint(path_icv) - path_ct_id_scv = loc.FindClosestPoint(path_scv) + path_ct_id_icv = find_closest_point(endo, path_icv) + path_ct_id_scv = find_closest_point(endo, path_scv) return path_ct_id_icv, path_ct_id_scv @@ -669,12 +660,9 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, else: center_point_icv = center_point_2 center_point_scv = center_point_1 - loc = vtk.vtkPointLocator() - loc.SetDataSet(endo) - loc.BuildLocator() - path_tv_id_icv = loc.FindClosestPoint(center_point_icv) - path_tv_id_scv = loc.FindClosestPoint(center_point_scv) + path_tv_id_icv = find_closest_point(endo, center_point_icv) + path_tv_id_scv = find_closest_point(endo, center_point_scv) return path_tv_id_icv, path_tv_id_scv @@ -751,25 +739,14 @@ def get_endo_ct_intersection_cells(endo, ct): def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_inf_surface, la_epi_surface, ra_epi_surface): - loc_mv = vtk.vtkPointLocator() - loc_mv.SetDataSet(la_mv_surface) - loc_mv.BuildLocator() - - point_1_id = loc_mv.FindClosestPoint(appen_point) + point_1_id = find_closest_point(la_mv_surface, appen_point) point_1 = la_mv_surface.GetPoint(point_1_id) - loc_rpv_inf = vtk.vtkPointLocator() - loc_rpv_inf.SetDataSet(la_rpv_inf_surface) - loc_rpv_inf.BuildLocator() - point_2_id = loc_rpv_inf.FindClosestPoint(appen_point) + point_2_id = find_closest_point(la_rpv_inf_surface, appen_point) point_2 = la_rpv_inf_surface.GetPoint(point_2_id) - loc = vtk.vtkPointLocator() - loc.SetDataSet(la_epi_surface) - loc.BuildLocator() - - point_1_id = loc.FindClosestPoint(point_1) - point_2_id = loc.FindClosestPoint(point_2) + point_1_id = find_closest_point(la_epi_surface, point_1) + point_2_id = find_closest_point(la_epi_surface, point_2) bb_aux_l_points = dijkstra_path(apply_vtk_geom_filter(la_epi_surface), point_1_id, point_2_id) length = len(bb_aux_l_points) @@ -777,21 +754,12 @@ def get_connection_point_la_and_ra_surface(appen_point, la_mv_surface, la_rpv_in # ra la_epi_surface = apply_vtk_geom_filter(la_epi_surface) - ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - loc_la_epi = vtk.vtkPointLocator() - loc_la_epi.SetDataSet(la_epi_surface) - loc_la_epi.BuildLocator() - - loc_ra_epi = vtk.vtkPointLocator() - loc_ra_epi.SetDataSet(ra_epi_surface) - loc_ra_epi.BuildLocator() - - la_connect_point_id = loc_la_epi.FindClosestPoint(la_connect_point) + la_connect_point_id = find_closest_point(la_epi_surface, la_connect_point) la_connect_point = la_epi_surface.GetPoint(la_connect_point_id) - ra_connect_point_id = loc_ra_epi.FindClosestPoint(la_connect_point) + ra_connect_point_id = find_closest_point(ra_epi_surface, la_connect_point) ra_connect_point = ra_epi_surface.GetPoint(ra_connect_point_id) return la_connect_point, ra_connect_point @@ -804,25 +772,14 @@ def get_connection_point_la_and_ra(appen_point): la_epi_surface = smart_reader('../../Generate_Boundaries/LA/result/la_epi_surface.vtk') ra_epi_surface = smart_reader('../../Generate_Boundaries/RA/result/ra_epi_surface.vtk') - loc_mv = vtk.vtkPointLocator() - loc_mv.SetDataSet(la_mv_surface) - loc_mv.BuildLocator() - - point_1_id = loc_mv.FindClosestPoint(appen_point) + point_1_id = find_closest_point(la_mv_surface, appen_point) point_1 = la_mv_surface.GetPoint(point_1_id) - loc_rpv_inf = vtk.vtkPointLocator() - loc_rpv_inf.SetDataSet(la_rpv_inf_surface) - loc_rpv_inf.BuildLocator() - point_2_id = loc_rpv_inf.FindClosestPoint(appen_point) + point_2_id = find_closest_point(la_rpv_inf_surface, appen_point) point_2 = la_rpv_inf_surface.GetPoint(point_2_id) - loc_endo = vtk.vtkPointLocator() - loc_endo.SetDataSet(endo) - loc_endo.BuildLocator() - - point_1_id_endo = loc_endo.FindClosestPoint(point_1) - point_2_id_endo = loc_endo.FindClosestPoint(point_2) + point_1_id_endo = find_closest_point(endo, point_1) + point_2_id_endo = find_closest_point(endo, point_2) bb_aux_l_points = dijkstra_path(apply_vtk_geom_filter(endo), point_1_id_endo, point_2_id_endo) length = len(bb_aux_l_points) @@ -833,18 +790,10 @@ def get_connection_point_la_and_ra(appen_point): ra_epi_surface = apply_vtk_geom_filter(ra_epi_surface) - loc_la_epi = vtk.vtkPointLocator() - loc_la_epi.SetDataSet(la_epi_surface) - loc_la_epi.BuildLocator() - - loc_ra_epi = vtk.vtkPointLocator() - loc_ra_epi.SetDataSet(ra_epi_surface) - loc_ra_epi.BuildLocator() - - la_connect_point_id = loc_la_epi.FindClosestPoint(la_connect_point) + la_connect_point_id = find_closest_point(la_epi_surface, la_connect_point) la_connect_point = la_epi_surface.GetPoint(la_connect_point_id) - ra_connect_point_id = loc_ra_epi.FindClosestPoint(la_connect_point) + ra_connect_point_id = find_closest_point(ra_epi_surface, la_connect_point) ra_connect_point = ra_epi_surface.GetPoint(ra_connect_point_id) return la_connect_point, ra_connect_point @@ -856,21 +805,13 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): endo = smart_reader('../../Generate_Boundaries/LA/result/la_endo_surface.vtk') epi = smart_reader('../../Generate_Boundaries/LA/result/la_epi_surface.vtk') - loc_mv = vtk.vtkPointLocator() - loc_mv.SetDataSet(la_mv_surface) - loc_mv.BuildLocator() - - loc_epi = vtk.vtkPointLocator() - loc_epi.SetDataSet(epi) - loc_epi.BuildLocator() - - appendage_basis_id = loc_epi.FindClosestPoint(appendage_basis) - lpv_sup_basis_id = loc_epi.FindClosestPoint(lpv_sup_basis) + appendage_basis_id = find_closest_point(epi, appendage_basis) + lpv_sup_basis_id = find_closest_point(epi, lpv_sup_basis) left_inf_pv_center = get_mean_point(la_lpv_inf_surface) - point_l1_id = loc_mv.FindClosestPoint(left_inf_pv_center) + point_l1_id = find_closest_point(la_mv_surface, left_inf_pv_center) point_l1 = la_mv_surface.GetPoint(point_l1_id) - bb_mv_id = loc_epi.FindClosestPoint(point_l1) + bb_mv_id = find_closest_point(epi, point_l1) epi_polydata = apply_vtk_geom_filter(epi) @@ -883,10 +824,7 @@ def get_bachmann_path_left(appendage_basis, lpv_sup_basis): def create_free_bridge_semi_auto(la_epi, ra_epi, ra_point, radius): - loc_la_epi = vtk.vtkPointLocator() - loc_la_epi.SetDataSet(la_epi) - loc_la_epi.BuildLocator() - point_end_id = loc_la_epi.FindClosestPoint(ra_point) + point_end_id = find_closest_point(la_epi, ra_point) point_end = la_epi.GetPoint(point_end_id) start = np.asarray(ra_point) end = np.asarray(point_end) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index ef2a7f3..4ab556f 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -43,6 +43,7 @@ vtk_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append, \ apply_extract_cell_filter, get_cells_with_ids +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -85,12 +86,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): tv_ra = vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) # Find middle and upper posterior bridges points - - loc = vtk.vtkPointLocator() - loc.SetDataSet(ra_septum) - loc.BuildLocator() - point_septum_SVC = ra_septum.GetPoint(loc.FindClosestPoint(SVC_p)) - point_septum_IVC = ra_septum.GetPoint(loc.FindClosestPoint(IVC_p)) + point_septum_SVC = ra_septum.GetPoint(find_closest_point(ra_septum, SVC_p)) + point_septum_IVC = ra_septum.GetPoint(find_closest_point(ra_septum, IVC_p)) SVC_IVC_septum_path = Method.dijkstra_path_coord(ra_epi_surface, point_septum_SVC, point_septum_IVC) @@ -116,15 +113,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # Coronary sinus bridge point - loc = vtk.vtkPointLocator() # it happened that the point is too close to the edge and the heart is not found - loc.SetDataSet(mv_la) - loc.BuildLocator() - point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p + TV_p * 0.1)) # adapt this value if CS is too low + # it happened that the point is too close to the edge and the heart is not found + point_CS_on_MV = mv_la.GetPoint(find_closest_point(mv_la, CS_p + TV_p * 0.1)) # adapt this value if CS is too low - loc = vtk.vtkPointLocator() - loc.SetDataSet(ra_septum) - loc.BuildLocator() - point_CS_bridge = ra_septum.GetPoint(loc.FindClosestPoint(point_CS_on_MV)) + point_CS_bridge = ra_septum.GetPoint(find_closest_point(ra_septum, point_CS_on_MV)) csb_tube, csb_sphere_1, csb_sphere_2, csb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, ra_epi_surface, diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index ec66717..890d241 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -45,6 +45,7 @@ vtk_unstructured_grid_writer, vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, vtk_append, \ apply_extract_cell_filter, get_cells_with_ids +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -137,12 +138,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): tv_ra = vtk_thr(ra_epi, 2, "CELLS", "elemTag", tricuspid_valve_epi, tricuspid_valve_epi) # Find middle and upper posterior bridges points - - loc = vtk.vtkPointLocator() - loc.SetDataSet(ra_septum) - loc.BuildLocator() - point_septum_SVC = ra_septum.GetPoint(loc.FindClosestPoint(SVC_p)) - point_septum_IVC = ra_septum.GetPoint(loc.FindClosestPoint(IVC_p)) + point_septum_SVC = ra_septum.GetPoint(find_closest_point(ra_septum, SVC_p)) + point_septum_IVC = ra_septum.GetPoint(find_closest_point(ra_septum, IVC_p)) SVC_IVC_septum_path = Method.dijkstra_path_coord(ra_epi_surface, point_septum_SVC, point_septum_IVC) @@ -164,15 +161,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # Coronary sinus bridge point - loc = vtk.vtkPointLocator() # it happened that the point is too close to the edge and the heart is not found - loc.SetDataSet(mv_la) - loc.BuildLocator() - point_CS_on_MV = mv_la.GetPoint(loc.FindClosestPoint(CS_p + TV_p * 0.1)) + # it happened that the point is too close to the edge and the heart is not found + point_CS_on_MV = mv_la.GetPoint(find_closest_point(mv_la, CS_p + TV_p * 0.1)) - loc = vtk.vtkPointLocator() - loc.SetDataSet(ra_septum) - loc.BuildLocator() - point_CS_bridge = ra_septum.GetPoint(loc.FindClosestPoint(point_CS_on_MV)) + point_CS_bridge = ra_septum.GetPoint(find_closest_point(ra_septum, point_CS_on_MV)) csb_tube, csb_sphere_1, csb_sphere_2, csb_fiber = Method.create_free_bridge_semi_auto(la_epi_surface, ra_epi_surface, diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index b546c48..220293e 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -42,6 +42,7 @@ vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, generate_ids, \ get_cells_with_ids, apply_extract_cell_filter, get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -249,13 +250,9 @@ def ra_generate_fiber(model, args, job): mesh_surf = apply_vtk_geom_filter(CT_band) - loc = vtk.vtkPointLocator() - loc.SetDataSet(mesh_surf) - loc.BuildLocator() - - IVC_CT_pt_id = loc.FindClosestPoint(np.array(IVC_CT_pt)) + IVC_CT_pt_id = find_closest_point(mesh_surf, np.array(IVC_CT_pt)) - SVC_CT_pt_id = loc.FindClosestPoint(np.array(SVC_CT_pt)) + SVC_CT_pt_id = find_closest_point(mesh_surf, np.array(SVC_CT_pt)) CT_ub_pts = Method.dijkstra_path(mesh_surf, IVC_CT_pt_id, SVC_CT_pt_id) @@ -280,21 +277,13 @@ def ra_generate_fiber(model, args, job): tao_RAA = np.max(vtk_to_numpy(CT_band.GetCellData().GetArray('phie_v2'))) - loc = vtk.vtkPointLocator() - loc.SetDataSet(CT_band) - loc.BuildLocator() - - IVC_CT_pt_id = loc.FindClosestPoint(np.array(IVC_CT_pt)) + IVC_CT_pt_id = find_closest_point(CT_band, np.array(IVC_CT_pt)) no_IVC_s = apply_vtk_geom_filter(no_IVC_s) - loc = vtk.vtkPointLocator() - loc.SetDataSet(no_IVC_s) - loc.BuildLocator() - - IVC_CT_pt_id = loc.FindClosestPoint(np.array(CT_band.GetPoint(IVC_CT_pt_id))) - IVC_max_r_CT_pt_id = loc.FindClosestPoint(np.array(IVC_max_r_CT_pt)) - IVC_SEPT_CT_pt_id = loc.FindClosestPoint(np.array(IVC_SEPT_CT_pt)) + IVC_CT_pt_id = find_closest_point(no_IVC_s, np.array(CT_band.GetPoint(IVC_CT_pt_id))) + IVC_max_r_CT_pt_id = find_closest_point(no_IVC_s, np.array(IVC_max_r_CT_pt)) + IVC_SEPT_CT_pt_id = find_closest_point(no_IVC_s, np.array(IVC_SEPT_CT_pt)) CT_SEPT_path = np.concatenate((Method.dijkstra_path(no_IVC_s, IVC_CT_pt_id, IVC_max_r_CT_pt_id), Method.dijkstra_path(no_IVC_s, IVC_max_r_CT_pt_id, IVC_SEPT_CT_pt_id)), axis=0) @@ -426,11 +415,7 @@ def ra_generate_fiber(model, args, job): tag[RAA_ids] = right_atrial_appendage_epi - loc = vtk.vtkPointLocator() - loc.SetDataSet(CT_band) - loc.BuildLocator() - - RAA_CT_pt = CT_band.GetPoint(loc.FindClosestPoint(np.array(df["RAA"]))) + RAA_CT_pt = CT_band.GetPoint(find_closest_point(CT_band, np.array(df["RAA"]))) CT = CT_band @@ -554,19 +539,12 @@ def ra_generate_fiber(model, args, job): vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/RA_epi_with_fiber.vtu", meshNew.VTKObject) center = np.asarray((np.array(df["SVC"]) + np.array(df["IVC"])) / 2) - loc = vtk.vtkPointLocator() - loc.SetDataSet(CT) - loc.BuildLocator() - - point1_id = loc.FindClosestPoint(IVC_max_r_CT_pt) - point2_id = loc.FindClosestPoint(SVC_CT_pt) + point1_id = find_closest_point(CT, IVC_max_r_CT_pt) + point2_id = find_closest_point(CT, SVC_CT_pt) - loc = vtk.vtkPointLocator() - loc.SetDataSet(TV_s) - loc.BuildLocator() - - point3_id = loc.FindClosestPoint(IVC_max_r_CT_pt) - point4_id = loc.FindClosestPoint(np.array(df["RAA"])) # this is also the id for Bachmann-Bundle on the right atrium + point3_id = find_closest_point(TV_s, IVC_max_r_CT_pt) + point4_id = find_closest_point(TV_s, + np.array(df["RAA"])) # this is also the id for Bachmann-Bundle on the right atrium CT = apply_vtk_geom_filter(CT) @@ -595,13 +573,10 @@ def ra_generate_fiber(model, args, job): if args.debug: Method.create_pts(ct_points_data, 'ct_points_data', f'{args.mesh}_surf/') - loc = vtk.vtkPointLocator() - loc.SetDataSet(TV_lat) - loc.BuildLocator() + point3_id = find_closest_point(TV_lat, TV_s.GetPoint(point3_id)) - point3_id = loc.FindClosestPoint(TV_s.GetPoint(point3_id)) - point4_id = loc.FindClosestPoint( - TV_s.GetPoint(point4_id)) # this is also the id for Bachmann-Bundle on the right atrium + # this is also the id for Bachmann-Bundle on the right atrium + point4_id = find_closest_point(TV_lat, TV_s.GetPoint(point4_id)) tv_points_data = Method.dijkstra_path(TV_lat, point3_id, point4_id) @@ -635,6 +610,7 @@ def ra_generate_fiber(model, args, job): loc = vtk.vtkPointLocator() loc.SetDataSet(surface) loc.BuildLocator() + point_apx_id = loc.FindClosestPoint(np.array(df["RAA"])) pm_ct_id_list = [] for i in range(len(ct_points_data)): @@ -651,11 +627,8 @@ def ra_generate_fiber(model, args, job): print("Creating Pectinate muscle 1") # the first PM is the one to the appendage # pm = Method.dijkstra_path(surface, pm_ct_id_list[-1], point_apx_id) - loc = vtk.vtkPointLocator() - loc.SetDataSet(surface) - loc.BuildLocator() - RAA_CT_id = loc.FindClosestPoint(RAA_CT_pt) + RAA_CT_id = find_closest_point(surface, RAA_CT_pt) # Pectinate muscle going from the septum spurius to the RAA apex pm = Method.dijkstra_path(surface, RAA_CT_id, point_apx_id) @@ -821,20 +794,12 @@ def ra_generate_fiber(model, args, job): if args.mesh_type == "vol": surface = apply_vtk_geom_filter(epi) - loc = vtk.vtkPointLocator() - loc.SetDataSet(RAS_S) - loc.BuildLocator() - - bb_c_id = loc.FindClosestPoint((np.array(df["TV"]) + np.array(df["SVC"])) / 2) - - loc = vtk.vtkPointLocator() - loc.SetDataSet(surface) - loc.BuildLocator() + bb_c_id = find_closest_point(RAS_S, (np.array(df["TV"]) + np.array(df["SVC"])) / 2) # Bachmann-Bundle starting point - bb_1_id = loc.FindClosestPoint(SVC_CT_pt) - bb_2_id = loc.FindClosestPoint(TV_lat.GetPoint(point4_id)) - bb_c_id = loc.FindClosestPoint(RAS_S.GetPoint(bb_c_id)) + bb_1_id = find_closest_point(surface, SVC_CT_pt) + bb_2_id = find_closest_point(surface, TV_lat.GetPoint(point4_id)) + bb_c_id = find_closest_point(surface, RAS_S.GetPoint(bb_c_id)) bachmann_bundle_points_data_1 = Method.dijkstra_path(surface, bb_1_id, bb_c_id) @@ -930,18 +895,10 @@ def ra_generate_fiber(model, args, job): else: ra_epi = surface - loc_la_epi = vtk.vtkPointLocator() - loc_la_epi.SetDataSet(la_epi) - loc_la_epi.BuildLocator() - - loc_ra_epi = vtk.vtkPointLocator() - loc_ra_epi.SetDataSet(ra_epi) - loc_ra_epi.BuildLocator() - - ra_a_id = loc_ra_epi.FindClosestPoint(ra_bb_center) - la_c_id = loc_la_epi.FindClosestPoint(ra_bb_center) - ra_b_id = loc_ra_epi.FindClosestPoint(la_epi.GetPoint(la_c_id)) - la_d_id = loc_la_epi.FindClosestPoint(la_appendage_basis_point) + ra_a_id = find_closest_point(ra_epi, ra_bb_center) + la_c_id = find_closest_point(la_epi, ra_bb_center) + ra_b_id = find_closest_point(ra_epi, la_epi.GetPoint(la_c_id)) + la_d_id = find_closest_point(la_epi, la_appendage_basis_point) path_1 = Method.dijkstra_path(ra_epi, ra_a_id, ra_b_id) path_2 = Method.dijkstra_path(la_epi, la_c_id, la_d_id) diff --git a/standalones/function.py b/standalones/function.py index 6e872d5..6f847cf 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -33,6 +33,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, \ get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane @@ -197,10 +198,7 @@ def get_mv_l_and_r(mv_band, center_lpv): def get_closest_point_id_from_polydata(polydata, coordiante): - loc = vtk.vtkPointLocator() - loc.SetDataSet(polydata) - loc.BuildLocator() - return loc.FindClosestPoint(coordiante) + return find_closest_point(polydata, coordiante) def multidim_intersect(arr1, arr2): diff --git a/standalones/getmarks.py b/standalones/getmarks.py index 8b5ae2d..83aaf09 100644 --- a/standalones/getmarks.py +++ b/standalones/getmarks.py @@ -33,6 +33,7 @@ import standalones.function as function from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between @@ -71,18 +72,16 @@ def get_landmarks(mesh, prealigned=1, scale=1): thr = get_threshold_between(model, 5, 5, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") rsv = thr.GetOutput() - thr = get_threshold_between(model, 4, 4,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag" ) + thr = get_threshold_between(model, 4, 4, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") riv = thr.GetOutput() - - thr=get_threshold_between(model,3,3,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") + thr = get_threshold_between(model, 3, 3, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") lsv = thr.GetOutput() - - thr=get_threshold_between(model,2,2,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") + thr = get_threshold_between(model, 2, 2, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") liv = thr.GetOutput() - thr=get_threshold_between(model,1,1,"vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") + thr = get_threshold_between(model, 1, 1, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "boundary_tag") mv = thr.GetOutput() rsv_points = vtk_to_numpy(rsv.GetPoints().GetData()) @@ -113,23 +112,17 @@ def get_landmarks(mesh, prealigned=1, scale=1): mv_l_fuzzy, mv_r_fuzzy = function.get_mv_l_and_r(mv_band, center_lpv) # mv_anterior - loc_an = vtk.vtkPointLocator() - loc_an.SetDataSet(mv_anterior) - loc_an.BuildLocator() - mv_an_l = mv_anterior.GetPoint(loc_an.FindClosestPoint(mv_l_fuzzy)) - mv_an_r = mv_anterior.GetPoint(loc_an.FindClosestPoint(mv_r_fuzzy)) + mv_an_l = mv_anterior.GetPoint(find_closest_point(mv_anterior, mv_l_fuzzy)) + mv_an_r = mv_anterior.GetPoint(find_closest_point(mv_anterior, mv_r_fuzzy)) # mv_posterior - loc_po = vtk.vtkPointLocator() - loc_po.SetDataSet(mv_posterior) - loc_po.BuildLocator() - mv_po_l = mv_posterior.GetPoint(loc_po.FindClosestPoint(mv_l_fuzzy)) - mv_po_r = mv_posterior.GetPoint(loc_po.FindClosestPoint(mv_r_fuzzy)) - - path_an = function.dijkstra_path(function.to_polydata(mv_anterior), loc_an.FindClosestPoint(mv_l_fuzzy), - loc_an.FindClosestPoint(mv_r_fuzzy)) - path_po = function.dijkstra_path(function.to_polydata(mv_posterior), loc_po.FindClosestPoint(mv_l_fuzzy), - loc_po.FindClosestPoint(mv_r_fuzzy)) + mv_po_l = mv_posterior.GetPoint(find_closest_point(mv_posterior, mv_l_fuzzy)) + mv_po_r = mv_posterior.GetPoint(find_closest_point(mv_posterior, mv_r_fuzzy)) + + path_an = function.dijkstra_path(function.to_polydata(mv_anterior), find_closest_point(mv_anterior, mv_l_fuzzy), + find_closest_point(mv_anterior, mv_r_fuzzy)) + path_po = function.dijkstra_path(function.to_polydata(mv_posterior), find_closest_point(mv_posterior, mv_l_fuzzy), + find_closest_point(mv_posterior, mv_r_fuzzy)) length_an = len(path_an) mv_an_middle = path_an[int(length_an * 0.5)] diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 476ec86..6caba6e 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -40,6 +40,7 @@ from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_mesh_with_radius from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper @@ -149,10 +150,8 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, vessels_cutt apex = pick_point(mesh_from_vtk, "atrial appendage apex") model = smart_reader(f"{full_path}/{atrium}_cutted.vtk") - loc = vtk.vtkPointLocator() - loc.SetDataSet(model) - loc.BuildLocator() - apex_id = loc.FindClosestPoint(apex) + + apex_id = find_closest_point(model, apex) if atrium == "LA": LAA = apex_id elif atrium == "RA": diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 7c58745..40d332b 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -44,6 +44,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_cells_with_ids, get_center_of_mass +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -226,10 +227,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu apex = p.picked_point p.close() - loc = vtk.vtkPointLocator() - loc.SetDataSet(model) - loc.BuildLocator() - apex_id = loc.FindClosestPoint(apex) + + apex_id = find_closest_point(model, apex) if atrium == "LA": LAA = apex_id @@ -246,11 +245,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p.show() if p.picked_point is not None: - loc = vtk.vtkPointLocator() - loc.SetDataSet(model) - loc.BuildLocator() transeptal_punture_id = vtk_to_numpy(model.GetPointData().GetArray('Ids'))[ - loc.FindClosestPoint(p.picked_point)] + find_closest_point(model, p.picked_point)] p.close() for i in range(num): @@ -354,10 +350,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu p.close() model = smart_reader(f"{full_path}/{atrium}_cutted.vtk") - loc = vtk.vtkPointLocator() - loc.SetDataSet(model) - loc.BuildLocator() - apex_id = loc.FindClosestPoint(apex) + + apex_id = find_closest_point(model, apex) if atrium == "LA": LAA = apex_id elif atrium == "RA": diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index e02dd00..94c0895 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -37,6 +37,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_cells_with_ids +from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -136,10 +137,7 @@ def low_vol_LAT(args, path): max_pt = np.mean(not_low_volt_endo_pts[ii][ids], axis=0) - loc = vtk.vtkPointLocator() - loc.SetDataSet(not_low_volt_endo) - loc.BuildLocator() - args.max_LAT_id = loc.FindClosestPoint(max_pt) + args.max_LAT_id = find_closest_point(not_low_volt_endo, max_pt) max_pt = np.array(not_low_volt_endo.GetPoint(args.max_LAT_id)) args.LaAT = np.max(LAT_not_low_volt) @@ -150,10 +148,7 @@ def low_vol_LAT(args, path): stim_pt = np.mean(not_low_volt_endo_pts[ii][ids], axis=0) - loc = vtk.vtkPointLocator() - loc.SetDataSet(not_low_volt_endo) - loc.BuildLocator() - stim_pt_id = loc.FindClosestPoint(stim_pt) + stim_pt_id = find_closest_point(not_low_volt_endo, stim_pt) stim_pt = np.array(not_low_volt_endo.GetPoint(stim_pt_id)) min_LAT = np.min(LAT_not_low_volt[ii]) From 80b135b5dfac2b438198a514fe72d2ad4fefb1c1 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 13:52:38 +0100 Subject: [PATCH 39/70] Implemented write_to_dat into AugmentA code --- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 2 -- .../Methods_fit_to_clinical_LAT.py | 7 ++--- ...tune_conductivities_to_fit_clinical_LAT.py | 30 ++++++------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 220293e..ec23da8 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -601,10 +601,8 @@ def ra_generate_fiber(model, args, job): elif args.mesh_type == "bilayer": - fiber_endo = el.copy() tag_endo = np.copy(tag) - surface = apply_vtk_geom_filter(endo) loc = vtk.vtkPointLocator() diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 94c0895..c05d388 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -39,6 +39,7 @@ clean_polydata, generate_ids, get_cells_with_ids from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader +from vtk_opencarp_helper_methods.writer import write_to_dat vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -351,11 +352,7 @@ def low_CV(model, low_CV_thr, meshfold): sigma = np.ones((model.GetNumberOfCells(),)) sigma[low_CV_ids] = 0.6 ** 2 # low_sigma - - f = open(meshfold + '/low_CV.dat', 'w') - for i in sigma: - f.write(f"{i:.4f}\n") - f.close() + write_to_dat(meshfold + '/low_CV.dat', sigma) def dijkstra_path(polydata, StartVertex, EndVertex): diff --git a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py index f457a04..7f62fb3 100644 --- a/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/tune_conductivities_to_fit_clinical_LAT.py @@ -29,6 +29,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_xml_unstructured_grid_writer from vtk_opencarp_helper_methods.vtk_methods.filters import generate_ids from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader +from vtk_opencarp_helper_methods.writer import write_to_dat EXAMPLE_DESCRIPTIVE_NAME = 'Tune conductivities to fit clinical LAT map' EXAMPLE_AUTHOR = 'Luca Azzolin ' @@ -420,15 +421,8 @@ def run(args, job): slow_CV_old = np.ones((len(endo_ids),)) # Create the conductivity scale map with ones factors as initial condition - f = open(simid + '/low_CV.dat', 'w') - for i in slow_CV: - f.write(f"{i:.4f}\n") - f.close() - - f = open(simid + '/low_CV_old.dat', 'w') - for i in slow_CV: - f.write(f"{i:.4f}\n") - f.close() + write_to_dat(simid + '/low_CV.dat', slow_CV) + write_to_dat(simid + '/low_CV_old.dat', slow_CV) final_diff = [] old_cells = np.array([], dtype=int) @@ -671,10 +665,9 @@ def run(args, job): LAT_diff = RMSE os.rename(simid + '/low_CV.dat', simid + '/low_CV_old.dat') - f = open(simid + '/low_CV.dat', 'w') - for i in slow_CV: - f.write(f"{i:.4f}\n") - f.close() + + write_to_dat(simid + '/low_CV.dat', slow_CV) + it += 1 else: old_cells = np.union1d(old_cells, active_cells_old_old) @@ -751,10 +744,8 @@ def run(args, job): print(f"Final last ACT: {last_ACT}") print(f"Final giL: {args.giL}") print(f"Final geL: {args.geL}") - f = open(job.ID + '/err.dat', 'w') - for i in final_diff: - f.write(f"{i:.4f}\n") - f.close() + + write_to_dat(job.ID + '/err.dat', final_diff) if os.path.exists('RMSE_patients.txt'): append_write = 'a' # append if already exists @@ -769,10 +760,7 @@ def run(args, job): slow_CV_bil[endo_ids] = slow_CV slow_CV_bil[endo_ids + len(endo_ids)] = slow_CV - f = open(meshfold + f'/low_CV_3_{args.step}_{args.thr}.dat', 'w') - for i in slow_CV_bil: - f.write(f"{i:.4f}\n") - f.close() + write_to_dat(meshfold + f'/low_CV_3_{args.step}_{args.thr}.dat', slow_CV_bil) meshNew = dsa.WrapDataObject(new_endo) meshNew.PointData.append(lats, "lat_s") From ef64a6a9151aec936340ad0bf624e42cf89085c5 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 14:40:37 +0100 Subject: [PATCH 40/70] Included write to vtx to AugmentA --- .../Generate_Boundaries/extract_rings.py | 125 +++-------------- .../extract_rings_TOP_epi_endo.py | 132 +++--------------- .../Generate_Boundaries/generate_surf_id.py | 14 +- .../LDRBM/Fiber_LA/la_generate_fiber.py | 10 +- 4 files changed, 42 insertions(+), 239 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 240b96f..b1f2831 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -38,7 +38,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk -from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point @@ -324,15 +324,6 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): for r in rings: id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + f'/ids_{r.name}.vtx' - if os.path.exists(fname): - id_vec = id_vec[0:len(id_vec) - 1] - f = open(fname, 'a') - else: - f = open(fname, 'w') - f.write(f'{len(id_vec)}\n') - f.write('extra\n') - if r.name == "MV": b_tag[id_vec] = 1 elif r.name == "LIPV": @@ -348,34 +339,13 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): b_tag[id_vec] = 5 RPV = RPV + list(id_vec) - for i in id_vec: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + f'/ids_{r.name}.vtx', id_vec, True) centroids[r.name] = r.center - fname = outdir + '/ids_LAA.vtx' - f = open(fname, 'w') - f.write(f'{1}\n') - f.write('extra\n') - f.write(f'{LAA_id}\n') - f.close() - - fname = outdir + '/ids_LPV.vtx' - f = open(fname, 'w') - f.write(f'{len(LPV)}\n') - f.write('extra\n') - for i in LPV: - f.write(f'{i}\n') - f.close() - - fname = outdir + '/ids_RPV.vtx' - f = open(fname, 'w') - f.write(f'{len(RPV)}\n') - f.write('extra\n') - for i in RPV: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_LAA.vtx', LAA_id) + write_to_vtx(outdir + '/ids_LPV.vtx', LPV) + write_to_vtx(outdir + '/ids_RPV.vtx', RPV) return b_tag, centroids @@ -420,11 +390,6 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): for r in rings: id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + f'/ids_{r.name}.vtx' - - f = open(fname, 'w') - f.write(f'{len(id_vec)}\n') - f.write('extra\n') if r.name == "TV": b_tag[id_vec] = 6 @@ -435,19 +400,11 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): elif r.name == "CS": b_tag[id_vec] = 9 - for i in id_vec: - f.write(f'{i}\n') - - f.close() + write_to_vtx(outdir + f'/ids_{r.name}.vtx', id_vec) centroids[r.name] = r.center - fname = outdir + '/ids_RAA.vtx' - f = open(fname, 'w') - f.write(f'{1}\n') - f.write('extra\n') - f.write(f'{RAA_id}\n') - f.close() + write_to_vtx(outdir + '/ids_RAA.vtx', RAA_id) return b_tag, centroids, rings @@ -506,21 +463,8 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): MV_ant = set(ids).intersection(MV_ids) MV_post = MV_ids - MV_ant - fname = outdir + '/ids_MV_ant.vtx' - f = open(fname, 'w') - f.write(f'{len(MV_ant)}\n') - f.write('extra\n') - for i in MV_ant: - f.write(f'{i}\n') - f.close() - - fname = outdir + '/ids_MV_post.vtx' - f = open(fname, 'w') - f.write(f'{len(MV_post)}\n') - f.write('extra\n') - for i in MV_post: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_MV_ant.vtx', MV_ant) + write_to_vtx(outdir + '/ids_MV_post.vtx', MV_post) lpv_mv = find_closest_point(MV_ring[0].vtk_polydata, lpv_mean) rpv_mv = find_closest_point(MV_ring[0].vtk_polydata, rpv_mean) @@ -542,13 +486,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): for r in rings: mv_lpv = mv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - fname = outdir + '/ids_MV_LPV.vtx' - f = open(fname, 'w') - f.write(f'{len(mv_lpv)}\n') - f.write('extra\n') - for i in mv_lpv: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_MV_LPV.vtx', mv_lpv) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundary_edges) @@ -562,13 +500,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): for r in rings: mv_rpv = mv_rpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - fname = outdir + '/ids_MV_RPV.vtx' - f = open(fname, 'w') - f.write(f'{len(mv_rpv)}\n') - f.write('extra\n') - for i in mv_rpv: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_MV_RPV.vtx', mv_rpv) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundary_edges) @@ -582,13 +514,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): for r in rings: rpv_lpv = rpv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - fname = outdir + '/ids_RPV_LPV.vtx' - f = open(fname, 'w') - f.write(f'{len(rpv_lpv)}\n') - f.write('extra\n') - for i in rpv_lpv: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_RPV_LPV.vtx', rpv_lpv) def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): @@ -637,24 +563,14 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, plane)) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TV_F.vtx' - f = open(fname, 'w') - f.write(f'{len(tv_f_ids)}\n') - f.write('extra\n') - for i in tv_f_ids: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TV_F.vtx', tv_f_ids) tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, plane2, extract_boundary_cells_on=True)) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TV_S.vtx' - f = open(fname, 'w') - f.write(f'{len(tv_s_ids)}\n') - f.write('extra\n') - for i in tv_s_ids: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TV_S.vtx', tv_s_ids) svc_points = svc.GetPoints().GetData() svc_points = vtk_to_numpy(svc_points) @@ -764,13 +680,8 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): surface = clean_polydata(connect.GetOutput()) top_endo = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TOP_ENDO.vtx' - f = open(fname, 'w') - f.write(f'{len(top_endo)}\n') - f.write('extra\n') - for i in top_endo: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TOP_ENDO.vtx', top_endo) def create_pts(array_points, array_name, mesh_dir): diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index ed0caa0..3d6b54f 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -38,7 +38,7 @@ from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk -from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point @@ -312,13 +312,6 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): for r in rings: id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + f'/ids_{r.name}.vtx' - if os.path.exists(fname): - f = open(fname, 'a') - else: - f = open(fname, 'w') - f.write(f'{len(id_vec)}\n') - f.write('extra\n') if r.name == "MV": b_tag[id_vec] = 1 @@ -335,34 +328,13 @@ def mark_LA_rings(LAA_id, rings, b_tag, centroids, outdir, LA): b_tag[id_vec] = 5 RPV = RPV + list(id_vec) - for i in id_vec: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + f'/ids_{r.name}.vtx', id_vec, True) centroids[r.name] = r.center - fname = outdir + '/ids_LAA.vtx' - f = open(fname, 'w') - f.write(f'{1}\n') - f.write('extra\n') - f.write(f'{LAA_id}\n') - f.close() - - fname = outdir + '/ids_LPV.vtx' - f = open(fname, 'w') - f.write(f'{len(LPV)}\n') - f.write('extra\n') - for i in LPV: - f.write(f'{i}\n') - f.close() - - fname = outdir + '/ids_RPV.vtx' - f = open(fname, 'w') - f.write(f'{len(RPV)}\n') - f.write('extra\n') - for i in RPV: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_LAA.vtx', LAA_id) + write_to_vtx(outdir + '/ids_LPV.vtx', LPV) + write_to_vtx(outdir + '/ids_RPV.vtx', RPV) return b_tag, centroids @@ -390,11 +362,6 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): for r in rings: id_vec = vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids")) - fname = outdir + f'/ids_{r.name}.vtx' - - f = open(fname, 'w') - f.write(f'{len(id_vec)}\n') - f.write('extra\n') if r.name == "TV": b_tag[id_vec] = 6 @@ -405,19 +372,11 @@ def mark_RA_rings(RAA_id, rings, b_tag, centroids, outdir): elif r.name == "CS": b_tag[id_vec] = 9 - for i in id_vec: - f.write(f'{i}\n') - - f.close() + write_to_vtx(outdir + f'/ids_{r.name}.vtx', id_vec) centroids[r.name] = r.center - fname = outdir + '/ids_RAA.vtx' - f = open(fname, 'w') - f.write(f'{1}\n') - f.write('extra\n') - f.write(f'{RAA_id}\n') - f.close() + write_to_vtx(outdir + '/ids_RAA.vtx', RAA_id) return b_tag, centroids, rings @@ -480,21 +439,8 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): MV_ant = set(ids).intersection(MV_ids) MV_post = MV_ids - MV_ant - fname = outdir + '/ids_MV_ant.vtx' - f = open(fname, 'w') - f.write(f'{len(MV_ant)}\n') - f.write('extra\n') - for i in MV_ant: - f.write(f'{i}\n') - f.close() - - fname = outdir + '/ids_MV_post.vtx' - f = open(fname, 'w') - f.write(f'{len(MV_post)}\n') - f.write('extra\n') - for i in MV_post: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_MV_ant.vtx', MV_ant) + write_to_vtx(outdir + '/ids_MV_post.vtx', MV_post) lpv_mv = find_closest_point(MV_ring[0].vtk_polydata, lpv_mean) rpv_mv = find_closest_point(MV_ring[0].vtk_polydata, rpv_mean) @@ -516,13 +462,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): for r in rings: mv_lpv = mv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - fname = outdir + '/ids_MV_LPV.vtx' - f = open(fname, 'w') - f.write(f'{len(mv_lpv)}\n') - f.write('extra\n') - for i in mv_lpv: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_MV_LPV.vtx', mv_lpv) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundary_edges) @@ -536,13 +476,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): for r in rings: mv_rpv = mv_rpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - fname = outdir + '/ids_MV_RPV.vtx' - f = open(fname, 'w') - f.write(f'{len(mv_rpv)}\n') - f.write('extra\n') - for i in mv_rpv: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_MV_RPV.vtx', mv_rpv) path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(boundary_edges) @@ -556,13 +490,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): for r in rings: rpv_lpv = rpv_lpv - set(vtk_to_numpy(r.vtk_polydata.GetPointData().GetArray("Ids"))) - fname = outdir + '/ids_RPV_LPV.vtx' - f = open(fname, 'w') - f.write(f'{len(rpv_lpv)}\n') - f.write('extra\n') - for i in rpv_lpv: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + '/ids_RPV_LPV.vtx', rpv_lpv) def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): @@ -620,24 +548,14 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, plane)) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TV_F.vtx' - f = open(fname, 'w') - f.write(f'{len(tv_f_ids)}\n') - f.write('extra\n') - for i in tv_f_ids: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TV_F.vtx', tv_f_ids) tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, plane2, extract_boundary_cells_on=True)) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TV_S.vtx' - f = open(fname, 'w') - f.write(f'{len(tv_s_ids)}\n') - f.write('extra\n') - for i in tv_s_ids: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TV_S.vtx', tv_s_ids) svc_points = svc.GetPoints().GetData() svc_points = vtk_to_numpy(svc_points) @@ -791,13 +709,8 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # Clean unused points top_epi = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TOP_EPI.vtx' - f = open(fname, 'w') - f.write(f'{len(top_epi)}\n') - f.write('extra\n') - for i in top_epi: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TOP_EPI.vtx', top_epi) to_delete = np.zeros((len(pts_in_top_endo),), dtype=int) for i in range(len(pts_in_top_endo)): @@ -842,13 +755,8 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # Clean unused points top_endo = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) - fname = outdir + '/ids_TOP_ENDO.vtx' - f = open(fname, 'w') - f.write(f'{len(top_endo)}\n') - f.write('extra\n') - for i in top_endo: - f.write(f'{i}\n') - f.close() + + write_to_vtx(outdir + '/ids_TOP_ENDO.vtx', top_endo) if __name__ == '__main__': diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py index cf1ad2a..e898577 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py @@ -33,24 +33,14 @@ from scipy.spatial import cKDTree from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.exporting import write_to_vtx sys.path.append('Atrial_LDRBM/Generate_Boundaries') from extract_rings import smart_reader def write_surf_ids(outdir, name, ii): - fname = outdir + f'/ids_{name}.vtx' - f = open(fname, 'w') - if isinstance(ii, int): - f.write('1\n') - f.write('extra\n') - f.write(f'{ii}\n') - else: - f.write(f'{len(ii)}\n') - f.write('extra\n') - for i in ii: - f.write(f'{i}\n') - f.close() + write_to_vtx(outdir + f'/ids_{name}.vtx', ii) def generate_surf_id(meshname, atrium): diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 74c525c..80967fe 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -39,7 +39,7 @@ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ - vtk_xml_unstructured_grid_writer + vtk_xml_unstructured_grid_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, generate_ids, \ get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points @@ -212,13 +212,7 @@ def la_generate_fiber(model, args, job): LAA_bb_ids = np.append(LAA_bb_ids, MV_ring_ids) - fname = f'{args.mesh}_surf/ids_LAA_bb.vtx' - f = open(fname, 'w') - f.write(f'{len(LAA_bb_ids)}\n') - f.write('extra\n') - for i in LAA_bb_ids: - f.write(f'{i}\n') - f.close() + write_to_vtx(f'{args.mesh}_surf/ids_LAA_bb.vtx', LAA_bb_ids) LAA_s = laplace_0_1(args, job, model, "LAA", "LAA_bb", "phie_ab3") From 95063f184bbee4cfdad4420efb49a29534a6bc9b Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 15:26:57 +0100 Subject: [PATCH 41/70] Included point selection into AugmentA files --- pipeline.py | 28 +++-------- standalones/open_orifices_manually.py | 12 +---- standalones/open_orifices_with_curvature.py | 51 ++++----------------- standalones/resample_surf_mesh.py | 48 +++---------------- 4 files changed, 22 insertions(+), 117 deletions(-) diff --git a/pipeline.py b/pipeline.py index c91ff9c..2b14329 100644 --- a/pipeline.py +++ b/pipeline.py @@ -26,6 +26,7 @@ """ from Atrial_LDRBM.LDRBM.Fiber_LA import la_main from Atrial_LDRBM.LDRBM.Fiber_RA import ra_main +from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point, pick_point_with_preselection from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -99,17 +100,8 @@ def AugmentA(args): polydata = apply_vtk_geom_filter(smart_reader(args.mesh)) mesh_from_vtk = pv.PolyData(polydata) - p = pv.Plotter(notebook=False) - p.add_mesh(mesh_from_vtk, 'r') - p.add_text('Select the appendage apex and close the window', position='lower_left') - p.enable_point_picking(mesh_from_vtk, use_picker=True) - p.show() - - if p.picked_point is not None: - apex = p.picked_point - else: - raise ValueError("Please select the appendage apex") - p.close() + + apex = pick_point(mesh_from_vtk, "appendage apex") tree = cKDTree(mesh_from_vtk.points.astype(np.double)) dd, apex_id = tree.query(apex) @@ -128,17 +120,8 @@ def AugmentA(args): mesh_data["LAA_id"] = [apex_id] mesh_from_vtk = pv.PolyData(polydata) - p = pv.Plotter(notebook=False) - p.add_mesh(mesh_from_vtk, 'r') - p.add_text('Select the RA appendage apex and close the window', position='lower_left') - p.enable_point_picking(mesh_from_vtk, use_picker=True) - p.show() - - if p.picked_point is not None: - apex = p.picked_point - else: - raise ValueError("Please select the appendage apex") - p.close() + + apex = pick_point_with_preselection(mesh_from_vtk, "RA appendage apex", apex) tree = cKDTree(mesh_from_vtk.points.astype(np.double)) dd, apex_id = tree.query(apex) @@ -320,6 +303,7 @@ def AugmentA(args): bil['elemTag'][mask] = bil['elemTag'][mask] - 10 mask = bil['elemTag'] > 50 bil['elemTag'][mask] = bil['elemTag'][mask] - 50 + p = pv.Plotter(notebook=False) if not args.closed_surface: fibers = bil.glyph(orient="fiber", factor=0.5, geom=geom, scale="elemTag") diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 6caba6e..6378768 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -123,17 +123,7 @@ def open_orifices_manually(meshpath, atrium, MRI, scale=1, size=30, vessels_cutt orifices = ['tricuspid valve', 'inferior vena cava', 'superior vena cava', 'coronary sinus'] for r in orifices: - picked_pt = None - while picked_pt is None: - p = pv.Plotter(notebook=False) - p.add_mesh(meshfix.mesh, 'r') - p.add_text(f'Select the center of the {r} and close the window to cut, otherwise just close', - position='lower_left') - p.enable_point_picking(meshfix.mesh, use_picker=True) - p.show() - - picked_pt = p.picked_point - p.close() + picked_pt = pick_point(meshfix.mesh, f"center of the {r}") if r == 'mitral valve' or r == 'tricuspid valve': selected_radius = valve_cutting_radius else: diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index 40d332b..d007b7b 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -39,6 +39,7 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from standalones.open_orifices_manually import open_orifices_manually +from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point_with_preselection, pick_point from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer @@ -217,16 +218,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu if MRI: cc = pv.PolyData(valve_center) - p = pv.Plotter(notebook=False) - p.add_mesh(meshfix.mesh, 'r') - p.add_text('Select the appendage apex and close the window', position='lower_left') - p.add_mesh(cc, color='w', point_size=30., render_points_as_spheres=True) - p.enable_point_picking(meshfix.mesh, use_picker=True) - p.show() - - apex = p.picked_point - p.close() + apex = pick_point_with_preselection(meshfix.mesh, "appendage apex", cc) apex_id = find_closest_point(model, apex) @@ -236,18 +229,13 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu RAA = apex_id else: transeptal_punture_id = -1 - p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_clean.vtk") - p.add_mesh(mesh_from_vtk, 'r') - p.add_text('Select the transeptal punture and close the window', position='lower_left') - p.enable_point_picking(meshfix.mesh, use_picker=True) - p.show() + mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_clean.vtk") - if p.picked_point is not None: + picked_point = pick_point(mesh_from_vtk, "transeptal puncture") + if picked_point is not None: transeptal_punture_id = vtk_to_numpy(model.GetPointData().GetArray('Ids'))[ - find_closest_point(model, p.picked_point)] - p.close() + find_closest_point(model, picked_point)] for i in range(num): connect.AddSpecifiedRegion(i) @@ -323,31 +311,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu vtk_polydata_writer(f"{full_path}/{atrium}_cutted.vtk", model) if debug: - if apex is not None: - point_cloud = pv.PolyData(apex) - - p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") - p.add_mesh(mesh_from_vtk, 'r') - p.add_mesh(point_cloud, color='w', point_size=30., render_points_as_spheres=True) - p.enable_point_picking(meshfix.mesh, use_picker=True) - p.add_text('Select the appendage apex and close the window', position='lower_left') - p.show() - - if p.picked_point is not None: - apex = p.picked_point - p.close() - else: - p = pv.Plotter(notebook=False) - mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") - p.add_mesh(mesh_from_vtk, 'r') - p.enable_point_picking(meshfix.mesh, use_picker=True) - p.add_text('Select the appendage apex and close the window', position='lower_left') - p.show() - - if p.picked_point is not None: - apex = p.picked_point - p.close() + mesh_from_vtk = pv.PolyData(f"{full_path}/{atrium}_cutted.vtk") + apex = pick_point_with_preselection(mesh_from_vtk, "appendage apex", apex) model = smart_reader(f"{full_path}/{atrium}_cutted.vtk") diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index b43b7ea..6400a03 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -36,6 +36,7 @@ from scipy.spatial import cKDTree from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import find_elements_around_path_within_radius +from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point_with_preselection, pick_point from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, get_cells_with_ids, \ @@ -196,38 +197,12 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv mesh_curv = pv.read(f'{meshname}.obj') apex = mesh_curv.points[np.argmax(curv), :] - - point_cloud = pv.PolyData(apex) - - p = pv.Plotter(notebook=False) - - p.add_mesh(meshin, color='r') - p.add_mesh(point_cloud, color='w', point_size=30. * scale, render_points_as_spheres=True) - p.enable_point_picking(meshin, use_picker=True) - p.add_text('Select the appendage apex and close the window', position='lower_left') - - p.show() - - if p.picked_point is None: - print("Please pick a point as apex") - else: - apex = p.picked_point - print("Apex coordinates: ", apex) + apex = pick_point_with_preselection(meshin, "appendage apex", apex) + print("Apex coordinates: ", apex) elif find_apex_with_curv == 0 and apex_id == -1: - - p = pv.Plotter(notebook=False) - - p.add_mesh(meshin, color='r') - p.enable_point_picking(meshin, use_picker=True) - p.add_text('Select the appendage apex and close the window', position='lower_left') # Select the LAA first - - p.show() - if p.picked_point is None: - print("Please pick a point as apex") - else: - apex = p.picked_point - print("Apex coordinates: ", apex) + apex = pick_point(meshin, "appendage apex") + print("Apex coordinates: ", apex) tree = cKDTree(meshin.points.astype(np.double)) dist, apex_id = tree.query(apex) @@ -239,18 +214,9 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv if atrium == 'LA_RA': atrium = 'RA' - p = pv.Plotter(notebook=False) - - p.add_mesh(meshin, color='r') - p.enable_point_picking(meshin, use_picker=True) - p.add_text('Select the RA appendage apex and close the window', position='lower_left') - p.show() - if p.picked_point is None: - print("Please pick a point as apex") - else: - apex = p.picked_point - print("Apex coordinates: ", apex) + apex = pick_point(meshin, "RA appendage apex") + print("Apex coordinates: ", apex) tree = cKDTree(meshin.points.astype(np.double)) dist, apex_id = tree.query(apex) From a40aac40a4ffdc87045ede044e5e1054feab89b2 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 17:56:24 +0100 Subject: [PATCH 42/70] Fixed refactoring bug in create_bridges.py --- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 4ab556f..8d81ef9 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -134,8 +134,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): meshNew = dsa.WrapDataObject(biatrial_epi) meshNew.CellData.append(tag, "elemTag") - - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", vtk_append([meshNew.VTKObject])) + biatrial_mesh = vtk_append([meshNew.VTKObject]) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_res.vtu", biatrial_mesh) elif args.mesh_type == "bilayer": la_e = Method.smart_reader(job.ID + "/result_LA/LA_epi_with_fiber.vtu") @@ -144,8 +144,8 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): ra_e = Method.smart_reader(job.ID + "/result_RA/RA_epi_with_fiber.vtu") ra_e = apply_vtk_geom_filter(ra_e) - biatrial_e = vtk_append([la_e, ra_e]) - vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_e) + biatrial_mesh = vtk_append([la_e, ra_e]) + vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/LA_epi_RA_epi_with_tag.vtu", biatrial_mesh) bridge_list = ['BB_intern_bridges', 'coronary_sinus_bridge', 'middle_posterior_bridge', 'upper_posterior_bridge'] for var in bridge_list: @@ -176,7 +176,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): "-surf=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj", "-outmsh=" + job.ID + "/bridges/" + str(var) + "_bridge_resampled.vtk"]) - la_ra_usg = append_filter.GetOutput() # this has already elemTag + la_ra_usg = biatrial_mesh # this has already elemTag if args.debug: vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_usg.vtu", la_ra_usg) From cff181d890113f813101fe96940bbcbab0362728 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Wed, 27 Nov 2024 18:55:03 +0100 Subject: [PATCH 43/70] Extracted method for generating splines and for clearing out all data of a mesh --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 36 +++++++++----- .../LDRBM/Fiber_LA/la_generate_fiber.py | 20 ++------ Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 48 ++----------------- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 15 +----- .../LDRBM/Fiber_RA/create_bridges_test.py | 15 +----- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 42 +++------------- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 12 ++--- 7 files changed, 46 insertions(+), 142 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 86f0883..0b942c8 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -809,19 +809,7 @@ def get_wide_bachmann_path_left(epi, inf_appendage_basis_id, sup_appendage_basis def creat_center_line(start_end_point): - spline_points = vtk.vtkPoints() - for i in range(len(start_end_point)): - spline_points.InsertPoint(i, start_end_point[i][0], start_end_point[i][1], start_end_point[i][2]) - - # Fit a spline to the points - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - tubePolyData = functionSource.GetOutput() + tubePolyData = generate_spline_points(start_end_point) points = tubePolyData.GetPoints().GetData() points = vtk_to_numpy(points) @@ -950,3 +938,25 @@ def optimize_shape_PV(surface, num, bound): break return found, arr[l - 1] + + +def generate_spline_points(input_points): + spline_points = vtk.vtkPoints() + for i in range(len(input_points)): + spline_points.InsertPoint(i, input_points[i][0], input_points[i][1], input_points[i][2]) + # Fit a spline to the points + spline = vtk.vtkParametricSpline() + spline.SetPoints(spline_points) + functionSource = vtk.vtkParametricFunctionSource() + functionSource.SetParametricFunction(spline) + functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) + functionSource.Update() + return functionSource.GetOutput() + + +def clean_all_data(mesh): + for i in range(mesh.GetPointData().GetNumberOfArrays() - 1, -1, -1): + mesh.GetPointData().RemoveArray(mesh.GetPointData().GetArrayName(i)) + for i in range(mesh.GetCellData().GetNumberOfArrays() - 1, -1, -1): + mesh.GetCellData().RemoveArray(mesh.GetCellData().GetArrayName(i)) + return mesh diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 80967fe..154bc6e 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -34,6 +34,7 @@ from vtk.numpy_interface import dataset_adapter as dsa import Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA as Method +from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data from Atrial_LDRBM.LDRBM.Fiber_LA.la_laplace import laplace_0_1 from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon @@ -370,11 +371,7 @@ def la_generate_fiber(model, args, job): sheet_endo = np.cross(el_endo, et) sheet_endo = np.where(sheet_endo == [0, 0, 0], [1, 0, 0], sheet_endo).astype("float32") - for i in range(endo.GetPointData().GetNumberOfArrays() - 1, -1, -1): - endo.GetPointData().RemoveArray(endo.GetPointData().GetArrayName(i)) - - for i in range(endo.GetCellData().GetNumberOfArrays() - 1, -1, -1): - endo.GetCellData().RemoveArray(endo.GetCellData().GetArrayName(i)) + endo = clean_all_data(endo) meshNew = dsa.WrapDataObject(endo) meshNew.CellData.append(tag_endo, "elemTag") @@ -490,11 +487,7 @@ def la_generate_fiber(model, args, job): sheet_epi = np.cross(el_epi, et) sheet_epi = np.where(sheet_epi == [0, 0, 0], [1, 0, 0], sheet_epi).astype("float32") - for i in range(epi.GetPointData().GetNumberOfArrays() - 1, -1, -1): - epi.GetPointData().RemoveArray(epi.GetPointData().GetArrayName(i)) - - for i in range(epi.GetCellData().GetNumberOfArrays() - 1, -1, -1): - epi.GetCellData().RemoveArray(epi.GetCellData().GetArrayName(i)) + epi = clean_all_data(epi) meshNew = dsa.WrapDataObject(epi) meshNew.CellData.append(tag_epi, "elemTag") @@ -533,12 +526,7 @@ def la_generate_fiber(model, args, job): sheet = np.cross(el, et) sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") - for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): - model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): - model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) - + model = clean_all_data(model) meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") meshNew.CellData.append(el, "fiber") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index aca1912..62bd602 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -30,6 +30,8 @@ from vtk.numpy_interface import dataset_adapter as dsa import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations +from Atrial_LDRBM.LDRBM.Fiber_LA import Methods_LA +from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import generate_spline_points from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.openCARP.exporting import write_to_elem, write_to_pts, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk @@ -50,17 +52,7 @@ def downsample_path(points_data, step): [points_data[i] for i in range(len(points_data)) if i % step == 0 or i == len(points_data) - 1]) # fit a spline - spline_points = vtk.vtkPoints() - for i in range(len(path_all)): - spline_points.InsertPoint(i, path_all[i][0], path_all[i][1], path_all[i][2]) - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - points_data = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) - return points_data + return vtk_to_numpy(generate_spline_points(path_all).GetPoints().GetData()) def move_surf_along_normals(mesh, eps, direction): @@ -283,20 +275,6 @@ def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): def creat_tube_around_spline(points_data, radius): - # Creat a points set - spline_points = vtk.vtkPoints() - for i in range(len(points_data)): - spline_points.InsertPoint(i, points_data[i][0], points_data[i][1], points_data[i][2]) - - # Fit a spline to the points - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - # Interpolate the scalars interpolatedRadius = vtk.vtkTupleInterpolator() interpolatedRadius.SetInterpolationTypeToLinear() @@ -304,7 +282,7 @@ def creat_tube_around_spline(points_data, radius): # Generate the radius scalars tubeRadius = vtk.vtkDoubleArray() - n = functionSource.GetOutput().GetNumberOfPoints() + n = generate_spline_points(points_data).GetNumberOfPoints() tubeRadius.SetNumberOfTuples(n) tubeRadius.SetName("TubeRadius") @@ -840,23 +818,7 @@ def create_free_bridge_semi_auto(la_epi, ra_epi, ra_point, radius): def creat_center_line(start_end_point): - spline_points = vtk.vtkPoints() - for i in range(len(start_end_point)): - spline_points.InsertPoint(i, start_end_point[i][0], start_end_point[i][1], start_end_point[i][2]) - - # Fit a spline to the points - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - tubePolyData = functionSource.GetOutput() - points = tubePolyData.GetPoints().GetData() - points = vtk_to_numpy(points) - - return points + return Methods_LA.creat_center_line(start_end_point) def smart_bridge_writer(tube, sphere_1, sphere_2, name, job): diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 8d81ef9..a3dbb45 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -36,6 +36,7 @@ from vtk.numpy_interface import dataset_adapter as dsa import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method +from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import generate_spline_points from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy @@ -294,19 +295,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): f = open(filename, 'rb') bb_fiber = pickle.load(f) - spline_points = vtk.vtkPoints() - for i in range(len(bb_fiber)): - spline_points.InsertPoint(i, bb_fiber[i][0], bb_fiber[i][1], bb_fiber[i][2]) - - # Fit a spline to the points - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - bb_fiber_points_data = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + bb_fiber_points_data = vtk_to_numpy(generate_spline_points(bb_fiber).GetPoints().GetData()) print("Union between earth and bridges") for var in bridge_list: diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py index 890d241..756450d 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges_test.py @@ -38,6 +38,7 @@ from vtk.numpy_interface import dataset_adapter as dsa import Methods_RA as Method +from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import generate_spline_points from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy @@ -291,19 +292,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): f = open(filename, 'rb') bb_fiber = pickle.load(f) - spline_points = vtk.vtkPoints() - for i in range(len(bb_fiber)): - spline_points.InsertPoint(i, bb_fiber[i][0], bb_fiber[i][1], bb_fiber[i][2]) - - # Fit a spline to the points - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - bb_fiber_points_data = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + bb_fiber_points_data = vtk_to_numpy(generate_spline_points(bb_fiber).GetPoints().GetData()) print("Union between earth and bridges") for var in bridge_list: diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index ec23da8..65321bf 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -36,6 +36,8 @@ from vtk.numpy_interface import dataset_adapter as dsa import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method +from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data +from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import downsample_path from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ @@ -485,11 +487,7 @@ def ra_generate_fiber(model, args, job): if args.mesh_type == "bilayer": sheet = np.cross(el, et) - for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): - model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): - model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) + model = clean_all_data(model) meshNew = dsa.WrapDataObject(model) meshNew.CellData.append(tag, "elemTag") @@ -711,11 +709,7 @@ def ra_generate_fiber(model, args, job): tag_endo[IVC_ids] = tag[IVC_ids] - for i in range(endo.GetPointData().GetNumberOfArrays() - 1, -1, -1): - endo.GetPointData().RemoveArray(endo.GetPointData().GetArrayName(i)) - - for i in range(endo.GetCellData().GetNumberOfArrays() - 1, -1, -1): - endo.GetCellData().RemoveArray(endo.GetCellData().GetArrayName(i)) + endo = clean_all_data(endo) fiber_endo = np.where(fiber_endo == [0, 0, 0], [1, 0, 0], fiber_endo).astype("float32") sheet = np.cross(fiber_endo, et) @@ -767,11 +761,7 @@ def ra_generate_fiber(model, args, job): if args.debug: - for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): - model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): - model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) + model = clean_all_data(model) el = np.where(el == [0, 0, 0], [1, 0, 0], el).astype("float32") sheet = np.cross(el, et) @@ -808,32 +798,14 @@ def ra_generate_fiber(model, args, job): np.savetxt(job.ID + '/bb.txt', bachmann_bundle_points_data, fmt='%.5f') # Change directory bb_step = int(len(bachmann_bundle_points_data) * 0.1) - bb_path = np.asarray([bachmann_bundle_points_data[i] for i in range(len(bachmann_bundle_points_data)) if - i % bb_step == 0 or i == len(bachmann_bundle_points_data) - 1]) - spline_points = vtk.vtkPoints() - for i in range(len(bb_path)): - spline_points.InsertPoint(i, bb_path[i][0], bb_path[i][1], bb_path[i][2]) - - # Fit a spline to the points - spline = vtk.vtkParametricSpline() - spline.SetPoints(spline_points) - functionSource = vtk.vtkParametricFunctionSource() - functionSource.SetParametricFunction(spline) - functionSource.SetUResolution(30 * spline_points.GetNumberOfPoints()) - functionSource.Update() - - bb_points = vtk_to_numpy(functionSource.GetOutput().GetPoints().GetData()) + bb_points = downsample_path(bachmann_bundle_points_data, bb_step) tag = Method.assign_element_tag_around_path_within_radius(model, bb_points, w_bb, tag, bachmann_bundel_right) el = Method.assign_element_fiber_around_path_within_radius(model, bb_points, w_bb, el, smooth=True) tag[SN_ids] = sinus_node - for i in range(model.GetPointData().GetNumberOfArrays() - 1, -1, -1): - model.GetPointData().RemoveArray(model.GetPointData().GetArrayName(i)) - - for i in range(model.GetCellData().GetNumberOfArrays() - 1, -1, -1): - model.GetCellData().RemoveArray(model.GetCellData().GetArrayName(i)) + model = clean_all_data(model) el = np.where(el == [0, 0, 0], [1, 0, 0], el).astype("float32") sheet = np.cross(el, et) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index 2dbb9a8..8e70036 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -39,6 +39,7 @@ from Atrial_LDRBM.LDRBM.Fiber_RA.ra_laplace import ra_laplace from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader def parser(): @@ -98,20 +99,13 @@ def jobID(args): @tools.carpexample(parser, jobID) def run(args, job): RA_mesh = args.mesh + '_surf/RA' - - if args.mesh_type == "bilayer": - reader = vtk.vtkPolyDataReader() - else: - reader = vtk.vtkUnstructuredGridReader() - reader.SetFileName(RA_mesh + '.vtk') - reader.Update() - RA = reader.GetOutput() + RA = smart_reader(RA_mesh + '.vtk') if args.normals_outside: reverse = vtk.vtkReverseSense() reverse.ReverseCellsOn() reverse.ReverseNormalsOn() - reverse.SetInputConnection(reader.GetOutputPort()) + reverse.SetInputData(RA) reverse.Update() RA = reverse.GetOutput() From 7e904eab762564dbdb6c3ef958446b8c8343c013 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 28 Nov 2024 10:08:35 +0100 Subject: [PATCH 44/70] Applied encapsulation for connectivity filter and some redundant method removal --- .../Generate_Boundaries/extract_rings.py | 27 ++---- .../extract_rings_TOP_epi_endo.py | 35 ++----- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 25 +---- .../LDRBM/Fiber_LA/la_generate_fiber.py | 14 +-- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 20 +--- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 10 +- standalones/function.py | 8 +- standalones/open_orifices_manually.py | 53 ----------- standalones/open_orifices_with_curvature.py | 92 ++----------------- standalones/resample_surf_mesh.py | 6 +- .../Methods_fit_to_clinical_LAT.py | 30 +----- 11 files changed, 50 insertions(+), 270 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index b1f2831..bb9950a 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -42,7 +42,8 @@ from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane, \ + init_connectivity_filter, ExtractionModes from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -100,7 +101,6 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i extension = mesh.split('.')[-1] mesh = mesh[:-(len(extension) + 1)] - meshname = mesh.split("/")[-1] outdir = f"{mesh}_surf" if not os.path.exists(outdir): os.makedirs(outdir) @@ -123,12 +123,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i centroids["LAA_base"] = LA_bs_point centroids["RAA_base"] = RA_bs_point - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh_surf) - connect.SetExtractionModeToAllRegions() - connect.ColorRegionsOn() - connect.Update() - mesh_conn = connect.GetOutput() + mesh_conn = init_connectivity_filter(mesh_surf, ExtractionModes.ALL_REGIONS, True).GetOutput() mesh_conn.GetPointData().GetArray("RegionId").SetName("RegionID") id_vec = vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) @@ -237,10 +232,7 @@ def detect_and_mark_rings(surf, ap_point, outdir, debug): boundary_edges = get_feature_edges(surf, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, non_manifold_edges_on=False) "Splitting rings" - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(boundary_edges) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(boundary_edges, ExtractionModes.ALL_REGIONS) num = connect.GetNumberOfExtractedRegions() connect.SetExtractionModeToSpecifiedRegions() @@ -578,10 +570,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): ivc_points = svc.GetPoints().GetData() # Changed ivc_points = vtk_to_numpy(ivc_points) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(gamma_top) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(gamma_top, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for i in range(num): @@ -651,11 +640,7 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): mv_id = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(geo_port) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() - + connect = init_connectivity_filter(geo_port, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for i in range(num): diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 3d6b54f..afa7f81 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -42,7 +42,8 @@ from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane, \ + init_connectivity_filter, ExtractionModes from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -118,12 +119,7 @@ def label_atrial_orifices_TOP_epi_endo(mesh, LAA_id="", RAA_id="", LAA_base_id=" centroids["LAA_base"] = LA_bs_point centroids["RAA_base"] = RA_bs_point - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh_surf) - connect.SetExtractionModeToAllRegions() - connect.ColorRegionsOn() - connect.Update() - mesh_conn = connect.GetOutput() + mesh_conn = init_connectivity_filter(mesh_surf, ExtractionModes.ALL_REGIONS, True).GetOutput() mesh_conn.GetPointData().GetArray("RegionId").SetName("RegionID") id_vec = vtk_to_numpy(mesh_conn.GetPointData().GetArray("RegionID")) @@ -229,10 +225,7 @@ def detect_and_mark_rings(surf, ap_point): "Splitting rings" - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(boundary_edges) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(boundary_edges, ExtractionModes.ALL_REGIONS) num = connect.GetNumberOfExtractedRegions() connect.SetExtractionModeToSpecifiedRegions() @@ -563,10 +556,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): ivc_points = ivc.GetPoints().GetData() ivc_points = vtk_to_numpy(ivc_points) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(gamma_top_epi) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(gamma_top_epi, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for i in range(num): connect.AddSpecifiedRegion(i) @@ -606,10 +596,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): pts_in_top_epi = vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(gamma_top_endo) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(gamma_top_endo, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for i in range(num): connect.AddSpecifiedRegion(i) @@ -680,10 +667,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): thresh_geo = apply_vtk_geom_filter(thresh.GetOutputPort(), True) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(thresh_geo) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(thresh_geo, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for i in range(num): @@ -726,10 +710,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): mv_id_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(thresh_geo) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(thresh_geo, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for i in range(num): diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 0b942c8..cfa1d90 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -41,7 +41,8 @@ clean_polydata, vtk_append, apply_extract_cell_filter, get_center_of_mass, get_feature_edges, \ get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane, init_connectivity_filter, \ + ExtractionModes from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_upper_threshold, \ get_threshold_between @@ -468,10 +469,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, plane = initialize_plane(-norm_1[0], moved_center[0]) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(get_elements_above_plane(ra_tv_surface, plane)) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(get_elements_above_plane(ra_tv_surface, plane), ExtractionModes.ALL_REGIONS) connect.SetExtractionModeToSpecifiedRegions() connect.AddSpecifiedRegion(1) connect.Update() @@ -510,18 +508,6 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, return path_tv_id_icv, path_tv_id_scv -def extract_largest_region(mesh): - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh) - connect.SetExtractionModeToLargestRegion() - connect.Update() - surface = connect.GetOutput() - - surface = apply_vtk_geom_filter(surface) - - return clean_polydata(surface) - - def assign_ra_appendage(model, SCV, appex_point, tag): appex_point = np.asarray(appex_point) locator = vtk.vtkStaticPointLocator() @@ -833,10 +819,7 @@ def find_tau(model, ub, lb, low_up, scalar): else: thresh = get_upper_threshold(model, (ub + lb) / 2, "vtkDataObject::FIELD_ASSOCIATION_CELLS", scalar) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(thresh.GetOutput()) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(thresh.GetOutput(), ExtractionModes.ALL_REGIONS) num = connect.GetNumberOfExtractedRegions() print("Iteration: ", k) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 154bc6e..3c042f1 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -43,7 +43,8 @@ vtk_xml_unstructured_grid_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, generate_ids, \ get_elements_above_plane -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, init_connectivity_filter, \ + ExtractionModes EXAMPLE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -135,10 +136,8 @@ def la_generate_fiber(model, args, job): print('Calculating tao_lpv done! tap_lpv = ', tao_lpv) thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(thr) - connect.SetExtractionModeToAllRegions() - connect.Update() + + connect = init_connectivity_filter(thr, ExtractionModes.ALL_REGIONS) PVs = dict() # Distinguish between LIPV and LSPV @@ -165,10 +164,7 @@ def la_generate_fiber(model, args, job): thr = vtk_thr(model, 0, "CELLS", "phie_v", tao_rpv) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(thr) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(thr, ExtractionModes.ALL_REGIONS) # Distinguish between RIPV and RSPV PVs = Method.distinguish_PVs(connect, PVs, df, "RIPV", "RSPV") diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 62bd602..cde64b4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -40,7 +40,8 @@ from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, vtk_append, apply_extract_cell_filter, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane, init_connectivity_filter, \ + ExtractionModes from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -604,10 +605,7 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, extracted_mesh = get_elements_above_plane(ra_tv_s_surface, plane) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(extracted_mesh) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(extracted_mesh, ExtractionModes.ALL_REGIONS) connect.SetExtractionModeToSpecifiedRegions() connect.AddSpecifiedRegion(1) connect.Update() @@ -645,18 +643,6 @@ def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, return path_tv_id_icv, path_tv_id_scv -def extract_largest_region(mesh): - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh) - connect.SetExtractionModeToLargestRegion() - connect.Update() - surface = connect.GetOutput() - - surface = apply_vtk_geom_filter(surface) - - return clean_polydata(surface) - - def assign_ra_appendage(model, SCV, appex_point, tag, elemTag): appex_point = np.asarray(appex_point) locator = vtk.vtkStaticPointLocator() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 65321bf..a34e6d2 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -38,7 +38,7 @@ import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import downsample_path -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, extract_largest_region from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer @@ -208,7 +208,7 @@ def ra_generate_fiber(model, args, job): IVC_s = vtk_thr(no_TV_s, 0, "CELLS", "phie_v", tao_icv) # Changed 0-1 because ICV and SVC are inverted no_IVC_s = vtk_thr(no_TV_s, 1, "CELLS", "phie_v", tao_icv) # Changed 1-0 - IVC_s = Method.extract_largest_region(IVC_s) # Added + IVC_s = extract_largest_region(IVC_s) # Added max_phie_r_ivc = np.max(vtk_to_numpy(IVC_s.GetCellData().GetArray('phie_r'))) + 0.2 @@ -217,7 +217,7 @@ def ra_generate_fiber(model, args, job): SVC_s = vtk_thr(RAW_s, 1, "CELLS", "phie_v", tao_scv) # Changed 1->0 no_SVC_s = vtk_thr(RAW_s, 0, "CELLS", "phie_v", tao_scv) # Changed 0->1 - SVC_s = Method.extract_largest_region(SVC_s) + SVC_s = extract_largest_region(SVC_s) if args.debug: # CHECK Method.writer_vtk(IVC_s, f'{args.mesh}_surf/' + "ivc_s.vtk") @@ -241,10 +241,10 @@ def ra_generate_fiber(model, args, job): IVC_s.GetPointData().GetArray('phie_r')))) # not always the best choice for pm1 CT_band = vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w - CT_band = Method.extract_largest_region(CT_band) + CT_band = extract_largest_region(CT_band) CT_ub = vtk_thr(RAW_s, 2, "CELLS", "phie_w", tao_ct_plus - 0.02, tao_ct_plus) # grad_w - CT_ub = Method.extract_largest_region(CT_ub) + CT_ub = extract_largest_region(CT_ub) if args.debug: Method.writer_vtk(CT_band, f'{args.mesh}_surf/' + "ct_band.vtk") diff --git a/standalones/function.py b/standalones/function.py index 6f847cf..e444a33 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -34,7 +34,8 @@ from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, \ get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane, init_connectivity_filter, \ + ExtractionModes def to_polydata(mesh): @@ -162,10 +163,7 @@ def dijkstra_path(polydata, StartVertex, EndVertex): def get_mv_l_and_r(mv_band, center_lpv): - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mv_band) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(mv_band, ExtractionModes.ALL_REGIONS) connect.SetExtractionModeToSpecifiedRegions() connect.AddSpecifiedRegion(1) connect.Update() diff --git a/standalones/open_orifices_manually.py b/standalones/open_orifices_manually.py index 6378768..6f52c6f 100644 --- a/standalones/open_orifices_manually.py +++ b/standalones/open_orifices_manually.py @@ -25,21 +25,15 @@ under the License. """ import argparse -import collections -import numpy as np import pymeshfix import pyvista as pv import vtk -from scipy.spatial import cKDTree -from vtk.numpy_interface import dataset_adapter as dsa import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from Atrial_LDRBM.Generate_Boundaries import extract_rings from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point -from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.helper_methods import cut_mesh_with_radius from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper @@ -168,52 +162,5 @@ def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): thr2) -def extract_largest_region(mesh): - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh) - connect.SetExtractionModeToLargestRegion() - connect.Update() - surface = connect.GetOutput() - - surface = apply_vtk_geom_filter(surface) - - return clean_polydata(surface) - - -def point_array_mapper(mesh1, mesh2, idat): - pts1 = vtk_to_numpy(mesh1.GetPoints().GetData()) - pts2 = vtk_to_numpy(mesh2.GetPoints().GetData()) - - tree = cKDTree(pts1) - - dd, ii = tree.query(pts2, workers=-1) - - meshNew = dsa.WrapDataObject(mesh2) - if idat == "all": - for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk_to_numpy( - mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) - if isinstance(data[0], collections.abc.Sized): - data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) - else: - data2 = np.zeros((len(pts2),), dtype=data.dtype) - - data2 = data[ii] - data2 = np.where(np.isnan(data2), 10000, data2) - - meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) - else: - data = vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) - if isinstance(data[0], collections.abc.Sized): - data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) - else: - data2 = np.zeros((len(pts2),), dtype=data.dtype) - - data2 = data[ii] - meshNew.PointData.append(data2, idat) - - return meshNew.VTKObject - - if __name__ == '__main__': run() diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index d007b7b..cb7e607 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -37,9 +37,10 @@ from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa -import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from standalones.open_orifices_manually import open_orifices_manually from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point_with_preselection, pick_point +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import extract_largest_region, vtk_thr +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer @@ -48,6 +49,8 @@ from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.helper_methods import get_maximum_distance_of_points, cut_mesh_with_radius, \ cut_elements_from_mesh, find_elements_within_radius +from vtk_opencarp_helper_methods.vtk_methods.init_objects import init_connectivity_filter, ExtractionModes +from vtk_opencarp_helper_methods.vtk_methods.mapper import point_array_mapper from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader pv.set_plot_theme('dark') @@ -170,7 +173,7 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu debug) if debug and atrium == 'RA': - writer_vtk(valve, f"{full_path}/{atrium}_clean_with_curv_" + "valve.vtk") + vtk_polydata_writer(valve, f"{full_path}/{atrium}_clean_with_curv_" + "valve.vtk") center_of_mass = filters.get_center_of_mass(valve, False) @@ -201,15 +204,10 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu vtk_unstructured_grid_writer(f"{full_path}/{atrium}_h_curv.vtk", high_c, True) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(high_c) - connect.SetExtractionModeToAllRegions() - connect.Update() + connect = init_connectivity_filter(high_c, ExtractionModes.ALL_REGIONS) num = connect.GetNumberOfExtractedRegions() - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(high_c) - connect.SetExtractionModeToSpecifiedRegions() + connect = init_connectivity_filter(high_c, ExtractionModes.SPECIFIED_REGIONS) rings = [] @@ -254,10 +252,8 @@ def open_orifices_with_curvature(meshpath, atrium, MRI, scale=1, size=30, min_cu if len(set(pt_high_c).intersection(pts_low_v)) > 0: # the region is both high curvature and low voltage pt_max_curv = np.asarray(model.GetPoint(Gl_pt_id.index(pt_high_c[np.argmax(curv_s)]))) el_low_vol = set() - connect2 = vtk.vtkConnectivityFilter() - connect2.SetInputData(low_v) - connect2.SetExtractionModeToAllRegions() - connect2.Update() + + connect2 = init_connectivity_filter(low_v, ExtractionModes.ALL_REGIONS) num2 = connect2.GetNumberOfExtractedRegions() connect2.SetExtractionModeToSpecifiedRegions() @@ -334,75 +330,5 @@ def run(): args.min_cutting_radius, args.max_cutting_radius, args.LAA, args.RAA, args.debug) - -def vtk_thr(model, mode, points_cells, array, thr1, thr2="None"): - return vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations.vtk_thr(model, mode, points_cells, array, thr1, - thr2) - - -def extract_largest_region(mesh): - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh) - connect.SetExtractionModeToLargestRegion() - connect.Update() - surface = connect.GetOutput() - - surface = apply_vtk_geom_filter(surface) - return clean_polydata(surface) - - -def point_array_mapper(mesh1, mesh2, idat): - pts1 = vtk_to_numpy(mesh1.GetPoints().GetData()) - pts2 = vtk_to_numpy(mesh2.GetPoints().GetData()) - - tree = cKDTree(pts1) - - dd, ii = tree.query(pts2, workers=-1) - - meshNew = dsa.WrapDataObject(mesh2) - if idat == "all": - for i in range(mesh1.GetPointData().GetNumberOfArrays()): - data = vtk_to_numpy( - mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) - if isinstance(data[0], collections.abc.Sized): - data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) - else: - data2 = np.zeros((len(pts2),), dtype=data.dtype) - - data2 = data[ii] - data2 = np.where(np.isnan(data2), 10000, data2) - - meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) - else: - data = vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) - if isinstance(data[0], collections.abc.Sized): - data2 = np.zeros((len(pts2), len(data[0])), dtype=data.dtype) - else: - data2 = np.zeros((len(pts2),), dtype=data.dtype) - - data2 = data[ii] - meshNew.PointData.append(data2, idat) - - return meshNew.VTKObject - - -def create_pts(array_points, array_name, mesh_dir): - f = open(f"{mesh_dir}{array_name}.pts", "w") - f.write("0 0 0\n") - for i in range(len(array_points)): - f.write(f"{array_points[i][0]} {array_points[i][1]} {array_points[i][2]}\n") - f.close() - - -def to_polydata(mesh): - polydata = apply_vtk_geom_filter(mesh) - - return polydata - - -def writer_vtk(mesh, filename): - vtk_polydata_writer(filename, to_polydata(mesh)) - - if __name__ == '__main__': run() diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 6400a03..3b3f7bb 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -41,6 +41,7 @@ from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, get_cells_with_ids, \ get_feature_edges +from vtk_opencarp_helper_methods.vtk_methods.init_objects import init_connectivity_filter, ExtractionModes pv.set_plot_theme('dark') vtk_version = vtk.vtkVersion.GetVTKSourceVersion().split()[-1].split('.')[0] @@ -128,10 +129,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv earth = apply_vtk_geom_filter(get_cells_with_ids(reader.GetOutput(), cells_no_bd)) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(clean_polydata(earth)) - connect.SetExtractionModeToLargestRegion() - connect.Update() + connect = init_connectivity_filter(clean_polydata(earth), ExtractionModes.LARGEST_REGION) vtk_obj_writer(f'{meshname}_cleaned.obj', clean_polydata(connect.GetOutput())) mesh_data["vol"] = [vol] diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index c05d388..593c36b 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -38,6 +38,7 @@ from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_cells_with_ids from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point +from vtk_opencarp_helper_methods.vtk_methods.init_objects import init_connectivity_filter, ExtractionModes from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.writer import write_to_dat @@ -185,11 +186,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): b_ids = vtk_to_numpy(band.GetCellData().GetArray('Global_ids')).astype(int) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(band) - connect.SetExtractionModeToClosestPointRegion() - connect.SetClosestPoint(stim_pt) - connect.Update() + connect = init_connectivity_filter(band, ExtractionModes.CLOSEST_POINT, closest_point=stim_pt) largest_band = connect.GetOutput() l_b_ids = vtk_to_numpy(largest_band.GetCellData().GetArray('Global_ids')).astype(int) @@ -217,10 +214,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): tree = cKDTree(pts) - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(el_removed) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(el_removed, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for n in range(num): connect.AddSpecifiedRegion(n) @@ -272,10 +266,7 @@ def areas_to_clean(endo, args, min_LAT, stim_pt): tree = cKDTree(pts) # Find elements at the boundary of the areas to clean, which are gonna be used for the fitting of the conductivities - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(endo_to_interpolate) - connect.SetExtractionModeToSpecifiedRegions() - connect.Update() + connect = init_connectivity_filter(endo_to_interpolate, ExtractionModes.SPECIFIED_REGIONS) num = connect.GetNumberOfExtractedRegions() for n in range(num): connect.AddSpecifiedRegion(n) @@ -380,15 +371,4 @@ def get_EAP(path_mod, path_fib): print(LA_MV_ids[np.argmin(LAT_map[LA_MV_ids])]) stim_pt = model.GetPoint(LA_MV_ids[np.argmin(LAT_map[LA_MV_ids])]) - return stim_pt - - -def extract_largest_region(mesh): - connect = vtk.vtkConnectivityFilter() - connect.SetInputData(mesh) - connect.SetExtractionModeToLargestRegion() - connect.Update() - surface = connect.GetOutput() - - surface = apply_vtk_geom_filter(surface) - return clean_polydata(surface) + return stim_pt \ No newline at end of file From 0f0fa0ae7763503a824a815c74d18cc1efd903b8 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 28 Nov 2024 10:34:06 +0100 Subject: [PATCH 45/70] Further removed duplicated methods --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 16 +--- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 82 +++---------------- standalones/function.py | 45 ++++------ standalones/open_orifices_with_curvature.py | 3 - .../Methods_fit_to_clinical_LAT.py | 12 --- 5 files changed, 31 insertions(+), 127 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index cfa1d90..ef077f7 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -32,6 +32,7 @@ from scipy.spatial.distance import cosine from vtk.numpy_interface import dataset_adapter as dsa +import standalones.function from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, get_normalized_cross_product from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk @@ -229,15 +230,7 @@ def creat_tube_around_spline(points_data, radius): def dijkstra_path(polydata, StartVertex, EndVertex): - path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(polydata) - # attention the return value will be reversed - path.SetStartVertex(EndVertex) - path.SetEndVertex(StartVertex) - path.Update() - points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk_to_numpy(points_data) - return points_data + return standalones.function.dijkstra_path(polydata, StartVertex, EndVertex) def dijkstra_path_on_a_plane(polydata, StartVertex, EndVertex, plane_point): @@ -408,10 +401,7 @@ def get_mean_point(data): def multidim_intersect(arr1, arr2): - arr1_view = arr1.view([('', arr1.dtype)] * arr1.shape[1]) - arr2_view = arr2.view([('', arr2.dtype)] * arr2.shape[1]) - intersected = np.intersect1d(arr1_view, arr2_view) - return intersected.view(arr1.dtype).reshape(-1, arr1.shape[1]) + return standalones.function.multidim_intersect(arr1, arr2) def multidim_intersect_bool(arr1, arr2): diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index cde64b4..6e40809 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -29,6 +29,7 @@ from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa +import standalones.function import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from Atrial_LDRBM.LDRBM.Fiber_LA import Methods_LA from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import generate_spline_points @@ -283,7 +284,8 @@ def creat_tube_around_spline(points_data, radius): # Generate the radius scalars tubeRadius = vtk.vtkDoubleArray() - n = generate_spline_points(points_data).GetNumberOfPoints() + spline_points = generate_spline_points(points_data) + n = spline_points.GetNumberOfPoints() tubeRadius.SetNumberOfTuples(n) tubeRadius.SetName("TubeRadius") @@ -297,13 +299,13 @@ def creat_tube_around_spline(points_data, radius): tubeRadius.SetTuple1(i, r) # Add the scalars to the polydata - tubePolyData = functionSource.GetOutput() - tubePolyData.GetPointData().AddArray(tubeRadius) - tubePolyData.GetPointData().SetActiveScalars("TubeRadius") + tube_poly_data = spline_points + tube_poly_data.GetPointData().AddArray(tubeRadius) + tube_poly_data.GetPointData().SetActiveScalars("TubeRadius") # Create the tubes TODO: SidesShareVerticesOn()??? tuber = vtk.vtkTubeFilter() - tuber.SetInputData(tubePolyData) + tuber.SetInputData(tube_poly_data) tuber.SetNumberOfSides(40) tuber.SidesShareVerticesOn() tuber.SetVaryRadiusToVaryRadiusByAbsoluteScalar() @@ -319,30 +321,14 @@ def creat_tube_around_spline(points_data, radius): def dijkstra_path(polydata, StartVertex, EndVertex): - path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(polydata) - - path.SetStartVertex(EndVertex) - path.SetEndVertex(StartVertex) - path.Update() - points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk_to_numpy(points_data) - return points_data + return standalones.function.dijkstra_path(polydata, StartVertex, EndVertex) def dijkstra_path_coord(polydata, StartVertex, EndVertex): StartVertex = find_closest_point(polydata, StartVertex) EndVertex = find_closest_point(polydata, EndVertex) - path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(polydata) - - path.SetStartVertex(EndVertex) - path.SetEndVertex(StartVertex) - path.Update() - points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk_to_numpy(points_data) - return points_data + return dijkstra_path(polydata, StartVertex, EndVertex) def dijkstra_path_on_a_plane(polydata, args, StartVertex, EndVertex, plane_point): @@ -542,55 +528,7 @@ def get_mean_point(data): def multidim_intersect(arr1, arr2): - arr1_view = arr1.view([('', arr1.dtype)] * arr1.shape[1]) - arr2_view = arr2.view([('', arr2.dtype)] * arr2.shape[1]) - intersected = np.intersect1d(arr1_view, arr2_view) - return intersected.view(arr1.dtype).reshape(-1, arr1.shape[1]) - - -def multidim_intersect_bool(arr1, arr2): - arr1_view = arr1.view([('', arr1.dtype)] * arr1.shape[1]) - arr2_view = arr2.view([('', arr2.dtype)] * arr2.shape[1]) - intersected = np.intersect1d(arr1_view, arr2_view) - if len(intersected.view(arr1.dtype).reshape(-1, arr1.shape[1])) == 0: - res = 0 - else: - res = 1 - return res - - -def get_ct_end_points_id(endo, ct, scv, icv): - # endo - points_data = endo.GetPoints().GetData() - endo_points = vtk_to_numpy(points_data) - - # ct - points_data = ct.GetPoints().GetData() - ct_points = vtk_to_numpy(points_data) - - # scv - points_data = scv.GetPoints().GetData() - scv_points = vtk_to_numpy(points_data) - - # icv - points_data = icv.GetPoints().GetData() - icv_points = vtk_to_numpy(points_data) - - # intersection - # inter_ct_endo = multidim_intersect(endo_points, ct_points) - # inter_icv = multidim_intersect(inter_ct_endo, icv_points) - # inter_scv = multidim_intersect(inter_ct_endo, scv_points)` - inter_icv = multidim_intersect(ct_points, icv_points) - inter_scv = multidim_intersect(ct_points, scv_points) - - # calculating mean point - path_icv = np.asarray([np.mean(inter_icv[:, 0]), np.mean(inter_icv[:, 1]), np.mean(inter_icv[:, 2])]) - path_scv = np.asarray([np.mean(inter_scv[:, 0]), np.mean(inter_scv[:, 1]), np.mean(inter_scv[:, 2])]) - - path_ct_id_icv = find_closest_point(endo, path_icv) - path_ct_id_scv = find_closest_point(endo, path_scv) - - return path_ct_id_icv, path_ct_id_scv + return standalones.function.multidim_intersect(arr1, arr2) def get_tv_end_points_id(endo, ra_tv_s_surface, ra_ivc_surface, ra_svc_surface, ra_tv_surface): diff --git a/standalones/function.py b/standalones/function.py index e444a33..3a0a9b5 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -39,9 +39,7 @@ def to_polydata(mesh): - polydata = apply_vtk_geom_filter(mesh) - - return polydata + return apply_vtk_geom_filter(mesh) def get_mean_point(ring_points): @@ -98,23 +96,17 @@ def find_points_on_mv(mv_points, center_lpv): kDTree.FindClosestNPoints(1, center_lpv, id_list) index = id_list.GetId(0) res_1 = mv_points_array_1[index] - distance = [] - for i in range(len(mv_points_array_1)): - d = np.linalg.norm(mv_points_array_1[i] - res_1, ord=None, axis=None, keepdims=False) - distance += [d] - res_2 = mv_points_array_1[distance.index(max(distance))] - - distance_diff = [] - for i in range(len(mv_points_array_1)): - d_mv_l = np.linalg.norm(mv_points_array_1[i] - res_1, ord=None, axis=None, keepdims=False) - d_mv_r = np.linalg.norm(mv_points_array_1[i] - res_2, ord=None, axis=None, keepdims=False) - distance_diff += [abs(d_mv_l - d_mv_r)] + distances = np.linalg.norm(mv_points_array_1 - res_1, axis=1) + res_2 = mv_points_array_1[np.argmax(distances)] + + d_mv_l = np.linalg.norm(mv_points_array_1 - res_1, axis=1) # Distances to res_1 + d_mv_r = np.linalg.norm(mv_points_array_1 - res_2, axis=1) # Distances to res_2 + distance_diff = np.abs(d_mv_l - d_mv_r) # Absolute differences + res_3 = mv_points_array_1[distance_diff.index(min(distance_diff))] - distance_2 = [] - for i in range(len(mv_points_array_1)): - d_2 = np.linalg.norm(mv_points_array_1[i] - res_3, ord=None, axis=None, keepdims=False) - distance_2 += [d_2] + distance_2 = np.linalg.norm(mv_points_array_1 - res_3, axis=1) + res_4 = mv_points_array_1[distance_2.index(max(distance_2))] return res_1, res_2, res_3, res_4 @@ -150,12 +142,12 @@ def cut_into_two_parts(polydata, point_1, point_2, point_3): return sub_1, sub_2 -def dijkstra_path(polydata, StartVertex, EndVertex): +def dijkstra_path(polydata, start_vertex, end_vertex): path = vtk.vtkDijkstraGraphGeodesicPath() path.SetInputData(polydata) # attention the return value will be reversed - path.SetStartVertex(EndVertex) - path.SetEndVertex(StartVertex) + path.SetStartVertex(end_vertex) + path.SetEndVertex(start_vertex) path.Update() points_data = path.GetOutput().GetPoints().GetData() points_data = vtk_to_numpy(points_data) @@ -171,9 +163,8 @@ def get_mv_l_and_r(mv_band, center_lpv): # Clean unused points surface = to_polydata(connect.GetOutput()) - points_data = clean_polydata(surface).GetPoints().GetData() - ring = vtk_to_numpy(points_data) - center_point_1 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) + ring = vtk_to_numpy(clean_polydata(surface).GetPoints().GetData()) + center_point_1 = np.mean(ring, axis=0) connect.DeleteSpecifiedRegion(1) connect.AddSpecifiedRegion(0) @@ -181,9 +172,9 @@ def get_mv_l_and_r(mv_band, center_lpv): # Clean unused points surface = to_polydata(connect.GetOutput()) - points_data = clean_polydata(surface).GetPoints().GetData() - ring = vtk_to_numpy(points_data) - center_point_2 = np.asarray([np.mean(ring[:, 0]), np.mean(ring[:, 1]), np.mean(ring[:, 2])]) + ring = vtk_to_numpy(clean_polydata(surface).GetPoints().GetData()) + center_point_2 = np.mean(ring, axis=0) + dis_1 = np.linalg.norm(center_point_1 - center_lpv) dis_2 = np.linalg.norm(center_point_2 - center_lpv) if dis_1 > dis_2: diff --git a/standalones/open_orifices_with_curvature.py b/standalones/open_orifices_with_curvature.py index cb7e607..17fb138 100644 --- a/standalones/open_orifices_with_curvature.py +++ b/standalones/open_orifices_with_curvature.py @@ -25,7 +25,6 @@ under the License. """ import argparse -import collections import os import sys import warnings @@ -34,13 +33,11 @@ import pymeshfix import pyvista as pv import vtk -from scipy.spatial import cKDTree from vtk.numpy_interface import dataset_adapter as dsa from standalones.open_orifices_manually import open_orifices_manually from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point_with_preselection, pick_point from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import extract_largest_region, vtk_thr -from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts from vtk_opencarp_helper_methods.vtk_methods import filters from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer diff --git a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py index 593c36b..2319dbe 100644 --- a/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py +++ b/tune_conductivity_from_clinical_LAT_map/Methods_fit_to_clinical_LAT.py @@ -346,18 +346,6 @@ def low_CV(model, low_CV_thr, meshfold): write_to_dat(meshfold + '/low_CV.dat', sigma) -def dijkstra_path(polydata, StartVertex, EndVertex): - path = vtk.vtkDijkstraGraphGeodesicPath() - path.SetInputData(polydata) - # attention the return value will be reversed - path.SetStartVertex(EndVertex) - path.SetEndVertex(StartVertex) - path.Update() - points_data = path.GetOutput().GetPoints().GetData() - points_data = vtk_to_numpy(points_data) - return points_data - - def get_EAP(path_mod, path_fib): model = smart_reader(path_mod) mod_fib = smart_reader(path_fib) From 6810e3438fe9cce30bd01a1b544b1ec296a9e359 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 28 Nov 2024 10:36:29 +0100 Subject: [PATCH 46/70] Removed unused variables in la_generate_fiber.py --- .../LDRBM/Fiber_LA/la_generate_fiber.py | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 3c042f1..80e32ad 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -15,7 +15,7 @@ "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an @@ -76,9 +76,6 @@ def la_generate_fiber(model, args, job): inferior_right_pulmonary_vein_epi = int(tag_dict['inferior_right_pulmonary_vein_epi']) left_atrial_appendage_epi = int(tag_dict['left_atrial_appendage_epi']) left_atrial_wall_epi = int(tag_dict['left_atrial_wall_epi']) - left_atrial_lateral_wall_epi = int(tag_dict['left_atrial_lateral_wall_epi']) - left_septum_wall_epi = int(tag_dict['left_septum_wall_epi']) - left_atrial_roof_epi = int(tag_dict['left_atrial_roof_epi']) # load endo tags mitral_valve_endo = int(tag_dict['mitral_valve_endo']) @@ -88,23 +85,14 @@ def la_generate_fiber(model, args, job): inferior_right_pulmonary_vein_endo = int(tag_dict['inferior_right_pulmonary_vein_endo']) left_atrial_appendage_endo = int(tag_dict['left_atrial_appendage_endo']) left_atrial_wall_endo = int(tag_dict['left_atrial_wall_endo']) - left_atrial_lateral_wall_endo = int(tag_dict['left_atrial_lateral_wall_endo']) - left_septum_wall_endo = int(tag_dict['left_septum_wall_endo']) - left_atrial_roof_endo = int(tag_dict['left_atrial_roof_endo']) bachmann_bundel_left = int(tag_dict['bachmann_bundel_left']) - tao_mv = 0.85 - # ab - ab = model.GetCellData().GetArray('phie_ab') ab_grad = model.GetCellData().GetArray('grad_ab') - ab = vtk_to_numpy(ab) ab_grad = vtk_to_numpy(ab_grad) # v - v = model.GetCellData().GetArray('phie_v') v_grad = model.GetCellData().GetArray('grad_v') - v = vtk_to_numpy(v) v_grad = vtk_to_numpy(v_grad) # r @@ -113,15 +101,6 @@ def la_generate_fiber(model, args, job): r = vtk_to_numpy(r) r_grad = vtk_to_numpy(r_grad) - # r2 - r2 = model.GetCellData().GetArray('phie_r2') - r2 = vtk_to_numpy(r2) - - # phie - if args.mesh_type == "vol": - phie = model.GetCellData().GetArray('phie_phi') - phie = vtk_to_numpy(phie) - phie_grad = model.GetCellData().GetArray('grad_phi') phie_grad = vtk_to_numpy(phie_grad) @@ -195,10 +174,6 @@ def la_generate_fiber(model, args, job): tag[endo_ids] = left_atrial_wall_endo - LAA_s = vtk_thr(model, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv + 0.01) - - LAA_s = vtk_thr(LAA_s, 0, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03) - ## Optimize shape of LAA solving a laplacian with 0 in LAA and 1 in the boundary of LAA_s LAA_bb = vtk_thr(model, 2, "POINTS", "phie_ab2", max_phie_ab_tau_lpv - 0.03, max_phie_ab_tau_lpv + 0.01) From 105240cff4c2a059dbcf0b44a4a2491d4fa2bc25 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 28 Nov 2024 11:21:05 +0100 Subject: [PATCH 47/70] Extracted method for calculation of en for fiber generation --- .../LDRBM/Fiber_LA/la_generate_fiber.py | 118 +++++++----------- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 7 +- 2 files changed, 49 insertions(+), 76 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 80e32ad..08b2393 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -67,25 +67,10 @@ def la_generate_fiber(model, args, job): tag_dict = {} reader = csv.DictReader(f) for row in reader: - tag_dict[row['name']] = row['tag'] + tag_dict[row['name']] = int(row['tag']) # load epi tags mitral_valve_epi = int(tag_dict['mitral_valve_epi']) - superior_left_pulmonary_vein_epi = int(tag_dict['superior_left_pulmonary_vein_epi']) - inferior_left_pulmonary_vein_epi = int(tag_dict['inferior_left_pulmonary_vein_epi']) - superior_right_pulmonary_vein_epi = int(tag_dict['superior_right_pulmonary_vein_epi']) - inferior_right_pulmonary_vein_epi = int(tag_dict['inferior_right_pulmonary_vein_epi']) left_atrial_appendage_epi = int(tag_dict['left_atrial_appendage_epi']) - left_atrial_wall_epi = int(tag_dict['left_atrial_wall_epi']) - - # load endo tags - mitral_valve_endo = int(tag_dict['mitral_valve_endo']) - superior_left_pulmonary_vein_endo = int(tag_dict['superior_left_pulmonary_vein_endo']) - inferior_left_pulmonary_vein_endo = int(tag_dict['inferior_left_pulmonary_vein_endo']) - superior_right_pulmonary_vein_endo = int(tag_dict['superior_right_pulmonary_vein_endo']) - inferior_right_pulmonary_vein_endo = int(tag_dict['inferior_right_pulmonary_vein_endo']) - left_atrial_appendage_endo = int(tag_dict['left_atrial_appendage_endo']) - left_atrial_wall_endo = int(tag_dict['left_atrial_wall_endo']) - bachmann_bundel_left = int(tag_dict['bachmann_bundel_left']) # ab ab_grad = model.GetCellData().GetArray('grad_ab') @@ -157,12 +142,12 @@ def la_generate_fiber(model, args, job): epi.DeepCopy(model) tag_epi = np.zeros(len(r), dtype=int) - tag_epi[:] = left_atrial_wall_epi + tag_epi[:] = tag_dict['left_atrial_wall_epi'] tag_endo = np.zeros(len(r), dtype=int) - tag_endo[:] = left_atrial_wall_endo + tag_endo[:] = tag_dict['left_atrial_wall_endo'] else: # Volume mesh - tag = np.ones(len(r), dtype=int) * left_atrial_wall_epi + tag = np.ones(len(r), dtype=int) * tag_dict['left_atrial_wall_epi'] epi = vtk_thr(model, 0, "CELLS", "phie_phi", 0.5) @@ -172,7 +157,7 @@ def la_generate_fiber(model, args, job): endo_ids = np.setdiff1d(endo_ids, epi_ids) - tag[endo_ids] = left_atrial_wall_endo + tag[endo_ids] = tag_dict['left_atrial_wall_endo'] ## Optimize shape of LAA solving a laplacian with 0 in LAA and 1 in the boundary of LAA_s @@ -200,58 +185,43 @@ def la_generate_fiber(model, args, job): # tagging endo-layer if args.mesh_type == 'bilayer': - tag_endo[MV_ids] = mitral_valve_endo + tag_endo[MV_ids] = tag_dict['mitral_valve_endo'] ab_grad[MV_ids] = r_grad[MV_ids] - tag_endo[LAA_ids] = left_atrial_appendage_endo + tag_endo[LAA_ids] = tag_dict['left_atrial_appendage_endo'] - tag_endo[PVs["RIPV"]] = inferior_right_pulmonary_vein_endo - tag_endo[PVs["LIPV"]] = inferior_left_pulmonary_vein_endo - - tag_endo[PVs["RSPV"]] = superior_right_pulmonary_vein_endo - tag_endo[PVs["LSPV"]] = superior_left_pulmonary_vein_endo - - ab_grad[PVs["RIPV"]] = v_grad[PVs["RIPV"]] - ab_grad[PVs["LIPV"]] = v_grad[PVs["LIPV"]] - ab_grad[PVs["RSPV"]] = v_grad[PVs["RSPV"]] - ab_grad[PVs["LSPV"]] = v_grad[PVs["LSPV"]] + tag_endo = copy_valve_ids(PVs["LIPV"], PVs["LSPV"], PVs["RIPV"], PVs["RSPV"], tag_dict, tag_endo) + ids_to_clone = [PVs["RIPV"], PVs["LIPV"], PVs["RSPV"], PVs["LSPV"]] + ab_grad = clone_ids(v_grad, ab_grad, ids_to_clone) # tagging epi-layer tag_epi[MV_ids] = mitral_valve_epi tag_epi[LAA_ids] = left_atrial_appendage_epi - tag_epi[PVs["RIPV"]] = inferior_right_pulmonary_vein_epi - tag_epi[PVs["LIPV"]] = inferior_left_pulmonary_vein_epi - - tag_epi[PVs["RSPV"]] = superior_right_pulmonary_vein_epi - tag_epi[PVs["LSPV"]] = superior_left_pulmonary_vein_epi + tag_epi = copy_valve_ids(PVs["LIPV"], PVs["LSPV"], PVs["RIPV"], PVs["RSPV"], tag_dict, tag_epi) ab_grad_epi = np.copy(ab_grad) else: MV_ids_endo = np.intersect1d(MV_ids, endo_ids) - tag[MV_ids_endo] = mitral_valve_endo + tag[MV_ids_endo] = tag_dict['mitral_valve_endo'] ab_grad[MV_ids_endo] = r_grad[MV_ids_endo] LAA_ids_endo = np.intersect1d(LAA_ids, endo_ids) - tag[LAA_ids_endo] = left_atrial_appendage_endo + tag[LAA_ids_endo] = tag_dict['left_atrial_appendage_endo'] RIPV_ids_endo = np.intersect1d(PVs["RIPV"], endo_ids) - tag[RIPV_ids_endo] = inferior_right_pulmonary_vein_endo LIPV_ids_endo = np.intersect1d(PVs["LIPV"], endo_ids) - tag[LIPV_ids_endo] = inferior_left_pulmonary_vein_endo RSPV_ids_endo = np.intersect1d(PVs["RSPV"], endo_ids) - tag[RSPV_ids_endo] = superior_right_pulmonary_vein_endo LSPV_ids_endo = np.intersect1d(PVs["LSPV"], endo_ids) - tag[LSPV_ids_endo] = superior_left_pulmonary_vein_endo - ab_grad[RIPV_ids_endo] = v_grad[RIPV_ids_endo] - ab_grad[RSPV_ids_endo] = v_grad[RSPV_ids_endo] - ab_grad[LIPV_ids_endo] = v_grad[LIPV_ids_endo] - ab_grad[LSPV_ids_endo] = v_grad[LSPV_ids_endo] + tag = copy_valve_ids(LIPV_ids_endo, LSPV_ids_endo, RIPV_ids_endo, RSPV_ids_endo, tag_dict, tag) + + id_to_clone = [RIPV_ids_endo, RSPV_ids_endo, LIPV_ids_endo, LSPV_ids_endo] + ab_grad = clone_ids(v_grad, ab_grad, id_to_clone) # tagging epi-layer @@ -262,13 +232,11 @@ def la_generate_fiber(model, args, job): tag[LAA_ids_epi] = left_atrial_appendage_epi RIPV_ids_epi = np.intersect1d(PVs["RIPV"], epi_ids) - tag[RIPV_ids_epi] = inferior_right_pulmonary_vein_epi LIPV_ids_epi = np.intersect1d(PVs["LIPV"], epi_ids) - tag[LIPV_ids_epi] = inferior_left_pulmonary_vein_epi RSPV_ids_epi = np.intersect1d(PVs["RSPV"], epi_ids) - tag[RSPV_ids_epi] = superior_right_pulmonary_vein_epi LSPV_ids_epi = np.intersect1d(PVs["LSPV"], epi_ids) - tag[LSPV_ids_epi] = superior_left_pulmonary_vein_epi + + tag = copy_valve_ids(LIPV_ids_epi, LSPV_ids_epi, RIPV_ids_epi, RSPV_ids_epi, tag_dict, tag) # Get epi bundle band @@ -308,19 +276,11 @@ def la_generate_fiber(model, args, job): k_epi = ab_grad_epi print('############### k ###############') - en_endo = k_endo - et * np.sum(k_endo * et, axis=1).reshape(len(et), 1) - en_epi = k_epi - et * np.sum(k_epi * et, axis=1).reshape(len(et), 1) + en_endo = calculate_en(et, k_endo) - # normalize the en - abs_en = np.linalg.norm(en_endo, axis=1, keepdims=True) - abs_en = np.where(abs_en != 0, abs_en, 1) - en_endo = en_endo / abs_en + en_epi = calculate_en(et, k_epi) - abs_en = np.linalg.norm(en_epi, axis=1, keepdims=True) - abs_en = np.where(abs_en != 0, abs_en, 1) - en_epi = en_epi / abs_en print('############### en ###############') - # el el_endo = np.cross(en_endo, et) el_epi = np.cross(en_epi, et) @@ -379,15 +339,8 @@ def la_generate_fiber(model, args, job): k = ab_grad print('############### k ###############') - en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) - - # normalize the en - abs_en = np.linalg.norm(en, axis=1, keepdims=True) - abs_en = np.where(abs_en != 0, abs_en, 1) - en = en / abs_en - + en = calculate_en(et, k) print('############### en ###############') - # el el = np.cross(en, et) print('############### el ###############') @@ -427,7 +380,8 @@ def la_generate_fiber(model, args, job): bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi, df, left_atrial_appendage_epi, mitral_valve_epi) - tag_epi = Method.assign_element_tag_around_path_within_radius(epi, bb_left, w_bb, tag_epi, bachmann_bundel_left) + tag_epi = Method.assign_element_tag_around_path_within_radius(epi, bb_left, w_bb, tag_epi, + tag_dict['bachmann_bundel_left']) el_epi = Method.assign_element_fiber_around_path_within_radius(epi, bb_left, w_bb, el_epi, smooth=True) else: bb_left, LAA_basis_inf, LAA_basis_sup, LAA_far_from_LIPV = Method.compute_wide_BB_path_left(epi_surf, df, @@ -437,7 +391,7 @@ def la_generate_fiber(model, args, job): vtk_to_numpy( epi_surf.GetCellData().GetArray( 'elemTag')), - bachmann_bundel_left) + tag_dict['bachmann_bundel_left']) el[epi_surf_ids] = Method.assign_element_fiber_around_path_within_radius(epi_surf, bb_left, w_bb, vtk_to_numpy( epi_surf.GetCellData().GetArray( @@ -517,3 +471,25 @@ def la_generate_fiber(model, args, job): end_time = datetime.datetime.now() running_time = end_time - start_time print('Writing as LA_with_fiber... done! ' + str(end_time) + '\nIt takes: ' + str(running_time) + '\n') + + +def calculate_en(et, k): + en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) + abs_en = np.linalg.norm(en, axis=1, keepdims=True) + abs_en = np.where(abs_en != 0, abs_en, 1) + en = en / abs_en + return en + + +def clone_ids(source, dest, id_to_clone): + for ids in id_to_clone: + dest[ids] = source[ids] + return dest + + +def copy_valve_ids(LIPV_ids, LSPV_ids, RIPV_ids, RSPV_ids, tag_source, tag_goal): + tag_goal[RIPV_ids] = tag_source['inferior_right_pulmonary_vein_endo'] + tag_goal[LIPV_ids] = tag_source['inferior_left_pulmonary_vein_endo'] + tag_goal[RSPV_ids] = tag_source['superior_right_pulmonary_vein_endo'] + tag_goal[LSPV_ids] = tag_source['superior_left_pulmonary_vein_endo'] + return tag_goal diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index a34e6d2..35c6912 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -37,6 +37,7 @@ import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data +from Atrial_LDRBM.LDRBM.Fiber_LA.la_generate_fiber import calculate_en from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import downsample_path from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, extract_largest_region from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy @@ -465,11 +466,7 @@ def ra_generate_fiber(model, args, job): # k = ab_grad print('############### k ###############') - en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) - - abs_en = np.linalg.norm(en, axis=1, keepdims=True) - abs_en = np.where(abs_en != 0, abs_en, 1) - en = en / abs_en + en = calculate_en(et, k) print('############### en ###############') # el el = np.cross(en, et) From d3ed0c0300d3b99586a161992628358cef660a63 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 28 Nov 2024 11:43:01 +0100 Subject: [PATCH 48/70] Extracted method for calculation of normalized_vectors --- .../Generate_Boundaries/extract_rings.py | 2 +- .../extract_rings_TOP_epi_endo.py | 2 +- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 3 ++- .../LDRBM/Fiber_LA/la_generate_fiber.py | 23 +++++-------------- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 6 ++--- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 6 ++--- standalones/function.py | 2 +- 7 files changed, 16 insertions(+), 28 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index bb9950a..7de156e 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -36,7 +36,7 @@ from sklearn.cluster import KMeans from vtk.numpy_interface import dataset_adapter as dsa -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index afa7f81..c52f9bd 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -36,7 +36,7 @@ from sklearn.cluster import KMeans from vtk.numpy_interface import dataset_adapter as dsa -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index ef077f7..75f1724 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -33,7 +33,8 @@ from vtk.numpy_interface import dataset_adapter as dsa import standalones.function -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, get_normalized_cross_product +from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, vtk_unstructured_grid_writer, \ diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 08b2393..84f4bf0 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -35,6 +35,7 @@ import Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA as Method from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors from Atrial_LDRBM.LDRBM.Fiber_LA.la_laplace import laplace_0_1 from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon @@ -271,14 +272,9 @@ def la_generate_fiber(model, args, job): et = phie_grad_norm print('############### et ###############') - # k - k_endo = ab_grad - k_epi = ab_grad_epi - print('############### k ###############') + en_endo = calculate_en(et, ab_grad) - en_endo = calculate_en(et, k_endo) - - en_epi = calculate_en(et, k_epi) + en_epi = calculate_en(et, ab_grad_epi) print('############### en ###############') # el @@ -286,10 +282,7 @@ def la_generate_fiber(model, args, job): el_epi = np.cross(en_epi, et) print('############### el ###############') - abs_v_grad = np.linalg.norm(v_grad, axis=1, keepdims=True) - abs_v_grad = np.where(abs_v_grad != 0, abs_v_grad, 1) - v_grad_norm = v_grad / abs_v_grad - + v_grad_norm = normalize_vectors(v_grad) ### Subendo PVs bundle selection el_endo[PVs["LIPV"]] = v_grad_norm[PVs["LIPV"]] @@ -345,9 +338,7 @@ def la_generate_fiber(model, args, job): el = np.cross(en, et) print('############### el ###############') - abs_v_grad = np.linalg.norm(v_grad, axis=1, keepdims=True) - abs_v_grad = np.where(abs_v_grad != 0, abs_v_grad, 1) - v_grad_norm = v_grad / abs_v_grad + v_grad_norm = normalize_vectors(v_grad) ### Subendo PVs bundle selection @@ -475,9 +466,7 @@ def la_generate_fiber(model, args, job): def calculate_en(et, k): en = k - et * np.sum(k * et, axis=1).reshape(len(et), 1) - abs_en = np.linalg.norm(en, axis=1, keepdims=True) - abs_en = np.where(abs_en != 0, abs_en, 1) - en = en / abs_en + en = normalize_vectors(en) return en diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index 6e40809..b93acf4 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -33,7 +33,8 @@ import vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations from Atrial_LDRBM.LDRBM.Fiber_LA import Methods_LA from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import generate_spline_points -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors, \ + get_normalized_cross_product from vtk_opencarp_helper_methods.openCARP.exporting import write_to_elem, write_to_pts, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, vtk_polydata_writer, \ @@ -253,8 +254,7 @@ def generate_sheet_dir(args, model, job): sheet = np.cross(normals, fiber) sheet = np.where(sheet == [0, 0, 0], [1, 0, 0], sheet).astype("float32") # normalize - abs_sheet = np.linalg.norm(sheet, axis=1, keepdims=True) - sheet_norm = sheet / abs_sheet + sheet_norm = normalize_vectors(sheet) ''' writing diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index 35c6912..d510531 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -37,6 +37,7 @@ import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors from Atrial_LDRBM.LDRBM.Fiber_LA.la_generate_fiber import calculate_en from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import downsample_path from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, extract_largest_region @@ -451,10 +452,7 @@ def ra_generate_fiber(model, args, job): tag[SN_ids] = sinus_node print('Bundles selection...done') - # normalize the gradient phie - abs_phie_grad = np.linalg.norm(phie_grad, axis=1, keepdims=True) - abs_phie_grad = np.where(abs_phie_grad != 0, abs_phie_grad, 1) - phie_grad_norm = phie_grad / abs_phie_grad + phie_grad_norm = normalize_vectors(phie_grad) ##### Local coordinate system ##### # et diff --git a/standalones/function.py b/standalones/function.py index 3a0a9b5..25948d4 100644 --- a/standalones/function.py +++ b/standalones/function.py @@ -29,7 +29,7 @@ import scipy.spatial as spatial import vtk -from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import get_normalized_cross_product +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, \ get_elements_above_plane From 2c5148582d21e46061d538b2af79d72be941e495 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 28 Nov 2024 16:29:52 +0100 Subject: [PATCH 49/70] Fixed bug where epi tags where epi tags went missing --- .../LDRBM/Fiber_LA/la_generate_fiber.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 84f4bf0..bb0bce6 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -35,9 +35,9 @@ import Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA as Method from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data -from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors from Atrial_LDRBM.LDRBM.Fiber_LA.la_laplace import laplace_0_1 from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ @@ -191,7 +191,7 @@ def la_generate_fiber(model, args, job): tag_endo[LAA_ids] = tag_dict['left_atrial_appendage_endo'] - tag_endo = copy_valve_ids(PVs["LIPV"], PVs["LSPV"], PVs["RIPV"], PVs["RSPV"], tag_dict, tag_endo) + tag_endo = copy_valve_ids(PVs["LIPV"], PVs["LSPV"], PVs["RIPV"], PVs["RSPV"], tag_dict, tag_endo, "endo") ids_to_clone = [PVs["RIPV"], PVs["LIPV"], PVs["RSPV"], PVs["LSPV"]] ab_grad = clone_ids(v_grad, ab_grad, ids_to_clone) @@ -201,7 +201,7 @@ def la_generate_fiber(model, args, job): tag_epi[LAA_ids] = left_atrial_appendage_epi - tag_epi = copy_valve_ids(PVs["LIPV"], PVs["LSPV"], PVs["RIPV"], PVs["RSPV"], tag_dict, tag_epi) + tag_epi = copy_valve_ids(PVs["LIPV"], PVs["LSPV"], PVs["RIPV"], PVs["RSPV"], tag_dict, tag_epi, "epi") ab_grad_epi = np.copy(ab_grad) @@ -219,7 +219,7 @@ def la_generate_fiber(model, args, job): RSPV_ids_endo = np.intersect1d(PVs["RSPV"], endo_ids) LSPV_ids_endo = np.intersect1d(PVs["LSPV"], endo_ids) - tag = copy_valve_ids(LIPV_ids_endo, LSPV_ids_endo, RIPV_ids_endo, RSPV_ids_endo, tag_dict, tag) + tag = copy_valve_ids(LIPV_ids_endo, LSPV_ids_endo, RIPV_ids_endo, RSPV_ids_endo, tag_dict, tag,"endo") id_to_clone = [RIPV_ids_endo, RSPV_ids_endo, LIPV_ids_endo, LSPV_ids_endo] ab_grad = clone_ids(v_grad, ab_grad, id_to_clone) @@ -237,7 +237,7 @@ def la_generate_fiber(model, args, job): RSPV_ids_epi = np.intersect1d(PVs["RSPV"], epi_ids) LSPV_ids_epi = np.intersect1d(PVs["LSPV"], epi_ids) - tag = copy_valve_ids(LIPV_ids_epi, LSPV_ids_epi, RIPV_ids_epi, RSPV_ids_epi, tag_dict, tag) + tag = copy_valve_ids(LIPV_ids_epi, LSPV_ids_epi, RIPV_ids_epi, RSPV_ids_epi, tag_dict, tag, "epi") # Get epi bundle band @@ -476,9 +476,9 @@ def clone_ids(source, dest, id_to_clone): return dest -def copy_valve_ids(LIPV_ids, LSPV_ids, RIPV_ids, RSPV_ids, tag_source, tag_goal): - tag_goal[RIPV_ids] = tag_source['inferior_right_pulmonary_vein_endo'] - tag_goal[LIPV_ids] = tag_source['inferior_left_pulmonary_vein_endo'] - tag_goal[RSPV_ids] = tag_source['superior_right_pulmonary_vein_endo'] - tag_goal[LSPV_ids] = tag_source['superior_left_pulmonary_vein_endo'] +def copy_valve_ids(LIPV_ids, LSPV_ids, RIPV_ids, RSPV_ids, tag_source, tag_goal, extension): + tag_goal[RIPV_ids] = tag_source[f'inferior_right_pulmonary_vein_{extension}'] + tag_goal[LIPV_ids] = tag_source[f'inferior_left_pulmonary_vein_{extension}'] + tag_goal[RSPV_ids] = tag_source[f'superior_right_pulmonary_vein_{extension}'] + tag_goal[LSPV_ids] = tag_source[f'superior_left_pulmonary_vein_{extension}'] return tag_goal From 9dbaeb39519bee4bff3d11ee9b2e68391be10b0e Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Fri, 29 Nov 2024 18:06:28 +0100 Subject: [PATCH 50/70] Added checks for file extensions for all writer --- Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index bb0bce6..3cb3c17 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -219,7 +219,7 @@ def la_generate_fiber(model, args, job): RSPV_ids_endo = np.intersect1d(PVs["RSPV"], endo_ids) LSPV_ids_endo = np.intersect1d(PVs["LSPV"], endo_ids) - tag = copy_valve_ids(LIPV_ids_endo, LSPV_ids_endo, RIPV_ids_endo, RSPV_ids_endo, tag_dict, tag,"endo") + tag = copy_valve_ids(LIPV_ids_endo, LSPV_ids_endo, RIPV_ids_endo, RSPV_ids_endo, tag_dict, tag, "endo") id_to_clone = [RIPV_ids_endo, RSPV_ids_endo, LIPV_ids_endo, LSPV_ids_endo] ab_grad = clone_ids(v_grad, ab_grad, id_to_clone) From 5b72cc0c88d660fdb1c1c179dbc418075d05b9d0 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Fri, 29 Nov 2024 18:19:25 +0100 Subject: [PATCH 51/70] Extracted method for fiber generation for left and right atrium --- Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py | 76 +++++++++++++++----------- Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py | 26 +-------- 2 files changed, 46 insertions(+), 56 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py index 2dd179b..1828092 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_main.py @@ -35,6 +35,7 @@ from Atrial_LDRBM.LDRBM.Fiber_LA.la_laplace import la_laplace from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts, write_to_elem, write_to_lon from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy +from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader def parser(): @@ -81,41 +82,11 @@ def jobID(args): @tools.carpexample(parser, jobID) def run(args, job): - LA_mesh = args.mesh + '_surf/LA' - - if args.mesh_type == "bilayer": - reader = vtk.vtkPolyDataReader() - else: - reader = vtk.vtkPolyDataReader() - # reader = vtk.vtkUnstructuredGridReader() - reader.SetFileName(LA_mesh + '.vtk') - reader.Update() - LA = reader.GetOutput() - - if args.normals_outside: - reverse = vtk.vtkReverseSense() - reverse.ReverseCellsOn() - reverse.ReverseNormalsOn() - reverse.SetInputConnection(reader.GetOutputPort()) - reverse.Update() - - LA = reverse.GetOutput() - - pts = vtk_to_numpy(LA.GetPoints().GetData()) - - write_to_pts(LA_mesh + '.pts', pts) - - write_to_elem( LA_mesh + '.elem', LA, np.ones(LA.GetNumberOfCells(), dtype=int)) - - fibers = np.zeros((LA.GetNumberOfCells(), 6)) - fibers[:, 0] = 1 - fibers[:, 4] = 1 - - warnings.warn("Test if lon is storred correctly la_main.py l116 ff.") - write_to_lon(LA_mesh + '.lon', fibers, [fiber[3:6] for fiber in fibers], precession=1) + LA = init_mesh_and_fibers(args, "LA") start_time = datetime.datetime.now() init_start_time = datetime.datetime.now() + print('[Step 1] Solving laplace-dirichlet... ' + str(start_time)) output_laplace = la_laplace(args, job, LA) end_time = datetime.datetime.now() @@ -134,5 +105,46 @@ def run(args, job): print('Total running time: ' + str(tot_running_time)) +def init_mesh_and_fibers(args, atrium): + """ + Initializes the mesh and fibers for the fiber generation. + Sores both to disk for further processing. + + :param args: + :param atrium: 'LA' or 'RA' + :return: The loaded mesh + """ + mesh = args.mesh + f'_surf/{atrium}' + atrial_mesh = smart_reader(mesh + '.vtk') + if args.normals_outside: + reverse = vtk.vtkReverseSense() + reverse.ReverseCellsOn() + reverse.ReverseNormalsOn() + reverse.SetInputData(atrial_mesh) + reverse.Update() + + atrial_mesh = reverse.GetOutput() + pts = vtk_to_numpy(atrial_mesh.GetPoints().GetData()) + write_to_pts(mesh + '.pts', pts) + write_to_elem(mesh + '.elem', atrial_mesh, np.ones(atrial_mesh.GetNumberOfCells(), dtype=int)) + init_fibers(atrial_mesh, atrium, mesh) + return atrial_mesh + + +def init_fibers(atrial_mesh, atrium, mesh): + """ + Initializes fibers with ones and stores them to disk for further processing. + :param atrial_mesh: + :param atrium: + :param mesh: + :return: + """ + fibers = np.zeros((atrial_mesh.GetNumberOfCells(), 6)) + fibers[:, 0] = 1 + fibers[:, 4] = 1 + warnings.warn(f"Test if lon is stored correctly {atrium}_main.py l116 ff.") + write_to_lon(mesh + '.lon', fibers, [fiber[3:6] for fiber in fibers], precession=1) + + if __name__ == '__main__': run() diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py index 8e70036..80f7d5f 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_main.py @@ -34,6 +34,7 @@ from carputils import tools import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method +from Atrial_LDRBM.LDRBM.Fiber_LA.la_main import init_mesh_and_fibers from Atrial_LDRBM.LDRBM.Fiber_RA.create_bridges import add_free_bridge from Atrial_LDRBM.LDRBM.Fiber_RA.ra_generate_fiber import ra_generate_fiber from Atrial_LDRBM.LDRBM.Fiber_RA.ra_laplace import ra_laplace @@ -98,30 +99,7 @@ def jobID(args): @tools.carpexample(parser, jobID) def run(args, job): - RA_mesh = args.mesh + '_surf/RA' - RA = smart_reader(RA_mesh + '.vtk') - - if args.normals_outside: - reverse = vtk.vtkReverseSense() - reverse.ReverseCellsOn() - reverse.ReverseNormalsOn() - reverse.SetInputData(RA) - reverse.Update() - - RA = reverse.GetOutput() - - pts = vtk_to_numpy(RA.GetPoints().GetData()) - - write_to_pts(RA_mesh + '.pts', pts) - - write_to_elem(RA_mesh + '.elem', RA, np.ones(RA.GetNumberOfCells(), dtype=int)) - - fibers = np.zeros((RA.GetNumberOfCells(), 6)) - fibers[:, 0] = 1 - fibers[:, 4] = 1 - - write_to_lon(RA_mesh + '.lon', fibers, [fiber[3:6] for fiber in fibers]) - warnings.warn("Test if lon is storred correctly ra_main.py l120 ff.") + RA = init_mesh_and_fibers(args, "RA") start_time = datetime.datetime.now() print('[Step 1] Solving laplace-dirichlet... ' + str(start_time)) From ad23db5ee3d807158b712151cb8b38860d3f6eab Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Sun, 1 Dec 2024 19:00:45 +0100 Subject: [PATCH 52/70] Extracted more functionality form extract rings to improve readability --- .../Generate_Boundaries/extract_rings.py | 234 +++++++++--------- 1 file changed, 121 insertions(+), 113 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 7de156e..67a6261 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -37,6 +37,7 @@ from vtk.numpy_interface import dataset_adapter as dsa from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product +from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ @@ -109,7 +110,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i for r in fname: os.remove(r) # Biatrial geometry - if (LAA_id != "" and RAA_id != ""): + if LAA_id != "" and RAA_id != "": LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) @@ -141,7 +142,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i LA = generate_ids(mesh_poly, "Ids", "Ids") - vtkWrite(LA, outdir + '/LA.vtk') + vtk_write(LA, outdir + '/LA.vtk') LAA_id = find_closest_point(LA, LA_ap_point) @@ -155,7 +156,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i dataSet = dsa.WrapDataObject(LA) dataSet.PointData.append(b_tag, 'boundary_tag') - vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) + vtk_write(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) thr.ThresholdBetween(RA_tag, RA_tag) thr.Update() @@ -168,7 +169,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i if LAA_base_id != "": RAA_base_id = find_closest_point(RA, RA_bs_point) - vtkWrite(RA, outdir + '/RA.vtk') + vtk_write(RA, outdir + '/RA.vtk') b_tag = np.zeros((RA.GetNumberOfPoints(),)) RA_rings = detect_and_mark_rings(RA, RA_ap_point, outdir, debug) b_tag, centroids, RA_rings = mark_RA_rings(RAA_id, RA_rings, b_tag, centroids, outdir) @@ -177,10 +178,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i dataSet = dsa.WrapDataObject(RA) dataSet.PointData.append(b_tag, 'boundary_tag') - vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) + vtk_write(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) elif RAA_id == "": - vtkWrite(mesh_surf, outdir + '/LA.vtk'.format(mesh)) + vtk_write(mesh_surf, outdir + '/LA.vtk'.format(mesh)) LA_ap_point = mesh_surf.GetPoint(int(LAA_id)) centroids["LAA"] = LA_ap_point array_name = "Ids" @@ -197,10 +198,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i dataSet = dsa.WrapDataObject(LA) dataSet.PointData.append(b_tag, 'boundary_tag') - vtkWrite(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) + vtk_write(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) elif LAA_id == "": - vtkWrite(mesh_surf, outdir + '/RA.vtk'.format(mesh)) + vtk_write(mesh_surf, outdir + '/RA.vtk'.format(mesh)) RA_ap_point = mesh_surf.GetPoint(int(RAA_id)) centroids["RAA"] = RA_ap_point @@ -213,7 +214,7 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i dataSet = dsa.WrapDataObject(RA) dataSet.PointData.append(b_tag, 'boundary_tag') - vtkWrite(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) + vtk_write(dataSet.VTKObject, outdir + '/RA_boundaries_tagged.vtk'.format(mesh)) df = pd.DataFrame(centroids) df.to_csv(outdir + "/rings_centroids.csv", float_format="%.2f", index=False) @@ -250,7 +251,7 @@ def detect_and_mark_rings(surf, ap_point, outdir, debug): # be careful overwrite previous rings if debug: - vtkWrite(surface, outdir + '/ring_' + str(i) + '.vtk') + vtk_write(surface, outdir + '/ring_' + str(i) + '.vtk') ring_surf = vtk.vtkPolyData() ring_surf.DeepCopy(surface) @@ -521,48 +522,19 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): ivc_center = np.array(r.center) ivc = r.vtk_polydata - plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) + tv_f_plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) - surface = apply_vtk_geom_filter(model) + model_surface = apply_vtk_geom_filter(model) - surface = apply_vtk_geom_filter(get_elements_above_plane(surface, plane)) + surface_over_tv_f = apply_vtk_geom_filter(get_elements_above_plane(model_surface, tv_f_plane)) if debug: - vtkWrite(surface, outdir + '/cutted_RA.vtk') - - """ - here we will extract the feature edge - """ - - gamma_top = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, - non_manifold_edges_on=False) - - if debug: - surface = apply_vtk_geom_filter(gamma_top) - - vtkWrite(surface, outdir + '/gamma_top.vtk') + vtk_write(surface_over_tv_f, outdir + '/cutted_RA.vtk') """ separate the tv into tv tv-f and tv-f """ - norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) - norm_2 = - norm_1 - - plane = initialize_plane(norm_1[0], tv_center) - - plane2 = initialize_plane(norm_2[0], tv_center) - - tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, plane)) - - tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) - - write_to_vtx(outdir + '/ids_TV_F.vtx', tv_f_ids) - - tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, plane2, extract_boundary_cells_on=True)) - - tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) - - write_to_vtx(outdir + '/ids_TV_S.vtx', tv_s_ids) + split_tv(outdir, tv, tv_center, ivc_center, svc_center) svc_points = svc.GetPoints().GetData() svc_points = vtk_to_numpy(svc_points) @@ -570,56 +542,14 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): ivc_points = svc.GetPoints().GetData() # Changed ivc_points = vtk_to_numpy(ivc_points) - connect = init_connectivity_filter(gamma_top, ExtractionModes.SPECIFIED_REGIONS) - num = connect.GetNumberOfExtractedRegions() - - for i in range(num): - connect.AddSpecifiedRegion(i) - connect.Update() - surface = connect.GetOutput() - - if debug: - vtkWrite(surface, outdir + f'/gamma_top_{str(i)}.vtk') - - # Clean unused points - surface = clean_polydata(surface) - - points = surface.GetPoints().GetData() - points = vtk_to_numpy(points) - points = points.tolist() - - if debug: - create_pts(points, f'/border_points_{str(i)}', outdir) - - in_ivc = False - in_svc = False - # if there is point of group i in both svc and ivc then it is the "top_endo+epi" we need - while in_ivc == False and in_svc == False: - for var in points: - if var in ivc_points: - in_ivc = True - if var in svc_points: - in_svc = True - if in_ivc and in_svc: - top_endo_id = i - break - else: - top_endo_id = i # comment this line if errors - break - - # delete added region id - connect.DeleteSpecifiedRegion(i) - connect.Update() - # It can happen that the first i=region(0) is the CS. Remove the -1 if that is the case - connect.AddSpecifiedRegion(top_endo_id - 1) # Find the id in the points dividing the RA, avoid CS - connect.Update() - surface = connect.GetOutput() + """ + here we will extract the feature edge + """ - # Clean unused points - top_cut = clean_polydata(surface) + top_cut = extract_top_cut(outdir, surface_over_tv_f, ivc_points, svc_points, debug) if debug: - vtkWrite(top_cut, outdir + '/top_endo_epi.vtk') # If this is the CS, then change top_endo_id in 877 + vtk_write(top_cut, outdir + '/top_endo_epi.vtk') # If this is the CS, then change top_endo_id in 877 pts_in_top = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids")) pts_in_svc = vtk_to_numpy(svc.GetPointData().GetArray("Ids")) @@ -627,9 +557,9 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): to_delete = np.zeros((len(pts_in_top),), dtype=int) - for i in range(len(pts_in_top)): - if pts_in_top[i] in pts_in_svc or pts_in_top[i] in pts_in_ivc: - to_delete[i] = 1 + for region_id in range(len(pts_in_top)): + if pts_in_top[region_id] in pts_in_svc or pts_in_top[region_id] in pts_in_ivc: + to_delete[region_id] = 1 meshNew = dsa.WrapDataObject(top_cut) meshNew.PointData.append(to_delete, "delete") @@ -641,49 +571,127 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): mv_id = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] connect = init_connectivity_filter(geo_port, ExtractionModes.SPECIFIED_REGIONS) - num = connect.GetNumberOfExtractedRegions() + num_regions = connect.GetNumberOfExtractedRegions() - for i in range(num): - connect.AddSpecifiedRegion(i) + for region_id in range(num_regions): + connect.AddSpecifiedRegion(region_id) connect.Update() - surface = connect.GetOutput() + surface_over_tv_f = connect.GetOutput() # Clean unused points - surface = clean_polydata(surface) + surface_over_tv_f = clean_polydata(surface_over_tv_f) - pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) + pts_surf = vtk_to_numpy(surface_over_tv_f.GetPointData().GetArray("Ids")) if mv_id not in pts_surf: - found_id = i + found_id = region_id break # delete added region id - connect.DeleteSpecifiedRegion(i) + connect.DeleteSpecifiedRegion(region_id) connect.Update() connect.AddSpecifiedRegion(found_id) connect.Update() - surface = clean_polydata(connect.GetOutput()) + surface_over_tv_f = clean_polydata(connect.GetOutput()) - top_endo = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) + top_endo = vtk_to_numpy(surface_over_tv_f.GetPointData().GetArray("Ids")) write_to_vtx(outdir + '/ids_TOP_ENDO.vtx', top_endo) +def extract_top_cut(outdir, surface_over_tv_f, ivc_points, svc_points, debug): + gamma_top = get_feature_edges(surface_over_tv_f, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + non_manifold_edges_on=False) + if debug: + surface_over_tv_f = apply_vtk_geom_filter(gamma_top) + + vtk_write(surface_over_tv_f, outdir + '/gamma_top.vtk') + connect = init_connectivity_filter(gamma_top, ExtractionModes.SPECIFIED_REGIONS) + num_regions = connect.GetNumberOfExtractedRegions() + for region_id in range(num_regions): + connect.AddSpecifiedRegion(region_id) + connect.Update() + surface_over_tv_f = clean_polydata(connect.GetOutput()) + + if debug: + vtk_write(surface_over_tv_f, outdir + f'/gamma_top_{str(region_id)}.vtk') + + boarder_points = surface_over_tv_f.GetPoints().GetData() + boarder_points = vtk_to_numpy(boarder_points).tolist() + + if debug: + create_pts(boarder_points, f'/border_points_{str(region_id)}', outdir) + + if is_top_endo_epi_cut(ivc_points, svc_points, boarder_points): + top_endo_id = region_id + else: + print(f"Region {region_id} is not the top cut for endo and epi") + + # delete added region id + connect.DeleteSpecifiedRegion(region_id) + connect.Update() + # It can happen that the first i=region(0) is the CS. Remove the -1 if that is the case + connect.AddSpecifiedRegion(top_endo_id - 1) # Find the id in the points dividing the RA, avoid CS + connect.Update() + surface_over_tv_f = connect.GetOutput() + # Clean unused points + top_cut = clean_polydata(surface_over_tv_f) + return top_cut + + +def split_tv(out_dir, tv, tv_center, ivc_center, svc_center): + """ + Splits the tricuspid valve along the svc to ivc axis + :param out_dir: Output directory where the two parts are stored + :param tv: The tricuspid valve geometry + :param tv_center: Center of the tricuspid valve + :param ivc_center: Center of the ivc + :param svc_center: Center of the svc + :return: + """ + norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) + tv_f_plane = initialize_plane(norm_1[0], tv_center) + tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, tv_f_plane)) + tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) + write_to_vtx(out_dir + '/ids_TV_F.vtx', tv_f_ids) + + norm_2 = - norm_1 + tv_s_plane = initialize_plane(norm_2[0], tv_center) + tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, tv_s_plane, extract_boundary_cells_on=True)) + tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) + write_to_vtx(out_dir + '/ids_TV_S.vtx', tv_s_ids) + + +def is_top_endo_epi_cut(ivc_points, svc_points, points): + """ + Returns if the given region cuts the mesh into top and lower cut for endo and epi + :param ivc_points: Points labeled as IVC (Inferior vena cava) + :param svc_points: Points labeled as SVC (Superior vena cava) + :param points: all points associated with this region + :return: + """ + in_ivc = False + in_svc = False + # if there is point of region_id in both svc and ivc then it is the "top_endo+epi" we need + for var in points: + if var in ivc_points: + in_ivc = True + if var in svc_points: + in_svc = True + if in_ivc and in_svc: + return True + return False + + def create_pts(array_points, array_name, mesh_dir): - f = open(f"{mesh_dir}{array_name}.pts", "w") - f.write("0 0 0\n") - for i in range(len(array_points)): - f.write(f"{array_points[i][0]} {array_points[i][1]} {array_points[i][2]}\n") - f.close() + write_to_pts(f"{mesh_dir}{array_name}.pts", array_points) def to_polydata(mesh): - polydata = apply_vtk_geom_filter(mesh) - - return polydata + return apply_vtk_geom_filter(mesh) -def vtkWrite(input_data, name): +def vtk_write(input_data, name): vtk_polydata_writer(name, input_data) From 58dbefd68651405d7a78b60e19ab7cf84ec83d76 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Sun, 1 Dec 2024 19:26:11 +0100 Subject: [PATCH 53/70] Further extraction of methods from extract_rings.py and extract_rings_TOP_epi_endo.py --- .../Generate_Boundaries/extract_rings.py | 41 +++++----- .../extract_rings_TOP_epi_endo.py | 81 +++++-------------- 2 files changed, 41 insertions(+), 81 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 67a6261..49a8f56 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -40,8 +40,8 @@ from vtk_opencarp_helper_methods.openCARP.exporting import write_to_pts from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx -from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ - clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane +from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, clean_polydata, generate_ids, \ + get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane, \ init_connectivity_filter, ExtractionModes @@ -531,9 +531,6 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): if debug: vtk_write(surface_over_tv_f, outdir + '/cutted_RA.vtk') - """ - separate the tv into tv tv-f and tv-f - """ split_tv(outdir, tv, tv_center, ivc_center, svc_center) svc_points = svc.GetPoints().GetData() @@ -566,41 +563,47 @@ def cutting_plane_to_identify_tv_f_tv_s(model, rings, outdir, debug): thresh = get_lower_threshold(meshNew.VTKObject, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "delete") - geo_port, _geo_filter = get_vtk_geom_filter_port(thresh.GetOutputPort(), True) + threshed_mesh = apply_vtk_geom_filter(thresh.GetOutputPort(), True) mv_id = vtk_to_numpy(top_cut.GetPointData().GetArray("Ids"))[0] - connect = init_connectivity_filter(geo_port, ExtractionModes.SPECIFIED_REGIONS) - num_regions = connect.GetNumberOfExtractedRegions() + top_endo_ids = get_top_endo_ids(mv_id, threshed_mesh) + write_to_vtx(outdir + '/ids_TOP_ENDO.vtx', top_endo_ids) + + +def get_top_endo_ids(mv_id, threshed_mesh): + region_without_mv = get_region_not_including_ids(threshed_mesh, mv_id) + top_endo_ids = vtk_to_numpy(clean_polydata(region_without_mv).GetPointData().GetArray("Ids")) + return top_endo_ids + +def get_region_not_including_ids(mesh, ids): + connect = init_connectivity_filter(mesh, ExtractionModes.SPECIFIED_REGIONS) + num_regions = connect.GetNumberOfExtractedRegions() for region_id in range(num_regions): connect.AddSpecifiedRegion(region_id) connect.Update() - surface_over_tv_f = connect.GetOutput() + surface = connect.GetOutput() # Clean unused points - surface_over_tv_f = clean_polydata(surface_over_tv_f) + surface = clean_polydata(surface) - pts_surf = vtk_to_numpy(surface_over_tv_f.GetPointData().GetArray("Ids")) + pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - if mv_id not in pts_surf: + if ids not in pts_surf: found_id = region_id break # delete added region id connect.DeleteSpecifiedRegion(region_id) connect.Update() - connect.AddSpecifiedRegion(found_id) connect.Update() - surface_over_tv_f = clean_polydata(connect.GetOutput()) - - top_endo = vtk_to_numpy(surface_over_tv_f.GetPointData().GetArray("Ids")) - - write_to_vtx(outdir + '/ids_TOP_ENDO.vtx', top_endo) + return connect.GetOutput() def extract_top_cut(outdir, surface_over_tv_f, ivc_points, svc_points, debug): - gamma_top = get_feature_edges(surface_over_tv_f, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, + gamma_top = get_feature_edges(surface_over_tv_f, boundary_edges_on=True, feature_edges_on=False, + manifold_edges_on=False, non_manifold_edges_on=False) if debug: surface_over_tv_f = apply_vtk_geom_filter(gamma_top) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index c52f9bd..3beb445 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -36,6 +36,7 @@ from sklearn.cluster import KMeans from vtk.numpy_interface import dataset_adapter as dsa +from Atrial_LDRBM.Generate_Boundaries.extract_rings import get_region_not_including_ids from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx @@ -557,9 +558,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): ivc_points = vtk_to_numpy(ivc_points) connect = init_connectivity_filter(gamma_top_epi, ExtractionModes.SPECIFIED_REGIONS) - num = connect.GetNumberOfExtractedRegions() - for i in range(num): - connect.AddSpecifiedRegion(i) + num_regions = connect.GetNumberOfExtractedRegions() + for region_id in range(num_regions): + connect.AddSpecifiedRegion(region_id) connect.Update() surface = connect.GetOutput() # Clean unused points @@ -578,13 +579,13 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): if var in svc_points: in_svc = True if in_ivc and in_svc: - top_epi_id = i + top_epi_id = region_id break else: break # delete added region id - connect.DeleteSpecifiedRegion(i) + connect.DeleteSpecifiedRegion(region_id) connect.Update() connect.AddSpecifiedRegion(top_epi_id) @@ -597,9 +598,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): pts_in_top_epi = vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) connect = init_connectivity_filter(gamma_top_endo, ExtractionModes.SPECIFIED_REGIONS) - num = connect.GetNumberOfExtractedRegions() - for i in range(num): - connect.AddSpecifiedRegion(i) + num_regions = connect.GetNumberOfExtractedRegions() + for region_id in range(num_regions): + connect.AddSpecifiedRegion(region_id) connect.Update() surface = connect.GetOutput() # Clean unused points @@ -618,13 +619,13 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): if var in svc_points: in_svc = True if in_ivc and in_svc: - top_endo_id = i + top_endo_id = region_id break else: break # delete added region id - connect.DeleteSpecifiedRegion(i) + connect.DeleteSpecifiedRegion(region_id) connect.Update() connect.AddSpecifiedRegion(top_endo_id) @@ -656,9 +657,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # tree = cKDTree(pts_in_top_epi) - for i in range(len(pts_in_top_epi)): - if pts_in_top_epi[i] in pts_in_svc_epi or pts_in_top_epi[i] in pts_in_ivc_epi: - to_delete[i] = 1 + for region_id in range(len(pts_in_top_epi)): + if pts_in_top_epi[region_id] in pts_in_svc_epi or pts_in_top_epi[region_id] in pts_in_ivc_epi: + to_delete[region_id] = 1 meshNew = dsa.WrapDataObject(top_cut_epi) meshNew.PointData.append(to_delete, "delete") @@ -667,29 +668,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): thresh_geo = apply_vtk_geom_filter(thresh.GetOutputPort(), True) - connect = init_connectivity_filter(thresh_geo, ExtractionModes.SPECIFIED_REGIONS) - num = connect.GetNumberOfExtractedRegions() - - for i in range(num): - connect.AddSpecifiedRegion(i) - connect.Update() - surface = connect.GetOutput() - # Clean unused points - surface = clean_polydata(surface) - - pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - - if tv_id_epi not in pts_surf: - found_id = i - break - - # delete added region id - connect.DeleteSpecifiedRegion(i) - connect.Update() - - connect.AddSpecifiedRegion(found_id) - connect.Update() - surface = connect.GetOutput() + surface = get_region_not_including_ids(thresh_geo, tv_id_epi) # Clean unused points top_epi = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) @@ -697,9 +676,9 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): write_to_vtx(outdir + '/ids_TOP_EPI.vtx', top_epi) to_delete = np.zeros((len(pts_in_top_endo),), dtype=int) - for i in range(len(pts_in_top_endo)): - if pts_in_top_endo[i] in pts_in_svc_endo or pts_in_top_endo[i] in pts_in_ivc_endo: - to_delete[i] = 1 + for region_id in range(len(pts_in_top_endo)): + if pts_in_top_endo[region_id] in pts_in_svc_endo or pts_in_top_endo[region_id] in pts_in_ivc_endo: + to_delete[region_id] = 1 meshNew = dsa.WrapDataObject(top_cut_endo) meshNew.PointData.append(to_delete, "delete") @@ -710,29 +689,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): mv_id_endo = vtk_to_numpy(top_cut_endo.GetPointData().GetArray("Ids"))[0] - connect = init_connectivity_filter(thresh_geo, ExtractionModes.SPECIFIED_REGIONS) - num = connect.GetNumberOfExtractedRegions() - - for i in range(num): - connect.AddSpecifiedRegion(i) - connect.Update() - surface = connect.GetOutput() - # Clean unused points - surface = clean_polydata(surface) - - pts_surf = vtk_to_numpy(surface.GetPointData().GetArray("Ids")) - - if tv_id_endo not in pts_surf: - found_id = i - break - - # delete added region id - connect.DeleteSpecifiedRegion(i) - connect.Update() - - connect.AddSpecifiedRegion(found_id) - connect.Update() - surface = connect.GetOutput() + surface = get_region_not_including_ids(thresh_geo, tv_id_endo) # Clean unused points top_endo = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) From 4ae913f759f46c2df223d296a01d62a9cf507032 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Sun, 1 Dec 2024 19:37:53 +0100 Subject: [PATCH 54/70] Used methods from extract_rings for extract_rings_TOP_epi_endo.py --- .../extract_rings_TOP_epi_endo.py | 83 ++++--------------- 1 file changed, 18 insertions(+), 65 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 3beb445..9d6cdb8 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -36,15 +36,14 @@ from sklearn.cluster import KMeans from vtk.numpy_interface import dataset_adapter as dsa -from Atrial_LDRBM.Generate_Boundaries.extract_rings import get_region_not_including_ids -from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import get_normalized_cross_product +from Atrial_LDRBM.Generate_Boundaries.extract_rings import get_region_not_including_ids, is_top_endo_epi_cut, split_tv from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy, numpy_to_vtk from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_polydata_writer, write_to_vtx from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter, get_vtk_geom_filter_port, \ clean_polydata, generate_ids, get_center_of_mass, get_feature_edges, get_elements_above_plane from vtk_opencarp_helper_methods.vtk_methods.finder import find_closest_point -from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, initialize_plane, \ - init_connectivity_filter, ExtractionModes +from vtk_opencarp_helper_methods.vtk_methods.init_objects import initialize_plane_with_points, init_connectivity_filter, \ + ExtractionModes from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_lower_threshold, get_threshold_between @@ -487,7 +486,7 @@ def cutting_plane_to_identify_UAC(LPVs, RPVs, rings, LA, outdir): write_to_vtx(outdir + '/ids_RPV_LPV.vtx', rpv_lpv) -def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): +def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, out_dir): for r in rings: if r.name == "TV": tv_center = np.array(r.center) @@ -499,11 +498,11 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): ivc_center = np.array(r.center) ivc = r.vtk_polydata - plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) + tv_f_plane = initialize_plane_with_points(tv_center, svc_center, ivc_center, tv_center) surface = apply_vtk_geom_filter(model) - surface = apply_vtk_geom_filter(get_elements_above_plane(surface, plane)) + surface = apply_vtk_geom_filter(get_elements_above_plane(surface, tv_f_plane)) """ here we will extract the feature edge @@ -520,7 +519,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): surface = apply_vtk_geom_filter(endo) - surface = apply_vtk_geom_filter(get_elements_above_plane(surface, plane)) + surface = apply_vtk_geom_filter(get_elements_above_plane(surface, tv_f_plane)) """ here we will extract the feature edge @@ -529,27 +528,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): gamma_top_endo = get_feature_edges(surface, boundary_edges_on=True, feature_edges_on=False, manifold_edges_on=False, non_manifold_edges_on=False) - """ - separate the tv into tv tv-f and tv-f - """ - - norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) - norm_2 = - norm_1 - - plane = initialize_plane(norm_1[0], tv_center) - plane2 = initialize_plane(norm_2[0], tv_center) - - tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, plane)) - - tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) - - write_to_vtx(outdir + '/ids_TV_F.vtx', tv_f_ids) - - tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, plane2, extract_boundary_cells_on=True)) - - tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) - - write_to_vtx(outdir + '/ids_TV_S.vtx', tv_s_ids) + split_tv(out_dir, tv, tv_center, ivc_center, svc_center) svc_points = svc.GetPoints().GetData() svc_points = vtk_to_numpy(svc_points) @@ -566,23 +545,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # Clean unused points surface = clean_polydata(surface) points = surface.GetPoints().GetData() - points = vtk_to_numpy(points) - points = points.tolist() - - in_ivc = False - in_svc = False - # if there is point of group i in both svc and ivc then it is the "top_endo+epi" we need - while in_ivc == False and in_svc == False: - for var in points: - if var in ivc_points: - in_ivc = True - if var in svc_points: - in_svc = True - if in_ivc and in_svc: - top_epi_id = region_id - break - else: - break + points = vtk_to_numpy(points).tolist() + + if is_top_endo_epi_cut(ivc_points, svc_points, points): + top_epi_id = region_id # delete added region id connect.DeleteSpecifiedRegion(region_id) @@ -606,23 +572,10 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # Clean unused points surface = clean_polydata(surface) points = surface.GetPoints().GetData() - points = vtk_to_numpy(points) - points = points.tolist() - - in_ivc = False - in_svc = False - # if there is point of group i in both svc and ivc then it is the "top_endo+epi" we need - while in_ivc == False and in_svc == False: - for var in points: - if var in ivc_points: - in_ivc = True - if var in svc_points: - in_svc = True - if in_ivc and in_svc: - top_endo_id = region_id - break - else: - break + points = vtk_to_numpy(points).tolist() + + if is_top_endo_epi_cut(ivc_points, svc_points, points): + top_endo_id = region_id # delete added region id connect.DeleteSpecifiedRegion(region_id) @@ -673,7 +626,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # Clean unused points top_epi = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) - write_to_vtx(outdir + '/ids_TOP_EPI.vtx', top_epi) + write_to_vtx(out_dir + '/ids_TOP_EPI.vtx', top_epi) to_delete = np.zeros((len(pts_in_top_endo),), dtype=int) for region_id in range(len(pts_in_top_endo)): @@ -694,7 +647,7 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, outdir): # Clean unused points top_endo = vtk_to_numpy(clean_polydata(surface).GetPointData().GetArray("Ids")) - write_to_vtx(outdir + '/ids_TOP_ENDO.vtx', top_endo) + write_to_vtx(out_dir + '/ids_TOP_ENDO.vtx', top_endo) if __name__ == '__main__': From ba30987539671f46e3247adf41b354c6b76e0524 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Sun, 1 Dec 2024 19:44:21 +0100 Subject: [PATCH 55/70] Further method extraction in extract_rings_TOP_epi_endo.py --- .../extract_rings_TOP_epi_endo.py | 68 +++++++------------ 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py index 9d6cdb8..d161bd2 100644 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings_TOP_epi_endo.py @@ -536,54 +536,14 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, out_dir): ivc_points = ivc.GetPoints().GetData() ivc_points = vtk_to_numpy(ivc_points) - connect = init_connectivity_filter(gamma_top_epi, ExtractionModes.SPECIFIED_REGIONS) - num_regions = connect.GetNumberOfExtractedRegions() - for region_id in range(num_regions): - connect.AddSpecifiedRegion(region_id) - connect.Update() - surface = connect.GetOutput() - # Clean unused points - surface = clean_polydata(surface) - points = surface.GetPoints().GetData() - points = vtk_to_numpy(points).tolist() - - if is_top_endo_epi_cut(ivc_points, svc_points, points): - top_epi_id = region_id - - # delete added region id - connect.DeleteSpecifiedRegion(region_id) - connect.Update() - - connect.AddSpecifiedRegion(top_epi_id) - connect.Update() - surface = connect.GetOutput() + surface = get_top_endo_epi_cut(gamma_top_epi, ivc_points, svc_points) # Clean unused points top_cut_epi = clean_polydata(surface) pts_in_top_epi = vtk_to_numpy(top_cut_epi.GetPointData().GetArray("Ids")) - connect = init_connectivity_filter(gamma_top_endo, ExtractionModes.SPECIFIED_REGIONS) - num_regions = connect.GetNumberOfExtractedRegions() - for region_id in range(num_regions): - connect.AddSpecifiedRegion(region_id) - connect.Update() - surface = connect.GetOutput() - # Clean unused points - surface = clean_polydata(surface) - points = surface.GetPoints().GetData() - points = vtk_to_numpy(points).tolist() - - if is_top_endo_epi_cut(ivc_points, svc_points, points): - top_endo_id = region_id - - # delete added region id - connect.DeleteSpecifiedRegion(region_id) - connect.Update() - - connect.AddSpecifiedRegion(top_endo_id) - connect.Update() - surface = connect.GetOutput() + surface = get_top_endo_epi_cut(gamma_top_endo, ivc_points, svc_points) # Clean unused points top_cut_endo = clean_polydata(surface) @@ -650,5 +610,29 @@ def cutting_plane_to_identify_tv_f_tv_s_epi_endo(mesh, model, rings, out_dir): write_to_vtx(out_dir + '/ids_TOP_ENDO.vtx', top_endo) +def get_top_endo_epi_cut(gamma_top, ivc_points, svc_points): + connect = init_connectivity_filter(gamma_top, ExtractionModes.SPECIFIED_REGIONS) + num_regions = connect.GetNumberOfExtractedRegions() + for region_id in range(num_regions): + connect.AddSpecifiedRegion(region_id) + connect.Update() + surface = connect.GetOutput() + # Clean unused points + surface = clean_polydata(surface) + points = surface.GetPoints().GetData() + points = vtk_to_numpy(points).tolist() + + if is_top_endo_epi_cut(ivc_points, svc_points, points): + top_id = region_id + + # delete added region id + connect.DeleteSpecifiedRegion(region_id) + connect.Update() + connect.AddSpecifiedRegion(top_id) + connect.Update() + surface = connect.GetOutput() + return surface + + if __name__ == '__main__': run() From f7cb0af70a9002c5e16f939b7600d0015d001cb3 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 09:19:31 +0100 Subject: [PATCH 56/70] Fixed stupid bug introduced at refactoring --- .../LDRBM/Fiber_RA/ra_generate_fiber.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py index d510531..7fbdc09 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_generate_fiber.py @@ -37,10 +37,10 @@ import Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA as Method from Atrial_LDRBM.LDRBM.Fiber_LA.Methods_LA import clean_all_data -from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors from Atrial_LDRBM.LDRBM.Fiber_LA.la_generate_fiber import calculate_en from Atrial_LDRBM.LDRBM.Fiber_RA.Methods_RA import downsample_path from vtk_opencarp_helper_methods.AugmentA_methods.vtk_operations import vtk_thr, extract_largest_region +from vtk_opencarp_helper_methods.mathematical_operations.vector_operations import normalize_vectors from vtk_opencarp_helper_methods.vtk_methods.converters import vtk_to_numpy from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_unstructured_grid_writer, \ vtk_xml_unstructured_grid_writer @@ -244,6 +244,7 @@ def ra_generate_fiber(model, args, job): CT_band = vtk_thr(RAW_s, 2, "CELLS", "phie_w", 0.1, tao_ct_plus) # grad_w CT_band = extract_largest_region(CT_band) + CT_ub = vtk_thr(RAW_s, 2, "CELLS", "phie_w", tao_ct_plus - 0.02, tao_ct_plus) # grad_w CT_ub = extract_largest_region(CT_ub) @@ -504,6 +505,8 @@ def ra_generate_fiber(model, args, job): CT = vtk_thr(model, 2, "CELLS", "elemTag", crista_terminalis, crista_terminalis) + CT = extract_largest_region(CT) # clean so path can be found + CT_ids = vtk_to_numpy(CT.GetCellData().GetArray('Global_ids')) elif args.mesh_type == "vol": @@ -536,8 +539,8 @@ def ra_generate_fiber(model, args, job): point2_id = find_closest_point(CT, SVC_CT_pt) point3_id = find_closest_point(TV_s, IVC_max_r_CT_pt) - point4_id = find_closest_point(TV_s, - np.array(df["RAA"])) # this is also the id for Bachmann-Bundle on the right atrium + RAA_on_tv_s = find_closest_point(TV_s, + np.array(df["RAA"])) # this is also the id for Bachmann-Bundle on the right atrium CT = apply_vtk_geom_filter(CT) @@ -550,7 +553,7 @@ def ra_generate_fiber(model, args, job): n = np.linalg.norm(norm) norm_1 = norm / n - initialize_plane(norm_1, df["TV"]) + plane = initialize_plane(norm_1, df["TV"]) TV_lat = get_elements_above_plane(TV_s, plane) @@ -569,9 +572,9 @@ def ra_generate_fiber(model, args, job): point3_id = find_closest_point(TV_lat, TV_s.GetPoint(point3_id)) # this is also the id for Bachmann-Bundle on the right atrium - point4_id = find_closest_point(TV_lat, TV_s.GetPoint(point4_id)) + RAA_on_tv_lat = find_closest_point(TV_lat, TV_s.GetPoint(RAA_on_tv_s)) - tv_points_data = Method.dijkstra_path(TV_lat, point3_id, point4_id) + tv_points_data = Method.dijkstra_path(TV_lat, point3_id, RAA_on_tv_lat) if args.debug: Method.create_pts(tv_points_data, 'tv_points_data', f'{args.mesh}_surf/') @@ -642,7 +645,7 @@ def ra_generate_fiber(model, args, job): tree = cKDTree(centroids_array) - ii = tree.query_ball_point(pm, r=w_pm, n_jobs=-1) + ii = tree.query_ball_point(pm, r=w_pm, workers=-1) ii = list(set([item for sublist in ii for item in sublist])) @@ -781,7 +784,7 @@ def ra_generate_fiber(model, args, job): # Bachmann-Bundle starting point bb_1_id = find_closest_point(surface, SVC_CT_pt) - bb_2_id = find_closest_point(surface, TV_lat.GetPoint(point4_id)) + bb_2_id = find_closest_point(surface, TV_lat.GetPoint(RAA_on_tv_lat)) bb_c_id = find_closest_point(surface, RAS_S.GetPoint(bb_c_id)) bachmann_bundle_points_data_1 = Method.dijkstra_path(surface, bb_1_id, bb_c_id) From 8364be1b5f3c469f58f8f2f46fe6a437c1042caf Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 09:32:42 +0100 Subject: [PATCH 57/70] Updated pymeshlab methods to newer version --- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index a3dbb45..27b0d24 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -59,15 +59,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): bridge_radius = 1.65 * args.scale - bachmann_bundel_left = int(tag_dict['bachmann_bundel_left']) - bachmann_bundel_right = int(tag_dict['bachmann_bundel_right']) bachmann_bundel_internal = int(tag_dict['bachmann_bundel_internal']) middle_posterior_bridge_left = int(tag_dict['middle_posterior_bridge_left']) - middle_posterior_bridge_right = int(tag_dict['middle_posterior_bridge_right']) upper_posterior_bridge_left = int(tag_dict['upper_posterior_bridge_left']) - upper_posterior_bridge_right = int(tag_dict['upper_posterior_bridge_right']) coronary_sinus_bridge_left = int(tag_dict['coronary_sinus_bridge_left']) - coronary_sinus_bridge_right = int(tag_dict['coronary_sinus_bridge_right']) right_atrial_septum_epi = int(tag_dict['right_atrial_septum_epi']) left_atrial_wall_epi = int(tag_dict["left_atrial_wall_epi"]) mitral_valve_epi = int(tag_dict["mitral_valve_epi"]) @@ -164,7 +159,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # add the mesh to the MeshSet ms.add_mesh(m, "bridge_mesh") # apply filter - ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=0.4 * args.scale, adaptive=True) + ms.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(0.4 * args.scale), adaptive=True) ms.save_current_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj", \ save_vertex_color=False, save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) @@ -324,7 +319,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): # if args.just_bridges and var == 'BB_intern_bridges': # job.ID='../'+job.ID# Change if you enter from ra_main and not from pipeline.py, otherwise comment the line ms.load_new_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj") - ms.remeshing_isotropic_explicit_remeshing(iterations=5, targetlen=0.4 * args.scale, adaptive=True) + ms.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(0.4 * args.scale), adaptive=True) ms.save_current_mesh(job.ID + "/bridges/" + str(var) + "_union.obj", save_vertex_color=False, save_vertex_normal=False, save_face_color=False, save_wedge_texcoord=False, save_wedge_normal=False) @@ -455,7 +450,7 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): vtk_xml_unstructured_grid_writer(job.ID + "/result_RA/la_ra_endo.vtu", endo) # Has elemTag! :, bilayer = Method.generate_bilayer(args, job, endo, epi, 0.12 * args.scale) # Does not have elemTag :(! - Method.write_bilayer(args, job) + Method.write_bilayer(bilayer, args, job) else: From c978780ec885d179c78b8d62a1fb05c79ccd52f5 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 09:33:43 +0100 Subject: [PATCH 58/70] Fixed minor bugs --- .../Generate_Boundaries/extract_rings.py | 18 ++++++++++-------- Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py | 6 +++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 49a8f56..608346f 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -136,9 +136,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i RA_tag = id_vec[int(RAA_id)] warning("WARNING: Should be checkt for functionality extract_rings l151") - thr = get_threshold_between(mesh_conn, LA_tag, LA_tag, "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") + la_threshold_filter = get_threshold_between(mesh_conn, LA_tag, LA_tag, + "vtkDataObject::FIELD_ASSOCIATION_POINTS", "RegionID") - mesh_poly = apply_vtk_geom_filter(thr.GetOutputPort(), True) + mesh_poly = apply_vtk_geom_filter(la_threshold_filter.GetOutputPort(), True) LA = generate_ids(mesh_poly, "Ids", "Ids") @@ -158,9 +159,10 @@ def label_atrial_orifices(mesh, LAA_id="", RAA_id="", LAA_base_id="", RAA_base_i vtk_write(dataSet.VTKObject, outdir + '/LA_boundaries_tagged.vtk'.format(mesh)) - thr.ThresholdBetween(RA_tag, RA_tag) - thr.Update() - RA_poly = apply_vtk_geom_filter(thr.GetOutputPort(), True) + ra_threshold_filter = get_threshold_between(mesh_conn, RA_tag, RA_tag, + "vtkDataObject::FIELD_ASSOCIATION_POINTS", + "RegionID") + RA_poly = apply_vtk_geom_filter(ra_threshold_filter.GetOutputPort(), True) RA = generate_ids(RA_poly, "Ids", "Ids") @@ -634,7 +636,7 @@ def extract_top_cut(outdir, surface_over_tv_f, ivc_points, svc_points, debug): connect.DeleteSpecifiedRegion(region_id) connect.Update() # It can happen that the first i=region(0) is the CS. Remove the -1 if that is the case - connect.AddSpecifiedRegion(top_endo_id - 1) # Find the id in the points dividing the RA, avoid CS + connect.AddSpecifiedRegion(top_endo_id) # Find the id in the points dividing the RA, avoid CS connect.Update() surface_over_tv_f = connect.GetOutput() # Clean unused points @@ -653,13 +655,13 @@ def split_tv(out_dir, tv, tv_center, ivc_center, svc_center): :return: """ norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) - tv_f_plane = initialize_plane(norm_1[0], tv_center) + tv_f_plane = initialize_plane(norm_1, tv_center) tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, tv_f_plane)) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) write_to_vtx(out_dir + '/ids_TV_F.vtx', tv_f_ids) norm_2 = - norm_1 - tv_s_plane = initialize_plane(norm_2[0], tv_center) + tv_s_plane = initialize_plane(norm_2, tv_center) tv_s = apply_vtk_geom_filter(get_elements_above_plane(tv, tv_s_plane, extract_boundary_cells_on=True)) tv_s_ids = vtk_to_numpy(tv_s.GetPointData().GetArray("Ids")) write_to_vtx(out_dir + '/ids_TV_S.vtx', tv_s_ids) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py index b93acf4..d9c99a8 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/Methods_RA.py @@ -169,12 +169,12 @@ def write_bilayer(bilayer, args, job): write_to_pts(f'{file_name}.pts', pts) - tag_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) + tag_epi = vtk_to_numpy(bilayer.GetCellData().GetArray('elemTag')) write_to_elem(f'{file_name}.elem', bilayer, tag_epi) - el_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) - sheet_epi = vtk.util.vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) + el_epi = vtk_to_numpy(bilayer.GetCellData().GetArray('fiber')) + sheet_epi = vtk_to_numpy(bilayer.GetCellData().GetArray('sheet')) write_to_lon(f'{file_name}.lon', el_epi, sheet_epi) From 5ae58883db9a72b23325b8639ea581901aee03ba Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 09:35:14 +0100 Subject: [PATCH 59/70] Added additional remeshing step so the laplace generation is more robust --- standalones/resample_surf_mesh.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index 3b3f7bb..bd814af 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -151,7 +151,7 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv # get the average edge length from the dictionary avg_edge_length = out_dict['avg_edge_length'] - tgt_edge_length = target_mesh_resolution * scale + tgt_edge_length = (target_mesh_resolution * scale)+0.1 loc_tgt_edge_length = target_mesh_resolution * scale it = 1 @@ -176,6 +176,27 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv break it += 1 + tgt_edge_length = tgt_edge_length - 0.1 + print("Current resolution: {} mm".format(avg_edge_length / scale)) + print("Target resolution: {} mm".format(tgt_edge_length / scale)) + while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: + ms.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(loc_tgt_edge_length)) + if it == 1: + ms.apply_coord_laplacian_smoothing() + out_dict = ms.get_geometric_measures() + + avg_edge_length = out_dict['avg_edge_length'] + print("Current resolution: {} mm".format(avg_edge_length / scale)) + if avg_edge_length > tgt_edge_length * 1.05: + loc_tgt_edge_length = tgt_edge_length * 0.95 + print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) + elif avg_edge_length < tgt_edge_length * 0.95: + loc_tgt_edge_length = tgt_edge_length * 1.05 + print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) + else: + break + it += 1 + mesh_data["avg_edge_length"] = [out_dict['avg_edge_length']] mesh_data["surf"] = [out_dict['surface_area']] From cf86fc4aa80f51f5c075fb3644a43d4a7fe2a77f Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 10:52:06 +0100 Subject: [PATCH 60/70] Cross product was inverted in split_tv for extract rings --- Atrial_LDRBM/Generate_Boundaries/extract_rings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py index 608346f..31faaa7 100755 --- a/Atrial_LDRBM/Generate_Boundaries/extract_rings.py +++ b/Atrial_LDRBM/Generate_Boundaries/extract_rings.py @@ -654,7 +654,7 @@ def split_tv(out_dir, tv, tv_center, ivc_center, svc_center): :param svc_center: Center of the svc :return: """ - norm_1 = get_normalized_cross_product(tv_center, svc_center, ivc_center) + norm_1 = -get_normalized_cross_product(tv_center, svc_center, ivc_center) tv_f_plane = initialize_plane(norm_1, tv_center) tv_f = apply_vtk_geom_filter(get_elements_above_plane(tv, tv_f_plane)) tv_f_ids = vtk_to_numpy(tv_f.GetPointData().GetArray("Ids")) From ce05bbb8dbc23efad46b32bc7a92f7df4a34ce64 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 11:34:26 +0100 Subject: [PATCH 61/70] Switched to union operation for connecting earth and bridges --- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 27b0d24..413ac54 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -304,15 +304,10 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): mesh_D = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj") mesh_E = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_earth.obj") # # Warning: set -1 if pts normals are pointing outside - # # Use union if the endo normals are pointing outside - # output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - if args.mesh_type == "bilayer": + output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") # Use difference if the endo normals are pointing inside - output_mesh_2 = pymesh.boolean(mesh_E, mesh_D, operation="difference", engine="corefinement") - pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) - else: - output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) + # output_mesh_2 = pymesh.boolean(mesh_E, mesh_D, operation="difference", engine="corefinement") + pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) print("Union between earth and bridges in " + var) ms = pymeshlab.MeshSet() From 4ab441aa6f509220235d2d1b0a14a43a738aa07a Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 16:36:41 +0100 Subject: [PATCH 62/70] Changed bridge merging to difference --- Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py index 413ac54..bdba5b8 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/create_bridges.py @@ -304,9 +304,9 @@ def add_free_bridge(args, la_epi, ra_epi, CS_p, df, job): mesh_D = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_bridge_resampled.obj") mesh_E = pymesh.load_mesh(job.ID + "/bridges/" + str(var) + "_earth.obj") # # Warning: set -1 if pts normals are pointing outside - output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") - # Use difference if the endo normals are pointing inside - # output_mesh_2 = pymesh.boolean(mesh_E, mesh_D, operation="difference", engine="corefinement") + #output_mesh_2 = pymesh.boolean(mesh_D, mesh_E, operation="union", engine="corefinement") + # Use difference if the endo normals are pointing inside + output_mesh_2 = pymesh.boolean(mesh_E, mesh_D, operation="difference", engine="corefinement") pymesh.save_mesh(job.ID + "/bridges/" + str(var) + "_union_to_resample.obj", output_mesh_2, ascii=True) print("Union between earth and bridges in " + var) From fe8c7fbbf9ed2fa9d9946fb8feed01238fe9d2ee Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 16:37:02 +0100 Subject: [PATCH 63/70] Added automatic detection of normal orientation --- main.py | 2 +- pipeline.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 5e77a6d..5444162 100644 --- a/main.py +++ b/main.py @@ -89,7 +89,7 @@ def parser(): help='target mesh resolution in mm') parser.add_argument('--normals_outside', type=int, - default=1, + default=-1, help='set to 1 if surface normals are pointing outside, 0 otherwise') parser.add_argument('--add_bridges', type=int, diff --git a/pipeline.py b/pipeline.py index 2b14329..eae9db4 100644 --- a/pipeline.py +++ b/pipeline.py @@ -28,6 +28,7 @@ from Atrial_LDRBM.LDRBM.Fiber_RA import ra_main from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point, pick_point_with_preselection from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.normal_orientation import are_normals_outside from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader EXAMPLE_DESCRIPTIVE_NAME = 'AugmentA: Patient-specific Augmented Atrial model Generation Tool' @@ -71,6 +72,10 @@ def AugmentA(args): extension = args.mesh.split('.')[-1] meshname = args.mesh[:-(len(extension) + 1)] + if args.normals_outside < 0: + # value not set + args.normals_outside = int(are_normals_outside(smart_reader(args.mesh))) + if args.closed_surface: separate_epi_endo(args.mesh, args.atrium) meshname_old = str(meshname) From 942257a91a6b1d36616448aaeb5b9d6b7e1847f4 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 16:37:25 +0100 Subject: [PATCH 64/70] Fixed bug where store to xml got lost while refactoring --- Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py index e779089..b75a2bc 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py +++ b/Atrial_LDRBM/LDRBM/Fiber_RA/ra_laplace.py @@ -164,7 +164,7 @@ def ra_laplace(args, job, model): if args.mesh_type == "vol": vtk_xml_unstructured_grid_writer(simid + "/RA_with_laplace.vtu", meshNew.VTKObject) else: - vtk_polydata_writer(simid + "/RA_with_laplace.vtp", meshNew.VTKObject) + vtk_polydata_writer(simid + "/RA_with_laplace.vtp", meshNew.VTKObject, store_xml=True) """ calculate the gradient From fad158f861d28ded6b973b6cd809d56ef6476cb0 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Tue, 3 Dec 2024 17:10:59 +0100 Subject: [PATCH 65/70] Extracted core resampling algorithm into separate method --- standalones/resample_surf_mesh.py | 86 +++++++++++++++---------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/standalones/resample_surf_mesh.py b/standalones/resample_surf_mesh.py index bd814af..884eee8 100644 --- a/standalones/resample_surf_mesh.py +++ b/standalones/resample_surf_mesh.py @@ -148,54 +148,13 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv # and save the results in the out_dict dictionary out_dict = ms.get_geometric_measures() - # get the average edge length from the dictionary - avg_edge_length = out_dict['avg_edge_length'] - - tgt_edge_length = (target_mesh_resolution * scale)+0.1 - - loc_tgt_edge_length = target_mesh_resolution * scale - it = 1 - print(f"Current resolution: {avg_edge_length / scale} mm") - print(f"Target resolution: {tgt_edge_length / scale} mm") - while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: - - ms.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(loc_tgt_edge_length)) - if it == 1: - ms.apply_coord_laplacian_smoothing() - out_dict = ms.get_geometric_measures() + tgt_edge_length = (target_mesh_resolution * scale) + 0.1 - avg_edge_length = out_dict['avg_edge_length'] - print(f"Current resolution: {avg_edge_length / scale} mm") - if avg_edge_length > tgt_edge_length * 1.05: - loc_tgt_edge_length = tgt_edge_length * 0.95 - print(f"New target resolution: {loc_tgt_edge_length / scale} mm") - elif avg_edge_length < tgt_edge_length * 0.95: - loc_tgt_edge_length = tgt_edge_length * 1.05 - print(f"New target resolution: {loc_tgt_edge_length / scale} mm") - else: - break - it += 1 + out_dict = resample_mesh_set(ms, out_dict, scale, target_mesh_resolution, tgt_edge_length) + #second run of resampling to be smoother for laplacian generation tgt_edge_length = tgt_edge_length - 0.1 - print("Current resolution: {} mm".format(avg_edge_length / scale)) - print("Target resolution: {} mm".format(tgt_edge_length / scale)) - while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: - ms.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(loc_tgt_edge_length)) - if it == 1: - ms.apply_coord_laplacian_smoothing() - out_dict = ms.get_geometric_measures() - - avg_edge_length = out_dict['avg_edge_length'] - print("Current resolution: {} mm".format(avg_edge_length / scale)) - if avg_edge_length > tgt_edge_length * 1.05: - loc_tgt_edge_length = tgt_edge_length * 0.95 - print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) - elif avg_edge_length < tgt_edge_length * 0.95: - loc_tgt_edge_length = tgt_edge_length * 1.05 - print("New target resolution: {} mm".format(loc_tgt_edge_length / scale)) - else: - break - it += 1 + out_dict = resample_mesh_set(ms, out_dict, scale, target_mesh_resolution, tgt_edge_length) mesh_data["avg_edge_length"] = [out_dict['avg_edge_length']] mesh_data["surf"] = [out_dict['surface_area']] @@ -259,6 +218,43 @@ def resample_surf_mesh(meshname, target_mesh_resolution=0.4, find_apex_with_curv df.to_csv(fname, float_format="%.2f", index=False) + +def resample_mesh_set(mesh_set, out_dict, scale, target_mesh_resolution, tgt_edge_length): + """ + Resample mesh based on the target mesh resolution + :param mesh_set: + :param out_dict: Dictonary which stores the avg_edge_length + :param scale: Scale of the mesh + :param target_mesh_resolution: + :param tgt_edge_length: + :return: + """ + avg_edge_length = out_dict['avg_edge_length'] + loc_tgt_edge_length = target_mesh_resolution * scale + it = 1 + print(f"Current resolution: {avg_edge_length / scale} mm") + print(f"Target resolution: {tgt_edge_length / scale} mm") + while avg_edge_length > tgt_edge_length * 1.05 or avg_edge_length < tgt_edge_length * 0.95 or it < 3: + + mesh_set.meshing_isotropic_explicit_remeshing(iterations=5, targetlen=pymeshlab.PureValue(loc_tgt_edge_length)) + if it == 1: + mesh_set.apply_coord_laplacian_smoothing() + out_dict = mesh_set.get_geometric_measures() + + avg_edge_length = out_dict['avg_edge_length'] + print(f"Current resolution: {avg_edge_length / scale} mm") + if avg_edge_length > tgt_edge_length * 1.05: + loc_tgt_edge_length = tgt_edge_length * 0.95 + print(f"New target resolution: {loc_tgt_edge_length / scale} mm") + elif avg_edge_length < tgt_edge_length * 0.95: + loc_tgt_edge_length = tgt_edge_length * 1.05 + print(f"New target resolution: {loc_tgt_edge_length / scale} mm") + else: + break + it += 1 + return out_dict + + def run(): args = parser().parse_args() resample_surf_mesh(args.mesh, args.target_mesh_resolution, args.find_apex_with_curv, args.scale, args.size) From c6498958a253eda3c2184c9c96d60cdde2b504c9 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 5 Dec 2024 10:44:41 +0100 Subject: [PATCH 66/70] Modified optimization of PV so it does not crash for volumetric meshes with short PVs --- Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py | 37 ++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py index 75f1724..e836878 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/Methods_LA.py @@ -886,6 +886,14 @@ def distinguish_PVs(connect, PVs, df, name1, name2): def optimize_shape_PV(surface, num, bound): + """ + optimizes a PV ring by checking for the difference between centers of equidistant spaced slices of the ring. + This slicing is based on phie_v. + :param surface: + :param num: Number of slices + :param bound: 0 for positive phie_v 1 for negative phie_v + :return: + """ if bound == 0: phie_v = np.max(vtk_to_numpy(surface.GetCellData().GetArray('phie_v'))) else: @@ -894,26 +902,47 @@ def optimize_shape_PV(surface, num, bound): arr = np.linspace(bound, phie_v, num) c_mass_l = [] + is_complete_ring_list = [] found = 0 for l in range(num - 1): if bound == 0: out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l], arr[l + 1]) else: out = vtk_thr(surface, 2, "CELLS", "phie_v", arr[l + 1], arr[l]) - + is_complete_ring_list.append(check_for_ring_completeness(out)) center = get_center_of_mass(apply_vtk_geom_filter(out), False) c_mass_l.append(center) - v1 = np.array(c_mass_l[0]) - np.array(c_mass_l[1]) - for l in range(1, num - 2): + non_zero_indices = np.nonzero(is_complete_ring_list)[0] + first_valid_ring_index = num if len(non_zero_indices) < 1 else non_zero_indices[0] + if first_valid_ring_index > num - 3: + # no optimization needed + return 0, 0 + + v1 = np.array(c_mass_l[first_valid_ring_index]) - np.array(c_mass_l[first_valid_ring_index + 1]) + for l in range(first_valid_ring_index, num - 2): v2 = np.array(c_mass_l[l]) - np.array(c_mass_l[l + 1]) - if 1 - cosine(v1, v2) < 0: + if 1 - cosine(v1, v2) < 0 and is_complete_ring_list[l]: found = 1 break return found, arr[l - 1] +def check_for_ring_completeness(ring_mesh, min_points=50, max_regions=2): + """ + Check if the given input is a valid ring. + Should split in maximum 2 regions and have more than 50 + :param max_regions: Maximum number of individual regions the rings is allowed to have + :param min_points: Minimum number of points the ring has to have + :param ring_mesh: A vtk mesh containing the ring + :return: True if the ring fits the defined parameters + """ + connect_region = init_connectivity_filter(ring_mesh, ExtractionModes.ALL_REGIONS) + num_con_reg = connect_region.GetNumberOfExtractedRegions() + return 1 if (num_con_reg <= max_regions) and ring_mesh.GetNumberOfPoints() > min_points else 0 + + def generate_spline_points(input_points): spline_points = vtk.vtkPoints() for i in range(len(input_points)): From 96cd6a09f7490214c64efe0d4883d362f8af3f62 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 5 Dec 2024 10:47:13 +0100 Subject: [PATCH 67/70] Added additional steps to make volumetric meshes work. Mainly mapping ids created on the endo part to the volumetric mesh and some minor bug fixes with filenames --- .../Generate_Boundaries/generate_surf_id.py | 5 +++-- .../Generate_Boundaries/separate_epi_endo.py | 5 ++++- Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py | 10 +++++----- pipeline.py | 13 +++++++++++-- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py index e898577..4bde676 100644 --- a/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py +++ b/Atrial_LDRBM/Generate_Boundaries/generate_surf_id.py @@ -43,7 +43,7 @@ def write_surf_ids(outdir, name, ii): write_to_vtx(outdir + f'/ids_{name}.vtx', ii) -def generate_surf_id(meshname, atrium): +def generate_surf_id(meshname, atrium, resampled=False): """The whole model""" vol = smart_reader(meshname + f"_{atrium}_vol.vtk") @@ -61,7 +61,8 @@ def generate_surf_id(meshname, atrium): os.makedirs(outdir) shutil.copyfile(meshname + f"_{atrium}_vol.vtk", outdir + f'/{atrium}.vtk') - shutil.copyfile(meshname + f"_{atrium}_epi_surf/rings_centroids.csv", outdir + '/rings_centroids.csv') + resampled = "_res" if resampled else "" + shutil.copyfile(meshname + f"_{atrium}_epi{resampled}_surf/rings_centroids.csv", outdir + '/rings_centroids.csv') write_surf_ids(outdir, "EPI", ii) diff --git a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py index 37fb6e6..e91b836 100644 --- a/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py +++ b/Atrial_LDRBM/Generate_Boundaries/separate_epi_endo.py @@ -1,7 +1,7 @@ import csv import sys -from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer +from vtk_opencarp_helper_methods.vtk_methods.exporting import vtk_obj_writer, vtk_polydata_writer from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter from vtk_opencarp_helper_methods.vtk_methods.thresholding import get_threshold_between @@ -37,6 +37,7 @@ def separate_epi_endo(path, atrium): raise ValueError("Atrium has to be LA or RA") vtk_obj_writer(meshname + f"_{atrium}.obj", apply_vtk_geom_filter(thresh.GetOutput())) + vtk_polydata_writer(meshname + f"_{atrium}.vtk", apply_vtk_geom_filter(thresh.GetOutput())) if atrium == "LA": thresh = get_threshold_between(model, left_atrial_wall_epi, left_atrial_wall_epi, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") @@ -49,6 +50,7 @@ def separate_epi_endo(path, atrium): la_epi = apply_vtk_geom_filter(thresh.GetOutput()) vtk_obj_writer(meshname + f"_{atrium}_epi.obj", la_epi) + vtk_polydata_writer(meshname + f"_{atrium}_epi.vtk", la_epi) if atrium == "LA": thresh = get_threshold_between(model, left_atrial_wall_endo, left_atrial_wall_endo, "vtkDataObject::FIELD_ASSOCIATION_CELLS", "tag") @@ -61,3 +63,4 @@ def separate_epi_endo(path, atrium): la_endo = apply_vtk_geom_filter(thresh.GetOutput()) vtk_obj_writer(meshname + f"_{atrium}_endo.obj", la_endo) + vtk_polydata_writer(meshname + f"_{atrium}_endo.vtk", la_endo) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 3cb3c17..496fbbb 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -100,9 +100,9 @@ def la_generate_fiber(model, args, job): tao_lpv = Method.find_tau(model, ub, lb, "low", "phie_v") print('Calculating tao_lpv done! tap_lpv = ', tao_lpv) - thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) + thr_phi_v = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) - connect = init_connectivity_filter(thr, ExtractionModes.ALL_REGIONS) + connect = init_connectivity_filter(thr_phi_v, ExtractionModes.ALL_REGIONS) PVs = dict() # Distinguish between LIPV and LSPV @@ -110,12 +110,12 @@ def la_generate_fiber(model, args, job): model = laplace_0_1(args, job, model, "RPV", "LAA", "phie_ab2") - thr = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) + thr_lpv = vtk_thr(model, 1, "CELLS", "phie_v", tao_lpv) - phie_r2_tau_lpv = vtk_to_numpy(thr.GetCellData().GetArray('phie_r2')) + phie_r2_tau_lpv = vtk_to_numpy(thr_lpv.GetCellData().GetArray('phie_r2')) max_phie_r2_tau_lpv = np.max(phie_r2_tau_lpv) - phie_ab_tau_lpv = vtk_to_numpy(thr.GetPointData().GetArray('phie_ab2')) + phie_ab_tau_lpv = vtk_to_numpy(thr_lpv.GetPointData().GetArray('phie_ab2')) max_phie_ab_tau_lpv = np.max(phie_ab_tau_lpv) print("max_phie_r2_tau_lpv ", max_phie_r2_tau_lpv) diff --git a/pipeline.py b/pipeline.py index eae9db4..0ba1f21 100644 --- a/pipeline.py +++ b/pipeline.py @@ -24,10 +24,12 @@ specific language governing permissions and limitations under the License. """ + from Atrial_LDRBM.LDRBM.Fiber_LA import la_main from Atrial_LDRBM.LDRBM.Fiber_RA import ra_main from vtk_opencarp_helper_methods.AugmentA_methods.point_selection import pick_point, pick_point_with_preselection from vtk_opencarp_helper_methods.vtk_methods.filters import apply_vtk_geom_filter +from vtk_opencarp_helper_methods.vtk_methods.mapper import mapp_ids_for_folder from vtk_opencarp_helper_methods.vtk_methods.normal_orientation import are_normals_outside from vtk_opencarp_helper_methods.vtk_methods.reader import smart_reader @@ -219,7 +221,9 @@ def AugmentA(args): meshin = pv.read(f'{processed_mesh}.ply') pv.save_meshio(f'{processed_mesh}.obj', meshin, "obj") - elif not args.resample_input and not args.find_appendage: # do not resample and do not find appendage + + + else: # do not resample and do not find appendage processed_mesh = meshname # Provide mesh with _res in the name @@ -253,8 +257,13 @@ def AugmentA(args): # Atrial region annotation and fiber generation using LDRBM if args.closed_surface: generate_mesh(meshname_old + f'_{args.atrium}') - generate_surf_id(meshname_old, args.atrium) + generate_surf_id(meshname_old, args.atrium, args.resample_input) processed_mesh = meshname_old + f"_{args.atrium}_vol" + resampled = "_res" if args.resample_input else "" + old_folder = meshname + resampled + "_surf" + origin_mesh = smart_reader(old_folder + "/LA.vtk") + volumetric_mesh = smart_reader(processed_mesh + "_surf/LA.vtk") + mapp_ids_for_folder(old_folder, processed_mesh + "_surf", origin_mesh, volumetric_mesh) la_main.run( ["--mesh", processed_mesh, "--np", str(n_cpu), "--normals_outside", str(0), "--mesh_type", "vol", "--ofmt", args.ofmt, "--debug", str(args.debug), "--overwrite-behaviour", "append"]) From 6d378772d3245fb191c3bee67b597d3a472d2350 Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 5 Dec 2024 13:17:37 +0100 Subject: [PATCH 68/70] Fixed refactoring bug regarding the order of the cross product in la_generate_fiber.py --- Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py index 496fbbb..ccae87a 100644 --- a/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py +++ b/Atrial_LDRBM/LDRBM/Fiber_LA/la_generate_fiber.py @@ -245,7 +245,7 @@ def la_generate_fiber(model, args, job): rpv_mean = np.mean([df["RIPV"].to_numpy(), df["RSPV"].to_numpy()], axis=0) mv_mean = df["MV"].to_numpy() - plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean) + plane = initialize_plane_with_points(mv_mean, rpv_mean, lpv_mean, mv_mean, invert_norm=True) band_s = vtk_thr(epi, 0, "CELLS", "phie_r2", max_phie_r2_tau_lpv) From 6b353afa3b1a832913fcf9c0e474bc9591027f8e Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Thu, 5 Dec 2024 16:07:57 +0100 Subject: [PATCH 69/70] Added publicly available submodule for functionality --- .gitmodules | 3 +++ VTK_openCARP_helper_methods | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 VTK_openCARP_helper_methods diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f2c8b00 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "VTK_openCARP_helper_methods"] + path = VTK_openCARP_helper_methods + url = https://github.com/KIT-IBT/VTK_openCARP_helper_methods.git diff --git a/VTK_openCARP_helper_methods b/VTK_openCARP_helper_methods new file mode 160000 index 0000000..2021bf2 --- /dev/null +++ b/VTK_openCARP_helper_methods @@ -0,0 +1 @@ +Subproject commit 2021bf222d8ec9d25d85d4dfb109572a4258870e From 1a5d5b959297670a4119d92d209eb3ba932e0bbf Mon Sep 17 00:00:00 2001 From: Pascal Maierhofer Date: Fri, 6 Dec 2024 10:07:36 +0100 Subject: [PATCH 70/70] Changed path for submodule --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index f2c8b00..8fb055e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "VTK_openCARP_helper_methods"] path = VTK_openCARP_helper_methods - url = https://github.com/KIT-IBT/VTK_openCARP_helper_methods.git + url = https://gitlab.kit.edu/kit/ibt-public/vtk_opencarp_helper_methods.git