snakemake 规则:传递文件名之外的变量

snakemake rules: Passing on variables outside of the file name

到目前为止,我使用 snakemake 通过 snakemake 生成了单独的图。这很好用!不过现在,我想创建一个规则来创建跨主题的组合图,而不是明确地将名称放在图中。请参阅下面的 combined_plot 规则。

topics=["soccer", "football"]
params=[1, 2, 3, 4]

rule all:
  input:
    expand("plot_p={param}_{topic}.png", topic=topics, param=params),
    expand("combined_p={param}_plot.png", param=params),

rule plot:
  input:
    "data_p={param}_{topic}.csv"
  output:
    "plot_p={param}_{topic}.png"
  shell:
    "plot.py --input={input} --output={output}"

rule combined_plot:
  input:
    # all data_p={param}_{topic}.csv files
  output:
    "combined_p={param}_plot.png"
  shell:
    "plot2.py " + # one "--input=" and one "--output" for each csv file

有没有简单的方法可以用 snakemake 做到这一点?

我得到了一个工作版本,通过使用一个名为 'wcs' 的函数作为输入(参见 here)并且我使用 run 而不是 shell。在 run 部分,我可以先定义一个变量,然后再使用 shell(...) 执行结果。

我也可以直接在 lambda 函数中使用 topics,而不是使用 glob 来引用文件。

如果有更多经验的人看到这个,请告诉我这是否是 "right" 的方法。

from glob import glob

topics=["soccer", "football"]
params=[1, 2]

rule all:
  input:
    expand("plot_p={param}_{topic}.png", topic=topics, param=params),
    expand("combined_p={param}_plot.png", param=params),

rule plot:
  input:
    "data_p={param}_{topic}.csv"
  output:
    "plot_p={param}_{topic}.png"
  shell:
    "echo plot.py {input} {output}"

rule combined_plot:
  input:
    lambda wcs: glob("data_p={param}_*.csv".format(**wcs))
  output:
    "combined_p={param}_plot.png"
  run:
    inputs=" ".join(["--input " + inp for inp in input])
    shell("echo plot2.py {inputs}")

如果我理解正确,下面的代码应该更直接,因为它将 lambda 和 glob 替换为 expand 函数。它将执行两个命令:

plot2.py --input=data_p=1_soccer.csv --input=data_p=1_football.csv --output combined_p=1_plot.png
plot2.py --input=data_p=2_soccer.csv --input=data_p=2_football.csv --output combined_p=2_plot.png 

topics=["soccer", "football"]
params=[1, 2]

rule all:
    input:
        expand("combined_p={param}_plot.png", param=params),

rule combined_plot:
    input:
        csv= expand("data_p={{param}}_{topic}.csv", topic= topics)
    output:
        "combined_p={param}_plot.png",
    run:
        inputs= ['--input=' + x for x in input.csv] 
        shell("plot2.py {inputs} --output {output}")