使用snakemake设置日志文件id的函数

问题描述 投票:0回答:2

我想使用一个函数来轻松设置输出日志文件名。

我尝试了以下功能

# output_path=simulations/sim1/model/test.out
# idx=2   == add <x> after 2nd element
# x=logs
# returns= simulations/sim1/logs/model/test.out
def get_xpath(wildcards,x,idx):
  outbase=wildcards.output[0]
  return str('/'.join(outbase.split('/')[:idx])+"/"+x+"/"+'/'.join(outbase.split('/')[idx:]))

rule testme:
...
  log: lambda wildcards: get_xpath(wildcards,"logs",2),

但它给出了以下 AttributeError

'function' object has no attribute 'get_wildcard_names'

我也尝试过使用 lambda:

rule testme:
...
  log: lambda wildcards, output: output[0].split('.')[0],

这给出了同样的错误。我在 Snakemake 文档中找不到任何实现此目的的示例,所以我不确定这是否可能。有什么想法吗?

谢谢!

python snakemake
2个回答
1
投票

这只是一个 hack,但一种方法是将其放入

params
指令中。好处是如果规则失败,这条不会被删除:

rule abc:
    params: log = lambda wildcards: get_xpath(wildcards,"logs",2),
    ...

当然,可执行文件(shell/run/script)内的引用必须调整为

params.log
而不是
log


0
投票

这是一个解决方法。

如果不手动复制,您仍然无法获取输出文件名,但您可以使用一个函数,通过使用规则名称作为变量来更轻松地命名日志文件。可以通过使用某些通配符或提供输出文件名的硬拷贝来改进它。尽管将规则名称设置为变量会限制某些功能,例如通过名称直接调用规则。

def logfile(rule_name,wildcards=None,output=None):
    return f"{config['dataset_id']}/logs/{rule_name}.log"

ruleid="get_fasta_per_locus"
rule ruleid:
    input:
    output:
    log:
        lambda wildcards: logfile(ruleid)

2024年更新

我目前的解决方法:

def get_output_log(wildcards, output):
        out=output[0].split('/')
        if len(out) < 4:
                raise ValueError("Output path must have at least 4 components")
        out.insert(2, "logs")
        # create the directory if it does not exist
        out = [x.format(**wildcards) for x in out]
        os.makedirs('/'.join(out[:-1]), exist_ok=True)
        return '/'.join(out)

用途:

rule xx:
    input: ...
    output: ...
    params:
        log=lambda wildcards, output: get_output_log(wildcards, output),
    shell:
        """
        command &> {params.log}
        """
© www.soinside.com 2019 - 2024. All rights reserved.