snakemake 配置参数值可以是带有 {} 值的字符串吗<name>?



有没有办法在 .yaml 文件中定义一个 snakemake 配置字符串,以便它可以包含 {通配符} 和 {param} 值,当该字符串在 shell 命令中使用时,{} 值被替换为">"的实际值?

例如,假设您希望配置字符串定义要作为参数传递给程序的字符串的格式:

RG: "ID:{ID} REP:{REP}">

其中上述内容在 .yaml 文件中,ID 和 REP 是通配符,shell 命令会将扩展的字符串作为参数传递给程序。

让我试着对这个问题提供一个简短的答案:

在 Snakemake 中,您可以为参数提供函数,这些参数将通配符作为参数。在这些函数中,您可以执行任何 python 代码,包括格式化配置值的格式语句,例如

configfile: "config.yaml"
rule:
output:
"plots/myplot.{mywildcard}.pdf"
params:
myparam=lambda wildcards: config["mykey"].format(**wildcards)
shell:
...

如您所见,您可以使用 python 解包运算符和str.format方法来替换配置文件中的值。这假设config["mykey"]生成一个包含与上述相同通配符的字符串,例如"foo{mywildcard}bar".

是的,使用 params lambda 函数:

MACBOOK> cat paramsArgs.yaml
A: "Hello world"
B: "Message: {config[A]}  ID: {wildcards.ID}   REP: {wildcards.REP}"
MACBOOK> cat paramsArgs
configfile: "paramsArgs.yaml"
rule all:
input: "ID2307_REP12.txt"
def paramFunc(key, wildcards, config):
return config[key].format(wildcards=wildcards, config=config)
rule:
output: "ID{ID}_REP{REP}.txt"
params: A=config["A"], B=lambda wildcards: paramFunc("B", wildcards, config)
shell:
"""
echo 'A is {params.A}' > {output}
echo 'B is {params.B}' >> {output}
"""
MACBOOK> snakemake -s paramsArgs
Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
count   jobs
1   2
1   all
2
rule 2:
output: ID2307_REP12.txt
jobid: 1
wildcards: REP=12, ID=2307
Finished job 1.
1 of 2 steps (50%) done
localrule all:
input: ID2307_REP12.txt
jobid: 0
Finished job 0.
2 of 2 steps (100%) done
MACBOOK> cat ID2307_REP12.txt 
A is Hello world
B is Message: Hello world  ID: 2307   REP: 12

这是一个参数函数,可让您在配置字符串中扩展来自几个不同 snakemake 源的值:

def paramFunc(wildcards, input, output, threads, resources, config,
global_cfg, this_cfg, S):
return S.format(wildcards=wildcards, input=input, output=output,
threads=threads, resources=resources, config=config,
global_cfg=global_cfg, this_cfg=this_cfg)

下面是一个如何从 Snakemake params: 部分中调用 paramFunc(( 的示例,以扩展配置参数 config["XYZ"] 的值并将其分配给名为 "text" 的参数,然后在 shell 命令中展开该 "text" 参数:

params:
text=lambda wildcards, input, output, threads, resources:
paramFunc(wildcards, input, output, threads, resources, config,
global_cfg, my_local_cfg, config["XYZ"])
shell: "echo 'text is {params.text}'"

请注意,paramFunc(( 的最后一个参数是您想要的参数值 要扩展,在这种情况下,配置 ["XYZ"]。 其他参数都是包含该参数值可能引用的值的字典。

您可能已经定义了这样的 config["XYZ"],例如,在 .yaml 文件中:

ABC: "Hello world"
XYZ: "ABC is {config[ABC]}"

但是,字符串 XYZ 不限于扩展同一文件中定义的值(此处扩展了 ABC(,但您可以使用其他"{}"构造来访问在其他位置定义的其他值:

Defined in                               Use this construct in param
----------                               ---------------------------
"config" dictionary                      "{config[<name>]}"
wildcards used in the output filename    "{wildcards[<name>]}"
input filename(s)                        "{input}" or "{input[NAME]}" or "{input[#]}"
output filename(s)                       "{output}" or "{output[NAME]}" or "{output[#]}"
threads                                  "{threads}"
resources                                "{resources[<name>]}"
"global_cfg" global config dictionary    "{global_cfg[<name>]}"
"my_local_cfg" module config dictionary  "{this_cfg[<name>]}"

值"global_cfg"和"my_local_cfg"是两个特殊的字典,可以添加它们来帮助模块化蛇文件。

对于"global_cfg",这个想法是你可能想要一个 snakefile-global 定义的字典。 在您的主蛇文件中,执行以下操作:

include: "global_cfg.py"

在文件global_cfg.py中,放置全局定义:

global_cfg = {
"DATA_DIR" : "ProjData",
"PROJ_DESC" : "Mint Sequencing"
}

然后,您可以在参数字符串中引用这些值,例如:

"{global_cfg[DATADIR]}"

(字符串必须通过调用 paramFunc((在 params: 部分中扩展(

对于"my_local_cfg",这个想法是您可能希望将每个 snakefile 规则放在一个单独的文件中,并将该规则的参数也定义在一个单独的文件中,因此每个规则都有一个规则文件和一个参数文件。 在主蛇文件中:

(include paramFunc() definition above)
include: "myrule.snake"
rule all:
input: "myrule.txt"

在myrule.snake中:

include: "myrule.py"

myrule.py 放置 myrule 模块的配置设置:

myrule_cfg = {
"SPD" : 125,
"DIST" : 98,
"MSG" : "Param settings: Speed={this_cfg[SPD]}  Dist={this_cfg[DIST]}"
}

回到myrule.snake:

include: "myrule.py"
rule myrule:
params:
SPD=myrule_cfg["SPD"],
DIST=myrule_cfg["DIST"],
# For MSG call paramFunc() to expand {name} constructs.
MSG=lambda wildcards, input, output, threads, resources:
paramFunc(wildcards, input, output, threads, resources, config,
global_cfg, myrule_cfg, myrule_cfg["MSG"])
message: "{params.MSG}"
output: "myrule.txt"
shell: "echo '-speed {params.SPD} -dist {params.DIST}' >{output}"

请注意,paramFunc(( 函数将名称 "myrule_cfg"(因规则而异(映射到固定名称 "this_cfg"(无论规则如何都相同(。

请注意,我包含.py定义global_cfg和this_cfg字典的文件。 这些可以在 .yaml 文件中定义,但问题是它们最终都在一个字典"config"中结束。 如果配置文件命令允许指定字典,那就太好了,例如:

configfile: global_cfg="global_cfg.yaml"

也许有一天,该功能会被添加到snakemake中。

我意识到 Johannes Köster 的答案中 **config 和 **globals(( 到 format(( 的附加参数可用于允许扩展在 snakefile 的 python 代码中定义的变量,例如以下示例中的变量"ABC",并允许扩展配置参数而不在扩展中使用"config"。 假设 config.yaml 包含:

X: "Hello"
MSG: "config X: {X}   variable ABC: {ABC}   wildcard WW: {WW}"

你有这个蛇锉:

configfile: "config.yaml"
rule all:
input: "test.Goodbye.txt"
rule A:
output: "test.{WW}.txt"
params: MSG=lambda wildcards: config["MSG"].format(wildcards=wildcards, **config, **globals())
message: "{params.MSG}"
shell: "echo '{params.MSG}' >{output}"

ABC = "This is the ABC variable"

消息和文件输出将是以下行:

config X: Hello   variable ABC: This is the ABC variable   wildcard WW: Goodbye

相关内容

  • 没有找到相关文章

最新更新