Quick Recipes ============= Overview -------- This manual contains documentation for over two hundred functions and several dozen extension object types. Learning to combine the right functions in order to accomplish a visualization task without guidance would involve hours of trial and error. To maximize productivity and start creating visualizations using Visit_'s Python Interface as fast as possible, this chapter provides some common patterns, or "quick recipes" that you can combine to quickly create complex scripts. How to start ------------ The most important question when developing a script is: "Where do I start?". You can either use session files that you used to save the state of your visualization to initialize the plots before you start scripting or you can script every aspect of plot initialization. Using session files ~~~~~~~~~~~~~~~~~~~ VisIt_'s session files contain all of the information required to recreate plots that have been set up in previous interactive VisIt sessions. Since session files contain all of the information about plots, etc., they are natural candidates to make scripting easier since they can be used to do the hard part of setting up the complex visualization, leaving the bulk of the script to animate through time or alter the plots in some way. To use session files within a script, use the RestoreSession function. .. literalinclude:: ../../test/tests/quickrecipes/how_to_start.py :language: Python :start-after: # using session files { :end-before: # using session files } :dedent: 4 Getting something on the screen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you don't want to use a session file to begin the setup for your visualization then you will have to dive into opening databases, creating plots, and animating through time. This is where all of hand-crafted scripts begin. The first step in creating a visualization is opening a database. VisIt provides the OpenDatabase function to open a database. Once a database has been opened, you can create plots from its variables using the AddPlot function. The AddPlot function takes a plot plugin name and the name of a variable from the open database. Once you've added a plot, it is in the new state, which means that it has not yet been submitted to the compute engine for processing. To make sure that the plot gets drawn, call the DrawPlots function. .. literalinclude:: ../../test/tests/quickrecipes/how_to_start.py :language: Python :start-after: # getting something on the screen { :end-before: # getting something on the screen } :dedent: 4 Using VisIt with the system Python ---------------------------------- There are situations where you may want to import the VisIt_ module into the system Python. Some common use cases are using VisIt_ as part of a larger Python workflow or when you need to use a Python module that VisIt_'s Python does not include. You should always try to use VisIt_'s Python interpreter directly, since importing VisIt's Python module may not always work. When importing the VisIt_ module into the system Python, at a minimum the major version numbers must match and ideally the major and minor version numbers would match. In general, there are three things you must do to import the VisIt_ module into the system Python. 1. Tell the Python interpreter where the standard C++ library used to compile VisIt_ is located. This needs to be done before any modules other than `ctypes` are imported. 2. Tell the Python interpreter where the VisIt_ module is located. 3. Specify the version of VisIt_ you are using if you have multiple versions of VisIt_ installed in the same directory. Not all of the steps are necessary. For example, if VisIt_ was compiled with the default system compiler then you do not need to perform the first step. It is important that the steps are done in the order specified above. In this example VisIt_ is imported into the system Python and used to save an image from one of our sample datasets. The paths specified for the location of the standard C++ library and the VisIt_ module will need to be changed as appropriate for your system. :: python3 Python 3.7.2 (default, Feb 26 2019, 08:59:10) [GCC 4.9.3] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import ctypes >>> ctypes.cdll.LoadLibrary('/usr/tce/packages/gcc/gcc-7.3.0/lib64/libstdc++.so.6') >>> import sys >>> sys.path.append("/usr/gapps/visit/3.3.3/linux-x86_64/lib/site-packages/") >>> import visit >>> visit.AddArgument("-v") >>> visit.AddArgument("3.3.3") >>> visit.LaunchNowin() Running: viewer3.3.3 -nowin -forceversion 3.3.3 -noint -host 127.0.0.1 -port 5601 True >>> import visit >>> visit.OpenDatabase("/usr/gapps/visit/data/noise.silo") Running: mdserver3.3.3 -forceversion 3.3.3 -host 127.0.0.1 -port 5601 Running: engine_ser3.3.3 -forceversion 3.3.3 -dir /usr/gapps/visit -idle-timeout 480 -host 127.0.0.1 -port 5601 1 >>> visit.AddPlot("Pseudocolor", "hardyglobal") 1 >>> visit.DrawPlots() 1 >>> visit.SaveWindow() VisIt: Message - Rendering window 1... VisIt: Message - Saving window 1... VisIt: Message - Saved visit0000.png 'visit0000.png' >>> quit() Sometimes telling Python where the standard C++ library used to compile VisIt_ is located does not work and instead you can tell it where VisIt_'s Python library is located. :: python3 Python 3.9.12 (main, Apr 15 2022, 09:20:22) [GCC 10.3.1 20210422 (Red Hat 10.3.1-1)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import ctypes >>> ctypes.CDLL('/usr/gapps/visit/3.3.3/linux-x86_64-toss4/lib/libpython3.7m.so') >>> import sys >>> sys.path.append("/usr/gapps/visit/3.3.3/linux-x86_64-toss4/lib/site-packages") >>> import visit >>> visit.AddArgument("-v") >>> visit.AddArgument("3.3.3") >>> visit.LaunchNowin() Running: viewer3.3.3 -nowin -forceversion 3.3.3 -noint -host 127.0.0.1 -port 5600 True >>> import visit >>> visit.OpenDatabase("/usr/gapps/visit/data/noise.silo") Running: mdserver3.3.3 -forceversion 3.3.3 -host 127.0.0.1 -port 5600 Running: engine_ser3.3.3 -forceversion 3.3.3 -dir /usr/gapps/visit -idle-timeout 480 -host 127.0.0.1 -port 5600 1 >>> visit.AddPlot("Pseudocolor", "hardyglobal") 1 >>> visit.DrawPlots() 1 >>> visit.SaveWindow() VisIt: Message - Rendering window 1... VisIt: Message - Saving window 1... VisIt: Message - Saved visit0000.png 'visit0000.png' >>> quit() Handling Command line arguments ------------------------------- In some cases, a VisIt_ python script also needs to handle its own command line arguments. This is handled using the ``Argv()`` method. For example, to run the python script, ``myscript.py`` with two arguments like so :: visit -nowin -cli -s myscript.py myarg1 myarg2 these arguments can be accessed using the ``Argv()`` method which returns the Python tuple, ``('myarg1', 'myarg2')``. Similarly, ``sys.argv`` will return the Python list, ``['myscript.py', 'myarg1', 'myarg2']`` which includes the script name itself as the zeroth argument. Saving images ------------- Much of the time, the entire purpose of using VisIt_'s Python Interface is to create a script that can save out images of a time-varying database for the purpose of making movies. Saving images using VisIt_'s Python Interface is a straight-forward process, involving just a few functions. Setting the output image characteristics ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VisIt provides a number of options for saving files, including: format, fileName, and image width and height, to name a few. These attributes are grouped into the SaveWindowAttributes object. To set the options that VisIt uses to save files, you must create a SaveWindowAttributes object, change the necessary attributes, and call the SetSaveWindowAttributes function. Note that if you want to create images using a specific image resolution, the best way is to use the *-geometry* command line argument with VisIt_'s Command Line Interface and tell VisIt to use screen capture. If you instead require your script to be capable of saving several different image sizes then you can turn off screen capture and set the image resolution in the SaveWindowAttributes object. .. literalinclude:: ../../test/tests/quickrecipes/saving_images.py :language: Python :start-after: # setting output image characteristics { :end-before: # setting output image characteristics } :dedent: 4 Saving an image ~~~~~~~~~~~~~~~ Once you have set the SaveWindowAttributes to your liking, you can call the SaveWindow function to save an image. The SaveWindow function returns the name of the image that is saved so you can use that for other purposes in your script. .. literalinclude:: ../../test/tests/quickrecipes/saving_images.py :language: Python :start-after: # saving an image { :end-before: # saving an image } :dedent: 4 Working with databases ---------------------- VisIt allows you to open a wide array of databases both in terms of supported file formats and in terms how databases treat time. Databases can have a single time state or can have multiple time states. Databases can natively support multiple time states or sets of single time states files can be grouped into time-varying databases using .visit files or using virtual databases. Working with databases gets even trickier if you are using VisIt to visualize a database that is still being generated by a simulation. This section describes how to interact with databases. Opening a database ~~~~~~~~~~~~~~~~~~ Opening a database is a relatively simple operation - most complexities arise in how the database treats time. If you only want to visualize a single time state or if your database format natively supports multiple timestates per file then opening a database requires just a single call to the OpenDatabase function. .. literalinclude:: ../../test/tests/quickrecipes/working_with_dbs.py :language: Python :start-after: # opening a database { :end-before: # opening a database } :dedent: 4 Opening a database at specific time ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Opening a database at a later timestate is done just the same as opening a database at time state zero except that you must specify the time state at which you want to open the database. There are a number of reasons for opening a database at a later time state. The most common reason for doing so, as opposed to just changing time states later, is that VisIt uses the metadata from the first opened time state to describe the contents of the database for all timestates (except for certain file formats that don't do this, i.e. SAMRAI). This means that the list of variables found for the first time state that you open is used for all timestates. If your database contains a variable at a later timestate that does not exist at earlier time states, you must open the database at a later time state to gain access to the transient variable. .. literalinclude:: ../../test/tests/quickrecipes/working_with_dbs.py :language: Python :start-after: # opening a database at specific time { :end-before: # opening a database at specific time } :dedent: 4 Opening a virtual database ~~~~~~~~~~~~~~~~~~~~~~~~~~ VisIt provides two ways for accessing a set of single time-state files as a single time- varying database. The first method is a .visit file, which is a simple text file that contains the names of each file to be used as a time state in the time-varying database. The second method uses "virtual databases", which allow VisIt to exploit the file naming conventions that are often employed by simulation codes when they create their dumps. In many cases, VisIt can scan a specified directory and determine which filenames look related. Filenames with close matches are grouped as individual time states into a virtual database whose name is based on the more abstract pattern used to create the filenames. .. literalinclude:: ../../test/tests/quickrecipes/working_with_dbs.py :language: Python :start-after: # opening a virtual database { :end-before: # opening a virtual database } :dedent: 4 Opening a remote database ~~~~~~~~~~~~~~~~~~~~~~~~~ VisIt supports running the client on a local computer while also allowing you to process data in parallel on a remote computer. If you want to access databases on a remote computer using VisIt_'s Python Interface, the only difference to accessing a database on a local computer is that you must specify a host name as part of the database name. .. literalinclude:: ../../test/tests/quickrecipes/working_with_dbs.py :language: Python :start-after: # opening a remote database { :end-before: # opening a remote database } :dedent: 4 Opening a compute engine ------------------------ Sometimes it is advantageous to open a compute engine before opening a database. When you tell VisIt to open a database using the OpenDatabase function, VisIt also launches a compute engine and tells the compute engine to open the specified database. When the VisIt Python Interface is run with a visible window, the **Engine Chooser Window** will present itself so you can select a host profile. If you want to design a script that must specify parallel options, etc in batch mode where there is no **Engine ChooserWindow** then you have few options other than to open a compute engine before opening a database. To open a compute engine, use the OpenComputeEngine function. You can pass the name of the host on which to run the compute engine and any arguments that must be used to launch the engine such as the number of processors. .. literalinclude:: ../../test/tests/quickrecipes/opening_compute_engine.py :language: Python :start-after: # opening a compute engine 1 { :end-before: # opening a compute engine 1 } :dedent: 4 The options for starting the compute engine are the same as the ones used on the command line. Here are the most common options for launching a compute engine. :: -l Launch in parallel using the given method. -np <# procs> The number of processors to use. -nn <# nodes> The number of nodes to allocate. -p Partition to run in. -b Bank from which to draw resources. -t