Snakemake如何用绝对路径配对无通配符的输入与输出?
无共享通配符的绝对路径输入输出配对问题
问题背景
需要实现Snakemake规则对多组绝对路径的输入输出进行配对处理:输入/path/to/input1生成/path/to/output1,同时并行处理/path/to/input2生成/path/to/output2。参考类似方案改用绝对路径后,始终出现键错误或输入缺失异常,但相对路径可正常运行。
用户尝试的代码如下:
numbers = ['/tmp/1.txt', '/tmp/2.txt', '/tmp/3.txt', '/tmp/4.txt'] letters = ['/tmp/A.txt', '/tmp/B.txt', '/tmp/C.txt', '/tmp/D.txt'] ln = dict(zip(numbers, letters)) rule all: input: expand('{number}', number= numbers), rule out: input: letter= lambda wc: ln[wc.number], output: '{number}' shell: """ echo {input.letter} > {output} """
解决方案
1. 标准化路径格式(核心修复)
Snakemake对绝对路径的wildcard解析可能存在路径表示不一致的问题(如/tmp/1.txt和/tmp//1.txt),导致字典键匹配失败。使用pathlib标准化路径即可解决:
from pathlib import Path # 用Path对象处理路径,确保格式统一 numbers = [Path("/tmp/1.txt"), Path("/tmp/2.txt"), Path("/tmp/3.txt"), Path("/tmp/4.txt")] letters = [Path("/tmp/A.txt"), Path("/tmp/B.txt"), Path("/tmp/C.txt"), Path("/tmp/D.txt")] # 生成标准化路径的配对字典 ln = {num.resolve(): letter.resolve() for num, letter in zip(numbers, letters)} rule all: input: expand("{number}", number=numbers), rule out: input: # 对wildcard捕获的路径做标准化,确保和字典键匹配 letter= lambda wc: ln[Path(wc.number).resolve()], output: "{number}" # 注意此处必须缩进,否则会触发语法错误 shell: """ cat {input.letter} > {output} """
2. 简化配对逻辑(无需wildcard匹配)
如果不想处理路径标准化问题,可直接通过输出列表的索引关联输入,避免wildcard的路径解析问题:
inputs = ["/tmp/A.txt", "/tmp/B.txt", "/tmp/C.txt", "/tmp/D.txt"] outputs = ["/tmp/1.txt", "/tmp/2.txt", "/tmp/3.txt", "/tmp/4.txt"] rule all: input: outputs # 直接指定所有输出目标 rule process: input: # 通过输出在列表中的索引找到对应输入 lambda wc: inputs[outputs.index(wc.output)], output: "{output}" shell: """ cat {input} > {output} """
注意事项
- 确保输入文件的路径与代码中定义的完全一致(包括大小写、斜杠格式);
- 规则中
output字段的内容必须缩进,否则会触发语法错误导致异常。
内容的提问来源于stack exchange,提问作者Rboreal_Frippery
相关产品推荐
相关产品推荐

