存储 shell 命令的结果

Storing the result of a shell command

正如您在标题中看到的那样,我对存储 shell 命令的结果并将其传递给另一个规则很感兴趣。

以下是我的规则:

SAMTOOLS = config["SAMTOOLS"]
rule useDepth:
  input:
     depth = "{individual}_{chr}.fixmate.sort.rgmdup.bam.depth"
  output:
     tmpVCF = "{individual}_{chr}.vcf"
  run:
     depth = storage.fetch("chrDepth")
     shell("echo {depth} | exit 1")

rule calDepth:
  input:
     bam = "{individual}.fixmate.sort.rgmdup.bam"
  output:
     temp("{individual}_{chr}.fixmate.sort.rgmdup.bam.depth")
  run:
     import subprocess,shlex
     depth=subprocess.check_output(shlex.split("{SAMTOOLS} depth -r {wildcards.chr} {input.bam} | awk '{{sum += }} END {{print sum / NR}}'"),shell=True)
     storage.store("chrDepth", depth)
     shell("echo \"Depth for {wildcards.chr} has been calculated\" > {output[0]}")

可以肯定的是,由于出口 1,我在这里收到了一个错误!但这只是为了测试。

我要解决的错误是 subprocess.check_output()!

中 {SAMTOOLS} 的值
depth: 1: depth: {SAMTOOLS}: not found
Error in job chrDepth while creating output file
RuleException:
Command '['{SAMTOOLS}', 'depth', '-r', '{wildcards.chr}', '{input.bam}', '|', 'awk', '{{sum += }} END {{print sum / NR}}']'

为了提供更多信息,因为不同的用户可能会在不同的地方安装 samtools,我们通过配置文件使 samtools 的地址可配置。但是,这里我不能:

1) 读取{SAMTOOLS}的正确值!

2) 使整个命令可运行!

那么,能否请您告诉我是否有任何其他方法可以 store/pass 将一个规则的输出输出到另一个规则!?更具体地说,我如何增强 snakemake 以告知 shell {SAMTOOLS} 可用。

谢谢!

这是您设置访问权限以用作 Python 变量。

SAMTOOLS = config["SAMTOOLS"]

但是您尝试通过 {SAMTOOLS} 在此处访问它,作为 Snakemake 规则特定的通配符:

depth=subprocess.check_output(shlex.split("{SAMTOOLS} depth -r {wildcards.chr} {input.bam} | awk '{{sum += }} END {{print sum / NR}}'"),shell=True)

Snakemake 通配符的访问方式与 Python 变量不同。 此外,此处的 {SAMTOOLS} 被作为 Snakemake 通配符访问,但您没有将其用作规则输出中的通配符。

假设 {wildcards.chr} 有效,并且 {SAMTOOLS} 调用是唯一未找到的通配符(不仅仅是第一个未知的通配符),我认为您应该尝试以下两种方法之一。

没有预分配:

depth=subprocess.check_output(shlex.split("config['SAMTOOLS'] depth -r {wildcards.chr} {input.bam} | awk '{{sum += }} END {{print sum / NR}}'"),shell=True)

将其作为 python 变量作为字符串访问(它是一个表示字符串的对象):

depth=subprocess.check_output(shlex.split(SAMTOOLS + " depth -r {wildcards.chr} {input.bam} | awk '{{sum += }} END {{print sum / NR}}'"),shell=True)

最后,也是最不推荐的,因为它引入了规则-规则耦合,在 Snakemake 中有一些方法可以跨规则传递变量,你已经在使用它了,但是,我认为这不是这里所需要的.适当的访问和设计应该就足够了。

Snakemake Tutorial FAQ: How to pass variables between rules

旁注

为了消除跨规则传递的字符深度,并将其保存为文件名的路径,并解耦规则,我强烈建议将 chrDepth 转换为命名通配符...

类似...

rule useDepth:
  input:
     depth = "{individual}_{chr}_of_{chrDepth}.fixmate.sort.rgmdup.bam.depth"
  output:
     tmpVCF = "{individual}_{chr}_of{chrDepth}.vcf"

但我不确定您是如何计算 chrDepth 的。我担心你在所有这些规则之间传递它,而不仅仅是依赖良好的命名约定。它可能会不必要地耦合您的代码,导致下游出现问题和开销。