Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Adding new plots to UVCDAT

benbu edited this page · 2 revisions

In this tutorial we show how to add a new plot to UV-CDAT.

Pipeline Execution results

Prerequisites

  • Working installation of UVCDAT 1.3 or greater
  • [UVCDAT 1.3 only] VisTrails submodule updated to commit 655ee329277d7e9412ee5cbe15c76bc4a322c236

Outline

  1. Create VisTrails Pipeline
  2. Register Plot with UV-CDAT
  3. Create a PipelineHelper

Step 1 - Create VisTrails Pipeline

  1. Open UVCDAT, and make a simple plot to use as a starting point for your custom plot pipeline.

    • In this example we create a VCS-BoxPlot-ASD using the 'clt' variable from file 'clt.nc' (located in UVCDAT's sample_data directory).
  2. From the main menu, select VisTrails > Builder to bring up the VisTrails Builder window.

  3. Build your custom plot pipeline

from numpy import uint8, ndarray
import vtk

#get the cdms transient variable object from the CDMSVariable module
cdms_var = var_module.var

#get the underlying numpy array
numpy_arr = cdms_var.data

#convert array to uint8 for use with vtk
data_matrix = numpy_arr.astype(uint8)

# For VTK to be able to use the data, it must be stored as a VTK-image. This can be done by the 
# vtkImageImport-class which imports raw data and stores it.
dataImporter = image_import_in.vtkInstance
# The preaviusly created array is converted to a string of chars and imported.
data_string = data_matrix.tostring()
dataImporter.CopyImportVoidPointer(data_string, len(data_string))
# The type of the newly imported data is set to unsigned char (uint8)
dataImporter.SetDataScalarTypeToUnsignedChar()
# Because the data that is imported only contains an intensity value (it isnt RGB-coded or something
# similar), the importer must be told this is the case.
dataImporter.SetNumberOfScalarComponents(1)

#get extents of array for vtk, and make sure we have the right dimensions
ext1 = len(numpy_arr)-1
if isinstance(numpy_arr[0], ndarray):
    ext2 = len(numpy_arr[0])-1
    if isinstance(numpy_arr[0][0], ndarray):
        ext3 = len(numpy_arr[0][0])-1
        if isinstance(numpy_arr[0][0][0], ndarray):
            raise Exception("Expecting 3D data, got 4D or greater instead")
    else:
        raise Exception("Expecting 3D data, got 2D instead")
else:
    raise Exception("Expecting 3D data, got 1D instead")

extents = [0, ext1, 0, ext2, 0, ext3]

# The following two functions describe how the data is stored and the dimensions of the array it is
# stored in. I have to admit however, that I honestly dont know the difference between
# SetDataExtent() and SetWholeExtent() although VTK complains if not both are used.
dataImporter.SetDataExtent(*extents)
dataImporter.SetWholeExtent(*extents)

image_import = image_import_in
+ The rest of the pipeline was built to mimic the python code in the vtk example![Complete Plot Pipeline](http://i.imgur.com/pdVjSVa.jpg)
  1. Execute your custom plot pipeline to make sure it works and you get the desired result in the UV-CDAT spreadsheet.

  2. Important When you're happy with your results, go back to the VisTrails Builder window and remove the CDMSVariable and CellLocation modules. These modules are generated by UV-CDAT. (Notice the two missing modules in the following image, marked by yellow rectangles)Pipeline with Modules Removed

  3. From the VisTrails builder, save your vistrail (we named ours TranslucentVolume.vt)

Step 2 - Register Plot with UV-CDAT

Now that we have a plot, we need to add it to UV-CDAT's registry. This is located at /vistrails/vistrails/core/uvcdat/plots. This folder contains all of the plot packages.

  1. Create a new folder with the name of the package you are creating (e.g. 'NewVTK')
    • cd /usr/local/uvcdat/1.3.1/vistrails/vistrails/core/uvcdat/plots
    • mkdir NewVTK
  2. Copy the vt file generated in the previous step into this folder
    • `cp ~/Documents/TranslucentVolume.vt NewVTK/
  3. Create a new configuration file for the plot in the same folder
    • emacs NewVTK/TranslucentVolume.cfg
[global]
cellnum = 1
filenum = 1
varnum = 1
dependencies = edu.utah.sci.vistrails.vtk
+ This basically just says our plot uses one cell, one variable, and depends on the vtk package
  1. Create a package registry config file in the same folder
    • emacs NewVTK/registry.cfg
[Translucent Volume]
config_file = TranslucentVolume.cfg
vt_file = TranslucentVolume.vt
+ The name in the brackets is what users will see in the gui
  1. Add the package to the bottom of the main registry file (one level above the NewVTK dir)
    • emacs registry.cfg
...

[NewVTK]
codepath = NewVTK
config_file = registry.cfg
helper = core.uvcdat.plots.NewVTK.NewVTKPipelineHelper
+ The last line references the PipelineHelper we are about to create. Normally these are defined inside of the VisTrails package definitions, but since we didn't create a new VisTrails package for this example, we'll just place it inside our NewVTK folder.

Step 3 - Create a PipelineHelper

The PipelineHelper is the glue needed to match variable module to the plot pipeline we just created. In this case it is fairly simple, but it can be more complicated when multiple variables are involved.

  1. Create a new python file in the package registry folder we just created
    • emacs NewVTK/__init__.py
from packages.uvcdat_cdms.pipeline_helper import CDMSPipelineHelper

class NewVTKPipelineHelper(CDMSPipelineHelper):

    @staticmethod
    def build_plot_pipeline_action(controller, version, var_modules, 
                                   plots,row, col, template=None):

        # only support one plot
        plot = plots[0]

        # This function copies all of the modules and connections from the
        # vt file specified in the plot registry config. It returns all 
        # the generated pipeline items, as well as a list of ports that
        # accept a CDMSVariable in the pipeline.
        pipeline_items, cdms_ports = \
                CDMSPipelineHelper.create_plot_workflow_items(
                        plot.workflow, controller, row, col)

        # We need to match variable modules to the ports returned in above call.
        # Since our plot only works on a single variable, we'll just match the 
        # first in each list.
        variable_matches = [(var_modules[0], cdms_ports[0])]      

        #finalize pipeline creation
        action = CDMSPipelineHelper.finish_plot_workflow(controller,
                                                         pipeline_items, 
                                                         variable_matches, 
                                                         version)

        return action

Now you should be able to use your plot in UVCDAT.

Plot list showing newly added plot

All of the files used in this example can be found on branch uvcdat-add-new-plot-example of the VisTrails repository.

Something went wrong with that request. Please try again.