Python 在Snakemake中是否可以有一个可选的输出文件?

Python 在Snakemake中是否可以有一个可选的输出文件?,python,bioinformatics,snakemake,Python,Bioinformatics,Snakemake,我正在编写一个snakemake规则,它将处理对单端或成对端测序数据执行fastq修剪。如果数据是成对端,则应有两个输出文件,如果是单端,则应有一个输出文件 到目前为止,我编写的规则是有效的,但是,我不知道修剪的第二对是输出文件。这意味着snakemake没有检查该文件是否存在。它将输出,但不检查,是否可以有可选输出 input: #get the value in the fast1 column fastq_file = lambda wildcards: r

我正在编写一个snakemake规则,它将处理对单端或成对端测序数据执行fastq修剪。如果数据是成对端,则应有两个输出文件,如果是单端,则应有一个输出文件

到目前为止,我编写的规则是有效的,但是,我不知道修剪的第二对是输出文件。这意味着snakemake没有检查该文件是否存在。它将输出,但不检查,是否可以有可选输出

    input:
    #get the value in the fast1 column
        fastq_file = lambda wildcards: return_fastq(wildcards.fastq_name,wildcards.unit,first_pair = True)
    output:
        out_fastqc = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_trimmed.fastq.gz",
        fastpjson = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.json",
        fastphtml = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.html"
    params:
        fastp_parameters = return_parsed_extra_params(config['fastp_parameters']),
        fastq_file2 = lambda wildcards: return_fastq(wildcards.fastq_name,wildcards.unit,first_pair = False),
        out_fastqc2 = lambda wildcards: return_fastq2_name(wildcards.fastq_name,wildcards.unit),
        fastpjson = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.json",
        fastphtml = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.html"
    run:
        if config["end_type"] == "se":
            shell("{config[fastp_path]} -i {input.fastq_file} -o {output.out_fastqc} --json {output.fastpjson} --html {output.fastphtml} {params.fastp_parameters}")
        if config["end_type"] == "pe":
            shell("{config[fastp_path]} --in1 {input.fastq_file} --in2 {params.fastq_file2} --out1 {output.out_fastqc} --out2  {params.out_fastqc2} --json {output.fastpjson} --html {output.fastphtml} {params.fastp_parameters}")
目标是将out_fastqc2作为规则的可选输出包括在内,以便snakemake检查它是否存在,如果不存在,则适当地给我一个错误


如果Snakemake不允许可选输出,我可以分为两个规则,但这不是我想要的。

看看
expand
函数是如何工作的。它在Snakemake构造依赖项的DAG时被调用,并使用此函数的结果构造
输出
部分的文件列表

我建议您尝试同样的方法:构造一个空或不空的列表,这取决于条件

只有当您事先知道是否需要
out\u fastqc2
时,此解决方案才会起作用(但是,使用优先级定义两个规则也是如此)。如果您仅在运行规则时获得有关需要
out\u fastqc2
的信息,则需要检查点的情况完全不同

下面是说明我的方法的代码:
out\u fastqc2
成为描述文件的字符串(如果
end\u type
配置为
“pe”
),否则将成为一个空列表,不会更改输出列表

output:
    out_fastqc = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_trimmed.fastq.gz",
    out_fastqc2 = lambda wildcards: return_fastq2_name(wildcards.fastq_name,wildcards.unit) if config["end_type"] == "pe" else []

由于配对端和单端之间的选择在配置中似乎是固定的,因此您可以尝试根据配置以两种方式定义规则:

if config["end_type"] == "se":
    rule do_fastp:
        input:
        #get the value in the fast1 column
            fastq_file = lambda wildcards: return_fastq(wildcards.fastq_name, wildcards.unit, first_pair = True)
        output:
            out_fastqc = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_trimmed.fastq.gz",
            fastpjson = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.json",
            fastphtml = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.html"
        params:
            fastp_parameters = return_parsed_extra_params(config['fastp_parameters']),
        shell:
            """
            {config[fastp_path]} -i {input.fastq_file} -o {output.out_fastqc} \\
                --json {output.fastpjson} --html {output.fastphtml} \\
                {params.fastp_parameters}
            """
if config["end_type"] == "pe":
    rule do_fastp:
        input:
        #get the value in the fast1 column
            fastq_file1 = lambda wildcards: return_fastq(wildcards.fastq_name, wildcards.unit, first_pair = True),
            fastq_file2 = lambda wildcards: return_fastq(wildcards.fastq_name, wildcards.unit, first_pair = False)
        output:
            out_fastqc1 = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_trimmed_1.fastq.gz",
            out_fastqc2 = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_trimmed_2.fastq.gz",
            fastpjson = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.json",
            fastphtml = config["fastp_trimmed_output_folder"] + "{unit}/{fastq_name}_fastp.html"
        params:
            fastp_parameters = return_parsed_extra_params(config['fastp_parameters']),
        shell:
            """
            {config[fastp_path]} \\
                --in1 {input.fastq_file1} --in2 {params.fastq_file2} \\
                --out1 {output.out_fastqc1} --out2 {output.out_fastqc2} \\
                --json {output.fastpjson} --html {output.fastphtml} \\
                {params.fastp_parameters}
            """

可以根据
config[“end\u type”]
在规则之外构造输出。您能用代码解释一下您的实际意思吗?语言不清楚。您不能在snakemake的输出中使用函数。@Anna Leigh:我可以;)。不管怎样,看起来你的问题变得模棱两可了。您可以根据启动管道之前存在的条件(例如,基于配置中的设置),在输出节中指定可变数量的文件,但一旦文件添加到输出节中,就必须在规则中创建它。这是合乎逻辑的,只要其他规则可以等待该文件,并且在先决条件规则“成功”完成后,如果没有找到该文件,您会感到非常惊讶。@Anna Leigh,补充我之前的评论:有时您事先不知道文件数(即,它取决于规则生成的群集数)。在这种情况下,您可以使用动态输出(不推荐使用)或检查点。这需要Snakemake根据规则完成后产生的新信息重建DAG。关于Snakemake版本5.4.4。在输出中使用函数会导致语法错误,但是这可以通过以下方式解决:
out\u fastqc2=config[“fastp\u trimmed\u output\u folder”]+“{unit}/{fastq\u name}/{fastq\u trimmed.fastq.gz”if config[“end\u type”]==“pe”else[/code>这也解决了问题,但我希望有可选的输出,而不需要有两条规则,或者在这种情况下,相同规则的两个版本。