是否可以在 Snakemake 中有一个可选的输出文件?
Is it possible to have an optional output file in Snakemake?
我正在编写一个 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 阶段被调用,它使用这个函数的结果来构建 output
部分的文件列表。
我建议您尝试相同的方法:构造一个空或空的列表 - 取决于条件。
只有当您事先知道是否需要 out_fastqc2
时,此解决方案才有效(但是定义 2 个具有优先级的规则也是如此)。如果您仅在 运行 规则时获得有关 out_fastqc2
需求的信息,那么您需要检查点的情况就完全不同了。
下面是说明我的方法的代码:out_fastqc2
变成描述文件的字符串(如果 end_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 []
由于 paired-end 和 single-end 之间的选择似乎在配置中是固定的,您可以尝试根据配置以两种方式定义规则:
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}
"""
我正在编写一个 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 阶段被调用,它使用这个函数的结果来构建 output
部分的文件列表。
我建议您尝试相同的方法:构造一个空或空的列表 - 取决于条件。
只有当您事先知道是否需要 out_fastqc2
时,此解决方案才有效(但是定义 2 个具有优先级的规则也是如此)。如果您仅在 运行 规则时获得有关 out_fastqc2
需求的信息,那么您需要检查点的情况就完全不同了。
下面是说明我的方法的代码:out_fastqc2
变成描述文件的字符串(如果 end_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 []
由于 paired-end 和 single-end 之间的选择似乎在配置中是固定的,您可以尝试根据配置以两种方式定义规则:
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}
"""