ovito.pipeline

This module contains object types that are part of OVITO’s data pipeline system.

Pipeline:

Pipeline data sources:

class ovito.pipeline.Pipeline

This class represents a data pipeline, i.e. a data source plus a chain of zero or more modifiers that manipulate the data on the way through the pipeline.

Pipeline creation

Pipelines have a data source, which loads or dynamically generates the input data entering the pipeline. This source object is accessible through the Pipeline.source field and may be replaced if needed. For pipelines created by the import_file() function, the data source is set to be a FileSource instance, which is responsible for loading the input data from the external file and feeding it into the pipeline. Another type of data source is the StaticSource, which allows to explicitly specify the set of data objects that enter the pipeline.

The modifiers that are part of the pipeline are accessible through the Pipeline.modifiers list. This list is initially empty and you can populate it with modifiers of various kinds (see the ovito.modifiers module). Note that it is possible to employ the same Modifier instance in more than one pipeline. It is also valid to assign the same source object as source of several pipelines to make them share the same input data.

Pipeline evaluation

Once the pipeline is set up, an evaluation can be requested by calling compute(), which means that the input data is loaded/generated by the source and all modifiers of the pipeline are applied to the data one after the other. The compute() method returns a PipelineFlowState structure containing all the data objects produced by the pipeline. Under the hood, an automatic caching system makes sure that unnecessary file accesses and computations are avoided. Repeatedly calling compute() will not trigger a recalculation of the pipeline’s results unless you modify the pipeline source, the sequence of modifiers or any of the modifier’s parameters in some way.

Usage example

The following code example shows how to create a new pipeline by importing an MD simulation file and inserting a SliceModifier to cut away some of the particles. Finally, the total number of remaining particles is printed.

from ovito.io import import_file
from ovito.modifiers import SliceModifier

# Import a simulation file. This creates a Pipeline object.
pipeline = import_file('input/simulation.dump')

# Insert a modifier that operates on the data:
pipeline.modifiers.append(SliceModifier(normal=(0,0,1), distance=0))

# Compute the effect of the slice modifier by evaluating the pipeline.
output = pipeline.compute()
print("Remaining particle count:", len(output.particle_properties['Position']))

It is possible to also access the input data that enters the modification pipeline. It is cached by the FileSource constituting the source of the pipeline:

# Access the cached input data of the FileSource:
input = pipeline.source
print("Input particle count:", len(input.particle_properties['Position']))

Data visualization and export

Finally, if you are interested in producing a graphical rendering of the data generated by a Pipeline, you need to make the pipeline part of the current three-dimensional scene by calling the add_to_scene() method. Another possibility is to pass the pipeline to the ovito.io.export_file() function to export its output data to a file.

add_to_scene()

Inserts the pipeline into the three-dimensional scene by appending it to the ovito.DataSet.scene_pipelines list. The visual representation of the computed data will appear in rendered images and in the interactive viewports of the graphical OVITO version.

You can remove the pipeline from the scene again by calling remove_from_scene().

compute(frame=None)

Computes and returns the results of this data pipeline.

This method requests an evaluation of the pipeline and blocks until the input data has been obtained from the data source and all modifiers have been applied to the data. When invoking the compute() method repeatedly without changing the pipeline between calls, it may return immediately with cached results from an earlier evaluation.

The optional frame parameter determines at which animation time the pipeline is evaluated. Animation frame numbering starts at 0. If no frame is specified, the current animation position (given by the global state variable AnimationSettings.current_frame) is used.

The compute() method raises a RuntimeError when the pipeline could not be successfully evaluated for some reason. This can happen due to invalid modifier parameters or input file parsing errors, for example.

Note: The returned PipelineFlowState data collection contains data objects that are owned by the pipeline. That means it is not safe to modify these objects as this would lead to unexpected side effects. You can however use the DataCollection.copy_if_needed() method to make a copy of data objects that you want to modify in place. See the PipelineFlowState class for more information.

Parameters:frame (int) – The animation frame number at which the pipeline should be evaluated.
Returns:A PipelineFlowState containing the output of the data pipeline.
modifiers

The sequence of modifiers in the pipeline.

This list contains any modifiers that are applied to the input data provided by the pipeline’s data source. You can add and remove modifiers as needed using standard Python append() and del operations. The head of the list represents the beginning of the pipeline, i.e. the first modifier receives the data from the data source, manipulates it and passes the results on to the second modifier in the list and so forth.

Example: Adding a new modifier to the end of a data pipeline:

pipeline.modifiers.append(WrapPeriodicImagesModifier())
remove_from_scene()

Removes the visual representation of the pipeline from the scene by deleting it from the ovito.DataSet.scene_pipelines list. The output data computed by the pipeline will disappear from the viewports after calling this method.

source

The object that provides the data entering the pipeline. This typically is a FileSource instance if the node was created by a call to import_file(). You can assign a new source to the pipeline if needed. See the ovito.pipeline module for a list of available pipeline source types. Note that you can even make several pipelines share the same source object.

class ovito.pipeline.Modifier

This is the base class for all modifier types in OVITO. See the ovito.modifiers module for a list of concrete modifier types that can be inserted into a data Pipeline.

enabled

Controls whether the modifier is applied to the data. Disabled modifiers are skipped during evaluation of a data pipeline.

Default:True
class ovito.pipeline.StaticSource
Base class:ovito.data.DataCollection

Serves as a data source for a Pipeline. Being a type of DataCollection, a StaticSource can store a set of data objects, which will be passed to the Pipeline as input data. One typically fills a StaticSource with some data objects and wires it to a Pipeline as follows:

from ovito.pipeline import StaticSource, Pipeline
from ovito.data import SimulationCell
from ovito.modifiers import CreateBondsModifier
from ovito.io import export_file

# Create a new Pipeline with a StaticSource as data source:
pipeline = Pipeline(source = StaticSource())

# Insert a new SimulationCell object into the StaticSource:
cell = SimulationCell(pbc = (False, False, False))
with cell:
    cell[:,0] = (4,0,0)
    cell[:,1] = (0,2,0)
    cell[:,2] = (0,0,2)
pipeline.source.objects.append(cell)

# Insert two particles into the StaticSource:
xyz = [[0,0,0],[2,0,0]]
pipeline.source.particle_properties.create('Position', data=xyz)

# Apply a modifier:
pipeline.modifiers.append(CreateBondsModifier(cutoff = 3.0))

# Write pipeline results to an output file:
export_file(pipeline, 'output/structure.data', 'lammps/data', atom_style='bond')

Another common use of the StaticSource class is in conjunction with the ovito.io.ase.ase_to_ovito() function.

class ovito.pipeline.FileSource
Base class:ovito.data.DataCollection

This object type can serve as a Pipeline.source and takes care of reading the input for the Pipeline from an external data file.

You normally do not need to create an instance of this class; the import_file() function does it for you and wires the configured FileSource to the Pipeline. If desired, the FileSource.load() method allows you to load a different input file later on:

from ovito.io import import_file

# Create a new pipeline with a FileSource:
pipeline = import_file('input/first_file.dump')

# Get the data from the first file:
data1 = pipeline.compute()

# Use FileSource.load() method to replace the pipeline's input with a different file 
pipeline.source.load('input/second_file.dump')

# Now the pipeline gets its input data from the new file:
data2 = pipeline.compute()

File sources are furthermore used in conjunction with certain modifiers. The CalculateDisplacementsModifier can make use of a FileSource to load a reference configuration from a separate input file. Another example is the LoadTrajectoryModifier, which employs its own FileSource instance to load the particle trajectories from disk.

Data access

You can call the file source’s compute() method to retrieve a PipelineFlowState containing the data that was read from the input file. Typically you would use this method to access a Pipeline’s unmodified input data.

Note that the FileSource itself derives from the DataCollection base class. It operates like a cache for the data that was read from the external file during the most recent load operation. You may directly access this cached data through the methods and properties inherited from the DataCollection interface.

from ovito.io import import_file

# This creates a Pipeline with an attached FileSource.
pipeline = import_file('input/simulation.dump')

# Retrieve the data for the first frame from the FileSource.
data = pipeline.source.compute(0)
print(data.particle_properties['Position'][...])

# Or access the data currently cached in the FileSource.
print(pipeline.source.particle_properties['Position'][...])
adjust_animation_interval

A Boolean flag that controls whether the animation length in OVITO is automatically adjusted to match the number of frames in the loaded file or file sequence.

The current length of the animation in OVITO is managed by the global AnimationSettings object. The number of frames in the external file or file sequence is indicated by the num_frames attribute of this FileSource. If adjust_animation_interval is True, then the animation length will be automatically adjusted to match the number of frames provided by the FileSource.

In some situations it makes sense to turn this option off, for example, if you import several data files into OVITO simultaneously, but their frame counts do not match.

Default:True
compute(frame=None)

Retrieves the data from this data source, which will load it from the external file if needed.

The optional frame parameter determines the frame to retrieve, which must be in the range 0 through (num_frames-1). If no frame is specified, the current animation position is used (as given by the global setting AnimationSettings.current_frame). This is frame 0 by default.

The FileSource uses a caching mechanism to keep one or more frames in memory. Thus, invoking compute() repeatedly to retrieve the same frame will typically be very fast.

Note: The returned PipelineFlowState data collection contains data objects that are owned by the FileSource. That means it is not safe to modify these objects as this would lead to unexpected side effects. You can however use the DataCollection.copy_if_needed() method to make a copy of data objects that you want to modify in place. See the PipelineFlowState class for more information.

Parameters:frame (int) – The animation frame number at which the source should be evaluated.
Returns:A PipelineFlowState containing the loaded data.
load(location, **params)

Associates this data source with a new input file, where it will retrieve its data from.

The function accepts additional keyword arguments, which are forwarded to the format-specific file importer. For further information, please see the documentation of the import_file() function, which has the same function interface as this method.

Parameters:location (str) – The local file or remote sftp:// URL to load.
num_frames

The number of frames found in the input file or sequence of input files (read-only).

source_path

The path or URL of the file (or file sequence) where this data source retrieves its input data from.

class ovito.pipeline.TrajectoryLineGenerator
Base class:ovito.pipeline.StaticSource

A type of pipeline source that generates trajectory lines by sampling the particle positions of another Pipeline. It is used to statically visualize the trajectories of particles. The trajectory line generation must be explicitly triggered by a call to generate(). The visual appearance of the trajectory lines is controlled by a TrajectoryLineDisplay attached to the generated TrajectoryLines data object.

Usage example:

from ovito.pipeline import TrajectoryLineGenerator, Pipeline
from ovito.io import import_file
from ovito.vis import TrajectoryLineVis

# Load a particle simulation sequence:
pipeline = import_file('input/simulation.*.dump')

# Create a second pipeline for the trajectory lines:
traj_pipeline = Pipeline()

# Create data source and assign it to the second pipeline.
# The first pipeline provides the particle positions.
traj_pipeline.source = TrajectoryLineGenerator(
    source_pipeline = pipeline,
    only_selected = False
)

# Generate the trajectory lines by sampling the 
# particle positions over the entire animation interval.
traj_object = traj_pipeline.source.generate()

# Configure trajectory line visualization:
traj_object.vis.width = 0.4
traj_object.vis.color = (1,0,0)
traj_object.vis.shading = TrajectoryLineVis.Shading.Flat

# Insert both pipelines into the scene to make both the particles and 
# the trajectory lines visible in rendered images:
pipeline.add_to_scene()
traj_pipeline.add_to_scene()
frame_interval

The animation frame interval over which the particle positions are sampled to generate the trajectory lines. Set this to a tuple of two integers to specify the first and the last animation frame; or use None to generate trajectory lines over the entire input sequence.

Default:None
generate()

Generates the trajectory lines by sampling the positions of the particles from the source_pipeline in regular animation time intervals. The method creates a TrajectoryLines data object to store the trajectory line data. The object is inserted into this data collection and also returned to the caller.

only_selected

Controls whether trajectory lines should only by generated for currently selected particles.

Default:True
sampling_frequency

Length of the animation frame intervals at which the particle positions should be sampled.

Default:1
source_pipeline

The Pipeline providing the time-dependent particle positions from which the trajectory lines will be generated.

unwrap_trajectories

Controls whether trajectory lines should be automatically unwrapped at the box boundaries when the particles cross a periodic boundary.

Default:True
class ovito.pipeline.ReferenceConfigurationModifier
Base class:ovito.pipeline.Modifier

This is the common base class of analyis modifiers that perform some kind of comparison of the current particle configuration with a reference configuration. For example, the CalculateDisplacementsModifier, the AtomicStrainModifier and the WignerSeitzAnalysisModifier are modifier types that require a reference configuration as additional input.

Constant and sliding reference configurations

The ReferenceConfigurationModifier base class provides various fields that allow you to specify the reference particle configuration. By default, frame 0 of the currently loaded simulation sequence is used as reference. You can select any other frame with the reference_frame field. Sometimes an incremental analysis is desired, instead of a fixed reference configuration. That means the sliding reference configuration and the current configuration are separated along the time axis by a constant period (delta t). The incremental analysis mode is activated by setting the use_frame_offset flag and specifying the desired frame_offset.

External reference configuration file

By default, the reference particle positions are obtained by evaluating the same data pipeline that also provides the current particle positions, i.e. which the modifier is part of. That means any modifiers preceding this modifier in the pipeline will also act upon the reference particle configuration, but not modifiers that follow in the pipeline.

Instead of taking it from the same data pipeline, you can explicitly provide a reference configuration by loading it from a separate data file. To this end the reference field contains a FileSource object and you can use its load() method to load the reference particle positions from a separate file.

Handling of periodic boundary conditions and cell deformations

Certain analysis modifiers such as the CalculateDisplacementsModifier and the AtomicStrainModifier calculate the displacements particles experienced between the reference and the current configuration. Since particle coordinates in periodic simulation cells are often stored in a wrapped form, caculating the displacement vectors is non-trivial when particles have crossed the periodic boundaries. By default, the minimum image convention is used in these cases, but you can turn if off by setting minimum_image_convention to False, for example if the input particle coordinates are given in unwrapped form.

Furthermore, if the simulation cell of the reference and the current configuration are different, it makes a slight difference whether displacements are calculated in the reference or in the current frame. The affine_mapping property controls the type of coordinate mapping that is used.

affine_mapping
Selects the type of affine deformation applied to the particle coordinates of either the reference or the current configuration prior to the actual analysis computation. Must be one of the following modes:
  • ReferenceConfigurationModifier.AffineMapping.Off
  • ReferenceConfigurationModifier.AffineMapping.ToReference
  • ReferenceConfigurationModifier.AffineMapping.ToCurrent

When affine mapping is disabled (AffineMapping.Off), particle displacement vectors are simply calculated from the difference of current and reference positions, irrespective of the cell shape the reference and current configuration. Note that this can introduce a small geometric error if the shape of the periodic simulation cell changes considerably. The mode AffineMapping.ToReference applies an affine transformation to the current configuration such that all particle positions are first mapped to the reference cell before calculating the displacement vectors. The last option, AffineMapping.ToCurrent, does the reverse: it maps the reference particle positions to the deformed cell before calculating the displacements.

Default:ReferenceConfigurationModifier.AffineMapping.Off
frame_offset

The relative frame offset when using a sliding reference configuration (if use_frame_offset == True). Negative frame offsets correspond to reference configurations that precede the current configuration in time.

Default:-1
minimum_image_convention

If False, then displacements are calculated from the particle coordinates in the reference and the current configuration as is. Note that in this case the calculated displacements of particles that have crossed a periodic simulation cell boundary will be wrong if their coordinates are stored in a wrapped form. If True, then the minimum image convention is applied when calculating the displacements of particles that have crossed a periodic boundary.

Default:True
reference

A pipeline source object that provides the reference particle positions. By default this field is None, in which case the modifier obtains the reference particle positions from data pipeline it is part of. You can explicitly assign a data source object such as a FileSource or a StaticSource to this field to specify an explicit reference configuration.

For backward compatibility reasons with older OVITO versions, a FileSource instance is automatically created for you on the first read access to this field. You can call its load() method to load the reference particle positions from a data file.

# The modifier that requires a reference config:
mod = CalculateDisplacementsModifier()

# Load the reference config from a separate input file.
mod.reference = FileSource()
mod.reference.load('input/simulation.0.dump')
Default:None
reference_frame

The frame number to use as reference configuration. Ignored if use_frame_offset is set.

Default:0
use_frame_offset

Determines whether a sliding reference configuration is taken at a constant time offset (specified by frame_offset) relative to the current frame. If False, a constant reference configuration is used (set by the reference_frame parameter) irrespective of the current frame.

Default:False