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

    filename

    Name of the Silo file to open

    flags

    Pass either Silo.DB_READ if you will only read objects from the file or Silo.DB_APPEND if you need to also write data to the file.

  • Description:

    Returns a DBfile object 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 driver to use. Pass either Silo.DB_PDB or Silo.DB_HDF5. Note that advanced driver features are not available through the Python interface. Default is Silo.DB_PDB.

    clobber

    [optional int] indicate whether any existing file should be clobbered. Pass either Silo.DB_CLOBBER or Silo.DB_NOCLOBBER. Default is Silo.DB_CLOBBER.

  • Description:

    Returns a DBfile object as a Python object










































<DBfile>.GetToc()

  • Summary: Get the table of contents

  • C Signature:

    DBtoc <DBfile>.GetToc()
    
  • Description:

    Returns a DBToc object as a Python object. This probably should really be a Python dictionary object but it is not presently. There are no methods defined for a DBToc object 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] name of object to read

    flag

    [optional int] flag to 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 /.silo directory 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] name of primitive array to read

  • Description:

    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_LONG or DB_LONG_LONG and python floating point data for DB_FLOAT or DB_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, use DBGetVarInfo().










































<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] name of directory to set

  • Description:

    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] name of the new object to write

    obj_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 DBGetUcdmesh and DBGetMaterial, 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.py and run it

    python3 ./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
    groupnames  
    

    It 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] name of the primitive array

    data

    [required tuple] the data to write

    dims

    [optional tuple] the dimensions of data. If not present, defaults to size of data.

    datatype

    [optional int] the Silo data type (e.g. DB_INT, …). If not present, guessed by type of first value in data.

  • 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] name of the directory to create

  • Description:

    Creates a new directory in a Silo file