Snakemake 无法访问 config.yaml 中的嵌套值

Snakemake trouble accessing nested values in config.yaml

所以我的以下问题已部分解决,但现在我正尝试将一个变量作为输入传递到所有规则中,并解析它以获取因变量作为另一个规则中的输入。我的代码:

rule all:
        [f"outputs/STAR/all/{x}/counts_2.txt" for x in config["method"]]

rule feature_counts_per_sample:
    input:
        bam=[f"outputs/STAR/{name}/Aligned.sortedByCoord.out.sortedbyname.bam" for name in config["method"][{x}]],
        gtf="data/chr19_20Mb.gtf"
    output:
        outA="outputs/STAR/all/{x}/counts_1.txt",
        outB="outputs/STAR/all/{x}/counts_2.txt"
    shell:
        "mkdir -p outputs/STAR/all/{wildcards.x}/ && featureCounts -p -t exon -g gene_id -a {input.gtf} -o {output.outA} -s 1 {input.bam} && featureCounts -p -t exon -g gene_id -a {input.gtf} -o {output.outB} -s 2 {input.bam}"

问题出在 input.bam - 我收到 name 'x' is not defined 错误,但找不到解决方法。除此之外,我知道该代码有效,因为如果我将 {x} 替换为常量值,我会得到预期的结果。有没有办法做到这一点,或者我应该寻找一种完全不同的方法?


我无法从我的 config.yaml 文件访问嵌套值。我的 config.yaml:

method:
    collibri:
        - Collibri_standard_protocol-HBR-Collibri-100_ng-2_S1_L001_R
        - Collibri_standard_protocol-HBR-Collibri-100_ng-3_S2_L001_R
        - Collibri_standard_protocol-UHRR-Collibri-100_ng-2_S3_L001_R
        - Collibri_standard_protocol-UHRR-Collibri-100_ng-3_S4_L001_R
    kapa:
        - KAPA_mRNA_HyperPrep_-UHRR-KAPA-100_ng_total_RNA-3_S8_L001_R
        - KAPA_mRNA_HyperPrep_-HBR-KAPA-100_ng_total_RNA-2_S5_L001_R
        - KAPA_mRNA_HyperPrep_-HBR-KAPA-100_ng_total_RNA-3_S6_L001_R
        - KAPA_mRNA_HyperPrep_-UHRR-KAPA-100_ng_total_RNA-2_S7_L001_R

num:
    - 1
    - 2

type:
    - collibri
    - kapa

我的目标是立即调用方法组中的所有文件作为输入,并将输出定向到上面有方法名称的文件夹(例如 运行 规则使用 'kapa' 下的所有名称一次并将输出放在 'kapa' 文件夹中)。我的 Snakefile 的简化版本:

configfile: "config.yaml"

rule all:
    input:
        expand("outputs/STAR/{filename}/Aligned.sortedByCoord.out.bam.bai", filename=config["method"]["collibri"]),
        expand("outputs/STAR/{filename}/counts_2.txt", filename=config["method"]["collibri"]),
        expand("outputs/STAR/{filename}/Aligned.sortedByCoord.out.bam.bai", filename=config["method"]["kapa"]),
        expand("outputs/STAR/{filename}/counts_2.txt", filename=config["method"]["kapa"]),
        expand("outputs/STAR/{type}/counts_2.txt", type=config["type"])

rule bam_index:
    input:
        "outputs/STAR/{filename}/Aligned.sortedByCoord.out.bam"
    output:
        "outputs/STAR/{filename}/Aligned.sortedByCoord.out.bam.bai"
    shell:
        "samtools index {input}"
        
rule bam_sort_name:
    input:
        "outputs/STAR/{filename}/Aligned.sortedByCoord.out.bam"
    output:
        "outputs/STAR/{filename}/Aligned.sortedByCoord.out.sortedbyname.bam"
    shell:
        "samtools sort -n -o {output} {input}"

rule feature_counts:
    input:
        bam="outputs/STAR/{filename}/Aligned.sortedByCoord.out.sortedbyname.bam",
        gtf="data/chr19_20Mb.gtf"
    output:
        out1="outputs/STAR/{filename}/counts_1.txt",
        out2="outputs/STAR/{filename}/counts_2.txt"
    shell:
        "featureCounts -p -t exon -g gene_id -a {input.gtf} -o {output.out1} -s 1 {input.bam} && featureCounts -p -t exon -g gene_id -a {input.gtf} -o {output.out2} -s 2 {input.bam}"

rule feature_counts_per_sample:
    input:
        bam=expand("outputs/STAR/{name}/Aligned.sortedByCoord.out.sortedbyname.bam", name=config["method"][{type}]),
        gtf="data/chr19_20Mb.gtf"
    output:
        out1="outputs/STAR/{type}/counts_1.txt",
        out2="outputs/STAR/{type}/counts_2.txt"
    shell:
        "mkdir -p outputs/STAR/{type}/ && featureCounts -p -t exon -g gene_id -a {input.gtf} -o {output.out1} -s 1 {input.bam} && featureCounts -p -t exon -g gene_id -a {input.gtf} -o {output.out2} -s 2 {input.bam}"

总的来说有两个问题我无法解决:

一种解决方案是使用 python 的列表理解,例如:

desired_inputs = [
   f"outputs/STAR/{filename}/counts_2.txt"
   for method in config["method"].keys()
   for filename in config["method"][method]
]

rule all:
    input: desired_inputs

这一行是错误的:

    bam=[f"outputs/STAR/{name}/Aligned.sortedByCoord.out.sortedbyname.bam" for name in config["method"][{x}]],

Snakemake只有在规则评估的时候才会知道x的具体值,所以上面的命令会导致错误。要推迟评估,您需要使用 lambda wildcards 语法:

   bam=lambda wildcards: [f"outputs/STAR/{name}/Aligned.sortedByCoord.out.sortedbyname.bam" for name in config["method"][wildcards.x]],