我正在尝试不同的方法来重命名文件,我很困惑为什么其中一些方法不起作用。假设我想使用字典
in
将文件 out
复制到文件 {"out": "in"}
。
代码不起作用#1:
rename = {"out": "in"}
def mapFile(wildcards):
print ('wc:',wildcards.rr)
file = rename[wildcards.rr]
return (file)
rule all:
input:
expand("{rr}", rr = list(rename.keys()))
rule rename:
input:
mapFile
output:
"{rr}"
shell:
"cp {input} {output}"
错误信息:
Building DAG of jobs...
wc: out
wc: in
InputFunctionException in rule rename in file /Users/geo/Desktop/tmp/q.snakefile, line 12:
Error:
KeyError: 'in'
Wildcards:
rr=in
Traceback:
File "/Users/geo/Desktop/tmp/q.snakefile", line 5, in mapFile (rule rename, line 19, /Users/geo/Desktop/tmp/q.snakefile)
令我困惑的是,传递给的
rr
通配符包含 in
和 out
,但我正在扩展的字典键只是 out
...
代码不起作用#2:
rename = {"out": "in"}
rule all:
input:
expand("{rr}", rr = list(rename.keys()))
rule rename:
input:
lambda wildcards: rename[wildcards.rr]
output:
"{rr}"
shell:
"cp {input} {output}"
错误信息:
Building DAG of jobs...
InputFunctionException in rule rename in file /Users/geo/Desktop/tmp/q.snakefile, line 12:
Error:
KeyError: 'in'
Wildcards:
rr=in
Traceback:
File "/Users/geo/Desktop/tmp/q.snakefile", line 15, in <lambda> (rule rename, line 19, /Users/geo/Desktop/tmp/q.snakefile)
代码工作#3:
rename = {"out": "in"}
rule all:
input:
expand("{rr}", rr = list(rename.keys()))
rule rename:
input:
lambda wildcards: rename.get(f"{wildcards.rr}", "")
output:
"{rr}"
shell:
"cp {input} {output}"
我不明白发生了什么事。所有三个解决方案应该是相同的,但只有#3 有效。你能帮忙吗?
问题是您的规则重命名也会生成文件
in
。由于该文件不存在,snakemake 尝试创建它,并在选项 1 和 2 的输入函数中遇到关键错误。您可以使用 --debug-dag
选项更清楚地看到这一点,如果您 touch in
一切都应该可以工作。第三个选项“有效”,因为当请求的文件不在您的字典中时,您不会返回任何内容。据推测,如果您运行该工作流程,它将无法执行,因为 shell 将是 cp in
。
更一般地,您希望您的文件具有唯一的前缀或后缀。如果您将文件放入子目录中:
def mapFile(wildcards):
print ('wc:',wildcards.rr)
file = 'inputs/' + rename[wildcards.rr]
return file
rule rename:
input:
mapFile
output:
"outputs/{rr}"
shell:
"cp {input} {output}"
一切都应该有效。这也是组织输出的好习惯,当您有多个规则时,它可以防止规则不明确。