是否可以动态添加规则到 'localrules:'?

Is it possible to dynamically add rules to 'localrules:'?

这里给出的例子localrules: https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#local-rules 显示如何明确列出应在主机节点上执行的规则。

有没有办法在 运行 时添加规则,并根据工作流程的参数对它们进行调节?

例如看起来像下面的东西?

my_local_rules = ['rule1', 'rule_2']
if condition:
    my_local_rules.append('rule3')

localrules: my_local_rules

我已经尝试了以下方法,其中 运行 带有警告,表明 localrules 指令没有按照我的意愿执行。

local_rules_list = ['all']

if True:
   local_rules_list.append('test')

localrules: local_rules_list

rule all:
    input:
        # The first rule should define the default target files
        # Subsequent target rules can be specified below. They should start with all_*.
        "results/test.out"


rule test:
    input:
        "workflow/Snakefile"
    output:
        "results/test.out"
    shell:
        "cp {input} {output}"

具体来说,它失败并出现以下错误:

localrules directive specifies rules that are not present in the Snakefile:
    local_rules_list

我的具体用例是软件 Cell Ranger which has both a local mode and a cluster mode

在本地模式下,cellranger 命令作为计算节点上的作业提交。 在集群模式下,cellranger 命令应该在头节点上 运行,因为 cellranger 本身处理向计算节点提交的作业。

我希望我的工作流程让用户选择 运行 Cell Ranger 的模式(例如 localsge),因此,如果 mode: sge工作流会将 运行s cellranger 的规则添加到 localrules: ...。 这可能吗,或者只能在 Snakefile 中硬编码本地规则?

最好的, 凯文

谢谢

@Maarten-vd-Sande 评论中 中建议的 'hack' 对我来说很好。

在这个玩具示例中,我已按如下方式调整了建议的 hack。 即:

  • 规则 alllocalrules 指令中明确设置
  • 规则 test1 被添加到使用 hack 的本地规则集中,演示了虚拟条件的使用,正如我在问题中所说明的那样
  • 规则test2在这里作为阴性对照,在任何时候都不会添加到本地规则列表

# The main entry point of your workflow.
# After configuring, running snakemake -n in a clone of this repository should successfully execute a dry-run of the workflow.


report: "report/workflow.rst"

# Allow users to fix the underlying OS via singularity.
singularity: "docker://continuumio/miniconda3"

localrules: all

rule all:
    input:
        # The first rule should define the default target files
        # Subsequent target rules can be specified below. They should start with all_*.
        "results/test1.out",
        "results/test2.out"


rule test1:
    input:
        "workflow/Snakefile"
    output:
        "results/test1.out"
    shell:
        "cp {input} {output}"

      
rule test2:
    input:
        "workflow/Snakefile"
    output:
        "results/test2.out"
    shell:
        "cp {input} {output}"


include: "rules/common.smk"
include: "rules/other.smk"


# Conditionally add rules to the directive 'localrules'
_localrules = list(workflow._localrules) # get the local rules so far

if True: # set condition here
    _localrules.append('test1') # add rules as required

workflow._localrules = set(_localrules) # set the updated local rules

谢谢!