gpt4 book ai didi

python - 优雅地处理可变数量的输入和输出文件

转载 作者:行者123 更新时间:2023-12-04 07:23:47 25 4
gpt4 key购买 nike

您有一个管道,其中一些样本有一个输入文件并生成一个输出文件,而其他样本有两个输入文件并生成两个输出文件。生物信息学领域的典型案例是 NGS 测序文库,其中一些样本是双端测序,其他样本是单端测序。如果您需要修剪读取并对齐它们,您必须考虑输入/输出文件的可变数量。
处理这个问题的最合适的方法是什么?我觉得使用检查点是矫枉过正,因为在我看来检查点有点神秘,但我可能是错的......
对于文件的输入/输出数量只能为 1 或 2 的情况,我会这样做:有一个 if-elserun指令首先基于输入文件的数量。如果输入数为 1,则触摸第二个文件。对于以下规则再次有 if-else这次检查第二个文件是否有0字节。
这是一个示例(未经测试,但应该是正确的):

import os

samples = {'S1': ['s1.R1.fastq'],
'S2': ['s2.R1.fastq', 's2.R2.fastq']}

rule all:
input:
expand('bam/{sample_id}.bam', sample_id= samples),

rule cutadapt:
input:
fastq= lambda wc: samples[wc.sample_id],
output:
r1= 'cutadapt/{sample_id}.R1.fastq',
r2= touch('cutadapt/{sample_id}.R2.fastq'),
run:
if len(input.fastq) == 1:
# {output.r1} created, {output.r2} touched
shell('cutadapt ... -o {output.r1} {input.fastq}')
else:
shell('cutadapt ... -o {output.r1} -p {output.r2} {input.fastq}')

rule align:
input:
r1= 'cutadapt/{sample_id}.R1.fastq',
r2= 'cutadapt/{sample_id}.R2.fastq',
output:
'bam/{sample_id}.bam',
run:
if os.path.getsize(input.r2) == 0:
# or
# if len(samples[wildcards.sample_id]) == 1:
shell('hisat2 ... {input.r1} > {output.bam}')
else:
shell('hisat2 ... -1 {input.r1} -2 {input.r2} > {output.bam}')
这有效,但我发现人为地创建第二个文件只是为了让工作流程保持愉快是很尴尬的。有更好的解决方案吗?

最佳答案

对于单端和双端情况,应有两个单独的规则:

rule single_end:
input:
fastq = 's{n}.R1.fastq'
output:
r1 = 'cutadapt/S{n}.R1.fastq'
shell:
'cutadapt ... -o {output.r1} {input.fastq}'

rule pair_ends:
input:
r1 = 's{n}.R1.fastq',
r2 = 's{n}.R2.fastq'
output:
r1 = 'cutadapt/S{n}.R1.fastq',
r2 = 'cutadapt/S{n}.R2.fastq'
shell:
'cutadapt ... -o {output.r1} -p {output.r2} {input}'
现在有一个歧义:每当 pair_ends可以申请, single_end也可以申请。这个问题可以用可以解决 ruleorder :
ruleorder pair_ends > single_end

关于python - 优雅地处理可变数量的输入和输出文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68337750/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com