我的逻辑可能有缺陷,我需要你的帮助来找到解决这个问题的最佳方法:
我有一个菊花链式工作流程,其中我分多个步骤注释 .vcf 文件,每个步骤都有一个中间索引操作(注意输入和输出之间的扩展名差异):
rule first:
input: "{file}.vcf.gz"
output: "{file}_first.vcf"
shell: "annotate {input} {output}"
rule first_index:
input: rules.first.output
output:
gz="{file}_first.vcf.gz"
tbi="{file}_first.vcf.gz.tbi"
shell: """
bgzip {input}
tabix -p vcf {output.gz}
"""
rule second:
input: rules.first.index.output.gz
output: "{file}_first_second.vcf"
shell: "annotate2 {input} {output}"
rule second_index:
input: rules.second.output
output:
gz="{file}_first_second.vcf.gz"
tbi="{file}_first_second.vcf.gz.tbi"
shell: """
bgzip {input}
tabix -p vcf {output.gz}
"""
... (etc, five or six iterations more like that)
现在,这种方法可能非常庞大,并且由于工作流程链中的文件命名而导致一些错误,并且如果我想在两个现有规则中间添加规则,则可能非常不灵活,需要我重新编辑所有后续规则 - 两次,一次用于注释,第二次用于索引。
这里有两个时刻我想优化。首先是根据先前的规则输入加上当前的规则名称来命名输出文件。但是,这并不重要。更重要的是,我想清理索引步骤,这实际上是通用的。有没有办法设计一个在输出中引用输入的规则?
比如说,获取未知的输入文件并将其转换为具有不同扩展名的相同名称:
rule generic_index:
input: "{file}.vcf"
output:
gz="{input}.gz"
tbi="{input}.gz.tbi"
shell: """
bgzip {input}
tabix -p vcf {output.gz}
"""
这样我就可以在每一步之后以最小的更改重新使用索引规则:
use rule generic_index as generic_index_first with:
input: rules.first.output
这将消除每次我想重新使用规则时重新指定输出名称(从而重复信息)的需要。非常欢迎您分享任何其他建议/最佳实践解决方案!
谢谢!
您提出的通用索引规则对我来说看起来很正确,有一些小修正:
rule generic_index:
input: "{file}.vcf"
output:
gz = "{file}.vcf.gz",
tbi = "{file}.vcf.gz.tbi"
shell:
"""
bgzip {input}
tabix -p vcf {output.gz}
"""
修复是:您无法在输出文件名中引用
{input}
(仅在 shell 部分);你必须说{file}.vcf
。此外,您还需要在输出之间使用逗号,并在 shell:
之后添加换行符,因为命令字符串是多行的。 注意 - 我没有测试上面的代码
这应该就是您所需要的。当你问“我如何重新使用这条规则”时,答案是没有什么可做的。如果你的名字正确,那么 Snakemake 会根据与名字匹配的模式为你链接规则。查看代码的其余部分,所有对
rules.whatever.output
的显式引用看起来都是错误的。我的建议是花一点时间浏览官方的 Snakemake 教程。了解这些示例中的所有规则如何使用通配符模式进行链接 - 没有直接引用任何其他规则。