如何在Snakemake中实现目录符号链接自动生成工作流?
解决Snakemake符号链接目录别名的问题
我来帮你搞定这个Snakemake工作流里的符号链接目录问题!你的核心需求是不修改现有YAML配置和逻辑,解决MissingInputException、ImproperOutputException以及重运行报错的问题,下面是适配Snakemake 5.x版本的可行方案:
修改后的完整Snakefile
### Setup ### configfile: "config.yaml" ### Targets ### # 生成英文投票文件路径(保持原逻辑不变) votes = ["english/" + flavour + "/" + voter for flavour, voters in config["flavours"].items() for voter in voters] # 重构翻译目录目标生成,确保每个翻译路径都被正确枚举 translations = [] for lang, trans_map in config["translations"].items(): for trans_name, orig_flavour in trans_map.items(): translations.append(f"{lang}_translation/{trans_name}") ### Commands ### create_file_cmd = "touch '{output}'" # 新增--force参数,重运行时自动覆盖已存在的符号链接 relative_symlink_cmd = "ln --symbolic --relative --force '{input}' '{output}'" ### Rules ### rule all: input: votes, # 明确标记翻译路径为目录目标,让Snakemake正确识别 [directory(path) for path in translations] rule english: output: "english/{flavour}/{voter}" shell: create_file_cmd rule translation: # 标记输入为目录,关联原英文口味目录的依赖 input: directory(lambda wc: f"english/{config['translations'][wc.lang][wc.trans]}") # 标记输出为目录,解决ImproperOutputException output: directory("{lang}_translation/{trans}") shell: relative_symlink_cmd
关键修改说明
明确标记目录类型
- 在
rule all中用directory()包装翻译路径,告诉Snakemake这些是目录而非普通文件,避免触发MissingInputException。 translation规则的输入和输出都标记为directory(),让Snakemake正确处理目录级别的依赖,解决ImproperOutputException。
- 在
优化翻译目标生成逻辑
- 把原集合生成的
translations改成遍历式列表生成,虽然集合也能工作,但列表更直观,确保每个翻译目录都被准确纳入目标列表。
- 把原集合生成的
解决重运行报错
- 在
ln命令中添加--force参数,重运行时会自动覆盖已存在的符号链接,彻底解决ChildIOException问题,无需手动清理旧链接。
- 在
自动关联目录依赖
- 由于
english规则会生成对应口味目录下的所有投票文件,Snakemake会自动识别到原口味目录的存在依赖于这些文件,因此无需分两次运行,一次执行就能完成所有文件和符号链接的生成。
- 由于
现在直接运行snakemake就能一次性生成所有英文投票文件和多语言别名目录的符号链接,重运行也不会出现任何报错啦!
内容的提问来源于stack exchange,提问作者mschilli
相关产品推荐
相关产品推荐

