shell 在Snakemake中不能正常使用星号作为glob模式

wqsoz72f  于 7个月前  发布在  Shell
关注(0)|答案(1)|浏览(73)

我想在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命令中使用glob模式,而不是在input中使用glob模式,则可以工作:

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

hivapdat

hivapdat1#

由于执行范例的原因,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将删除依赖的输出。然而,如果你必须首先生成那些样本文件,这将 * 失败 *,因为它只会查看文件系统中当前的内容。这可能不是一个问题,但最好的方法是有一个config,json或csv文件,可以将每个样本Map到条形码。然后你的输入函数可以从中提取,以确定它需要哪些样本。

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中使用星号。

相关问题