Python Interface
Tip
Silo’s python interface is designed to compile and work with either Python 2 or Python 3
Silo’s CMake logic looks for python3 first.
If it cannot find python3, then it looks for python.
Warning
CMake’ing with -DSILO_ENABLE_SHARED:BOOL=OFF will disable the python module.
It is probably easiest to understand the Python interface to Silo by examining some examples and tests. In the source code distribution, you can find some examples in tools/python and tests in tests directories. Here, we briefly describe Silo’s Python interface.
The Python interface will be in the lib dir of the Silo installation, named Silo.so.
To use it, Python needs to be told where to find it.
You can do this a couple of ways; through the PYTHONPATH environment variable or by explicitly adding the Silo installation lib dir to Python’s path using sys.path.append().
For example, if Silo is installed to /foo/bar, this works…
% env PYTHONPATH=/foo/bar/lib python
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple `LLVM` 7.0.0] on darwin
Type "help", "copyright", "credits" or "license" for more info.
>>> import Silo
Or, if you prefer to use sys.path.append…
% python
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple `LLVM` 7.0.0] on darwin
Type "help", "copyright", "credits" or "license" for more info.
>>> import sys
>>> sys.path.append("/foo/bar/lib")
>>> import Silo
Silo.Open()
Summary: Open a Silo file (See
DBOpen)C Signature:
DBfile Silo.Open(filename, flags);
Arguments:
Arg name
Description
filenameName of the Silo file to open
flagsPass either
Silo.DB_READif you will only read objects from the file orSilo.DB_APPENDif you need to also write data to the file.Description:
Returns a
DBfileobject as a Python object
Silo.Create()
Summary: Create a new silo file (See
DBCreate)C Signature:
DBfile Silo.Create(filename, info, driver, clobber)
Arguments:
Arg name
Description
filename[required string] name of the file to create
info[required string] comment to be stored in the file
driver[optional int] which
driverto use. Pass eitherSilo.DB_PDBorSilo.DB_HDF5. Note that advanceddriverfeatures are not available through the Python interface. Default isSilo.DB_PDB.clobber[optional int] indicate whether any existing file should be clobbered. Pass either
Silo.DB_CLOBBERorSilo.DB_NOCLOBBER. Default isSilo.DB_CLOBBER.Description:
Returns a
DBfileobject as a Python object
<DBfile>.GetToc()
Summary: Get the table of contents
C Signature:
DBtoc <DBfile>.GetToc()
Description:
Returns a
DBTocobject as a Python object. This probably should really be a Python dictionary object but it is not presently. There are no methods defined for aDBTocobject but if you print it, you can get the list of objects in the current working directory in the file.
<DBfile>.GetVarInfo()
Summary: Get metadata and bulk data of any object (See
DBGetObject)C Signature:
dict <DBfile>.GetVarInfo(name, flag)
Arguments:
Arg name
Description
name[required string]
nameof object to readflag[optional int]
flagto indicate if object bulk/raw data should be included. Pass 0 to not also read object bulk/raw data. Pass non-zero to also read object bulk/raw data. Default is 0.Description:
Returns a Python dictionary object for any Silo object. If object bulk data is not also read, then the dictionary members for those sub-objects will contain a string holding the name/path of either a sub-object or a primitive array. Note that on the HDF5 driver, if friendly HDF5 names were not used to create the file, then the string paths for these sub-objects are often cryptic references to primitive arrays in the hidden
/.silodirectory of the Silo file such as/.silo/#000042.When this method is applied to raw (or primitive) variable object, it will return a python dictionary object indicating the data type and dimensions of the primitive variable.
This method is poorly named. A better name is probably
GetObject.
<DBfile>.GetVar()
Summary: Get a primitive array (See
DBReadVar)C Signature:
tuple <DBfile>.GetVar(name)
Arguments:
Arg name
Description
name[required string]
nameof primitive array to readDescription:
This method returns the bulk data of a raw Silo variable as a Python tuple. However, because the method provides no means for returning the variable’s type, it will return python integer data for anything that has Silo type
DB_SHORT,DB_INT,DB_LONGorDB_LONG_LONGand python floating point data forDB_FLOATorDB_DOUBLE. This is potentially problematic when a writer intends to overwrite the data in the file with new raw variable data. Overwriting Silo data requires that the new data take no more space in the file than the original data. Otherwise, bad things will happen. To get better information regarding a raw Silo variable’s true data type in the file, useDBGetVarInfo().
<DBfile>.SetDir()
Summary: Set current working directory of the Silo file (See
DBSetDir)C Signature:
NoneType <DBfile>.SetDir(name)
Arguments:
Arg name
Description
name[required string]
nameof directory to setDescription:
Sets the current working directory of the Silo file
<DBfile>.Close()
Summary: Close the Silo file
C Signature:
NoneType <DBfile>.Close()
Description:
Close the Silo file
<DBfile>.WriteObject()
Summary: Write a Python dictionary as a Silo object (See
DBWriteObject)C Signature:
NoneType <DBfile>.WriteObject(name, obj_dict)
Arguments:
Arg name
Description
name[required string]
nameof the new object to writeobj_dict[required dict] Python dictionary containing object data
Description:
This method will write any Python dictionary object to a Silo file as a Silo object. Here’s the rub. Readers employing Silo’s high level C interface (e.g.
DBGetUcdmesh,DBGetQuadvar, etc.) will be able recognize an object so written if and only if the dict object’s structure matches a known high-level Silo object.So, you can use this method to write objects that can be read later via Silo’s C language, high-level object methods such as
DBGetUcdmeshandDBGetMaterial, etc. as long as the Python dictionary’s members match what Silo expects.Often, the easiest way to interrogate how a given Python dict object should be structured to match a Silo high-level object is to find an example object in some Silo file and read it into Python with
GetVarInfo(). Be aware, however, that many Silo objects have a lot of optional members which are not required to ensure the given object matches a high-level Silo object.We demonstrate this approach by first reading a multi-mesh object from an existing Silo file. Then, using it as a template, we write a multi-mesh object to a new Silo file and finally confirm we have created a valid, high-level object by test reading it into Silo’s browser.
Python code:
import Silo # # create destination database # db2 = Silo.Create("foobar.silo", "test python", Silo.DB_HDF5, Silo.DB_CLOBBER) # # Find an existing object type to read # Note: example file can be found in https://github.com/visit-dav/visit/blob/develop/data/silo_hdf5_test_data.tar.xz db = Silo.Open("multi_ucd3d.silo") mm = db.GetVarInfo("mesh1",0) print(mm) # # Remove any optional (optlist) items you don't plan to use # try: mm['extentssize']=0 except: pass try: del mm['extents'] except: pass try: del mm['zonecounts'] except: pass try: del mm['has_external_zones'] except: pass # # overwrite relevant entries with YOUR data # mm['nblocks']=3 mm['meshtypes']=(510,510,510) # 510 is DB_UCDMESH mm['meshnames']=("snap","crackle","pop") # # Write the object # db2.WriteObject("foo",mm) db2.Close() db.Close()
Ok, save the above script as
gorfo.pyand run itpython3 ./gorfo.py
It generates the following output…
{'name': 'mesh1', 'type': 'multiblockmesh', 'nblocks': 36, 'cycle': 48, 'blockorigin': 1, 'grouporigin': 1, 'time': 4.800000190734863, 'dtime': 4.8, 'extentssize': 6, 'meshtypes': '/.silo/#001419', 'meshnames': '/.silo/#001420', 'extents': '/.silo/#001421', 'zonecounts': '/.silo/#001422', 'has_external_zones': '/.silo/#001423'}
It also creates the new multimesh object in
foobar.silo. We can confirm that the object is correct by reading it with browser…browser -e foo foobar.silo INFO: opening `foobar.silo' as $1 = DBmultimesh: struct id = 0 nblocks = 3 ngroups = 0 guihide = false blockorigin = 1 grouporigin = 1 extentssize = 0 mrgtree_name = (null) tv_connectivity = 0 disjoint_mode = 0 topo_dim = not specified file_ns = (null) block_ns = (null) block_type = 0 repr_block_idx = not specified alt_nodenum_vars = NULL alt_zonenum_vars = NULL empty_cnt = 0 empty_list = NULL meshids = NULL meshnames[0] = {"snap", "crackle", "pop"} meshtypes[0] = {DB_UCDMESH, DB_UCDMESH, DB_UCDMESH} dirids = NULL extents = NULL zonecounts = NULL has_external_zones = NULL lgroupings = 0 groupings = NULL groupnamesIt is fine to create a dict object with additional members too. For example, if you create a dict object that is intended to be a Silo material object, you can add additional members to it and readers will still be able to read it via the high-level C interface method
DBGetMaterial. Of course, such readers will not be aware of any additional members so handled.It is also fine to create wholly new kinds of Silo objects for which there are no corresponding high-level interface methods in the C language interface. Such an object can be read only as a generic object using the
DBGetObject()C language interface method.
<DBfile>.Write()
Summary: Write primitive array data to a Silo file (see DBWrite)
C Signature:
NoneType <DBfile>.Write(name, data, [dims, datatype])
Arguments:
Arg name
Description
name[required string]
nameof the primitive arraydata[required tuple] the
datato writedims[optional tuple] the dimensions of
data. If not present, defaults to size ofdata.datatype[optional int] the Silo data type (e.g.
DB_INT, …). If not present, guessed by type of first value indata.Description:
This method will write a raw variable to a Silo file. If you need to overwrite Silo data, this is the method to use because it allows the writer to specify the Silo datatype.
<DBfile>.MkDir()
Summary: Make a directory in a Silo file
C Signature:
NoneType <DBfile>.MkDir(name)
Arguments:
Arg name
Description
name[required string]
nameof the directory to createDescription:
Creates a new directory in a Silo file