snakemake 规则是否可以依赖文件中的数据而不是其更改状态

Can a snakemake rule depend on data in the file instead of its change state

我的 CSV 文件中的数据经常更改。 CSV 文件是 snakefile 规则的来源。我的问题是我希望此规则仅在 CSV 文件的数据中出现某个值时才 运行,而不是每次文件更改时。是否可以让规则执行取决于已更改的文件中的特定模式而不是它已更改的事实?

Snakemake 为确定规则是否应该 re-executed 所做的具体检查是基于时间戳(而不是文件内容),因此首先要做的是将相关文件包装在 ancient 中。

接下来,由于 Snakefile 是一个 Python 文件,因此可以使用 pandas 或其他一些用于处理 csvs 的库来合并所需的逻辑。以下是一个粗略的想法:

import pandas as pd
csv_file = 'some_file.txt'
df = pd.read_csv(csv_file)
items_to_do = df.query('column_x>=10')['column_y'].values.tolist()

rule all:
    input: expand('file_out_{y}.txt', y=items_to_do)

rule some_rule:
    input: ancient('test.csv')
    output: 'file_out_{y}.txt'
    ... # code to generate the file

因此,如果您更新 some_file.txt,但更新的值与 column_x 相关联且小于 10,则不会执行任何新作业。

更新:我假设有问题的规则使用通配符生成多个文件,但re-reading问题似乎并非如此。如果只是一条规则,则可以修改上面的代码片段以按照以下方式工作:

import pandas as pd
csv_file = 'some_file.txt'

def file_is_updated():
    df = pd.read_csv(csv_file)
    # implement logic to decide if the rule should be re-run
    # e.g. set to True if len() > 50
    needs_updating = True if len(df)>50 else False
    return needs_updating

# use python to execute conditionally
if file_is_updated():
    rule some_rule:
        input: csv_file
        ...

一个选项可以是始终 运行 条件规则,但如果 CSV 中的值存在,则 运行 将其设置为“虚拟”模式。主要是伪代码:

rule run_if:
    input:
        'data.csv',
    output:
        'done.out',
    run:
        if 'some_value' is in data.csv:
            do stuff and write 'done.out'
        else:
            # Only update the file
            touch('done.out')

不过这取决于 done.out 之后会发生什么 created/updated。

一般来说,最好从 input/output 文件链的角度来考虑 snakemake,而不是根据你想要 运行 的规则来考虑 运行。