如何在输入输出中正确使用通配符

Posted

技术标签:

【中文标题】如何在输入输出中正确使用通配符【英文标题】:How to properly use wildcards in input and output 【发布时间】:2019-08-27 13:38:11 【问题描述】:

我最近决定从 snakemake 开始。我在堆栈和snakemake doc 上都找不到任何适合我需要的东西。我觉得我有些不明白,我可能需要一些解释。

我正在尝试制作一个简单的 snakemake 工作流程,该工作流程将一个 fastq 文件和一个测序摘要文件(包含有关读取的信息)作为输入,并将快速中的读取过滤成几个文件(low.fastq 和 high .fastq)。

我的输入数据和我尝试执行的 Snakefile 是这样存储的:

.
├── data
│   ├── sequencing-summary-example.txt 
│   └── tiny-example.fastq 
├── Snakefile
└── split_fastq

这是我迄今为止尝试过的:

*imports*
rule targets:
    input:
        "split_fastq/low.fastq",
        "split_fastq/high.fastq"

rule split_fastq:
    input:
        "data/reads.fastq",
        "data/seqsum.txt"
    output:
        "split_fastq/low.fastq",
        "split_fastq/high.fastq"
    run:
        * do the thing *

我希望有一个目录“split_fastq”,其中包含“低”和“高”fastq。但是我得到了错误:

Building DAG of jobs...
WildcardError in line 10 of /work/sbsuser/test/roxane/alignement-ont/Snakefile:
Wildcards in input files cannot be determined from output files:
'reads'

尽管这似乎是一个非常流行的错误,但我不确定我是否不了解如何使用通配符或是否存在其他问题。我是否正确使用了“输入”和“输出”?

【问题讨论】:

我最近回答了一个非常相似的问题:***.com/questions/57327210/… 是的,我一直在阅读这个帖子,但我对您必须在工作流程中写下您的文件名这一事实感到困惑。我想将此工作流程用于任何 fastq,我不想编写路径或文件名,我想要一些动态的东西,例如有点像 -f myFastq 选项。但也许snakenamke 不是为了那个,而是更“面向特定数据集”?也许这就是我理解不正确? 有(至少)两个选项。首先是输出与输入具有相同的通配符。然后你可以运行类似snakemake split_fastq/low-example.fastq 的东西。另一种是你在链接中使用globbing的方式,然后会找到相关的样本,并决定需要生成哪些输出。 好吧,所以在我的例子中替换,我会写在输出部分 split_fastq/reads-low.fastq","split_fastq/readshigh.fastq" 对吗? 有点,summary.txt 还需要一个通配符,每个输出都需要两个通配符(读取和 seqsum)。再次查看通配符如何工作的文档。很遗憾,我没有时间输入答案。 【参考方案1】:

问题是您在输入中有通配符,但在输出中没有。输出中需要通配符。这样想,通过将通配符放在输入中,您正在创建一个您打算在许多不同的 fastq 文件上单独运行的规则。但是对于每个不同的 fastq 文件,该规则的输出文件将是完全相同的文件。他们会互相覆盖!您希望将通配符合并到您的输出文件中,以便为每个可能的输入获得一个唯一的文件,例如:

rule split_fastq:
    input:
        "data/reads.fastq",
        "data/seqsum.txt"
    output:
        "split_fastq/reads.low.fastq",
        "split_fastq/reads.high.fastq"
    run:
        * do the thing *

现在将tiny-example.fastq 作为输入,您将得到tiny-example.low.fastqtiny-example.high.fastq 作为输出。如果您添加第二个 fastq 文件,您将获得该文件的不同高低输出文件。但是这条规则仍然不起作用,因为“seqsum”通配符也不是输出的一部分。在这种情况下,您可能想要做的是让 sequence-summary-example.txt 包含 fastq 文件的名称,例如将其命名为 sequence-summary-tiny-example.txt。现在您可以像这样制定规则:

rule split_fastq:
    input:
        "data/reads.fastq",
        "data/sequence-summary-reads.txt"
    output:
        "split_fastq/reads.low.fastq",
        "split_fastq/reads.high.fastq"
    run:
        * do the thing *

现在,如果您添加other-example.fastqsequence-summary-other-example.txt,您的snakemake 管道应该能够创建other-example.low.fastqother-example.high.fastq

Snakemake 的思维方式总是与我们的思维方式相反。我们首先考虑输入,然后考虑它产生的输出。但是 Snakemake 知道它需要制作什么文件,并且它试图弄清楚它需要什么输入来制作它。所以在你的原始规则中,它知道它需要生成low.fastq,并且它看到split_fastq 规则可以做到这一点,但是它不知道输入中的通配符“读取”应该是什么。现在,在新规则中,它知道它需要制作tiny-example.low.fastq,并看到split_fastq 可以创建模板reads.low.fastq 的输出文件,所以它说“嘿,如果我制作reads = tiny-example,那么我可以使用这个规矩!”然后它查看输入并说“好的,因为输入我需要reads.fastq,我知道reads = tiny-example,那么这意味着输入我需要tiny-example.fastq,我有这个!”

【讨论】:

感谢您非常详细的回答,帮助我理解。我仍然不明白一切,因为我觉得在某些时候我必须给他一些写在石头上的文件名。我按照您的建议修改了我的脚本:但它仍然给我这个错误:“目标规则可能不包含通配符。请指定具体文件或不带通配符的规则。”有没有构建我的脚本的好方法?或者我应该调用snakemake一个输出文件,我希望他在调用他时创建而不是仅仅使用“snakemake”? 当你运行snakemake时,它会尝试运行第一条规则。您在原始帖子中的内容是正确的,您在其中定义了一个名为“目标”的规则或类似的规则,仅输入文件是您的“一成不变”文件名。你也可以在执行命令的时候给snakemake特定的文件,比如“snakemake split_fastq/tiny-example.low.fastq”。

以上是关于如何在输入输出中正确使用通配符的主要内容,如果未能解决你的问题,请参考以下文章

华为OJ平台——字符串通配符

mySqli 使用通配符绑定参数 LIKE

多命令顺序执行,dd命令,管道|,grep,通配符

通配符及输入输出重定向

五周第三次课(1月10日) 8.1 shell介绍 8.2 命令历史 8.3 命令补全和别名 8.4 通配符 8.5 输入输出重定向

如何使用带有通配符查询的 Hibernate Search 并输出结果对象列表