如果您事先知道布局,那么最简单的方法是将其存储在某个变量中,如下所示(或者您从配置文件中将其读取到字典中):
layouts = {"sample1": "paired", "sample2": "single", ... etc}
然后你可以做的是像这样“合并”你的规则(我猜你正在谈论修剪和对齐,所以这就是我的例子):
ruleorder: B > A
rule A:
input:
{sample}.fastq.gz
output:
trimmed_{sample}.fastq.gz
shell:
"somecommand -i {input} -o {output}"
rule B:
input:
input1={sample}_R1.fastq.gz,
input2={sample}_R2.fastq.gz
output:
output1=trimmed_{sample}_R1.fastq.gz,
output2=trimmed_{sample}_R2.fastq.gz
shell:
"somecommand -i1 {input.input1} -i2 {input.input2} -o1 {output.output1} -o2 {output.output2}"
def get_fastqs(wildcards):
output = dict()
if layouts[wildcards.sample] == "single":
output["input"] = "trimmed_sample2.fastq.gz"
elif layouts[wildcards.sample] == "paired":
output["input1"] = "trimmed_sample1_R1.fastq.gz"
output["input2"] = "trimmed_sample1_R2.fastq.gz"
return output
rule alignment:
def input:
unpack(get_fastqs)
def output:
somepath/{sample}.bam
shell:
...
这里发生了很多事情。
- 首先,您需要一个规则顺序,以便蛇形知道如何处理模棱两可的情况
- 规则 A 和 B 都必须存在(除非你对输出文件做 sth hacky)。
- 对齐规则需要一个输入函数来确定它需要哪个输入。
一些自我推销:我做了一个蛇形管道,它可以做很多事情,包括 RNA-seq 和在线下载样本并自动确定它们的布局(单端与双端)。请看看它是否解决了您的问题:https ://vanheeringen-lab.github.io/seq2science/content/workflows/rna_seq.html
编辑:
- 当您说“合并”规则时,您是指规则 A、B 和对齐吗?
那是我不清楚的措辞。合并我的意思是“将单端和双端和双端逻辑合并在一起,这样您就可以继续使用单个规则(例如计数表,您可以命名它)。
- 规则顺序:为什么选择 B > A?确保配对样本最终不会在单端规则中运行?
确切地!当一条规则需要 trimmed_sample1_R1.fastq.gz 时,Snakemake 怎么知道你的样本名称?样品的名称是 sample1,还是 sample1_R1?两者都可以,这让snakemake抱怨它不知道如何解决这个问题。添加规则顺序时,您告诉 Snakemake,如果不清楚,请按此顺序解决。
- 对齐规则中的命令需要 1 或 2 个输入。我打算在 params 指令中使用 if/else 来选择输入。我这样想对吗?(我认为您在管道中也这样做了)
是的,这就是我们解决它的方式。我们这样做是因为我们希望每个规则都有自己的环境。如果您不使用单独的 conda 环境进行对齐,那么您可以做得更干净/更漂亮,就像这样
rule alignment:
input:
unpack(get_fastqs)
output:
somepath/{sample}.bam
run:
if layouts[wildcards.sample] == "single":
shell("single-end command")
if layouts[wildcards.sample] == "paired":
shell("paired-end command")
我觉得这个选项比我们在 seq2science 管道中所做的要清晰得多。然而,在 seq2science 管道中,我们支持许多不同的对齐器,并且它们都有不同的 conda 环境,因此run
不能使用该指令。