Snakemake:如何对新创建的文件使用 glob_wildcards ?

MKR*_*MKR 2 python snakemake

问题:

我有一个很大的工作流程,它在某个时刻创建任意数量的文件{sample},命名为例如test1.txttest2.txt等。

然后我需要使用这些文件进行进一步处理。下一条规则的输入文件是{sample}/test1.txt{sample}/test2.txt等。因此test1test2等成为通配符。

数据结构为:

---data
 ---sample1
   ---test1.txt
   ---test2.txt
   ---test3.txt
 ---sample2
   ---test1.txt
   ---test2.txt
Snakefile
Run Code Online (Sandbox Code Playgroud)

我正在努力如何使用snakemake来解决此类问题。我研究过该函数glob_wildcards,但不知道如何使用它。

直觉上,我会做这样的事情:

samples = ['sample1', 'sample2']

rule append_hello:
  input:
    glob_wildcards('data/{sample}/{id}.txt')
  output:
    'data/{sample}/{id}_2.txt'
  shell:
    " echo {input} 'hello' >> {output} "
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. Snakemkae 中如何处理这个问题?
  2. 您将如何构造 arule all来运行它。

任何进一步阅读的意见或提示将不胜感激。

编辑

我认为这与通配符限制有关。当我跑步时:

assemblies = []
for filename in glob_wildcards(os.path.join("data/{sample}", "{i}.txt")):
    assemblies.append(filename)
print(assemblies)
Run Code Online (Sandbox Code Playgroud)

我得到两个相应索引匹配的列表:

[['sample1', 'sample1', 'sample1', 'sample2', 'sample2'], ['test1', 'test2', 'test3', 'test5', 'test4']]
Run Code Online (Sandbox Code Playgroud)

现在我基本上只需要告诉snakemake使用相应的通配符值。

Dmi*_*nov 6

您的问题是,glob_wildcards在执行任何规则之前仅评估一次,因此系统不知道该规则会生成多少个文件。

你需要的是一个检查点。此功能允许您在某个点停止 Snakemake 并重新评估 DAG。

samples = ["sample1", "sample2"]

rule all:
    input:
        expand("data/{sample}/processed.txt", sample=samples)


checkpoint generate_arbitrary:
    output:
        directory("data/{sample}/arbitrary")
    run:
        if wildcards.sample == "sample1":
            n = 3
        else:
            n = 2

        shell("mkdir {output}")
        for id in range(1, n + 1):
            shell(f"echo '{{id}}' > data/{wildcards.sample}/arbitrary/{id}.txt")



def aggregate_input(wildcards):
    checkpoints.generate_arbitrary.get(sample=wildcards.sample)
    ids = glob_wildcards(f"data/{wildcards.sample}/arbitrary/{{id}}.txt").id
    return expand(f"data/{wildcards.sample}/arbitrary/{{id}}.txt", id=ids)


rule append_hello:
    input:
        aggregate_input
    output:
        "data/{sample}/processed.txt"
    shell:
        "echo {input} 'hello' > {output}"
Run Code Online (Sandbox Code Playgroud)