Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
danbryce committed Oct 21, 2023
1 parent 558ebc8 commit f72ab97
Show file tree
Hide file tree
Showing 17 changed files with 508 additions and 541 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@
parameter_values=[],
)

execution.to_dot().view()
# execution.to_dot().view()
with open(os.path.join(OUT_DIR, f"{filename}.nt"), "w") as f:
f.write(doc.write_string(sbol3.SORTED_NTRIPLES).strip())

Expand Down
6 changes: 5 additions & 1 deletion labop/execution/behavior_dynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

# Project packages
import uml
from labop import ActivityNodeExecution, SampleArray, SampleCollection, SampleMap
from labop.data import deserialize_sample_format, serialize_sample_format
from labop.strings import Strings

from ..activity_node_execution import ActivityNodeExecution
from ..sample_array import SampleArray
from ..sample_collection import SampleCollection
from ..sample_map import SampleMap


class SampleProvenanceObserver:
"""
Expand Down
196 changes: 193 additions & 3 deletions labop/execution/execution_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import hashlib
import logging
import os
import types
import uuid
from abc import ABC
from typing import Callable, Dict, List, Optional, Tuple, Union
Expand All @@ -23,16 +24,21 @@
from labop.sample_data import SampleData
from labop.strings import Strings
from uml import ActivityNode, CallBehaviorAction
from uml.action import Action
from uml.activity import Activity
from uml.activity_edge import ActivityEdge
from uml.activity_parameter_node import ActivityParameterNode
from uml.fork_node import ForkNode
from uml.literal_specification import LiteralSpecification
from uml.object_flow import ObjectFlow
from uml.output_pin import OutputPin
from uml.parameter import Parameter
from uml.pin import Pin
from uml.utils import WellFormednessIssue, WellformednessLevels, literal

from .behavior_dynamics import SampleProvenanceObserver
from .execution_context import ExecutionContext
from .primitive_execution import primitive_to_output_function

l: logging.Logger = logging.getLogger(__file__)
l.setLevel(logging.ERROR)
Expand Down Expand Up @@ -182,6 +188,16 @@ def get_current_time(self, as_string: bool = False):
cur_time = self.start_time + rel_start
return cur_time if not as_string else str(cur_time)

def initialize_primitive_compute_output(self, doc: sbol3.Document):
for k, v in primitive_to_output_function.items():
try:
p = Primitive.get_primitive(doc, k, copy_to_doc=False)
p.compute_output = types.MethodType(v, p)
except Exception as e:
l.warning(
f"Could not set compute_output() for primitive {k}, did you import the correct library?"
)

def initialize(
self,
protocol: Protocol,
Expand All @@ -198,7 +214,7 @@ def initialize(

if self.use_defined_primitives:
# Define the compute_output function for known primitives
Primitive.initialize_primitive_compute_output(doc)
self.initialize_primitive_compute_output(doc)

# First, set up the record for the protocol and parameter values
if self.ex is not None and overwrite_execution:
Expand Down Expand Up @@ -468,7 +484,8 @@ def next_tokens(
ActivityEdgeFlow(
edge=edge,
token_source=record,
value=node.get_value(
value=self.get_value(
node,
edge,
parameter_value_map,
node_outputs,
Expand Down Expand Up @@ -505,7 +522,8 @@ def next_tokens(
ActivityEdgeFlow(
edge=edge,
token_source=record,
value=node.get_value(
value=self.get_value(
node,
edge,
parameter_value_map,
node_outputs,
Expand Down Expand Up @@ -559,6 +577,178 @@ def next_tokens(

return new_tokens

def get_value(
self,
node: ActivityNode,
edge: "ActivityEdge",
node_inputs: Dict[str, Union[List[LiteralSpecification], LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
value = ""
reference = False
from uml.control_flow import ControlFlow
from uml.object_flow import ObjectFlow

if isinstance(edge, ControlFlow):
value = ["uml.ControlFlow"]
elif isinstance(edge, ObjectFlow):
if isinstance(node, Pin):
value = self.get_pin_value(
node,
edge,
node_inputs,
node_outputs,
sample_format,
invocation_hash,
)
elif isinstance(node, ForkNode):
value = self.get_fork_node_value(
node,
edge,
node_inputs,
node_outputs,
sample_format,
invocation_hash,
)
elif isinstance(node, ActivityParameterNode):
value = self.get_activity_parameter_node_value(
node,
edge,
node_inputs,
node_outputs,
sample_format,
invocation_hash,
)
elif isinstance(node, Action):
value = self.get_action_value(
node,
edge,
node_inputs,
node_outputs,
sample_format,
invocation_hash,
)

reference = lambda v: (isinstance(v, sbol3.Identified) and v.identity != None)
if isinstance(value, list):
value = [literal(v, reference=reference(v)) for v in value]
else:
value = [literal(value, reference=reference(value))]
return value

# from OutputPin
def get_pin_value(
self,
node: "Pin",
edge: "ActivityEdge",
node_inputs: Dict[str, Union[List[LiteralSpecification], LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
value = node_inputs[node.name]
return value

# from ForkNode
def get_fork_node_value(
self,
node: "ForkNode",
edge: "ActivityEdge",
parameter_value_map: Dict[str, List[LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
value = next(iter(parameter_value_map.values()))
return value

# from ActivityParameterNode
def get_activity_parameter_node_value(
self,
node: ActivityParameterNode,
edge: "ActivityEdge",
parameter_value_map: Dict[str, List[LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
if node.is_output():
value = parameter_value_map[node.name]
else:
value = ""
return value

# from Action
def get_action_value(
self,
node: Action,
edge: "ActivityEdge",
parameter_value_map: Dict[str, List[LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
parameter = node.get_parameter(name=edge.get_target().name)
value = self.get_parameter_value(
node,
parameter,
parameter_value_map,
node_outputs,
sample_format,
invocation_hash,
)

return value

# from CBA
def get_call_behavior_action_value(
self,
node: CallBehaviorAction,
edge: "ActivityEdge",
parameter_value_map: Dict[str, List[LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
from .activity import Activity

if isinstance(node.get_behavior(), Activity):
# Activity Invocations do not send objects to their output pins
# The activity output parameters will send object to the output pins.
value = "uml.ControlFlow"
reference = False
else:
parameter = node.get_parameter(name=edge.get_target().name)
value = node_outputs(
parameter, parameter_value_map, sample_format, invocation_hash
)
return value

def get_parameter_value(
self,
call_behavior_action: CallBehaviorAction,
parameter: Parameter,
parameter_value_map: Dict[str, List[LiteralSpecification]],
node_outputs: Callable,
sample_format: str,
invocation_hash: int,
):
if node_outputs:
value = node_outputs(self, parameter)
elif hasattr(call_behavior_action.get_behavior(), "compute_output"):
value = call_behavior_action.get_behavior().compute_output(
parameter_value_map,
parameter,
sample_format,
invocation_hash,
self,
)
else:
value = f"{parameter.name}"
return value

def possible_calling_behaviors(self, node: ActivityNode):
# Get all CallBehaviorAction nodes that correspond to a CallBehaviorExecution that supports the current execution of the ActivityNode
tokens_supporting_node = [
Expand Down
6 changes: 4 additions & 2 deletions labop/execution/harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,9 @@ def __init__(self, *args, **kwargs):

self.base_dir = kwargs["base_dir"] if "base_dir" in kwargs else "."
self.output_dir = (
kwargs["output_dir"] if "output_dir" in kwargs else "artifacts"
kwargs["output_dir"]
if "output_dir" in kwargs
else f"{self.protocol_name}/artifacts"
)
self.full_output_dir = os.path.join(self.base_dir, self.output_dir)

Expand Down Expand Up @@ -610,7 +612,7 @@ def __init__(self, *args, **kwargs):
self._results = {}

def filename_prefix(self) -> str:
return self.entry_point.__name__
return self.protocol_name

def dataset_filename(self) -> str:
return self.filename_prefix() + ".data.xslx"
Expand Down
Loading

0 comments on commit f72ab97

Please sign in to comment.