.. include:: ../../macros.hrst
.. include:: ../../abbreviations.hrst

.. _chapter:TargetedTrame:

Targeted: Trame
######################


Introduction
=============================

Trame, is Python framework to build applications with interactive
scientific visualization that can be driven from a Web browser.
Those applications can leverage a VTK and/or ParaView backend for
large data processing and rendering along with many other Python libraries.

The trame website provide many examples showcasing VTK or ParaView. - https://kitware.github.io/trame/


Running a trame application
=============================

ParaView 5.13+ now support a ``--venv /path/to/venv`` that let you extend ParaView python with your own virtual-environment and therefore libraries. While this option is very powerful, they are a couple caveats that needs your attention.

1. The ``venv`` needs to be created with the same version as ParaView is using. For example, ParaView 5.13 is using ParaView 3.10, which means the venv needs to be created with a Python 3.10.*.
2. The ``venv`` can not provide different version of the Python libraries that are already available within ParaView (i.e. numpy, pandas).


Virtual Environment creation
----------------------------------

.. code-block:: console

   python3.10 -m venv .venv
   source .venv/bin/activate
   pip install -U pip
   pip install trame trame-vtk trame-vuetify # Add anything more you plan to use


Running a script locally
----------------------------------

If you create a ``pv_cone.py`` file with the following content.


.. code-block:: python

    r"""
    Installation requirements:
        pip install trame trame-vuetify trame-vtk
    """

    from trame.app import get_server
    from trame.decorators import TrameApp, change
    from trame.widgets import vuetify3 as v3, paraview as pv_widgets
    from trame.ui.vuetify3 import SinglePageLayout

    from paraview import simple

    # -----------------------------------------------------------------------------

    @TrameApp()
    class ConeApp:
        def __init__(self, server=None):
            self.server = get_server(server, client_type="vue3")

            self.cone = simple.Cone()
            self.representation = simple.Show(self.cone)
            self.view = simple.Render()

            self.state.trame__title = "ParaView - Cone"
            self.ui = self._build_ui()

        @property
        def state(self):
            return self.server.state

        @property
        def ctrl(self):
            return self.server.controller

        @change("resolution")
        def on_resolution_change(self, resolution, **_):
            self.cone.Resolution = resolution
            self.ctrl.view_update()

        def reset_resolution(self):
            self.state.resolution = 6

        def _build_ui(self):
            with SinglePageLayout(self.server, full_height=True) as layout:
                layout.icon.click = self.ctrl.view_reset_camera
                layout.title.set_text("ParaView - Cone")

                with layout.toolbar:
                    v3.VSpacer()
                    v3.VSlider(
                        v_model=("resolution", 6),
                        min=3,
                        max=60,
                        step=1,
                        hide_details=True,
                        dense=True,
                        style="max-width: 300px",
                    )
                    v3.VDivider(vertical=True, classes="mx-2")
                    with v3.VBtn(icon=True, click=self.reset_resolution):
                        v3.VIcon("mdi-undo-variant")

                with layout.content:
                    with v3.VContainer(fluid=True, classes="pa-0 fill-height"):
                        html_view = pv_widgets.VtkRemoteView(self.view, interactive_ratio=1)
                        self.ctrl.view_reset_camera = html_view.reset_camera
                        self.ctrl.view_update = html_view.update

                return layout

    # -----------------------------------------------------------------------------

    def main(**kwargs):
        app = ConeApp()
        app.server.start(**kwargs)

    # -----------------------------------------------------------------------------

    if __name__ == "__main__":
        main()

You can run it by doing the following

.. code-block:: console

    pvpython --venv .venv ./pv_cone.py


Running a packaged application
----------------------------------

Assuming that application is available in your virtual environment, you can run the following

.. code-block:: console

    # vtk.js example
    pvpython --venv .venv -m trame.app.demo

    # ParaView example
    pvpython --venv .venv -m trame.app.pv_demo
