我正在构建一个 Snakemake 管道,该管道对序列进行聚类并输出每个聚类的登录号文件。我不知道会产生多少集群。我想生成一个通配符,可以在规则的输入和输出中使用它来处理新创建的文件。我的玩具示例如下:
#!/usr/bin/env python3
import os
import re
import pathlib
from Bio import SeqIO
#Snakemake --cores 18
###########
# GLOBALS #
###########
TRANSCRIPTOME = ["protein"]
OUTDIR = ["outdir"]
def get_cluster(wildcards):
checkpoints.cluster_csplit.get()
return glob_wildcards(f"{OUTDIR}/Cluster/{TRANSCRIPTOME}-{{CLUSTER}}").CLUSTER
#########
# RULES #
#########
rule all:
input:
expand('{OUTDIR}/{TRANSCRIPTOME}.90.faa.clstr', TRANSCRIPTOME = TRANSCRIPTOME, OUTDIR = OUTDIR),
expand('{OUTDIR}/Cluster/{TRANSCRIPTOME}-0000', TRANSCRIPTOME = TRANSCRIPTOME, OUTDIR = OUTDIR),
expand("{OUTDIR}/Cluster/{TRANSCRIPTOME}-{CLUSTER}.acc", TRANSCRIPTOME = TRANSCRIPTOME, OUTDIR = OUTDIR, CLUSTER = get_cluster)
########
# MAIN #
########
#Use cdhit to the cluster seqs
rule NMG_cdhit:
input:
'{TRANSCRIPTOME}.faa'
output:
fa = '{OUTDIR}/{TRANSCRIPTOME}.90.faa',
clstr = '{OUTDIR}/{TRANSCRIPTOME}.90.faa.clstr'
threads:
14
shell:
'cd-hit '
'-T {threads} '
'-i {input} '
'-o {output.fa} '
'-d 0 '
'-sc 1 '
'-c 0.90 '
#split the cluster file into seperate cluster files
checkpoint cluster_csplit:
input:
'{OUTDIR}/{TRANSCRIPTOME}.90.faa.clstr'
output:
'{OUTDIR}/Cluster/{TRANSCRIPTOME}-0000'
params:
'{OUTDIR}/Cluster/{TRANSCRIPTOME}-'
shell:
"""csplit --digits=4 -z --prefix={params} {input} "/>Cluster*/" {{*}} """
#process
rule get_cluster_files:
input:
"{OUTDIR}/Cluster/{TRANSCRIPTOME}-{CLUSTER}"
output:
"{OUTDIR}/Cluster/{TRANSCRIPTOME}-{CLUSTER}.acc"
shell:
"echo {input} > {output}" #To be replaced with script to return accession numbers. Just renames the files for now.
我希望使用通配符
'{CLUSTER}'
重命名文件。相反,我得到了一个
"MissingInputException in line 63 of /home/js/Projects/cd-hit_2_fa_snakemake/Snakefile:
Missing input files for rule get_cluster_files:
outdir/Cluster/protein-<function get_cluster at 0x7f5ca2b07b50>"
错误。
任何帮助将不胜感激。
我会查看有关检查点的文档和一些有关 SO 的示例。您正在像普通的 python 函数一样使用输入函数。您可以通过调用扩展函数中的函数来实现此功能
get_cluster()
。您在该函数中不使用通配符,因此您也可以丢弃输入参数。这可能不起作用,因为 Snakemake 处理检查点的方式变得脆弱,我建议重构您的规则以使用输入函数。