Snakemake是否支持可选输出文件?单双端测序修剪场景需求
解决Snakemake规则中双端测序修剪输出的追踪问题
你的核心问题是要让双端模式下的第二个修剪文件被Snakemake正确追踪,同时保持单条规则兼容单端/双端数据,不用拆分成两条规则。其实Snakemake支持动态条件输出,完全可以实现你的需求,不需要拆分规则。
解决方案:使用动态命名输出
我们可以定义一个函数来根据配置的end_type动态生成规则的输出文件列表,这样Snakemake会自动在双端模式下追踪第二个输出文件,单端模式下则忽略它。
修改后的完整规则代码如下:
# 先定义一个生成输出的辅助函数 def get_fastp_outputs(wildcards): # 基础输出(单端和双端都需要的文件) outputs = { "out_fastqc": config["fastp_trimmed_output_folder"] + f"{wildcards.unit}/{wildcards.fastq_name}_trimmed.fastq.gz", "fastpjson": config["fastp_trimmed_output_folder"] + f"{wildcards.unit}/{wildcards.fastq_name}_fastp.json", "fastphtml": config["fastp_trimmed_output_folder"] + f"{wildcards.unit}/{wildcards.fastq_name}_fastp.html" } # 如果是双端模式,添加第二个修剪文件到输出 if config["end_type"] == "pe": outputs["out_fastqc2"] = return_fastq2_name(wildcards.fastq_name, wildcards.unit) return outputs rule trim_fastq: input: fastq_file = lambda wildcards: return_fastq(wildcards.fastq_name, wildcards.unit, first_pair=True) output: get_fastp_outputs # 引用上面的动态输出函数 params: fastp_parameters = return_parsed_extra_params(config['fastp_parameters']), fastq_file2 = lambda wildcards: return_fastq(wildcards.fastq_name, wildcards.unit, first_pair=False) 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}") else: # 双端模式 shell("{config[fastp_path]} --in1 {input.fastq_file} --in2 {params.fastq_file2} --out1 {output.out_fastqc} --out2 {output.out_fastqc2} --json {output.fastpjson} --html {output.fastphtml} {params.fastp_parameters}")
关键修改说明
- 动态输出函数:
get_fastp_outputs会根据全局配置的end_type决定是否添加out_fastqc2到输出列表。Snakemake会自动识别这个动态生成的输出集合,在双端模式下检查out_fastqc2的存在性,缺失时会触发规则重新运行或报错。 - 移除冗余参数:把原来
params里的out_fastqc2、fastpjson、fastphtml都删掉了——这些本来就是输出文件,没必要放在params里,直接从output引用更规范。 - 清晰的命名输出:用字典形式的命名输出,在
run块里可以通过output.out_fastqc、output.out_fastqc2这种直观的方式引用文件,比索引更易读。
扩展:如果样本级别的单/双端不同
如果你的项目里有些样本是单端、有些是双端(不是全局统一的end_type),只需要修改get_fastp_outputs的判断逻辑即可,比如从配置文件里读取每个样本的end_type:
def get_fastp_outputs(wildcards): outputs = { # 基础输出... } # 假设config里有samples字典,每个样本对应end_type if config["samples"][wildcards.fastq_name]["end_type"] == "pe": outputs["out_fastqc2"] = return_fastq2_name(wildcards.fastq_name, wildcards.unit) return outputs
这种方案既保持了单条规则的简洁性,又让Snakemake正确追踪所有必要的输出文件,完美解决你的问题。
内容的提问来源于stack exchange,提问作者Al Bro
相关产品推荐
相关产品推荐

