在规则

时间:2017-08-03 20:34:04

标签: python output config snakemake

是否有某个地方完全描述了在snakemake规则中使用配置数据?

在yaml文件的用户指南中有一个示例:

samples:
    A: data/samples/A.fastq
    B: data/samples/B.fastq

然后,它被用在这样的规则中:

bam=expand("sorted_reads/{sample}.bam", sample=config["samples"]),

似乎上面的内容会将{sample}替换为“data / samples / A.fastq”而不是“A”(和“B”等),就像它显然那样。

在输出规则中使用配置数据的正确方法是什么,例如帮助形成输出文件名?此表单不起作用:

output: "{config.dataFolder}/{ID}/{ID}.yyy"

如果我在yaml文件中定义复杂的结构化数据,我正在寻找语法指导 - 如何在snake规则中使用它?我什么时候使用Python语法?什么时候使用SnakeMake语法?

yaml和JSON配置文件受到严格限制,因为它们无法使用文件中先前定义的值来定义新值,对吧?这是设置配置参数时经常要做的事情。

使用配置文件有什么好处?为什么不使用include:包含一个python文件来定义参数?

一个有用的东西是参考手册,它详细描述了SnakeMake的细节。当前的网站有点分散,需要一段时间才能找到你以前在其中某处找到的东西。

3 个答案:

答案 0 :(得分:1)

如何在“输出”规则中使用配置数据?我发现输出字符串不能包含{config。}值。但是,可以使用Python代码包含它们,如下所示:

output: config["OutputDir"] + "/myfile.txt"

但是,这种方法不起作用(在输出中:或输入:):

params: config=config
output: "{params.config[OutputDir]}/myfile.txt"

但是,它在“shell:”中工作:

params: config=config
output: config["OutputDir"] + "/myfile.txt"
shell: echo "OutputDir is {params.config[OutputDir]}" > {output}

请注意,shell cmd中[]内的OutputDir周围没有引号。扩展字符串中值的{}方法不使用键周围的引号。

配置数据是可以定义蛇文件还是python-wise?是!

参数可以在使用'configfile'包含的.yaml文件中定义,也可以通过使用'include'包含的常规Python文件定义。后者是恕我直言,因为.yaml文件不允许定义引用以前的定义,除了最简单的配置文件之外,它们都是常见的。

使用yaml:

定义上面的“OutputDir”参数

xxx.yaml:

OutputDir: DATA_DIR

snakefile:

configfile: 'xxx.yaml'

使用Python定义它与上面完全兼容:

xxx.py:

config['OutputDir'] = "DATA_DIR"

snakefile:

include: 'xxx.py'

或者,在Python包含的配置文件中定义一个简单的变量'OutputDir',然后在规则中使用它:

xxx.py:

OutputDir = "DATA_DIR"

snakefile:

include: 'xxx.py'
rule:
    output: OutputDir + "/myfile.txt"

可以通过.yaml文件和python文件轻松定义和访问多嵌套字典和列表。例如:

MACBOOK> cat cfgtest.yaml
cfgtestYAML:

    A: 10
    B: [1, 2, 99]
    C:
        nst1: "hello"
        nst2: ["big", "world"]

MACBOOK> cat cfgtest.py
cfgtestPY = {

    'X': -2,
    'Y': range(4,7),
    'Z': {
        'nest1': "bye",
        'nest2': ["A", "list"]
        }
    }

MACBOOK> cat cfgtest
configfile: "cfgtest.yaml"
include: "cfgtest.py"

rule:
    output: 'cfgtest.txt'
    params: YAML=config["cfgtestYAML"], PY=cfgtestPY
    shell:
        """
        echo "params.YAML[A]: {params.YAML[A]}"             >{output}
        echo "params.YAML[B]: {params.YAML[B]}"             >>{output}
        echo "params.YAML[B][2]: {params.YAML[B][2]}"       >>{output}
        echo "params.YAML[C]: {params.YAML[C]}"             >>{output}
        echo "params.YAML[C][nst1]: {params.YAML[C][nst1]}" >>{output}
        echo "params.YAML[C][nst2]: {params.YAML[C][nst2]}" >>{output}
        echo "params.YAML[C][nst2][1]: {params.YAML[C][nst2][1]}" >>{output}

        echo "" >>{output}

        echo "params.PY[X]: {params.PY[X]}"                 >>{output}
        echo "params.PY[Y]: {params.PY[Y]}"                 >>{output}
        echo "params.PY[Y][2]: {params.PY[Y][2]}"           >>{output}
        echo "params.PY[Z]: {params.PY[Z]}"                 >>{output}
        echo "params.PY[Z][nest1]: {params.PY[Z][nest1]}"     >>{output}
        echo "params.PY[Z][nest2]: {params.PY[Z][nest2]}"     >>{output}
        echo "params.PY[Z][nest2][1]: {params.PY[Z][nest2][1]}" >>{output}
        """

MACBOOK> snakemake -s cfgtest
Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
    count   jobs
    1   1
    1

rule 1:
    output: cfgtest.txt
    jobid: 0

Finished job 0.
1 of 1 steps (100%) done

MACBOOK> cat cfgtest.txt
params.YAML[A]: 10
params.YAML[B]: 1 2 99
params.YAML[B][2]: 99
params.YAML[C]: {'nst1': 'hello', 'nst2': ['big', 'world']}
params.YAML[C][nst1]: hello
params.YAML[C][nst2]: big world
params.YAML[C][nst2][1]: world

params.PY[X]: -2
params.PY[Y]: range(4, 7)
params.PY[Y][2]: 6
params.PY[Z]: {'nest1': 'bye', 'nest2': ['A', 'list']}
params.PY[Z][nest1]: bye
params.PY[Z][nest2]: A list
params.PY[Z][nest2][1]: list

答案 1 :(得分:0)

YAML配置

这与YAML文件的嵌套有关,请参阅示例here

配置[" samples"]请求将同时返回' A'和' B'。我是我的脑袋,我想它会返回一个列表,但我对变量类型并不乐观。

使用此处列出的配置文件: https://snakemake.readthedocs.io/en/latest/tutorial/advanced.html

您可以使用YAML格式链接以下YAML配置文件。

设置/ config.yaml:

samples:
    A
    B

OR

设置/ config.yaml:

sampleID:
    123
    124
    125
baseDIR:
    data

使用YAML配置访问产生的呼叫

Snakefile:

configfile: "settings/config.yaml"

rule all:
    input:
        expand("{baseDIR}/{ID}.bam", baseDIR=config["baseDIR"], ID=config["sampleID"]),


rule fastq2bam:
    input:
        expand("{{baseDIR}}/{{ID}}.{readDirection}.fastq", readDirection=['1','2'])
    output:
        "{baseDIR}/{ID}.bam"
        #Note different number of {}, 1 for wildcards not in expand.
        #Equivalent line with 'useless' expand call would be:
        #expand("{{baseDIR}}/{{ID}}.bam")

    shell:
    """
    bwa mem {input[0]} {input[1]} > {output}
    """

虚拟示例,只是试图举例说明不同字符串和配置变量的使用。我在fastq2bam规则中使用通配符。通常我只使用配置变量在我的规则中设置所有内容,如果可能,这是最佳做法。我不能说shell调用是否真的适用于bwa mem,但我认为你能理解我所暗示的内容。

可以看到更大版本的Snakefile here

设置配置文件后,要引用其中的任何内容,请使用' config'。它可以根据需要用于深入访问YAML。在这里,我将下调3个假设的水平,如下:

hypothetical_var = config["yamlVarLvl1"]["yamlVarLvl2"]["yamlVarLvl3"]

等同于(我对于打字没有积极性,我认为它会转换为字符串)

 hypothetical_var = ['124', '125', '126', '127', '128', '129']

如果YAML是:

yamlVarLvl1:
    yamlVarLvl2:
        yamlVarLvl3:
            '124'
            '125'
            '126'
            '127'
            '128'
            '129'

代码组织

Python和Snakemake代码,大部分都可以在certian位置交错。我建议不要这样做,因为它会使代码难以维护。由用户决定如何实现这一点。例如,使用run或shell指令更改如何访问变量。

YAML和JSON文件是首选的配置变量文件,因为我相信它为编辑和命令行界面过度变量提供了一些支持。如果使用外部导入的python变量实现它,那么它就不会那么干净。它也有助于我的大脑,知道python文件做事情,YAML文件存储东西。

YAML始终是外部文件,但是......

  1. 如果您使用的是单个Snakefile,请将支持python放在顶部?
  2. 如果您使用的是多文件系统,请考虑将支持的python脚本外部化。
  3. 教程

    我认为一个完美的小插图很难设计。我试图教我的小组关于Snakemake,我有超过40页的个人书面文档,我提供了三个1小时+演示文稿和PowerPoint幻灯片,我几乎阅读了整本ReadTheDocs.io手册对于Snakemake,我刚刚完成了额外的resources列表,但是,我还在学习!

    旁注,我发现这个tutorial也非常好。

    这是否提供了足够的背景?

答案 2 :(得分:0)

  

是否有某个地方完全描述了在snakemake规则中使用配置数据?

如果可以将其解析为python对象,则可以在配置文件中添加的内容没有限制。基本上,“你的想象力是极限”。

  

在输出规则中使用配置数据的正确方法是什么,例如帮助形成输出文件名?

我从规则之外的配置中提取东西,用普通的python。

而不是output: "{config.dataFolder}/{ID}/{ID}.yyy",我会这样做:

data_folder = config.dataFolder

rule name_of_the_rule:
    output:unction
        os.path.join(data_folder, "{ID}", "{ID}.yyy")

我想你用你所尝试的东西,当来自通配符和其他东西的混合物时,snakemake在格式化字符串方面存在问题。但是,使用formatted string litteralsoutput: f"{config.dataFolder}/{ID}/{ID}.yyy"可能以下在python 3.6中有效。我没有检查过。

  

如果我在yaml文件中定义复杂的结构化数据,我正在寻找语法指导 - 如何在snake规则中使用它?我什么时候使用Python语法?什么时候使用SnakeMake语法?

在snakefile中,我通常会读取配置文件,以便在规则之前提取配置信息。这基本上是纯Python,除了Snakemake直接提供config对象以方便使用。您可以使用config = json.load("config.json")config = yaml.load("config.yaml")来使用普通标准python。

在snakefile中,在规则之外,你可以在python中做任何你想要的计算。这可以在读取配置之前以及之后。您可以定义可在规则中使用的函数(例如,生成规则的输入),计算将用作通配符的事物列表。我认为唯一的问题是需要在使用它的规则之前定义一个对象。

Snakemake语法似乎主要是描述规则的一种方法。在规则的run部分内,您可以使用任何您想要的python,因为您知道可以访问wildcards对象来帮助您。规则的输入和输出是文件路径列表,您可以使用python来构建它们。