Python snakemake使用脚本实现shell I/O重定向和访问snakemake变量

Python snakemake使用脚本实现shell I/O重定向和访问snakemake变量,python,snakemake,Python,Snakemake,问题很简单: 我想从规则中调用脚本,我希望该规则同时适用于以下两种情况: 执行stdout和stderr重定向 从脚本访问snakemake变量(变量可以是列表和文本) 如果使用shell:,则可以执行I/O重定向,但不能在脚本中使用snakemake变量 注意:当然可以从shell将变量作为参数传递给脚本。但是,通过这样做,脚本无法区分文本和列表变量。 如果改用script:,则可以访问snakemake变量,但无法执行I/O重定向和许多其他shell功能 举例说明问题: 1) 使用s

问题很简单:
我想从规则中调用脚本,我希望该规则同时适用于以下两种情况:

  • 执行stdout和stderr重定向
  • 从脚本访问snakemake变量(变量可以是列表和文本)
如果使用
shell:
,则可以执行I/O重定向,但不能在脚本中使用
snakemake
变量
注意:当然可以从shell将变量作为参数传递给脚本。但是,通过这样做,脚本无法区分文本和列表变量。
如果改用
script:
,则可以访问snakemake变量,但无法执行I/O重定向和许多其他shell功能


举例说明问题:
1) 使用
shell:

rule create_hdf5:
    input:
        genes_file = OUTPUT_PATH+'/{sample}/outs/genes.tsv'
    params:
        # frequencies is a list!!!
        frequencies = config['X_var']['freqs']
    output:
        HDF5_OUTPUT+'/{sample}.h5'
    log:
        out = LOG_FILES+'/create_hdf5/sample_{sample}.out',
        err = LOG_FILES+'/create_hdf5/sample_{sample}.err'
    shell:
        'python scripts/create_hdf5.py {input.genes_file} {params.frequencies} {output} {threads} 2> {log.err} 1> {log.out} '
问题1):自然,python脚本认为频率列表中的每个元素都是一个新参数。但是,脚本无法访问
snakemake
变量

2) 使用
脚本:

rule create_hdf5:
    input:
        genes_file = OUTPUT_PATH+'/{sample}/outs/genes.tsv'
    params:
        # frequencies is a list!!!
        frequencies = config['X_var']['freqs']
    output:
        HDF5_OUTPUT+'/{sample}.h5'
    log:
        out = LOG_FILES+'/create_hdf5/sample_{sample}.out',
        err = LOG_FILES+'/create_hdf5/sample_{sample}.err'
    script:
        'scripts/create_hdf5.py'
问题2):我可以访问脚本中的snakemake变量。但是现在我不能使用bash工具,比如I/O重定向

我想知道是否有办法实现这两个目标(也许我在snakemake文档中遗漏了一些东西)?
提前谢谢

如果可能,我建议您使用模块来解析脚本的输入,这样它就可以使用
nargs=“*”
选项解析参数列表:

def main():
“”“程序的主要功能。”“”
parser=argparse.ArgumentParser(
description=\uuuuuu doc\uuuuuuuuuu,
格式化程序(class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_参数(
“-g”、“--genes_文件”,
必需=真,
help=“包含基因的文件的路径。”)
parser.add_参数(
“-o”、“--output_文件”,
必需=真,
help=“输出文件的路径。”)
parser.add_参数(
“-f”、“--频率”,
nargs=“*”,
help=“频率间隔列表。”)
parser.add_参数(
“-t”、“--threads”,
类型=int,
默认值=1,
help=“要使用的线程数。”)
args=parser.parse_args()
#然后使用args.gene_文件作为文件名,使用args.frequencies作为列表,等等。
你可以这样称呼它:

shell:
"""
python脚本/create_hdf5.py\\
-g{input.genes_file}-f{params.frequencies}\\
-o{output}-t{threads}2>{log.err}1>{log.out}
"""

您可以使用snakemake.log varaibale访问python脚本中的日志文件名,该列表包含两个文件名:

snakemake.log = [ LOG_FILES+'/create_hdf5/sample_1.out', LOG_FILES+'/create_hdf5/sample_1.err' ]
因此,您可以在脚本中使用它来创建日志文件,例如

import logging
mylogger = logging.getLogger('My logger')
# create file handler
fh = logging.FileHandler(snakemake.log[0])
mylogger.addHandler(fh)
mylogger.error("Some error")

我可以将列表序列化为JSON,然后将其作为参数传递给脚本,并在脚本中反序列化。有没有比这更优雅的方法呢?是的,使用argparse是一个很好的实践。谢谢你的回答,我正在以这种方式修改我的所有脚本。同时,我注意到argparse还有一个R实现: