VisIt

At the moment the VisIt infrastructure does not work correctly for compatibility issues with our MFA system. We are aware of it and discussing possible solutions internally.
We are sorry for the inconvenience.

Overview

From (VisIt HomePage) :

VisIt is an Open Source, interactive, scalable, visualization, animation and analysis tool. From Unix, Windows or Mac workstations, users can interactively visualize and analyze data ranging in scale from small (101 cores) desktop-sized projects to large (105 cores) leadership-class computing facility simulation campaigns. Users can quickly generate visualizations, animate them through time, manipulate them with a variety of operators and mathematical expressions, and save the resulting images and animations for presentations. VisIt contains a rich set of visualization features to enable users to view a wide variety of data including scalar and vector fields defined on two- and three-dimensional (2D and 3D) structured, adaptive and unstructured meshes. Owing to its customizable plugin design, VisIt is capable of visualizing data from over 120 different scientific data formats (see this partial list). See a table of key features and a complete table of the tool's features.

This is the user's documentation of the VisIt module present on the Linux Cluster and SuperMUC-NG supercomputer at LRZ. The module is usable either in batch mode through VisIt python scripting interface, or through interactive GUI accessible from the users' local machines, via remote host configuration.

Remote GUI usage

VisIt is configured to launch jobs on either machine's regular queues. That sets up a remote engine that connects automatically to your local open GUI, allowing access to the remote data with your local visit configuration. No dedicated server is used.

Publications acknowledgment

Maintenance of the remote GUI service is especially taxing and time consuming. If you are using this service, we would appreciate acknowledgement in publications and movie credits, besides citing the VisIt original paper. Please consider including the following statement:


Visualizations displayed in this work have been produced via the VisIt remote GUI provided by the  Leibniz Supercomputing Centre (LRZ) on the [SuperMUC-NG]/[Linux Cluster] system. We thank LRZ and its VisIt maintainer Dr. Salvatore Cielo for keeping this service optimized.


To set it up, please follow these configuration steps.

Check to have a working SSH connection

You will only need a machine capable of connecting to your server (e.g. check this page for SuperMUC-NG) running a local instance of VisIt FOR ONE OF THE VERSION present on the machine (e.g. 3.2). VisIt essentially uses the SSH protocol under the hood, so all the configurations needed for a Secure Shell connection apply. Setting up an SSH key would speed up connection, but beware of the restrictions for SuperMUC-NG.

The first step is testing to have a working SSH connection over command line interface before proceeding with the remote GUI setup. 
After that, you won't need a CLI connection anymore; host configuration and remote connection will happen through your local VisIt GUI.

Download the provided host configuration files

Once you have a working SSH connection, in order to set the remote engine you just need a configuration file: please save the following files under your local ~./visit/hosts directory (C:\Users\<my user name>\Documents\VisIt\hosts on Windows): host_linux_cluster.xml and host_supermuc_ng.xml.

Alternatively, since version 3.1.1 you should be able to access those from the list of known remote hosts: simply open your local VisIt, select Options → Host Profiles ... → Remote Profiles → Update. You may have to check the dev branch. Then select the file for either SuperMUC-NG or the Linux cluster and click on ImportThe files presented on this page are updated more frequently, though.

FInally, if you need a custom connection AND you know what you are doing, you may also fill or edit all Options → Host Profiles ... → Host Settings tabs manually by yourself.

Customize the host configuration with your LRZ account

In either case you need to update the host configuration with your account data. Enter you username in the Options → Host Profiles ... → Host Settings → Username field. You will have the option to change username via a pop-up window at connection time.

For SuperMUC-NG you also have to enter your SLURM account number (i.e. your LRZ project number), just like for any regular job submission via SLURM. Please add that under Options → Host Profiles ... → Launch Profiles → Advanced → Launcher Arguments.

You may have to select Options → Save Settings on the menu to make such edits permanent. All the other parameters should be set correctly.

Launching a remote engine

At this point you can launch a remote host simply by opening a file on the remote server in the Open dialog box, a very intuitive procedure. Select the desired host from the Host menu; you will then be connected to your remote filesystem. Select the file you want to open; the following dialog box will ask to select a job profile.
The provided hostfiles contain an exhaustive collection of launch profiles, corresponding exactly to the different partitions of the linux cluster and queues of SuperMUC-NG, with both salloc and sbatch/mpiexec; just select the desired job class, based on needs and machine availability (you can check that with the sinfo command). You will be able to select the number of processes (i.e. MPI tasks), nodes and the timeout of your job in the next popup.

Using 2 or 4 MPI tasks per node is a reasonable choiche when using OSPRay volume rendering (which is STRONGLY advised, since LRZ machines do not include accelerators at the time of writing). For other rendering methods, use more tasks (e.g. all or half the cores per node of the machine you are using) but expect inferior perfomance. 

The default values of these parameters can be customized in the Options → Host Profiles ... → Launch Profiles → Parallel tab. Select Options → Save Settings on the menu to make such edits permanent.
Then proceed using VisIt normally. At this point or at the first Draw operation the job will be queued and your remote engine will be made available for you.

Warnings when using the remote GUI

Please DO NOT launch the GUI on the login nodes, respect the other users.


Remember that the job is submitted in real time in the standard queues, so any general queue restriction applies, and asking for too many hours or nodes will result in long waiting times.

The status of the launched job (e.g. start time, residual time, all other parameters) can be verified at anytime by logging into the server, via squeue or sview

Closing a remote engine

On either machine, it is good practice to double-check that the remote engine job is actually concluded after use.

An unused running egine will still consume your project budget!

You can check the status of your engine from the File→Compute Engine menu. When no computation is running, just click on the Close Engine button to cancel the remote job.
You can also log onto the remote machine via command line SSH and end it manually with the scancel command. Only at thi point you can close the VisIt GUI.

Batch jobs and Python Scripting

For the largest jobs that cannot fit into interactive queues, users must submit scripts with VisIt python Command Line Interface via batch SLURM jobs, instead of using the GUI. Python scripting in VisIt is as complete and powerful as the GUI. The manuals contain an exhaustive guide. Assistance, including examples and tips for python can also be found on this page of the VisIt users' forum. Here we showcase the basic workflow on LRZ machines, provide some working examples, and address some common problems.

To get started, either on the login nodes or in SLURM scripts, you can just type module load visit while module avail visit will list all available versions.

Launching scripted jobs

We provide sample job scripts for SLURM files specific for LRZ machines.

Linux Cluster
#!/bin/bash 
#SBATCH -J visit
#SBATCH --time=01:30:00 
#SBATCH --dependency=singleton    # Jobs with the same name will wait 
#SBATCH --export=NONE 
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=4       # OSPRay jobs, MPI + TBB, does not need more
#SBATCH --cluster=mpp2            # mpp2 | mmp3 
##SBATCH --constraint=quad,cache  # ONLY for mpp3
##SBATCH --mail-type=all 
##SBATCH --mail-user=<email> 

source /etc/profile.d/modules.sh 
module load slurm_setup visit 

echo ${SLURM_JOB_NAME} ${SLURM_JOB_ID} $(date) 
cpuinfo 
module list 

visit -cli -nowin -launchengine localhost -l mpiexec -np ${II} -ppn ${SLURM_NTASKS_PER_NODE} -s <your_script.py> # your python script here, also supporting own options and arguments. 
# alternatively, movie command including -movie and -sessionfile
# Check for debug and advanced options (e.g. timings) with visit -fullhelp

exit
SuperMUC-NG
#!/bin/bash 
#SBATCH -J visit
#SBATCH --time=01:30:00 
#SBATCH --dependency=singleton    # Jobs with the same name will wait 
#SBATCH --export=NONE 
#SBATCH --nodes=4                 # set the right partition below
#SBATCH --partition=micro         # test, micro, general, large
#SBATCH --ntasks-per-node=4       # OSPRay jobs, MPI + TBB, does not need more
#SBATCH --account=<account>       # your project name
##SBATCH --mail-type=all 
##SBATCH --mail-user=<email> 

source /etc/profile.d/modules.sh 
module load slurm_setup visit 

echo ${SLURM_JOB_NAME} ${SLURM_JOB_ID} $(date) 
cpuinfo 
module list 

visit -cli -nowin -launchengine localhost -l mpiexec -np ${II} -ppn ${SLURM_NTASKS_PER_NODE} -s <your_script.py> # your python script here, also supporting own options and arguments. 
# alternatively, movie command including -movie and -sessionfile
# Check for debug and advanced options (e.g. timings) with visit -fullhelp

exit 

Tips and tricks

Shortcuts to VisIt's python API.

The following two options suffice in most cases, and may save you from getting your hands too dirty:

  1. When generating a movie with the GUI, the user can select Later, tell me the command to run  when deciding how to allocate the resources for that rendering. This command can be launched in batch, although it relies on the user's filesystem (session, preferences, ...).
    Also, the session should contain a parallel engine identical to the one that needs to be used; so you cannot use this feature to move your job to a larger allocation. But you can of course reserve more time, which could be impractical for the interactive job (long queue times).
  2. The Control → Command Menu in the GUI VisIt is capable of recording and translating to python all the actions performed by the user between the push of record and stop buttons. Besides reverse-engineering all the syntax, one can record automatic actions, such as the camera positions obtained automatically in Spin Mode in the window toolbar.
    One can thus produce movies or entire scripts in this way, without using taxing Keyframing.

Limitations of Control→Command 

  • Unlike the entries the Option menu,  those of Preferences have no python equivalent. So you can't set these via scripting, you have to save them in the session used. 
  • When performing a Volume Rendering, each additional color and opacity control point (besides the one in the default colormap) has to be initialised manually (this is a bug!):

    VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())      # Always 
    [...]
    VolumeAtts.opacityControlPoints.AddControlPoints(GaussianControlPoint()) # Only when using gaussian transfer functions

Some useful commands to have at hand

  • You are told how to execute queries with the Control→Command approach; yet in batch the result is neither collected nor printed on screen by default.  After each query, you then need to add:   my_variable = GetQueryOutputValue

  • import time; time.clock()  gives you an effective python timer, measuring wall clock time. But you can use any python timer. Visit has its own timers as well (check with visit --fullhelp ).

  • DrawPlots() will draw all active plots,  SaveWindow() will print the image according to the set SaveOptions

Important difference between windowed and `-nowin` mode

When in windowed mode,  DrawPlots() will BOTH initialize the scene AND render it. A scalable rendering is then REPEATED during SaveWindow(), unless File → Set Save Option → Screen Capture is ticked.
That may double your workload when scripting in windowed mode. In (-cli) -nowin mode, as it is always the case in batch, only SaveWindow() will trigger the scalable rendering (no screen capture is possible).

Sample python scripts

The following scripts may be used for testing and as a basis to produce your own. Many of the following have been generated by Control→Command and some edits. Input test files are provided in the VisIt webpage.

Never forget to invoke quit() at the end of each script, or the job may not terminate (wasteful for your own compute budget!).

Testing Parallel Engine
Please check this section of VisIt wiki: https://www.visitusers.org/index.php?title=ParallelPorting#Making_sure_you_actually_have_a_parallel_engine
Data query: Weighted Variable Sum
import numpy as np 
import time 
outfile = 'times_temp.txt' 

OpenDatabase("RD0028/RedshiftOutput0028.boundary", 0) # Substitute for an actual dataset of yours
AddPlot("Pseudocolor", "Temperature", 1, 1)           # Substitute for an actual variable in your dataset

clk0 = time.clock() 
DrawPlots() 
clk1 = time.clock() 
Query("Weighted Variable Sum") 
temp = GetQueryOutputValue() 
clk2 = time.clock() 
if os.path.exists(outfile) and os.path.getsize(outfile) > 0: 
	f1=open(outfile, 'w+') 
	print >> f1, 'np', 'drawn_t', 'query_t', 'total_t' 
	f1.close() 
props = GetEngineProperties(GetEngineList()[0]) 
f1=open(outfile, 'a+') 
print >> f1, props.numProcessors, clk1-clk0, clk2-clk1, clk2-clk0 
f1.close() 
quit() 
Volume rendering: kernel-based, scalable (v2.13, deprecated), with timing
# This script was mostly automatically generated by the record button.
# Possibly highly redundant, but not worthy of investigation.
# Do not forget the quit() at the end and the correct file to load!!
# Also the box size and the view attributes may be wrong for your data.
import time
import numpy as np

# Parameters
imw   = 1024       # Dimension of final picture
imh   = 1024
outfile = 'times_plot.txt'
lx05  = 0.0625 * 2 # The size of a cubic cut to your dataset, your internal units 
OpenDatabase("RD0028/RedshiftOutput0028.boundary", 0) # Substitute for an actual dataset of yours
AddPlot("Volume", "Density", 1, 1)                    # Substitute for an actual variable in your dataset

AddOperator("Box", 1)
BoxAtts = BoxAttributes()
BoxAtts.amount = BoxAtts.Some  # Some, All
BoxAtts.minx = 0.5 - lx05
BoxAtts.maxx = 0.5 + lx05
BoxAtts.miny = 0.5 - lx05
BoxAtts.maxy = 0.5 + lx05
BoxAtts.minz = 0.5 - lx05
BoxAtts.maxz = 0.5 + lx05
BoxAtts.inverse = 0
SetOperatorOptions(BoxAtts, 1)

SetActivePlots(0)

SetWindowArea(0, 0, imw, imh)

InvertBackgroundColor()

RenderingAtts = RenderingAttributes()
RenderingAtts.antialiasing = 0
RenderingAtts.orderComposite = 1
RenderingAtts.depthCompositeThreads = 2
RenderingAtts.depthCompositeBlocking = 65536
RenderingAtts.alphaCompositeThreads = 2
RenderingAtts.alphaCompositeBlocking = 65536
RenderingAtts.depthPeeling = 0
RenderingAtts.occlusionRatio = 0
RenderingAtts.numberOfPeels = 16
RenderingAtts.multiresolutionMode = 0
RenderingAtts.multiresolutionCellSize = 0.002
RenderingAtts.geometryRepresentation = RenderingAtts.Surfaces  # Surfaces, Wireframe, Points
RenderingAtts.displayListMode = RenderingAtts.Auto  # Never, Always, Auto
RenderingAtts.stereoRendering = 0
RenderingAtts.stereoType = RenderingAtts.CrystalEyes  # RedBlue, Interlaced, CrystalEyes, RedGreen
RenderingAtts.notifyForEachRender = 0
RenderingAtts.scalableActivationMode = RenderingAtts.Always  # Never, Always, Auto
RenderingAtts.scalableAutoThreshold = 2000000
RenderingAtts.specularFlag = 0
RenderingAtts.specularCoeff = 0.6
RenderingAtts.specularPower = 10
RenderingAtts.specularColor = (255, 255, 255, 255)
RenderingAtts.doShadowing = 0
RenderingAtts.shadowStrength = 0.5
RenderingAtts.doDepthCueing = 0
RenderingAtts.depthCueingAutomatic = 1
RenderingAtts.startCuePoint = (-10, 0, 0)
RenderingAtts.endCuePoint = (10, 0, 0)
RenderingAtts.compressionActivationMode = RenderingAtts.Never  # Never, Always, Auto
RenderingAtts.colorTexturingFlag = 1
RenderingAtts.compactDomainsActivationMode = RenderingAtts.Never  # Never, Always, Auto
RenderingAtts.compactDomainsAutoThreshold = 256
SetRenderingAttributes(RenderingAtts)

# Logging for SetAnnotationObjectOptions is not implemented yet.
AnnotationAtts = AnnotationAttributes()
AnnotationAtts.axes2D.visible = 1
AnnotationAtts.axes2D.autoSetTicks = 1
AnnotationAtts.axes2D.autoSetScaling = 1
AnnotationAtts.axes2D.lineWidth = 0
AnnotationAtts.axes2D.tickLocation = AnnotationAtts.axes2D.Outside  # Inside, Outside, Both
AnnotationAtts.axes2D.tickAxes = AnnotationAtts.axes2D.BottomLeft  # Off, Bottom, Left, BottomLeft, All
AnnotationAtts.axes2D.xAxis.title.visible = 1
AnnotationAtts.axes2D.xAxis.title.font.font = AnnotationAtts.axes2D.xAxis.title.font.Courier  # Arial, Courier, Times
AnnotationAtts.axes2D.xAxis.title.font.scale = 1
AnnotationAtts.axes2D.xAxis.title.font.useForegroundColor = 1
AnnotationAtts.axes2D.xAxis.title.font.color = (0, 0, 0, 255)
AnnotationAtts.axes2D.xAxis.title.font.bold = 1
AnnotationAtts.axes2D.xAxis.title.font.italic = 1
AnnotationAtts.axes2D.xAxis.title.userTitle = 0
AnnotationAtts.axes2D.xAxis.title.userUnits = 0
AnnotationAtts.axes2D.xAxis.title.title = "X-Axis"
AnnotationAtts.axes2D.xAxis.title.units = ""
AnnotationAtts.axes2D.xAxis.label.visible = 1
AnnotationAtts.axes2D.xAxis.label.font.font = AnnotationAtts.axes2D.xAxis.label.font.Courier  # Arial, Courier, Times
AnnotationAtts.axes2D.xAxis.label.font.scale = 1
AnnotationAtts.axes2D.xAxis.label.font.useForegroundColor = 1
AnnotationAtts.axes2D.xAxis.label.font.color = (0, 0, 0, 255)
AnnotationAtts.axes2D.xAxis.label.font.bold = 1
AnnotationAtts.axes2D.xAxis.label.font.italic = 1
AnnotationAtts.axes2D.xAxis.label.scaling = 0
AnnotationAtts.axes2D.xAxis.tickMarks.visible = 1
AnnotationAtts.axes2D.xAxis.tickMarks.majorMinimum = 0
AnnotationAtts.axes2D.xAxis.tickMarks.majorMaximum = 1
AnnotationAtts.axes2D.xAxis.tickMarks.minorSpacing = 0.02
AnnotationAtts.axes2D.xAxis.tickMarks.majorSpacing = 0.2
AnnotationAtts.axes2D.xAxis.grid = 0
AnnotationAtts.axes2D.yAxis.title.visible = 1
AnnotationAtts.axes2D.yAxis.title.font.font = AnnotationAtts.axes2D.yAxis.title.font.Courier  # Arial, Courier, Times
AnnotationAtts.axes2D.yAxis.title.font.scale = 1
AnnotationAtts.axes2D.yAxis.title.font.useForegroundColor = 1
AnnotationAtts.axes2D.yAxis.title.font.color = (0, 0, 0, 255)
AnnotationAtts.axes2D.yAxis.title.font.bold = 1
AnnotationAtts.axes2D.yAxis.title.font.italic = 1
AnnotationAtts.axes2D.yAxis.title.userTitle = 0
AnnotationAtts.axes2D.yAxis.title.userUnits = 0
AnnotationAtts.axes2D.yAxis.title.title = "Y-Axis"
AnnotationAtts.axes2D.yAxis.title.units = ""
AnnotationAtts.axes2D.yAxis.label.visible = 1
AnnotationAtts.axes2D.yAxis.label.font.font = AnnotationAtts.axes2D.yAxis.label.font.Courier  # Arial, Courier, Times
AnnotationAtts.axes2D.yAxis.label.font.scale = 1
AnnotationAtts.axes2D.yAxis.label.font.useForegroundColor = 1
AnnotationAtts.axes2D.yAxis.label.font.color = (0, 0, 0, 255)
AnnotationAtts.axes2D.yAxis.label.font.bold = 1
AnnotationAtts.axes2D.yAxis.label.font.italic = 1
AnnotationAtts.axes2D.yAxis.label.scaling = 0
AnnotationAtts.axes2D.yAxis.tickMarks.visible = 1
AnnotationAtts.axes2D.yAxis.tickMarks.majorMinimum = 0
AnnotationAtts.axes2D.yAxis.tickMarks.majorMaximum = 1
AnnotationAtts.axes2D.yAxis.tickMarks.minorSpacing = 0.02
AnnotationAtts.axes2D.yAxis.tickMarks.majorSpacing = 0.2
AnnotationAtts.axes2D.yAxis.grid = 0
AnnotationAtts.axes3D.visible = 0
AnnotationAtts.axes3D.autoSetTicks = 1
AnnotationAtts.axes3D.autoSetScaling = 1
AnnotationAtts.axes3D.lineWidth = 0
AnnotationAtts.axes3D.tickLocation = AnnotationAtts.axes3D.Inside  # Inside, Outside, Both
AnnotationAtts.axes3D.axesType = AnnotationAtts.axes3D.ClosestTriad  # ClosestTriad, FurthestTriad, OutsideEdges, StaticTriad, StaticEdges
AnnotationAtts.axes3D.triadFlag = 1
AnnotationAtts.axes3D.bboxFlag = 1
AnnotationAtts.axes3D.xAxis.title.visible = 1
AnnotationAtts.axes3D.xAxis.title.font.font = AnnotationAtts.axes3D.xAxis.title.font.Arial  # Arial, Courier, Times
AnnotationAtts.axes3D.xAxis.title.font.scale = 1
AnnotationAtts.axes3D.xAxis.title.font.useForegroundColor = 1
AnnotationAtts.axes3D.xAxis.title.font.color = (0, 0, 0, 255)
AnnotationAtts.axes3D.xAxis.title.font.bold = 0
AnnotationAtts.axes3D.xAxis.title.font.italic = 0
AnnotationAtts.axes3D.xAxis.title.userTitle = 0
AnnotationAtts.axes3D.xAxis.title.userUnits = 0
AnnotationAtts.axes3D.xAxis.title.title = "X-Axis"
AnnotationAtts.axes3D.xAxis.title.units = ""
AnnotationAtts.axes3D.xAxis.label.visible = 1
AnnotationAtts.axes3D.xAxis.label.font.font = AnnotationAtts.axes3D.xAxis.label.font.Arial  # Arial, Courier, Times
AnnotationAtts.axes3D.xAxis.label.font.scale = 1
AnnotationAtts.axes3D.xAxis.label.font.useForegroundColor = 1
AnnotationAtts.axes3D.xAxis.label.font.color = (0, 0, 0, 255)
AnnotationAtts.axes3D.xAxis.label.font.bold = 0
AnnotationAtts.axes3D.xAxis.label.font.italic = 0
AnnotationAtts.axes3D.xAxis.label.scaling = 0
AnnotationAtts.axes3D.xAxis.tickMarks.visible = 1
AnnotationAtts.axes3D.xAxis.tickMarks.majorMinimum = 0
AnnotationAtts.axes3D.xAxis.tickMarks.majorMaximum = 1
AnnotationAtts.axes3D.xAxis.tickMarks.minorSpacing = 0.02
AnnotationAtts.axes3D.xAxis.tickMarks.majorSpacing = 0.2
AnnotationAtts.axes3D.xAxis.grid = 0
AnnotationAtts.axes3D.yAxis.title.visible = 1
AnnotationAtts.axes3D.yAxis.title.font.font = AnnotationAtts.axes3D.yAxis.title.font.Arial  # Arial, Courier, Times
AnnotationAtts.axes3D.yAxis.title.font.scale = 1
AnnotationAtts.axes3D.yAxis.title.font.useForegroundColor = 1
AnnotationAtts.axes3D.yAxis.title.font.color = (0, 0, 0, 255)
AnnotationAtts.axes3D.yAxis.title.font.bold = 0
AnnotationAtts.axes3D.yAxis.title.font.italic = 0
AnnotationAtts.axes3D.yAxis.title.userTitle = 0
AnnotationAtts.axes3D.yAxis.title.userUnits = 0
AnnotationAtts.axes3D.yAxis.title.title = "Y-Axis"
AnnotationAtts.axes3D.yAxis.title.units = ""
AnnotationAtts.axes3D.yAxis.label.visible = 1
AnnotationAtts.axes3D.yAxis.label.font.font = AnnotationAtts.axes3D.yAxis.label.font.Arial  # Arial, Courier, Times
AnnotationAtts.axes3D.yAxis.label.font.scale = 1
AnnotationAtts.axes3D.yAxis.label.font.useForegroundColor = 1
AnnotationAtts.axes3D.yAxis.label.font.color = (0, 0, 0, 255)
AnnotationAtts.axes3D.yAxis.label.font.bold = 0
AnnotationAtts.axes3D.yAxis.label.font.italic = 0
AnnotationAtts.axes3D.yAxis.label.scaling = 0
AnnotationAtts.axes3D.yAxis.tickMarks.visible = 1
AnnotationAtts.axes3D.yAxis.tickMarks.majorMinimum = 0
AnnotationAtts.axes3D.yAxis.tickMarks.majorMaximum = 1
AnnotationAtts.axes3D.yAxis.tickMarks.minorSpacing = 0.02
AnnotationAtts.axes3D.yAxis.tickMarks.majorSpacing = 0.2
AnnotationAtts.axes3D.yAxis.grid = 0
AnnotationAtts.axes3D.zAxis.title.visible = 1
AnnotationAtts.axes3D.zAxis.title.font.font = AnnotationAtts.axes3D.zAxis.title.font.Arial  # Arial, Courier, Times
AnnotationAtts.axes3D.zAxis.title.font.scale = 1
AnnotationAtts.axes3D.zAxis.title.font.useForegroundColor = 1
AnnotationAtts.axes3D.zAxis.title.font.color = (0, 0, 0, 255)
AnnotationAtts.axes3D.zAxis.title.font.bold = 0
AnnotationAtts.axes3D.zAxis.title.font.italic = 0
AnnotationAtts.axes3D.zAxis.title.userTitle = 0
AnnotationAtts.axes3D.zAxis.title.userUnits = 0
AnnotationAtts.axes3D.zAxis.title.title = "Z-Axis"
AnnotationAtts.axes3D.zAxis.title.units = ""
AnnotationAtts.axes3D.zAxis.label.visible = 1
AnnotationAtts.axes3D.zAxis.label.font.font = AnnotationAtts.axes3D.zAxis.label.font.Arial  # Arial, Courier, Times
AnnotationAtts.axes3D.zAxis.label.font.scale = 1
AnnotationAtts.axes3D.zAxis.label.font.useForegroundColor = 1
AnnotationAtts.axes3D.zAxis.label.font.color = (0, 0, 0, 255)
AnnotationAtts.axes3D.zAxis.label.font.bold = 0
AnnotationAtts.axes3D.zAxis.label.font.italic = 0
AnnotationAtts.axes3D.zAxis.label.scaling = 0
AnnotationAtts.axes3D.zAxis.tickMarks.visible = 1
AnnotationAtts.axes3D.zAxis.tickMarks.majorMinimum = 0
AnnotationAtts.axes3D.zAxis.tickMarks.majorMaximum = 1
AnnotationAtts.axes3D.zAxis.tickMarks.minorSpacing = 0.02
AnnotationAtts.axes3D.zAxis.tickMarks.majorSpacing = 0.2
AnnotationAtts.axes3D.zAxis.grid = 0
AnnotationAtts.axes3D.setBBoxLocation = 1
AnnotationAtts.axes3D.bboxLocation = (BoxAtts.minx, BoxAtts.maxx, BoxAtts.miny, BoxAtts.maxy, BoxAtts.minz, BoxAtts.maxz)
AnnotationAtts.userInfoFlag = 0
AnnotationAtts.userInfoFont.font = AnnotationAtts.userInfoFont.Arial  # Arial, Courier, Times
AnnotationAtts.userInfoFont.scale = 1
AnnotationAtts.userInfoFont.useForegroundColor = 1
AnnotationAtts.userInfoFont.color = (0, 0, 0, 255)
AnnotationAtts.userInfoFont.bold = 0
AnnotationAtts.userInfoFont.italic = 0
AnnotationAtts.databaseInfoFlag = 0
AnnotationAtts.timeInfoFlag = 1
AnnotationAtts.databaseInfoFont.font = AnnotationAtts.databaseInfoFont.Arial  # Arial, Courier, Times
AnnotationAtts.databaseInfoFont.scale = 1
AnnotationAtts.databaseInfoFont.useForegroundColor = 1
AnnotationAtts.databaseInfoFont.color = (0, 0, 0, 255)
AnnotationAtts.databaseInfoFont.bold = 0
AnnotationAtts.databaseInfoFont.italic = 0
AnnotationAtts.databaseInfoExpansionMode = AnnotationAtts.File  # File, Directory, Full, Smart, SmartDirectory
AnnotationAtts.databaseInfoTimeScale = 1
AnnotationAtts.databaseInfoTimeOffset = 0
AnnotationAtts.legendInfoFlag = 0
AnnotationAtts.backgroundColor = (0, 0, 0, 255)
AnnotationAtts.foregroundColor = (255, 255, 255, 255)
AnnotationAtts.gradientBackgroundStyle = AnnotationAtts.Radial  # TopToBottom, BottomToTop, LeftToRight, RightToLeft, Radial
AnnotationAtts.gradientColor1 = (0, 0, 255, 255)
AnnotationAtts.gradientColor2 = (0, 0, 0, 255)
AnnotationAtts.backgroundMode = AnnotationAtts.Solid  # Solid, Gradient, Image, ImageSphere
AnnotationAtts.backgroundImage = ""
AnnotationAtts.imageRepeatX = 1
AnnotationAtts.imageRepeatY = 1
AnnotationAtts.axesArray.visible = 1
AnnotationAtts.axesArray.ticksVisible = 1
AnnotationAtts.axesArray.autoSetTicks = 1
AnnotationAtts.axesArray.autoSetScaling = 1
AnnotationAtts.axesArray.lineWidth = 0
AnnotationAtts.axesArray.axes.title.visible = 1
AnnotationAtts.axesArray.axes.title.font.font = AnnotationAtts.axesArray.axes.title.font.Arial  # Arial, Courier, Times
AnnotationAtts.axesArray.axes.title.font.scale = 1
AnnotationAtts.axesArray.axes.title.font.useForegroundColor = 1
AnnotationAtts.axesArray.axes.title.font.color = (0, 0, 0, 255)
AnnotationAtts.axesArray.axes.title.font.bold = 0
AnnotationAtts.axesArray.axes.title.font.italic = 0
AnnotationAtts.axesArray.axes.title.userTitle = 0
AnnotationAtts.axesArray.axes.title.userUnits = 0
AnnotationAtts.axesArray.axes.title.title = ""
AnnotationAtts.axesArray.axes.title.units = ""
AnnotationAtts.axesArray.axes.label.visible = 1
AnnotationAtts.axesArray.axes.label.font.font = AnnotationAtts.axesArray.axes.label.font.Arial  # Arial, Courier, Times
AnnotationAtts.axesArray.axes.label.font.scale = 1
AnnotationAtts.axesArray.axes.label.font.useForegroundColor = 1
AnnotationAtts.axesArray.axes.label.font.color = (0, 0, 0, 255)
AnnotationAtts.axesArray.axes.label.font.bold = 0
AnnotationAtts.axesArray.axes.label.font.italic = 0
AnnotationAtts.axesArray.axes.label.scaling = 0
AnnotationAtts.axesArray.axes.tickMarks.visible = 1
AnnotationAtts.axesArray.axes.tickMarks.majorMinimum = 0
AnnotationAtts.axesArray.axes.tickMarks.majorMaximum = 1
AnnotationAtts.axesArray.axes.tickMarks.minorSpacing = 0.02
AnnotationAtts.axesArray.axes.tickMarks.majorSpacing = 0.2
AnnotationAtts.axesArray.axes.grid = 0
SetAnnotationAttributes(AnnotationAtts)

VolumeAtts = VolumeAttributes()
VolumeAtts.legendFlag = 1
VolumeAtts.lightingFlag = 0
VolumeAtts.colorControlPoints.GetControlPoints(0).colors = (64, 0, 75, 255)
VolumeAtts.colorControlPoints.GetControlPoints(0).position = 0
VolumeAtts.colorControlPoints.GetControlPoints(1).colors = (118, 42, 131, 255)
VolumeAtts.colorControlPoints.GetControlPoints(1).position = 0.1
VolumeAtts.colorControlPoints.GetControlPoints(2).colors = (153, 112, 171, 255)
VolumeAtts.colorControlPoints.GetControlPoints(2).position = 0.2
VolumeAtts.colorControlPoints.GetControlPoints(3).colors = (194, 165, 207, 255)
VolumeAtts.colorControlPoints.GetControlPoints(3).position = 0.3
VolumeAtts.colorControlPoints.GetControlPoints(4).colors = (231, 212, 232, 255)
VolumeAtts.colorControlPoints.GetControlPoints(4).position = 0.4
VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())
VolumeAtts.colorControlPoints.GetControlPoints(5).colors = (247, 247, 247, 255)
VolumeAtts.colorControlPoints.GetControlPoints(5).position = 0.5
VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())
VolumeAtts.colorControlPoints.GetControlPoints(6).colors = (217, 240, 211, 255)
VolumeAtts.colorControlPoints.GetControlPoints(6).position = 0.6
VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())
VolumeAtts.colorControlPoints.GetControlPoints(7).colors = (166, 219, 160, 255)
VolumeAtts.colorControlPoints.GetControlPoints(7).position = 0.7
VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())
VolumeAtts.colorControlPoints.GetControlPoints(8).colors = (90, 174, 97, 255)
VolumeAtts.colorControlPoints.GetControlPoints(8).position = 0.8
VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())
VolumeAtts.colorControlPoints.GetControlPoints(9).colors = (27, 120, 55, 255)
VolumeAtts.colorControlPoints.GetControlPoints(9).position = 0.9
VolumeAtts.colorControlPoints.AddControlPoints(ColorControlPoint())
VolumeAtts.colorControlPoints.GetControlPoints(10).colors = (0, 68, 27, 255)
VolumeAtts.colorControlPoints.GetControlPoints(10).position = 1
VolumeAtts.colorControlPoints.smoothing = VolumeAtts.colorControlPoints.Linear  # None, Linear, CubicSpline
VolumeAtts.colorControlPoints.equalSpacingFlag = 0
VolumeAtts.colorControlPoints.discreteFlag = 0
VolumeAtts.colorControlPoints.categoryName = ""
VolumeAtts.opacityAttenuation = 0.647059  
VolumeAtts.opacityMode = VolumeAtts.FreeformMode  # FreeformMode, GaussianMode, ColorTableMode
#controlPoints does not contain any GaussianControlPoint objects.
VolumeAtts.resampleFlag = 1
VolumeAtts.resampleTarget = 50000
VolumeAtts.opacityVariable = "default"
VolumeAtts.compactVariable = "default"
VolumeAtts.freeformOpacity = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 
201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255)
VolumeAtts.useColorVarMin = 1
VolumeAtts.colorVarMin = 2     # Your data minimum 
VolumeAtts.useColorVarMax = 1
VolumeAtts.colorVarMax = 200   # Your data maximum 
VolumeAtts.useOpacityVarMin = 0
VolumeAtts.opacityVarMin = 0
VolumeAtts.useOpacityVarMax = 0
VolumeAtts.opacityVarMax = 0
VolumeAtts.smoothData = 1
VolumeAtts.samplesPerRay = 800
VolumeAtts.rendererType = VolumeAtts.RayCasting  # Splatting, Texture3D, RayCasting, RayCastingIntegration, SLIVR, RayCastingSLIVR, Tuvok
VolumeAtts.gradientType = VolumeAtts.SobelOperator  # CenteredDifferences, SobelOperator
VolumeAtts.num3DSlices = 200
VolumeAtts.scaling = VolumeAtts.Log  # Linear, Log, Skew
VolumeAtts.skewFactor = 1
VolumeAtts.limitsMode = VolumeAtts.OriginalData  # OriginalData, CurrentPlot
VolumeAtts.sampling = VolumeAtts.KernelBased  # KernelBased, Rasterization, Trilinear
VolumeAtts.rendererSamples = 6
#transferFunction2DWidgets does not contain any TransferFunctionWidget objects.
VolumeAtts.transferFunctionDim = 1
VolumeAtts.lowGradientLightingReduction = VolumeAtts.Lower  # Off, Lowest, Lower, Low, Medium, High, Higher, Highest
VolumeAtts.lowGradientLightingClampFlag = 0
VolumeAtts.lowGradientLightingClampValue = 1
VolumeAtts.materialProperties = (0.4, 0.75, 0, 15)
SetPlotOptions(VolumeAtts)

SaveWindowAtts = SaveWindowAttributes()
SaveWindowAtts.outputToCurrentDirectory = 1
SaveWindowAtts.outputDirectory = "."
SaveWindowAtts.fileName = "visit"
SaveWindowAtts.family = 1
SaveWindowAtts.format = SaveWindowAtts.PNG  # BMP, CURVE, JPEG, OBJ, PNG, POSTSCRIPT, POVRAY, PPM, RGB, STL, TIFF, ULTRA, VTK, PLY
SaveWindowAtts.width = imw
SaveWindowAtts.height = imh
SaveWindowAtts.screenCapture = 1
SaveWindowAtts.saveTiled = 0
SaveWindowAtts.quality = 80
SaveWindowAtts.progressive = 0
SaveWindowAtts.binary = 0
SaveWindowAtts.stereo = 0
SaveWindowAtts.compression = SaveWindowAtts.None  # None, PackBits, Jpeg, Deflate
SaveWindowAtts.forceMerge = 0
SaveWindowAtts.resConstraint = SaveWindowAtts.EqualWidthHeight  # NoConstraint, EqualWidthHeight, ScreenProportions
SaveWindowAtts.advancedMultiWindowSave = 0
SetSaveWindowAttributes(SaveWindowAtts)

View3DAtts = View3DAttributes()
View3DAtts.viewNormal = (0.2, 0.8, 0.5)
View3DAtts.focus = (0.5, 0.5, 0.5)
View3DAtts.viewUp = (0, 0, 1)
View3DAtts.viewAngle = 30
View3DAtts.parallelScale = 0.1
View3DAtts.nearPlane = -0.2
View3DAtts.farPlane = 0.2
View3DAtts.imagePan = (0, 0)
View3DAtts.imageZoom = 1
View3DAtts.perspective = 1
View3DAtts.eyeAngle = 2
View3DAtts.centerOfRotationSet = 0
View3DAtts.centerOfRotation = (0.5, 0.5, 0.5)
View3DAtts.axis3DScaleFlag = 0
View3DAtts.axis3DScales = (1, 1, 1)
View3DAtts.shear = (0, 0, 1)
View3DAtts.windowValid = 1
SetView3D(View3DAtts)

clock1= time.clock()
DrawPlots()
clock2= time.clock()

clock3 = time.clock()
SaveWindow()
clock4 = time.clock()

if not os.path.exists(outfile):
   f1=open(outfile, 'w+')
   print >> f1,  'np', 'pip_t', 'ren_t',
   f1.close()
   
props = GetEngineProperties(GetEngineList()[0])
f1=open(outfile, 'a+')
print >> f1,  props.numProcessors, clock2-clock1, clock4-clock3
f1.close()

quit()