【发布时间】:2018-03-20 03:25:30
【问题描述】:
是否有可能避免在执行shell命令之前删除snakemake规则中定义的输出文件?我在这里找到了对这种行为的描述:http://snakemake.readthedocs.io/en/stable/project_info/faq.html#can-the-output-of-a-rule-be-a-symlink
我要做的是为输入列表和输出文件列表(N:M 关系)定义规则。如果输入文件之一已更改,则应触发此规则。然后,在 shell 命令中调用的 python 脚本只创建那些不存在的输出,或者与现有文件相比,其内容发生了变化(即,在 python 脚本中实现了更改检测)。我希望类似以下规则的东西应该可以解决这个问题,但是由于在运行 python 脚本之前删除了 output.jsons,所有 output.jsons 都将使用新的时间戳创建,而不仅仅是那些已更改的时间戳。
rule jsons:
"Create transformation files out of landmark correspondences."
input:
matchfiles = ["matching/%04i-%04i.h5" % (SECTIONS[i], SECTIONS[i+1]) for i in range(len(SECTIONS)-1)]
output:
jsons = ["transformation/{section}_transformation.json".format(section=s) for s in SECTIONS]
shell:
"python create_transformation_jsons.py --matchfiles {input.matchfiles} --outfiles {output.jsons}"
如果无法避免在 Snakemake 中删除输出文件,是否有人知道如何将此工作流映射到 snakemake 规则而不更新所有输出文件?
更新:
我尝试通过更改 Snakemake 源代码来解决这个问题。我删除了 jobs.py 中的 self.remove_existing_output() 行,以避免在执行规则之前删除输出文件。此外,我在 executors.handle_job_success 中调用 self.dag.check_and_touch_output() 时添加了参数no_touch=True。这很好用,因为现在输出文件在执行规则之前既没有被删除也没有被触及。但是对于每个 json 文件(即使它没有更改)仍然会触发以 json 文件作为输入的以下规则,因为 Snakemake 认识到 json 文件之前被定义为输出并且必须已经更改。
所以我认为避免删除输出文件并不能解决我的问题,也许一种解决方法 - 如果存在 - 是唯一的方法......
更新 2:
我也尝试通过将上面定义的jsons规则的输出路径更改为transformation/tmp/...并添加以下规则,在不更改Snakemake源代码的情况下找到解决方法:
def cmp_jsons(wildcards):
section = int(wildcards.section)
# compare json for given section in transformation/ with json in transformation/tmp/
# return [] if json did not change
# return path to tmp json filename if json has changed
rule copy:
input:
json_tmp = cmp_jsons
output:
jsonfile = "transformation/B21_{section,\d+}_affine_transformation.json"
shell:
"cp {input.json_tmp} {output.jsonfile}"
但由于在工作流开始之前评估输入函数,tmp-jsons 要么不存在,要么尚未被 jsons 规则更新,因此比较将不正确。
【问题讨论】: