User-defined file writers

OVITO provides a flexible framework for exporting data to custom file formats through the implementation of user-defined file writers. You can do this by creating a new Python class that derives from the ovito.io.FileWriterInterface base class. By implementing the required methods of this interface, you can define how data should be written to your custom file format.

The FileWriterInterface requires the implementation of the following methods:

  1. write(): This is the main method that performs the actual writing of data to the file. It must be implemented by the derived class. The method receives several parameters, including the filename, trajectory frame(s), pipeline, and any additional keyword arguments. The method should handle writing the data to the specified file, iterating over the trajectory frames if necessary.

  2. supports_trajectories() (optional): This method can be overridden to indicate whether the file writer supports exporting an entire trajectory to a single file (instead of writing one file per frame). If this method returns True, the write() method will be invoked once to export a sequence of frames. If it returns False, the write() method will be called separately for each frame.

  3. exportable_type() (optional): This method can be overridden to specify the type of data that the file writer can export. It should return either Pipeline or DataObject, indicating the type of data the writer can handle.

Here is a basic outline of how to implement a custom file writer:

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

class MyCustomFileWriter(FileWriterInterface):

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

Once you have implemented your custom file writer, you can use it with the export_file() function in your Python programs to export a pipeline’s output data:

from ovito.io import import_file, export_file

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

By following the steps described in Packaging and installation of user extensions for OVITO, you can create a custom file writer that integrate seamlessly with OVITO’s data export functionality, allowing you to export data in any format you require from the GUI.

Exposing file writer parameters

Your file writer class can expose adjustable user parameters based on the Traits framework. In OVITO Pro, the parameter traits of your class are editable by the user in the file export dialog during an export operation. The system works similar to user-defined parameters of Python modifiers.

from ovito.io import FileWriterInterface
from ovito.pipeline import Pipeline
from traits.api import Bool

class AppendFileWriter(FileWriterInterface):

    # Define a custom trait to control 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):
        mode = 'a' if self.append_mode else 'w'
        with open(filename, mode) as file:
            data = pipeline.compute(frame)
            file.write(f"{data.particles.count}\n")

When using your file writer in a standalone Python program, the export_file() function forwards any additional keyword arguments to your file writer class to initialize its parameter traits with matching names.

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