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 的唯一原因。
希望对您有所帮助。否则,您可以评论或编辑您所担心的更现实的例子。
我想了解 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 的唯一原因。
希望对您有所帮助。否则,您可以评论或编辑您所担心的更现实的例子。