snakemake 如何处理由于规则 运行 并行同时附加到单个文件而导致的可能损坏?

How does snakemake handle possible corruptions due to a rule run in parallel simultaneously appending to a single file?

我想了解 snakemake 如何处理以下情况,以及避免的最佳做法是什么 collisions/corruptions。

rule something:
    input:
            expand("/path/to/out-{asd}.txt", asd=LIST)
    output:
            "/path/to/merged.txt"
    shell:
            "cat {input} >> {output}"

使用 snakemake -j10 命令将尝试同时附加到同一个文件,我不知道这是否会导致可能的损坏或者是否已经处理。

此外,如何处理更复杂的案件,例如它不仅 cat 而是另一个进程的 return 值,该值基于附加到同一文件的输入值?最佳做法是先将它们写入单独的文件,然后 cat 将它们组合在一起吗?

rule get_merged_total_distinct:
    input:
        expand("{dataset_id}/merge_libraries/{tomerge}_merged_rmd.bam",dataset_id=config["dataset_id"],tomerge=list(TOMERGE.keys())),
    output:
        "{dataset_id}/merge_libraries/merged_total_distinct.csv"
    params:
        with_dups="{dataset_id}/merge_libraries/{tomerge}_merged.bam"
    shell:
        """
        RCT=$(samtools view -@4 -c -F1 -F4 -q 30 {params.with_dups})
        RCD=$(samtools view -@4 -c -F1 -F4 -q 30 {input})
        printf "{wildcards.tomerge},${{RCT}},${{RCD}}\n" >> {output}
        """

或者调用外部脚本将结果打印到单个输出文件的情况?

    input:
        expand("infile/{x}",...) # expanded as above
    output:
        "results/all.txt"
    shell:
        """
        bash script.sh {params.x} {input} {params.y} >> {output}
        """

对于您的示例,shell 指令将扩展为

cat /path/to/out-SAMPLE1.txt /path/to/out-SAMPLE2.txt [...] >> /path/to/merged.txt

其中 SAMPLE1 等来自 LIST。在这种情况下,没有碰撞、损坏或竞争条件。一个线程将 运行 该命令,就像您在 shell 上输入它一样,所有输入都将 cat 输出到输出。由于 snakemake 是基于拉动的,一旦输出存在,​​如果输入发生变化,则该规则将仅 运行 再次出现,由于使用 >>。因此,我建议使用 > 以便删除旧内容;规则应尽可能确定。

现在,如果你做了类似

的事情
rule something:
        input:
                "/path/to/out-{asd}.txt"
        output:
                touch("/path/to/merged-{asd}.txt")
        params:
                output="/path/to/merged.txt"
        shell:
                "cat {input} >> {params.output}"
# then invoke
snakemake -j10 /path/to/merged-{a..z}.txt

事情更乱了。 Snakemake 将启动所有 10 个作业并输出到单个 merged.txt。请注意,文件现在是一个参数,我们的目标是一些虚拟文件。这将表现得好像您有 10 个不同的 shell 并执行了命令

cat /path/to/out-a.txt >> /path/to/merged.txt
# ...
cat /path/to/out-z.txt >> /path/to/merged.txt

一下子。输出将具有随机顺序,并且行可能会交错或中断。

一些指导

  • 尝试使输出具有确定性。给定相同的输入,您应该始终产生相同的输出。如果可能,设置随机种子并强制输入顺序。在第二个例子中,你不知道输出是什么。
  • 不要使用附加运算符。这是从第一点得出的。如果输出已经存在并且需要更新,请从头开始。
  • 如果您需要附加一堆输出,比如日志文件或创建摘要,请在单独的规则中执行。这又是第一点,但这是我能想到使用 append 的唯一原因。

希望对您有所帮助。否则,您可以评论或编辑您所担心的更现实的例子。