Skip to content

Commit

Permalink
Add to_python for all operators
Browse files Browse the repository at this point in the history
  • Loading branch information
illusional committed Mar 15, 2021
1 parent c61df3f commit 260a02c
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 18 deletions.
35 changes: 32 additions & 3 deletions janis_core/operators/logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def __repr__(self):
def evaluate(self, inputs):
return self.evaluate_arg(self.args[0], inputs) is not None

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"{arg} is not None"

def to_cwl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
# 2 equals (!=) in javascript will coerce undefined to equal null
Expand Down Expand Up @@ -103,6 +107,10 @@ def to_cwl(self, unwrap_operator, *args):
cond, v1, v2 = [unwrap_operator(a) for a in self.args]
return f"{cond} ? {v1} : {v2}"

def to_python(self, unwrap_operator, *args):
condition, iftrue, iffalse = [unwrap_operator(a) for a in self.args]
return f"({iftrue} if {condition} else {iffalse})"


class AssertNotNull(Operator):
@staticmethod
Expand All @@ -117,6 +125,9 @@ def evaluate(self, inputs):
assert result is not None
return result

def to_python(self, unwrap_operator, *args):
return unwrap_operator(unwrap_operator(args[0]))

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"select_first([{arg}])"
Expand Down Expand Up @@ -168,6 +179,12 @@ def returntype(self):
def apply_to(value):
return not value

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"not {arg}"



# Two value operators


Expand All @@ -178,7 +195,7 @@ def friendly_signature():

@staticmethod
def symbol():
return "&&"
return "and"

@staticmethod
def wdl_symbol():
Expand Down Expand Up @@ -206,7 +223,7 @@ def friendly_signature():

@staticmethod
def symbol():
return "||"
return "or"

@staticmethod
def wdl_symbol():
Expand Down Expand Up @@ -559,6 +576,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"math.floor({arg})"

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"floor({arg})"
Expand All @@ -577,7 +598,7 @@ def evaluate(self, inputs):
class CeilOperator(Operator):
@staticmethod
def friendly_signature():
return "Numeric, NumericType -> Int"
return "Numeric -> Int"

def argtypes(self) -> List[DataType]:
return [NumericType]
Expand All @@ -592,6 +613,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"math.ceil({arg})"

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"ceil({arg})"
Expand Down Expand Up @@ -625,6 +650,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"math.round({arg})"

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"round({arg})"
Expand Down
20 changes: 19 additions & 1 deletion janis_core/operators/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ def to_wdl(self, unwrap_operator, *args):
def to_cwl(self, unwrap_operator, *args):
pass

@abstractmethod
def to_python(self, unwrap_operator, *args):
pass

def to_string_formatter(self):
import re
from janis_core.operators.stringformatter import StringFormatter
Expand All @@ -158,7 +162,10 @@ def argtypes(self):
return [Array(AnyType), Int]

def returntype(self):
return self.args[0].returntype().subtype()
inner = get_instantiated_type(self.args[0].returntype())
if isinstance(inner, Array):
return inner.subtype()
return inner

def __str__(self):
base, index = self.args
Expand All @@ -172,6 +179,9 @@ def evaluate(self, inputs):

return iterable[idx]

def to_python(self, unwrap_operator, *args):
base, index = [unwrap_operator(a) for a in self.args]
return f"{base}[{index}]"
def to_wdl(self, unwrap_operator, *args):
base, index = [unwrap_operator(a) for a in self.args]
return f"{base}[{index}]"
Expand Down Expand Up @@ -219,6 +229,10 @@ def to_wdl(self, unwrap_operator, *args):
def to_cwl(self, unwrap_operator, *args):
return f"{self.cwl_symbol()}({unwrap_operator(*args)})"

def to_python(self, unwrap_operator, *args):
return f"{self.symbol()}({unwrap_operator(*args)})"



class TwoValueOperator(Operator, ABC):
@staticmethod
Expand Down Expand Up @@ -253,6 +267,10 @@ def to_cwl(self, unwrap_operator, *args):
arg1, arg2 = [unwrap_operator(a) for a in self.args]
return f"({arg1} {self.cwl_symbol()} {arg2})"

def to_python(self, unwrap_operator, *args):
arg1, arg2 = [unwrap_operator(a) for a in self.args]
return f"({arg1} {self.symbol()} {arg2})"

def __str__(self):
args = self.args
return f"({args[0]} {self.symbol()} {args[1]})"
Expand Down
11 changes: 11 additions & 0 deletions janis_core/operators/selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,14 @@ def to_string_formatter(self):

return StringFormatter(f"{{{self.input_to_select}}}", **kwarg)

def init_dictionary(self):
d = {"input_to_select": self.input_to_select}
if self.remove_file_extension is not None:
d["remove_file_extension"] = self.remove_file_extension
if not isinstance(self.type_hint, File):
d["type_hint"] = self.type_hint
return d

def __str__(self):
return "inputs." + self.input_to_select

Expand Down Expand Up @@ -412,6 +420,9 @@ def __init__(self, inner: Selector, dt: ParseableType):
def returntype(self) -> DataType:
return self.data_type

def __repr__(self):
return f"({self.inner_selector} as {self.data_type})"

def to_string_formatter(self):
from janis_core.operators.stringformatter import StringFormatter

Expand Down
106 changes: 105 additions & 1 deletion janis_core/operators/standard.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from copy import copy
from typing import List

from janis_core.utils.logger import Logger
from janis_core.types import (
DataType,
UnionType,
Expand All @@ -22,6 +24,9 @@ def friendly_signature():
def argtypes(self) -> List[DataType]:
return [File()]

def to_python(self, unwrap_operator, *args):
raise NotImplementedError("Determine _safe_ one line solution for ReadContents")

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(args[0])
return f"read_string({arg})"
Expand Down Expand Up @@ -56,6 +61,10 @@ def evaluate(self, inputs):
with open(file) as f:
return load(f)

def to_python(self, unwrap_operator, *args):
raise NotImplementedError("Determine _safe_ one line solution for ReadContents")


def to_wdl(self, unwrap_operator, *args):
f = unwrap_operator(self.args[0])
return f"read_json({f})"
Expand Down Expand Up @@ -91,6 +100,10 @@ def argtypes(self):
def returntype(self):
return String()

def to_python(self, unwrap_operator, *args):
iterable, separator = [unwrap_operator(a) for a in self.args]
return f"{separator}.join({iterable})"

def to_wdl(self, unwrap_operator, *args):
iterable, separator = [unwrap_operator(a) for a in self.args]
iterable_arg = self.args[0]
Expand Down Expand Up @@ -124,8 +137,12 @@ class BasenameOperator(Operator):
def friendly_signature():
return "Union[File, Directory] -> String"

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(args[0])
return f"os.path.basename({arg})"

def to_wdl(self, unwrap_operator, *args):
arg = args[0]
arg = unwrap_operator(args[0])
return f"basename({unwrap_operator(arg)})"

def to_cwl(self, unwrap_operator, *args):
Expand Down Expand Up @@ -169,6 +186,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
iterable = unwrap_operator(self.args[0])
return f"[[{iterable}[j][i] for j in range(len({iterable}))] for i in range(len({iterable}[0]))]"

def to_wdl(self, unwrap_operator, *args):
return f"transform({unwrap_operator(args[0])})"

Expand Down Expand Up @@ -200,6 +221,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"len({arg})"

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"length({arg})"
Expand All @@ -213,6 +238,41 @@ def evaluate(self, inputs):
return len(ar)


class RangeOperator(Operator):
@staticmethod
def friendly_signature():
return "Int -> Array[Int]"

def argtypes(self):
return [Int]

def returntype(self):
return Array(Int())

def __str__(self):
return f"0...{self.args[0]}"

def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"range({arg})"

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"range({arg})"

def to_cwl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"Array.from({{ length: {arg} + 1 }}, (_, i) => i)"
# return f"{arg}.length"

def evaluate(self, inputs):
ar = self.evaluate_arg(self.args[0], inputs)
return list(range(ar))


class FlattenOperator(Operator):
@staticmethod
def friendly_signature():
Expand All @@ -230,6 +290,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"[el for sublist in {arg} for el in sublist]"

def to_wdl(self, unwrap_operator, *args):
arg = unwrap_operator(self.args[0])
return f"flatten({arg})"
Expand Down Expand Up @@ -261,6 +325,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
prefix, iterable = [unwrap_operator(a) for a in self.args]
return f"[{prefix} + i for i in {iterable}]"

def to_wdl(self, unwrap_operator, *args):
prefix, iterable = [unwrap_operator(a) for a in self.args]
return f"prefix({prefix}, {iterable})"
Expand All @@ -278,6 +346,30 @@ class FileSizeOperator(Operator):
"""
Returned in MB: Note that this does NOT include the reference files (yet)
"""
def __new__(cls, *args, **kwargs):
multiplier = None
src, *otherargs = args

if len(otherargs) == 1:
f = otherargs[0].lower()
multiplier_heirarchy = [
("ki" in f, 1024),
("k" in f, 1000),
("mi" in f, 1.024),
("gi" in f, 0.001024),
("g" in f, 0.001),
]
if not any(m[0] for m in multiplier_heirarchy):
Logger.warn(f"Couldn't determine prefix {f} for FileSizeOperator, defaulting to MB")
else:
multiplier = [m[1] for m in multiplier_heirarchy if m[0] is True][0]

instance = super(FileSizeOperator, cls).__new__(cls)
instance.__init__(args[0])

if multiplier is not None and multiplier != 1:
return instance * multiplier
return instance

@staticmethod
def friendly_signature():
Expand All @@ -296,6 +388,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
f = unwrap_operator(self.args[0])
return f"os.stat({f}).st_size / 1000"

def to_wdl(self, unwrap_operator, *args):
f = unwrap_operator(self.args[0])
return f'size({f}, "MB")'
Expand Down Expand Up @@ -338,6 +434,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
iterable = unwrap_operator(self.args[0])
return f"[a for a in {iterable} if a is not None][0]"

def to_wdl(self, unwrap_operator, *args):
iterable = unwrap_operator(self.args[0])
return f"select_first({iterable})"
Expand Down Expand Up @@ -376,6 +476,10 @@ def __str__(self):
def __repr__(self):
return str(self)

def to_python(self, unwrap_operator, *args):
iterable = unwrap_operator(self.args[0])
return f"[a for a in {iterable} if a is not None]"

def to_wdl(self, unwrap_operator, *args):
iterable = unwrap_operator(self.args[0])
return f"select_all({iterable})"
Expand Down
Loading

0 comments on commit 260a02c

Please sign in to comment.