# 11. Python Expressions

This tutorial describes using Python expressions. Python expressions are an advanced feature and should olny be used if the needed functionality is not available in the standard expression system.

## 11.1. Python Expressions Overview

When the available expressions fail to provide needed functionality, users can extend VisIt’s expression system in arbitrary ways using Python expressions. However, Python expressions require users to become somewhat converscent in detailed aspects of how mesh and variable data is represented in terms of VTK objects as well as how they are decomposed and processed in parallel. Nonetheless, Python expressions provide a powerful approach to filling in gaps in needed functionality.

Python expressions are run on the compute engine and will run in parallel whenever a) the compute engine is parallel and b) the input dataset is decomposed for parallel.
Python expressions operate on `vtkDataSets`

, which provide access to mesh variables as well as the mesh coordinates and topology.
Python expression also have access to VisIt’s metadata as well as access to MPI when running in parallel.
Python expressions return a `vtkDataArray`

, which allows returning new variables.
It is not possible to change the mesh topology or coordinates *within* a Python expression.
However, it is possible to *combine* Python expressions with Cross Mesh Field Evaluation (CMFE) functions which can have the effect of changing mesh topology and coordinates.
The functionality is available through the **GUI** and the **CLI**.
When using the **GUI**, they can be created in the *Expressions* window.
When using the **CLI**, they can be created with the *DefinePythonExpression* function.

## 11.2. Creating a Python Expression with the **GUI**

We will now go through the steps required to create a Python expression using the **GUI**.

Let us start by opening a file and creating a plot.

Open the file

`curv2d.silo`

.Create a Psuedocolor plot of

`d`

.

Now let us go ahead and create the Python expression.

Go to

*Controls->Expressions*.This brings up the Expressions window.

Click

*New*in the*Expression list*to create a new expression.Change the

*Name*in the*Definition*section to “MyExpression”.Click on the

*Python expression editor*tab in the*Definition*section.Select

*Insert variable…->Scalars->d*to add`d`

to the*Arguments*text field.Select

*Insert variable…->Scalars->p*to add`p`

to the*Arguments*text field. Note that the variable names are seperated by a comma. If the variable names are not separated by commas you will get a cryptic error message when you try to plot the expression.Click

*Load script->Template->Simple filter*to add a template of a Python expression in the*Python expression script*editor.

At this point you modify the template to create your expression.
A common practice is to make modifications to the script and test it using the Pseudocolor plot.
Changes to the script can be made either by modifying the script in the *Python expression script* editor or modifying it in an external text editor and then reloading the script.
Generaly speaking, modifying the script in the *Python expression script* editor is easier than doing it in an external text editor except that it is difficult to tell how many spaces are at the beginning of the line since the editor does not use a fixed width font.

### 11.2.1. Developing the script in the *Python expression script* editor

The following steps can be used to iteratively develop your script using the *Python expression script* editor.

Edit the script.

Click the

*Apply*button.Go to

*Variables->d*to change the variable to`d`

. The first time you try your script this will not be necessary since the variable is already`d`

.Go to

*Variables->MyExpression*to change the variable to “MyExpression” and execute the script.

### 11.2.2. Developing the script in a text editor

The following steps can be used to iteratively develop your script using a text editor.

Before you can modify the script you will need to save it.

Click

*Save script*to save the script.

Now you are ready to modify the script.

Edit the script with your favorit editor.

Go to

*Load script->File*to load the script.Click the

*Apply*button.Go to

*Variables->d*to change the variable to`d`

. The first time you try your script this will not be necessary since the variable is already`d`

.Go to

*Variables->MyExpression*to change the variable to “MyExpression” and execute the script.

## 11.3. Python Expression Example 1

This example adds two cell centered variables. It demonstrates accessing multiple variables and performing simple operations with them to generate a result.

Here is the example script.

```
class MyExpression(SimplePythonExpression):
def __init__(self):
SimplePythonExpression.__init__(self)
self.name = "PythonExpression"
self.description = "Add two scalar variables together"
self.output_is_point_var = False
self.output_dimension = 1
def modify_contract(self,contract):
pass
def derive_variable(self,ds_in,domain_id):
# ds_in is the input data set
# Get the data array for the first variable
cell_vals1 = ds_in.GetCellData().GetArray(self.input_var_names[0])
# Get the data array for the second variable
cell_vals2 = ds_in.GetCellData().GetArray(self.input_var_names[1])
# Get the number of values in the variables
ncells = ds_in.GetNumberOfCells()
# Create a scalar float array with ncells values for the result
res = vtk.vtkFloatArray()
res.SetNumberOfComponents(1)
res.SetNumberOfTuples(ncells)
for i in range(ncells):
# Add the i'th value from the first variable to the i'th
# value for the second variable
val = cell_vals1.GetTuple1(i) + cell_vals2.GetTuple1(i)
# Store the value in the i'th value in the result
res.SetTuple1(i, val)
return res
py_filter = MyExpression
```

Let us start off by creating a Pseudocolor plot from the expression.

Copy the script into the

*Python expression script*editor.Click the

*Apply*button.Go to

*Variables->MyExpression*to change the variable to the expression.

Now let us take a look at the script and see what each portion does.

The `__init__`

method provides information about the expression, including

That it inherits from

`SimplePythonExpression`

.The name of the expression.

A description of the expression.

A flag indicating that the output is not a point centered value.

A flag that the output is a scalar.

```
def __init__(self):
SimplePythonExpression.__init__(self)
self.name = "PythonExpression"
self.description = "Add two scalar variables together"
self.output_is_point_var = False
self.output_dimension = 1
```

The `modify_contract`

method can be used to request special information for the expression from VisIt.
In this case it is a no-op.

```
def modify_contract(self,contract):
pass
```

The `derive_variable`

method performs the real work of the expression.
It is passed the input `vtkDataSet`

and the `domain_id`

.

```
def derive_variable(self,ds_in,domain_id):
# ds_in is the input data set
```

The following lines get the `vtkDataArrays`

for the cell values for the two variables and the number of cells.

```
# Get the data array for the first variable
cell_vals1 = ds_in.GetCellData().GetArray(self.input_var_names[0])
# Get the data array for the second variable
cell_vals2 = ds_in.GetCellData().GetArray(self.input_var_names[1])
# Get the number of values in the variables
ncells = ds_in.GetNumberOfCells()
```

The following lines set the output `vtkDataArray`

to be an array of floats with 1 component and ncells values.

```
# Create a scalar float array with ncells values for the result
res = vtk.vtkFloatArray()
res.SetNumberOfComponents(1)
res.SetNumberOfTuples(ncells)
```

Now we loop over the cells, setting the output value for each cell.

```
for i in range(ncells):
```

The following lines add the two variables for the current cell.

```
# Add the i'th value from the first variable to the i'th
# value for the second variable
val = cell_vals1.GetTuple1(i) + cell_vals2.GetTuple1(i)
```

The following lines set the result value for the current cell.

```
# Store the value in the i'th value in the result
res.SetTuple1(i, val)
```

Once we have finished processing all the cells, we return the `vtkDataArray`

.

```
return res
```

### 11.3.1. Using your Python Expression with the **CLI**

The Python expression we just created can also be used with the **CLI**.

We will start by saving the script we just created.

Click

*Save script*and save the script with the name`MyExpression.py`

.

The following script will open `curv2d.silo`

and create a Pseudocolor plot of the expression.

```
OpenDatabase("/usr/gapps/visit/data/curv2d.silo")
DefinePythonExpression("MyExpression", ['d', 'p'], file="MyExpression.py")
AddPlot("Pseudocolor", "MyExpression")
DrawPlots()
```

## 11.4. Python Expression Example 2

This example operates on 2D meshes and takes the distance around the edges of each cell and multiplies it by the value of the cell. It demonstrates accessing the coordinates and topology of the mesh as well as a variable.

Here is the example script.

```
from math import sqrt
class MyExpression(SimplePythonExpression):
def __init__(self):
SimplePythonExpression.__init__(self)
self.name = "PythonExpression"
self.description = "Multiply the variable by sum of cell edge lengths in 2D"
self.output_is_point_var = False
self.output_dimension = 1
def modify_contract(self,contract):
pass
def derive_variable(self,ds_in,domain_id):
# ds_in is the input data set
# Get the data array for the variable
cell_vals = ds_in.GetCellData().GetArray(self.input_var_names[0])
# Get the number of values in the variable
ncells = ds_in.GetNumberOfCells()
# Create a scalar float array with ncells values for the result
res = vtk.vtkFloatArray()
res.SetNumberOfComponents(1)
res.SetNumberOfTuples(ncells)
for i in range(ncells):
# Get the i'th cell
cell = ds_in.GetCell(i)
# Get the number of edges in the cell
nedges = cell.GetNumberOfEdges()
# Sum up the lengths of the edges
sum = 0.
for j in range(nedges):
# Get the j'th edge
edge = cell.GetEdge(j)
# Calculate the edge length from the end points
pt1 = ds_in.GetPoint(edge.GetPointId(0))
pt2 = ds_in.GetPoint(edge.GetPointId(1))
len = sqrt((pt2[0] - pt1[0]) * (pt2[0] - pt1[0]) +
(pt2[1] - pt1[1]) * (pt2[1] - pt1[1]) +
(pt2[2] - pt1[2]) * (pt2[2] - pt1[2]))
sum = sum + len
# Multiply the sum by the i'th value of the variable
sum *= cell_vals.GetTuple1(i)
# Store the value in the i'th value in the result
res.SetTuple1(i, sum)
return res
py_filter = MyExpression
```

Let us start off by creating a Pseudocolor plot from the expression.

Copy the script into the

*Python expression script*editor.Click the

*Apply*button.Go to

*Variables->MyExpression*to change the variable to the expression.

The `__init__`

and `modify_contract`

methods are the same as the previous example, so we will only look at the `derive_variable`

method.

```
def derive_variable(self,ds_in,domain_id):
# ds_in is the input data set
```

The following lines get the `vtkDataArray`

for the cell values and the number of cells.

```
# Get the data array for the variable
cell_vals = ds_in.GetCellData().GetArray(self.input_var_names[0])
# Get the number of values in the variable
ncells = ds_in.GetNumberOfCells()
```

The following lines set the output `vtkDataArray`

to be an array of floats with 1 component and ncells values.

```
# Create a scalar float array with ncells values for the result
res = vtk.vtkFloatArray()
res.SetNumberOfComponents(1)
res.SetNumberOfTuples(ncells)
```

Now we loop over the cells, setting the output value for each cell.

```
for i in range(ncells):
```

The following lines get the current cell and the number of edges in the cell.

```
# Get the i'th cell
cell = ds_in.GetCell(i)
# Get the number of edges in the cell
nedges = cell.GetNumberOfEdges()
```

Now we loop over the edges, calculating the sum of the lengths of the edges.

```
# Sum up the lengths of the edges
sum = 0.
for j in range(nedges):
```

We calculate the length of the edge from the 3D coordinates of the end points of the edge, which we add to the sum.

```
# Get the j'th edge
edge = cell.GetEdge(j)
# Calculate the edge length from the end points
pt1 = ds_in.GetPoint(edge.GetPointId(0))
pt2 = ds_in.GetPoint(edge.GetPointId(1))
len = sqrt((pt2[0] - pt1[0]) * (pt2[0] - pt1[0]) +
(pt2[1] - pt1[1]) * (pt2[1] - pt1[1]) +
(pt2[2] - pt1[2]) * (pt2[2] - pt1[2]))
sum = sum + len
```

Once we have summed the lengths of the edges we multiply the sum by the cell value and set it in the result.

```
# Multiply the sum by the i'th value of the variable
sum *= cell_vals.GetTuple1(i)
# Store the value in the i'th value in the result
res.SetTuple1(i, sum)
```

Once we have finished processing all the cells, we return the `vtkDataArray`

.

```
return res
```

### 11.4.1. Using your Python Expression with the **CLI**

This Python expression can also be used with the **CLI**, just as the one in the first example, except the specification of the variables to use is slightly different.
Since you are only passing a single variable you would use `("d")`

for the list of variables.

```
OpenDatabase("/usr/gapps/visit/data/curv2d.silo")
DefinePythonExpression("MyExpression", ("d"), file="MyExpression.py")
AddPlot("Pseudocolor", "MyExpression")
DrawPlots()
```

## 11.5. Using VTK in Python

The VTK Python interface mirrors the C++ interface.

To find out information on a particular VTK class, type the name of the class in your favorite search engine.

Here are links to some VTK classes that will be of most use to you.