snakemake - 不要删除失败规则的输出
snakemake - do not delete output of failed rules
我有一个 snakemake 工作流程,其中包含运行另一个“内部”snakemake 工作流程的规则。
有时内部工作流的某个规则失败,这意味着内部工作流失败。因此,内部工作流 output
下列出的所有文件都被外部工作流删除,即使创建它们的内部工作流规则已成功完成。
有没有办法防止 snakemake 删除失败规则的输出?或者您可以建议另一种解决方法?
一些注意事项:
- 必须列出内部工作流的输出,b/c它们用作外部工作流中其他规则的输入。
- 我尝试将内部工作流程的输出设置为
protected
,但这没有帮助。
- 我也试过在调用内部工作流程的末尾添加
exit 0
让 snakemake 认为它成功完成,
像这样:
rule run_inner:
input:
inputs...
output:
outputs...
shell:
"""
snakemake -s inner.snakefile
exit 0
"""
但输出仍然被删除。
将不胜感激任何帮助。谢谢!
一种解决方法是使用 run
而不是 shell
:
rule run_inner:
input:
inputs...
output:
outputs...
run:
shell("""snakemake -s inner.snakefile""")
# Add your code here to store the files before removing
即使 shell
函数调用中的脚本失败,文件仍然存在,直到 run
部分中的脚本完成。您可以将文件复制到安全的地方。
更新: 您需要处理异常以在脚本 returns 出错时继续执行。下面的脚本说明了这个想法:except:
块中的 print
函数打印 True
,onerror
中的另一个函数打印 False
rule run_inner:
output:
"output.txt"
run:
try:
shell("""touch output.txt; exit 1""")
except:
print(os.path.exists("output.txt"))
onerror:
print(os.path.exists("output.txt"))
一个选项可能是让 run_inner
生成一个虚拟输出文件来标记规则的完成。 run_inner
之后的规则将输入虚拟文件。例如:
rule run_inner:
...
output:
# or just 'run_inner.done' if wildcards are not involved
touch('{sample}.run_inner.done'),
shell:
'snakemake -s inner.snakefile'
run next:
input:
'{sample}.run_inner.done',
params:
real_input= '{sample}.data.txt', # This is what run_inner actually produces
shell:
'do stuff {params.real_input}'
如果 snakemake -s inner.snakefile
失败,虚拟输出将被删除,但 snakemake -s inner.snakefile
将从它离开的地方重新开始。
另一种选择是将 inner.snakefile
中的规则集成到您的外部管道中,例如使用include 语句。我觉得这个选项更可取,但当然,实施起来会更复杂。
程序在返回非零 return 值时“失败”。因此,我们只需要“修复”这个问题来欺骗内心的 shell 认为所有程序都已成功完成。最简单的方法是使用 some error command || true
。下面是一个最小的例子:
rule test:
output:
"test.output",
shell:
"""
touch test.output
# below cat will trigger error
cat file_not_exist || true
"""
你会发现尽管 cat
抛出错误,test.output
仍然存在。
我有一个 snakemake 工作流程,其中包含运行另一个“内部”snakemake 工作流程的规则。
有时内部工作流的某个规则失败,这意味着内部工作流失败。因此,内部工作流 output
下列出的所有文件都被外部工作流删除,即使创建它们的内部工作流规则已成功完成。
有没有办法防止 snakemake 删除失败规则的输出?或者您可以建议另一种解决方法?
一些注意事项:
- 必须列出内部工作流的输出,b/c它们用作外部工作流中其他规则的输入。
- 我尝试将内部工作流程的输出设置为
protected
,但这没有帮助。 - 我也试过在调用内部工作流程的末尾添加
exit 0
让 snakemake 认为它成功完成,
像这样:
rule run_inner:
input:
inputs...
output:
outputs...
shell:
"""
snakemake -s inner.snakefile
exit 0
"""
但输出仍然被删除。
将不胜感激任何帮助。谢谢!
一种解决方法是使用 run
而不是 shell
:
rule run_inner:
input:
inputs...
output:
outputs...
run:
shell("""snakemake -s inner.snakefile""")
# Add your code here to store the files before removing
即使 shell
函数调用中的脚本失败,文件仍然存在,直到 run
部分中的脚本完成。您可以将文件复制到安全的地方。
更新: 您需要处理异常以在脚本 returns 出错时继续执行。下面的脚本说明了这个想法:except:
块中的 print
函数打印 True
,onerror
中的另一个函数打印 False
rule run_inner:
output:
"output.txt"
run:
try:
shell("""touch output.txt; exit 1""")
except:
print(os.path.exists("output.txt"))
onerror:
print(os.path.exists("output.txt"))
一个选项可能是让 run_inner
生成一个虚拟输出文件来标记规则的完成。 run_inner
之后的规则将输入虚拟文件。例如:
rule run_inner:
...
output:
# or just 'run_inner.done' if wildcards are not involved
touch('{sample}.run_inner.done'),
shell:
'snakemake -s inner.snakefile'
run next:
input:
'{sample}.run_inner.done',
params:
real_input= '{sample}.data.txt', # This is what run_inner actually produces
shell:
'do stuff {params.real_input}'
如果 snakemake -s inner.snakefile
失败,虚拟输出将被删除,但 snakemake -s inner.snakefile
将从它离开的地方重新开始。
另一种选择是将 inner.snakefile
中的规则集成到您的外部管道中,例如使用include 语句。我觉得这个选项更可取,但当然,实施起来会更复杂。
程序在返回非零 return 值时“失败”。因此,我们只需要“修复”这个问题来欺骗内心的 shell 认为所有程序都已成功完成。最简单的方法是使用 some error command || true
。下面是一个最小的例子:
rule test:
output:
"test.output",
shell:
"""
touch test.output
# below cat will trigger error
cat file_not_exist || true
"""
你会发现尽管 cat
抛出错误,test.output
仍然存在。