如何将Snakemake规则run段返回的输出路径传递到output段
结论
Snakemake不支持直接将同规则run:上下文内生成的变量传递给output:上下文,因为Snakemake的执行流程有严格的先后顺序:
- 第一阶段为DAG构建阶段:Snakemake会先解析所有规则的
input/output/params等声明,确定任务依赖关系、输出目标,这个阶段还不会执行run:块内的代码 - 第二阶段为任务执行阶段:DAG完全构建完成后,才会执行
run:块内的逻辑,此时output的路径已经固定,无法再动态修改
适配方案
根据你的场景(函数仅依赖input文件和提前可用的metadata),优先推荐下面的方案,不需要改核心逻辑就能实现需求:
方案1:将路径生成逻辑提前到规则声明阶段(推荐)
把函数调用放到params块中预计算,output块直接引用预计算得到的路径即可,示例如下:
# 提前引入函数,不要放在run块内 from module import function rule task01: input: "path/to/input.tsv" params: # DAG构建阶段就会执行函数计算路径 out_path = lambda wildcards, input: function(metadata=metadata) output: # 直接引用params中提前算好的路径 lambda wildcards, params: params.out_path run: # run块内直接用params里的路径即可 p = params.out_path # 后续执行你的文件写入逻辑
这个方案的优势是完全适配Snakemake的原生机制,缓存、依赖检查、任务调度所有功能都能正常生效。
方案2:动态输出适配(仅特殊场景使用)
如果你的函数依赖只有执行阶段才能拿到的内容,无法提前计算路径,可以用动态输出标记,示例如下:
rule task01: input: "path/to/input.tsv" output: # 匹配所有符合该命名模式的输出文件,可根据你的实际路径调整匹配规则 dynamic("results/*.tsv") run: from module import function p = function(metadata=metadata) # 直接往p路径写入文件即可,Snakemake会自动识别生成的文件作为该规则的输出
该方案的缺点是DAG构建阶段无法确定输出路径,后续依赖该规则的任务需要做对应适配,缓存、依赖检查的能力也会受限,仅作为备选方案。
内容的提问来源于stack exchange,提问作者user3521099
相关产品推荐
相关产品推荐

