微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Snakemake:使用校验和而不是时间戳?

如何解决Snakemake:使用校验和而不是时间戳?

我的项目可能会出现输入数据集被覆盖但内容未更改的情况。 Snakemake 有没有办法使用校验和而不是时间戳来检查构建更改?

例如,Scons 使用 md5 散列(仅在时间戳更改时计算散列)检查代码和数据中的构建更改。但我更喜欢使用 Snakemake,因为它具有其他杀手级功能

所需的行为类似于文档中描述的 between workflow caching 功能。在文档中它说:

无需使用此功能来避免工作流中的冗余计算。 Snakemake 已经开箱即用。

但所有对此问题的引用都指向 Snakemake 仅在正常工作流程中使用时间戳。

使用 ancient 标记或使用 touch 调整时间戳对我不起作用,因为这需要太多的手动干预。

我最终发现 an old SO post 表明我可以通过编写自己的脚本来比较校验和然后将其输入 Snakemake 来实现这一点,但我不确定这是否仍然是唯一的选择。

解决方法

我不知道蛇形中的内置解决方案。也许这就是我要做的。

假设您的输入数据是 data.txt。这是可能被覆盖而不更改的文件。不是直接在snakemake rules 中使用此文件,而是使用缓存副本,只有当原始和缓存之间的md5 发生更改时才会覆盖该副本。可以使用标准 python 代码在 rule all 之前完成检查。

这是一个伪代码示例:

input_md5 = get_md5('data.txt')
cache_md5 = get_md5('cache/data.txt')

if input_md5 != cache_md5:
    # This will trigger the pipeline because cache/data.txt is newer than output
    copy('data.txt','cache/data.txt') 

rule all:
    input:
        'stuff.txt'

rule one:
    input:
        'cache/data.txt',output:
        'stuff.txt',

编辑:这个伪代码保存了缓存输入文件的 md5,因此它们不需要每次都重新计算。它还将输入数据的时间戳保存到文件中,以便仅当此类时间戳比缓存的时间戳新时才重新计算输入的 md5:

for each input datafile do:

current_input_timestamp = get_timestamp('data.txt')
cache_input_timestamp = read('data.timestamp.txt')

if current_input_timestamp > cache_input_timestamp:
    input_md5 = get_md5('data.txt')
    cache_md5 = read('cache/data.md5')

    if input_md5 != cache_md5:
        copy('data.txt','cache/data.txt') 
        write(input_md5,'cache/data.md5')
        write(current_input_timestamp,'data.timestamp.txt')

# If any input datafile is newer than the cache,the pipeline will be triggered

然而,这增加了管道的复杂性,所以我会检查它是否值得。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。