无法让这个正则表达式适用于snakemake中的wildcard_constraints

时间:2017-10-20 20:14:58

标签: python regex snakemake

我有一个用Snakemake编写的工作流程来分析生物测序数据。工作流程要求组织所有数据文件,以便每个原始读取文件都以测定类型(RNASeq,DNaseSeq等)开头,并且在工作流生成的所有文件中保持此文件名约定。

我有一个规则来对齐除了RNASeq之外的每个测定的数据的读数,以及应该仅应用于RNASeq数据的不同规则。我一直无法设置这些规则,以便snakemake知道哪些文件用于哪些文件。

在RNASeq规则中,我有这个:

wildcard_constraints: library='RNASeq_.+'

这有助于确保RNASeq库使用该规则。不过,我仍然会对其他分析的模糊规则出错,因此我认为我需要在其他规则中限制通配符。我试过这个:

wildcard_constraints: library='(!?RNASeq)_.+'

说匹配任何没有RNASeq的东西,但是如果我在python解释器中尝试它,那么snakemake似乎无法匹配这个正则表达式的任何东西。我已经尝试过其他方式,比如'[^ R] [^ N] [^ A]',但无法正常工作。

由于这些正则表达式在我手动对齐字符串时起作用,我认为有一个关于snakemake如何应用正则表达式的错误,或者我不明白它们是如何被snakemake使用的。我假设它只是“如果此正则表达式匹配通配符字符串,请使用此规则。如果没有,请不要使用此规则。”

2 个答案:

答案 0 :(得分:1)

如果您不希望您的线路以RNASeq或DNaseSeq开头,您可以

r'^(?!RNASeq)(?!DNaseSeq).+'

答案 1 :(得分:0)

我相信以下内容展示了您正在努力实现的目标:

# Snakefile

rule sam_startswith_dna:
    output: '{pattern}.sam'
    wildcard_constraints: pattern='dna.+'
    shell: 'touch {output}'

rule sam_not_startswith_dna:
    output: '{pattern}.sam'
    wildcard_constraints: pattern='(?!dna).+'  # negative lookahead assertion
    shell: 'touch {output}'

rule bam_endswith_rna:
    output: '{pattern}.bam'
    wildcard_constraints: pattern='.+rna'
    shell: 'touch {output}'

rule bam_not_endswith_rna:
    output: '{pattern}.bam'
    wildcard_constraints: pattern='.+(?<!rna)'  # negative lookbehind assertion
    shell: 'touch {output}'

使用它(snakemake 4.6.0,python 3.6):

$ snakemake -n dna_sample.sam   # runs rule: sam_startswith_sam

$ snakemake -n sample.sam       # runs rule: sam_not_startswith_sam
$ snakemake -n sample_dna.sam   # runs rule: sam_not_startswith_sam

$ snakeamke -n sample_rna.bam   # runs rule: bam_endswith_rna

$ snakemake -n sample.bam       # runs rule: bam_not_endswith_rna
$ snakemake -n rna_sample.bam   # runs rule: bam_not_endswith_rna

这是我认为你在做的事情:

# Snakefile2

rule sam_startswith_dna_:
    output: '{pattern}.sam'
    wildcard_constraints: pattern='dna_.+'
    shell: 'touch {output}'

rule sam_not_startswith_dna_:
    output: '{pattern}.sam'
    wildcard_constraints: pattern='(?!dna)_.+'
    shell: 'touch {output}'

使用它:

$ snakemake -s Snakefile2 dna_data.sam  # runs rule: sam_startswith_dna_

$ snakemake -s Snakefile2 rna_data.sam  # raises MissingRuleException :( :( :(

以下是解决问题的方法:

# Snakefile3

rule sam_startswith_dna_:
    output: '{pattern}.sam'
    wildcard_constraints: pattern='dna_.+'
    shell: 'touch {output}'

rule sam_not_startswith_dna_:
    output: '{pattern}.sam'
    wildcard_constraints: pattern='(?!dna)[^_]{3}_.+'
    shell: 'touch {output}'

使用它:

$ snakemake -s Snakefile3 -n dna_data.sam  # runs rule: sam_startswith_dna_

$ snakemake -s Snakefile3 -n rna_data.sam  # runs rule: sam_not_startswith_dna_

由于硬编码{3}

,它不是很通用
$ snakemake -s Snakefile3 -n gdna_data.sam  # raises MissingRuleException

以下是基于我对snakemake.io.regex的简要介绍和一些探讨;可能包含错误

一般来说,给出这样的规则:

rule some_rule:
    output: 'some.{pattern}.txt'
    wildcard_constraints: pattern='[a-z_]+'
    shell: 'touch {output}'

和这样的命令行调用:

$ snakemake some.tar_get.txt

如果

,将执行规则some_rule
re.search('some\.(?P<pattern>[a-z_]+)\.txt$', 'some.tar_get.txt')

返回一个匹配(假设其他检查通过(例如歧义,循环dag等))。

有趣的是,$会附加到模式中,但^不会被添加到前面。

这种行为与我最初的想法不同,后者就是这样(这样可以在^中使用$wildcard_constraints

# python3, pseudo-code-ish

output = 'some.{pattern}.txt'
pattern = '[a-z_]+'

target = 'some.tar_get.txt'

# First test: does the target file name match the output (without the constraint)?
m = re.search('some\.(?P<pattern>.+)\.txt', target)
if not m:
    raise MissingInputException

# Second test: does the wildcard satisfy user-supplied constraint?
m = re.search(pattern, m.group('pattern'))
if not m:
    raise MissingInputException

run_rule()