如何制作以目录为输入,多个目录/文件为输出的规则?



我想使用cellranger软件将BCL文件从音序器转换为表达式矩阵。我是做蛇的新手。

我将文件从存储器复制到本机,在shell中启动mkfastq生成FASTQ文件并存储在FASTQ/中。

为了从FASTQ文件生成表达式矩阵,我应该将整个FASTQ目录传递给cellranger。之后,cellranger创建示例目录,并在其中存储表达式矩阵。日志和其他文件。

我的管道:

samples = ['201', '202']
fc_name = '230119_FOO'
run = 'storage/vud/230119_FOO'
rule all:
input:
expand("RESULT/{fc_name}/{sample}", sample=samples, fc_name = fc_name)

#Copy from storage to local machine
rule copy:
input:
expand({run}, run=run)
output:
expand("BCL/{fc_name}", fc_name = fc_name)
shell:
"rsync -ah {run} BCL/"
#Make FASTQ files
rule mkfastq:
input:
fastq_run=expand("BCL/{fc_name}", fc_name = fc_name)
output:
expand("FASTQ/{fc_name}", fc_name = fc_name),
expand("FASTQ/{fc_name}/outs/input_samplesheet.csv", fc_name = fc_name)
shell:
"cellranger mkfastq --run={input.fastq_run} --id={fc_name} --output-dir=FASTQ/"
# Make matrices
rule mkmat:
input:
expand("FASTQ/{fc_name}", fc_name = fc_name)
output:
expand("RESULT/{fc_name}/{sample}", sample=samples, fc_name=fc_name)
shell:
expand("cellranger count -id=RESULT/{{fc_name}}/{{samples}} --transcriptome=refdata-gex-mm10-2020-A/ --fastqs=FASTQ/230119_FOO --sample={{samples}}", samples = samples, fc_name=fc_name)

执行管道的干式运行,然后抛出错误:

File "/miniconda3/envs/snakemake/lib/python3.11/site-packages/snakemake/jobs.py", line 521, in shellcmd
self.format_wildcards(self.rule.shellcmd)
File "/miniconda3/envs/snakemake/lib/python3.11/site-packages/snakemake/jobs.py", line 986, in format_wildcards
f"{ex.__class__.__name__}: {ex}, when formatting the following:n"
TypeError: can only concatenate str (not "list") to str

如何将目录"FASTQ/230119_FOO"传递给mkmat规则并得到这样的输出:

├── RESULT
│   ├── 230119_FOO
│   │   ├── 201
│   │   │   ├── ...
│   │   ├── 202
│   │   │   ├── ...

首先,您有rule mkmat:shell:部分的问题。这个section应该是一个字符串,而expand函数返回一个字符串列表,这正是解释器抱怨的地方:

TypeError: can only concatenate str (not "list") to str

无论如何,--dry-run忽略了shell:部分的内容(只要它们提供有效的字符串),所以为了你的问题的清晰度,我们可能只是删除它们并再次尝试--dry-run

samples = ['201', '202']
fc_name = '230119_FOO'
run = 'storage/vud/230119_FOO'
rule all:
input:
expand("RESULT/{fc_name}/{sample}", sample=samples, fc_name = fc_name)

rule copy:
input:
expand({run}, run=run)
output:
expand("BCL/{fc_name}", fc_name = fc_name)
rule mkfastq:
input:
fastq_run=expand("BCL/{fc_name}", fc_name = fc_name)
output:
expand("FASTQ/{fc_name}", fc_name = fc_name),
expand("FASTQ/{fc_name}/outs/input_samplesheet.csv", fc_name = fc_name)
rule mkmat:
input:
expand("FASTQ/{fc_name}", fc_name = fc_name)
output:
expand("RESULT/{fc_name}/{sample}", sample=samples, fc_name=fc_name)

现在问题在rule mkfastq:中,因为它声明了两个输出,其中一个是另一个的子输出:

ChildIOException:
File/directory is a child to another output:
...FASTQ230119_FOO
...FASTQ230119_FOOoutsinput_samplesheet.csv

我不确定这是否可以被视为Snakemake中的bug(例如,您可以阅读此讨论:https://github.com/bioinformatics-centre/BayesTyper/issues/29)。无论如何,有一些变通方法,在您的简化情况中,最简单的方法是将目录声明为输出:

rule mkfastq:
input:
fastq_run=expand("BCL/{fc_name}", fc_name = fc_name)
output:
expand("FASTQ/{fc_name}", fc_name = fc_name)

总的来说,你的管道过于简化了,因为它甚至不包含通配符(所以你甚至不需要expand调用的任何技巧,因为你的管道是用全局变量完全定义的)。在真正的管道中,依赖关系不应该在全局变量中定义,而应该由文件系统的结构来定义。因此,在更复杂的管道中,只是删除rule mkfastq:中的一个输出可能没有帮助,您需要重新设计管道。

最新更新