Snakemake 中不同(已知)的输出数量

Varying (known) number of outputs in Snakemake

我有一个适用于数据存档的 Snakemake 规则,基本上可以解压缩其中的数据。档案包含在我的规则开始之前我知道的不同数量的文件,所以我想利用它并做一些类似

的事情
rule unpack:
    input: '{id}.archive'
    output: 
        lambda wildcards: ARCHIVE_CONTENTS[wildcards.id]

但我不能使用 output 中的函数,这是有充分理由的。但是,我想不出一个好的替代品。这条规则对运行来说非常昂贵,所以我做不到

rule unpack:
    input: '{id}.archive'
    output: '{id}/{outfile}'

和运行规则对每个存档多次。另一种选择可能是

rule unpack:
    input: '{id}.archive'
    output: '{id}/{outfile}'
    run:
        if os.path.isfile(output[0]):
            return
        ...

但恐怕会引入竞争条件。

dynamic标记规则输出真的是唯一的选择吗?我可以为每个存档自动生成一个单独的规则,但我还没有找到这样做的方法。

在这里,Snakemake 是 plain Python 的扩展就变得很方便了。您可以为每个存档生成单独的规则:

for id, contents in ARCHIVE_CONTENTS.items():
    rule:
        input: 
            '{id}.tar.gz'.format(id=id)
        output: 
            expand('{id}/{outfile}', outfile=contents)
        shell:
            'tar -C {wildcards.id} -xf {input}'

根据这是什么类型的存档,您也可以有一个只提取所需文件的规则,例如:

rule unpack:
    input:
        '{id}.tar.gz'
    output:
        '{id}/{outfile}'
    shell:
        'tar -C {wildcards.id} -xf {input} {wildcards.outfile}'