Beispiel #1
0
def make_output(rule, prefix="s1"):
    """Generate output file for rule. Assume target is based on prefix
    's1'; else, use rules2targets dictionary"""

    rn = os.path.basename(rule).replace(".rule", "")
    app = os.path.basename(os.path.dirname(rule))
    target = rules2targets.get(app, {}).get(rn, None)
    if target:
        return target
    code, linemake, rulecount = parse(rule)
    m = re.search("@workflow.output\(\s+(?P<output>.*)", code)
    if m is None:
        # return input case
        m = re.search("@workflow.input\(\s+(?P<input>.*)", code)
        output = m.group("input")
    else:
        output = m.group("output")
    m = re.search(
        "\"[ ]*(?P<prefix>\{[a-zA-Z_0-9]+\})+(?P<ext>[_\/\.a-zA-Z0-9 ]+)\"",
        output)
    # Regular extension; use first one
    if m:
        return "{prefix}{ext}".format(prefix=prefix, ext=m.group("ext"))
    # expand case; skip for now
    m = re.search("expand", output)
    if m:
        return None
    # Config case
    m = re.search("[a-zA-Z =]*(?P<config>config[^\)]+)", output)
    if m:
        return "config"
    return None
Beispiel #2
0
def get_rule_names(snakefile_name):
    """ Run snakemake.parser.parse and use regexp to get the rule names
        This is incredibly inefficient, but a little more stable than trying to
        parse rules myself.
    """
    for line in parse(snakefile_name)[0].split("\n"):
        m = rule_rexp.match(line)
        if m:
            yield m.group(1)
Beispiel #3
0
    def include(
        self,
        snakefile,
        overwrite_first_rule=False,
        print_compilation=False,
        overwrite_shellcmd=None,
    ):
        """
        Include a snakefile.
        """
        # check if snakefile is a path to the filesystem
        if not urllib.parse.urlparse(snakefile).scheme:
            if not os.path.isabs(snakefile) and self.included_stack:
                snakefile = os.path.join(self.current_basedir, snakefile)
            # Could still be an url if relative import was used
            if not urllib.parse.urlparse(snakefile).scheme:
                snakefile = os.path.abspath(snakefile)
        # else it could be an url.
        # at least we don't want to modify the path for clarity.

        if snakefile in self.included:
            logger.info("Multiple include of {} ignored".format(snakefile))
            return
        self.included.append(snakefile)
        self.included_stack.append(snakefile)

        global workflow

        workflow = self

        first_rule = self.first_rule
        code, linemap, rulecount = parse(
            snakefile,
            overwrite_shellcmd=self.overwrite_shellcmd,
            rulecount=self._rulecount,
        )
        self._rulecount = rulecount

        if print_compilation:
            print(code)

        # insert the current directory into sys.path
        # this allows to import modules from the workflow directory
        sys.path.insert(0, os.path.dirname(snakefile))

        self.linemaps[snakefile] = linemap
        exec(compile(code, snakefile, "exec"), self.globals)
        if not overwrite_first_rule:
            self.first_rule = first_rule
        self.included_stack.pop()
Beispiel #4
0
    def include(self, snakefile,
                overwrite_first_rule=False,
                print_compilation=False,
                overwrite_shellcmd=None):
        """
        Include a snakefile.
        """
        # check if snakefile is a path to the filesystem
        if not urllib.parse.urlparse(snakefile).scheme:
            if not os.path.isabs(snakefile) and self.included_stack:
                current_path = os.path.dirname(self.included_stack[-1])
                snakefile = os.path.join(current_path, snakefile)
            # Could still be an url if relative import was used
            if not urllib.parse.urlparse(snakefile).scheme:
                snakefile = os.path.abspath(snakefile)
        # else it could be an url.
        # at least we don't want to modify the path for clarity.

        if snakefile in self.included:
            logger.info("Multiple include of {} ignored".format(snakefile))
            return
        self.included.append(snakefile)
        self.included_stack.append(snakefile)

        global workflow

        workflow = self

        first_rule = self.first_rule
        code, linemap, rulecount = parse(snakefile,
                                         overwrite_shellcmd=self.overwrite_shellcmd,
                                         rulecount=self._rulecount)
        self._rulecount = rulecount

        if print_compilation:
            print(code)

        # insert the current directory into sys.path
        # this allows to import modules from the workflow directory
        sys.path.insert(0, os.path.dirname(snakefile))

        self.linemaps[snakefile] = linemap
        exec(compile(code, snakefile, "exec"), self.globals)
        if not overwrite_first_rule:
            self.first_rule = first_rule
        self.included_stack.pop()
Beispiel #5
0
    def include(self, snakefile, workdir=None, overwrite_first_rule=False,
        print_compilation=False):
        """
        Include a snakefile.
        """
        global workflow
        workflow = self
        first_rule = self.first_rule
        if workdir:
            os.chdir(workdir)
        code, linemap = parse(snakefile)

        if print_compilation:
            print(code)

        self.linemaps[snakefile] = linemap
        exec(compile(code, snakefile, "exec"), self.globals)
        if not overwrite_first_rule:
            self.first_rule = first_rule
Beispiel #6
0
def make_output(rule, prefix="s1"):
    rn = os.path.basename(rule).replace(".rule", "")
    app = os.path.basename(os.path.dirname(rule))
    target = rules2targets.get(app, {}).get(rn, None)
    if target:
        return target
    code, linemake, rulecount = parse(rule)
    m = re.search("@workflow.output\(\s+(?P<output>.*)", code)
    output = m.group("output")
    m = re.search("\"[ ]*(?P<prefix>\{[a-zA-Z_0-9]+\})+(?P<ext>[_\/\.a-zA-Z0-9 ]+)\"", output)
    # Regular extension; use first one
    if m:
        return "{prefix}{ext}".format(prefix=prefix, ext=m.group("ext"))
    # expand case; skip for now
    m = re.search("expand", output)
    if m:
        return None
    # Config case
    m = re.search("[a-zA-Z =]*(?P<config>config[^\)]+)", output)
    if m:
        return "config"
    return None
Beispiel #7
0
    def include(self,
                snakefile,
                workdir=None,
                overwrite_first_rule=False,
                print_compilation=False):
        """
        Include a snakefile.
        """
        global workflow
        workflow = self
        first_rule = self.first_rule
        if workdir:
            os.chdir(workdir)
        code, linemap = parse(snakefile)

        if print_compilation:
            print(code)

        self.linemaps[snakefile] = linemap
        exec(compile(code, snakefile, "exec"), self.globals)
        if not overwrite_first_rule:
            self.first_rule = first_rule
Beispiel #8
0
def parse_rule(rule, prefix=None):
    """Generate information for rule stored in a dictionary.

    Params:
      rule (str): file containing a snakemake rule

    Results:
      input (list): list of input files
      output (list): list of output targets
    """
    d = {}
    codemap = {
        'rule': "",
        'input': "",
        'output': "",
        'wildcard_constraints': ""
    }
    rn = os.path.basename(rule).replace(".rule", "")
    app = os.path.basename(os.path.dirname(rule))
    code, linemake, rulecount = parse(rule)

    l = regex_workflow.findall(code)
    for k, v in l:
        codemap[k] = re.sub("[\t\n ]", "", v)

    m_name = regex_name.search(codemap['rule'])
    d['name'] = m_name.group("name")
    d['output'] = get_targets(codemap["output"])
    d['input'] = get_targets(codemap["input"])
    d['wildcard_constraints'] = {
        k: v
        for k, v in regex_wildcard_constraints.findall(
            codemap["wildcard_constraints"])
    }
    if d['wildcard_constraints'] == '':
        d['wildcard_constraints'] = {}

    # Output missing; return input case if possible
    return d
Beispiel #9
0
def _cli():
    ########################################################################
    # First install snakemake module
    parser = argparse.ArgumentParser(
        description="Converts *.smk file to *.py using snakemake parser",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("input",
                        metavar="INPUT",
                        help="Snakemake file (or *.smk file)")

    parser.add_argument("output", metavar="OUTPUT", help="Result python file")

    args = parser.parse_args()
    input_path = args.input
    output_path = args.output

    ########################################################################

    compilation, _linemap, rc = smp.parse(input_path)
    with open(output_path, mode="w") as out:
        print(compilation, file=out)
    print("Done, rules:", str(rc))
    print("Saved to :", output_path)