【问题标题】:Problems with dynamic input and dynamic output rule动态输入和动态输出规则的问题
【发布时间】:2018-11-05 17:59:46
【问题描述】:

我有一个关于使用动态通配符的简短问题。我搜索了文档和论坛,但没有找到直接回答我的问题的答案。

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

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 规则的输入和输出中使用了两个不同的通配符:

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

【问题讨论】:

  • 按照Snakemake教程尝试step-2-generalizing-the-read-mapping-rule
  • @stovfl 感谢您的回复。我尝试使用相同的通配符进行输入和输出,但是当我调用 rule all 时,它无法确定通配符。错误输出如下所示:$ snakemake allBuilding 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我将修改我的原始帖子以反映更改并添加所有规则。
  • 教程不用dynamic?将您的测试用例剥离为 rule carveme:。在这个rule 中,从shell 中删除all,除了两个echo {...}。尝试逐行添加。您正在使用 relative 文件路径并执行cd ...,这是矛盾的。其次,您正在定义output,但不是我们吗?
  • 不错,教程没有使用动态。这是另一个用户向我推荐的。我试图将我的测试用例剥离为仅 carveme 规则,但问题是它的输入和输出中有通配符,这意味着它不能成为我的目标规则。同样真实的是,我没有使用 carveme 规则的输出,但据我了解,我需要指定它,以便规则都知道在哪里可以找到它!您能否扩展相对文件路径注释?它是如何矛盾的?感谢您的帮助!
  • “相对文件路径注释”:使用cd ... 更改根目录。这可能导致无法访问实际文件路径carvemeOut/。这是一个猜测,因为我不知道 {config[carveme_params][dir]} 是如何扩展的。

标签: python bioinformatics snakemake


【解决方案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 函数来生成可能的物种名称列表,并使用它来扩展规则 all 中的通配符,而不是使这个示例动态化。你确定你需要动态输出吗?

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

【讨论】:

  • 谢谢!是的,这成功了。我很确定我需要动态,因为我的管道会根据宏基因组数据生成集群,并且无法事先知道会生成多少集群!我知道 dyanamic() 有严格的限制,这是不幸的。你认为我可以避免以某种方式使用动态吗?你的意思是说我的管道中只能有一个动态通配符?还是您的意思是每条规则?
  • 每个管道只能有一个动态通配符。在你有 input: dynamic("carvemeOut/{species}.txt")output: dynamic("carvemeOut/{gem}.xml") 之前,这不会像你有 gemspecies 作为动态通配符一样工作。我很难回答是否可以避免使用动态,并且很大程度上取决于计算将生成多少个集群需要多长时间。
  • 实际上,我已经让我的管道使用两个动态通配符。唯一的限制似乎是我不能有两个动态通配符作为全部规则的输入。最简单的解决方法是在 rule all 之前创建一个伪规则,它将动态通配符之一作为输入,接触一个虚拟文件,并将其作为输入传递给 rule all。
  • 感谢您让我知道我已从答案中删除了不正确的部分。我错误地认为这适用于 Snakefile,但实际上是一个规则限制。由于我总是在目标规则中使用多个动态,因此我从未选择过这个警告。很高兴知道!
猜你喜欢
  • 1970-01-01
  • 2019-03-27
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 2011-10-17
相关资源
最近更新 更多