Drilling Down

ParaView 2 was almost entirely a qualitative analysis tool. It was very good at drawing pictures of large scientific data sets so that you could view the data and tell if it looked "right", but it was not easy to use for finding hard quantitative information about the data and verifying that that was the case. The recommended use was to use ParaView to visualize, interact with and subset your data and then export the result into a format that could be imported by a different tool. A major goal of ParaView 3 has been to add quantitative analysis capabilities to turn it into a convenient and comprehensive tool in which you can visualize, interact with and drill all the way down into the data.

These capabilities vary from semi-qualitative ones such as the Ruler source and Cube Axis representation (see Users_Guide_Annotation) to Selection which allows you to define and extract arbitrary subsets of the data based, to the spreadsheet view which presents the data in textual form. Taken together with features like the statistical analysis filters ParaView/Users_Guide/List_of_filters#Descriptive_Statistics, calculator filters, 2D plot and chart views and programmable filters (which give you the ability to run arbitrary code on the server and have access to every data point) these give you the ability to inspect the data at from the highest level view all the way down to the hard numbers.

In this chapter we describe the various tools that ParaView gives you to support quantitative analysis.

Python Programmable Filter

Introduction

The Programmable Filter is a ParaView filter that processes one or more input datasets based on a Python script provided by the user. The parameters of the filter include the output data type, the script and a toggle that controls whether the input arrays are copied to the output. In this document, we introduce the use of the Programmable Filter and give a summary of the API available to the user.

Note that the Programmable Filter depends on Python. All ParaView binaries distributed by Kitware are built with Python enabled. If you have built ParaView yourself, you have to make sure that PARAVIEW_ENABLE_PYTHON is turned on when configuring the ParaView build.

Since the entire VTK API as well as any module that can be imported through Python is available through this filter, we can only skim the surface of what can be accomplished with this filter here. If you are not familiar with Python, we recommend first taking a look at one of the introductory guides such as the official Python Tutorial. Also, if you are going to do any programming beyond the very basic stuff, we recommend reading up on the VTK API. The VTK website has links to VTK books and online documentation. For reference, you may need to look at the VTK class documentation. There is also more information about the Programmable Filter and some good recipes on the ParaView Wiki (Python_Programmable_Filter).

Basic Use

Requirements:

1. You are applying Programmable Filter to a "simple" dataset and not a composite dataset such as multi-block or AMR.

2. You have NumPy installed.

The most basic reason to use the Programmable Filter is to add a new array by possible deriving it from arrays in the input. This can be achieved by using the Python Calculator. One reason to use the Programmable Filter instead may be that the calculation is more involved and trying to do it in one expression may be difficult. Another reason may be that you need access to a program flow construct such as if or for. In any case. the Programmable Filter can be used to do everything the Calculator does and more.

Note: Since what we describe here builds on some of the concepts introduced in the Python Calculator section, please read it first if you are not familiar with the Calculator.

If you leave the "Output Dataset Type" parameter in the default setting of "Same as Input", the Programmable Filter will copy the topology and geometry of the input to the output before calling your Python script. Therefore, if you Apply the filter without filling the script, you should see a copy of the input without any of its arrays in the output. If you also check the "Copy Arrays" option, the output will have all of the input arrays. This behavior allows you to focus on creating new arrays without worrying about the mesh.

Let's try an example. Create a Sphere source and then apply the Programmable Filter. Use the following script.

normals = inputs[0].PointData['Normals']
output.PointData.append(normals[:,0], "Normals_x")

This should create a sphere with on array called "Normals_x". There a few things to note here:

- You cannot refer to arrays directly by name as in the Python Calculator. You need to access arrays using the .PointData and .CellData qualifiers.

- Unlike the Python Calculator, you have to explicitly add an array to the output using the append function. Note that this function takes the name of the array as the second argument.

You can use any of the functions available in the Calculator in the Programmable Filter. For example, the following code creates two new arrays and adds them to the output.

normals = inputs[0].PointData['Normals']
output.PointData.append(sin(normals[:,0]), "sin of Normals_x")
output.PointData.append(normals[:,1] + 1, "Normals_y + 1")

Intermediate Use

Mixing VTK and NumPy APIs

The examples above demonstrate how the Programmable Filter can be used as an advanced Python Calculator. However, the full power of the Programmable Filter can only be harnessed by using the VTK API. Let's start with a simple example. Create a Sphere source and apply the Programmable Filter with the following script.

input = inputs[0]
newPoints = vtk.vtkPoints()
numPoints = input.GetNumberOfPoints()
for i in range(numPoints):
x, y, z = input.GetPoint(i)
newPoints.InsertPoint(i, x, y, 1 + z*0.3)
output.SetPoints(newPoints)

This requires some explanation. We start with creating a new instance of vtkPoints.

newPoints = vtk.vtkPoints()

vtkPoints is a data structure that VTK uses to store the coordinates of points. Next, we loop over all points of the input and insert a new point in the output with coordinates (x, y, 1+z*0.3)

for i in range(numPoints):
x, y, z = input.GetPoint(i)
newPoints.InsertPoint(i, x, y, 1 + z*0.3)

Finally, we replace the output points with the new points we created using the following.

output.SetPoints(newPoints)

Note: Python is an interpreted language and Python scripts do not execute as efficiently as compiled C++ code. Therefore, using a for loop that iterates over all points or cells may be a significant bottleneck when processing large datasets.

The NumPy and VTK APIs can be mixed to achieve good performance. Even though this may seem a bit complicated at first, it can be used with great effect. For example, the example above can be rewritten as follows.

from paraview.vtk.dataset_adapter import numpyTovtkDataArray
input = inputs[0]
newPoints = vtk.vtkPoints()
zs = 1 + input.Points[:,2]*0.3
coords = hstack([input.Points[:,0:2],zs])
newPoints.SetData(numpyTovtkDataArray(coords))
output.SetPoints(newPoints)

Even though this produces exactly the same result, it is much more efficient because we eliminated the for loop. Well, we didn't really eliminate it. We rather moved it from Python to C. Under the hood, NumPy uses C and Fortran for tight loops.

If you read the Python Calculator documentation, this example is pretty straightforward except the use of numpyTovtkDataArray(). First of all, note that we are mixing two APIs here: the VTK API and NumPy. VTK and NumPy uses different types of objects to represents arrays. The basic examples we previously used carefully hide this from you. However, once you start manipulating VTK objects using NumPy, you have to start converting objects between two APIs. Note that for the most part this conversion happens without "deep copying" arrays, e.g. copying the raw contents from one memory location to another. Rather, pointers are passed between VTK and NumPy whenever possible.

The dataset_adapter provides two methods to do the conversions described above:

- vtkDataArrayToVTKArray: This function create a NumPy compatible array from a vtkDataArray. Note that VTKArray is actually a subclass of numpy.matrix and can be used anywhere matrix can be used. This function always copies the pointer and not the contents. Important: You should not directly change the values of the resulting array if the argument is an array from the input.

- numpyTovtkDataArray: Converts a NumPy array (or a VTKArray) to a vtkDataArray. This function copies the pointer if the argument is a contiguous array. There are various ways of creating discontinuous arrays with NumPy including using hstack and striding. See NumPy documentation for details.

Multiple Inputs

Like the Python Calculator, the Programmable Filter can accept multiple inputs. First select two or more pipeline objects in the pipeline browser and then apply the Programmable Filter. Then each input can be accessed using the inputs[] variable. Note that if the Output Dataset Type is set to Same as Input, the filter will copy the mesh from the first input to the output. If Copy Arrays is on, it will also copy arrays from the first input. As an example, the following script compares the Pressure attribute from two inputs using the difference operator.

output.append(inputs[1].PointData['Pressure'] - inputs[0].PointData['Pressure'], "difference")

Dealing with Composite Datasets

So far, none of the example we used apply to multi-block or AMR datasets. When talking about the Python Calculator, we did not have to differentiate between simple and composite datasets. This is because the calculator loops over all of the leaf blocks of composite datasets and applies the expression to each one. Therefore, inputs in an expression are guaranteed to be simple datasets. On the other hand, the Programmable Filter does not perform this iteration and passes the input, composite or simple, as it is to the script. Even though this makes basic scripting harder for composite datasets, it provides enormous flexibility.

The only thing that you have to know to work with composite datasets is how to iterate over them to access the leaf nodes. Let's start with a simple example.

for block in inputs[0]:
print block

Here we iterate over all of the non-NULL leaf nodes (i.e. simple datasets) of the input and print them to the Output Messages console. Note that this will work only if the input is multi-block or AMR.

Note that when Output Dataset Type is set to "Same as Input", the Programmable Filter will copy composite dataset to the output - it will copy only the mesh unless Copy Arrays is on. Therefore, you can also iterate over the output. A simple trick is to turn on Copy Arrays and then use the arrays from the output when generating new ones. Below is an example. We use the can.ex2 file from the ParaView testing dataset collection.

def process_block(block):
displ = block.PointData['DISPL']
block.PointData.append(displ[:,0], "displ_x")
for block in output:
process_block(block)

Alternatively, you can use the MultiCompositeDataIterator to iterate over the input and output block simultaneously. The following is equivalent to the previous example.

def process_block(input_block, output_block):
displ = input_block.PointData['DISPL']
output_block.PointData.append(displ[:,0], "displ_x")
from paraview.vtk.dataset_adapter import MultiCompositeDataIterator
iter = MultiCompositeDataIterator([inputs[0], output])
for input_block, output_block in iter:
process_block(input_block, output_block)

Advanced (but read it anyway)

Changing Output Type

So far, all of the examples we discussed depended on that the output type being the same as input and that the Programmable Filter copied the input mesh to the output. If we set the output type to something other than Same as Input, we are on own: the Programmable Filter will create an empty output of the type we specified but will not copy any information. Even though it may be more work, this gives us a lot of flexibility. Since we are approaching the realm of full-blown VTK filter authoring, we will pick a very simple example here. If you are already familiar with VTK API, you will realize that this is a great way of prototyping VTK filters. If you are not, reading up on VTK is a good idea.

Create a Wavelet source, apply a Programmable Filter, set the output type to vtkTable and use the following script:

rtdata = inputs[0].PointData['RTData']
output.RowData.append(min(rtdata), 'min')
output.RowData.append(max(rtdata), 'max')

Here, we added two columns to the output table. First one has one value - minimum of RTData - and the second one has the maximum of RTData. When you apply this filter, the output should automatically be shown in a Spreadsheet view. We could also use this sort of script to chart part of our input data. For example, the output of the following script can be display as a line chart.

rtdata = inputs[0].PointData['RTData']
output.RowData.append(rtdata, 'rtdata')

Changing the output type is also often necessary when using VTK filters within the script. We will demonstrate how to do that in the following section.

Dealing with Structured Data Output

Let's say that we have a curvilinear grid. A good example is bluntfin.vts from the ParaView testing data. We would like to volume render a subset of this grid. As of 3.10, ParaView does not support volume rendering of curvilinear grids so we have two choices:

- Resample to an image data

- Convert to unstructured grid

Here we will demonstrate how to resample to an image data using the Programmable Filter. Of course, this can be accomplished using the Resample with Dataset filter but it is a good example nevertheless. Start with loading bluntfin.vts, then apply the Programmable Filter. Make sure to set the output type to vtkImageData. Here is the script:

pinput = vtk.vtkImageData()
pinput.SetExtent(0, 10, 0, 10, 0, 10)
pinput.SetOrigin(0, 1, 0)
pinput.SetSpacing(0.5, 0.5, 0.5)
probe = vtk.vtkProbeFilter()
probe.SetInput(pinput)
input_copy = inputs[0].NewInstance()
input_copy.UnRegister(None)
input_copy.ShallowCopy(inputs[0].VTKObject)
probe.SetSource(input_copy)
probe.Update()
output.ShallowCopy(probe.GetOutput())

Note: See the next section for details about using a VTK filter within the Programmable Filter.

If you already applied, you may notice that the output looks much bigger than it should be. This is because we are missing an important piece. We need to use the following as the RequestInformation script:

from paraview.util import SetOutputWholeExtent
SetOutputWholeExtent(self, [0, 10, 0, 10, 0, 10])

This requires a bit of explanation. VTK expects that all data sources and filters that produce structured data (rectilinear or curvilinear grids) to provide meta data about the logical extents of the output dataset before full execution. Thus the RequestInformation is called by the Programmable Filter before execution and is where you should provide this meta-data. This is not required if the filter is simply copying the mesh as the meta-data would have been provided by another pipeline object upstream. However, if you are using the Programmable Filter to produce a structured data with a different mesh than the input, you need to provide this information.

You are probably wondering what the RequestUpdateExtent script does. This script can be used to augment the request that propagates upstream before execution. This is used to ask for a specific data extent, for example. This is an advanced concept and is not discussed further here.

Using VTK Filters with Programmable Filter

The previous example demonstrated how you can use a VTK filter (vtkProbeFilter in this case) from with the Programmable Filter. We will explain that example in more detail here. Here it is again.

pinput = vtk.vtkImageData()
pinput.SetExtent(0, 10, 0, 10, 0, 10)
pinput.SetOrigin(0, 1, 0)
pinput.SetSpacing(0.5, 0.5, 0.5)
probe = vtk.vtkProbeFilter()
probe.SetInput(pinput)
input_copy = inputs[0].NewInstance()
input_copy.UnRegister(None)
input_copy.ShallowCopy(inputs[0].VTKObject)
probe.SetSource(input_copy)
probe.Update()
output.ShallowCopy(probe.GetOutput())

There are two important tricks to use a VTK filter from another VTK filter. First, do not directly set the input to the outer filter as the input of the inner filter. It is difficult to explain why without getting into VTK pipeline mechanics so please take our word for it. Instead, make a shallow copy as follow.

input_copy = inputs[0].NewInstance()
input_copy.UnRegister(None)
input_copy.ShallowCopy(inputs[0].VTKObject)

The UnRegister() call is essential to avoid memory leaks.

The second trick is to use ShallowCopy() to copy the output of the internal filter to the output of the outer filter as follows.

output.ShallowCopy(probe.GetOutput())

This should be enough to get you started. There are a large number of VTK filters so it is not possible to describe them here. Refer to the VTK documentation for more information.

Calculator

Basics

The Calculator Filter can be use to calculate derived quantities from existing attributes. The main parameter of the Calculator is an expression that describes how to calculate the derived quantity. You can enter this expression as free-form text or using some of the shortcuts (buttons and menus provided). There are some "hidden" expressions for which there are no buttons. Operands that are accessible only by typing in the function name include:

- min(expr1, expr2)

- returns the lesser of the two scalar expressions

- max(expr1, expr2)

- returns the greater of the two scalar expressions

- cross(expr1, expr2)

- returns the vector cross product of the two vector expressions

- sign(expr)

- returns -1, 0 or 1 depending if the scalar expression is less than, equal to or greater than zero respectively

- if(condition,true_expression,false_expression)

- evaluates the conditional expression and then evaluates and returns one of the two expressions

- > : numerical "greater than" conditional test

- < : numerical "less than" conditional test

- = : numerical "equal to" conditional test

- & : boolean "and" test conjunction

- | : boolean "or" test conjunction

Here we describe various options available within the Calculator.

Note: We recommend that you use the Python Calculator instead of Calculator if possible. The Python Calculator is more flexible, has more functions and is more efficient. However, it requires that ParaView is compiled with Python support and that NumPy is installed.

Let's start with a simple example. Create a Wavelet source and then apply the Calculator using "1" as the expression. Note: You can enter an expression by clicking in the expression entry box and typing. This should create an point array called "Result" in the output. A few things to note:

- The Calculator copies the input mesh to the output. It is possible to have the calculator to change the point coordinates. We will discuss this later.

- The expression is calculated for each element in the output point or cell data (depending on the Attribute Mode).

Next, change the expression to be "5 * RTData" and the Result Array Name to be "5 times rtdata" (without the quotes). If you change to surface representation and color by the new array, you will notice that the filter calculated "5 * RTData" at each point.

The main use case for the Calculator is to utilize one or more input arrays to calculate derived quantities. The Calculator can either work on point centered attributes or cell centered attributes (but not both). In order to help enter the names of the input arrays, the Calculator provides two menus accessible through the "Scalars" and "Vectors" buttons. If you select an array name from either menus, it will be inserted to the expression entry box at the cursor location. You can also use the other buttons to enter any of the functions available to the Calculator. Most of these functions are obvious. We will cover the ones that are not below.

Working with Vectors

Let's start with an example. Create a Wavelet source then apply the Random Vectors filter. Next, apply the Calculator. Now look at the Scalars and Vectors menus on the Object Inspector panel. You will notice that BrownianVectors shows up under Vectors, whereas BrownianVectors_X, _Y and _Z show up under scalars. The Calculator allows access to individual components of vectors using this naming convention. So if we use BrownianVectors_X as the expression, the Calculator will extract the first component of the BrownianVectors attribute. All of the Calculator's functions are applicable to vectors. Most of these functions treat the vector attributes same as scalars, mainly apply the same functions to all components of all elements. However, the following functions work only on vectors:

- v1 . v2 : Dot product of two vectors. Returns a scalar.

- norm : Creates a new array which contains normalized versions of the input vectors.

- mag : Returns the magnitude of input vectors.

You may have noticed that 4 calculator buttons on the Object Inspector are not actually functions. Clear is straightforward. It cleans the expression entry box. iHat, jHat and kHat on the other hand are not as clear. These represent unit vectors in X, Y and Z directions. They can be used to construct vectors from scalars. Let's consider a simple but common use case. We want to set the Z component of BrownianVectors from the previous example to 0. The expression to do that is "BrownianVectors_X *iHat+BrownianVectors_Y*jHat+0*kHat". This expression multiplies the X unit vector with the X component of the input vector, the Y unit vector with the Y component, and the Z unit vector with 0 and add them together. You can use this sort of expression to create vectors from individual components of a vector if the reader loaded them separately, for example. Note: We didn't really need the 0*kHat bit. It was for demonstration.

Working with Point Coordinates

You may have noticed that one point-centered vector and its 3 components are always available in the Calculator. This vector is called "coords" and represents the point coordinates. You can use this array in your expression like any other array. For example, in our example above, we could use "mag(coords)*RTData" to scale RTData with the distance of the point to the origin.

It is also possible to change the coordinates of the mesh by checking the "Coordinate Results" box. Note that this does not work for rectilinear grids (uniform and non-uniform) since their point coordinates cannot be adjusted one-by-one. Since our previous examples used a uniform rectilinear grid, we cannot use them. Instead, start with the Sphere source, then use this expression: "coords+2*iHat". Make sure to check he "Coordinate Results" box. The output of the Calculator should be a shifted version of the input sphere.

Dealing with Invalid Results

Certain functions are not applicable to certain arguments. For example, sqrt() works only on positive numbers since the calculator does not support complex numbers. Unless the "Replace invalid results" option is turned on, an expression that tries to evaluate the square root of a negative number will return an error such as this:

ERROR: In /Users/berk/Work/ParaView/git/VTK/Common/vtkFunctionParser.cxx, line 697vtkFunctionParser (0x128d97730): Trying to take a square root of a negative value

However, if you turn on the "Replace invalid results" option, the calculator will silently replace the result of the invalid expression with the value specified in "Replacement value". Note that this will happen only when the expression result in an invalid result so some of the output points (or cells) may have the Replacement Value whereas others may have valid results.

Python Calculator

Introduction

The Python Calculator is a ParaView filter that processes one or more input arrays based on an expression provided by the user to produce a new output array. The parameters of the filter include the expression, the association of the output array (Point or Cell Data), the name of output array and a toggle that controls whether the input arrays are copied to the output. In this document, we introduce the use of the Python Calculator and provide a list of functions available to the user.

Note that the Python Calculator depends on Python and NumPy. All ParaView binaries distributed by Kitware are built with these to enable the calculator. If you have built ParaView yourself, you have to make sure that NumPy is installed and that PARAVIEW_ENABLE_PYTHON is turned on when configuring the ParaView build.

Basic Tutorial

Start by creating a Sphere source and applying the Python Calculator to it. As the first expression, use the following and apply:

5

This should create an array name "result" in the output point data. Note that this is an array that has a value of 5 for each point. When the expression results in a single value, the calculator will automatically make an constant array. Next, try the following:

Normals

Now the "result" array should be the same as the input array Normals. As described in detail later, various functions are available through the calculator. For example, the following is a valid expression.

sin(Normals) + 5

It is very important to note that the Python Calculator has to produce one value per point or cell depending on the Array Association parameter. Most of the functions described here apply individually to all point or cell values and produce an array as the same dimensions as the input. However, some of them (such as min() and max()) produce single values.

Accessing Data

There are several ways of accessing input arrays within expressions. The simplest way is to access it by name:

sin(Normals) + 5

This is equivalent to:

sin(inputs[0].PointData['Normals']) + 5

The example above requires some explanation. Here inputs[0] refer to the first input (dataset) to the filter. Python Calculator can accept multiple inputs. Each input can be accessed as inputs[0], inputs[1], ... You can access the point or cell data of an input using the .PointData or .CellData qualifiers. You can then access individual arrays within the point or cell data containers using the [] operator. Make sure to use quotes or double-quotes around the array name. NOTE: Arrays that have names with certain characters (such as space, +, -, *, /) in their name can only be accessed using this method.

Certain functions apply directly on the input mesh. These filters expect an input dataset as argument. For example,

area(inputs[0])

For data types that explicitly define the point coordinates, you can access the coordinates array using the .Points qualifier. The following extracts the first component of the coordinates array:

inputs[0].Points[:,0]

Note that certain data types, mainly image data (uniform rectilinear grid) and rectilinear grid, point coordinates are defined implicitly and cannot be accessed as an array.

Comparing Multiple Datasets

As described above, the Python Calculator can accept multiple inputs. Using this functionality, you can compare multiple datasets. There are a few things to note:

- Python Calculator will always copy the mesh from the first input to its output,

- All operations are applied point by point. In most cases, this requires that the input meshes (topology and geometry) are the same. At the least, it requires the the inputs have the same number of points or cells

- In parallel execution mode, the inputs have to be distributed exactly the same way across processes

For example, to compare the temperature of 2 datasets, you can select both inputs, apply the Python Calculator and then use the following expression.

inputs[0].PointData['temperature'] - inputs[1].PointData['temperature']

Basic Operations

The Python calculator supports all of the basic arithmetic operations using the +, -, * and / operators. These are always applied element-by-element to point and cell data including scalars, vectors and tensors. These operations also work with single values. For example, the following adds 5 to all components of all Normals.

Normals + 5

The following adds 1 to the first component, 2 to the second component and 3 to the third component:

Normals + [1,2,3]

This is specially useful when mixing functions that return single values. For example, the following normalizes the Normals array:

(Normals - min(Normals))/(max(Normals) - min(Normals))

A common use case in a calculator is to work on one component of an array. This can be accomplished with the following:

Normals[:, 0]

The expression above extracts the first component of the Normals vector. Here, : is a placeholder for "all elements". One element can be extracted by replacing : with an index. For example, the following creates an constant array from the first component of the normal of the first point:

Normals[0, 0]

Whereas the following, assigns the normal of the first point to all points:

Normals[0, :]

It is also possible to merge multiple scalars into on array. For this, we can use the hstack() function:

hstack([velocity_x, velocity_y, velocity_z])

Note the use of square brackets ([]).

Under the cover, the Python Calculator uses NumPy. All arrays in the expression are compatible with NumPy arrays and can be used where NumPy arrays can be used. For more information on what you can do with these arrays, consult with the NumPy book, which can be downloaded here.

Functions

The following is a list of functions available in the Python Calculator. Note that this list is partial since most of the NumPy and SciPy functions can be used in the Python Calculator. Many of these functions can take single values or arrays as argument.

abs (x) : Returns the absolute value(s) of x.

add (x, y): Returns the sum of two values. x and y can be single values or arrays. Same as x+y.

area (dataset) : Returns the surface area of each cell in a mesh.

aspect (dataset) : Returns the aspect ratio of each cell in a mesh.

aspect_gamma (dataset) : Returns the aspect ratio gamma of each cell in a mesh.

condition (dataset) : Returns the condition number of each cell in a mesh.

cross (x, y) : Return the cross product for two 3D vectors from two arrays of 3D vectors.

curl (array): Returns the curl of an array of 3D vectors.

divergence (array): Returns the divergence of an array of 3D vectors.

divide (x, y): Element by element division. x and y can be single values or arrays. Same as x/y.

det (array) : Returns the determinant of an array of 2D square matrices.

determinant (array) : Returns the determinant of an array of 2D square matrices.

diagonal (dataset) : Returns the diagonal length of each cell in a dataset.

dot (a1, a2): Returns the dot product of two scalars/vectors of two array of scalars/vectors.

eigenvalue (array) : Returns the eigenvalue of an array of 2D square matrices.

eigenvector (array) : Returns the eigenvector of an array of 2D square matrices.

exp (x): Returns power(e, x).

global_max(array): Returns the maximum value of an array of scalars/vectors/tensors among all process. Not yet supported for multi-block and AMR datasets.

global_mean (array) : Returns the mean value of an array of scalars/vectors/tensors among all process. Not yet supported for multi-block and AMR datasets.

global_min(array): Returns the minimum value of an array of scalars/vectors/tensors among all process. Not yet supported for multi-block and AMR datasets.

gradient(array): Returns the gradient of an array of scalars/vectors.

inv (array) : Returns the inverse an array of 2D square matrices.

inverse (array) : Returns the inverse of an array of 2D square matrices.

jacobian (dataset) : Returns the jacobian of an array of 2D square matrices.

laplacian (array) : Returns the jacobian of an array of scalars.

ln (array) : Returns the natural logarithm of an array of scalars/vectors/tensors.

log (array) : Returns the natural logarithm of an array of scalars/vectors/tensors.

log10 (array) : Returns the base 10 logarithm of an array of scalars/vectors/tensors.

max (array): Returns the maximum value of the array as a single value. Note that this function returns the maximum within a block for AMR and multi-block datasets, not across blocks/grids. Also, this returns the maximum within each process when running in parallel.

max_angle (dataset) : Returns the maximum angle of each cell in a dataset.

mag (a) : Returns the magnigude of an array of scalars/vectors.

mean (array) : Returns the mean value of an array of scalars/vectors/tensors.

min (array) : Returns the minimum value of the array as a single value. Note that this function returns the minimum within a block for AMR and multi-block datasets, not across blocks/grids. Also, this returns the minimum within each process when running in parallel.

min_angle (dataset) : Returns the minimum angle of each cell in a dataset.

mod (x, y): Same as remainder (x, y).

multiply (x, y): Returns the product of x and y. x and y can be single values or arrays. Note that this is an element by element operation when x and y are both arrays. Same as x * y.

negative (x): Same as -x.

norm (a) : Returns the normalized values of an array of scalars/vectors.

power (x, a): Exponentiation of x with a. Here both x and a can either be a single value or an array. If x and y are both arrays, a one-by-one mapping is used between two arrays.

reciprocal (x): Returns 1/x.

remainder (x, y): Returns x − y*floor(x/y). x and y can be single values or arrays.

rint (x): Rounds x to the nearest integer(s).

shear (dataset) : Returns the shear of each cell in a dataset.

skew (dataset) : Returns the skew of each cell in a dataset.

square (x): Returns x*x.

sqrt (x): Return square root of x.

strain (array) : Returns the strain of an array of 3D vectors.

subtract (x, y): Returns the difference between two values. x and y can be single values or arrays. Same as x - y.

surface_normal (dataset) : Returns the surface normal of each cell in a dataset.

trace (array) : Returns the trace of an array of 2D square matrices.

volume (dataset) : Returns the volume normal of each cell in a dataset.

vorticity(array): Returns the vorticity/curl of an array of 3D vectors.

vertex_normal (dataset) : Returns the vertex normal of each point in a dataset.

Trigonometric Functions

Below is a list of supported triginometric functions.

sin (x)

cos (x)

tan (x)

arcsin (x)

arccos (x)

arctan (x)

hypot (x1, x2)

sinh(x)

cosh (x)

tanh (x)

arcsinh (x)

arccosh (x)

arctanh (x)

Spreadsheet View

In several cases it’s very useful to look at the raw dataset. This is where the Spreadsheet view comes in handy.

Spreadsheet View allows users to explore the raw data in a spreadsheet-like display. Users can inspect cells and points and data values associated with these using this view. This makes it a very useful for drilling down into the data.

Spreadsheet View, as the name suggests is a view i.e. users can create one by splitting the main-view frame in the application client-area. Refer to the chapter on Views for details on views. Spreadsheet View can only show one dataset at a time. However, users can use ParaView’s multi-view capabilities to create multiple spreadsheet views for inspecting different datasets.

Inspecting Large Datasets

Spreadsheet View is a client-only view i.e. it delivers the necessary data to the client, when running in client-server mode. Additionally, it is not available through Python scripting (except when running through the Pyhton shell provided by the ParaView application) or batch scripting. Furthermore, when running on a tile-display, the area covered by the spreadsheet on the client simply shows up as a blank region on the tiles.

Unlike complex views like the 3D render view, that can generate the renderings on the server and simply deliver images to the client, the spreadsheet view requires that the data is available on the client. This can be impractical when inspecting really large datasets since the client may not even have enough memory, even if we assume infinite bandwidth. To address such issues, the Spreadsheet View streams the data to the client, only fetching the data for the row currently visible in the viewport.

Double Precision

Using the precision spin-box in the view header, users can control the precision for floating point numbers. The value determines the number of significant digits after the decimal point.

Selection with Spreadsheet View

Spreadsheet View, in many ways, behaves like typical spreadsheet applications. One can scroll, select rows using mouse clicks, arrow keys and modifiers like Shift and Ctrl keys, sort columns by clicking on the header. Additionally, one can double-click on a column header to toggle the maximization of a column for better readability.

On selecting rows the corresponding cells or points will get selected and ParaView will highlight those in other views, such as the 3D view. Conversely, when one makes a selection in the 3D View or the chart views, one the rows corresponding to the selected cells/points will be highlighted in the spreadsheet view. Of course, for the view to highlight the selection, the selected dataset must be the one that’s being shown in the spreadsheet view. To make it easier to inspect just the selected elements, one check the “Show only selected” button on the view header.

When in “Show only Selected” mode, one can no longer create selections on the Spreadsheet view. One has to use the other views to make the selection and the Spreadsheet view will automatically update to show the details for the items that got selected.

Spreadsheet View can show data associated with cells, points or even field data. To choose what attribute the view shows, one can use the attribute-type combo-box. The selection created by the view depends on the attribute-type, i.e. when if user selects in the view when attribute type is “Points”, points in the dataset will be selected. The spreadsheet view also performs selection conversions if possible, i.e. if you select a cell in the 3D view, however you the spreadsheet view is setup to show points, then the view will highlight the points that form the selected cell.

The Spreadsheet View may add several additional data columns which may not be present in the your actual data. These data-columns are either derived information such as the (i, j, k) co-ordinates for structured data or provide additional information about the data, e.g. block index for composite datasets, or provide additional information about the data distribution such as process-id when connected to a parallel server (pvserver or pvdataserver).

Working with Composite Datasets

Spreadsheet view works seamlessly with different kinds of dataset types including composite datasets such as multi-block datasets or AMR datasets. When dealing with composite datasets, the view shows one block at a time. Users can choose the block to inspect by using the display tab.

Selection

Selection is the mechanism for identifying a subset of a dataset by using user specified criteria. This subset can be a set of point or cells or a block of composite dataset. This functionality allows users to focus on a smaller subset that is important. For example, the elements of a finite-element mesh that have pressure above a certain threshold can be identified very easily using the threshold selection. Furthermore, this selection can be converted to a set of global element ids in order to plot the attribute values of those elements over time.

In this chapter we discuss the mechanism for creating selections using Views and Selection Inspector. In the following chapter, we detail another powerful and flexible mechanism of creating selection using queries.

ParaView supports a single active selection. This selection is associated with a data source (here data source refers to any reader, source or filter) and is shown in every view that displays the data source’s output. This article uses a use-case driven approach to demonstrate how this selection can be described and used. In the next section, we introduce the main GUI components that are used in the article. The subsequent sections address different use cases.

Selection Inspector

ParaView provides a selection inspector (referred to simply as the inspector in this article) to inspect and edit the details about the active selection. One can toggle the inspector visibility from the View menu. The inspector can be used to create a new active selection, view/edit the properties of the active selection as well as change the way the selection is displayed in the 3D window e.g. change the color, show labels etc.

We will look at each of these options as we try to explore the different selection types in ParaView.

Spreadsheet View

Spreadsheet View provides data exploration capabilities. One of the common complaints many users have is not being able to look at the raw data directly. Spreadsheet view provides exactly that. It allows the user to look at the raw cell data, point data or field data associated with a dataset. For more details on how to use the Spreadsheet View, please refer to Spreadsheet View Chapter.

Create a Selection

In this section we will discuss different ways of creating a selection.

Select cells/points on the Surface

One of the simplest use-cases is to select cells or points on the surface of the dataset. It is possible to select surface cells by drawing a rubber-band on the 3D view. With the 3D view showing the dataset active, click on Select Cells (or Points) On in the Selection Controls toolbar or under the Edit menu (you can also use the ‘S’ key a shortcut for ‘Select Cells On’). This will put ParaView into a selection mode. In this mode, click and drag over the surface of the dataset in the active view to select the cells (or points) on the surface. If anything was selected, it will be highlighted in all the views showing the data and the source producing the selected dataset will become active in the Pipeline Browser. ParaView supports selecting only one source at a time. Hence even if you draw the rubber band such that it covers data from multiple sources, only one of them will be selected (the one that has the largest number of selected cells or points).

As mentioned earlier, when data from a source is selected, all the views displaying the data show the selection. This includes spreadsheet view as well. If the spreadsheet view will show cell or point attributes of the selected data, then it will highlight the corresponding rows. When selecting points, the spreadsheet view will show the selection only if point attributes are being displayed. When selecting cells, it will highlight the cells in the cell attribute mode, and highlight the points forming the cells in the point attribute mode. For any decent sized dataset, it can be a bit tricky to locate the selected rows. In that case, the Show only selected elements on the display tab can be used to hide all the rows that were not selected.

When selecting cells (or points) on the surface, ParaView determines the cell (or point) ids for each of the cell (or point) rendered within the selection box. The selection is simply the ids for cells (or points) thus determined.

Select cells/points using a Frustum

This is similar to selecting on the surface except that instead of selecting the cells (or points) on the surface of the dataset, it selects all cells (or points) that lie within the frustum formed by extruding the rectangular rubber band drawn on the view into 3D space. To perform a frustum selection, we use Select Cells (or Points) Through in the Selection Controls toolbar or under the Edit menu. As with surface selection, the selected cells/points are shown in all the views in which the data is shown including the spreadsheet view. Unlike surface selection, the indices of the cells or points are not computed after a frustum selection. Instead ParaView performs intersections to identify the cells (or points) that lie within the frustum. Note that this selection can produce a very large selection. This may be time consuming and can increase the memory usage significantly.

Select Blocks in a Composite Dataset

Composite datasets are multi-block or AMR (adaptive mesh refinement) datasets. In case of multi-block datasets, each block may represent different components of a large assembly e.g. tires, chassis etc. for a car dataset. Just like selecting cells or points, it is possible to select entire blocks. To enter the block selection mode use Select Block in the Selection Controls toolbar or under the Edit menu (you can also use the ‘B’ key as a shortcut for Select Block). Once in block selection mode, you can simply click on the block in the 3D view to select a single block or click and drag to select multiple blocks. When a block is selected, its surface cells will be highlighted.

Select using the Spreadsheet View

Until now we have been looking at defining the selection on the 3D view. Now we will see how to create selections using the spreadsheet view. As we discussed earlier, the spreadsheet view simply shows the raw cell (point or field) data in a table. Each row represents a unique cell (or point) from the dataset. Like with any other spreadsheet application, one can select a cell (or a point) by simply clicking on the row to select. One can expand the selection using Ctrl, Shift keys while clicking. If the spreadsheet view is currently showing point attributes, then selecting on it will create a point based selection. Similarly, if it’s showing cell attributes then it will create a cell based selection. Selection cannot be created when showing field attributes which are not associated with any cell or point.

We know that all views showing a selected dataset show the selection. The spreadsheet view showing the data from a source selected in the 3D view highlights the corresponding cells/points. Conversely, when we create a selection in the spreadsheet view, the corresponding cell (or point) gets highlighted in all the 3D views showing the source.

Select using the Selection Inspector

We have seen how to use the different views for creating different types of selections. However, sometimes you may want to tweak the selection or create a new selection with a known set of cell (or point) ids or create selections based of value of any array or location etc. This is possible using the selection inspector.

Whenever a selection is created in any of the views, it becomes the active selection. The active selection is always shown in the selection inspector. For example, if you select cells on the surface of a dataset, then as shown in Figure [1], the selection inspector will show indices for the cells selected.

The selection inspector has three sections: the topmost Current Object and Create Selection are used to choose the source whose output you want to create a selection on. The Active Selection group shows the details of the active selection, if any. The Display Style group makes it possible to change the way the selection in shown in the active 3D view.

To create a new selection, choose the source whose output needs to be selected in the Current Object combo-box and then hit Create Selection. An empty selection will be created and its properties will be shown in the active selection group. Alternatively you can use any of the methods described earlier to create a selection. It will still be shown in the selection inspector.

When you select cells (or points) on the surface or using the spreadsheet view, the selection type is set to IDs. Creating a frustum selection results in a selection with the selection type set to Frustum, while selecting a block in a composite dataset creates a Block selection. Field Type indicates whether cells or points are to be selected.

In the active selection group, Selection Type indicates the type of the active selection. One can change the type by choosing one of the available options.

As shown in Figure [1], for IDs selection, the inspector lists all the selected cell or point indices. You can edit the list of ids to add or remove values. When connected to a parallel server, cell or point ids are not unique. Hence, one has to additionally specify the process number for each cell or point id. Process number -1 implies that the cell (or point) at the given index is selected on all processes. For multi-block datasets, we also need to indicate the block to which the cell or point belongs; while for AMR datasets, we need to specify the (AMR level, index) pair.

As shown in Figure [2], for Frustum selection, currently only the Show Frustum option is available. When this option is turned on, ParaView shows the selection frustum in the 3D view. In the future, we will implement a 3D widget to modify the frustum.

As shown in Figure [3], for Block selection, the full composite tree is shown in the inspector with the selected blocks checked. Using the selection inspector one can create a selection based on thresholds for scalars in the dataset. Choose the scalar array and then add value ranges for the selected cells (or points).

Selection inspector can be used to create location based selection. When field type is CELL, cells at the indicated 3D locations will be selected. When field type is POINT, the point closest to the location within a certain threshold is selected. If Select cells that include the selected points is checked, then all the cells that contain the selected point are selected. It is possible to specify more than one location. To aid in choosing positions, one can turn the Show location widgets option on. As a result ParaView will show cross hairs in the active 3D view which can be moved interactively, as shown in Figure [4].

Selection inspector also provides a means to create global id based selection. These are similar to index based selection however since global ids are unique across all processes and blocks, one does not need to specify any additional as needed by the id based selection.

Convert Selections

Selection inspector can also be used to convert a selection of one type to another. With some valid active selection present, if one changes the selection type then ParaView will try to convert the current selection to the new type, still preserving the cells (or points) that were selected, if possible. For example, if one create a frustum based selection and then changes the selection type to IDs, ParaView will determine the indices for all the cells (or points) that lie with the frustum and initialize the new index based selection with those indices. Note that the number of cells or points that get selected in frustum selection mode can potentially be very large; hence this conversion can be slow and memory expensive. Similarly, if the dataset provides global ids, then it is possible to convert between IDs selection and global id based selection.

It is not possible to convert between all types of selections due to obvious reasons. Conversions between id based and global id based selections, conversions from frustum to id based selections, and conversions from frustum to global id based selections are supported by the selection inspector.

Label Selected Cell/Points

Once an active selection is created, we can label the cells or points or their associated values in a 3D view. This can be done using the selection inspector. At the bottom of the selection inspector panel, there are two tabs Cell Label and Point Label which can be used to change the cell or point label visibility and other label attributes such color, font etc. These tabs are enabled only if the active view is a 3D view. Any changes done in the Display Style group (including the labels) only affect the active 3D view.

﻿

Extract Selection

Selection makes it possible to highlight and observe regions of interest. Oftentimes once a region of interest has been identified, one would like to apply additional operations on it, such as apply filters to only the selected section of the data. This can be achieved using the Extract Selection filter. To set the selection to extract, create a selection using any of the methods already described. Then apply the extract selection filter to the source producing the selected data. To copy the active selection to the filter, use the Copy Active Selection button. One can change the active selection at any time and update the filter to use it by using this button. Figure [5] shows the extract selection filter applied after a frustum selection operation. Now, one can treat this as any other data source and apply filters to it, save state, save data etc.

Plot Selection over Time

For time varying datasets, you may want to analyze how the data variables change over time for a particular cell or a point. This can be done using the Plot Selection Over Time filter. This filter is similar to the Extract Selection filter, except that it extracts the selection for all time-steps provided by the data source (typically a reader) and accumulates the values for all the cell (or point) attributes over time. Since the selection can comprise of multiple cells or points, the display tab provides the Select Block widget which can be used to select the cell or point to plot, as shown in Figure [6]. Currently only one cell (or point) can be plotted at once in the same xy-plot view. One can create multiple plot views to show multiple plots simultaneously.

Querying for Data

As previously described, Selection is a mechanism in ParaView for sub-setting and focusing on a particular elements in the dataset. Different views provides different mechanisms for selecting elements, e.g. one can select visible cells or points using the 3D View. Another mechanism for creating selections is by specifying a selection criteria. For example, support you want to select all cell where the pressure value is between a certain threshold. In such cases, one can use the Find Data dialog. The Find Data dialog performs a dual role: not only does it enable specifying the selection criteria but also show details of the selected elements in a spreadsheet. This makes it easier to inspect the selected elements.

To open the Find Data dialog, choose Find Data from the Edit menu.

When to use Find Data

This feature is useful every time you run into situations where you want to know the cell or the point at which a certain condition happens eg.

- What are the cells at which PRESSURE >= 12?

- What are the points with TEMP values in the range (12, 133)?

- Locate the cell at ID 122, in Block 2.

This feature provides a convenient way of creating selections based on certain criteria that can then be extracted from the data if needed.

Using the Find Data dialog

The dialog is designed to be used in two distinct operations:

- Define the selection criteria or query

- Process the selected cells/points e.g. show labels in active 3D view, extract selection etc.

One must define the selection query and then execute the query, using Run Query button before being able to inspect or process the selected elements.

Defining the Query

First decide what type of elements you are interested in selecting i.e. cells or points and from what data-source. This can be done using the following combo-boxes. Note that as you change these, any previous selections/queries will be cleared.

Next, we must define the selection criteria. For defining the criteria, one first choose the term e.g. IDs, Global IDs, attribute array names etc. available for the chosen element type. Next one chooses the operator, and finally the value or values. Based on the operator one or more values may be entered in the value entry box using comma (,) as the separator.

In addition based on the data-type and the nature of the current session, there may additional rows that allow users to qualify the selection using optional parameters such as process number (when running in parallel), or block number (for composite datasets).

Once you have defined your query, hit Run Query button to execute the query. If any elements get selected, then they will be shown in the spreadsheet in this dialog. Also, is any of they views are showing the dataset that is selected, then they will highlight the selected elements as well, just like regular view-based selection.

Displaying the Selection

Once a query is executed, the selected elements will be highlighted in all views where the selected data is visible. If the active view is a 3D view, one can choose whether the show labels for selected elements as well as the color to use for showing the selected elements using the controls on the Find Data dialog itself.

Extracting the Selection

The results of a query are temporary. They get replaced when a new query is executed or when the user creates a selection using any of the selection mechanisms. Sometimes however, users may want to further analyze the selected elements such as apply more filters to only the selected elements, or plot the change in attributes on the selected elements over time. In that case, one should extract the selection. That creates a new filter that is setup to run the query on its input and produce a dataset matching the selection criteria. Both Extract Selection and Plot Selection Over Time are filters available through the Filters menu. The Find Data dialog provides shortcut buttons to quickly create those filters and set then up with the selection criteria chosen.

Histogram

The Histogram filter produces output indicating the number of occurrences of each value from a chosen data array. It takes in a vtkDataObject but the object must have either point or cell data to operate on. The filter cannot be directly used with a table but the Table to Points filter can be used to convert the table to a polydata for input into the Histogram filter. The bar chart is the default view for the output of the Histogram filter. Other views that can be used are the line chart view, parallel coordinate view, and spreadsheet view. The chart views are useful for observing trends in the data while the spreadsheet view is useful for seeing exact numbers. An example Histogram filter output in a bar chart view is shown below.

Options for the Histogram filter are:

- Which array to process. This can be either a point data array or a cell data array. For arrays with more than 1 component the user can specify which component to compute with respect to. The default is the first component.

- The number of bins to put the results in as well as the range the bins should be divided from.

- An option to average other field information of the same type for each of the bins.

- Which variables are to be displayed in the view. This is under the Display tab of the Object Inspector.

Plotting and Probing Data

There are multiple ways of probing a data set for point or cell values. The simplest is the Probe Location filter. Additionally, there are a variety of filters to plot data with respect to time, location, or grid object Id.

Probe Filter

The probe filter can be used to query a data set for point or cell data.

Options for the probe filter are:

- Show point button is used to show where the center of the sphere is for generating the probe points.

- Center on bounds will place the sphere center at the center of the data set's bounds.

- The sphere center can either be set in the properties tab of the object inspector or in the 3d view with the mouse cursor. To choose a new point in the 3d view window, press P and then click on the desired point. Note that the Show Point option must be selected in order to activate the point widget.

The output for this filter is a single cell comprised of a set of points in a vtkPolyData.

Line Plots

The line plots have similar control functionality for displaying the results. These options are in the Display tab of the Object Inspector and include selecting which point and/or cell data to include in the plot, what should be used as the x axis values (e.g. point/cell index or a specified point or cell data array), and plot preferences such as line thickness and marker style. See the line chart view section for more information on setting the display properties for these filters. An example line plot is shown below.

Plot Data / Scatter Plot

The Plot Data filter and Scatter Plot filter are very similar in functionality with the Scatter Plot filter being a deprecated version of the Plot Data filter. The main difference is that the Scatter Plot filter's output is a 1D rectilinear grid while the Plot Data filter's output is the same type as the input.

The Plot Data filter plots point or cell data over the entire data set. By default the x axis values are determined with respect to their point or cell index.

Plot Over Line

The Plot Over Line filter is used to plot point data over a specified straight line. The Plot Over Line filter will not display cell data over the line so the user can use the Cell Data to Point Data filter to convert cell data to point data in order to use this filter for viewing desired cell data. The line geometry can specified either by setting the points in the Properties tab of the Object Inspector or by pressing P and selecting the beginning and ending points of the line. Note that the Show Line option must be selected to activate the line widget. The resolution option is used to specify at how many evenly spaced points on the line to query the data set for information the point data to plot with respect to.

Plot on Sorted Lines

The Plot on Sorted Lines filter is used when polydata with line cell types have been extracted from a data set and the user wants to see how point data varies over the line. This filter orders the lines by their connectivity instead of their point index. The output of the filter is a multiblock with a block for each contiguous line.

Plot on Intersection Curves

The Plot on Intersection Curves filter is used to plot point data where the data set intersects the given polygonal slice object. The results is a multiblock of polydatas where each block represents a contiguous set of cells. Note that the polydatas will only have 1D cell types. Thus if the slice type object intersection with the data set has 2D geometry the filter will take the boundary of the slice type object in order to reduce down to 1D geometry. If the slice type is a sphere which is wholly contained in a volumetric data set then the filter parameters are invalid and no lines will be output.

Plot Selection Over Time

The Plot Selection Over Time filter can be used to visualize the variation of point or cell data from a selection with respect to time. The selection should be made on the data set of the filter that precedes the Plot Selection Over Time filter in the pipeline in order to ensure that the proper points or cells are selected. Note that information for only a single point or cell can be plotted at a time.

Plot Global Variables Over Time

The Plot Global Variables Over Time filter plots field data that is defined over time. Filters must be set up explicitly to provide the proper information as this will not work for field data in general. As an example see the Exodus reader in ParaView.