Starting my first ewoks orange widget#
In this chapter we will:
see how to do a basic connection between an ewoks task and an orangecontrib widget
Setting up ewoksorange#
Please make sure you already have ewoksorange install on your python environment. Else please see installation
Defining an ewoks task#
For this tutorial we would like to add a dedicated interface for the a task performing some data clipping from percentiles. We already have implemented it with ewokscore.
from ewokscore.task import Task
import numpy
class ClipDataTask(
Task,
input_names=["data", "percentiles"],
output_names=["data"],
):
"""
Task to rescale 'data' (numpy array) to the given percentiles.
"""
def run(self):
data = self.inputs.data
# compute data min and max
percentiles = self.inputs.percentiles
assert isinstance(percentiles, tuple) and len(percentiles) == 2, "incoherent input"
assert percentiles[0] <= percentiles[1], "incoherent percentiles value"
self.outputs.data = numpy.clip(
data,
a_min=numpy.percentile(data, percentiles[0]),
a_max=numpy.percentile(data, percentiles[1]),
)
Associate a task to a dedicated orange widget#
Now we want to create a widget associated to the task.
There is different ways to define the ewoks tasks execution with orange (see Ewoks widgets and execution).
On this example we will take the ewoks widget doing the processing in a single thread (Execute the associated Ewoks task in a single dedicated thread). Because this will make sure the gui will not freeze with it and we don’t need concurrent execution.
Widget ‘skeleton’ is the following:
1class ClipDataOW(
2 OWEwoksWidgetOneThread,
3 ewokstaskclass=ClipDataTask,
4):
5 name = "rescale data"
6 id = "orange.widgets.my_project.ClipDataTask"
7 description = (
8 "widget to clip data (numpy array) within a percentile range."
9 )
10 pass
Hint
l1: OW stand for Orange Widget
l2: inheritance with the ewoks orange widget
l3: definition of the ewoks task to bind. This is usually given with the full module path. For example if RescaleDataTask is saved in my_project.tasks.rescale the value would be my_project.tasks.rescale.RescaleDataTask
l5: the name of the widget (will be displayed in the canvas)
l6: id from the orange point of view. It should be constant with time to make insure workflow compatibility.
l7: tooltip of the widget
Results
import numpy
from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
from ewokscore.task import Task
class ClipDataTask(
Task,
input_names=["data", "percentiles"],
output_names=["data"],
):
"""
Task to rescale 'data' (numpy array) to the given percentiles.
"""
def run(self):
data = self.inputs.data
# compute data min and max
percentiles = self.inputs.percentiles
assert (
isinstance(percentiles, tuple) and len(percentiles) == 2
), "incoherent input"
assert percentiles[0] <= percentiles[1], "incoherent percentiles value"
self.outputs.data = numpy.clip(
data,
a_min=numpy.percentile(data, percentiles[0]),
a_max=numpy.percentile(data, percentiles[1]),
)
class ClipDataOW(
OWEwoksWidgetOneThread,
ewokstaskclass=ClipDataTask,
):
name = "rescale data"
id = "orange.widgets.my_project.ClipDataTask"
description = "widget to clip data (numpy array) within a percentile range."
pass