Python Snakemake:将多个输入用于具有多个子组的一个输出的规则

Python Snakemake:将多个输入用于具有多个子组的一个输出的规则,python,bioinformatics,snakemake,vcf-variant-call-format,Python,Bioinformatics,Snakemake,Vcf Variant Call Format,我有一个工作管道,用于下载、对齐和执行对公共测序数据的变体调用。问题是,目前它只能在每个样本的基础上工作(即样本作为每个单独的测序实验)。如果我想对一组实验(例如样本的生物和/或技术复制)执行变量调用,那么它就不起作用。我试着解决它,但没能成功 下面是对齐规则的简化: rule alignment: input: rules.download.output.fastq output: '{group}/alignment/{sample}.bam'

我有一个工作管道,用于下载、对齐和执行对公共测序数据的变体调用。问题是,目前它只能在每个样本的基础上工作(即样本作为每个单独的测序实验)。如果我想对一组实验(例如样本的生物和/或技术复制)执行变量调用,那么它就不起作用。我试着解决它,但没能成功

下面是对齐规则的简化:

rule alignment:
    input:
        rules.download.output.fastq
    output:
        '{group}/alignment/{sample}.bam'
    shell:
        "bash scripts/02_alignment.sh {wildcards.group} {wildcards.samples}"
对于变量调用也是如此:

rule variant_calling:
    input:
        rules.alignment.output
    output:
        '{group}/variants/{sample}.vcf.gz'
    shell:
        "bash scripts/03_variant_calling.sh {wildcards.sample} {wildcards.group}"
这很好,因为为每个对齐的
.bam
文件生成了一个
.vcf
文件。但是我想做的是从任意数量的
.bam
文件生成一个
.vcf
文件。我有一个
pandas
数据框,包含所有
sample
名称及其对应的
。基本上,我想将第二条规则的
输出
更改为
'{group}/variants/{group}.vcf'
,但我所做的一切都以某种方式失败了

我的想法是提供规则,将所有按组排列的
.bam
文件作为输入,然后只给脚本它运行它们所在的目录。问题是,我找不到一种方法以这种按组的方式提供输入:要么按样本提供(作为工作管道),要么为每个组变量调用提供所有
.bam
文件,而不管它们实际上属于哪个组。我不能只使用通配符,因为
{sample}
通配符不存在于最后的输出中。我还尝试使用函数作为输入,但这会导致与上面相同的问题

问题的关键似乎是分组的层次:如果我想对数据集中所有对齐的
.bam
文件执行变量调用,那么这可能会很好,请给出我上面提到的问题。整个数据集的子组会出现问题:

  sample1      sample2             sample1      sample2      sample3
     |            |                   |            |            |
     |            |                   |            |            |
     --------------                   ---------------------------
            |                                      |
            |                                      |
          group1                                 group2

关于如何解决这个问题,您有什么想法吗?

您必须使用某种结构将样本分组保存:

GROUPS = {
    "group1":["sample1","sample2"],
    "group2":["sample1","sample2","sample3"]
}
然后像这样:

rule all:
    input:
         expand("{group}/variants/{group}.vcf.gz", group=list(GROUPS.keys()))

rule alignment:
    input:
        rules.download.output.fastq
    output:
        '{group}/alignment/{sample}.bam'
    shell:
        "bash scripts/02_alignment.sh {wildcards.group} {wildcards.samples}"

rule variant_calling:
    input:
        lambda wildcards: expand("{group}/alignment/{sample}.bam", group=wildcards.group, sample=GROUPS[wildcards.group]
    output:
        '{group}/variants/{group}.vcf.gz'
    shell:
        "bash scripts/03_variant_calling.sh {input} {output}"
当然,有些规则你没有显示出来,但我想你会明白的

规则变量_调用中的shell命令可能很难处理,但您始终可以将目录定义为如下参数:

params: groupAlignDir = "{group}/alignment"
在外壳中使用:

"bash scripts/03_variant_calling.sh {params.groupAlignDir} {output}"

并在脚本“variant\u calling.sh”中获取目录中的所有bam文件

哦,太好了!我总是以“样本到组”的方式思考,而不是将组中的所有样本列为输入。获取输入目录时,我使用
$(dirname{input[0]})
作为脚本的参数,因为这与我使用的其他东西类似。非常感谢你的帮助!