【问题标题】:Snakemake: confusion on how to access config files properlySnakemake:关于如何正确访问配置文件的困惑
【发布时间】:2018-11-15 22:26:26
【问题描述】:

这个问题来自我之前问过的question,它涉及理解如何使用 Snakemake 正确访问配置文件。我有一个需要解决的具体问题,我会先问这个问题,然后我会问一个理解索引如何工作的一般问题。

我正在使用 snakemake 运行从对齐/QC 到基序分析的 ATAC-seq 管道。

答:具体问题

我正在尝试添加一个名为 trim_galore_pe 的规则,以在对齐之前从我的 fastq 文件中修剪适配器,并且由于 trim galore 生成的输出文件的名称与预期的不匹配,snakemake 会抛出错误语句由蛇制造。这是因为我无法弄清楚如何在我的蛇形文件中正确编写输出文件语句以使名称匹配。

TRIM GALORE 生成的名称示例包含 SRA 编号,例如:

trimmed_fastq_files/SRR2920475_1_val_1.fq.gz

而 snakemake 预期的文件包含 sample 引用,应为:

trimmed_fastq_files/Corces2016_4983.7B_Mono_1_val_1.fq.gz

这也会影响trim_galore_pe 规则之后的后续规则。我需要找到一种方法来使用我的配置文件中的信息来生成所需的输出文件。

对于 Snakefile 中显示的规则之后的所有规则,我需要用 示例名称 命名文件,即 Corces2016_4983.7A_Mono。在下面的 Snakefile 中显示的所有 FAST_QCMULTIQC 规则在输出文件名结构中具有 示例名称 也很有用,它们都已经在当前的 Snakefile 中这样做了。

但是,Bowtie2 的输入、FASTQC 规则以及trim_galore_pe 规则的输入和输出需要包含 SRA 编号。问题从trim_galore 的输出开始,并影响所有下游规则。

虽然我在之前的规则中提取了 SRA 编号,但我不确定在不使用配置文件中明确说明的 fastq_files 文件夹时如何执行此操作。通过引入trim_galore_pe 规则,我有效地将一组新的SRA 文件移动到新的trimmed_fastq_files 文件夹中。如何从包含旧文件夹名称的 SRA 文件配置文件列表中提取 SRA 编号,同时引用 Snakefile 中的新 trimmed_fastq_files 文件夹是我的问题的症结所在。

我希望这很清楚。

这是我的配置文件:

samples:
    Corces2016_4983.7A_Mono: fastq_files/SRR2920475
    Corces2016_4983.7B_Mono: fastq_files/SRR2920476
cell_types:
    Mono:
    - Corces2016_4983.7A
index: /home/genomes_and_index_files/hg19

这是我的蛇文件:

# read config info into this namespace
configfile: "config.yaml"
print (config['samples'])

rule all:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.zip", sample=config["samples"], num=['1', '2']),
        expand("bam_files/{sample}.bam", sample=config["samples"]),
        "FastQC/PRETRIM/fastq_multiqc.html",
        "FastQC/POSTTRIM/fastq_multiqc.html"

rule fastqc_pretrim:
    input:
        sample=lambda wildcards: f"{config['samples'][wildcards.sample]}_{wildcards.num}.fastq.gz"
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/PRETRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/PRETRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_pretrim:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/PRETRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule trim_galore_pe:
    input:
        sample=lambda wildcards: expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])
    output:
        "trimmed_fastq_files/{sample}_1_val_1.fq.gz",
        "trimmed_fastq_files/{sample}_1.fastq.gz_trimming_report.txt",
        "trimmed_fastq_files/{sample}_2_val_2.fq.gz",
        "trimmed_fastq_files/{sample}_2.fastq.gz_trimming_report.txt"
    params:
        extra="--illumina -q 20"
    log:
        "logs/trim_galore/{sample}.log"
    wrapper:
        "0.23.1/bio/trim_galore/pe"

rule fastqc_posttrim:
    input:
        "trimmed_fastq_files/{sample}_1_val_1.fq.gz", "trimmed_fastq_files/{sample}_2_val_2.fq.gz"
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/POSTTRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/POSTTRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_posttrim:
    input:
        expand("FastQC/POSTTRIM/{sample}_{num}.trim_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/POSTTRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule bowtie2:
    input:
        "trimmed_fastq_files/{sample}_1_val_1.fq.gz", "trimmed_fastq_files/{sample}_2_val_2.fq.gz"
    output:
        "bam_files/{sample}.bam"
    log:
        "logs/bowtie2/{sample}.txt"
    params:
       index=config["index"],  # prefix of reference genome index (built with bowtie2-build),
       extra=""
    threads: 8
    wrapper:
        "0.23.1/bio/bowtie2/align"

目前正在运行,并使用snakemake -np 提供完整的作业列表,但会引发上述错误。

B:一般问题

是否有在线资源简洁地解释了如何使用 python 引用配置文件,尤其是关于 snakemake 的引用?在线文档是相当不足的,并且假设有 python 的先验知识。

我的编程经验主要是 bash 和 R,但我喜欢 Snakemake,并且大致了解字典和列表在 python 中的工作方式以及如何引用存储在其中的项目。然而,我发现在上面的一些 Snakemake 规则中,括号、通配符和引号的复杂使用令人困惑,因此在尝试引用配置文件中文件名的不同部分时往往会遇到困难。我想充分了解如何利用这些元素。

例如,在上面发布的 Snakefile 中这样的规则中:

sample=lambda wildcards: expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2]) 

这个命令实际上发生了什么?我的理解是我们正在使用config['samples'] 访问配置文件,并且我们正在使用[wildcards.sample] 部分显式访问配置文件的fastq_files/SRR2920475 部分。扩展允许我们遍历配置文件中适合命令参数的每个项目,即所有 SRA 文件,并且需要 lambda 通配符才能在命令中使用 wildcards 调用。我不确定的是:

  1. f 在展开之后会做什么?为什么需要它?
  2. 为什么config['samples'] 在方括号内包含引号,但[wildcards.sample] 周围不需要引号?
  3. 为什么要使用单双大括号?
  4. 查看上面的 Snakefile,其中一些规则包含将一系列数字分配给 num 的部分,但这些数字有时会用引号括起来,有时不会……为什么?

任何建议、提示、指点将不胜感激。

C:澄清@bli 提出的以下建议

我已按照您在评论中的建议编辑了我的配置文件,并省略了文件夹名称,只留下了 SRA 编号。这对我来说很有意义,但我还有其他一些问题阻止我运行这个 Snakefile。

新配置文件:

samples:
    Corces2016_4983.7A_Mono: SRR2920475
    Corces2016_4983.7B_Mono: SRR2920476
cell_types:
    Mono:
    - Corces2016_4983.7A
index: /home/c1477909/genomes_and_index_files/hg19

新的蛇文件:

# read config info into this namespace
configfile: "config.yaml"
print (config['samples'])

rule all:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.zip", sample=config["samples"], num=['1', '2']),
        expand("bam_files/{sample}.bam", sample=config["samples"]),
        "FastQC/PRETRIM/fastq_multiqc.html",
        "FastQC/POSTTRIM/fastq_multiqc.html",

rule fastqc_pretrim:
    input:
      lambda wildcards: f"fastq_files/{config['samples'][wildcards.sample]}_{wildcards.num}.fastq.gz"
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/PRETRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/PRETRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_pretrim:
    input:
        expand("FastQC/PRETRIM/{sample}_{num}_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/PRETRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule trim_galore_pe:
    input:
        lambda wildcards: expand(f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])
    output:
        "trimmed_fastq_files/{wildcards.sample}_1_val_1.fq.gz",
        "trimmed_fastq_files/{wildcards.sample}_1.fastq.gz_trimming_report.txt",
        "trimmed_fastq_files/{wildcards.sample}_2_val_2.fq.gz",
        "trimmed_fastq_files/{wildcards.sample}_2.fastq.gz_trimming_report.txt"
    params:
        extra="--illumina -q 20"
    log:
        "logs/trim_galore/{sample}.log"
    wrapper:
        "0.23.1/bio/trim_galore/pe"

rule fastqc_posttrim:
    input:
        lambda wildcards: expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2])
    output:
        # Output needs to end in '_fastqc.html' for multiqc to work
        html="FastQC/POSTTRIM/{sample}_{num}_fastqc.html",
        zip="FastQC/POSTTRIM/{sample}_{num}_fastqc.zip"
    wrapper:
        "0.23.1/bio/fastqc"

rule multiqc_fastq_posttrim:
    input:
        expand("FastQC/POSTTRIM/{sample}_{num}.trim_fastqc.html", sample=config["samples"], num=['1', '2'])
    output:
        "FastQC/POSTTRIM/fastq_multiqc.html"
    wrapper:
        "0.23.1/bio/multiqc"

rule bowtie2:
    input:
        lambda wildcards: expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2])
    output:
        "bam_files/{sample}.bam"
    log:
        "logs/bowtie2/{sample}.txt"
    params:
        index=config["index"],  # prefix of reference genome index (built with bowtie2-build),
        extra=""
    threads: 8
    wrapper:
        "0.23.1/bio/bowtie2/align"

使用这些新文件最初一切正常,snakemake -np 创建了部分作业列表。但是,这是因为已经运行了一半的完整作业列表;也就是说,trimmed_fastq_files 文件夹已生成,并且正确命名的修剪过的 fastq 文件已在其中到位。当我删除所有之前创建的文件以查看整个新版本的 Snakefile 是否可以正常工作时,snakemake -np 失败,指出trim_galore_pe 规则下游的规则缺少输入文件。

如您所见,我试图在输出部分的trim_galore_pe 规则的输入部分调用{wildcard.sample} 变量集,但snakemake 不喜欢这样。可以这样做吗?

我也尝试过使用以下答案中的提示,但这也不起作用:

rule trim_galore_pe:
    input:
        sample=lambda wildcards: expand(f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])
    output:
        expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2]),
        expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz_trimming_report.txt", num=[1,2])
    params:
        extra="--illumina -q 20"
    log:
        "logs/trim_galore/{sample}.log"
    wrapper:
        "0.23.1/bio/trim_galore/pe"

错误然后指出wildcards not defined。因此,从逻辑上讲,我尝试将lambda wildcards: 放在输出部分的两个扩展语句前面以尝试定义通配符,但这引发了语法错误Only input files can be specified as functions。我还尝试使用下面的一些索引建议,但无法获得正确的组合。

这可能是由于我对 Snakefiles 不确定的另一件事引起的,这就是作用域的工作原理。

  • 如果我在rule all 中定义了一个变量,所有其他规则都可以访问它吗?
  • 如果我在规则的输入部分定义了一个变量,它是否可用于该规则的所有其他部分(即输出、shell 命令等),但仅适用于该规则?
  • 如果是,如果我在输入部分定义了{wildcard.sample} 变量,为什么不能访问它?那是因为该变量包含在“封闭”范围的 lambda 函数中吗?

任何(进一步的)建议将不胜感激。

【问题讨论】:

  • “如何从包含旧文件夹名称的 SRA 文件配置文件列表中仅提取 SRA 编号,同时引用 Snakefile 中的新 trimmed_fastq_files 文件夹是我的问题的症结所在。”也许您可以在配置中使用 SRA 编号,并在 snakemake 代码中构建文件列表,根据规则知道您应该在哪个目录中搜索?
  • 谢谢 Bli,我对此有过尝试,但遇到了障碍,请参阅相关的 C 部分。
  • output部分,你不用{wildcards.sample},你直接用{sample}。 Snakemake 已经假设您正在谈论通配符属性。实际上,规则范围内存在的通配符属性是通过解析output部分来确定的。如果这可能有用,我尝试写一些关于我目前对该主题的理解的解释:bitbucket.org/blaiseli/snakemake/src/…
  • 我在答案末尾添加了更多解释。希望这可以帮助。至少它帮助我提高了对蛇形的理解。
  • 非常感谢 Bli - 这些答案极大地帮助了我理解 Snakemake。

标签: indexing config wildcard curly-braces snakemake


【解决方案1】:

我将尝试回答您的问题 B,并提供更多详细信息,希望对您和其他人有用。

编辑:我在最后添加了一些回答问题 C 的尝试。

关于报价

首先,关于所谓的“倒置”逗号,它们通常被称为“单引号”,它们在 python 中用于构建字符串。双引号也可以用于相同的目的。主要区别在于您尝试创建包含引号的字符串时。使用双引号可以创建包含单引号的字符串,反之亦然。否则,您需要使用反斜杠(“\”)“转义”引号:

s1 = 'Contains "double quotes"'
s1_bis = "Contains \"double quotes\""
s2 = "Contains 'single quotes'"
s2_bis = 'Contains \'single quotes\''

(我倾向于使用双引号,这只是个人喜好。)

分解示例

rule trim_galore_pe:
    input:
        sample=lambda wildcards: expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])

您正在将一个函数 (lambda wildcards: ...) 分配给一个变量 (sample),该变量恰好属于规则的输入部分。

这将导致 snakemake 在根据通配符的当前值(从它想要生成的输出的当前值推断)确定规则的特定实例的输入时使用此函数。

为了清楚起见,很可能通过将函数定义与规则声明分开来重写它,而不使用lambda 构造,并且它的工作方式相同:

def determine_sample(wildcards):
    return expand(
        f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz",
        num=[1,2])

rule trim_galore_pe:
    input:
        sample = determine_sample

expand 是一个snakemake 特有的函数(但您可以将它导入任何python 程序或使用from snakemake.io import expand 的交互式解释器),这使得生成字符串列表变得更加容易。在下面的交互式 python3.6 会话中,我们将尝试使用不同的原生 python 构造重现使用它时发生的情况。

访问配置

# We'll try to see how `expand` works, we can import it from snakemake
from snakemake.io import expand
    ​
# We want to see how it works using the following example
# expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])

# To make the example work, we will first simulate the reading
# of a configuration file
import yaml

config_text = """
samples:
    Corces2016_4983.7A_Mono: fastq_files/SRR2920475
    Corces2016_4983.7B_Mono: fastq_files/SRR2920476
cell_types:
    Mono:
    - Corces2016_4983.7A
index: /home/genomes_and_index_files/hg19
"""
# Here we used triple quotes, to have a readable multi-line string.
​
# The following is equivalent to what snakemake does with the configuration file:
config = yaml.load(config_text)
config

输出:

{'cell_types': {'Mono': ['Corces2016_4983.7A']},
 'index': '/home/genomes_and_index_files/hg19',
 'samples': {'Corces2016_4983.7A_Mono': 'fastq_files/SRR2920475',
  'Corces2016_4983.7B_Mono': 'fastq_files/SRR2920476'}}

我们获得了一个字典,其中键“samples”与嵌套字典相关联。

# We can access the nested dictionary as follows
config["samples"]
# Note that single quotes could be used instead of double quotes
# Python interactive interpreter uses single quotes when it displays strings

输出:

{'Corces2016_4983.7A_Mono': 'fastq_files/SRR2920475',
 'Corces2016_4983.7B_Mono': 'fastq_files/SRR2920476'}
# We can access the value corresponding to one of the keys
# again using square brackets
config["samples"]["Corces2016_4983.7A_Mono"]

输出:

'fastq_files/SRR2920475'
# Now, we will simulate a `wildcards` object that has a `sample` attribute
# We'll use a namedtuple for that
# https://docs.python.org/3/library/collections.html#collections.namedtuple
from collections import namedtuple
Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(sample="Corces2016_4983.7A_Mono")
wildcards.sample

输出:

'Corces2016_4983.7A_Mono'

编辑(2018 年 11 月 15 日):我发现了一种创建通配符的更好方法:

from snakemake.io import Wildcards
wildcards = Wildcards(fromdict={"sample": "Corces2016_4983.7A_Mono"})

# We can use this attribute as a key in the nested dictionary
# instead of using directly the string
config["samples"][wildcards.sample]
# No quotes here: `wildcards.sample` is a string variable

输出:

'fastq_files/SRR2920475'

解构expand

# Now, the expand of the example works, and it results in a list with two strings
expand(f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])    
# Note: here, single quotes are used for the string "sample",
# in order not to close the opening double quote of the whole string

输出:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']
# Internally, I think what happens is something similar to the following:
filename_template = f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz"

# This template is then used for each element of this "list comprehension"    
[filename_template.format(num=num) for num in [1, 2]]

输出:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']
# This is equivalent to building the list using a for loop:
filenames = []
for num in [1, 2]:
    filename = filename_template.format(num=num)
    filenames.append(filename)
filenames

输出:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']

字符串模板和格式

# It is interesting to have a look at `filename_template`    
filename_template

输出:

'fastq_files/SRR2920475_{num}.fastq.gz'
# The part between curly braces can be substituted
# during a string formatting operation:
"fastq_files/SRR2920475_{num}.fastq.gz".format(num=1)

输出:

'fastq_files/SRR2920475_1.fastq.gz'

现在让我们进一步展示如何使用字符串格式。

# In python 3.6 and above, one can create formatted strings    
# in which the values of variables are interpreted inside the string    
# if the string is prefixed with `f`.
# That's what happens when we create `filename_template`:
filename_template = f"{config['samples'][wildcards.sample]}_{{num}}.fastq.gz"    
filename_template    

输出:

'fastq_files/SRR2920475_{num}.fastq.gz'

在格式化字符串的过程中发生了两次替换:

  1. config['samples'][wildcards.sample] 的值用于制作字符串的第一部分。 (sample 周围使用了单引号,因为这个 python 表达式位于用双引号构建的字符串中。)

  2. 作为格式化操作的一部分,num 周围的双括号已减少为单个括号。这就是为什么我们可以在涉及num的进一步格式化操作中再次使用它。

# Equivalently, without using 3.6 syntax:    
filename_template = "{filename_prefix}_{{num}}.fastq.gz".format(
    filename_prefix = config["samples"][wildcards.sample])
filename_template

输出:

'fastq_files/SRR2920475_{num}.fastq.gz'
# We could achieve the same by first extracting the value
# from the `config` dictionary    
filename_prefix = config["samples"][wildcards.sample]
filename_template = f"{filename_prefix}_{{num}}.fastq.gz"
filename_template

输出:

'fastq_files/SRR2920475_{num}.fastq.gz'
# Or, equivalently:
filename_prefix = config["samples"][wildcards.sample]
filename_template = "{filename_prefix}_{{num}}.fastq.gz".format(
    filename_prefix=filename_prefix)
filename_template

输出:

'fastq_files/SRR2920475_{num}.fastq.gz'
# We can actually perform string formatting on several variables
# at the same time:
filename_prefix = config["samples"][wildcards.sample]
num = 1
"{filename_prefix}_{num}.fastq.gz".format(
    filename_prefix=filename_prefix, num=num)

输出:

'fastq_files/SRR2920475_1.fastq.gz'
# Or, using 3.6 formatted strings
filename_prefix = config["samples"][wildcards.sample]
num = 1
f"{filename_prefix}_{num}.fastq.gz"

输出:

'fastq_files/SRR2920475_1.fastq.gz'
# We could therefore build the result of the expand in a single step:
[f"{config['samples'][wildcards.sample]}_{num}.fastq.gz" for num in [1, 2]]

输出:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']

关于问题 C 的评论

就 Python 将如何构建字符串而言,以下内容有点复杂:

input:
    lambda wildcards: expand(f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz", num=[1,2])

但它应该可以工作,正如我们在下面的模拟中看到的那样:

from collections import namedtuple
from snakemake.io import expand

Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(sample="Corces2016_4983.7A_Mono")
config = {"samples": {
    "Corces2016_4983.7A_Mono": "SRR2920475",
    "Corces2016_4983.7B_Mono": "SRR2920476"}}
expand(
    f"fastq_files/{config['samples'][wildcards.sample]}_{{num}}.fastq.gz",
    num=[1,2])

输出:

['fastq_files/SRR2920475_1.fastq.gz', 'fastq_files/SRR2920475_2.fastq.gz']

trim_galore_pe 规则中的问题实际上出在其output 部分:您不应该在那里使用{wildcards.sample},而应该只使用{sample}

规则的output 部分是通过将它想要获取的文件与给定的模式匹配来告知snakemake 对于给定规则实例的通配符属性是什么。与花括号匹配的部分将用于设置相应属性名称的值。

例如,如果 snakemake 想要一个名为 "trimmed_fastq_files/Corces2016_4983.7A_Mono_1_val_1.fq.gz" 的文件,它会尝试将其与所有规则输出部分中存在的所有模式进行匹配,并最终找到这个:"trimmed_fastq_files/{sample}_1_val_1.fq.gz"

幸运的是,通过在Corces2016_4983.7A_Mono{sample} 部分之间建立对应关系,它将能够将文件名与模式匹配。然后它将在本地通配符实例中放置一个sample 属性,有点像我手动执行以下操作:

Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(sample="Corces2016_4983.7A_Mono")

如果您使用{wildcards.sample} 而不是{wildcards},我不知道在snakemake 中究竟会发生什么,但让我们试试我的模拟框架:

Wildcards = namedtuple("Wildcards", ["sample"])
wildcards = Wildcards(wildcards.sample="Corces2016_4983.7A_Mono")
  File "<ipython-input-12-c02ce12bff85>", line 1
    wildcards = Wildcards(wildcards.sample="Corces2016_4983.7A_Mono")
                         ^
SyntaxError: keyword can't be an expression

你接下来的尝试怎么样?

output:
    expand(f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz", num=[1,2]),

在这里,我的理解是 Python 首先尝试在 f"trimmed_fastq_files/{config['samples'][wildcards.sample]}_{{num}}_val_{{num}}.fq.gz" 上应用 f 字符串格式。 为此,它需要能够评估config['samples'][wildcards.sample],但wildcards 对象还不存在。因此wildcards not defined。 只有在将“下游”规则所需的文件名与包含{attribute_name} 模式的字符串匹配后,才会生成wildcards。但这是snakemake目前正在尝试构建的字符串。

以下是一些需要记住的要点:

  • wildcards 实际上只存在于本地,在规则实例中,在将其输出与另一个“下游”规则实例所需的文件匹配之后。
  • 您没有在输入部分中定义变量。您使用变量来构建规则实例将需要的文件的具体名称(或者,更准确地说,您说您希望在规则实例可以运行之前存在:规则不需要实际使用这些文件)。这些变量是在规则范围之外定义的变量,直接在蛇文件的底层,在纯 Python 模式下,以及本地 wildcards 对象。默认情况下,{attribute_name} 占位符将被本地 wildcards 对象的属性替换("{sample}" 变为 "Corces2016_4983.7A_Mono"),但如果你想做更复杂的事情来构建文件名,你需要做这通过一个必须显式处理此 wildcards 对象的函数(lambda wildcards: f"{wildcards.sample}" 变为 "Corces2016_4983.7A_Mono")。

【讨论】:

    【解决方案2】:

    对于您问题的 A 部分,我建议使用制表符分隔的文件来存储样本信息、ID 等,无论您拥有多少样本。然后,您可以将此文件的路径存储在您的配置文件中,并通过使用带有 pandas 库的列标识符来访问它。详情请参阅this thread

    关于B部分:

    1. 看起来这是一种在 python 中格式化字符串的新方法,例如 this link

    2. config['samples'] 旨在访问配置文件的键“samples”,而[wildcards.sample] 旨在访问工作流中定义的通配符{sample}(在rule all 中)。

    3. 双括号通常用于转义单括号。在这里它避免了扩展 {{num}} (我不能把我的手放在snakemake文档中的例子上)。

    4. num=['1', '2'] 将值列表分配给通配符{num},因此稍后可以使用{wildcards.num} 访问它。如果所有规则的输入和输出都已链接,则不必多次定义这些值。

    希望这能澄清您的一些担忧,祝您好运!

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      相关资源
      最近更新 更多