在 Snakemake 中通常无法使用星号作为 glob 模式

问题描述 投票:0回答:1

我想在 Snakemake 规则文件的 shell 部分中使用星号作为 glob 模式来代表“除 / 之外的任何字符串”(如

glob Wikipedia
中所述)。但注意到我无法像在 Shell 终端中一样正常使用它。是我的规则文件有错误,还是因为Snakemake在最新版本中禁止了?

我的规则文件如下所示:

barcodes = ["AAA", "GGG", "TTT"]

rule end:
    input: "output/merged.txt"

rule test_glob:
    input: "per_barcode/sample_*_rep_{barcode}.txt"
    output: "output/{barcode}.txt"
    shell:
        "head {input} > {output}"

rule merge:
    input: expand("output/{barcode}.txt", barcode = barcodes)
    output: "output/merged.txt"
    shell: 
        "cat {input} > {output}"

文件是:

ls per_barcode/
sample_10_rep_GGG.txt  sample_2_rep_AAA.txt  sample_5_rep_TTT.txt

错误信息是:

MissingInputException in line 7 of test.smk:
Missing input files for rule test_regex:
per_barcode/sample_*_rep_GGG.txt

但是,如果我将规则

test_glob
更改为以下内容,以在
shell
命令中而不是在
input
中使用 glob 模式,则它会起作用:

rule test_glob:
    output: "output/{barcode}.txt"
    shell:
        "head per_barcode/sample_*_rep_{wildcards.barcode}.txt > {output}"
python shell glob snakemake
1个回答
0
投票

由于执行范例,snakemake 中的通用星号 glob 存在一些问题。星号表示“给我这里存在的所有文件”,但snakemake需要知道这些文件是什么,以便它可以生成它们(如果需要)。在你的第二个例子中,当它运行时,它无法通知snakemake输入文件实际上是什么。如果您修改示例文件,snakemake 将无法检测并重新运行该规则。更好的编写方法是使用输入函数:

barcodes = ["AAA", "GGG", "TTT"]

rule end:
    input: "output/merged.txt"

def test_glob_input(wildcards):
    # get list of samples, format name with barcode from wildcards
    samples = glob_wildcards(
                 f"per_barcode/sample_{{sample}}_rep_{wildcards.barcode}.txt"
              ).sample
    return expand(
           "per_barcode/sample_{sample}_rep_{barcode}.txt",
           sample=samples,
           barcode=wildcards.barcode)


rule test_glob:
    input: test_glob_input
    output: "output/{barcode}.txt"
    shell:
        "head {input} > {output}"

rule merge:
    input: expand("output/{barcode}.txt", barcode = barcodes)
    output: "output/merged.txt"
    shell: 
        "cat {input} > {output}"

现在,如果文件发生更改,snakemake 将重新运行相关输出。但是,如果您必须首先生成这些示例文件,这将“失败”,因为它只查看文件系统上当前的内容。这可能不是问题,但最好的方法是拥有一个可以将每个样本映射到条形码的配置、json 或 csv 文件。然后你的输入函数可以从中提取以确定它需要哪些样本。 barcodes = ["AAA", "GGG", "TTT"] # need a dictionary or dataframe with barcode to sample mapping barcodes_to_sample = {"AAA": ['a1', 'a2', a3'], "GGG": ['g1', 'g2'], ...} rule end: input: "output/merged.txt" def test_glob_input(wildcards): # get list of samples from wildcard information samples = barcodes_to_sample[wildcards.barcode] return expand( "per_barcode/sample_{sample}_rep_{barcode}.txt", sample=samples, barcode=wildcards.barcode) rule test_glob: input: test_glob_input output: "output/{barcode}.txt" shell: "head {input} > {output}" rule merge: input: expand("output/{barcode}.txt", barcode = barcodes) output: "output/merged.txt" shell: "cat {input} > {output}"

虽然这巧妙地改变了文件,但对执行的影响意味着您可以添加上游规则来下载或过滤文件,并且仍然可以正常工作。

我不确定snakemake是否允许在输入规则中使用通配星号,ASAIK。

© www.soinside.com 2019 - 2024. All rights reserved.