def test_auto_connect_all_only_matching_types(self, graph): def my_increment(n: int) -> int: return n + 1 def my_decrement(m: int) -> int: return m - 1 increment_op = OperationPlugin(my_increment, output_names=("increment", )) decrement_op = OperationPlugin(my_decrement, output_names=("decrement", )) graph.add_operations(increment_op, decrement_op) graph.auto_connect_all() assert graph.links() == []
def test_auto_connect_all_matching_names_and_types(self, graph): def my_increment(n: int) -> int: return n + 1 def my_decrement(increment: int) -> int: return increment - 1 increment_op = OperationPlugin(my_increment, output_names=("increment", )) decrement_op = OperationPlugin(my_decrement, output_names=("end_result", )) graph.add_operations(increment_op, decrement_op) graph.auto_connect_all() assert graph.links() == [(increment_op, decrement_op, "increment", "increment")]
def setParameters(self, operation: OperationPlugin): if operation: # Create a new Parameter from the emitted operation, # Then wire up its connections for use in a parameter tree. parameter = operation.as_parameter() group = GroupParameter(name='Selected Operation', children=parameter) operation.wireup_parameter(group) # Add the Parameter to the parameter tree group.blockSignals(True) for child in group.children(): child.blockSignals(True) self.operationeditor.setParameters(group, showTop=False) threads.invoke_as_event(self._unblock_group, group) else: self.operationeditor.clear()
def setParameters(self, operation: OperationPlugin): if operation: # Create a new Parameter from the emitted operation, # Then wire up its connections for use in a parameter tree. parameter = operation.as_parameter() group = GroupParameter(name='Selected Operation', children=parameter) operation.wireup_parameter(group) # Add the Parameter to the parameter tree group.blockSignals(True) for child in group.children(): child.blockSignals(True) self.operationeditor.setParameters(group, showTop=False) QApplication.processEvents() group.blockSignals(False) for child in group.children(): child.blockSignals(False)
def setParameters(self, operation: OperationPlugin): parameter = operation.as_parameter() group = GroupParameter(name='Selected Operation', children=parameter) operation.wireup_parameter(group) for child, parameter in zip(group.children(), parameter): # wireup signals to update the workflow if parameter.get('fixable'): child.sigFixToggled.connect( partial(self.setFixed, operation, child.name)) child.sigValueChanged.connect( partial(self.setValue, operation, child.name)) group.blockSignals(True) for child in group.children(): child.blockSignals(True) self.operationeditor.setParameters(group, showTop=False) QApplication.processEvents() group.blockSignals(False) for child in group.children(): child.blockSignals(False)
def test_links_multiple(self, graph, sum_op): def my_func(x: int, y: int) -> (int, int): return y, x my_op = OperationPlugin(my_func, output_names=("y", "x")) graph.add_operations(sum_op, my_op) link1 = (my_op, sum_op, "y", "n1") link2 = (my_op, sum_op, "x", "n2") graph.add_link(*link1) graph.add_link(*link2) assert graph.links() == [link1, link2]
def insert_operation(self, index: int, operation: OperationPlugin): """Insert an operation at a specific index in the workflow. Parameters ---------- index : int Index where to insert the operation. 0 will add at the beginning; -1 will add to the end. operation : OperationPlugin Operation to insert. """ if not isinstance(operation, OperationPlugin): raise TypeError(f'Expected "{operation}" to be an OperationPlugin') self._operations.insert(index, operation) operation._workflow = ref(self) self.notify()
def test_operation_links_multiple(self, graph, sum_op, square_op, negative_op): def my_func(x: int, y: int) -> (int, int): return y, x my_op = OperationPlugin(my_func, output_names=("y", "x")) graph.add_operations(sum_op, square_op, negative_op, my_op) link1 = (my_op, sum_op, "y", "n1") link2 = (my_op, sum_op, "x", "n2") link3 = (sum_op, square_op, "sum", "n") link4 = (square_op, negative_op, "square", "num") graph.add_link(*link1) graph.add_link(*link2) graph.add_link(*link3) graph.add_link(*link4) assert graph.operation_links(my_op) == [link1, link2] assert graph.operation_links(sum_op) == [link3] assert graph.operation_links(negative_op) == []
def test_add_multiple_links(self, graph, sum_op, square_op): graph.add_operation(sum_op) graph.add_operation(square_op) import math def my_sqrt(num): return math.sqrt(num) sqrt_op = OperationPlugin(my_sqrt, output_names=("sqrt")) graph.add_operation(sqrt_op) # sum -> square -> sqrt # \ | # -------->------ graph.add_link(source=sum_op, dest=square_op, source_param="sum", dest_param="n") graph.add_link(source=square_op, dest=sqrt_op, source_param="square", dest_param="num") graph.add_link(source=sum_op, dest=sqrt_op, source_param="sum", dest_param="num") # sum -> square assert graph.get_inbound_links(sum_op)[square_op] == [] assert graph.get_outbound_links(sum_op)[square_op] == [("sum", "n")] assert graph.get_inbound_links(square_op)[sum_op] == [("sum", "n")] assert graph.get_outbound_links(square_op)[sum_op] == [] # square -> sqrt assert graph.get_inbound_links(square_op)[sqrt_op] == [] assert graph.get_outbound_links(square_op)[sqrt_op] == [("square", "num")] assert graph.get_inbound_links(sqrt_op)[square_op] == [("square", "num")] assert graph.get_outbound_links(sqrt_op)[square_op] == [] # sum -> sqrt assert graph.get_inbound_links(sum_op)[sqrt_op] == [] assert graph.get_outbound_links(sum_op)[sqrt_op] == [("sum", "num")] assert graph.get_inbound_links(sqrt_op)[sum_op] == [("sum", "num")] assert graph.get_outbound_links(sqrt_op)[sum_op] == []
def test_as_dask_graph_multiple_links(self, graph, sum_op, square_op, negative_op): def my_func(x: int, y: int) -> (int, int): return y, x # Connect sum_op to square_op. # Connect sum_op to my_op's x, square_op to my_op's y. # Leave negative_op unconnected my_op = OperationPlugin(my_func, output_names=("y", "x")) graph.add_operations(sum_op, square_op, negative_op, my_op) graph.add_link(sum_op, square_op, "sum", "n") graph.add_link(sum_op, my_op, "sum", "x") graph.add_link(square_op, my_op, "square", "y") dask_graph, end_ids = graph.as_dask_graph() # Should look like: sum_wrapper = dask_graph["0"] square_wrapper = dask_graph["1"] negative_wrapper = dask_graph["2"] my_wrapper = dask_graph["3"] # sum_op has no dependent nodes (no ops connect into it) assert len(sum_wrapper) == 1 assert sum_wrapper[0].node is sum_op # square_op has 1 dependent node, takes sum_op's output assert len(square_wrapper) == 2 assert square_wrapper[0].node is square_op # negative_op has no dependent nodes; is unconnected assert len(negative_wrapper) == 1 assert negative_wrapper[0].node is negative_op # my_op has two dependent nodes; sum_op and square_op connect to its inputs assert len(my_wrapper) == 3 assert my_wrapper[0].node is my_op assert my_wrapper[1] == "0" # sum_op assert my_wrapper[2] == "1" # square_op # negative_op, and my_op should be end nodes assert sorted(end_ids) == sorted(["2", "3"])
def setValue(self, operation: OperationPlugin, param_name: str, value): operation.filled_values[param_name] = value
def setFixed(self, operation: OperationPlugin, param_name: str, value): operation.fixed[param_name] = value
def negative_op(): def my_negative(num: int) -> int: return -1 * num return OperationPlugin(my_negative, output_names=("negative", ))
def square_op(): def my_square(n: int) -> int: return n * n return OperationPlugin(my_square, output_names=("square", ))
def sum_op(): def my_sum(n1: int, n2: int) -> int: return n1 + n2 return OperationPlugin(my_sum, output_names=("sum", ))