snakemake - Snakemake:使用校验和而不是时间戳?
问题描述
我的项目可能存在输入数据集被覆盖但内容未更改的情况。Snakemake 中有没有办法使用校验和而不是时间戳来检查构建更改?
例如,Scons 使用 md5 哈希检查代码和数据中的构建更改(仅在时间戳发生更改时计算哈希)。但我更喜欢使用 Snakemake,因为它还有其他杀手级功能。
所需的行为类似于文档中描述的工作流缓存功能之间的行为。在文档中它说:
无需使用此功能来避免工作流中的冗余计算。Snakemake 开箱即用。
但是所有对这个问题的引用都指向 Snakemake 仅在正常工作流程中使用时间戳。
使用ancient
标记或使用touch
来调整时间戳对我来说不起作用,因为这需要太多的手动干预。
我最终找到了一篇旧的 SO 帖子,表明我可以通过编写自己的脚本来比较校验和然后将其输入 Snakemake 来做到这一点,但我不确定这是否仍然是唯一的选择。
解决方案
我不知道snakemake 中的内置解决方案。也许这就是我将如何去做。
假设您的输入数据是data.txt
. 这是可能在不更改的情况下被覆盖的文件。不是直接在snakemake中使用这个文件rules
,而是使用一个缓存副本,只有当md5在原始和缓存之间发生变化时才会被覆盖。检查可以在rule all
使用标准 python 代码之前完成。
这是一个伪代码示例:
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
然而,这增加了管道的复杂性,所以我会检查它是否值得。
推荐阅读
- ios - 返回 xcode/swift/ios 项目 - 突然得到“没有这样的模块”
- aspnetboilerplate - 带有 JavaScript 的菜单项
- android - 如何跟踪用户吸引我的广告的时间
- sql - 如何在 postgresql 中获取组号?
- php - php数组迭代视觉上父>子
- android - android Polyline会在一段时间后滞后地图
- mysql - 我在将 mysql 数据库(phpmyadmin)连接到 node.js 时收到错误
- csv - Spark:正在写入的加载文件
- php - Symfony - 控制器编辑动作
- xamarin.forms - IContainerRegistryExtensions 如何将实例注册为单例