Snakemake:参数键的通配符
Snakemake: wildcards for parameter keys
我正在尝试创建一个 snakemake 规则,其输入和输出是由通配符指定的配置参数,但遇到了问题。
我想做类似的事情:
config.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}
被视为通配符,但我得到 {cam}
的 KeyError。有人可以帮忙吗?
是否可以将 {cam}
指定为通配符(或其他东西),然后可以将其用作配置密钥?
我认为这种方法存在一些问题:
概念上
在 config
中指定确切的 input
和 output
文件名没有多大意义,因为这与您使用 [=17] 的原因截然相反=]:根据输入推断管道的哪一部分需要 运行 创建所需的输出。在这种情况下,您将始终必须首先为每个 input/output 对编辑配置,并且整个自动化点都将丢失。
现在,实际问题是从 config
访问 input
和 output
的配置变量。通常,你会,例如在配置中提供一些路径并使用类似的东西:
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};"
我正在尝试创建一个 snakemake 规则,其输入和输出是由通配符指定的配置参数,但遇到了问题。
我想做类似的事情:
config.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}
被视为通配符,但我得到 {cam}
的 KeyError。有人可以帮忙吗?
是否可以将 {cam}
指定为通配符(或其他东西),然后可以将其用作配置密钥?
我认为这种方法存在一些问题:
概念上
在 config
中指定确切的 input
和 output
文件名没有多大意义,因为这与您使用 [=17] 的原因截然相反=]:根据输入推断管道的哪一部分需要 运行 创建所需的输出。在这种情况下,您将始终必须首先为每个 input/output 对编辑配置,并且整个自动化点都将丢失。
现在,实际问题是从 config
访问 input
和 output
的配置变量。通常,你会,例如在配置中提供一些路径并使用类似的东西:
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};"