首页 > 解决方案 > Snakemake:参数键的通配符

问题描述

我正在尝试创建一个蛇形规则,其输入和输出是通配符指定的配置参数,但有问题。

我想做类似的事情:

配置.yaml

cam1:
  raw: "src/in1.avi"
  bg: "out/bg1.png"
cam2:
  raw: "src/in2.avi"
  bg: "out/bg2.png"
cam3:
  raw: "src/in3.avi"
  bg: "out/bg3.png"

蛇文件:

configfile: "config.yml"

...
rule all:
  input:
    [config[f'cam{id}']['background'] for id in [1, 2, 3]]

rule make_bg:
  input:
    raw=config["{cam}"]["raw"]
  output:
    bg=config["{cam}"]["bg"]
  shell:
    """
    ./process.py {input.raw} {output.bg}
    """

但这似乎不起作用 - 我想{cam}被视为通配符,而不是我得到一个 KeyError for {cam}. 任何人都可以帮忙吗?

是否可以指定{cam}为通配符(或其他东西),然后可以使用配置键?

标签: snakemake

解决方案


我认为这种方法存在一些问题:

概念上

input在 a 中指定确切的文件名和output文件名没有多大意义config,因为这与您使用的原因截然相反snakemake:从输入推断需要运行管道的哪个部分来创建所需的输出。在这种情况下,您总是必须首先编辑每个输入/输出对的配置,并且整个自动化点都丢失了。

现在,实际的问题是从configforinputoutput. 通常,您会在配置中提供一些路径并使用类似的东西:

config.yaml

raw_input = 'src'
bg_output = 'out'

在管道中,您可以像这样使用它:

input: os.path.join(config['raw_input'], in{id}.avi)
output: os.path.join(config['bg_output'], bg{id}.avi)

就像我说的,在配置文件中特别指定输出是没有意义的。

如果要在 中指定输入config.yaml

cam1:
  raw: "src/in1.avi"
cam2:
  raw: "src/in2.avi"
cam3:
  raw: "src/in3.avi"

然后,您可以使用以下函数获取输入:

configfile: "config.yaml"

# create sample data
os.makedirs('src', exist_ok= True)
for i in [1,2,3]:
    Path(f'src/in{i}.avi').touch()

ids = [1,2,3]

def get_raw(wildcards):
    id = 'cam' + wildcards.id
    raw = config[f'{id}']['raw']
    return raw

rule all:
  input: expand('out/bg{id}.png', id = ids)

rule make_bg:
    input:
        raw = get_raw
    output:
        bg='out/bg{id}.png'
    shell:
        " touch {input.raw} ;"
        " cp {input.raw} {output.bg};"

推荐阅读