You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Snakemake工作流问题:如何为每行输入生成独立执行命令

问题分析

你当前的规则把所有SMILES条目和输出文件都打包成了单个任务,原因是:

  • output里用expand生成了所有输出文件,Snakemake将其视为一个任务的多输出
  • 变量smiles是整个文件的行列表,在shell命令中会被直接展开为所有字符串的拼接
解决方案

要实现每个SMILES对应一条独立命令,需要用**通配符(wildcard)**拆分任务,让每个任务对应单个输入条目和单个输出文件。修改后的Snakefile如下:

configfile: "config.yaml"

# 读取SMILES列表,建立索引到SMILES的映射
smiles = []
with open(config["smiles_file"]) as f:
    smiles = f.read().splitlines()
# 创建索引到SMILES的字典,方便后续通过通配符获取
smiles_dict = {str(i+1): smi for i, smi in enumerate(smiles)}

# 定义总目标:生成所有输出文件
rule all:
    input:
        expand("results/starting_geometries/{idx}.xyz", idx=smiles_dict.keys())

# 确保输出目录存在
rule make_output_dir:
    output:
        directory("results/starting_geometries")
    shell:
        "mkdir -p {output}"

# 单个SMILES转XYZ的规则,每个任务对应一个条目
rule geometry_from_smiles:
    input:
        config["smiles_file"],
        # 依赖目录创建完成
        "results/starting_geometries"
    output:
        "results/starting_geometries/{idx}.xyz"
    params:
        # 通过通配符{idx}获取对应的SMILES
        smi=lambda wildcards: smiles_dict[wildcards.idx]
    shell:
        "obabel -:'{params.smi}' -oxyz -h --gen3D > {output}"
关键改动说明
  • rule all:作为整个工作流的入口,定义需要生成的所有目标文件,Snakemake会自动拆分出每个独立任务。
  • 通配符{idx}:用索引作为通配符,关联每个任务对应的SMILES条目和输出文件。
  • smiles_dict:建立索引到SMILES的映射,在rule中通过通配符动态获取当前任务对应的SMILES。
  • make_output_dir:确保输出目录存在,避免shell命令因目录不存在报错。
测试验证

执行dry run(snakemake -n)时,会看到3条独立的命令,每条对应一个SMILES和一个输出文件:

obabel -:'c1ccccc1' -oxyz -h --gen3D > results/starting_geometries/1.xyz
obabel -:'Oc1ccccc1' -oxyz -h --gen3D > results/starting_geometries/2.xyz
obabel -:'Nc1ccccc1' -oxyz -h --gen3D > results/starting_geometries/3.xyz

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:52:48