In this tutorial we show how to add a new plot to UV-CDAT.
Open UVCDAT, and make a simple plot to use as a starting point for your custom plot pipeline.
From the main menu, select
VisTrails > Builder to bring up the VisTrails Builder window.
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, ndarray): ext2 = len(numpy_arr)-1 if isinstance(numpy_arr, ndarray): ext3 = len(numpy_arr)-1 if isinstance(numpy_arr, 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)
Execute your custom plot pipeline to make sure it works and you get the desired result in the UV-CDAT spreadsheet.
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)
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.
[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
[Translucent Volume] config_file = TranslucentVolume.cfg vt_file = TranslucentVolume.vt
+ The name in the brackets is what users will see in the gui
... [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.
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.
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 # 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, cdms_ports)] #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.
All of the files used in this example can be found on branch uvcdat-add-new-plot-example of the VisTrails repository.