# Advanced topics

This section covers several advanced topics related to OVITO’s scripting interface:

> - Saving and loading pipelines

> - Specifying the number of processor cores

## Saving and loading pipelines

The `ovito.io.export_file()` function lets you to save the computed output of a pipeline to disk. But how do you save the definition of the pipeline itself, including the modifiers and their parameters, to a file? OVITO can save the entire scene to a `.ovito` state file using the `Scene.save()` method. Thus, in order to save a `Pipeline` you need to first make it part of the scene by calling its `add_to_scene()` method:

    import ovito
    from ovito.io import import_file
    from ovito.modifiers import CoordinationAnalysisModifier

    pipeline = import_file("input/simulation.dump")
    pipeline.modifiers.append(CoordinationAnalysisModifier(cutoff = 3.4))
    # ...
    pipeline.add_to_scene()
    ovito.scene.save("output/mypipeline.ovito")

The saved state can be restored by calling the `Scene.load()` method. This function loads all saved data pipelines and makes them available in the `Scene.pipelines` list:

    import ovito

    ovito.scene.load("output/mypipeline.ovito")
    pipeline = ovito.scene.pipelines[0]
    data = pipeline.compute()

Of course, it is also possible to open the .ovito state file with the graphical OVITO application, or, conversely, to use the graphical application to create a data pipeline by hand and then save that pipeline to a .ovito file for future use.

You can either load the state file from a script at runtime using the `Scene.load()` method or preload the state file when running the script using the ovitos interpreter. This is done by specifying the -o command line option:

    ovitos -o mypipeline.ovito script.py

The code in `script.py` will now be executed in an environment where the `Scene` was already populated with the state loaded from the .ovito scene file. Instead of setting up a new pipeline from scratch, the script can now work with the existing pipeline(s) that were restored from the state file:

    import ovito

    pipeline = ovito.scene.pipelines[0]

    # Replace the data file that serves as pipeline input with a different one:
    pipeline.source.load("input/second_file.dump")
    # Adjust modifier parameters of the existing pipeline:
    pipeline.modifiers[0].cutoff = 3.1

    data = pipeline.compute()

## Specifying the number of processor cores

Some computation functions of OVITO have been parallelized in order to make use of all available processor cores. This includes, for example, computationally expensive modifiers such as `PolyhedralTemplateMatchingModifier`, `ClusterAnalysisModifier` or `ComputePropertyModifier`, and the software-based rendering engines `TachyonRenderer` and `OSPRayRenderer`.

By default, these parallelized algorithms will make use of all available cores of your CPU. This default number is determined by OVITO using the function QThread.idealThreadCount(), which can be queried as follows:

    >>> from ovito.qt_compat import QtCore
    >>> print(QtCore.QThread.idealThreadCount())
    4

Sometimes it is desirable to restrict OVITO to a single CPU core only, for example when running multiple instances of OVITO in parallel. This can be achieved in two ways. The graphical application ovito and the script interpreter ovitos both support the command line parameter --nthreads, which allows overriding the number of CPU cores used by parallel algorithms:

    ovitos --nthreads 1 script.py

The second option is to set the `OVITO_THREAD_COUNT` environment variable prior to invoking or importing OVITO. This approach always works: for the GUI application, the script interpreter ovitos, but also for scripts running in an external Python interpreter that imports the `ovito` module:

    export OVITO_THREAD_COUNT=1
    python script.py