动态输入和动态输出规则的问题

时间:2018-11-05 17:59:46

标签: python bioinformatics snakemake

我对使用动态通配符有一个快速的疑问。我已经搜索了文档和论坛,但没有找到查询的直接答案。

以下是给我带来麻烦的规则:

rule all:
input: dynamic("carvemeOut/{species}.xml")
shell:"snakemake --dag | dot -Tpng > pipemap.png"

rule speciesProt:
input:"evaluation-output/clustering_gt1000_scg.tab"
output: dynamic("carvemeOut/{species}.txt")
shell:
    """
    cd {config[paths][concoct_run]}
    mkdir -p {config[speciesProt_params][dir]}
    cp {input} {config[paths][concoct_run]}/{config[speciesProt_params][dir]}
    cd {config[speciesProt_params][dir]}
    sed -i '1d' {config[speciesProt_params][infile]} #removes first row
    awk '{{print $2}}' {config[speciesProt_params][infile]} > allspecies.txt #extracts node information
    sed '/^>/ s/ .*//' {config[speciesProt_params][metaFASTA]} > {config[speciesProt_params][metaFASTAcleanID]} #removes annotation to protein ID
    Rscript {config[speciesProt_params][scriptdir]}multiFASTA2speciesFASTA.R
    sed -i 's/"//g' species*
    sed -i '/k99/s/^/>/' species*
    sed -i 's/{config[speciesProt_params][tab]}/{config[speciesProt_params][newline]}/' species*
    cd {config[paths][concoct_run]}
    mkdir -p {config[carveme_params][dir]}
    cp {config[paths][concoct_run]}/{config[speciesProt_params][dir]}/species* {config[carveme_params][dir]}
    cd {config[carveme_params][dir]}
    find . -name "species*" -size -{config[carveme_params][cutoff]} -delete #delete files with little information, these cause trouble
    """

rule carveme:
input: dynamic("carvemeOut/{species}.txt")
output: dynamic("carvemeOut/{species}.xml")
shell:
    """
    set +u;source activate concoct_env;set -u
    cd {config[carveme_params][dir]}
    echo {input}
    echo {output}
    carve $(basename {input})
    """

我以前在carveme规则的输入和输出中使用了两个不同的Widlcard:

input: dynamic("carvemeOut/{species}.txt")
output: dynamic("carvemeOut/{gem}.xml")

我想要snakemake要做的是多次运行carveme规则,为每个输入.txt文件创建一个输出.xml文件。但是,snakemake而是一次运行该规则,使用输入列表创建一个输出,如下所示:

rule carveme:
input: carvemeOut/species2.txt, carvemeOut/species5.txt, carvemeOut/species1.txt, carvemeOut/species10.txt, carvemeOut/species4.txt, carvemeOut/species17.txt, carvemeOut/species13.txt, carvemeOut/species8.txt, carvemeOut/species14.txt
output: {*}.xml (dynamic)
jobid: 28

按照@stovfl的建议并在第一个代码框中显示的方式修改规则以使用相同的通配符后,我收到以下错误消息:

$ snakemake all
Building DAG of jobs...
WildcardError in line 174 of /c3se/NOBACKUP/groups/c3-c3se605-17-8/projects_francisco/binning/snakemake-concot/Snakefile:
Wildcards in input files cannot be determined from output files:
species

关于如何解决此问题的任何建议?

预先感谢, FZ

1 个答案:

答案 0 :(得分:1)

您希望所有规则都具有动态性,并且要在创建动态输出的规则中具有动态性,而不要在最后一个输出中具有动态性。

这是一个可行的示例。以物种的输入文件为例,species_example.txt

SpeciesA
SpeciesB
SpeciesC
SpeciesD

以下Snakefile将动态生成4个输出文件

#Snakefile
rule all:
input: 
    dynamic("carvemeOut/{species}.xml"),

rule speciesProt:
    input: "species_example.txt"
    output: dynamic("carvemeOut/{species}.txt")
shell:  
    """
    awk '{{gsub(/\\r/,"",$1);print  > "carvemeOut/"$1".txt";}}' {input}
    """


rule carveme:
    input: "carvemeOut/{species}.txt"
    output: "carvemeOut/{species}.xml"
    shell: "cat {input} > {output}"

Dynamic当前在Snakemake中有很多限制(只允许使用一个动态通配符,请参见下面的Francisco注释,在同一规则中不混合非动态和动态输出),因此我尽可能避免使用它。例如,与其使该示例成为动态示例,不如我使用pyhton函数在运行任何规则之前生成可能的物种名称列表,并使用该函数来扩展所有规则中的通配符。您确定需要动态输出吗?

此外,您应该避免直接在Snakefile中编写如此长的Shell部分,并使用外部脚本或将该Shell命令分成多个规则。