Batch Processing in Paraview¶
Batch processing is the automated processing of data without user intervention. This may occur on a local desktop machine, or on a batch process on a remote server where only ssh access is available. Batch processing output data can lend itself to highly efficient work flows and eliminate repeated manual processing using GUI tools.
Quick Start¶
This section will quickly get you started with batch processing M-Star results using Paraview. A ready to run script is provided so you can immediately get started. This script automatically processes all slice data and outputs images for all available data for the last time step.
Prerequisites
M-Star simulation results have been created in a directory called
out
Paraview is installed
Guide
Download this paraview script
and place it in a case directoryFind the Paraview install path and make note of the full path to the
/path/to/paraview/bin/pvpython
executable.Open a new command prompt or terminal and navigate to your case directory that contains the solver input files and
out
directoryRun the following command. Replace the pvpython path with your paraview install location noted from step (2)
/path/to/paraview/bin/pvpython post_slices.py
You should see some output from the script as it is running
Results are output to a directory
out/Renders
Bare Bones Script¶
This section will provide a minimal starting script for your own development. Additional explanation is given about paraview scripting itself and general concepts.
Setup
First you will need to import the paraview.simple python module and create a view:
from paraview.simple import *
view = CreateRenderView()
view.ViewSize = (600,400)
Load and show data
This following code loads in a out/Output/SliceY_0.250.pvd
data file and shows it in the rendering view. The field_reader
is a Paraview source proxy. It handles loading the data into the Paraview pipeline. A field_display
variable is returned from the Show
call. This object can be used to change how the object is displayed. This same pattern is used for all Paraview pipeline objects.:
field_reader = PVDReader(FileName="out/Output/SliceY_0.250.pvd")
field_display = Show(field_reader, view)
Add a text annotation
To further illustrate the data and display properties object pairing we have created a Text object and displayed it in the view. The field_text
is the Paraview pipeline object that handles the data, in this case a text string Velocity
. The field_text_display
variable returned from the Show
call can be used to change the font size and position in the render view.:
field_text = Text(Text="Velocity")
field_text_display = Show(field_text, view)
field_text_display.FontSize = 12
field_text_display.WindowLocation = "LowerLeftCorner"
Handling the camera position
The camera position determines the perspective of the displayed view. This can be tricky to get exactly right. In our example, the camera is positioned above the 3D slice. By default the camera “Focal Point”, what the camera is pointed at, is (0,0,0) so we do not need to change it here. The ResetCamera
function call makes sure the entire scene is visible in the view. By default, the 3D rendering view camera uses a perspective mode. This type of view attempts to convey 3D scene depth by making close objects appear larger using a vanishing point at a finite distance.
camera = view.GetActiveCamera()
camera.SetPosition(0,1,0)
ResetCamera(view)
Coloring slices by field data
This is a main reason we go to all the effort to load our data into Paraview. We want to see it colored by a specified color scale to show flow structures or help us understand complex flow problems. The general approach to field coloring is to first change to the last time step, create our coloring scale from that data range, and apply our desired color scale.
Here we are coloring by velocity magnitude, which is associated with the Cell paraview data. Most M-Star data will output data as cell centered, so you typically want to show coloring by Cell centers. The “GetColorTransferFunction” returns the color scale itself for a given data channel. Here we instruct Paraview to use the Viridis color scale. The selection of color scale can be a topic of discussion all on its own. The Viridis color scale was developed by visualization experts and tends to look good. It also has the advantage of being accessible by color blind individuals.
Finally, the color bar itself is added to the 3D window. Positioning, font, and sizing can all be controlled by interacting with the “bar” variable here.
# Change to last time before creating the color scale
view.ViewTime = field_reader.TimestepValues[-1]
Render()
# Color the field data by a given cell data channel
ColorBy(rep=field_display, value=("CELLS", "Velocity Magnitude (m/s)"))
# Change the coloring preset to use the "Viridis" preset.
lt = GetColorTransferFunction("Velocity Magnitude (m/s)", field_display)
lt.ApplyPreset("Viridis (matplotlib)", True)
# Add the color scalar bar to the view
bar = CreateScalarBar(LookupTable=lt)
view.Representations.append(bar)
Interacting with time
To change the time shown in the rendering window, set the view.ViewTime
field to the specified time. The available times can be accessed by on the source data itself. Here we using the last time step available. After changing the time step, you must call Render
.
view.ViewTime = field_reader.TimestepValues[-1]
Render(view)
Save rendered images
Once you have setup the rendered view, you can save the image to disk. It is good practice to specify the image resolution explicitly as we have done here. This allows arbitrary sized images to be created. In the following code we are also preserving the aspect ratio of the rendering view window and outputing a large image with a width of 1080 pixels. This approach will help avoid upscaling low resolution images. Instead we will have larger images which will get down sampled when embedded in presentations or reports.
# Specify the output size of the images
aspect_ratio = float(view.ViewSize[1]) / float(view.ViewSize[0])
output_width = 1080
output_height = int(aspect_ratio * output_width)
SaveScreenshot("image.png", view, ImageResolution=(output_width, output_height))
Full Bare Bones Script
from paraview.simple import *
# This is the rendering view where the visualization appears
view = CreateRenderView()
view.ViewSize = (600,400)
# Load in the static walls stl file
stl_reader = STLReader(FileNames="out/Output/Walls.stl")
stl_display = Show(stl_reader, view)
stl_display.Representation = "Surface"
stl_display.Opacity = 0.2
# Load in the moving body PVD file
solid_reader = PVDReader(FileName="out/Output/SliceMovingBody_Moving Body.pvd")
solid_display = Show(solid_reader, view)
# Load in the field data file
field_reader = PVDReader(FileName="out/Output/SliceY_0.250.pvd")
field_display = Show(field_reader, view)
# Add a simple time annotation
annotime = AnnotateTimeFilter(Input=field_reader)
annotime_display = Show(annotime, view)
annotime_display.FontSize = 12
# Add a simple text annotation
field_text = Text(Text="Velocity")
field_text_display = Show(field_text, view)
field_text_display.FontSize = 12
field_text_display.WindowLocation = "LowerLeftCorner"
# Change the camera to look at the Y plane and then fit the view to the displayed data
camera = view.GetActiveCamera()
camera.SetPosition(0,1,0)
ResetCamera(view)
# Change to last time before creating the color scale
view.ViewTime = field_reader.TimestepValues[-1]
Render()
# Color the field data by a given cell data channel
ColorBy(rep=field_display, value=("CELLS", "Velocity Magnitude (m/s)"))
# Change the coloring preset to use the "Viridis" preset.
lt = GetColorTransferFunction("Velocity Magnitude (m/s)", field_display)
lt.ApplyPreset("Viridis (matplotlib)",True)
# Add the color scalar bar to the view
bar = CreateScalarBar(LookupTable=lt)
view.Representations.append(bar)
# Specify the output size of the images
aspect_ratio = float(view.ViewSize[1]) / float(view.ViewSize[0])
output_width = 1080
output_height = int(aspect_ratio * output_width)
# Specify the time steps to output
time_steps_to_render = []
time_steps_to_render = [ field_reader.TimestepValues[-1] ]
#time_steps_to_render = field_reader.TimestepValues
count = 0
for t in time_steps_to_render:
fn = "output_{0}.png".format(count)
view.ViewTime = t
Render(view)
SaveScreenshot(fn, view, ImageResolution=(output_width, output_height))
count += 1
Additional Resources¶
The official Python Paraview documentation .
The Paraview Guide is a great resource . It is available on the download page of any Paraview release. Look for a “ParaViewGuide-5.X.Y.pdf” file in the Documentation section.
A lot can be learned by exporting python state files directly from Paraview. To do this, create an interesting visualization manually in paraview. Then go to File-Save State
, and change the file type to “Python state file”. This will write out a python script that creates the view you just created.
Use the Python Shell in Paraview to learn about objects and the API itself. Open that with View-Python Shell
. The shell opens up in the window. You can then interrogate your loaded data and see what fields are available. After loading some data into Paraview, type each command into the Python Shell:
d = GetActiveSource()
# What object do we have?
d
# What can I do with this object?
help(d)
# What cell arrays are available?
d.CellArrays