如何借助配置文件字典使用Snakemake实现文件重命名?
问题描述
借助配置文件中的字典,通过Snakemake按模式匹配重命名文件,但重命名后输入wildcard与输出wildcard不再匹配,导致rule all无法找到重命名后的输出文件。
现有数据结构
. ├── pool1 │ ├── name_A.txt │ ├── name_B.txt │ ├── name_C.txt │ └── name_D.txt └── pool2 ├── name_E.txt ├── name_F.txt ├── name_G.txt └── name_H.txt
目标结构
. ├── pool1 │ ├── name_1.txt │ ├── name_2.txt │ ├── name_3.txt │ └── name_4.txt └── pool2 ├── name_2.txt ├── name_3.txt ├── name_5.txt └── name_6.txt
配置文件规则
每个pool的替换规则存储在配置文件中:
pools=['pool1','pool2'] c2n : [{'A':'1', 'B':'2', 'C':'3', 'D':'4'}, {'E':'2', 'F':'3', 'G':'5', 'H':'6'}]
已做准备
基于配置文件通过嵌套循环生成了rename_in和rename_out列表,rule all设置如下:
rename_in=['pool1/name_A','pool1/name_B','pool1/name_C','pool1/name_D','pool2/name_E','pool2/name_F','pool2/name_G','pool2/name_H'] rename_out=['pool1/name_1','pool1/name_2','pool1/name_3','pool1/name_4','pool2/name_2','pool2/name_3','pool2/name_5','pool2/name_6'] rule all: input: # rename.smk expand("{pattern}.txt", pattern=rename_out)
尝试的三种方法
- 遍历列表生成多个规则:
for l, n in zip(rename_in, rename_out): rule: input: f"{l}.txt" output: f"{n}.txt" shell: "mv {input} {output}"
- 为单个pool配置规则后扩展到所有pool:
rule rename: input: "pool1/name_{l}.txt" output: "pool1/name_{config[c2n][l]}.txt" shell: "mv {input} {output}"
- 编写Python包装器调用
mv命令,但rule all仍无法正确识别输出。
需求:寻求简洁高效的方法实现Snakemake文件重命名,最好能基于pool动态处理,希望避开checkpoints。
编辑说明(已采纳解决方案)
采纳了Wayne的解决方案,完美适配需求。对于需要重命名已生成文件的用户,可参考该方案。
问题源于生物信息学工具对IsoSeq数据的拆分(demultiplexing):一个输入文件生成多个已知输出文件,需后续重命名,可通过配置文件实现。最终解决方案是将重命名步骤直接整合到生成已知输出模式的流程中,同时解决了只能重命名已生成文件的问题。
更实用的流程整合示例
遍历配置文件中的pool列表(config['pools']),通过索引获取对应的样本与barcode映射字典(config['name2bc'][idx]),类似原示例中的c2n(实际场景是将barcode转为名称,因此遍历值获取bcs)。拆分流程的输出作为重命名规则的输入,每个pool的重命名最终输出作为rule all的输入。config["name2pools"]用于将实际名称与pool关联,便于下游分析。
rule all: input: [f"output/lima/{pool}/{pool}.demux.hifi.{name}.renamed.bam" for name, pools in config["name2pools"].items() for pool in pools], for idx, pool in enumerate(config['pools']): n2bc = config['name2bc'][idx] bcs = list(n2bc.values()) rule: #rule lima_per_pool: """ Demultiplex the pools and remove primers + barcodes """ input: hifi=f"{pool}.hifi.bam", biosamples=f"biosamp_{pool}.csv", barcodes="barcodes_uniprimers.fasta" output: expand(f"output/lima/{pool}/{pool}.demux.hifi.{{bc}}.bam", bc=bcs) shell: "lima --flags" #rename_per_pool for name, barcodes in n2bc.items(): #rule rename_per_barcode rule: input: f"output/lima/{pool}/{pool}.demux.hifi.{barcodes}.bam" output: f"output/lima/{pool}/{pool}.demux.hifi.{name}.renamed.bam" shell: "ln -sf $(readlink -f {input}) {output}"
注:若输出文件/文件名未知,建议使用checkpoints。
内容的提问来源于stack exchange,提问作者Laron
相关产品推荐
相关产品推荐

