如何在Snakemake规则params中调用Python函数提取Fastq lane信息?
解决方案:Snakemake中为GATK传递Fastq Lane信息到-PU参数
以下是两种可靠的实现方式,解决你无法将Fastq路径传入自定义函数的问题,或提供更高效的替代方案:
1. 正确使用自定义Python函数传递参数
如果偏好用Python处理提取逻辑,需确保函数在延迟计算的上下文里调用,避免在rule初始化时传入未解析的参数路径。
步骤1:编写提取函数
def extract_lane_info(fastq_path): # 根据实际Fastq命名规则或文件头格式修改提取逻辑 # 示例1:从文件名提取(如Sample_L001_R1.fastq.gz) import os filename = os.path.basename(fastq_path) lane = filename.split("_")[1] # 截取L001部分 # 示例2:从Fastq文件头提取(Illumina标准格式:@FCID:LANE:TILE:X:Y:UMI:QUALITY) # import gzip # with gzip.open(fastq_path, 'rt') if fastq_path.endswith('.gz') else open(fastq_path, 'r') as f: # first_header = f.readline().strip() # lane = first_header.split(":")[1] return lane
步骤2:在Rule中通过Lambda延迟调用函数
利用Snakemake的lambda表达式,在规则执行时传入实际的input文件路径:
rule AddOrReplaceReadGroups: input: bam="aligned/{sample}.bam", r1="fastq/{sample}_L{lane}_R1.fastq.gz" # 此处r1为实际Fastq路径 output: "rg_added/{sample}.bam" params: # 通过lambda获取input中的r1路径,传递给提取函数 pu=lambda wildcards, input: extract_lane_info(input.r1) shell: """ gatk AddOrReplaceReadGroups \ -I {input.bam} \ -O {output} \ -PU {params.pu} \ -RGID {wildcards.sample} \ -RGLB lib1 \ -RGPL illumina \ -RGSM {wildcards.sample} """
2. 直接在Shell中提取(更高效)
若提取逻辑简单,无需编写Python函数,直接在shell命令中处理Fastq路径或文件头,避免函数调用的上下文问题:
rule AddOrReplaceReadGroups: input: bam="aligned/{sample}.bam", r1="fastq/{sample}_L{lane}_R1.fastq.gz" output: "rg_added/{sample}.bam" shell: """ # 方式1:从文件名提取lane(适配Sample_L001_R1.fastq.gz格式) LANE=$(basename {input.r1} | cut -d'_' -f2) # 方式2:从压缩Fastq的文件头提取(Illumina格式) # LANE=$(zcat {input.r1} | head -n1 | cut -d':' -f1) gatk AddOrReplaceReadGroups \ -I {input.bam} \ -O {output} \ -PU $LANE \ -RGID {wildcards.sample} \ -RGLB lib1 \ -RGPL illumina \ -RGSM {wildcards.sample} """
常见错误原因
你之前的报错大概率是因为:
- 直接在rule的params中调用
extract_lane_info(params.PathToReadR1),此时params.PathToReadR1尚未被解析为实际文件路径(Snakemake在初始化rule时不会填充动态参数) - 未通过lambda或其他延迟计算方式传递实际的input/wildcards变量
内容的提问来源于stack exchange,提问作者Ari Miller
相关产品推荐
相关产品推荐

