当文件数量已知时,如何在 snakemake 中实现文件拆分

How to implement splitting of files in snakemake when number of files is known

上下文

rule Ashell 指令中使用 split 命令。 rule A 生成的文件数量取决于用户在配置中指定的值,因此是已知的。

this question中存在差异,因为输出文件的数量未知,但有对dynamic()关键字的引用。显然这已被 checkpoint 的使用所取代。在这种情况下,这真的是正确的方法吗?还有类似 scattergatter 的东西,但我不清楚这个例子。

代码

chunks = config["chunks"]
sample_list = ["S1", "S2"]

rule all:
    input:
       expand("{sample}_chunk_{chunk}_done_something.tsv", sample=sample_list, 
             chunk=[f"{i}".zfill(len(str(chunks))-1) for i in range(0, chunks)])

rule A:
    input:
        "input_file_{sample}.tsv"
    output:
        # the user defined number of chunks, how to specify these?
    params: chunks=chunks
    shell:
        "split -n {params.chunks} --numeric-suffixes=1 --additional-suffix=.tsv {input[0]} some_prefix_{wildcards.sample}_"

rule B: 
    input:
        "some_prefix_{sample}_{chunk}.tsv"
    output:
        "{sample}_chunk_{chunk}_done_something.tsv"
    shell:
        "#Do something"

尝试次数

我尝试在 rule B 中使用带有 input function 的检查点,并在 rule A 中使用 directory()。但是,使用目录会导致 SyntaxError in line 253 of MySnakefile: Unexpected keyword directory in rule definition (Snakefile, line 253),即使不会引发错误,我也不知道如何将 chunks 放入此输入函数中,因为它不是通配符。

如何在Snakemake中最好地实现输入文件的拆分?

由于事先知道块的数量,您可以使用数组从块参数中设置 rule A 中的输出文件数:

rule A:
    ...
    output:
        chunks = ["some_prefix_{{sample}}_{02d}.tsv".format(x+1) for x in range(chunks)]

使用 chunks = 2,这将扩展为 chunks = ["some_prefix_{sample}_01.tsv", "some_prefix_{sample}_02.tsv"],匹配 split 输出的语法。 {sample} 通配符将由 Snakemake 的标准通配符替换项填充。