VsHdf5 User Guide

VsHdf5 Introduction

VsHdf5 is a collection of Python classes that provide an interface between VizSchema and Hdf5. These classes make it easy to read and write VizSchema-compliant files, which may be the result of simulation code dumps or analysis scripts. VizSchema-compliant files may be visualized in Composer, or other visualization software, such as VisIt.

Requirements

VsHdf5 has been developed using Python 2.7. It works with Python 2.6 as well, and probably Python 3.0 although that is currently not tested. VsHdf5 must be able to import pytables and numpy. When importing VsHdf5, if these modules cannot be loaded, an exception is thrown. VsHdf5 supports VizSchema version 2.1.

Usage

To use VsHdf5, first make sure that VsHdf5 (and numpy and pytables) are in your PYTHONPATH. Then simply use:

import VsHdf5

in your Python script.

Reading in VizSchema data from a file

To read an object from an existing VizSchema-compliant file in your Python script, simply create the object and pass in the name of the file and the name of the object in the file:

obj = VsHdf5.Object(fileName=filename, name=objectname)

where Object could be one of:

  • Dataset
    • Field
    • History
    • Particles
  • Group
    • RunInfo
    • TimeGroup
    • Limits
  • Mesh
    • StructuredMesh
    • UnstructuredMesh
    • UniformCartesianMesh
    • RectilinearMesh

So for instance, to read particles from a Vorpal dump file from a species called electrons, you could write:

e = VsHdf5.Particles(fileName='baseName_electrons_1.h5', name='electrons')

This will create an object called ‘e’ in Python, that contains both the data in the dataset ‘electrons’ in the file ‘baseName_electrons_1.h5’, as well as the attributes associated with that data. The data can be accessed as

e.dataset

or

e[:]

both of which are a numpy array, and can be sliced and manipulated with the usual numpy operators. You can get a list of the attributes that were stored in the dataset in the file by invoking

attrs = e.attributeList

which will return a dictionary with key/value pairs representing the attributes.

For objects that do not have datasets (those that are Hdf5 groups with only attributes in the file), then dataset = None.

Optionally, you can specify a location in the Hdf5 file from which to read the data or group:

e = VsHdf5.Particles(fileName='baseName_electrons_1.h5', name='electrons', location = '/fluids')

If not specified, the default location of ‘root’ is used (‘/’).

You can also read in a dataset and attributes directly after the object has been created:

e = VsHdf5.Particles()
array, attrs = e.readParticles('baseName_electrons_1.h5', 'electrons')

In this invocation, array will contain the numpy dataset, and attrs will contain the dictionary of attributes.

Certain objects often only occur once in a given file, such as Limits, Meshes, and RunInfo objects. For these types of objects, you can read from a file without specifying the name of the group or dataset that you want to read. VsHdf5 will search through the file until it finds a group or object of the correct type, and read it in for you. So you could read the (single) Limits group in a field file by invoking:

l=VsHdf5.Limits(fileName='gamma2D01_universe_0.h5')

The name of the Limits group in the file is contained in the data member

l.name

Required Attributes

Some objects require certain attributes to be VizSchema compliant. Typically, if you read an object from a simulation dump file, then all of the required attributes will be there. You can change individual attribute by using the methods

object.removeAttribute(attName)
object.assignAttribute(attName, attValue)

There are additional optional attributes for VizSchema. See the VizSchema documentation and VsHdf5.py docstrings for more details. The following attributes are required for the objects below. In some cases, there are default values.

Meshes (Hdf5 Group or Dataset):

Meshes are important types of objects for VizSchema, and deserve more attention here. Meshes may be datasets or groups in a Hdf5 file, depending on the kind of mesh. Currently, VsHdf5 supports reading and writing of mesh objects called StructuredMesh, UnstructuredMesh, UniformCartesianMesh, and RectilinearMesh. Each of these kinds require different attributes (see below). There is also a generic mesh object that makes it easier to read a mesh from a file. If you invoke:

m = VsHdf5.Mesh(fileName='gamma2D01_nodalE_0.h5')

for instance, then VsHdf5 will search for the (single) group or dataset that is a mesh in the file, will determine the kind of mesh, and will cast itself into that particular kind. So here, for instance, since the gamma2D01 simulation was in Cylindrical coordinates (ZR), we find that the mesh object is a RectilinearMesh.

In [5]: m = VsHdf5.Mesh(fileName='gamma2D01_nodalE_0.h5')
In [6]: m
Out[6]: <VsHdf5.RectilinearMesh instance at 0x104b88170>
Rectilinear Meshes (Hdf5 Group)
meshName
Name of the group to be written in the file. Default = objectName
axis0data
Dataset representing the coordinates of the mesh in direction 0
axis1data
Dataset representing the coordinates of the mesh in direction 1. Required if simulation is 2-Dimensional.
axis2data
Dataset representing the coordinates of the mesh in direction 2. Required if simulation is 3-Dimensional.
axis0Name
Name of the dataset corresponding to the first axis. Default = axis0
axis1Name
Name of the dataset corresponding to the second axis. Default = axis1
axis2Name
Name of the dataset corresponding to the third axis. Default = axis2
limits
Name of a limits group that gives the spatial limits of the simulation
UniformCartesian Meshes (Hdf5 Group)
meshName
Name of the group to be written in the file. Default = objectName
lowerBounds
Array of physical coordinates representing the left, bottom, back corner of the simulation domain
upperBounds
Array of physical coordinates representing the right, top, front corner of the simulation domain
numCells
Array of integers giving the number of computational cells in each direction
startCell
Cell index of lowerBounds, default = [0,0,0]
Structured Meshes (Hdf5 Dataset)
meshName
Name of the group to be written in the file. Default = objectName
Unstructured Meshes (Hdf5 Group)
meshName
Name of the group to be written in the file. Default = objectName
pointsData
Dataset of physical coordinates of vertexes of the mesh (reals)
edgesData
Dataset of connectivity between vertexes of the mesh (ints)
facesData
Dataset of connectivity between vertexes of the mesh (ints)
polygonsData
Dataset of connectivity between vertexes of the mesh (ints)
pointsName
Name of the dataset containing vertex coordinates. Default = “points”
polygonsName
Name of the dataset containing vertex connectivity. Default = “polygons”

Note

Only one of edgesData, facesData, or polygonsData is needed. pointsData is always required.

Fields (Hdf5 Dataset)

fieldName
Name of the dataset to be written in the file. Default = objectName
mesh
Name of a mesh group that the field is defined upon
limits
Name of a limits group that gives the spatial limits of the simulation
timeGroup
Name of a time group that indicates the simulation time and step
offset
Centering of the data. default = ‘none’
dumpTime
Simulation time when the data was dumped. default = 0.0

Histories (Hdf5 Dataset)

historyName
Name of the dataset to be written in the file. Default = objectName
mesh
Name of a mesh group that the field is defined upon, typically a 1-Dimensional time series

Particles (Hdf5 Dataset)

particlesName
Name of the dataset to be written in the file. Default = objectName
charge
The charge of the particle species
mass
The mass of the particle species
numPtclsInMacro
The number of physical particles per simulation particle
limits
Name of a limits group that gives the spatial limits of the simulation
timeGroup
Name of a time group that indicates the simulation time and step
numSpatialDims
Number of spatial dimensions. default = 3
vsNumSpatialDims
Number of spatial dimensions. default = 3
dumpTime
Simulation time when the data was dumped. default = 0.0

RunInfo (Hdf5 Group)

runInfoName
Name of the group to be written in the file. Default = objectName

TimeGroups (Hdf5 Group)

timeGroupName
Name of the group to be written in the file. Default = objectName
dumpTime
Simulation time when the data was dumped.

Reading in an entire file

It is also possible to parse an entire VizSchema-compliant file. To do this, invoke:

f = VsHdf5.VsFileReader(fileName=fileName)

This will create an object that contains all of the datasets and groups in the file that have VizSchema attributes. This does not guarantee that the file is VizSchema compliant however. In particular,

f.objectDict

is a Python dictionary with key equal to the name of the object (Field, Mesh, etc.) and value equal to a VsHdf5 object of the appropriate type. As with reading in individual objects, the objects in the dictionary will contain both datasets and attributes as appropriate to the type of object.

Now you can read in a group by calling it’s name explicitly

electrons = f.objectDict['electrons']
limits = f.objectDict['globalGridGlobalLimits']

Special Accessor methods

Some attributes are commonly used in analysis scripts, and so they have their own accessor methods. The value of any attribute can be found by

att = object.attribute(key)

where key is the name of the attribute. If the attribute does not exist in the object, then att = None.

For most objects (dataset and group types), where applicable:

object.getType(): return the value of 'vsType'.
object.getKind(): return the value of 'vsKind'.
object.getLowerBounds(): return the value of 'vsLowerBounds'.
object.getUpperBounds(): return the value of 'vsUpperBounds'.
object.getNumCells(): return the value of 'vsNumCells'.
object.getStartCell(): return the value of 'vsStartCell'.
object.getCentering(): return the value of 'vsCentering'.
object.getDumpTime(): return the value of 'time'.

For TimeGroup objects:

object.getTime(): return the value of 'vsTime'.
object.getDumpStep(): return the value of 'vsStep'.

For Particles objects:

object.getCharge(): return the value of 'charge'.
object.getMass(): return the value of 'mass'.
object.getNumPtclsInMacro(): return the value of 'numPtclsInMacro'.
object.getNumSpatialDims(): return the value of 'vsNumSpatialDims'.

Writing a VizSchema-compliant file from data

To write VizSchema-compliant data into a file, simply call the VsHdf5 objects write method, such as:

e.writeParticles(filename)

Similarly for fields (writeField), meshes (writeMesh), etc. See below.

Some objects require that certain attributes be defined. In this case, if you try to write the object to a file without defining those attributes, then a warning will be written to stdout and the object will not be written to a file. Similarly, if a dataset or group with the same name as the object to be written already exists in the file, it will not be overridden, and a warning will be printed.

If you have created a dataset that you would like to write into a file in a VizSchema-compliant fashion, you can do this by constructing the needed objects by hand (as opposed to reading them in from an existing file). Consider the following example:

lb=numpy.double(0.)
ub=numpy.double(1.)
nc=numpy.int(100)
ts = VsHdf5.UniformCartesianMesh(name='timeSeries')
ts.writeMesh('outputFile.vsh5', lowerBounds=lb, upperBounds=ub, numCells=nc)

array = numpy.zeros(100)
d = VsHdf5.History(name='myHistory')
d.assignDataset(array)
#[add any required attributes, e.g.]
d.assignAttribute('vsType','variable')
d.assignAttribute('vsMesh','timeSeries')
d.writeHistory('outputFile.vsh5')

This will create a file called ‘outputFile.vsh5’ with a 10x10 dataset called ‘myHistory’, with the attributes vsType=variable and vsMesh=timeSeries. Notice that we first created a mesh object that is the 1-Dimensional time series on which the history is defined. Also note that arrays and scalar numerical values that are passed to write methods must be numpy objects, not Python lists.

Example of Writing a VizSchema-compliant file from existing data

import VsHdf5

# read in the file
f=VsHdf5.VsFileReader(fileName='ECDriftQuad_electrons_1.h5')

#print file contents
print f.objectDict

electrons = f.objectDict['electrons']
limits = f.objectDict['globalGridBlobalLimits']
runInfo = f.objectDict['runInfo']
timeGroup = f.objectDict['time']

#print time group attributes
print timeGroup.attributeList

#print the dump time and dump step from the time group
print timeGroup.getDumpTime()
print timeGroup.getDumpStep()

#overwrite the attribute "vsStep" with a new value of 1
timeGroup.assignAttribute('vsStep',1)

#overwrite the attribute "vsTime" with a new value of 1e-1
timeGroup.assignAttribute('vsTime', 1e-1)

#print new time group attributes
print timeGroup.attributeList

#give the name of the new output file
of = 'outfile.vsh5'

#write the new timeGroup data to a file and copy the rest of the file as old
electrons.writeParticles(of,timeGroup='time')
runInfo.writeRunInfo(of)
limits.writeLimits(of)
timeGroup.writeTimeGroup(of)