.. include:: ../../macros.hrst
.. include:: ../../abbreviations.hrst

.. _chapter:PythonAndBatchParaViewAndPython:

Python & Batch: ParaView & Python
###################################


Introduction
============

|ParaView| offers a rich and powerful Python interface. This allows users
to automate processing of their data, and gives access to powerful tools
in the Visualization Tool Kit (VTK). This tutorial will describe
|ParaView| and Python. It shows a user how to drive |ParaView| using Python
commands, and how to automate the creation and use of these commands.

Overview
========

|ParaView| has a client / server architecture. The client includes the
|ParaView| GUI and display. The server reads the user's data, processes
the data, and passes these images to the client. We can use Python to
control ParaView either in the GUI, at the client level, or directly on
the server.

A simple Python toy example within ParaView
===========================================

-  Start |paraview|.
-  Start the Python Interpreter **Tools → Python Shell**
-  Notes:

   -  You can copy commands from elsewhere and paste them into the Python Shell.
   -  Python is case sensitive. Be sure to use correct capitalization as shown below.
   -  Python is indent sensitive. Be sure to not indent, as shown below.

-  Lets create and display a sphere, by typing the following commands into the Python Shell

   .. code-block:: python

      sphere=Sphere()
      Show()
      Render()

   We have now created a sphere in the pipeline, turned on it's
   visibility, and re-rendered.

-  Lets add a shrink filter. We hide the sphere, add the shrink filter, and re-render.

   .. code-block:: python

      Hide()
      Render()
      shrink = Shrink()
      Show()
      Render()

   ParaView will allow us to use either the GUI controls or Python. For
   instance:

   -  Select the Sphere in the pipeline browser, by typing the following in the Python Shell:

      .. code-block:: python

         clip = Clip()
         Show()
         Render()

   -  Or, we could continue in the Python as follows:

      .. code-block:: python

         clip = Clip()
         Hide(shrink)
         Show(clip)
         Render()

   Hide the Plane widget:

   .. code-block:: python

      Hide3DWidgets(proxy=clip)

.. admonition:: **Did you know?**
   :class: tip

   -  To see all commands available in ParaView:

      .. code-block:: python

         dir()

   -  To see all of the options for the Clip creator:

      .. code-block:: python

         dir(Clip)

   -  To see all of the options for the instance of the clip we created
      above:

      .. code-block:: python

         dir(clip)

   -  A better tool to see the available commands for an item in the
      pipeline is ListProperties, such as:

      .. code-block:: python

         clip.ListProperties()

      -  Note that this doesn't work on instantiated controls, such
         as the camera. Use dir() for controls such as camera.

   -  And, to see the different properties of the ClipType variable, use

      .. code-block:: python

         clip.ClipType.ListProperties()

   -  To see lots of detail on an instance of a command, create the
      instance and ask for help on that instance..

      .. code-block:: python

         help(clip)

Lets look at, and change, something

-  Print the Theta Resolution

   .. code-block:: python

      print(sphere.ThetaResolution)

-  Change it to 64

   .. code-block:: python

      sphere.ThetaResolution=64
      Show()
      Render()


-  Lets change the selected filter in the Pipeline Browser:

   .. code-block:: python

      SetActiveSource(sphere)

-  Lets delete the clip

   .. code-block:: python

      Delete(clip)

-  Lets add a filter to the sphere, without selecting it first

   .. code-block:: python

      wireframe = ExtractEdges(Input=sphere)
      Show()
      Render()

A simple Python example reading a datafile and writing a screenshot
===================================================================

-  Within the ParaView GUI, **Edit → Reset Session**
-  Start the Python Interpreter **Tools → Python Shell**

Read in data, use a filter and save a screenshot
------------------------------------------------

-  Lets read in can.ex2, clip can.ex2, paint can.ex2 and save a
   screenshot. We use this template.

   .. code-block:: python

      canex2 = OpenDataFile('D:/directoryName/can.ex2')

   Here is the current path. Be sure to update for version number

   .. code-block:: python

      canex2 = OpenDataFile('C:/Program Files (x86)/ParaView x.x.x/data/can.ex2')
      clip = Clip()
      Hide(canex2)
      Show(clip)
      ResetCamera()
      Render()
      SaveScreenshot('D:/directoryName/picture.jpg')

See more about file readers in :numref:`chapter:LoadingData` of the User's Guide.

Control the camera
------------------

-  We want to move the camera.
   First, get the camera and reset the camera to a known good position.

   .. code-block:: python

      camera=GetActiveCamera()
      camera.SetFocalPoint(0,0,0)
      camera.SetPosition(0,0,-10)
      camera.SetViewUp(0,1,0)

-  How to move the camera closer or further away

   .. code-block:: python

      camera.Dolly(10)
      Render()
      camera.Dolly(.1)
      Render()

-  How to rotate the camera around the view direction 45 degrees,
   centered on the dataset. After the reset above, rotate around the
   X axis.

   .. code-block:: python

      camera.Roll(45)
      Render()

-  How to rotate the camera around the vector up, centered on the Y
   axis. After the reset above, rotate around the Y axis.

   .. code-block:: python

      camera.Yaw(45)
      Render()

-  How to rotate the camera vertically around the camera point

   .. code-block:: python

      camera.Pitch(45)
      Render()

-  How to rotate the camera around the vector up, centered on the
   dataset. After the reset above, rotate around the Y axis.

   .. code-block:: python

      camera.Azimuth(45)
      Render()

-  How to rotate the camera around the X axis, centered on the
   dataset. After the reset above, rotate around the Y axis.

   .. code-block:: python

      camera.Elevation(45)
      Render()

-  How to reset the camera

   .. code-block:: python

      ResetCamera()

-  Available commands are found using:

   .. code-block:: python

      dir(camera) (after you have created the animationScene1
      variable)
      dir(GetActiveCamera())

Control time
------------

-  We want to move forward one timestep, so min and max are set correctly for a variable

   .. code-block:: python

      animationScene1 = GetAnimationScene()
      animationScene1.GoToNext()

-  Playing through all time is done with the following command.

   .. code-block:: python

     animationScene1.Play()

-  We need to acquire the available timesteps:

   .. code-block:: python

      tk = GetTimeKeeper()
      timesteps = tk.TimestepValues

-  First timestep is found using either of these methods:

   .. code-block:: python

      animationScene1.GoToFirst()
      animationScene1.AnimationTime = timesteps[0]

-  Last timestep is found using either of these methods:

   .. code-block:: python

      animationScene1.GoToLast()
      animationScene1.AnimationTime = timesteps[-1]

-  Moving to a specific timestep (such as timestep 10) is done as follows:

   .. code-block:: python

      # index starts with 0
      animationScene1.AnimationTime = timesteps[9]

-  To find out how many timesteps we have, you use the len command.
   Continued on from above.

   .. code-block:: python

      numTimesteps = len(timesteps)

-  Available commands are found using:

   .. code-block:: python

      # after you have created the animationScene1 variable
      dir(animationScene1)
      dir(GetAnimationScene())

Paint by a variable
-------------------

-  We want to color by the variable. Be sure to Show the Clip, and not the Can.
   Steps are, move forward one timestep, get the renderview, get the
   display, get the variables, ColorBy.

   .. code-block:: python

      animationScene1 = GetAnimationScene()
      animationScene1.GoToNext()
      renderView1 = GetActiveViewOrCreate('RenderView')
      canex2Display = Show(clip, renderView1)

-  Get point var names

   .. code-block:: python

      canex2 = GetActiveSource()
      print(canex2.PointVariables.GetAvailable())

-  Get Cell var names

   .. code-block:: python

      print(canex2.ElementPointVariables.GetAvailable())

-  For point vars

   .. code-block:: python

      vars = canex2.PointVariables.GetAvailable()
      print(vars)
      ColorBy(canex2Display, ('POINTS', vars[0]))

-  For cell vars

   .. code-block:: python

      vars = canex2.ElementVariables.GetAvailable()
      print(vars)
      ColorBy(canex2Display, ('CELLS', vars[0]))
      # Actually not needed
      Render()

Information on reading variable information is found in :numref:`sec:DataInformationInPython` of the User's Guide.

Scale Around Dataset Center - A userful example
===============================================

-  We want to create a script that allows us to scale a dataset around it's center.
   This example shows how to get the active source, get the bounds, and transform the camera.

   .. code-block:: python

      scale_factor = 2
      indata = GetActiveSource()

      bounds = indata.GetDataInformation().GetBounds()
      center = ((bounds[0] + bounds[1])/2, (bounds[2] + bounds[3])/2,(bounds[4] + bounds[5])/2)

      transform_to_center = Transform()
      transform_to_center.Transform.Translate = [-center[0],
      -center[1], -center[2]]
      Hide()

      scale = Transform()
      scale.Transform.Scale = [scale_factor, scale_factor,
      scale_factor]
      Hide()

      transform_from_center = Transform()
      transform_from_center.Transform.Translate = [center[0],
      center[1], center[2]]
      Show()

      Render()

Trace Recorder
==============

|paraview| includes a tool to automatically generate Python scripts for
us. It is called the Trace Recorder. An example is as follows.

-  Read in can.ex2, clip can, paint by EQPS, change the camera to +Y,
   write out a screenshot and write out a movie. The steps are:

   -  **Tools → Start Trace** Select **Show Incremental Trace**.
   -  Open can.ex2.
   -  **OK**.
   -  Turn all variables on.
   -  **Apply**.
   -  **+Y**.
   -  Select **Clip**.
   -  **Y Normal**.
   -  Unselect **Show Plane**.
   -  **Apply**.
   -  Set **Coloring** to **EQPS**.
   -  Last timestep.
   -  Rescale to Data Range.
   -  Set First timestep.
   -  **File → Save Screenshot**. Save as .png.
   -  **File → Save Animation**. Save as .avi.
   -  **Tools → Stop Trace**
   -  **File → Save** to a known location.

   Another way to find Python for |paraview| is through Save State. This
   should be a last resort, but it may include commands that the Trace
   Recorder missed. '''File → Save State → Python State File.

Running Scripts
===============

ParaView allows a user to run a script. This is done as follows:

-  **Tools → Python Shell**
-  **Run Script**

Now, browse to your script, and select OK.

Macros
======

|paraview| can save and use Python scripts that have been placed in a
known location. When you create a trace, you have the option to **File →
Save As Macro**. You also have the option on the Macros menu to **Import
new macro...**. Macros will be added to the Macro toolbar at the top of the
ParaView GUI. You can edit and delete these Macros through the **Macro
menu**.

   As an example, lets add the Python script that we created above.

-  **Macros → Impoort new macro...**, find your macro, and click **OK**.
-  Click on your **Macro** on the toolbar.

Python Help
===========

More information can about can be found throughout the User's Guide.

Additional information can be found in :numref:`chapter:BatchPythonScripting` of Self-directed Tutorial.
