Ejemplo n.º 1
0
def get_neighbors_around_minima(f, polyData, rd):
    points = np.array(polyData.GetPoints().GetData())
    gaussian = get_curvature_gaussian(rd)
    Mean = get_curvature_mean(rd)
    normals = get_normals(rd)
    T_Tree = vtk.vtkKdTreePointLocator()
    T_Tree.SetDataSet(polyData)
    T_Tree.BuildLocator()
    neighbours = []
    neighbours.append([
        points[f][0], points[f][1], points[f][2], 0, gaussian[f], Mean[f],
        normals[f][0], normals[f][1], normals[f][2]
    ])
    f = [points[f][0], points[f][1], points[f][2]]
    result = vtk.vtkIdList()
    num_of_neighbors = 200
    T_Tree.FindClosestNPoints(num_of_neighbors, f, result)
    for i in range(0, result.GetNumberOfIds()):
        point_ind = result.GetId(i)
        closestPoint = [0.0, 0.0, 0.0]
        T_Tree.GetDataSet().GetPoint(point_ind, closestPoint)
        distance = float(
            math.sqrt(vtk.vtkMath.Distance2BetweenPoints(closestPoint, f)))
        neighbours.append([
            closestPoint[0], closestPoint[1], closestPoint[2], distance,
            gaussian[point_ind], Mean[point_ind], normals[point_ind][0],
            normals[point_ind][1], normals[point_ind][2]
        ])
        y = np.array([np.array(xi) for xi in neighbours])
    return np.array(neighbours)
Ejemplo n.º 2
0
def transfer_mesh_scalars_get_weighted_average_n_closest(
        new_mesh, old_mesh, n=3):
    kDTree = vtk.vtkKdTreePointLocator()
    kDTree.SetDataSet(old_mesh)
    kDTree.BuildLocator()

    new_scalars = np.zeros(new_mesh.GetNumberOfPoints())
    scalars_old_mesh = np.copy(
        vtk_to_numpy(old_mesh.GetPointData().GetScalars()))
    for new_mesh_pt_idx in range(new_mesh.GetNumberOfPoints()):
        point = new_mesh.GetPoint(new_mesh_pt_idx)
        closest_ids = vtk.vtkIdList()
        kDTree.FindClosestNPoints(n, point, closest_ids)

        list_scalars = []
        distance_weighting = []
        for closest_pts_idx in range(closest_ids.GetNumberOfIds()):
            pt_idx = closest_ids.GetId(closest_pts_idx)
            _point = old_mesh.GetPoint(pt_idx)
            list_scalars.append(scalars_old_mesh[pt_idx])
            distance_weighting.append(1 / np.sqrt(
                np.sum(np.square(np.asarray(point) - np.asarray(_point)))))

        total_distance = np.sum(distance_weighting)
        normalized_value = np.sum(
            np.asarray(list_scalars) *
            np.asarray(distance_weighting)) / total_distance
        new_scalars[new_mesh_pt_idx] = normalized_value
    return new_scalars
Ejemplo n.º 3
0
def build_kd_tree(mesh):
    """
    This function..
    :param mesh:
    :return:
    """
    kd_tree = vtk.vtkKdTreePointLocator()
    kd_tree.SetDataSet(mesh)
    kd_tree.BuildLocator()
    return kd_tree
Ejemplo n.º 4
0
def locator(filename):
    vtk_reader = vtk.vtkXMLUnstructuredGridReader()
    vtk_reader.SetFileName(filename)
    vtk_reader.Update()
    grid = vtk_reader.GetOutput()
    kdtree = vtk.vtkKdTreePointLocator()
    kdtree.SetDataSet(grid)
    kdtree.BuildLocator()
    time = numpy_support.vtk_to_numpy(grid.GetPointData().GetScalars())
    return kdtree, time
def build_kd_tree(mesh):
    """
    This function..

    :param mesh:
    :return:
    """
    kd_tree = vtk.vtkKdTreePointLocator()
    kd_tree.SetDataSet(mesh)
    kd_tree.BuildLocator()
    return kd_tree
def find_closest_point(vtk_obj, point=(0., 0., 0.)):

    pointTree = vtk.vtkKdTreePointLocator()
    pointTree.SetDataSet(vtk_obj)
    pointTree.BuildLocator()

    radius = None
    if radius is None:
        vtkId = pointTree.FindClosestPoint(point)
        pcoord = vtk_obj.GetPoint(vtkId)

    return vtkId, pcoord
Ejemplo n.º 7
0
def find_point_correspondence(mesh, points):
    """
    Find the point IDs of the points on a VTK PolyData
    Args:
        mesh: the PolyData to find IDs on
        points: vtk Points
    
    Returns
        IdList: list containing the IDs
    """
    IdList = [None] * points.GetNumberOfPoints()
    locator = vtk.vtkKdTreePointLocator()
    locator.SetDataSet(mesh)
    locator.BuildLocator()
    for i in range(len(IdList)):
        newPt = points.GetPoint(i)
        IdList[i] = locator.FindClosestPoint(newPt)
    return IdList
	def keyPressEvent(self,obj,event):
		key = self.parent.GetKeySym()
		if key == 'Tab':
			if self.ActiveSelection == 0:
				self.ActiveSelection = 1
				self.textActor.SetInput("Current selection: max point (green)")
				print("To locate max point")
				self.parent.GetRenderWindow().Render()
			else:
				self.ActiveSelection = 0
				self.textActor.SetInput("Current selection: min point (red)")
				print("To locate min point")
				self.parent.GetRenderWindow().Render()
		if key == "space":
			self.parent.GetPicker().Pick(self.parent.GetEventPosition()[0],
					self.parent.GetEventPosition()[1],
					0,  # always zero.
					self.parent.GetRenderWindow().GetRenderers().GetFirstRenderer())
			picked = self.parent.GetPicker().GetPickPosition();

			# Create kd tree
			kDTree = vtk.vtkKdTreePointLocator()
			kDTree.SetDataSet(self.centerline)
			kDTree.BuildLocator()

			# Find the closest points to picked point
			iD = kDTree.FindClosestPoint(picked)
 
			# Get the coordinates of the closest point
			closestPoint = kDTree.GetDataSet().GetPoint(iD)

			if self.ActiveSelection == 0:
				self.minSphereSource.SetCenter(closestPoint)
			else:
				self.maxSphereSource.SetCenter(closestPoint)
			self.parent.GetRenderWindow().Render()
		if key == "Return":
			# Close the window
  			self.parent.GetRenderWindow().Finalize()
  			# Stop the interactor
  			self.parent.TerminateApp()

		return
Ejemplo n.º 9
0
def FindNewLandmarks(vtkPoints, meanSurfaceFilename, dirOutput):
    newLandmarks = vtk.vtkPoints()
    reader = vtk.vtkPolyDataReader()
    reader.SetFileName(meanSurfaceFilename)
    reader.Update()
    meanSurface = reader.GetOutput()
    print(meanSurface.GetBounds())
    kdTree = vtk.vtkKdTreePointLocator()
    kdTree.SetDataSet(meanSurface)
    kdTree.BuildLocator()
    for index in range(vtkPoints.GetNumberOfPoints()):
        point = [0, 0, 0]
        closestPoint = [0, 0, 0]
        vtkPoints.GetPoint(index, point)
        print(point)
        idx = kdTree.FindClosestPoint(point)
        kdTree.GetDataSet().GetPoint(idx, closestPoint)
        print(closestPoint)
        newLandmarks.InsertNextPoint(closestPoint)
    filename = meanSurfaceFilename[:-4] + '.txt'
    WriteLandmarkFile(newLandmarks, filename)
Ejemplo n.º 10
0
def translesional_result(centerline_file, wall_file,vtk_file_list, output_dir,minPoint=(0,0,0), prox_dist=5, dist_dist=5):
	# read centerline
	centerlineReader = vtk.vtkXMLPolyDataReader()
	centerlineReader.SetFileName(centerline_file)
	centerlineReader.Update()
	centerline = centerlineReader.GetOutput()

	# read vessel wall
	wallReader = vtk.vtkSTLReader()
	wallReader.SetFileName(wall_file)
	wallReader.Update()

	# read vtk files
	vtk_files = []
	centerlines = []

	if not os.path.exists(output_dir):
		os.makedirs(output_dir)

	if not os.path.exists(os.path.join(output_dir,"centerlines")):
		os.makedirs(os.path.join(output_dir,"centerlines"))

	# average filter
	averageFilter = vtk.vtkTemporalStatistics()

	for file_name in vtk_file_list:
		reader = vtk.vtkUnstructuredGridReader()
		reader.SetFileName(file_name)
		reader.Update() 

		geomFilter = vtk.vtkGeometryFilter()
		geomFilter.SetInputData(reader.GetOutput())
		geomFilter.Update()

		# scale up the CFD result
		transform = vtk.vtkTransform()
		transform.Scale(1000,1000,1000)

		transformFilter = vtk.vtkTransformPolyDataFilter()
		transformFilter.SetInputData(geomFilter.GetOutput())
		transformFilter.SetTransform(transform)
		transformFilter.Update()

		vtk_files.append(transformFilter.GetOutput())

		interpolator = vtk.vtkPointInterpolator()
		interpolator.SetSourceData(transformFilter.GetOutput())
		interpolator.SetInputData(centerline)
		interpolator.Update()

		# convert to desired unit
		# get the first element pressure
		try:
			first_point_pressure = interpolator.GetOutput().GetPointData().GetArray("p").GetValue(0)
		except:
			first_point_pressure = 120

		converter = vtk.vtkArrayCalculator()
		converter.SetInputData(interpolator.GetOutput())
		converter.AddScalarArrayName("p")
		converter.SetFunction("120 + (p - {}) * 921 * 0.0075".format(first_point_pressure)) # 921 = mu/nu = density of blood, 0.0075 converts from Pascal to mmHg, offset 120mmHg at ica
		converter.SetResultArrayName("p(mmHg)")
		converter.Update()

		converter2 = vtk.vtkArrayCalculator()
		converter2.SetInputData(converter.GetOutput())
		converter2.AddVectorArrayName("wallShearStress")
		converter2.SetFunction("wallShearStress * 921") # 921 = mu/nu = density of blood, 0.0075 converts from Pascal to mmHg, http://aboutcfd.blogspot.com/2017/05/wallshearstress-in-openfoam.html
		converter2.SetResultArrayName("wallShearStress(Pa)")
		converter2.Update()

		# output the probe centerline
		centerline_output_path = os.path.join(
			os.path.dirname(centerline_file),
			output_dir,
			"centerlines",
			"centerline_probe_{}.vtp".format(os.path.split(file_name)[1].split("_")[1].split(".")[0]) 
			)

		centerlines.append(converter2.GetOutput())
		averageFilter.SetInputData(converter2.GetOutput())
	averageFilter.Update()

	centerline = averageFilter.GetOutput()

	# extract lesion section
	# get the abscissas of min radius point
	# Create kd tree
	kDTree = vtk.vtkKdTreePointLocator()
	kDTree.SetDataSet(centerline)
	kDTree.BuildLocator()

	minIdx = kDTree.FindClosestPoint(minPoint)
	minPoint_absc = centerline.GetPointData().GetArray("Abscissas_average").GetTuple(minIdx)[0]
	thresholdFilter = vtk.vtkThreshold()
	thresholdFilter.ThresholdBetween(minPoint_absc-prox_dist,minPoint_absc+dist_dist)
	thresholdFilter.SetInputData(centerline)
	thresholdFilter.SetAllScalars(0) # important !!!
	thresholdFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS,"Abscissas_average");
	thresholdFilter.Update()

	# to vtkpolydata
	geometryFilter = vtk.vtkGeometryFilter()
	geometryFilter.SetInputData(thresholdFilter.GetOutput())
	geometryFilter.Update()

	# get closest line
	connectFilter = vtk.vtkConnectivityFilter()
	connectFilter.SetExtractionModeToClosestPointRegion()
	connectFilter.SetClosestPoint(minPoint)
	connectFilter.SetInputData(geometryFilter.GetOutput())
	connectFilter.Update()

	# compute result values
	abscissas = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))
	abscissas_unique, index = np.unique(sorted(abscissas), axis=0, return_index=True)

	pressure = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("p(mmHg)_average"))
	pressure = [x for _, x in sorted(zip(abscissas,pressure))]
	pressure = [pressure[x] for x in index]
	pressure_gradient = np.diff(pressure)/np.diff(abscissas_unique)

	velocity = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("U_average"))
	velocity = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in velocity]
	velocity = [x for _, x in sorted(zip(abscissas,velocity))]
	velocity = [velocity[x] for x in index]
	velocity_gradient = np.diff(velocity)/np.diff(abscissas_unique)

	vorticity = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("vorticity_average"))
	vorticity = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in vorticity]
	vorticity = [x for _, x in sorted(zip(abscissas,vorticity))]
	vorticity = [vorticity[x] for x in index]
	vorticity_gradient = np.diff(vorticity)/np.diff(abscissas_unique)

	wss = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("wallShearStress(Pa)_average"))
	wss = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in wss]
	wss = [wss[x] for x in index]
	wss = [x for _, x in sorted(zip(abscissas,wss))]
	wss_gradient = np.diff(wss)/np.diff(abscissas_unique)

	epsilon = 0.00001

	p_ratio = np.mean(pressure[-4:-1])/(np.mean(pressure[0:3])+epsilon)
	u_ratio = np.mean(velocity[-4:-1])/(np.mean(velocity[0:3])+epsilon)
	w_ratio = np.mean(vorticity[-4:-1])/(np.mean(vorticity[0:3])+epsilon)
	wss_ratio = np.mean(wss[-4:-1])/(np.mean(wss[0:3])+epsilon)

	dp_ratio = np.mean(pressure_gradient[-4:-1])/(np.mean(pressure_gradient[0:3])+epsilon)
	du_ratio = np.mean(velocity_gradient[-4:-1])/(np.mean(velocity_gradient[0:3])+epsilon)
	dw_ratio = np.mean(vorticity_gradient[-4:-1])/(np.mean(vorticity_gradient[0:3])+epsilon)
	dwss_ratio = np.mean(wss_gradient[-4:-1])/(np.mean(wss_gradient[0:3])+epsilon)

	return_value = {
		'translesion peak presssure(mmHg)': np.mean(heapq.nlargest(1, pressure)),
		'translesion presssure ratio': p_ratio,
		'translesion peak pressure gradient(mmHgmm^-1)': np.mean(heapq.nlargest(1, pressure_gradient)),
		'translesion pressure gradient ratio': dp_ratio,
		'translesion peak velocity(ms^-1)': np.mean(heapq.nlargest(1, velocity)),
		'translesion velocity ratio': u_ratio,
		'translesion velocity gradient ratio': du_ratio,
		'translesion peak velocity gradient(ms^-1mm^-1)': np.mean(heapq.nlargest(1, velocity_gradient)),
		'translesion peak vorticity(ms^-1)': np.mean(heapq.nlargest(1, vorticity)),
		'translesion vorticity ratio': w_ratio,
		'translesion vorticity gradient ratio': dw_ratio,
		'translesion peak vorticity gradient(Pamm^-1)':np.mean(heapq.nlargest(1, vorticity_gradient)),
		'translesion peak wss(Pa)': np.mean(heapq.nlargest(1, wss)),
		'translesion peak wss gradient(Pamm^-1)': np.mean(heapq.nlargest(1, wss_gradient)),
		'translesion wss ratio': wss_ratio,
		'translesion wss gradient ratio': dwss_ratio,
	}

	return return_value
Ejemplo n.º 11
0
def probe_min_max_point(centerline_filename, surface_filename, minPoint=(0,0,0), maxPoint=(0,0,0),probe=True):
	centerlineReader = vtk.vtkXMLPolyDataReader()
	centerlineReader.SetFileName(centerline_filename)
	centerlineReader.Update()
	centerline = centerlineReader.GetOutput()
	centerline.GetCellData().SetScalars(centerline.GetCellData().GetArray(2));
	centerline.GetPointData().SetScalars(centerline.GetPointData().GetArray("Radius"));

	surfaceReader = vtk.vtkSTLReader()
	surfaceReader.SetFileName(surface_filename)
	surfaceReader.Update()
	surface = surfaceReader.GetOutput()

	lut = vtk.vtkLookupTable()
	# lut.SetNumberOfTableValues(3);
	lut.Build()

	# Fill in a few known colors, the rest will be generated if needed
	# lut.SetTableValue(0, 1.0000, 0     , 0, 1);  
	# lut.SetTableValue(1, 0.0000, 1.0000, 0.0000, 1);
	# lut.SetTableValue(2, 0.0000, 0.0000, 1.0000, 1); 

	centerlineMapper = vtk.vtkPolyDataMapper()
	centerlineMapper.SetInputData(centerline)
	centerlineMapper.SetScalarRange(0, centerline.GetPointData().GetScalars().GetMaxNorm());
	centerlineMapper.SetLookupTable(lut);
	centerlineMapper.SetScalarModeToUsePointData()

	surfaceMapper = vtk.vtkPolyDataMapper()
	surfaceMapper.SetInputData(surface)

	scalarBar = vtk.vtkScalarBarActor()
	scalarBar.SetLookupTable(centerlineMapper.GetLookupTable());
	scalarBar.SetTitle("Radius");
	scalarBar.SetNumberOfLabels(4);
	scalarBar.SetWidth(0.08)
	scalarBar.SetHeight(0.6)
	scalarBar.SetPosition(0.9,0.1)

	# auto find the smallest radius point
	radius = centerline.GetPointData().GetArray("Radius")

	# build kd tree to locate the nearest point
	# Create kd tree
	kDTree = vtk.vtkKdTreePointLocator()
	kDTree.SetDataSet(centerline)
	kDTree.BuildLocator()

	minSource = vtk.vtkSphereSource()
	if minPoint == (0,0,0):
		minIdx = vtkArrayMin(radius)
		closestPoint = centerline.GetPoint(minIdx)
	else:
		# Find the closest point to the picked point
		iD = kDTree.FindClosestPoint(minPoint)

		# Get the id of the closest point
		closestPoint = kDTree.GetDataSet().GetPoint(iD)

	minSource.SetCenter(closestPoint)
	minSource.SetRadius(0.3);
	minMapper = vtk.vtkPolyDataMapper()
	minMapper.SetInputConnection(minSource.GetOutputPort());
	minActor = vtk.vtkActor()
	minActor.SetMapper(minMapper);
	minActor.GetProperty().SetColor((1.0,0.0,0.0))

	maxSource = vtk.vtkSphereSource()
	if maxPoint == (0,0,0):
		maxIdx = vtkArrayMin(radius)
		closestPoint = centerline.GetPoint(maxIdx)
	else:
		# Find the closest point to the picked point
		iD = kDTree.FindClosestPoint(maxPoint)

		# Get the id of the closest point
		closestPoint = kDTree.GetDataSet().GetPoint(iD)

	maxSource.SetCenter(closestPoint)
	maxSource.SetRadius(0.3);
	maxMapper = vtk.vtkPolyDataMapper()
	maxMapper.SetInputConnection(maxSource.GetOutputPort());
	maxActor = vtk.vtkActor()
	maxActor.SetMapper(maxMapper);
	maxActor.GetProperty().SetColor((0.0,1.0,0.0))

	centerlineActor = vtk.vtkActor()
	centerlineActor.SetMapper(centerlineMapper)
	
	surfaceActor = vtk.vtkActor()
	surfaceActor.SetMapper(surfaceMapper)       
	surfaceActor.GetProperty().SetOpacity(0.3)

	# text actor
	usageTextActor = vtk.vtkTextActor()
	usageTextActor.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
	usageTextActor.GetPosition2Coordinate().SetCoordinateSystemToNormalizedViewport()
	usageTextActor.SetPosition([0.001, 0.05])
	usageTextActor.SetInput("Tab: Switch max/min point\nSpace: Locate max/min point\nEnter/Close Window: Process")

	currentSelectionTextActor = vtk.vtkTextActor()
	currentSelectionTextActor.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
	currentSelectionTextActor.GetPosition2Coordinate().SetCoordinateSystemToNormalizedViewport()
	currentSelectionTextActor.SetPosition([0.25, 0.1])
	currentSelectionTextActor.SetInput("Current selection: min point (red)")

	if probe:
		renderer = vtk.vtkRenderer()
		renderer.AddActor(centerlineActor)
		renderer.AddActor(surfaceActor)
		renderer.AddActor(minActor)
		renderer.AddActor(maxActor)
		renderer.AddActor2D(scalarBar)
		renderer.AddActor(usageTextActor)
		renderer.AddActor(currentSelectionTextActor)

		renderWindow = vtk.vtkRenderWindow()
		renderWindow.AddRenderer(renderer)

		renderWindowInteractor = vtk.vtkRenderWindowInteractor()
		renderWindowInteractor.SetRenderWindow(renderWindow)
		mystyle = MyInteractorStyle(renderWindowInteractor)
		mystyle.SetMaxSphereSource(maxSource)
		mystyle.SetMinSphereSource(minSource)
		mystyle.SetCenterline(centerline)
		mystyle.SetSelectionTextActor(currentSelectionTextActor)
		renderWindowInteractor.SetInteractorStyle(mystyle)

		renderWindow.SetSize(1024,780); #(width, height)
		renderWindow.Render()
		renderWindowInteractor.Start()

	minPoint = minSource.GetCenter()
	maxPoint = maxSource.GetCenter()

	# compute degree of stenosis
	minIdx = kDTree.FindClosestPoint(minPoint)
	minRadius = centerline.GetPointData().GetArray("Radius").GetTuple(minIdx)[0]
	maxIdx = kDTree.FindClosestPoint(maxPoint)
	maxRadius = centerline.GetPointData().GetArray("Radius").GetTuple(maxIdx)[0]
	DoS = (1-minRadius/maxRadius)*100

	tqdm.write("min radius = {:.2f}\nmax radius = {:.2f} mm\nDegree of stenosis = {:.2f} %".format(minRadius,maxRadius,DoS))

	return DoS, minPoint, maxPoint
Ejemplo n.º 12
0
def moving_variance_matrix(centerline,fields, windows, minPoint=(0,0,0), bifurcationPoint=(0,0,0), result_path="", dev_result_path=""):
	# create input array from centerline
	thresholdFilter = vtk.vtkThreshold()
	thresholdFilter.SetInputData(centerline)
	thresholdFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "CenterlineIds_average")
	thresholdFilter.Update()

	fig, axs = plt.subplots(len(fields),1)
	fig.suptitle("CFD Moving Variance")
	fig.set_size_inches(10,8)

	fig2, axs2 = plt.subplots(len(fields),1)
	fig2.suptitle("CFD Derivative Moving Variance")
	fig2.set_size_inches(10,8)

	# build kd tree to locate the nearest point
	# Create kd tree
	kDTree = vtk.vtkKdTreePointLocator()
	kDTree.SetDataSet(centerline)
	kDTree.BuildLocator()

	# get the abscissas of bifurcation point
	if bifurcationPoint != (0,0,0):
		iD = kDTree.FindClosestPoint(bifurcationPoint)
		# Get the id of the closest point
		bifPointAbscissas = kDTree.GetDataSet().GetPointData().GetArray("Abscissas_average").GetTuple(iD)[0] - \
			vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))[0]

	# get the abscissas of min point
	if minPoint != (0,0,0):
		iD = kDTree.FindClosestPoint(minPoint)
		# Get the id of the closest point
		minPointAbscissas = kDTree.GetDataSet().GetPointData().GetArray("Abscissas_average").GetTuple(iD)[0] - \
			vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))[0]

	col_name = ["branch","window"] + fields
	pmv_df = pd.DataFrame(columns=col_name)
	col_name_dy = ["branch","window"] + [y+"_dev" for y in fields]
	pmv_dy_df = pd.DataFrame(columns=col_name_dy)

	for lineId in range(int(centerline.GetCellData().GetArray("CenterlineIds_average").GetMaxNorm())):
		a_x = []
		a_y = []
		a_dy = []

		thresholdFilter.ThresholdBetween(lineId,lineId)
		thresholdFilter.Update()

		# need at least 3 points to perform interpolation
		if thresholdFilter.GetOutput().GetNumberOfPoints() < 4:
			continue

		for i in range(len(fields)):
			x = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))
			x = [(value - x[0]) for value in x]

			y = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray(fields[i]))

			if len(y.shape) > 1:
				if y.shape[1] == 3:
					y = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in y]
					
			order = np.argsort(x)
			xs = np.array(x)[order]
			ys = np.array(y)[order]

			unique, index = np.unique(xs, axis=-1, return_index=True)
			xs = xs[index]
			ys = ys[index]

			f = interp1d(xs,ys,kind="cubic")
			xnew = np.linspace(0, np.amax(x), num=50, endpoint=True)
			ynew = f(xnew)

			dy = np.gradient(ynew, xnew)

			a_x.append(xnew)
			a_y.append(ynew)
			a_dy.append(dy)

		a_x = np.array(a_x)
		a_y = np.array(a_y)
		a_dy = np.array(a_dy)

		for window in windows:
			mv = np.var(rolling_window(a_y, window) , axis=-1)
			mv_dy = np.var(rolling_window(a_dy, window) , axis=-1)

			pmv = np.amax(mv,axis=-1)
			pmv = np.concatenate(([lineId,window],pmv))
			pmv_df.loc[len(pmv_df)] = pmv

			pmv_dy = np.amax(mv_dy,axis=-1)
			pmv_dy = np.concatenate(([lineId,window],pmv_dy))
			pmv_dy_df.loc[len(pmv_dy_df)] = pmv_dy

			for i in range(len(fields)):
				# plot moving variance
				if len(fields) == 1:
					ax = axs
					ax2 = axs2
				else:
					ax = axs[i]
					ax2 = axs2[i]

				ax.plot(a_x[i,:],mv[i,:])
				ax2.plot(a_x[i,:],mv_dy[i,:])

				if fields[i] == "Radius_average":
					ylabel = "Radius (mm)"
					ymin = 0
					ymax = 0.5
				elif fields[i] == "U_average":
					ylabel = "Velocity (ms^-1)"
					ymin = 0
					ymax = 0.5
				elif fields[i] == "p(mmHg)_average":
					ylabel = "Pressure (mmHg)"
					ymin = 0
					ymax = 1e3
				elif fields[i] == "vorticity_average":
					ylabel = "Vorticity (s^-1)"
					ymin = 0
					ymax = 1e7
				elif fields[i] == "Curvature_average":
					ylabel = "Curvature"
					ymin = 0
					ymax = 1e0
				elif fields[i] == "Torsion_average":
					ylabel = "Torsion"
					ymin = 0
					ymax = 1e9

				if bifurcationPoint !=(0,0,0):
					ax.axvline(x=bifPointAbscissas,ymin=0,ymax=1,linestyle="--",color='m')
					ax2.axvline(x=bifPointAbscissas,ymin=0,ymax=1,linestyle="--",color='m')

				if minPoint !=(0,0,0):
					ax.axvline(x=minPointAbscissas,ymin=0,ymax=1,linestyle="--",color='c')
					ax2.axvline(x=minPointAbscissas,ymin=0,ymax=1,linestyle="--",color='c')

				ax.set_ylabel(ylabel)
				ax2.set_ylabel(ylabel)
				if i == (len(fields)-1):
					ax.set_xlabel("Abscissas (mm)")
					ax2.set_xlabel("Abscissas (mm)")
				else:
					ax.set_xticklabels([])
					ax2.set_xticklabels([])
				ax.set_xlim(x[0],x[-1])
				ax.set_ylim(ymin,ymax)
				ax2.set_xlim(x[0],x[-1])
				ax2.set_ylim(ymin,ymax)

	# save the plot 
	fig.savefig(result_path,dpi=100)
	fig.clf()

	fig2.savefig(dev_result_path,dpi=100)
	fig2.clf()

	plt.close("all")

	pmv_df = pmv_df.groupby(['window']).max()
	pmv_df = pmv_df.drop(columns=['branch'])

	pmv_dy_df = pmv_dy_df.groupby(['window']).max()
	pmv_dy_df = pmv_dy_df.drop(columns=['branch'])

	return pmv_df, pmv_dy_df
Ejemplo n.º 13
0
def plot_centerline_result(centerline, array_names, result_path, dev_result_path ,minPoint=(0,0,0),bifurcationPoint=(0,0,0)):
	thresholdFilter = vtk.vtkThreshold()
	thresholdFilter.ThresholdBetween(1,9999)
	thresholdFilter.SetInputData(centerline)
	thresholdFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "CenterlineIds_average")
	thresholdFilter.Update()

	x = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))
	x = [(value - x[0]) for value in x]
	
	kDTree = vtk.vtkKdTreePointLocator()
	kDTree.SetDataSet(centerline)
	kDTree.BuildLocator()

	# get the abscissas of bifurcation point
	if bifurcationPoint != (0,0,0):
		iD = kDTree.FindClosestPoint(bifurcationPoint)
		# Get the id of the closest point
		bifPointAbscissas = kDTree.GetDataSet().GetPointData().GetArray("Abscissas_average").GetTuple(iD)[0] - \
			vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))[0]

	# get the abscissas of min point
	if minPoint != (0,0,0):
		iD = kDTree.FindClosestPoint(minPoint)
		# Get the id of the closest point
		minPointAbscissas = kDTree.GetDataSet().GetPointData().GetArray("Abscissas_average").GetTuple(iD)[0] - \
			vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))[0]

	fig, axs = plt.subplots(len(array_names),1)
	fig.suptitle("CFD result")
	fig.set_size_inches(10,8)

	fig2, axs2 = plt.subplots(len(array_names),1)
	fig2.suptitle("CFD result derivatives")
	fig2.set_size_inches(10,8)

	fit_dict= {}

	for i in range(len(array_names)):
		popt_list = []

		for lineId in range(int(centerline.GetCellData().GetArray("CenterlineIds_average").GetMaxNorm())):
			thresholdFilter.ThresholdBetween(lineId,lineId)
			thresholdFilter.Update()

			x = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))
			x = [(value - x[0]) for value in x]

			if len(x) < 3:
				continue

			y = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray(array_names[i]))

			if len(y.shape) > 1:
				if y.shape[1] == 3:
					y = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in y]
					
			if len(array_names) == 1:
				ax = axs
				ax2 = axs2
			else:
				ax = axs[i]
				ax2 = axs2[i]

			order = np.argsort(x)
			xs = np.array(x)[order]
			ys = np.array(y)[order]

			unique, index = np.unique(xs, axis=-1, return_index=True)
			xs = xs[index]
			ys = ys[index]

			f = interp1d(xs,ys,kind="cubic")
			xs = np.linspace(0, np.amax(x), num=200, endpoint=True)
			ys = f(xs)

			dys = np.gradient(ys, xs)

			ax.plot(xs,ys)
			ax2.plot(xs,dys)

			# curve fitting on specific values
			if array_names[i] == "Radius_average" or array_names[i] == "U_average" or array_names[i] == "p(mmHg)_average":
				try:
					popt, pcov = curve_fit(fit_func, xs, dys, p0=[50,0.1,-50])

					yfit = fit_func(xs, *popt)
					ax2.plot(xs, fit_func(xs, *popt), 'k-.',label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
				except RuntimeError:
					popt = [0,0,0]

				popt_list.append(popt)

		if array_names[i] == "Radius_average":
			ylabel = "Radius (mm)"
			ymin=0
			ymax = 5
			ymin2=-5
			ymax2 = 5
		elif array_names[i] == "U_average":
			ylabel = "Velocity (ms^-1)"
			ymin=0
			ymax = 3
			ymin2=-3
			ymax2 = 3
		elif array_names[i] == "p(mmHg)_average":
			ylabel = "Pressure (mmHg)"
			ymin=0
			ymax = 180
			ymin2=-180
			ymax2 = 180
		elif array_names[i] == "vorticity_average":
			ylabel = "Vorticity (s^-1)"
			ymin=0
			ymax = 4000
			ymin2=-4000
			ymax2 = 4000
		elif array_names[i] == "Curvature_average":
			ylabel = "Curvature"
			ymin = -1.5
			ymax = 1.5
			ymin2 = -1.5
			ymax2 = 1.5
		elif array_names[i] == "Torsion_average":
			ylabel = "Torsion"
			ymin = -100000
			ymax = 100000
			ymin2 = -100000
			ymax2 = 100000

		if bifurcationPoint !=(0,0,0):
			ax.axvline(x=bifPointAbscissas,ymin=ymin,ymax=ymax,linestyle ="--",color='m')
			ax2.axvline(x=bifPointAbscissas,ymin=ymin,ymax=ymax,linestyle ="--",color='m')

		if minPoint !=(0,0,0):
			ax.axvline(x=minPointAbscissas,ymin=ymin,ymax=ymax,linestyle ="--",color='c')
			ax2.axvline(x=minPointAbscissas,ymin=ymin,ymax=ymax,linestyle ="--",color='c')

		ax.set_ylabel(ylabel)
		ax2.set_ylabel(ylabel)
		if i == (len(array_names)-1):
			ax.set_xlabel("Abscissas (mm)")
			ax2.set_xlabel("Abscissas (mm)")
		else:
			ax.set_xticklabels([])
			ax2.set_xticklabels([])

		x = vtk_to_numpy(centerline.GetPointData().GetArray("Abscissas_average"))
		ax.set_xlim(x[0],x[-1])
		ax.set_ylim(ymin,ymax)
		ax2.set_xlim(x[0],x[-1])
		ax2.set_ylim(ymin2,ymax2)

		# max of popt[0]
		if len(popt_list) > 0:
			fit_dict.update({array_names[i]: np.abs(np.amax(np.array(popt_list),axis=0)[0])})
		
	# save the plot 
	fig.savefig(result_path,dpi=100)
	fig.clf()

	fig2.savefig(dev_result_path,dpi=100)
	fig2.clf()

	plt.close("all")

	return fit_dict
def vtu_To_hf3inp_inc_MV_matIDs_Producer(inputfilename, surfaceMesh, outputfilename):
	# ======================================================================
	# Define matIDs --------------------------------------------------------
	ID_UP = 21 # preliminary result, which gets overwritten by ID_ANT and ID_POST.
	ID_DOWN = 20
	ID_ANT = 17
	ID_POST = 18
	
	# ======================================================================
	# get system arguments -------------------------------------------------
	valve3dFilename_ = inputfilename
	valve2dFilename_ = surfaceMesh
	outputFilename_ = outputfilename
	
	print " "
	print "==========================================================================================="
	print "=== Execute Python script to produce HiFlow3 inp file (incl. matIDs) for MVR-Simulation ==="
	print "==========================================================================================="
	print " "
	
	# ======================================================================
	# read in files: -------------------------------------------------------
	# read in 3d valve
	# NOTE: ensure that the precedent meshing algorithm (CGAL or similar)
	#       produces consistent/good results w.r.t. the 'normal glyphs'.
	vtureader = vtk.vtkXMLUnstructuredGridReader()
	vtureader.SetFileName(valve3dFilename_)
	vtureader.Update()
	valve3d_ = vtureader.GetOutput()
	
	# get surface mesh of valve3d_
	geometryFilter = vtk.vtkGeometryFilter()
	if vtk.vtkVersion().GetVTKMajorVersion() >= 6:
  	  geometryFilter.SetInputData(valve3d_)
	else:
  	  geometryFilter.SetInput(valve3d_)
	geometryFilter.Update()
	valve3dSurface_ = geometryFilter.GetOutput()
	
	# compute normals of surface mesh
	normalsSurface_ = vtk.vtkPolyDataNormals()
	if vtk.vtkVersion().GetVTKMajorVersion() >= 6:
  	  normalsSurface_.SetInputData(valve3dSurface_)
	else:
  	  normalsSurface_.SetInput(valve3dSurface_)
	normalsSurface_.SplittingOn()
	normalsSurface_.ConsistencyOn() # such that on a surface the normals are oriented either 'all' outward OR 'all' inward.
	normalsSurface_.AutoOrientNormalsOn() # such that normals point outward or inward.
	normalsSurface_.ComputePointNormalsOff() # adapt here. On/Off.
	normalsSurface_.ComputeCellNormalsOn()   # adapt here.
	normalsSurface_.FlipNormalsOff()
	normalsSurface_.NonManifoldTraversalOn()
	normalsSurface_.Update()
	
	# get cell normals
	normalsSurfaceRetrieved_ = normalsSurface_.GetOutput().GetCellData().GetNormals() # adapt here.
	
	# read in 2d valve -----------------------------------------------------
	vtpreader = vtk.vtkXMLPolyDataReader()
	vtpreader.SetFileName(valve2dFilename_)
	vtpreader.Update()
	valve2d_ = vtpreader.GetOutput()
	
	# compute normals of valve2d_
	normalsValve2d_ = vtk.vtkPolyDataNormals()
	if vtk.vtkVersion().GetVTKMajorVersion() >= 6:
  	  normalsValve2d_.SetInputData(valve2d_)
	else:
  	  normalsValve2d_.SetInput(valve2d_)
	normalsValve2d_.SplittingOn()
	normalsValve2d_.ConsistencyOn()
	normalsValve2d_.ComputePointNormalsOff() # adapt here.
	normalsValve2d_.ComputeCellNormalsOn()
	normalsValve2d_.FlipNormalsOff()
	normalsValve2d_.NonManifoldTraversalOn()
	normalsValve2d_.Update()
	
	# get cell normals
	normalsValve2dRetrieved_ = normalsValve2d_.GetOutput().GetCellData().GetNormals() # adapt here.
	
	print "Reading 3D and 2D-annotated input files: DONE."
	
	# ======================================================================
	# initialize cell locator for closest cell search ----------------------
	# (using vtk methods, that find the closest point in a grid for an arbitrary point in R^3)
	cellLocator = vtk.vtkCellLocator()
	cellLocator.SetDataSet(valve2d_)
	cellLocator.BuildLocator()
	
	# ======================================================================
	# allocate memory for cell_udlr_list_ (up-down-left-right) -------------
	cell_udlr_list_ = [0 for i in range(valve3dSurface_.GetNumberOfCells())]
	
	# ======================================================================
	# iterate over the cells of the surface and compare normals ------------
	for i in range(valve3dSurface_.GetNumberOfCells()):
  	  # get cellId of closest point
  	  iD = valve3dSurface_.GetCell(i).GetPointId(0) # NOTE: only one (test)point (0) of respective cell
  	  testPoint = valve3dSurface_.GetPoint(iD)
  	  closestPoint = np.zeros(3)
  	  closestPointDist2 = vtk.mutable(0)
  	  cellId = vtk.mutable(0)
  	  subId = vtk.mutable(0)
  	  cellLocator.FindClosestPoint(testPoint, closestPoint, cellId, subId, closestPointDist2)
      
  	  normalSurf_ = np.zeros(3)
  	  normalsSurfaceRetrieved_.GetTuple(i, normalSurf_)
  	  
  	  normalV2d_ = np.zeros(3)
  	  normalsValve2dRetrieved_.GetTuple(cellId, normalV2d_)
  	  
  	  # set cell_udlr_list_ entry to (preliminary) "1", if cell is on upper side of leaflet
  	  if np.dot(normalSurf_, normalV2d_) > 0.0:
  	    cell_udlr_list_[i] = 1 # NOTE: "cell_udlr_list_[i] = 1" means "cell on upside".
  	  
  	# ======================================================================
	# iterate over cells on the upper side of the leaflet surface, and set ids for left/right ------------------
	kDTree = vtk.vtkKdTreePointLocator()
	kDTree.SetDataSet(valve2d_)
	kDTree.BuildLocator()
	
	VertexIDs_ = valve2d_.GetPointData().GetArray('VertexIDs')
	
	# allocate memory for upCellList_ (indicating if cell is on left/right side)
	upCellList_ = [i for i in range(valve3dSurface_.GetNumberOfCells()) if cell_udlr_list_[i]]
	
	for i in upCellList_:
	  iD = valve3dSurface_.GetCell(i).GetPointId(0)
	  testPoint = valve3dSurface_.GetPoint(iD)
	  result_ = vtk.vtkIdList()
	  counter = 1
	  cond_ = True
	  while cond_:
	    kDTree.FindClosestNPoints(counter, testPoint, result_)
	    for j in range(result_.GetNumberOfIds()):
	      iD2 = result_.GetId(j)
	      if int(VertexIDs_.GetTuple1(iD2)) == ID_ANT:
		    cond_ = False
		    cell_udlr_list_[i] = 2 # NOTE: "cell_udlr_list_[i] = 2" means "cell on ANT upside".
	      if int(VertexIDs_.GetTuple1(iD2)) == ID_POST:
		    cond_ = False
		    cell_udlr_list_[i] = 3 # NOTE: "cell_udlr_list_[i] = 3" means "cell on POST upside".
	    counter += 1
	
	print "Computing hf3-inp MV matID information: DONE."
	
	# ======================================================================
	# write results to inp file --------------------------------------------
	f = open(outputFilename_, 'w')
	
	# write first line
	s = str(valve3d_.GetNumberOfPoints()) + ' ' + str(valve3dSurface_.GetNumberOfCells()+valve3d_.GetNumberOfCells()) + ' 0 0 0\n'
	f.write(s)
	
	# write point coordinates
	for i in range(valve3d_.GetNumberOfPoints()):
	  pt = valve3d_.GetPoint(i)
	  s = str(i) + ' ' + str(pt[0]) + ' ' + str(pt[1]) + ' ' + str(pt[2]) + '\n'
	  f.write(s)
	
	# write connectivity information of triangles
	# integer, material id, vertex point ids
	for i in range(valve3dSurface_.GetNumberOfCells()):
	  cell = valve3dSurface_.GetCell(i)
	  iDs = cell.GetPointIds()
	  if cell_udlr_list_[i] == 2:     # NOTE: "cell_udlr_list_[i] = 2" means "cell on ANT upside".
	    matId = ID_ANT
	  elif cell_udlr_list_[i] == 3:   # NOTE: "cell_udlr_list_[i] = 3" means "cell on POST upside".
	    matId = ID_POST
	  else:                           # NOTE: "cell_udlr_list_[i] = 0" means "cell on downside".
	    matId = ID_DOWN
	  s = str(0) + ' ' + str(matId) + ' tri ' + str(iDs.GetId(0)) + ' ' + str(iDs.GetId(1)) + ' ' + str(iDs.GetId(2)) + '\n'
	  f.write(s)
	
	# write connectivity information of tetrahedrons
	# integer, material id, vertex point ids
	for i in range(valve3d_.GetNumberOfCells()):
	  cell = valve3d_.GetCell(i)
	  iDs = cell.GetPointIds()
	  matId = 10
	  s = str(0) + ' ' + str(matId) + ' tet ' + str(iDs.GetId(0)) + ' ' + str(iDs.GetId(1)) + ' ' + str(iDs.GetId(2)) + ' ' + str(iDs.GetId(3)) + '\n'
	  f.write(s)
	
	# close stream
	f.close()
	
	# ======================================================================
	print "Writing HiFlow3 inp output file (incl. MV matIDs): DONE."
	print "========================================================"
	print " "
Ejemplo n.º 15
0
    def create_kdtree(self, polydata=None):
        tree = vtk.vtkKdTreePointLocator()
        tree.SetDataSet(polydata)
        tree.BuildLocator()

        return tree
Ejemplo n.º 16
0
cN = [0.0, 0.0, 0.0]
p = [0.0, 0.0, 0.0]
size_points = normFilter.GetOutput().GetNumberOfPoints()
pointNormalsArray = vtk.vtkDoubleArray()
pointNormalsArray.SetNumberOfComponents(3)
pointNormalsArray.SetNumberOfTuples(10000000)

pts_Inner = vtk.vtkPoints()
for i in range(0, size_points):
    normFilter.GetOutput().GetPoint(i, p)
    pointNormalsRetrieved.GetTuple(i, cN)
    pts_Inner.InsertNextPoint(p)
    pointNormalsArray.SetTuple(i, cN)

kdTree = vtk.vtkKdTreePointLocator()
kdTree.SetDataSet(epicardial_wall)
kdTree.BuildLocator()

ps = [0.0, 0.0, 0.0]
pt = [0.0, 0.0, 0.0]
x = [0.0, 0.0, 0.0]
distmat = []
pts_Intersect = vtk.vtkPoints()
size_pts = endocardial_wall.GetNumberOfPoints()
for i in range(0, size_pts):

    pts_Inner.GetPoint(i, ps)

    iD = kdTree.FindClosestPoint(ps)
Ejemplo n.º 17
0
 def __init__(self, pts):
     ds = vtk.vtkPolyData()
     ds.SetPoints(pts)
     self.locator = vtk.vtkKdTreePointLocator()
     self.locator.SetDataSet(ds)
     self.locator.BuildLocator()
    def GetSemiUniDistnaceGrid(
        self, m_holePerSlice, m_numberOfSlice, m_errorTolerance=1, m_startPadding=0, m_endPadding=0, m_bufferDeg=40
    ):
        """
        Obtain a set of coordinates roughly equal to a projection of periodic square grid vertex on the arm
        surface. The gird also can arbitrarily has a buffer zone where no holes are drilled.

        :param m_holePerSlice:      [int]   Desired number of holes per slice
        :param m_numberOfSlice:     [int]   Desired number of slices
        :param m_errorTolerance:    [float] The maximum allowed deviation of hole coordinate from idea grid
        :param m_startPadding:      [int]   Starting side padding where no holes will be drilled
        :param m_endPadding:        [int]   Ending side padding where no holes will be drilled
        :param m_bufferDeg:         [float] Angle between planes where buffers zones are in between. Default to 40
        :return: [list] List of hole coordinates
        """
        vtkmath = vtk.vtkMath()

        if not self._centerLine._IS_READ_FLAG:
            self._centerLine.Read()

        if self._bufferAngle != None:
            m_bufferDeg = self._bufferAngle

        m_totalDistance = 0
        for i in xrange(
            1 + int(m_startPadding / 0.3), self._centerLine._data.GetNumberOfPoints() - int(m_endPadding / 0.3)
        ):
            m_totalDistance += self._centerLine.GetDistance(i, i - 1)

        # Shrink the distance a bit before deviding it so that all intervals will lie in the padded segment
        m_sliceSpacing = (m_totalDistance) * 0.98 / (m_numberOfSlice)
        m_intervalIndexes = self._centerLine.GetEqualDistanceIntervalsIndex(
            m_sliceSpacing, m_startPadding, m_endPadding
        )
        self._centerLineIntervals = m_intervalIndexes

        m_tangents = []
        for k in xrange(len(m_intervalIndexes)):
            m_tmp = self._centerLine.GetNormalizedTangent(m_intervalIndexes[k], range=12, step=3)
            m_tangents.append(m_tmp)

        m_average = [sum([m_tangents[i][j] for i in xrange(3)]) / float(len(m_tangents)) for j in xrange(3)]

        m_openingList = []
        m_holeList = []
        m_alphaNormal = None
        m_masterPt = self._centerLine.GetPoint(m_intervalIndexes[0])

        # Define cast opening zone and start drilling zone
        if m_bufferDeg != None and self._openingMarker != None:
            m_kdtree = vtk.vtkKdTreePointLocator()
            m_kdtree.SetDataSet(self._centerLine._data)
            m_kdtree.BuildLocator()
            m_closestCenterlinePointId = m_kdtree.FindClosestPoint(self._openingMarker)
            m_closestCenterlinePoint = self._centerLine.GetPoint(m_closestCenterlinePointId)
            m_masterPt = m_closestCenterlinePoint

        # Drill along intervals
        for i in xrange(len(m_intervalIndexes)):
            l_sliceCenter = self._centerLine.GetPoint(m_intervalIndexes[i])
            l_slice = self.SliceSurface(l_sliceCenter, m_average)
            if i == 0:
                # Define the starting vector for all slice
                # l_ringAlphaPt = l_slice.GetPoint(i)
                l_ringAlphaVect = [self._openingMarker[j] - m_masterPt[j] for j in xrange(3)]
                m_alphaNormal = [0, 0, 0]
                vtkmath.Cross(m_average, l_ringAlphaVect, m_alphaNormal)
                m_alphaNormalMag = sum([m_alphaNormal[i] for i in xrange(3)])
                m_alphaNormal = [m_alphaNormal[i] / m_alphaNormalMag for i in xrange(3)]

            # Define an initial accuracy which relax if no suitable points is found, affects calculation speed
            m_loopAccuracy = 0.25
            m_ringSliceAlphaVect = None
            while m_ringSliceAlphaVect == None:
                for j in xrange(l_slice.GetNumberOfPoints()):
                    l_ringSliceAlphaVect = [l_slice.GetPoint(j)[k] - l_sliceCenter[k] for k in xrange(3)]
                    # l_ringSliceMasterVect = [l_slice.GetPoint(j)[k] - m_masterPt[k] for k in xrange(3)]
                    if (
                        math.fabs(vtkmath.Dot(l_ringSliceAlphaVect, m_alphaNormal)) < m_loopAccuracy
                        and vtkmath.Dot(l_ringSliceAlphaVect, l_ringAlphaVect) > 0
                    ):
                        m_ringSliceAlphaVect = l_ringSliceAlphaVect
                        break
                m_loopAccuracy *= 2
                if m_loopAccuracy >= 10:
                    raise ValueError("Slice Alpha Vector search reaches maximum tolerance")
                    break

            l_uniformSectionDegree = (360.0 - m_bufferDeg) / m_holePerSlice
            l_sectionDegree = (360.0 - m_bufferDeg) / m_holePerSlice
            l_loopbreak = 0
            m_openingList.append(
                [l_ringSliceAlphaVect[k] + l_sliceCenter[k] for k in xrange(3)]
            )  # Include first vector
            l_holeList = []
            while len(l_holeList) < m_holePerSlice - 1:
                if len(l_holeList) == 0:
                    l_sectionDegree += m_bufferDeg / 2
                for j in xrange(l_slice.GetNumberOfPoints()):
                    l_p1 = [0.0, 0.0, 0.0]
                    l_ringVect = [l_slice.GetPoint(j)[k] - l_sliceCenter[k] for k in xrange(3)]
                    vtkmath.Cross(l_ringSliceAlphaVect, l_ringVect, l_p1)
                    l_p2 = vtkmath.Dot(l_p1, m_average)
                    l_angleBetweenRunningAndInitialVector = vtkmath.AngleBetweenVectors(
                        l_ringSliceAlphaVect, l_ringVect
                    )
                    if (
                        l_angleBetweenRunningAndInitialVector
                        > vtkmath.RadiansFromDegrees(l_sectionDegree - m_errorTolerance / 2)
                        and l_angleBetweenRunningAndInitialVector
                        < vtkmath.RadiansFromDegrees(l_sectionDegree + m_errorTolerance / 2.0)
                        and l_p2 > 0
                    ):
                        l_ringSliceAlphaVect = l_ringVect
                        l_holeList.append([l_ringVect[k] + l_sliceCenter[k] for k in xrange(3)])
                        l_sectionDegree += l_uniformSectionDegree - vtkmath.DegreesFromRadians(
                            l_angleBetweenRunningAndInitialVector
                        )
                        break
                if l_loopbreak == m_holePerSlice:
                    raise RuntimeError("Current error tolerence setting is to low to produce anything.")
                l_loopbreak += 1
            m_holeList.extend(l_holeList)
            self._openingList = m_openingList
        return m_holeList
Ejemplo n.º 19
0
	def addCSVFile(self,fname,mode='folded',csvDelimiter=None):
		self.setCaption(r' File:'+str(fname))
		pts=np.loadtxt(fname,csvDelimiter)
				
		points = vtk.vtkPoints()
		r,t,z = rec2cyl(pts[:,0],pts[:,1],pts[:,2])
		im_g=getGeomImperfection(r,z,np.mean(r))

		if pts.shape[1] == 4:
			useThickImp=True
		else:
			useThickImp=False

		if useThickImp:
			im_t=pts[:,3]
		else:
			im_t=np.zeros(pts.shape[0])

		rid=r-im_g
		if mode == 'unfolded':
			tt=t*r.mean()
			rr=im_g*self.scalingFactor
			for i in range(0,pts.shape[0]):
				points.InsertPoint(i,tt[i],z[i],rr[i] )
		else:
			xx,yy,zz=cyl2rec(rid+im_g*self.scalingFactor,t,z)
			for i in range(0,pts.shape[0]):
				points.InsertPoint(i,xx[i],yy[i],zz[i] )
		
        	
		polydata = vtk.vtkPolyData()
		polydata.SetPoints(points)
		polydata.Update()

		if useThickImp:
			imps=im_t
		else:
			imps=im_g
#		imps=vtk.vtkFloatArray()
#		if useThickImp:
#			for i in range(0,polydata.GetNumberOfPoints()):
#				imps.InsertNextValue(im_t[i])
#		else:
#				imps.InsertNextValue(im_g[i])
#		polydata.GetPointData().SetScalars(imps);
#
		surf =vtk.vtkSurfaceReconstructionFilter()
		surf.SetInput(polydata)
		surf.SetNeighborhoodSize(self.nbSize)
		surf.SetSampleSpacing(self.sampleSpacing)

		contourFilter = vtk.vtkContourFilter()
		contourFilter.SetInputConnection(surf.GetOutputPort())
		reverse = vtk.vtkReverseSense()
		reverse.SetInputConnection(contourFilter.GetOutputPort())
		reverse.ReverseCellsOn()
		reverse.ReverseNormalsOn()
		reverse.Update()

		outputPolyData=reverse.GetOutput()

		newSurf = self.transform_back( points, reverse.GetOutput());

		pts2=np.zeros((newSurf.GetNumberOfPoints(),3))
		for i in range(0,newSurf.GetNumberOfPoints()):
			pts2[i,:]=newSurf.GetPoint(i)

		r2,t2,z2 = rec2cyl(pts2[:,0],pts2[:,1],pts2[:,2])

				
		kDTree = vtk.vtkKdTreePointLocator()
		kDTree.SetDataSet(polydata)
		kDTree.BuildLocator()

		colors=vtk.vtkFloatArray()
			
		for i in range(0,len(pts2)):
			kid=kDTree.FindClosestPoint(pts2[i])
			colors.InsertNextValue(imps[kid])	


#		if mode == 'folded':
#				im2=getGeomImperfection(r2,z2,np.mean(r2))/self.scalingFactor
#
#		if mode == 'unfolded':
#			im2=pts2[:,2]/self.scalingFactor
#
#		colors=vtk.vtkFloatArray()
#		for i in range(0,newSurf.GetNumberOfPoints()):
#			colors.InsertNextValue(im2[i])

		newSurf.GetPointData().SetScalars(colors);
        
		self.scalarRange=colors.GetRange()
        
		self.lut=vtk.vtkLookupTable()
		self.lut.SetNumberOfTableValues(100)
		self.lut.SetTableRange(self.scalarRange)
		self.lut.SetHueRange(0.667, 0.0)
		self.lut.Build()

		
		self.resP=newSurf.GetProducerPort()
		self.colors=colors
		self.outputs.append(newSurf)

		mapper = vtk.vtkPolyDataMapper();
		mapper.SetLookupTable(self.lut)
		mapper.InterpolateScalarsBeforeMappingOn()
		mapper.SetInputConnection(newSurf.GetProducerPort())
		mapper.SetScalarModeToUsePointData()
		mapper.ScalarVisibilityOn();
		mapper.SetScalarRange(colors.GetRange())
		surfaceActor = vtk.vtkActor();
		surfaceActor.SetMapper(mapper);

		self.boundBox=newSurf.GetBounds()
		self.ren.AddActor(surfaceActor);
def BCdata_for_Hf3Sim_Producer(inputfilename, surfaceMesh, ringFilename, outputfilename):
	# ======================================================================
	# define number of given annulus point IDs -----------------------------
	# (see notation/representation of Annuloplasty Rings by DKFZ and corresponding addInfo)
	numberOfAnnulusPtIDs_ = 16
	
	# get system arguments -------------------------------------------------
	valve3dFilename_ = inputfilename
	valve2dFilename_ = surfaceMesh
	ringFilename_ = ringFilename
	outputFilename_ = outputfilename
	
	print " "
	print "====================================================================================="
	print "=== Execute Python script to produce BCdata for the  HiFlow3-based MVR-Simulation ==="
	print "====================================================================================="
	print " "
	
	# ======================================================================
	# read in files: -------------------------------------------------------
	# read in 3d valve
	vtureader = vtk.vtkXMLUnstructuredGridReader()
	vtureader.SetFileName(valve3dFilename_)
	vtureader.Update()
	valve3d_ = vtureader.GetOutput()
	
	# get surface mesh of valve3d_
	geometryFilter = vtk.vtkGeometryFilter()
	if vtk.vtkVersion().GetVTKMajorVersion() >= 6:
		geometryFilter.SetInputData(valve3d_)
	else:
		geometryFilter.SetInput(valve3d_)
	geometryFilter.Update()
	valve3dSurface_ = geometryFilter.GetOutput()
	
	# read in 2d valve
	vtpreader = vtk.vtkXMLPolyDataReader()
	vtpreader.SetFileName(valve2dFilename_)
	vtpreader.Update()
	valve2d_ = vtpreader.GetOutput()
	
	# read in ring
	vtpreader = vtk.vtkXMLPolyDataReader()
	vtpreader.SetFileName(ringFilename_)
	vtpreader.Update()
	ring_ = vtpreader.GetOutput()
	
	# get vertex ids of valve2d_ and ring_ ---------------------------------
	valve2dVertexIds_ = valve2d_.GetPointData().GetArray('VertexIDs')
	ringVertexIds_ = ring_.GetPointData().GetArray('VertexIDs')
	
	print "Reading input files: DONE."
	
	# ======================================================================
	# init. tree for closest point search ----------------------------------
	kDTree = vtk.vtkKdTreePointLocator()
	kDTree.SetDataSet(valve3dSurface_)
	kDTree.BuildLocator()
	
	# ======================================================================
	# arrays for storage of coordinates of annulus points (and interpolated points) on the MV surface and on the ring -----------------
	ringPoints_ = np.zeros((2*numberOfAnnulusPtIDs_,3))
	valvePoints_ = np.zeros((2*numberOfAnnulusPtIDs_,3))
	
	# Store coordiantes in arrays ---------------------------------------------------------------------------
	# NOTE: Alternatively, instead of a loop over all points and looking for their IDs,
	#       one could also loop over the array of vertexIDs and get the pointID.
	# find coordinates of points of ring_
	for i in range(ring_.GetNumberOfPoints()):
		if 0 <= int(ringVertexIds_.GetTuple1(i)) and int(ringVertexIds_.GetTuple1(i)) < numberOfAnnulusPtIDs_:
			ringPoints_[int(ringVertexIds_.GetTuple1(i))] = np.array(ring_.GetPoint(i))
	
	# find coordinates of points of valve2d_
	for i in range(valve2d_.GetNumberOfPoints()):
		if 0 <= int(valve2dVertexIds_.GetTuple1(i)) and int(valve2dVertexIds_.GetTuple1(i)) < numberOfAnnulusPtIDs_:
			valvePoints_[int(valve2dVertexIds_.GetTuple1(i))] = np.array(valve2d_.GetPoint(i))
	
	# find closest points to points stored in valvePoints_ on valve3dSurface_ and store (i.e. overwrite) them in valvePoints_
	for i in range(numberOfAnnulusPtIDs_):
		iD = kDTree.FindClosestPoint(valvePoints_[i])
		kDTree.GetDataSet().GetPoint(iD, valvePoints_[i])
	
	# ======================================================================
	# add additional boundary conditions by linear interpolation -------------------------------------------
	# NOTE: this requires the IDs to be ordered and going around annulus once!!!
	for i in range(numberOfAnnulusPtIDs_):
		valvePoints_[numberOfAnnulusPtIDs_+i] = 0.5 * (valvePoints_[i]+valvePoints_[(i+1)%numberOfAnnulusPtIDs_])
		ringPoints_[numberOfAnnulusPtIDs_+i] = 0.5 * (ringPoints_[i]+ringPoints_[(i+1)%numberOfAnnulusPtIDs_])
	
	# ======================================================================
	# Compute displacements ------------------------------------------------
	displacement_ = ringPoints_ - valvePoints_
	
	# ======================================================================
	# convert arrays to strings --------------------------------------------
	valvePointString_ = ""
	displacementString_ = ""
	for i in range(2*numberOfAnnulusPtIDs_):
		for j in range(3):
			valvePointString_ += str(valvePoints_[i][j])
			displacementString_ += str(displacement_[i][j])
			if j == 2:
				if i < 2*numberOfAnnulusPtIDs_-1:
					valvePointString_ += ";"
					displacementString_ += ";"
			else:
				valvePointString_ += ","
				displacementString_ += ","
	
	print "Computing BC data: DONE."
	
	# ======================================================================
	# Write BC data to XML file --------------------------------------------
	# build a tree structure
	root = ET.Element("Param")
	BCData = ET.SubElement(root, "BCData")
	DisplacementConstraintsBCs = ET.SubElement(BCData, "DisplacementConstraintsBCs")
	
	numberOfDPoints = ET.SubElement(DisplacementConstraintsBCs, "NumberOfDisplacedDirichletPoints")
	numberOfDPoints.text = str(2*numberOfAnnulusPtIDs_)
	
	dDPoints = ET.SubElement(DisplacementConstraintsBCs, "dDPoints")
	dDPoints.text = valvePointString_
	
	dDisplacements = ET.SubElement(DisplacementConstraintsBCs, "dDisplacements")
	dDisplacements.text = displacementString_
	
	# wrap it in an ElementTree instance, and save as XML
	tree = ET.ElementTree(root)
	tree.write(outputFilename_)
	
	# ======================================================================
	print "Writing mvrSimBCdata.xml output file: DONE."
	print "==========================================="
	print " "
Ejemplo n.º 21
0
def execute(working_dir):
    # convert vtk to stl
    reader = vtk.vtkGenericDataObjectReader()
    reader.SetFileName(os.path.join(working_dir, "surface.vtk"))
    reader.Update()
    surface = reader.GetOutput()

    writer = vtk.vtkSTLWriter()
    writer.SetFileName(os.path.join(working_dir, "surface.stl"))
    writer.SetInputData(surface)
    writer.Update()

    # compute centerline
    command = binary_path + " " + \
     os.path.join(working_dir,"surface.stl") + " " + \
     os.path.join(working_dir,"surface_capped.stl") + " " + \
     os.path.join(working_dir,"centerline.vtp")
    # os.system(command)

    # crop equal distance from the defected zone
    # load defected zone coordinate
    defected_point = open(os.path.join(working_dir, "defected_point.fcsv"),
                          "r").readlines()[3]
    defected_point = defected_point.split(",")[1:4]
    defected_point = [float(i) for i in defected_point]

    # load the centerline file
    reader = vtk.vtkXMLPolyDataReader()
    reader.SetFileName(os.path.join(working_dir, "centerline.vtp"))
    reader.Update()
    centerline = reader.GetOutput()

    kdTree = vtk.vtkKdTreePointLocator()
    kdTree.SetDataSet(centerline)
    iD = kdTree.FindClosestPoint(defected_point)

    end_id = centerline.GetNumberOfPoints() - 1

    defected_point_absc = centerline.GetPointData().GetArray(
        "Abscissas").GetComponent(iD, 0)

    # find the start point
    start_id = 0
    start_point_absc = 0
    start_point = [0, 0, 0]
    start_point_tangent = [1, 0, 0]
    start_point_normal = [0, 1, 0]
    start_point_binormal = [0, 0, 1]

    for i in range(centerline.GetNumberOfPoints() - 1):
        if defected_point_absc - centerline.GetPointData().GetArray(
                "Abscissas").GetComponent(i, 0) < dist_from_defect:
            break
        else:
            start_id = i
            start_point_absc = centerline.GetPointData().GetArray(
                "Abscissas").GetComponent(i, 0)
            start_point = list(centerline.GetPoints().GetPoint(i))
            start_point_tangent = list(centerline.GetPointData().GetArray(
                "FrenetTangent").GetTuple(i))
            start_point_normal = list(
                centerline.GetPointData().GetArray("FrenetNormal").GetTuple(i))
            start_point_binormal = list(centerline.GetPointData().GetArray(
                "FrenetBinormal").GetTuple(i))

    print(start_id, start_point, start_point_tangent, start_point_normal,
          start_point_binormal)

    clipBoxes = []
    clipPlanes = []
    surface, clipBox, clipPlane = clip_polydata_by_box(surface, start_point,
                                                       start_point_tangent,
                                                       start_point_normal,
                                                       start_point_binormal)
    centerline, _, _ = clip_polydata_by_box(centerline, start_point,
                                            start_point_tangent,
                                            start_point_normal,
                                            start_point_binormal)
    clipBoxes.append(clipBox)
    clipPlanes.append(clipPlane)

    # find end points
    # split the polydata by centerline id
    splitter = vtk.vtkThreshold()
    splitter.SetInputData(centerline)

    splitted_centerlines = []
    for i in range(
            int(centerline.GetCellData().GetArray("CenterlineIds").GetRange()
                [1]) + 1):
        splitter.ThresholdBetween(i, i)
        splitter.SetInputArrayToProcess(
            0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS,
            "CenterlineIds")
        splitter.Update()

        splitted_centerline = vtk.vtkPolyData()
        splitted_centerline.DeepCopy(splitter.GetOutput())
        splitted_centerlines.append(splitted_centerline)

    end_ids = []
    end_points = []
    end_points_tangent = []
    end_points_normal = []
    end_points_binormal = []

    for splitted_centerline in splitted_centerlines:
        end_id = splitted_centerline.GetNumberOfPoints() - 1
        end_point_absc = splitted_centerline.GetPointData().GetArray(
            "Abscissas").GetComponent(
                splitted_centerline.GetNumberOfPoints() - 1, 0)
        end_point = list(splitted_centerline.GetPoints().GetPoint(
            splitted_centerline.GetNumberOfPoints() - 1))
        end_point_tangent = list(splitted_centerline.GetPointData().GetArray(
            "FrenetTangent").GetTuple(splitted_centerline.GetNumberOfPoints() -
                                      1))
        end_point_normal = list(splitted_centerline.GetPointData().GetArray(
            "FrenetNormal").GetTuple(splitted_centerline.GetNumberOfPoints() -
                                     1))
        end_point_binormal = list(
            splitted_centerline.GetPointData().GetArray("FrenetBinormal").
            GetTuple(splitted_centerline.GetNumberOfPoints() - 1))

        for i in range(splitted_centerline.GetNumberOfPoints()):
            if splitted_centerline.GetPointData().GetArray(
                    "Abscissas").GetComponent(
                        i, 0) - start_point_absc > 2 * dist_from_defect:
                end_ids.append(end_id)
                end_points.append(end_point)
                end_points_tangent.append(end_point_tangent)
                end_points_normal.append(end_point_normal)
                end_points_binormal.append(end_point_binormal)
                break
            else:
                end_id = i
                end_point_absc = splitted_centerline.GetPointData().GetArray(
                    "Abscissas").GetComponent(i, 0)
                end_point = list(splitted_centerline.GetPoints().GetPoint(i))
                end_point_tangent = list(
                    splitted_centerline.GetPointData().GetArray(
                        "FrenetTangent").GetTuple(i))
                end_point_normal = list(
                    splitted_centerline.GetPointData().GetArray(
                        "FrenetNormal").GetTuple(i))
                end_point_binormal = list(
                    splitted_centerline.GetPointData().GetArray(
                        "FrenetBinormal").GetTuple(i))

            if i == splitted_centerline.GetNumberOfPoints() - 1:
                end_ids.append(end_id)
                end_points.append(end_point)
                end_points_tangent.append(end_point_tangent)
                end_points_normal.append(end_point_normal)
                end_points_binormal.append(end_point_binormal)

    for i in range(len(end_ids)):
        print(end_ids[i], end_points[i], end_points_tangent[i],
              end_points_normal[i], end_points_binormal[i])
        surface, clipBox, clipPlane = clip_polydata_by_box(
            surface, end_points[i], end_points_tangent[i],
            end_points_normal[i], end_points_binormal[i])
        centerline, _, _ = clip_polydata_by_box(centerline, end_points[i],
                                                end_points_tangent[i],
                                                end_points_normal[i],
                                                end_points_binormal[i])

        clipBoxes.append(clipBox)
        clipPlanes.append(clipPlane)

    # connected component calculation on surface and centerline
    connectedFilter = vtk.vtkConnectivityFilter()
    # connectedFilter.SetExtractionModeToAllRegions()
    # connectedFilter.ColorRegionsOn()
    connectedFilter.SetExtractionModeToClosestPointRegion()
    connectedFilter.SetClosestPoint(defected_point)
    connectedFilter.SetInputData(surface)
    connectedFilter.Update()
    surface.DeepCopy(connectedFilter.GetOutput())

    # output
    vtpWriter = vtk.vtkXMLPolyDataWriter()
    vtpWriter.SetFileName(os.path.join(working_dir, "surface_clipped.vtp"))
    vtpWriter.SetInputData(surface)
    vtpWriter.Update()

    connectedFilter.SetInputData(centerline)
    connectedFilter.Update()
    centerline.DeepCopy(connectedFilter.GetOutput())

    vtpWriter.SetFileName(os.path.join(working_dir, "centerline_clipped.vtp"))
    vtpWriter.SetInputData(centerline)
    vtpWriter.Update()

    for i in range(len(clipBoxes)):
        writer.SetFileName(
            os.path.join(working_dir, "clip_box_" + str(i) + ".stl"))
        writer.SetInputData(clipBoxes[i])
        writer.Update()

        writer.SetFileName(
            os.path.join(working_dir, "clip_plane_" + str(i) + ".stl"))
        writer.SetInputData(clipPlanes[i])
        writer.Update()
Ejemplo n.º 22
0
    def _run_interface(self, runtime):
        labelmap = sitk.ReadImage(self.inputs.labels_file)
        uncleanwm = readPolyData(self.inputs.wm_file)
        uncleangm = readPolyData(self.inputs.gm_file)
        if isdefined(self.inputs.atlas_info):
            atlas_dict = parse_labels_xml(self.inputs.atlas_info)
        # Clean the data
        cleanwm = vtk.vtkCleanPolyData()
        cleanwm.SetInputData(uncleanwm)
        cleangm = vtk.vtkCleanPolyData()
        cleangm.SetInputData(uncleangm)
        cleanwm.Update()
        cleangm.Update()
        wmsurf = cleanwm.GetOutput()
        gmsurf = cleangm.GetOutput()
        # setup KdTrees for each surface
        # this will help in finding the closest points
        kdTreewm = vtk.vtkKdTreePointLocator()
        kdTreewm.SetDataSet(wmsurf)
        kdTreewm.BuildLocator()
        kdTreegm = vtk.vtkKdTreePointLocator()
        kdTreegm.SetDataSet(gmsurf)
        kdTreegm.BuildLocator()
        measurements = dict()
        wmPD = wmsurf.GetPointData()
        wmPoints = wmsurf.GetPoints()
        wmCount = wmPD.GetNumberOfTuples()
        for i in range(0, wmCount):
            wmP = wmPoints.GetPoint(i)
            # Find the closest point to the gray matter surface point
            gmIndex = kdTreegm.FindClosestPoint(wmP)
            gmP = kdTreegm.GetDataSet().GetPoint(gmIndex)
            # Get the gray matter label from the label map
            gmlabel = vtkPoint_to_label(gmP, labelmap)
            if gmlabel != 0:
                label = str(gmlabel)
            else:
                # if the gray matter label is not defined try the wm label
                wmlabel = vtkPoint_to_label(wmP, labelmap)
                if wmlabel != 0:
                    label = str(wmlabel)
                else:
                    # label is not known
                    label = 'UNKNOWN'
            # compute the distance
            # distance from wm point to gm point
            dst1 = distance.euclidean(wmP, gmP)
            wmIndex = kdTreewm.FindClosestPoint(gmP)
            wmP2 = kdTreegm.GetDataSet().GetPoint(wmIndex)
            # distnace from gm to closest wm point
            dst2 = distance.euclidean(gmP, wmP2)
            # average the two distances
            thickness = (dst1 + dst2) / 2
            if not measurements.has_key(label):
                # first point in a labeled region
                measurements[label] = [thickness]
            else:
                measurements[label].append(thickness)

        mu = ["mean"]
        median = ["median"]
        std = ["std"]
        count = ["points"]
        minimum = ["min"]
        maximum = ["max"]
        labels = ["label"]
        for key in measurements.iterkeys():
            labels.append(key)
            data = np.array(measurements[key])
            mu.append(np.mean(data))
            median.append(np.median(data))
            std.append(np.std(data))
            count.append(len(data))
            minimum.append(np.min(data))
            maximum.append(np.max(data))

        out_csv = self._list_outputs()['out_file']
        with open(out_csv, 'w') as CSV_file:
            writer = csv.writer(CSV_file)
            writer.writerows([labels, mu, std, count, minimum, maximum])

        return runtime
Ejemplo n.º 23
0
    polyData = iter.GetCurrentDataObject()
    if not polyData.IsA("vtkPolyData"):
        print "ERROR: unexpected input (not vtkPolyData)"
        exit(1)
    nc = polyData.GetNumberOfCells()
    print "boundary",boundary_id,":",nc
    for i in range(nc):
        cell = polyData.GetCell(i)
        midpoint = get_midpoint(cell)
        boundary_mid_points.InsertNextPoint(midpoint)
        boundary_id_array.InsertNextValue(boundary_id)
    boundary_id += 1
    iter.GoToNextItem()
num_boundaries = boundary_id

loc = vtk.vtkKdTreePointLocator()
boundary_dataset = vtk.vtkPolyData()
boundary_dataset.SetPoints(boundary_mid_points)
loc.SetDataSet(boundary_dataset)
loc.BuildLocator()

# map from boundaries to a list of tuples containing point ids and the cell id
boundary_faces = []
for i in range(num_boundaries):
    boundary_faces.append([])

internal_faces = []

volume.BuildLinks()
nc = volume.GetNumberOfCells()
Ejemplo n.º 24
0
def build_kd_tree(mesh):
    kd_tree = vtk.vtkKdTreePointLocator()
    kd_tree.SetDataSet(mesh)
    kd_tree.BuildLocator()
    return kd_tree
Ejemplo n.º 25
0
def normalizeVessels(case_dir,
                     dist_from_bif_inlet=35,
                     dist_from_bif_outlet=35):
    # phases = ["baseline","baseline-post","12months","followup"]
    phases = ["baseline"]

    centerlines = {}
    surfaces = {}

    for phase in phases:
        if not os.path.exists(os.path.join(case_dir, phase, "centerline.vtp")):
            continue
        # load the centerline file
        reader = vtk.vtkXMLPolyDataReader()
        reader.SetFileName(os.path.join(case_dir, phase, "centerline.vtp"))
        reader.Update()
        centerline = reader.GetOutput()
        centerlines.update({phase: centerline})

        # load surface files
        if not os.path.exists(os.path.join(case_dir, phase, "surface.stl")):
            continue
        # reader = vtk.vtkGenericDataObjectReader()
        reader = vtk.vtkSTLReader()
        reader.SetFileName(os.path.join(case_dir, phase, "surface.stl"))
        reader.Update()
        surface = reader.GetOutput()
        surfaces.update({phase: surface})

    # get the bifurcation point from baseline data
    # split the polydata by centerline id
    splitter = vtk.vtkThreshold()
    splitter.SetInputData(centerlines["baseline"])
    splitter.ThresholdBetween(0, 0)
    splitter.SetInputArrayToProcess(0, 0, 0,
                                    vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS,
                                    "GroupIds")
    splitter.Update()
    mainBranch = splitter.GetOutput()

    maxAbsc = 0
    maxAbscId = 0

    for i in range(mainBranch.GetNumberOfPoints()):
        absc = mainBranch.GetPointData().GetArray("Abscissas").GetComponent(
            i, 0)
        if absc > maxAbsc:
            maxAbsc = absc
            maxAbscId = i

    bifPoint = mainBranch.GetPoint(maxAbscId)

    bifPoint_list = {}
    bifPoint_absc_list = {}
    bifPoint_id_list = {}
    endPoint1_absc_list = {}
    endPoint1_id_list = {}
    endPoint2_absc_list = {}
    endPoint2_id_list = {}

    for key, centerline in centerlines.items():
        kdTree = vtk.vtkKdTreePointLocator()
        kdTree.SetDataSet(centerline)
        iD = kdTree.FindClosestPoint(bifPoint)

        bifPoint_absc_list.update({
            key:
            centerline.GetPointData().GetArray("Abscissas").GetComponent(
                iD, 0)
        })
        bifPoint_id_list.update({key: iD})

        splitter = vtk.vtkThreshold()
        splitter.SetInputData(centerline)
        splitter.SetInputArrayToProcess(
            0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "GroupIds")
        splitter.ThresholdBetween(2, 2)
        splitter.Update()
        ACA = splitter.GetOutput()
        endPoint1_absc_list.update({
            key:
            ACA.GetPointData().GetArray("Abscissas").GetComponent(
                ACA.GetNumberOfPoints() - 1, 0) - bifPoint_absc_list[key]
        })
        endPoint1_id_list.update({key: ACA.GetNumberOfPoints() - 1})

        splitter.ThresholdBetween(3, 3)
        splitter.Update()
        MCA = splitter.GetOutput()
        endPoint2_absc_list.update({
            key:
            ACA.GetPointData().GetArray("Abscissas").GetComponent(
                MCA.GetNumberOfPoints() - 1, 0) - bifPoint_absc_list[key]
        })
        endPoint2_id_list.update({key: ACA.GetNumberOfPoints() - 1})

        # append the bifurcation point
        bifPoint_list.update({key: bifPoint})

    # get the start point coordinate
    start_id = 0
    start_point_absc = 0
    start_point = [0, 0, 0]
    start_point_tangent = [1, 0, 0]
    start_point_normal = [0, 1, 0]
    start_point_binormal = [0, 0, 1]

    for i in range(centerlines["baseline"].GetNumberOfPoints()):
        if (bifPoint_absc_list["baseline"] - centerlines["baseline"].GetPointData().GetArray("Abscissas").GetComponent(i,0) < min(bifPoint_absc_list.values())) and \
         (bifPoint_absc_list["baseline"] - centerlines["baseline"].GetPointData().GetArray("Abscissas").GetComponent(i,0) < dist_from_bif_inlet):
            break
        else:
            start_id = i
            start_point_absc = centerlines["baseline"].GetPointData().GetArray(
                "Abscissas").GetComponent(i, 0)
            start_point = list(centerlines["baseline"].GetPoint(i))
            start_point_tangent = list(
                centerlines["baseline"].GetPointData().GetArray(
                    "FrenetTangent").GetTuple(i))
            start_point_normal = list(
                centerlines["baseline"].GetPointData().GetArray(
                    "FrenetNormal").GetTuple(i))
            start_point_binormal = list(
                centerlines["baseline"].GetPointData().GetArray(
                    "FrenetBinormal").GetTuple(i))

    # get the end point coordinates
    end_ids = []
    end_points = []
    end_points_tangent = []
    end_points_normal = []
    end_points_binormal = []
    splitter = vtk.vtkThreshold()
    splitter.SetInputData(centerlines["baseline"])
    splitter.SetInputArrayToProcess(0, 0, 0,
                                    vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS,
                                    "GroupIds")

    groupdIds = [2, 3]

    for groupId in groupdIds:
        splitter.ThresholdBetween(groupId, groupId)
        splitter.Update()
        splitted_centerline = splitter.GetOutput()

        end_id = splitted_centerline.GetNumberOfPoints() - 1
        end_point_absc = splitted_centerline.GetPointData().GetArray(
            "Abscissas").GetComponent(
                splitted_centerline.GetNumberOfPoints() - 1, 0)
        end_point = list(splitted_centerline.GetPoints().GetPoint(
            splitted_centerline.GetNumberOfPoints() - 1))
        end_point_tangent = list(splitted_centerline.GetPointData().GetArray(
            "FrenetTangent").GetTuple(splitted_centerline.GetNumberOfPoints() -
                                      1))
        end_point_normal = list(splitted_centerline.GetPointData().GetArray(
            "FrenetNormal").GetTuple(splitted_centerline.GetNumberOfPoints() -
                                     1))
        end_point_binormal = list(
            splitted_centerline.GetPointData().GetArray("FrenetBinormal").
            GetTuple(splitted_centerline.GetNumberOfPoints() - 1))

        for i in range(splitted_centerline.GetNumberOfPoints()):
            if groupId == 2:
                endPoint_absc_list = endPoint1_absc_list.values()
            else:
                endPoint_absc_list = endPoint2_absc_list.values()

            if (splitter.GetOutput().GetPointData().GetArray("Abscissas").GetComponent(i,0)-bifPoint_absc_list["baseline"]< min(endPoint_absc_list)) and \
             (splitter.GetOutput().GetPointData().GetArray("Abscissas").GetComponent(i,0)-bifPoint_absc_list["baseline"] < dist_from_bif_outlet):
                end_id = i
                end_point_absc = splitted_centerline.GetPointData().GetArray(
                    "Abscissas").GetComponent(i, 0)
                end_point = list(splitted_centerline.GetPoints().GetPoint(i))
                end_point_tangent = list(
                    splitted_centerline.GetPointData().GetArray(
                        "FrenetTangent").GetTuple(i))
                end_point_normal = list(
                    splitted_centerline.GetPointData().GetArray(
                        "FrenetNormal").GetTuple(i))
                end_point_binormal = list(
                    splitted_centerline.GetPointData().GetArray(
                        "FrenetBinormal").GetTuple(i))

            else:
                end_ids.append(end_id)
                end_points.append(end_point)
                end_points_tangent.append(end_point_tangent)
                end_points_normal.append(end_point_normal)
                end_points_binormal.append(end_point_binormal)
                break

            if i == splitted_centerline.GetNumberOfPoints() - 1:
                end_ids.append(end_id)
                end_points.append(end_point)
                end_points_tangent.append(end_point_tangent)
                end_points_normal.append(end_point_normal)
                end_points_binormal.append(end_point_binormal)

    # clip the surfaces
    clipBoxes = {}
    clipPlanes = {}
    boundaryCaps = {}
    surfaces_clipped = {}
    centerlines_clipped = {}
    # connected component calculation on surface and centerline
    connectedFilter = vtk.vtkConnectivityFilter()
    # connectedFilter.SetExtractionModeToAllRegions()
    # connectedFilter.ColorRegionsOn()
    connectedFilter.SetExtractionModeToClosestPointRegion()
    connectedFilter.SetClosestPoint(bifPoint)
    key_point_list = {}

    for key, surface in surfaces.items():
        clipBoxes_ = {}
        clipPlanes_ = {}
        boundaryCaps_ = {}
        key_point_list_ = {}

        kdTree = vtk.vtkKdTreePointLocator()
        kdTree.SetDataSet(centerlines[key])

        iD = kdTree.FindClosestPoint(bifPoint_list[key])
        kdTree.Update()

        bif_point_ = list(centerlines[key].GetPoint(iD))
        bif_point_tangent_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetTangent").GetTuple(iD))
        bif_point_normal_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetNormal").GetTuple(iD))
        bif_point_binormal_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetBinormal").GetTuple(iD))

        bif_point_dict = {
            "coordinate": bif_point_,
            "tangent": bif_point_tangent_,
            "normal": bif_point_normal_,
            "binormal": bif_point_binormal_
        }
        key_point_list_.update({"BifurcationPoint": bif_point_dict})

        iD = kdTree.FindClosestPoint(start_point)
        kdTree.Update()

        start_point_ = list(centerlines[key].GetPoint(iD))
        start_point_tangent_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetTangent").GetTuple(iD))
        start_point_normal_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetNormal").GetTuple(iD))
        start_point_binormal_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetBinormal").GetTuple(iD))

        start_point_dict = {
            "coordinate": start_point_,
            "tangent": start_point_tangent_,
            "normal": start_point_normal_,
            "binormal": start_point_binormal_
        }
        key_point_list_.update({"ICA": start_point_dict})

        clip_result = clip_polydata_by_box(surface,
                                           start_point_,
                                           start_point_tangent_,
                                           start_point_normal_,
                                           start_point_binormal_,
                                           size=[15, 15, 1],
                                           capping=capping)

        # perform lcc everytime after clipping to guarantee clean result
        connectedFilter.SetInputData(clip_result["clipped_surface"])
        connectedFilter.Update()
        surface.DeepCopy(connectedFilter.GetOutput())

        clipBoxes_.update({"ICA": clip_result["clip_box"]})
        clipPlanes_.update({"ICA": clip_result["clip_plane"]})
        connectedFilter_cap = vtk.vtkConnectivityFilter()
        connectedFilter_cap.SetExtractionModeToClosestPointRegion()
        connectedFilter_cap.SetClosestPoint([
            start_point_[i] + start_point_tangent_[i]
            for i in range(len(start_point_))
        ])
        connectedFilter_cap.SetInputData(clip_result["boundary_cap"])
        connectedFilter_cap.Update()
        start_cap = vtk.vtkPolyData()
        start_cap.DeepCopy(connectedFilter_cap.GetOutput())
        boundaryCaps_.update({"ICA": start_cap})

        for i in range(len(end_points)):
            if i == 0:
                outlet_key = "ACA"
            else:
                outlet_key = "MCA"

            kdTree = vtk.vtkKdTreePointLocator()
            kdTree.SetDataSet(centerlines[key])
            iD = kdTree.FindClosestPoint(end_points[i])
            kdTree.Update()

            end_point_ = list(centerlines[key].GetPoint(iD))
            end_point_tangent_ = list(centerlines[key].GetPointData().GetArray(
                "FrenetTangent").GetTuple(iD))
            end_point_normal_ = list(centerlines[key].GetPointData().GetArray(
                "FrenetNormal").GetTuple(iD))
            end_point_binormal_ = list(
                centerlines[key].GetPointData().GetArray(
                    "FrenetBinormal").GetTuple(iD))

            end_point_dict = {
                "coordinate": end_point_,
                "tangent": end_point_tangent_,
                "normal": end_point_normal_,
                "binormal": end_point_binormal_
            }
            key_point_list_.update({outlet_key: start_point_dict})

            clip_result = clip_polydata_by_box(surface,
                                               end_point_,
                                               end_point_tangent_,
                                               end_point_normal_,
                                               end_point_binormal_,
                                               size=[10, 10, 1],
                                               capping=capping)
            # perform lcc everytime after clipping to guarantee clean result
            connectedFilter.SetInputData(clip_result["clipped_surface"])
            connectedFilter.Update()
            surface.DeepCopy(connectedFilter.GetOutput())

            clipBoxes_.update({outlet_key: clip_result["clip_box"]})
            clipPlanes_.update({outlet_key: clip_result["clip_plane"]})
            connectedFilter_cap = vtk.vtkConnectivityFilter()
            connectedFilter_cap.SetExtractionModeToClosestPointRegion()
            connectedFilter_cap.SetClosestPoint([
                end_point_[i] - end_point_tangent_[i]
                for i in range(len(end_point_))
            ])
            connectedFilter_cap.SetInputData(clip_result["boundary_cap"])
            connectedFilter_cap.Update()
            end_cap = vtk.vtkPolyData()
            end_cap.DeepCopy(connectedFilter_cap.GetOutput())
            # end_cap = clip_result["boundary_cap"]
            boundaryCaps_.update({outlet_key: end_cap})

        clipBoxes.update({key: clipBoxes_})
        clipPlanes.update({key: clipPlanes_})
        boundaryCaps.update({key: boundaryCaps_})
        surfaces_clipped.update({key: surface})
        key_point_list.update({key: key_point_list_})

    for key, centerline in centerlines.items():
        kdTree = vtk.vtkKdTreePointLocator()
        kdTree.SetDataSet(centerlines[key])
        iD = kdTree.FindClosestPoint(start_point)
        kdTree.Update()

        start_point_ = list(centerlines[key].GetPoint(iD))
        start_point_tangent_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetTangent").GetTuple(iD))
        start_point_normal_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetNormal").GetTuple(iD))
        start_point_binormal_ = list(centerlines[key].GetPointData().GetArray(
            "FrenetBinormal").GetTuple(iD))

        clip_result = clip_polydata_by_box(centerline,
                                           start_point_,
                                           start_point_tangent_,
                                           start_point_normal_,
                                           start_point_binormal_,
                                           size=[15, 15, 1])
        centerline = clip_result["clipped_surface"]

        for i in range(len(end_ids)):
            kdTree = vtk.vtkKdTreePointLocator()
            kdTree.SetDataSet(centerlines[key])
            iD = kdTree.FindClosestPoint(end_points[i])
            kdTree.Update()

            end_point_ = list(centerlines[key].GetPoint(iD))
            end_point_tangent_ = list(centerlines[key].GetPointData().GetArray(
                "FrenetTangent").GetTuple(iD))
            end_point_normal_ = list(centerlines[key].GetPointData().GetArray(
                "FrenetNormal").GetTuple(iD))
            end_point_binormal_ = list(
                centerlines[key].GetPointData().GetArray(
                    "FrenetBinormal").GetTuple(iD))

            clip_result = clip_polydata_by_box(centerline,
                                               end_point_,
                                               end_point_tangent_,
                                               end_point_normal_,
                                               end_point_binormal_,
                                               size=[10, 10, 1])
            centerline = clip_result["clipped_surface"]

        connectedFilter.SetInputData(centerline)
        connectedFilter.Update()
        centerline.DeepCopy(connectedFilter.GetOutput())
        centerlines_clipped.update({key: centerline})

    # output
    vtpWriter = vtk.vtkXMLPolyDataWriter()

    for key, value in centerlines_clipped.items():
        vtpWriter.SetFileName(
            os.path.join(case_dir, key, "centerline_clipped.vtp"))
        vtpWriter.SetInputData(value)
        vtpWriter.Update()

    stlWriter = vtk.vtkSTLWriter()

    for key, value in surfaces_clipped.items():
        stlWriter.SetFileName(
            os.path.join(case_dir, key, "surface_clipped.stl"))
        stlWriter.SetInputData(value)
        stlWriter.Update()

    for key, value in clipBoxes.items():
        for key_, value_ in value.items():
            stlWriter.SetFileName(
                os.path.join(case_dir, key, "clip_box_" + key_ + ".stl"))
            stlWriter.SetInputData(value_)
            stlWriter.Update()

    for key, value in clipPlanes.items():
        for key_, value_ in value.items():
            stlWriter.SetFileName(
                os.path.join(case_dir, key, "clip_plane_" + key_ + ".stl"))
            stlWriter.SetInputData(value_)
            stlWriter.Update()

    for key, value in boundaryCaps.items():
        for key_, value_ in value.items():
            stlWriter.SetFileName(
                os.path.join(case_dir, key, "boundary_cap_" + key_ + ".stl"))
            stlWriter.SetInputData(value_)
            stlWriter.Update()

    inletKeys = ["ICA", "ACA", "MCA"]

    if stl_concat:
        for phase in phases:
            if not os.path.exists(
                    os.path.join(case_dir, phase, "surface_clipped.stl")):
                continue
            os.remove(os.path.join(case_dir, phase, "surface_capped.stl"))

            # check nan and correct
            mesh = trimesh.load_mesh(
                os.path.join(case_dir, phase, "surface_clipped.stl"))
            mesh.process()
            mesh.export(os.path.join(case_dir, phase, "surface_clipped.stl"),
                        file_type='stl_ascii')

            stl_text = open(
                os.path.join(case_dir, phase,
                             "surface_clipped.stl")).read().splitlines(True)
            stl_text[0] = "solid vessel\n"
            stl_text.append("\n")

            fout = open(os.path.join(case_dir, phase, "surface_capped.stl"),
                        'w')
            fout.writelines(stl_text)

            for inletKey in inletKeys:
                # check nan and correct
                mesh = trimesh.load_mesh(
                    os.path.join(
                        os.path.join(case_dir, phase,
                                     "boundary_cap_" + inletKey + ".stl")))
                mesh.process()
                mesh.export(os.path.join(case_dir, phase,
                                         "boundary_cap_" + inletKey + ".stl"),
                            file_type='stl_ascii')

                stl_text = open(
                    os.path.join(case_dir, phase, "boundary_cap_" + inletKey +
                                 ".stl")).read().splitlines(True)
                stl_text[0] = "solid " + inletKey + "\n"
                stl_text.append("\n")

                fout.writelines(stl_text)

            fout.close()

    # output keypoint as json file
    for phase in phases:
        if not os.path.exists(os.path.join(case_dir, phase)):
            continue

        with open(os.path.join(case_dir, phase, "inlets.json"), "w") as fp:
            json.dump(key_point_list[phase], fp, indent=4)