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, *args, **kwargs)[source]¶ Call a function with the supplied parameters.
For every object in the stream, apply
clbl
to 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)[source]¶ Update obj using the values corresponding to the output ports.
-
transform_stream
(stream)[source]¶ Transform a stream.
By default, this calls
self.transform
with appropriate parameters.transform
has to be implemented by a subclass iftransform_stream
is 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, node)[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.
-
node
¶ The node that created the Variable.
- 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 + b
a.add(b)
Containment Test
a.contains(b)
,b.in_(a)
True Division
a / b
a.truediv(b)
Integer Division
a // b
a.floordiv(b)
Bitwise And
a & b
a.and_(b)
Bitwise Exclusive Or
a ^ b
a.xor(b)
Bitwise Inversion
~ a
a.invert(b)
Bitwise Or
a | b
a.or_(b)
Exponentiation
a ** b
a.pow(b)
Identity
a.is_(b)
Identity
a.is_not(b)
Indexed Assignment
obj[k] = v
Indexed Deletion
del obj[k]
Indexing
obj[k]
Left Shift
a << b
a.lshift(b)
Modulo
a % b
a.mod(b)
Multiplication
a * b
a.mul(b)
Matrix Multiplication
a @ b
a.matmul(b)
Negation (Arithmetic)
- a
a.neg(b)
Negation (Logical)
a.not_()
Positive
+ a
a.pos(b)
Right Shift
a >> b
a.rshift(b)
Slice Assignment
seq[i:j] = values
Slice Deletion
del seq[i:j]
Slicing
seq[i:j]
Subtraction
a - b
a.sub(b)
Ordering
a < b
a.lt(b)
Ordering
a <= b
a.leq(b)
Equality
a == b
a.eq(b)
Difference
a != b
a.ne(b)
Ordering
a >= b
a.ge(b)
Ordering
a > b
a.gt(b)
a
,b
,i
,j
andk
can be eitherVariable
instances or raw values.
-
Stream¶
-
morphocut.core.
Stream
¶ A stream is an Iterable of
StreamObject
s.