Core API
This chapter describes the core module of MorphoCut.
Pipelines
The Pipeline is the main entry point for a MorphoCut application.
- class morphocut.core.Pipeline(parent=None)[source]
A Pipeline manages the execution of nodes.
Nodes defined inside the pipeline context will be added to the pipeline. When the pipeline is executed, stream objects are passed from one node to the next in the same order.
- Parameters:
parent (Pipeline, optional) – A parent pipeline to attach to. If None and nested in an existing Pipeline, attach to this one.
Example
with Pipeline() as pipeline: ... pipeline.run()
Nodes
A Node applies creates, updates or deletes stream objects.
Call
In simple cases, a call to a regular function
can be recorded in a pipeline using Call.
- class morphocut.core.Call(clbl: Callable, *args, **kwargs)[source]
Call a function with the supplied parameters.
For every object in the stream, apply
clblto the corresponding stream variables.- Parameters:
clbl – A callable.
*args – Positional arguments to
clbl.**kwargs – Keyword-arguments to
clbl.
- Returns:
Variable – The result of the function invocation.
Example
def foo(bar): return bar baz = ... # baz is a stream variable. result = Call(foo, baz)
Subclassing Node
If a Node has multiple outputs or needs to change the stream,
Node has to be subclassed.
The subclass has no or any number of @Output decorators.
@ReturnOutputs is used to turn Node
subclasses into a functions returning stream variables.
Overriding transform(...)
If the Node handles one object at a time,
it is enough to implement a custom transform(...).
The parameter names have to correspond to attributes of the Node.
Node.transform_stream() will then use introspection
to call transform with the right parameter values.
@ReturnOutputs
@Output("bar")
@Output("baz")
class Foo(Node):
"""This class has two outputs."""
def __init__(self, ham, spam):
super().__init__()
self.ham = ham
self.spam = spam
# This is automatically called by Node.transform_stream,
# reading ham and spam from the stream
# and introducing the result back into the stream.
def transform(self, ham, spam):
# ham and spam are raw values here
return ham + spam, ham - spam
with Pipeline() as pipeline:
# ham and spam are stream variables here
ham = ...
spam = ...
bar, baz = Foo(ham, spam)
Overriding transform_stream
If the Node has to change the stream in some way,
Node.transform_stream() needs to be overridden.
@ReturnOutputs
@Output("bar")
@Output("baz")
class Foo(Node):
"""This class has two outputs."""
def __init__(self, ham, spam):
super().__init__()
self.ham = ham
self.spam = spam
def transform_stream(self, stream):
with closing_if_closable(stream):
for obj in stream:
# Retrieve raw values
ham, spam = self.prepare_input(obj, ("ham", "spam"))
# Remove objects from stream based on some condition
if not ham:
continue
# Append new values to the stream object:
# bar = ham + spam
# baz = ham - spam
yield self.prepare_output(obj, ham + spam, ham - spam)
with Pipeline() as pipeline:
# ham and spam are stream variables here
ham = ...
spam = ...
bar, baz = Foo(ham, spam)
- class morphocut.core.Node[source]
Base class for all stream processing nodes.
- after_stream()[source]
Do something after the stream was processed.
Called by transform_stream after stream processing is done. Override this in your own subclass.
- prepare_output(obj, *values, n_remaining_hint=None)[source]
Update obj using the values corresponding to the output ports.
- transform_stream(stream)[source]
Transform a stream. By default, this calls
self.transformwith appropriate parameters.transformhas to be implemented by a subclass iftransform_streamis not overridden. Override if the stream has to be altered in some way, i.e. objects are created, deleted or re-arranged.
Variables
Upon instanciation, Nodes return Variables that are used to identify values in stream objects.
- class morphocut.core.Variable(name, parent)[source]
A Variable identifies a value in a stream object.
Variables are (almost) never instanciated manually, they are created when calling a Node.
- name
The name of the Variable.
- parent
The parent that created the Variable. This is just used in the string representation.
- Operations:
Variables support the following operations. Each operation is realized as a new Node in the Pipeline, so use them sparingly. Operator and method can be used interchangeably (if both present).
Operation
Operator
Method
Addition
a + ba.add(b)Containment Test
a.contains(b),b.in_(a)True Division
a / ba.truediv(b)Integer Division
a // ba.floordiv(b)Bitwise And
a & ba.and_(b)Bitwise Exclusive Or
a ^ ba.xor(b)Bitwise Inversion
~ aa.invert(b)Bitwise Or
a | ba.or_(b)Exponentiation
a ** ba.pow(b)Identity
a.is_(b)Identity
a.is_not(b)Indexed Assignment
obj[k] = vIndexed Deletion
del obj[k]Indexing
obj[k]Left Shift
a << ba.lshift(b)Modulo
a % ba.mod(b)Multiplication
a * ba.mul(b)Matrix Multiplication
a @ ba.matmul(b)Negation (Arithmetic)
- aa.neg(b)Negation (Logical)
a.not_()Positive
+ aa.pos(b)Right Shift
a >> ba.rshift(b)Slice Assignment
seq[i:j] = valuesSlice Deletion
del seq[i:j]Slicing
seq[i:j]Subtraction
a - ba.sub(b)Ordering
a < ba.lt(b)Ordering
a <= ba.leq(b)Equality
a == ba.eq(b)Difference
a != ba.ne(b)Ordering
a >= ba.ge(b)Ordering
a > ba.gt(b)a,b,i,jandkcan be eitherVariableinstances or raw values.
Stream
- morphocut.core.Stream
A stream is an Iterator of
StreamObjects.alias of
Iterator[StreamObject]