Writing Plug-ins¶
A Shape-Link plug-in is a Python script with a class derived from
shapelink.ShapeLinkPlugin
and some additional meta data. Let’s have a look at
this example plugin
which
prints the rolling mean of a few
scalar features to stdout:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import shutil
import numpy as np
from shapelink import ShapeLinkPlugin
# We use the terminal width to make sure a line doesn't get cluttered
# with prints from a previous line.
TERMINAL_WIDTH = shutil.get_terminal_size((80, 20))[0]
class RollingMeansPlugin(ShapeLinkPlugin):
"""Displays a rolling mean of a few scalar features"""
def __init__(self, *args, **kwargs):
super(RollingMeansPlugin, self).__init__(*args, **kwargs)
self.window_size = 100
self.scalar_data = {}
def after_register(self):
print(" Preparing for transmission")
for feat in self.registered_data_format.scalars:
self.scalar_data[feat] = np.zeros(self.window_size) * np.nan
def after_transmission(self):
print("\n End of transmission\n")
def handle_event(self, event_data):
"""Handle a new event"""
window_index = event_data.id % self.window_size
for ii, feat in enumerate(self.registered_data_format.scalars):
self.scalar_data[feat][window_index] = event_data.scalars[ii]
# print the first three features to stdout
msgs = [" Rolling means: "]
num_prints = min(3, len(self.registered_data_format.scalars))
for ii in range(num_prints):
feat = self.registered_data_format.scalars[ii]
msgs.append("{}: {:.3g}".format(feat,
np.mean(self.scalar_data[feat])))
line = " ".join(msgs)
if len(line) < TERMINAL_WIDTH:
line += " " * (TERMINAL_WIDTH - len(line))
print(line, end="\r", flush=True)
return False
info = {
"class": RollingMeansPlugin,
"description": "Displays a rolling mean of a few scalar features",
"name": "Rolling Means",
"version": "0.1.0",
}
|
The main action happens in the
handle_event
function - your plugin must implement at least this function. The two functions
after_register
and
after_transmission
can be used to set things up
(e.g. creation of an additional output file) or to tear things down (e.g.
closing that file). Use the
__init__
function for defining additional class properties.
The info
dictionary is required so that the plugin
can be run via the Command-line interface.