예제 #1
0
def cross(left: List[Any], right: List[Any]) -> List[WDLPair]:
    """
    Return the cross product of the two arrays. Array[Y][1] appears before
    Array[X][1] in the output.

    WDL syntax: Array[Pair[X,Y]] cross(Array[X], Array[Y])
    """
    if not isinstance(left, list) or not isinstance(right, list):
        raise WDLRuntimeError(f'cross() requires both inputs to be Array[]!  Not: {type(left)} and {type(right)}')

    return list(WDLPair(left=left_val, right=right_val) for left_val in left for right_val in right)
예제 #2
0
def as_pairs(in_map: dict) -> List[WDLPair]:
    """
    Given a Map, the `as_pairs` function returns an Array containing each element
    in the form of a Pair. The key will be the left element of the Pair and the
    value the right element. The order of the the Pairs in the resulting Array
    is the same as the order of the key/value pairs in the Map.

    WDL syntax: Array[Pair[X,Y]] as_pairs(Map[X,Y])
    """
    if not isinstance(in_map, dict):
        raise WDLRuntimeError(f'as_pairs() requires "{in_map}" to be Map[]!  Not: {type(in_map)}')

    return list(WDLPair(left=k, right=v) for k, v in in_map.items())
예제 #3
0
def wdl_zip(left: List[Any], right: List[Any]) -> List[WDLPair]:
    """
    Return the dot product of the two arrays. If the arrays have different lengths
    it is an error.

    WDL syntax: Array[Pair[X,Y]] zip(Array[X], Array[Y])
    """
    if not isinstance(left, list) or not isinstance(right, list):
        raise WDLRuntimeError(f'zip() requires both inputs to be lists!  Not: {type(left)} and {type(right)}')

    if len(left) != len(right):
        raise WDLRuntimeError('zip() requires that input values have the same size!')

    return list(WDLPair(left=left_val, right=right_val) for left_val, right_val in zip(left, right))
예제 #4
0
def parse_value_from_type(in_data: Any,
                          var_type: str,
                          read_in_file: bool = False,
                          file_store: Optional[AbstractFileStore] = None,
                          cwd: Optional[str] = None,
                          temp_dir: Optional[str] = None,
                          docker: Optional[bool] = None
                          ):
    """
    Calls at runtime. This function parses and validates input from its type. File
    import is also handled.

    For values set in a task block, set `read_in_file` to True to process and read
    all encountered files. This requires `cwd`, `temp_dir`, and `docker` to be
    passed into this function.
    """

    def validate(val: bool, msg: str):
        if not val:
            raise WDLRuntimeError(f'Invalid input: {msg}')

    if not in_data:  # optional type?
        # TODO: check if type is in fact an optional.
        return in_data

    if var_type == 'File':
        # in_data can be an array of files
        if read_in_file:
            return process_and_read_file(f=abspath_file(f=in_data, cwd=cwd),
                                         tempDir=temp_dir,
                                         fileStore=file_store,
                                         docker=docker)

        return process_infile(in_data, file_store)

    elif isinstance(in_data, list):
        # if in_data is not an array of files, then handle elements one by one.
        return [parse_value_from_type(i, var_type, read_in_file, file_store, cwd, temp_dir, docker) for i in in_data]

    elif var_type == 'Pair':
        if isinstance(in_data, WDLPair):
            left = in_data.left
            right = in_data.right

        elif isinstance(in_data, dict):
            validate('left' in in_data and 'right' in in_data, f'Pair needs \'left\' and \'right\' keys')
            left = in_data.get('left')
            right = in_data.get('right')
        else:
            validate(isinstance(in_data, tuple) and len(in_data) == 2, 'Only support Pair len == 2')
            left, right = in_data

        return WDLPair(parse_value_from_type(left, var_type.left, read_in_file, file_store, cwd, temp_dir, docker),
                       parse_value_from_type(right, var_type.right, read_in_file, file_store, cwd, temp_dir, docker))

    elif var_type == 'Map':
        validate(isinstance(in_data, dict), f'Expected dict, but got {type(in_data)}')
        return {k:
                parse_value_from_type(v, var_type.value, read_in_file, file_store, cwd, temp_dir, docker)
                for k, v in in_data.items()}

    else:
        # everything else is fine as is.
        return in_data