コード例 #1
0
ファイル: utils.py プロジェクト: ukaraoz/snakemake-rules
def get_wildcards(inputmap, wildcard_constraints):
    """Given a list of snakemake IO filenames, extract the wildcards.

    Params:
      inputmap (list): list of input wildcard/filename tuples
    """
    d = {}
    try:
        all_wc = []
        all_files = []
        for wc, filename in inputmap:
            try:
                wc = eval(wc)
            except:
                pass
            wc = update_wildcard_constraints(wc, wildcard_constraints, {})
            all_wc.append(wc)
            if filename is None:
                continue
            if isinstance(filename, str):
                filename = [filename]
            all_files = all_files + filename
        for f in all_files:
            for wc in all_wc:
                wildcards = glob_wildcards(wc, [os.path.basename(f)])
                for k, v in wildcards._asdict().items():
                    if len(v) > 0:
                        d[k] = v[0]
    except:
        logger.debug("Failed to get wildcards for inputmap ", inputmap)
        raise
    return d
コード例 #2
0
 def _update_item_wildcard_constraints(self, item):
     if not (self.wildcard_constraints or self.workflow._wildcard_constraints):
         return item
     try:
         return update_wildcard_constraints(
             item, self.wildcard_constraints, self.workflow._wildcard_constraints
         )
     except ValueError as e:
         raise IOFileException(str(e), snakefile=self.snakefile, lineno=self.lineno)
コード例 #3
0
    def _set_inoutput_item(self, item, output=False, name=None):
        """
        Set an item to be input or output.

        Arguments
        item     -- the item
        inoutput -- either a Namedlist of input or output items
        name     -- an optional name for the item
        """
        inoutput = self.output if output else self.input
        if isinstance(item, str):
            # add the rule to the dependencies
            if isinstance(item, _IOFile) and item.rule:
                self.dependencies[item] = item.rule
            if output:
                rule = self
                if self.wildcard_constraints or self.workflow._wildcard_constraints:
                    try:
                        item = update_wildcard_constraints(
                            item, self.wildcard_constraints,
                            self.workflow._wildcard_constraints)
                    except ValueError as e:
                        raise IOFileException(
                            str(e),
                            snakefile=self.snakefile,
                            lineno=self.lineno)
            else:
                rule = None
                if contains_wildcard_constraints(item) and self.workflow.mode != Mode.subprocess:
                    logger.warning(
                        "wildcard constraints in inputs are ignored")
            # record rule if this is an output file output
            _item = IOFile(item, rule=rule)
            if is_flagged(item, "temp"):
                if output:
                    self.temp_output.add(_item)
            if is_flagged(item, "protected"):
                if output:
                    self.protected_output.add(_item)
            if is_flagged(item, "touch"):
                if output:
                    self.touch_output.add(_item)
            if is_flagged(item, "dynamic"):
                if output:
                    self.dynamic_output.add(_item)
                else:
                    self.dynamic_input.add(_item)
            if is_flagged(item, "subworkflow"):
                if output:
                    raise SyntaxError(
                        "Only input files may refer to a subworkflow")
                else:
                    # record the workflow this item comes from
                    self.subworkflow_input[_item] = item.flags["subworkflow"]
            inoutput.append(_item)
            if name:
                inoutput.add_name(name)
        elif callable(item):
            if output:
                raise SyntaxError(
                    "Only input files can be specified as functions")
            inoutput.append(item)
            if name:
                inoutput.add_name(name)
        else:
            try:
                start = len(inoutput)
                for i in item:
                    self._set_inoutput_item(i, output=output)
                if name:
                    # if the list was named, make it accessible
                    inoutput.set_name(name, start, end=len(inoutput))
            except TypeError:
                raise SyntaxError(
                    "Input and output files have to be specified as strings or lists of strings.")
コード例 #4
0
    def _set_inoutput_item(self, item, output=False, name=None):
        """
        Set an item to be input or output.

        Arguments
        item     -- the item
        inoutput -- a Namedlist of either input or output items
        name     -- an optional name for the item
        """
        inoutput = self.output if output else self.input
        # Check to see if the item is a path, if so, just make it a string
        if isinstance(item, Path):
            item = str(item)
        if isinstance(item, str):
            item = self.apply_default_remote(item)

            # add the rule to the dependencies
            if (isinstance(item, _IOFile) and item.rule
                    and item in item.rule.output):
                self.dependencies[item] = item.rule
            if output:
                rule = self
                if self.wildcard_constraints or self.workflow._wildcard_constraints:
                    try:
                        item = update_wildcard_constraints(
                            item, self.wildcard_constraints,
                            self.workflow._wildcard_constraints)
                    except ValueError as e:
                        raise IOFileException(str(e),
                                              snakefile=self.snakefile,
                                              lineno=self.lineno)
            else:
                rule = self
                if contains_wildcard_constraints(
                        item) and self.workflow.mode != Mode.subprocess:
                    logger.warning(
                        "wildcard constraints in inputs are ignored")
            # record rule if this is an output file output
            _item = IOFile(item, rule=rule)
            if is_flagged(item, "temp"):
                if output:
                    self.temp_output.add(_item)
            if is_flagged(item, "protected"):
                if output:
                    self.protected_output.add(_item)
            if is_flagged(item, "touch"):
                if output:
                    self.touch_output.add(_item)
            if is_flagged(item, "dynamic"):
                if output:
                    self.dynamic_output.add(_item)
                else:
                    self.dynamic_input.add(_item)
            if is_flagged(item, "report"):
                item.flags["report"] = os.path.join(
                    self.workflow.current_basedir, item.flags["report"])
            if is_flagged(item, "subworkflow"):
                if output:
                    raise SyntaxError(
                        "Only input files may refer to a subworkflow")
                else:
                    # record the workflow this item comes from
                    sub = item.flags["subworkflow"]
                    if _item in self.subworkflow_input:
                        other = self.subworkflow_input[_item]
                        if sub != other:
                            raise WorkflowError(
                                "The input file {} is ambiguously "
                                "associated with two subworkflows "
                                "{} and {}.".format(item, sub, other),
                                rule=self)
                    self.subworkflow_input[_item] = sub
            inoutput.append(_item)
            if name:
                inoutput.add_name(name)
        elif callable(item):
            if output:
                raise SyntaxError(
                    "Only input files can be specified as functions")
            inoutput.append(item)
            if name:
                inoutput.add_name(name)
        else:
            try:
                start = len(inoutput)
                for i in item:
                    self._set_inoutput_item(i, output=output)
                if name:
                    # if the list was named, make it accessible
                    inoutput.set_name(name, start, end=len(inoutput))
            except TypeError:
                raise SyntaxError(
                    "Input and output files have to be specified as strings or lists of strings."
                )