我有一个问题,弄清楚如何使输入指令只选择下面的规则中的所有{samples}
文件。
rule MarkDup:
input:
expand("Outputs/MergeBamAlignment/{samples}_{lanes}_{flowcells}.merged.bam", zip,
samples=samples['sample'],
lanes=samples['lane'],
flowcells=samples['flowcell']),
output:
bam = "Outputs/MarkDuplicates/{samples}_markedDuplicates.bam",
metrics = "Outputs/MarkDuplicates/{samples}_markedDuplicates.metrics",
shell:
"gatk --java-options -Djava.io.tempdir=`pwd`/tmp \
MarkDuplicates \
$(echo ' {input}' | sed 's/ / --INPUT /g') \
-O {output.bam} \
--VALIDATION_STRINGENCY LENIENT \
--METRICS_FILE {output.metrics} \
--MAX_FILE_HANDLES_FOR_READ_ENDS_MAP 200000 \
--CREATE_INDEX true \
--TMP_DIR Outputs/MarkDuplicates/tmp"
目前,它将创建正确命名的输出文件,但它会根据所有通配符选择与模式匹配的所有文件。所以我可能就在那里。我尝试在输入指令中将{samples}
更改为{{samples}}
:
expand("Outputs/MergeBamAlignment/{{samples}}_{lanes}_{flowcells}.merged.bam", zip,
lanes=samples['lane'],
flowcells=samples['flowcell']),`
但这不知何故打破了以前的规则。所以解决方案是这样的
input:
"{sample}_*.bam"
但显然这不起作用。是否可以收集所有与{sample}_*.bam
匹配的文件并将其用作输入?如果是这样,该函数是否仍然可以在shell指令中使用$(echo ' {input}' etc...)
?
如果您只想要目录中的所有文件,则可以使用lambda函数
from glob import glob
rule MarkDup:
input:
lambda wcs: glob('Outputs/MergeBamAlignment/%s*.bam' % wcs.samples)
output:
bam="Outputs/MarkDuplicates/{samples}_markedDuplicates.bam",
metrics="Outputs/MarkDuplicates/{samples}_markedDuplicates.metrics"
shell:
...
请注意,此方法无法检查丢失的文件,因为它始终会报告所需的文件是存在的文件。如果确实需要确认已执行上游规则,则可以让先前的规则触摸一个标志,然后您需要将该标志作为此规则的输入(尽管除了强制执行顺序之外,您实际上并未使用该文件) 。
如果我理解正确,zip
只需要应用于{lane}
和{flowcells}
而不是{samples}
。在那种情况下,使用两个expand
实例可以实现这一点。
input:
expand(expand("Outputs/MergeBamAlignment/{{samples}}_{lanes}_{flowcells}.merged.bam",
zip, lanes=samples['lane'], flowcells=samples['flowcell']),
samples=samples['sample'])
PS:output.tmp
文件使用{sample}
而不是{samples}
。错字?