示例#1
0
 def get_data_vtk(self, points_interpol, interpolation_method="linear"):
     """
     Get interpolated data for points_interpol using vtks built-in interpolation methods
     """
     kernels = {
         "voronoi": vtk.vtkVoronoiKernel(),
         "gaussian": vtk.vtkGaussianKernel(),
         "shepard": vtk.vtkShepardKernel(),
         "linear": vtk.vtkLinearKernel()
     }
     pointnumpyarray = np.array(
         [points_interpol[pt] for pt in points_interpol])
     out_u_grid = vtk.vtkUnstructuredGrid()
     r = vtk.vtkPoints()
     r.SetData(numpy_to_vtk(pointnumpyarray))
     out_u_grid.SetPoints(r)
     locator = vtk.vtkStaticPointLocator()
     locator.SetDataSet(self.output)
     locator.BuildLocator()
     interpolator = vtk.vtkPointInterpolator()
     interpolator.SetInputData(out_u_grid)
     interpolator.SetSourceData(self.output)
     interpolator.SetKernel(kernels[interpolation_method])
     interpolator.SetLocator(locator)
     interpolator.Update()
     return interpolator.GetOutput().GetPointData()
示例#2
0
    def probeUnstructuredGridVTKOverLine(self, lineVTK, readerUnstructuredGridVTK, varName,
                                         kernel="gaussian", radius=None, nullValue=None):
        """ Interpolate the data from the Unstructured Grid VTK onto a line (profile).

        The unstructured grid VTK is supposed to be a 2D surface in 3D space, such as the mesh used in 2D hydraulics
        models.

        To probe on them, the surface has to be flattened first.

        Parameters
        ----------
        lineVTK : vtkLineSource or vtkPoints
            coordinates of points in the vtkLineSource; the points don't need to ordered,
            thus they can be just a bunch of points
        readerUnstructuredGridVTK : vtkUnstructuredGridReader
            Unstructured Grid VTK reader
        varName : str
            name of the variable to be probed
        kernel : str
            name of the kernel for interpolation (linear, gaussin, voronoi, Shepard"
        radius : float
            radius for interpolation kernels
        nullValue: float
            value to be assigned to invalid probing points


        Returns
        -------
        points: numpy arrays [number of points, 3]; points on the profile
        probed result array:
        elev: elevation (z) of points in the profile

        """

        # Get data from the Unstructured Grid VTK reader
        data = readerUnstructuredGridVTK.GetOutput()

        # make sure the data is stored at points (for smoother interpolation)
        cell2point = vtk.vtkCellDataToPointData()
        cell2point.SetInputData(data)
        cell2point.Update()
        data = cell2point.GetOutput()   #after this, all data are stored at points, not cell centers.

        bounds = data.GetBounds()

        #print("Unstructured Grid VTK bounds = ", bounds)
        #print("Unstructured Grid number of cells: ", data.GetNumberOfCells())
        #print("Unstructured Grid number of points: ", data.GetNumberOfPoints())

        if radius is None:
            boundingArea = (bounds[1] - bounds[0]) * (bounds[3] - bounds[2])   #assume 2D Grid
            averageCellArea =  boundingArea/data.GetNumberOfCells()            #average cell area
            radius = np.sqrt(averageCellArea)                                  #average size of cell
            radius = 2.0*radius                                                #double the search radius

        ### make a transform to set all Z values to zero ###
        flattener = vtk.vtkTransform()
        flattener.Scale(1.0, 1.0, 0.0)

        ### flatten the input in case it's not already flat ###
        i_flat = vtk.vtkTransformFilter()

        if isinstance(lineVTK, vtk.vtkLineSource):
            i_flat.SetInputConnection(lineVTK.GetOutputPort())
        elif isinstance(lineVTK, vtk.vtkPoints):
            polydata_temp = vtk.vtkPolyData()
            polydata_temp.SetPoints(lineVTK)
            i_flat.SetInputData(polydata_temp)
        else:
            raise Exception("lineVTK type,", type(lineVTK),", not supported. Only vtkLineSource and vtkPoints are supported.")

        i_flat.SetTransform(flattener)

        ### transfer z elevation values to the source's point scalar data ###
        s_elev = vtk.vtkElevationFilter()
        s_elev.SetInputData(data)
        s_elev.SetHighPoint(0, 0, bounds[5])
        s_elev.SetLowPoint(0, 0, bounds[4])
        s_elev.SetScalarRange(bounds[4], bounds[5])
        s_elev.Update()

        #print("s_elev = ", s_elev.GetUnstructuredGridOutput())

        ### flatten the source data; the Z elevations are already in the scalars data ###
        s_flat = vtk.vtkTransformFilter()
        s_flat.SetInputConnection(s_elev.GetOutputPort())
        s_flat.SetTransform(flattener)

        # build the probe using vtkPointInterpolator
        # construct the interpolation kernel
        if kernel == 'gaussian':
            kern = vtk.vtkGaussianKernel()
            kern.SetSharpness(2)
            kern.SetRadius(radius)
        elif kernel == 'voronoi':
            kern = vtk.vtkVoronoiKernel()
        elif kernel == 'linear':
            kern = vtk.vtkLinearKernel()
            kern.SetRadius(radius)
        elif kernel == 'Shepard':
            kern = vtk.vtkShepardKernel()
            kern.SetPowerParameter(2)
            kern.SetRadius(radius)
        else:
            raise Exception("The specified kernel is not supported.")

        probe = vtk.vtkPointInterpolator()
        probe.SetInputConnection(i_flat.GetOutputPort())
        probe.SetSourceConnection(s_flat.GetOutputPort())
        probe.SetKernel(kern)
        if nullValue is not None:
            probe.SetNullValue(nullValue)
        else:
            probe.SetNullPointsStrategyToClosestPoint()

        probe.Update()

        # (This approach of using vtkProbeFilter is replaced by vtkPointInterpolator for smoother result)
        # vtkProbeFilter, the probe line is the input, and the underlying dataset is the source.
        #probe = vtk.vtkProbeFilter()
        #probe.SetInputConnection(i_flat.GetOutputPort())
        #probe.SetSourceConnection(s_flat.GetOutputPort())
        #probe.Update()

        # get the data from the VTK-object (probe) to an numpy array
        #print("varName =", varName)
        #print(probe.GetOutput().GetPointData().GetArray(varName))

        varProbedValues = VN.vtk_to_numpy(probe.GetOutput().GetPointData().GetArray(varName))

        numPoints = probe.GetOutput().GetNumberOfPoints()  # get the number of points on the line

        # get the elevation from the VTK-object (probe) to an numpy array
        elev = VN.vtk_to_numpy(probe.GetOutput().GetPointData().GetArray("Elevation"))

        # intialise the points on the line
        x = np.zeros(numPoints)
        y = np.zeros(numPoints)
        z = np.zeros(numPoints)
        points = np.zeros((numPoints, 3))

        # get the coordinates of the points on the line
        for i in range(numPoints):
            x[i], y[i], z[i] = probe.GetOutput().GetPoint(i)
            points[i, 0] = x[i]
            points[i, 1] = y[i]
            points[i, 2] = z[i]

        return points, varProbedValues, elev
示例#3
0
def interpolateToVolume(mesh,
                        kernel='shepard',
                        radius=None,
                        N=None,
                        bounds=None,
                        nullValue=None,
                        dims=(25, 25, 25)):
    """
    Generate a ``Volume`` by interpolating a scalar
    or vector field which is only known on a scattered set of points or mesh.
    Available interpolation kernels are: shepard, gaussian, or linear.

    :param str kernel: interpolation kernel type [shepard]
    :param float radius: radius of the local search
    :param list bounds: bounding box of the output Volume object
    :param list dims: dimensions of the output Volume object
    :param float nullValue: value to be assigned to invalid points

    |interpolateVolume| |interpolateVolume.py|_
    """
    if isinstance(mesh, vtk.vtkPolyData):
        output = mesh
    else:
        output = mesh.polydata()

    if radius is None and not N:
        colors.printc(
            "Error in interpolateToVolume(): please set either radius or N",
            c='r')
        raise RuntimeError

    # Create a probe volume
    probe = vtk.vtkImageData()
    probe.SetDimensions(dims)
    if bounds is None:
        bounds = output.GetBounds()
    probe.SetOrigin(bounds[0], bounds[2], bounds[4])
    probe.SetSpacing((bounds[1] - bounds[0]) / dims[0],
                     (bounds[3] - bounds[2]) / dims[1],
                     (bounds[5] - bounds[4]) / dims[2])

    # if radius is None:
    #     radius = min(bounds[1]-bounds[0], bounds[3]-bounds[2], bounds[5]-bounds[4])/3

    locator = vtk.vtkPointLocator()
    locator.SetDataSet(output)
    locator.BuildLocator()

    if kernel == 'shepard':
        kern = vtk.vtkShepardKernel()
        kern.SetPowerParameter(2)
    elif kernel == 'gaussian':
        kern = vtk.vtkGaussianKernel()
    elif kernel == 'linear':
        kern = vtk.vtkLinearKernel()
    else:
        print('Error in interpolateToVolume, available kernels are:')
        print(' [shepard, gaussian, linear]')
        raise RuntimeError()

    if radius:
        kern.SetRadius(radius)

    interpolator = vtk.vtkPointInterpolator()
    interpolator.SetInputData(probe)
    interpolator.SetSourceData(output)
    interpolator.SetKernel(kern)
    interpolator.SetLocator(locator)

    if N:
        kern.SetNumberOfPoints(N)
        kern.SetKernelFootprintToNClosest()
    else:
        kern.SetRadius(radius)

    if nullValue is not None:
        interpolator.SetNullValue(nullValue)
    else:
        interpolator.SetNullPointsStrategyToClosestPoint()
    interpolator.Update()
    return Volume(interpolator.GetOutput())
probe.SetSpacing((bounds[1]-bounds[0])/(res-1),
                 (bounds[3]-bounds[2])/(res-1),
                 (bounds[5]-bounds[4])/(res-1))

# Reuse the locator
locator = vtk.vtkStaticPointLocator()
locator.SetDataSet(output)
locator.BuildLocator()

# Use a gaussian kernel------------------------------------------------
gaussianKernel = vtk.vtkGaussianKernel()
gaussianKernel.SetRadius(0.5)
gaussianKernel.SetSharpness(4)
print ("Radius: {0}".format(gaussianKernel.GetRadius()))

interpolator = vtk.vtkPointInterpolator()
interpolator.SetInputData(probe)
interpolator.SetSourceData(output)
interpolator.SetKernel(gaussianKernel)
interpolator.SetLocator(locator)
interpolator.SetNullPointsStrategyToClosestPoint()

# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
interpolator.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Interpolate Points (Volume probe): {0}".format(time))

intMapper = vtk.vtkDataSetMapper()
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
def centerline_probe_result(centerline_file,vtk_file_list, output_dir,minPoint=(0,0,0), bifurcationPoint=(0,0,0)):
	# read centerline
	centerlineReader = vtk.vtkXMLPolyDataReader()
	centerlineReader.SetFileName(centerline_file)
	centerlineReader.Update()
	centerline = centerlineReader.GetOutput()

	# 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 = vtk.vtkTransformFilter()
		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()

		# 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(converter.GetOutput())
		averageFilter.SetInputData(converter.GetOutput())
		averageFilter.Update()

		writer = vtk.vtkXMLPolyDataWriter()
		writer.SetInputData(converter.GetOutput())
		writer.SetFileName(centerline_output_path)
		writer.Update()

	centerline_output_path = os.path.join(
				os.path.dirname(centerline_file),
				output_dir,
				"centerlines",
				"centerline_probe_avg.vtp" 
				)

	writer = vtk.vtkXMLPolyDataWriter()
	writer.SetInputData(averageFilter.GetOutput())
	writer.SetFileName(centerline_output_path)
	writer.Update()

	# plot result
	plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"result.png")
	dev_plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"result_dev.png")

	plot_array = [
		"Radius_average",
		"U_average",
		"p(mmHg)_average",
		"vorticity_average",
		"Curvature_average",
		"Torsion_average"
	]

	fit_dict = plot_centerline_result(
		averageFilter.GetOutput(),
		["U_average","p(mmHg)_average"], 
		#["Radius_average","U_average","p(mmHg)_average","vorticity_average","Curvature_average","Torsion_average"], 
		plot_array, 
		plot_result_path,
		dev_plot_result_path,
		minPoint = minPoint,
		bifurcationPoint = bifurcationPoint)

	# extract ica
	thresholdFilter = vtk.vtkThreshold()
	thresholdFilter.ThresholdBetween(0,999)
	thresholdFilter.SetInputData(averageFilter.GetOutput())
	thresholdFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "CenterlineIds_average")
	thresholdFilter.Update()

	if thresholdFilter.GetOutput().GetNumberOfPoints() == 0 or fit_dict == None:
		tqdm.write("Centerline file {} does not contain suitable number of CenterlineIds".format(centerline_file))
		return_value =  {
			'radius mean(mm)': "NA",
			'max radius gradient':"NA",
			'radius min(mm)': "NA",
			'pressure mean(mmHg)': "NA",
			'max pressure gradient(mmHg)': "NA",
			'in/out pressure gradient(mmHg)': "NA",
			'velocity mean(ms^-1)': "NA",
			'max velocity gradient(ms^-1)': "NA",
			'peak velocity(ms^-1)': "NA",
			'vorticity mean(s^-1)': "NA",
			'peak vorticity(s^-1)': "NA"
			}
	else:
		# compute result values
		abscissas = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average"))
		radius = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Radius_average"))
		pressure = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("p(mmHg)_average"))
		pressure_gradient = np.diff(pressure)/np.diff(abscissas)
		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]
		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]

		return_value = {
			'radius mean(mm)': np.mean(radius),
			'radius min(mm)': np.min(radius),
			'max radius gradient': fit_dict["Radius_average"],
			'pressure mean(mmHg)': np.mean(pressure),
			# 'max pressure gradient(mmHg)': np.mean(heapq.nlargest(5, pressure_gradient)),
			'max pressure gradient(mmHg)': fit_dict["p(mmHg)_average"], 
			'in/out pressure gradient(mmHg)': np.mean(pressure[0:5]) - np.mean(pressure[-5:]),
			'velocity mean(ms^-1)': np.mean(velocity),
			'peak velocity(ms^-1)': np.mean(heapq.nlargest(5, velocity)),
			'max velocity gradient(ms^-1)': fit_dict["U_average"],
			'vorticity mean(s^-1)': np.mean(vorticity),
			'peak vorticity(s^-1)': np.mean(heapq.nlargest(5, vorticity))
		}

	# moving variance matrix
	mv_fields = [
		"Radius_average",
		"U_average",
		"p(mmHg)_average",
		"vorticity_average",
		"Curvature_average",
		"Torsion_average"
		]
	mv_windows = np.arange(3,10,2)
	plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"moving_variance.png")
	dev_plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"moving_variance_dev.png")

	mv_matrix_df, mv_dy_matrix_df = moving_variance_matrix(averageFilter.GetOutput(),mv_fields,mv_windows,
		minPoint = minPoint,
		bifurcationPoint = bifurcationPoint,
		result_path = plot_result_path,
		dev_result_path=dev_plot_result_path)

	return return_value, mv_matrix_df, mv_dy_matrix_df
plane.SetResolution(res, res)
plane.SetOrigin(0, 0, 0)
plane.SetPoint1(10, 0, 0)
plane.SetPoint2(0, 10, 0)
plane.SetCenter(center)
plane.SetNormal(0, 1, 0)

# Reuse the locator
locator = vtk.vtkStaticPointLocator()
locator.SetDataSet(output)
locator.BuildLocator()

# Voronoi kernel------------------------------------------------
voronoiKernel = vtk.vtkVoronoiKernel()

interpolator = vtk.vtkPointInterpolator()
interpolator.SetInputConnection(plane.GetOutputPort())
interpolator.SetSourceData(output)
interpolator.SetKernel(voronoiKernel)
interpolator.SetLocator(locator)

# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
interpolator.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Interpolate Points (Voronoi): {0}".format(time))

intMapper = vtk.vtkPolyDataMapper()
intMapper.SetInputConnection(interpolator.GetOutputPort())
def vtkfile():

    csvfile = './sample.csv'

    colors = vtk.vtkNamedColors()

    points_reader = vtk.vtkDelimitedTextReader()
    points_reader.SetFileName(csvfile)
    points_reader.DetectNumericColumnsOn()
    points_reader.SetFieldDelimiterCharacters(',')
    points_reader.SetHaveHeaders(True)

    table_points = vtk.vtkTableToPolyData()
    table_points.SetInputConnection(points_reader.GetOutputPort())
    table_points.SetXColumn('CentroidX')
    table_points.SetYColumn('CentroidY')
    table_points.SetZColumn('CentroidZ')
    table_points.Update()

    points = table_points.GetOutput()
    points.GetPointData().SetActiveScalars('VelocityMagnitude')
    # range = points.GetPointData().GetScalars().GetRange()

    box = vtk.vtkImageData()
    box.SetDimensions([101, 101, 101])

    gaussian_kernel = vtk.vtkGaussianKernel()
    gaussian_kernel.SetSharpness(2)
    gaussian_kernel.SetRadius(12)

    interpolator = vtk.vtkPointInterpolator()
    interpolator.SetInputData(box)
    interpolator.SetSourceData(points)
    interpolator.SetKernel(gaussian_kernel)

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(interpolator.GetOutputPort())
    # mapper.SetScalarRange(range)

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    # point_mapper = vtk.vtkPointGaussianMapper()
    # point_mapper.SetInputData(points)
    # # point_mapper.SetScalarRange(range)
    # point_mapper.SetScaleFactor(0.6)
    # point_mapper.EmissiveOff()
    # point_mapper.SetSplatShaderCode(
    #     "//VTK::Color::Impl\n"
    #     "float dist = dot(offsetVCVSOutput.xy,offsetVCVSOutput.xy);\n"
    #     "if (dist > 1.0) {\n"
    #     "  discard;\n"
    #     "} else {\n"
    #     "  float scale = (1.0 - dist);\n"
    #     "  ambientColor *= scale;\n"
    #     "  diffuseColor *= scale;\n"
    #     "}\n"
    # )
    #
    # point_actor = vtk.vtkActor()
    # point_actor.SetMapper(point_mapper)

    renderer = vtk.vtkRenderer()
    renWin = vtk.vtkRenderWindow()
    renWin.AddRenderer(renderer)
    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)

    renderer.AddActor(actor)
    # renderer.AddActor(point_actor)
    renderer.SetBackground(colors.GetColor3d("SlateGray"))

    renWin.SetSize(640, 480)
    renWin.SetWindowName('PointInterpolator')

    renderer.ResetCamera()
    renderer.GetActiveCamera().Elevation(-45)

    iren.Initialize()

    renWin.Render()
    iren.Start()
示例#9
0
plane.SetResolution(res,res)
plane.SetOrigin(0,0,0)
plane.SetPoint1(10,0,0)
plane.SetPoint2(0,10,0)
plane.SetCenter(center)
plane.SetNormal(0,1,0)

# Reuse the locator
locator = vtk.vtkStaticPointLocator()
locator.SetDataSet(output)
locator.BuildLocator()

# Voronoi kernel------------------------------------------------
voronoiKernel = vtk.vtkVoronoiKernel()

interpolator = vtk.vtkPointInterpolator()
interpolator.SetInputConnection(plane.GetOutputPort())
interpolator.SetSourceData(output)
interpolator.SetKernel(voronoiKernel)
interpolator.SetLocator(locator)

# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
interpolator.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Interpolate Points (Voronoi): {0}".format(time))

intMapper = vtk.vtkPolyDataMapper()
intMapper.SetInputConnection(interpolator.GetOutputPort())
示例#10
0
probe.SetSpacing((bounds[1] - bounds[0]) / (res - 1),
                 (bounds[3] - bounds[2]) / (res - 1),
                 (bounds[5] - bounds[4]) / (res - 1))

# Reuse the locator
locator = vtk.vtkStaticPointLocator()
locator.SetDataSet(output)
locator.BuildLocator()

# Use a gaussian kernel------------------------------------------------
gaussianKernel = vtk.vtkGaussianKernel()
gaussianKernel.SetRadius(0.5)
gaussianKernel.SetSharpness(4)
print("Radius: {0}".format(gaussianKernel.GetRadius()))

interpolator = vtk.vtkPointInterpolator()
interpolator.SetInputData(probe)
interpolator.SetSourceData(output)
interpolator.SetKernel(gaussianKernel)
interpolator.SetLocator(locator)
interpolator.SetNullPointsStrategyToClosestPoint()

# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
interpolator.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Interpolate Points (Volume probe): {0}".format(time))

intMapper = vtk.vtkDataSetMapper()
示例#11
0
def npInterpolateVTK3D(npPoints,
                       npValues,
                       npTargetPoints,
                       ParametreInterpolatorVTK=None):

    if ParametreInterpolatorVTK == None:
        ParametreInterpolatorVTK = {
            'kernel': 'Gaussian',
            'Radius': 10.,
            'Sharpness': 2.
        }
    print('[' + ParametreInterpolatorVTK['kernel'] +
          ' Interpolation - Radius =' +
          str(ParametreInterpolatorVTK['Radius']) + ' - Sharpness =' +
          str(ParametreInterpolatorVTK['Sharpness']) + '] processing... ')
    #
    # Set Source Points
    UnGrid = vtk.vtkUnstructuredGrid()
    vtkP = vtk.vtkPoints()
    for [x, y, z] in npPoints:
        vtkP.InsertNextPoint(x, y, z)

    UnGrid.SetPoints(vtkP)
    # Set source Point Values
    l, c = npValues.shape
    for i in range(0, c):
        vtkFA = vtk.vtkFloatArray()
        vtkFA.SetName('Values' + str(i))
        for v in npValues:
            vtkFA.InsertNextValue(v[i])
        UnGrid.GetPointData().AddArray(vtkFA)

# Set Target Points

    vtkTP = vtk.vtkPoints()
    for [x, y, z] in npTargetPoints:
        vtkTP.InsertNextPoint(x, y, z)

    vtkTargetPointsPolyData = vtk.vtkPolyData()
    vtkTargetPointsPolyData.SetPoints(vtkTP)

    if ParametreInterpolatorVTK['kernel'] == 'Gaussian':

        Kernel = vtk.vtkGaussianKernel()
        Kernel.SetSharpness(ParametreInterpolatorVTK['Sharpness'])
        Kernel.SetRadius(ParametreInterpolatorVTK['Radius'])

    if ParametreInterpolatorVTK['kernel'] == 'Voronoi':
        Kernel = vtk.vtkVoronoiKernel()

    if ParametreInterpolatorVTK['kernel'] == 'Shepard':
        Kernel = vtk.vtkShepardKernel()
        Kernel.SetRadius(ParametreInterpolatorVTK['Radius'])

# Build locator
    locator = vtk.vtkStaticPointLocator()
    locator.SetDataSet(UnGrid)
    locator.BuildLocator()
    # build interpolator
    interp = vtk.vtkPointInterpolator()
    interp.SetInputData(vtkTargetPointsPolyData)
    interp.SetSourceData(UnGrid)
    interp.SetKernel(Kernel)
    interp.SetLocator(locator)
    interp.GetLocator().SetNumberOfPointsPerBucket(5)
    interp.SetNullPointsStrategyToMaskPoints()

    interp.Update()

    outputInterp = interp.GetOutput()
    pointsArr = outputInterp.GetPoints().GetData()
    nppointsArr = vtk_to_numpy(pointsArr)
    pdata = outputInterp.GetPointData()

    # Convert volocities into Numpy Array

    npOutputValues = np.zeros((len(npTargetPoints), c))

    for i in range(0, c):
        vtkOutputValues = pdata.GetArray('Values' + str(i))
        npOutputValues[:, i] = vtk_to_numpy(vtkOutputValues)

    return npOutputValues
示例#12
0
def main():
    points_fn, probe_fn = get_program_parameters()

    colors = vtk.vtkNamedColors()

    points_reader = vtk.vtkDelimitedTextReader()
    points_reader.SetFileName(points_fn)
    points_reader.DetectNumericColumnsOn()
    points_reader.SetFieldDelimiterCharacters('\t')
    points_reader.SetHaveHeaders(True)

    table_points = vtk.vtkTableToPolyData()
    table_points.SetInputConnection(points_reader.GetOutputPort())
    table_points.SetXColumn('x')
    table_points.SetYColumn('y')
    table_points.SetZColumn('z')
    table_points.Update()

    points = table_points.GetOutput()
    points.GetPointData().SetActiveScalars('val')
    range = points.GetPointData().GetScalars().GetRange()

    # Read a probe surface
    stl_reader = vtk.vtkSTLReader()
    stl_reader.SetFileName(probe_fn)
    stl_reader.Update()

    surface = stl_reader.GetOutput()
    bounds = np.array(surface.GetBounds())

    dims = np.array([101, 101, 101])
    box = vtk.vtkImageData()
    box.SetDimensions(dims)
    box.SetSpacing((bounds[1::2] - bounds[:-1:2]) / (dims - 1))
    box.SetOrigin(bounds[::2])

    # Gaussian kernel
    gaussian_kernel = vtk.vtkGaussianKernel()
    gaussian_kernel.SetSharpness(2)
    gaussian_kernel.SetRadius(12)

    interpolator = vtk.vtkPointInterpolator()
    interpolator.SetInputData(box)
    interpolator.SetSourceData(points)
    interpolator.SetKernel(gaussian_kernel)

    resample = vtk.vtkResampleWithDataSet()
    resample.SetInputData(surface)
    resample.SetSourceConnection(interpolator.GetOutputPort())

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(resample.GetOutputPort())
    mapper.SetScalarRange(range)

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    point_mapper = vtk.vtkPointGaussianMapper()
    point_mapper.SetInputData(points)
    point_mapper.SetScalarRange(range)
    point_mapper.SetScaleFactor(0.6)
    point_mapper.EmissiveOff()
    point_mapper.SetSplatShaderCode(
        "//VTK::Color::Impl\n"
        "float dist = dot(offsetVCVSOutput.xy,offsetVCVSOutput.xy);\n"
        "if (dist > 1.0) {\n"
        "  discard;\n"
        "} else {\n"
        "  float scale = (1.0 - dist);\n"
        "  ambientColor *= scale;\n"
        "  diffuseColor *= scale;\n"
        "}\n")

    point_actor = vtk.vtkActor()
    point_actor.SetMapper(point_mapper)

    renderer = vtk.vtkRenderer()
    renWin = vtk.vtkRenderWindow()
    renWin.AddRenderer(renderer)
    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)

    renderer.AddActor(actor)
    renderer.AddActor(point_actor)
    renderer.SetBackground(colors.GetColor3d('SlateGray'))

    renWin.SetSize(640, 480)
    renWin.SetWindowName('PointInterpolator')

    renderer.ResetCamera()
    renderer.GetActiveCamera().Elevation(-45)

    iren.Initialize()

    renWin.Render()
    iren.Start()
示例#13
0
def apply_displacement_to_mesh(mesh: Union[vtk.vtkDataObject, str],
                               field: Union[vtk.vtkStructuredGrid, str],
                               save_mesh: Union[bool, str] = False,
                               disp_array_name: str = 'estimatedDisplacement'):
    """Apply a displacement field to a mesh.
    The displacement field is stored as an array within a vtkStructuredGrid.

    :param mesh: Mesh to deform, can either be path to file or vtk object.
    :type mesh: Union[vtk.vtkDataObject, str]
    :param field: Grid containing displacement field, can either be path \
        to file or vtk object.
    :type field: Union[vtk.vtkStructuredGrid, str]
    :param save_mesh: If a file name is passed, the deformed mesh is saved \
        to disk, defaults to False
    :type save_mesh: Union[bool, str], optional
    :param disp_array_name: Name of array within vtkStructuredGrid containing \
        the displacement field, defaults to 'estimatedDisplacement'
    :type disp_array_name: str, optional
    :return: Displaced mesh
    :rtype: vtk.vtkPolyData
    """

    if isinstance(mesh, str):
        mesh = load_points_from_file(mesh)
    if isinstance(field, str):
        field = load_structured_grid(field)

    # In case the field data was transformed, also transform the test data:
    scale = 1  # default
    try:
        tf = loadTransformationMatrix(field)
        tf.Inverse()
        LOGGER.debug("Applying transform")
        tfFilter = vtk.vtkTransformFilter()
        tfFilter.SetTransform(tf)
        tfFilter.SetInputData(field)
        tfFilter.Update()
        field = tfFilter.GetOutput()

        # Apply transformation also to all vector fields:
        applyTransformation(field, tf)

        scale = tf.GetMatrix().GetElement(0, 0)

    #pylint:disable=broad-except
    except Exception as e:
        print(e)
        print("Could not find or apply transformation. Skipping.")

    # Threshold to ignore all points outside of field i.e.
    # Points outside of the model:
    threshold = vtk.vtkThreshold()
    threshold.SetInputArrayToProcess(
        0,
        0,
        0,
        vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS,
        "preoperativeSurface")
    threshold.ThresholdByLower(0)
    threshold.SetInputData(field)
    threshold.Update()
    fieldInternal = threshold.GetOutput()

    # Interpolate displacement field to points on mesh
    kernel = vtk.vtkGaussianKernel()
    kernel.SetRadius(0.01 * scale)
    kernel.SetKernelFootprintToRadius()

    interpolator = vtk.vtkPointInterpolator()
    interpolator.SetKernel(kernel)
    interpolator.SetNullPointsStrategyToMaskPoints()
    interpolator.SetValidPointsMaskArrayName("validInternalPoints")

    interpolator.SetSourceData(fieldInternal)
    interpolator.SetInputData(mesh)
    interpolator.Update()
    output = interpolator.GetOutput()

    # Actually displace the points in the mesh by adding the displacement
    # to the point coordinates
    displaced_points = vtk.vtkPoints()
    for i in range(output.GetNumberOfPoints()):
        p = output.GetPoint(i)
        displaced_points.InsertNextPoint(p)

    validInternalPoints = output.GetPointData().GetArray("validInternalPoints")

    displacement = output.GetPointData().GetArray(disp_array_name)

    np_disp = numpy_support.vtk_to_numpy(displacement)
    np_vip = numpy_support.vtk_to_numpy(validInternalPoints)

    for i in range(output.GetNumberOfPoints()):
        validity = validInternalPoints.GetTuple1(i)

        if validity > 0.5:

            p = output.GetPoint(i)
            p = np.asarray(p)
            d = displacement.GetTuple3(i)
            d = np.asarray(d)
            p_d = p + d

            displaced_points.SetPoint(i, p_d[0], p_d[1], p_d[2])

    output.SetPoints(displaced_points)

    if save_mesh:
        writer = vtk.vtkXMLPolyDataWriter()
        writer.SetInputData(output)
        writer.SetFileName(save_mesh)
        writer.Update()

    # Undo transformation so that field is 'reset' for future use
    tf = loadTransformationMatrix(field)
    LOGGER.debug("Reversing transform")
    tfFilter = vtk.vtkTransformFilter()
    tfFilter.SetTransform(tf)
    tfFilter.SetInputData(field)
    tfFilter.Update()
    field = tfFilter.GetOutput()

    # Apply transformation also to all vector fields:
    applyTransformation(field, tf)

    return output
示例#14
0
    def interpolate_data(self, points, disp, stretch=None, shear=None, on_deformed=True, kernel_radius=3.0,
                         kernel_sharpness=1.0, remove_null=True, return_deformed=True):

        """
        Interpolate data on the mesh. This can be used for comparing experimental and simulation data together.
        on_deform selects whether to interpolate the data on the original or on the deformed configuration
        """

        if stretch is None:
            stretch = np.array([])

        if shear is None:
            shear = np.array([])

        # We need nPts*3 data for vtk
        if points.shape[1] == 2:
            points_ = np.zeros([points.shape[0], 3])

        points_[:,0:2] = points

        # Deform data if needed
        if on_deformed:
            points_[:,0:2] = points + disp

        # Generate vtk points structure with all data
        vtkpoints = vtk.vtkPoints()
        vtkpoints.SetData(numpy_support.numpy_to_vtk(points_))

        vtkdisp = vtk.vtkDoubleArray()
        vtkdisp.SetName("disp")
        vtkdisp.SetNumberOfComponents(disp.shape[1])
        vtkdisp.SetNumberOfTuples(disp.shape[0])
        vtkdisp.SetVoidArray(disp.flatten(), disp.size, 1)

        vtkstretch = vtk.vtkDoubleArray()
        vtkstretch.SetName("stretch")
        vtkstretch.SetNumberOfComponents(1)
        vtkstretch.SetNumberOfTuples(stretch.size)
        vtkstretch.SetVoidArray(stretch, stretch.size, 1)

        shear = shear.reshape([-1, 4])
        vtkshear = vtk.vtkDoubleArray()
        vtkshear.SetName("shear")
        vtkshear.SetNumberOfComponents(shear.shape[1])
        vtkshear.SetNumberOfTuples(shear.shape[0])
        vtkshear.SetVoidArray(shear, shear.size, 1)

        vtkpointset = vtk.vtkPolyData()
        vtkpointset.SetPoints(vtkpoints)
        vtkpointset.GetPointData().AddArray(vtkdisp)
        vtkpointset.GetPointData().AddArray(vtkstretch)
        vtkpointset.GetPointData().AddArray(vtkshear)

        # Build the locator for the interpolation
        locator = vtk.vtkStaticPointLocator()
        locator.SetDataSet(vtkpointset)
        locator.BuildLocator()

        # Build the Gaussian kernel
        kernel = vtk.vtkGaussianKernel()
        kernel.SetKernelFootprint(0)
        kernel.SetRadius(kernel_radius)
        kernel.SetSharpness(kernel_sharpness)

        # If the interpolation is performed on the deformed configuration, warp the data
        if on_deformed:
            disp_ = np.zeros(self.x_nodes.shape)
            disp_[:,0:2] = self.disp

            warpData = vtk.vtkDoubleArray()
            warpData.SetName("warp")
            warpData.SetNumberOfComponents(3)
            warpData.SetNumberOfTuples(self.x_nodes.shape[0])
            warpData.SetVoidArray(disp_, self.x_nodes.shape[0], 1)

            self.vtkmesh.GetPointData().AddArray(warpData)
            self.vtkmesh.GetPointData().SetActiveVectors(warpData.GetName())

            warpVector = vtk.vtkWarpVector()
            warpVector.SetInputData(self.vtkmesh)
            warpVector.Update()

            self.vtkmesh = warpVector.GetOutput()

        coarseInterpolator = vtk.vtkPointInterpolator()
        coarseInterpolator.SetSourceData(vtkpointset)
        coarseInterpolator.SetInputData(self.vtkmesh)
        coarseInterpolator.SetKernel(kernel)
        coarseInterpolator.SetLocator(locator)
        coarseInterpolator.PassPointArraysOff()
        coarseInterpolator.SetNullPointsStrategyToMaskPoints() # Get points with an invalid interpolation
        coarseInterpolator.Update()

        vtkmesh = coarseInterpolator.GetOutput()

        if return_deformed:
            self.x_nodes[:,0:2] += self.disp

        self.disp = numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray("disp"))
        self.stretch = numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray("stretch"))
        self.shear = numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray("shear"))

        if remove_null:
            not_null = (numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray(
                coarseInterpolator.GetValidPointsMaskArrayName()))).astype(bool)

            idlist_old = np.arange(self.x_nodes.shape[0])[not_null]

            self.x_nodes = self.x_nodes[not_null]
            self.disp = self.disp[not_null]
            self.stretch = self.stretch[not_null]
            self.shear = self.shear[not_null]

            idlist_new = np.arange(self.x_nodes.shape[0])

            c1 = np.in1d(self.connec[:, 0], idlist_old)
            c2 = np.in1d(self.connec[:, 1], idlist_old)
            c3 = np.in1d(self.connec[:, 2], idlist_old)
            self.connec = self.connec[np.logical_and(np.logical_and(c1,c2),c3)]

            for i in idlist_new:
                self.connec[self.connec == idlist_old[i]] = i

            points = vtk.vtkPoints()
            points.SetData(numpy_support.numpy_to_vtk(self.x_nodes))
            vtkmesh.SetPoints(points)

            cells = vtk.vtkCellArray()
            cells.SetCells(self.connec.shape[0], numpy_support.numpy_to_vtkIdTypeArray(self.connec))
            vtkmesh.SetPolys(cells)

        self.shear = self.shear.reshape([-1, 2, 2])