【问题标题】:Snakemake: pass command line arguments to scriptsSnakemake:将命令行参数传递给脚本
【发布时间】:2020-04-22 16:23:06
【问题描述】:

我正在使用一些带有snakemake 的python 脚本来自动化工作流程。这些脚本接受命令行参数,虽然我可以用snakemake.input[0]snakemake.output[0] 等替换它们,但我不愿意这样做,因为我还希望能够在snakemake 之外使用它们。

解决这个问题的一种自然方法——我一直在做的——是将它们作为shell 而不是script 运行。但是,当我这样做时,依赖图被破坏了;我更新了我的脚本,DAG 认为不需要重新运行任何东西。

有没有办法将命令行参数传递给脚本但仍将它们作为脚本运行?

编辑:一个例子

我的python脚本

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-o", type=str)
args = parser.parse_args()

with open(args.o, "w") as file:
    file.write("My file output")

我的蛇文件

rule some_rule:
    output: "some_file_name.txt"
    shell: "python my_script.py -o {output}"

【问题讨论】:

  • 我不知道script 会让snakemake 知道脚本的变化(我总是使用shellshell() 调用run)。也许您可以为您的脚本创建一个双重接口,对第一个 try 进行异常处理,以访问来自 snakemake 对象的信息,并从 except 子句中的命令行访问信息。
  • 既然您似乎是在开发蛇文件旁边的脚本,您可以将 python 脚本作为输入添加到规则中吗?然后更改 python 脚本的修改时间将触发规则的重新运行。这很 hacky,但你可以在“完成”python 代码开发后将其删除。

标签: snakemake


【解决方案1】:

根据@troy-comi 的评论,我一直在做以下事情——虽然有点骇人听闻——但正是我想要的。我将脚本定义为snakemake 规则的输入,这实际上也有助于提高可读性。一个典型的规则(这不是一个完整的 MWE)可能看起来像

rule some_rule:
    input:
        files=expand("path_to_files/f", f=config["my_files"]),
        script="scripts/do_something.py"
    output: "path/to/my/output.txt"
    shell: "python {input.script} -i {input.files} -o {output}"

当我修改脚本时,它会触发重新运行;它是可读的;并且它不需要我在我的 python 脚本中插入snakemake.output[0](使得它们很难在这个工作流程之外回收)。

【讨论】:

    【解决方案2】:

    你能做一些简单的 if 语句来从 snakemake 或命令行获取参数吗

    那是

    if snakemake in globals():
        get parameters from snakemake
    else:
        get code some other way
    

    【讨论】:

      【解决方案3】:

      听起来你需要在你的 python 脚本中使用argparse。这是一个示例,其中 python 脚本通过命令行接受参数:

      • Python 脚本example.py
      import argparse
      parser = argparse.ArgumentParser()
      parser.add_argument("-i", "--infile", help="Filepath")
      parser.add_argument("-o", "--outfile", help="Filepath")
      args = parser.parse_args()
      
      infilepath = args.infile
      outfilepath = args.outfile
      # blah blah code
      
      • 蛇文件
      rule xx:
      input: "in.txt"
      output: "out.txt"
      shell: "python example.py -i {input} -o {output}"
      

      PS - 当我懒惰时,我只使用Fire 库而不是 argparse。 Fire 只需几行代码即可轻松地将函数/类公开给命令行。

      【讨论】:

      • 是的,这就是我现在正在做的事情。但是当我更新example.py 时,它不会触发重新运行规则
      • 啊,我明白了。看起来您的问题可能需要修改以反映这一点。添加示例会有所帮助。
      猜你喜欢
      • 2014-03-08
      • 2013-10-22
      • 2016-12-19
      • 2013-10-11
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      相关资源
      最近更新 更多