API version changes

This page documents changes to the Python programming interface introduced by new OVITO program releases. It is supposed to help script authors adapt their scripts to the most recent version of the Python API.

Migration from OVITO 2.x to 3.0

This major program update introduces significant interface changes. Various classes and methods have been deprecated and replaced with new facilities. The old interfaces no longer show up in the Python reference documentation, however, a backward compatibility layer has been put in place to support execution of old scripts. Thus, in many cases old Python scripts written for OVITO 2.x should still work, at least for now, but it is recommended to update them in order to use the new programming interfaces described in the following. The backward compatibility layer will be removed in a future version of OVITO.

Data pipelines and data sources

The ovito.PipelineSceneNode class has been renamed to Pipeline and moved into the new ovito.pipeline module. The old class name reflected the fact that instances are part of the scene graph in OVITO. However, this aspect is less important from the Python script perspective and therefore Pipeline is a more natural name choice.

The StaticSource is a type of data source for a Pipeline and can hold a set of data objects that should be processed by the pipeline. The FileSource class maintains its role as a data source for a pipeline, reading the input data from an external file. The PipelineFlowState is a type of data collection that is returned by the Pipeline.compute() method and holds the results of a pipeline evaluation.

The PipelineSceneNode.output field has been deprecated. It used to provide access to the cached results of the data pipeline after a call to PipelineSceneNode.compute(). Now the computation results should be stored in a local variable instead:

pipeline = import_file('simulation.dump')
data = pipeline.compute()

In the example above, the variable data points to a DataCollection returned by compute().

The DataCollection class

The DataCollection class no longer implements a dictionary interface to provide access to the contained data objects. Instead, the new objects field exposes all objects in an unordered list. The add(), remove() and replace() methods have been deprecated. Instead, you can insert/remove data objects as follows:

cell = SimulationCell()

The DataCollection properties .cell, .surface and .dislocations have been deprecated. Instead, the new general methods find() and expect() should be used to retrieve particular data objects, e.g.:

cell = data.expect(SimulationCell)

The properties .number_of_particles, .number_of_half_bonds and .number_of_full_bonds have been deprecated. Instead, these numbers should be obtained from the length of the Position particle property and the Bonds objects, respectively:

num_particles = len(data.particle_properties['Position'])
num_bonds = len(data.expect(Bonds))

The create_particle_property() and create_user_particle_property() methods have been replaced by the create_property() method in the new ParticlesView helper class, which is returned by the DataCollection.particles attribute. Similarly, the create_bond_property() and create_user_bond_property() methods have been replaced by the create_property() method in the new BondsView helper class, which is returned by the DataCollection.bonds attribute.

Particle and bond properties

The ParticleProperty and BondProperty classes now have a common base class, Property, which provides the functionality common to all property types in OVITO.

Access to standard particle and bond properties via Python named attributes has been deprecated. Instead, they should be looked up by name, similar to user-defined properties:

data = pipeline.compute()
pos_property = data.particles.position     # <-- Deprecated
pos_property = data.particles['Position']  # <-- Correct

Note that the DataCollection.particles object behaves like a (read-only) dictionary of particle properties, providing a filtered view of the data objects list in the DataCollection.

The array and marray accessor attributes of the ParticleProperty and BondProperty classes have been deprecated. Instead, these classes themselves now behave like Numpy arrays:

pos_property = data.particles['Position']
print('Number of particles:', len(pos_property))
print('Position of first particle:', pos_property[0])

However, note that ParticleProperty and BondProperty are not true Numpy array subclasses; they just mimic the Numpy array interface to some extent. You can turn them into true Numpy arrays if needed in two ways:

pos_array = numpy.asarray(pos_property)
pos_array = pos_property[...]

In both cases no data copy is made. The Numpy array will be a view of the internal memory of the Property. To modify the data stored in a Property, write access must be explicitly requested using a Python with statement:

with pos_property:
    pos_property[0] = (0,0,0)

The old .marray accessor attribute and a call to the deprecated ParticleProperty.changed() method to finalize the write transaction are no longer needed.

Simulation cells

The SimulationCell class now behaves like a read-only Numpy array of shape (3,4), providing direct access to the cell vectors and the cell origin. The old .array and .marray accessor attributes have been deprecated. Write access to the cell matrix now requires a with statement:

cell = pipeline.source.cell
with cell:
    cell[:,1] *= 1.1   # Expand cell along y-direction by scaling second cell vector


OVITO 3.x no longer works with a half-bond representation. Older program versions represented each full bond A<–>B as two separate half-bonds A–>B and B–>A. Now, only a single record per bond is maintained by OVITO.

The ovito.data.Bonds class has been removed. Instead, bond topology is now stored as a standard BondProperty named Topology, which is accessible through the BondsView object.

The Bonds.Enumerator helper class has been renamed to BondsEnumerator and its constructor now expects a DataCollection instead of a Bonds object.

File I/O

The ovito.io.import_file() function no longer requires the multiple_frames flag to load simulation files containing more than one frame. This happens automatically now. Furthermore, import_file() now supports loading file sequences that are specified as an explicit list of file paths. This makes it possible to load sets of files that are distributed over more than directory as one animation sequence.

The ovito.io.export_file() function now accepts not only a Pipeline object which generates the data to be exported, but alternatively also any DataCollection or individual data objects.

Some of the file format names accepted by export_file() have been renamed and the new vtk/trimesh has been added, which allows to export a SurfaceMesh to a VTK geometry file.

The FileSource.loaded_file attribute has been removed. The path of the input data file is now accessible as an attribute of the DataCollection interface, e.g.:

pipeline = import_file('input.dump')
data = pipeline.compute()

The old DataCollection.to_ase_atoms() and DataCollection.create_from_ase_atoms() methods have been refactored into the new ovito.io.ase module and are now standalone functions named ovito_to_ase() and ase_to_ovito(). The latter requires that the caller provides an existing data collection object as destination for the atoms data, e.g. a StaticSource instance.

Changes to the global DataSet class

The DataSet.selected_node and DataSet.scene_nodes fields have been renamed to DataSet.selected_pipeline and DataSet.scene_pipelines respectively.

Changes to modifiers

The SelectExpressionModifier has been renamed to ExpressionSelectionModifier.

The DeleteSelectedParticlesModifier has been renamed to DeleteSelectedModifier and can now operate on bonds too.

The SelectParticleTypeModifier has been renamed to SelectTypeModifier and can now operate on bonds too. Furthermore, it is now possible to specify the set of particle types to select in terms of type names. Before, it was only possible to select particles based on numeric type IDs.

The following modifier classes have been generalized and gained a new operate_on field that controls what kind(s) of data elements (e.g. particles, bonds, surfaces, etc.) the modifier should act on:

SurfaceMesh data object

The SurfaceMesh class has been greatly extended. It now provides access to the periodic domain the surface mesh is embedded in as well as the vertices and faces of the mesh. Export of the triangle mesh to a VTK file is now performed using the standard ovito.io.export_file() function ('vtk/trimesh' output format).

Furthermore, the SurfaceMesh class now provides the locate_point() method, which can be used to determine whether a spatial point is located on the surface manifold, inside the region enclosed by the surface, or outside.