如何编写Snakemake规则:以目录为输入,生成多目录/文件输出
解决Snakemake中Cell Ranger工作流的报错与目录结构问题
我看了你的Snakemake脚本和报错信息,核心问题出在mkmat规则的shell命令里错误使用了expand,而且整体规则没有利用Snakemake的wildcard特性处理多样本,导致字符串与列表拼接冲突。下面一步步帮你修正:
先拆解报错原因
你在mkmat的shell里调用expand(),这个函数返回的是一个列表(因为传入了多个样本),但Snakemake的shell命令需要的是字符串,直接把列表塞进去就触发了"只能拼接字符串,不能拼接列表"的类型错误。另外,原脚本没有针对单个样本拆分任务,不符合Snakemake并行处理的设计逻辑。
修改后的完整Snakemake脚本
samples = ['201', '202'] fc_name = '230119_FOO' run_path = 'storage/vud/230119_FOO' ref_transcriptome = 'refdata-gex-mm10-2020-A/' rule all: input: expand("RESULT/{fc}/{sample}", fc=fc_name, sample=samples) # 从存储复制BCL文件到本地 rule copy_bcl: input: run_path # 单个路径无需expand,直接传入即可 output: directory(f"BCL/{fc_name}") # 用directory标记目录类型,让Snakemake识别整个目录 shell: "rsync -ah {input} {output}/" # 明确输出目录,避免歧义 # 生成FASTQ文件 rule mkfastq: input: bcl_dir = f"BCL/{fc_name}" output: directory(f"FASTQ/{fc_name}"), f"FASTQ/{fc_name}/outs/input_samplesheet.csv" shell: "cellranger mkfastq --run={input.bcl_dir} --id={wildcards.fc} --output-dir=FASTQ/" # 生成每个样本的表达矩阵 rule mkmat: input: fastq_dir = f"FASTQ/{fc_name}", samplesheet = f"FASTQ/{fc_name}/outs/input_samplesheet.csv" output: directory("RESULT/{fc}/{sample}") # 用wildcard区分样本和测序批次 params: ref = ref_transcriptome shell: "cellranger count --id={wildcards.sample} " "--transcriptome={params.ref} " "--fastqs={input.fastq_dir} " "--sample={wildcards.sample} " "--output-dir=RESULT/{wildcards.fc}/{wildcards.sample}"
关键修改点说明
- 修正expand的错误使用:去掉
mkmatshell里的expand,改用wildcard{wildcards.sample}和{wildcards.fc}传递变量,每个样本会单独生成一个任务,支持并行处理。copy_bcl规则也无需对单个路径用expand,直接传入即可。 - 标记目录输出:用
directory()包裹目录类型的输出,让Snakemake识别整个目录作为输出单元,避免遗漏文件。 - 明确依赖关系:
mkmat的输入同时依赖FASTQ目录和样本表,确保mkfastq完全执行完毕后才启动count流程。 - 参数解耦:把参考转录组路径单独抽成变量,后续修改更便捷,也通过params传递到shell命令中。
验证修改效果
运行dry-run命令检查是否正常:
snakemake -n
如果没有报错,正式运行后会生成你需要的目录结构:
├── RESULT │ ├── 230119_FOO │ │ ├── 201 │ │ │ ├── ... # cellranger count输出的表达矩阵、报告、日志等文件 │ │ ├── 202 │ │ │ ├── ...
内容的提问来源于stack exchange,提问作者Losashik
相关产品推荐
相关产品推荐

