Python Postprocessing Tool Structure

Each plugin should implement at least the following Python classes.

  1. A data reader class responsible for loading the data from the simulation directory
  2. A visualizer class that outputs a matplotlib plot

The repository directory for PIConGPU Python modules for plugins is lib/python/picongpu/plugins/.

Data Reader

The data readers should reside in the lib/python/picongpu/plugins/data directory. There is a base class in base_reader.py defining the interface of a reader. Each reader class should derive from this class and needs to implement the following interface functions:

class picongpu.plugins.data.base_reader.DataReader(run_directory)

Base class that all data readers should inherit from.

__init__(run_directory)
Parameters:run_directory (string) – path to the run directory of PIConGPU (the path before simOutput/)
get(**kwargs)
Returns:
  • The data for the requested parameters in a plugin
  • dependent format and type.
get_data_path(**kwargs)
Returns:
Return type:A string with the path to the underlying data file.
get_iterations(**kwargs)
Returns:
  • An array with unsigned integers of iterations for which
  • data is available.

To shorten the import statements for the readers, please also add an entry in the __init__.py file of the data directory.

Visualizer

The visualizers should reside in the lib/python/picongpu/plugins/plot_mpl/ directory. The module names should end on _visualizer.py and the class name should only be Visualizer.

To shorten the import statements for the visualizers, please also add an entry in the __init__.py file of the plot_mpl directory.

There is a base class for visualization found in base_visualizer.py which already handles the plotting logic. It uses the data reader classes for accessing the data. After getting the data, it ensures that (for performance reasons) a matplotlib artist is created only for the first plot and later only gets updated with fresh data.

class picongpu.plugins.plot_mpl.base_visualizer.Visualizer(run_directory, ax=None)

Abstract base class for matplotlib visualizers that implements the visualization logic. Classes that derive from this class need to write their own implementations for the following functions in order to work:

_create_data_reader(self, run_directory) _create_plt_obj(self, ax) _update_plt_obj(self)

Note: When using classes derived from this within jupyter notebooks, use %matplotlib notebook mode.

__init__(run_directory, ax=None)

Initialize the reader and data as member parameters.

Parameters:
  • run_directory (string) – path to the run directory of PIConGPU (the path before simOutput/)
  • ax (matplotlib.axes) –
_create_data_reader(run_directory)

Needs to return an instance of a picongpu data reader (as defined in the ../plugin directory) which implements a ‘get()’ method.

_create_plt_obj()

Sets ‘self.plt_obj’ to an instance of a matplotlib.artist.Artist object (or derived classes) created by using ‘self.ax’ which can later be updated by feeding new data into it. Only called on the first call for visualization.

_update_plt_obj()

Take the ‘self.data’ member, interpret it and feed it into the ‘self.plt_obj’.

visualize(**kwargs)
  1. Creates the ‘plt_obj’ if it does not exist
  2. Fills the ‘data’ parameter by using the reader
  3. Updates the ‘plt_obj’ with the new data.

The complete implementation logic of the visualize function is pretty simple.

def visualize(self, **kwargs):
     self.data = self.data_reader.get(**kwargs)
     if self.plt_obj is None:
         self._create_plt_obj()
     else:
         self._update_plt_obj()

All new plugins should derive from this class.

When implementing a new visualizer you have to perform the following steps:

  1. Let your visualizer class inherit from the Visualizer class in base visualizer.py.

2. Implement the _create_data_reader(self, run_directory) function. This function should return a data reader object (see above) for this plugin’s data.

3. Implement the _create_plt_obj(self) function. This function needs to access the plotting data from the self.data member (this is the data structure as returned by the data readers .get(...) function, create some kind of matplotlib artist by storing it in the self.plt_obj member variable and set up other plotting details (e.g. a colorbar).

4. Implement the _update_plt_obj(self) function. This is called only after a valid self.plt_obj was created. It updates the matplotlib artist with new data. Therefore it again needs to access the plotting data from the self.data member and call the data update API for the matplotlib artist (normally via .set_data(...).