提问人:Xiaokang 提问时间:11/9/2023 更新时间:11/10/2023 访问量:25
在 Snakemake 中不能正常使用星号作为球形图案
Cannot use asterisk as glob pattern normally in Snakemake
问:
我想使用星号作为 glob 模式来代表 Snakemake 规则文件中的“除 / 之外的任何字符串”(如 glob Wikipedia 中所述)。但是注意到我不能像在壳牌终端中那样正常使用它。我是在我的规则文件中犯了什么错误,还是因为 Snakemake 在最新版本中禁止了它?shell
我的规则文件如下所示:
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
但是,如果我将规则更改为以下内容以在命令中使用 glob 模式而不是 ,它会起作用:test_glob
shell
input
rule test_glob:
output: "output/{barcode}.txt"
shell:
"head per_barcode/sample_*_rep_{wildcards.barcode}.txt > {output}"
答:
由于执行范式,snakemake 中的通用星号球存在一些问题。星号表示“给我此处存在的所有文件”,但 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 文件,该文件可以将每个样本映射到条形码。然后,您的输入函数可以从中提取以确定它需要哪些样本。
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 中使用 glob 星号。
上一个:Glob 已知子路径
下一个:对文件夹内的子文件夹执行任务
评论