User-defined file writers

OVITO Pro Python scripts

To export data in a file format OVITO doesn’t support, you can write a file writer in Python. It’s a class derived from FileWriterInterface, which implements the write() method:

from ovito.io import FileWriterInterface
from ovito.pipeline import Pipeline

class MyCustomFileWriter(FileWriterInterface):

    def write(self, *, filename: str, frame: int, pipeline: Pipeline, **kwargs):
        data = pipeline.compute(frame)
        with open(filename, "w") as file:
            file.write(f"{data.particles.count}\n")
            for xyz in data.particles.positions:
                file.write(f"{xyz[0]} {xyz[1]} {xyz[2]}\n")

The write() method receives the name of the output file, the pipeline whose output should be exported, and the frame to export. It evaluates the pipeline and writes the data to the file. As with other extensions, the parameter list must end with **kwargs, which accepts further arguments passed by the system.

In a Python script, you pass the class to the export_file() function:

from ovito.io import import_file, export_file

pipeline = import_file("input/simulation.dump")
export_file(pipeline, "output/file.custom", format=MyCustomFileWriter)

Once installed as an extension, the file writer appears in the list of available formats of OVITO Pro’s file export function.

Writing trajectories

By default, the system calls write() once for each frame to be exported, i.e. the output format stores a single frame per file. If your format can store several frames in one file, let supports_trajectories() return True. The system then calls write() just once, passing the list of all frames to be exported in the frames argument:

from collections.abc import Sequence

class MyTrajectoryWriter(FileWriterInterface):

    def supports_trajectories(self):
        return True

    def write(self, *, filename: str, frames: Sequence[int], pipeline: Pipeline, **kwargs):
        with open(filename, "w") as file:
            for frame in frames:
                data = pipeline.compute(frame)
                file.write(f"Frame {frame}: {data.particles.count} particles\n")
                yield frame / len(frames)   # Report progress

As shown in this example, a file writer can report its progress using yield statements (see Long-running computations).

A file writer designed to export one particular data object, e.g. a DataTable, can implement the optional exportable_type() method to return the class of the objects it supports. OVITO Pro then lets the user pick an object of that type from the pipeline output, and in a Python script, the key argument of export_file() selects it. The selected object is passed to write() in the object_ref argument.

User parameters

A file writer can expose parameters, which OVITO Pro displays in its file export dialog:

from traits.api import Bool

class AppendFileWriter(FileWriterInterface):

    # A parameter controlling the behavior of the file writer:
    append_mode = Bool(False, label="Append to existing file")

    def write(self, *, filename: str, frame: int, pipeline: Pipeline, **kwargs):
        data = pipeline.compute(frame)
        with open(filename, "a" if self.append_mode else "w") as file:
            file.write(f"{data.particles.count}\n")

In a Python script, export_file() forwards additional keyword arguments to the file writer to initialize parameters with matching names:

export_file(pipeline, "output/results.txt", format=AppendFileWriter, append_mode=True)