【问题标题】:Fastq parser not taking empty sequence (and other edge cases). PythonFastq 解析器不采用空序列(和其他边缘情况)。 Python
【发布时间】:2015-02-15 17:36:59
【问题描述】:

这是Generator not working to split string by particular identifier . Python 2 的延续。但是,我完全修改了代码,它根本不是相同的格式。这是关于边缘情况

Edge Cases:
 . when sequence length is different than number of quality values
 . when there's an empty sequence or entry
 . when the number of lines with quality values is more than one

我无法弄清楚如何处理上述边缘情况。如果它是一个空数据文件,那么我仍然想输出空字符串。我在这里为我的输入文件尝试使用这些序列:(只是一点背景,ID 在行首由 @ 设置,序列字符后面跟着行,直到到达带有 + 的行。下一行是会有质量值(值 ~= chr(char) )这种格式很糟糕而且考虑不周。

@m120204_092117_richard_c100250832550000001523001204251233_s1_p0/422/ccs
CTGTTGCGGATTGTTTGGCTATGGCTAAAACCGATGAAGAAAAAGGAAATGCCAAAACCGTTTATAGCGATTGATCCAAGAAATCCAAAATAAAAGGACACAAAACAAACAAAATCAATTGAGTAAAACAGAAAGGCCATCAAGCAAGCGAGTGCTTGATAACTTAGATGACCCTACTGATCAAGAGGCCATAGAGCAATGTTTAGAGGGCTTGAGCGATAGTGAAAGGGCGCTAATTCTAGGAATTCAAACGACAAGCTGATGAAGTGGATCTGATTTATAGCGATCTAAGAAACCGTAAAACCTTTGATAACATGGCGGCTAAAGGTTATCCGTTGTTACCAATGGATTTCAAAAATGGCGGCGATATTGCCACTATTAACCGCTACTAATGTTGATGCGGACAAATAGCTAGCAGATAATCCTATTTATGCTTCCATAGAGCCTGATATTACCAAGCATACGAAACAGAAAAAACCATTAAGGATAAGAATTTAGAAGCTAAATTGGCTAAGGCTTTAGGTGGCAATAAACAAATGACGATAAAGAAAAAAGTAAAAAACCCACAGCAGAAACTAAAGCAGAAAGCAATAAGATAGACAAAGATGTCGCAGAAACTGCCAAAAATATCAGCGAAATCGCTCTTAAGAACAAAAAAGAAAAGAGTGGGATTTTGTAGATGAAAATGGTAATCCCATTGATGATAAAAAGAAAGAAGAAAAACAAGATGAAACAAGCCCTGTCAAACAGGCCTTTATAGGCAAGAGTGATCCCACATTTGTTTTTAGCGCAATACACCCCCATTGAAATCACTCTGACTTCTAAAGTAGATGCCACTCTCACAGGTATAGTGAGTGGGGTTGTAGCCAAAGATGTATGGAACATGAACGGCACTATGATCTTATTAAGACAAACGGCCACTAAGGTGTATGGGAATTATCAAAGCGTGAAAGGTGGCCACGCCTATTATGACTCGTTTAATGATAGTCTTTACTAAAGCCATTACGCCTGATGGGGTGGTGATACCTCTAGCAAACGCTCAAGCAGCAGGCATGCTGGGTGAAGCAGGCGGTAGATGGCTATGTGAATAATCACTTCATGAAGCGTATAGGCTTTGCTGTGATAGCAAGCGTGGTTAATAGCTTCTTGCAAACTGCACCTATCATAGCTCTAGATAAACTCATAGGCCTTGGCAAAGGCAGAAGTGAAAGGACACCTGAATTTAATTACGCTTTGGGTCAAGCTATCAATGGTAGTATGCAAAGTTCAGCTCAGATGTCTAATCAAATTCTAGGGCAACTGATGAATATCCCCCAAGTTTTTACAAAAATGAGGGCGATAGTATTAAGATTCTCACCATGGACGATATTGATTTTAGTGGTGTGTATGATGTTAAAATTGACCAACAAATCTGTGGTAGATGAAATTATCAAACAAAGCACCAAAAACTTTGTCTAGAGAACATGAAGAAATCACCACAGCCCCAAAGGTGGCAATTGATTCAAGAGAAAGGATAAAATATATTCATGTTATTAAACTCGGTTCTTTACAAAATAAAAAGACAAACCAACCTAGGCTCTTCTAGAGGA
+
J(78=AEEC65HR+++*3327H00GD++++FF440.+-64444426ABAB<:=7888((/788P>>LAA8*+')3&++=<////==<4&<>EFHGGIJ66P;;;9;;FE34KHKHP<<11;HK:57678NJ990((&26>PDDJE,,JL>=@@88,8,+>::J88ELF9.-5.45G+@@@NP==??<>455F((<BB===;;EE;3><<;M=>89PLLPP?>KP8+7699>A;ANO===J@'''B;.(...HP?E@@AHGE77MNOO9=OO?>98?DLIMPOG>;=PRKB5H---3;MN&&&&&F?B>;99;8AA53)A<=;>777:<>;;8:LM==))6:@K..M?6?::7,/4444=JK>>HNN=//16@--F@K;9<:6449@BADD;>CD11JE55K;;;=&&%%,3644DL&=:<877..3>344:>>?44*+MN66PG==:;;?0./AGLKF99&&5?>+++JOP333333AC@EBBFBCJ>>HINPMNNCC>>++6:??3344>B=<89:/000::K>A=00@,+-/.,#(LL@>@I555K22221115666666477KML559-,333?GGGKCCP:::PPNPPNP??PPPLLMNOKKFOP2Q&&P7777PM<<<=<6<HPOPPP44?=@=:?BB=89:<<DHI777777645545PPO((((((((C3P??PM0000@NOPJPPFGGL<<<NNGNKGGGGGEELKB'''(((((L===L<<..*--MJ111?PO=788<8GG>>?JJL88,,1CF))??=?M6667PPKAKM&&&&&<?P43?OENPP''''&5579ICIFRPPPPOP>:>>>P888PLPAJDPCCDMMD;9=FBADDJFD7;ALL?,,,,06ID13..000DA4CFJC44,,->ED99;44CJK?42FAB?=CLNO''PJI999&77&&ERP><)))O==D677FP768PA=@@HEE.::NM&&&>O''PO88H@A999P<:?IHL;;;GIIPPMMPPB7777PP>>>>KOPIIEEE<<CL%%5656AAAG<<DDFFGG%%N21778;M&&>>CCL::LKK6.711DGHHMIA@BAJ7>%6700;;=@@?=;J55>>QP<<:>MF;;RPL==JMMPPPQR@@P===;=BM99M>>PPOQGD44777PKKFP=<'''2215566>CG>>HH<<PLJI800CE<<PPPMGNOPMJ>>GG***LCCC777,,@AP>>AOPMFN99ENNMEPP>>>>>>CLPP??66OOKLLP=:>>KMBCPOPP@FKEI<<ML?>EAF>>>LDCD77JK=H>BN==:=<<<:==JN,,,659???8K<:==<4))))))P98>>>>;967777N66@@@AMKKKIKPMG;;AD88HN&&LMIGJOJMGHPC>@5D((((C?9--?8HGCDPNH7?9974;;AC&ABH''#%:=NP:,,9999=GJG>>=>JG21''':9>>>;;MP*****OKKKIE??55PPKJ21:K---///Q11//EN&';;;;:=;00011;IP@@PP11?778JDDMM>>::KKLLKLNONOHDMPKLMIB>>?JP>9;KJL====;8;;;L)))))E@=$$$#.::,,BPJK76B;;F5<<J::K
@m120204_092117_richard_c100250832550000001523001204251233_s1_p0/904/ccs
CTCTCTCATCACACACGAGGAGTGAAGAGAGAACCTCCTCTCCACACGTGGAGTGAGGAGATCCTCTCACACACGTGAGGTGTTGAGAGAGATACTCTCTCATCACCTCACGTGAGGAGTGAGAGAGAT
+
{~~~~~sXNL>>||~~fVM~jtu~&&(uxy~f8YHh=<gA5
''<O1A44N'`oK57(((G&&Q*Q66;"$$Df66E~Z\ZMO>^;%L}~~~~~Q.~~~~x~@-LF9>~MMqbV~ABBV=99mhIwGRR~
@different_number_of_seq_qual
ATCG
+
**!
@this_should_work
GGGG
+
****

有错误的,我正在尝试用空字符串替换 seq 和 qual 字符串

seq,qual = '',''

到目前为止,这是我的代码。这些边缘情况对我来说很难弄清楚,请帮忙。 . .

def read_fastq(input, offset):
    """
    Inputs a fastq file and reads each line at a time.  'offset' parameter can be set to 33 (phred+33 encoding 
    fastq), and 64.  Yields a tuple in the format (ID, comments for a sequence, sequence, [integer quality values])
    Capable of reading empty sequences and empty files. 
    """

    ID, comment, seq, qual = None,'','',''

    step = 1 #step is a variable that organizes the order fastq parsing
    #step= 1 scans for ID and comment line
    #step= 2 adds relevant lines to sequence string
    #step= 3 adds quality values to string
    for line in input:
        line = line.strip()
        if step == 1 and line.startswith('@'): #Step system from Nedda Saremi
            if ID is not None: 
                qual = [ord(char)-offset for char in qual] #Converts from phred encoding to integer values
                sep = None
                if ' ' in ID: sep = ' '
                if sep is not None: 
                    ID, comment =  ID.split(sep,1) #Separates ID and comment by  ' '

                yield ID, comment, seq, qual
                ID,comment,seq,qual = None,'','','' #Resets variable for next sequence
            ID = line[1:]
            step = 2
            continue
        if step==2 and not line.startswith('@') and not line.startswith('+'):
            seq = seq + line.strip()
            continue
        if step == 2 and line.startswith('+'):
            step = 3
            continue
        while step == 3: 
        #process the quality data
            if len(qual) == len(seq):
            #once the length of the quality seq and seq are the same, end gathering data
                step = 1
                continue
            if len(qual) < len(seq):
                qual = qual + line.strip()
                if len(qual) < len(seq): 
                    step = 3
                    continue
                if (len(qual) > len(seq)): 
                    sys.stderr.write('\nError: ' + ID + ' sequence length not equal to quality values\n')
                    comment,seq,qual= '','',''
                    ID = line
                    step = 1
                    continue
            break

    if ID is not None:
        #Section reserved for last entry in file
        if len(qual) > 0: 
            qual = [ord(char)-offset for char in qual]
        sep = None
        if ' ' in ID: sep = ' '
        if sep is not None: 
            ID, comment =  ID.split(sep,1)
        if len(seq) == 0: ID,comment,seq,qual= '','','',''
        yield ID, comment, seq, qual       

我的输出跳过了 ID @m120204_092117_richard_c100250832550000001523001204251233_s1_p0/904/ccs 并添加了@**!当它不应该在输出中时

@m120204_092117_richard_c100250832550000001523001204251233_s1_p0/422/ccs
CTGTTGCGGATTGTTTGGCTATGGCTAAAACCGATGAAGAAAAAGGAAATGCCAAAACCGTTTATAGCGATTGATCCAAGAAATCCAAAATAAAAGGACACAAAACAAACAAAATCAATTGAGTAAAACAGAAAGGCCATCAAGCAAGCGAGTGCTTGATAACTTAGATGACCCTACTGATCAAGAGGCCATAGAGCAATGTTTAGAGGGCTTGAGCGATAGTGAAAGGGCGCTAATTCTAGGAATTCAAACGACAAGCTGATGAAGTGGATCTGATTTATAGCGATCTAAGAAACCGTAAAACCTTTGATAACATGGCGGCTAAAGGTTATCCGTTGTTACCAATGGATTTCAAAAATGGCGGCGATATTGCCACTATTAACCGCTACTAATGTTGATGCGGACAAATAGCTAGCAGATAATCCTATTTATGCTTCCATAGAGCCTGATATTACCAAGCATACGAAACAGAAAAAACCATTAAGGATAAGAATTTAGAAGCTAAATTGGCTAAGGCTTTAGGTGGCAATAAACAAATGACGATAAAGAAAAAAGTAAAAAACCCACAGCAGAAACTAAAGCAGAAAGCAATAAGATAGACAAAGATGTCGCAGAAACTGCCAAAAATATCAGCGAAATCGCTCTTAAGAACAAAAAAGAAAAGAGTGGGATTTTGTAGATGAAAATGGTAATCCCATTGATGATAAAAAGAAAGAAGAAAAACAAGATGAAACAAGCCCTGTCAAACAGGCCTTTATAGGCAAGAGTGATCCCACATTTGTTTTTAGCGCAATACACCCCCATTGAAATCACTCTGACTTCTAAAGTAGATGCCACTCTCACAGGTATAGTGAGTGGGGTTGTAGCCAAAGATGTATGGAACATGAACGGCACTATGATCTTATTAAGACAAACGGCCACTAAGGTGTATGGGAATTATCAAAGCGTGAAAGGTGGCCACGCCTATTATGACTCGTTTAATGATAGTCTTTACTAAAGCCATTACGCCTGATGGGGTGGTGATACCTCTAGCAAACGCTCAAGCAGCAGGCATGCTGGGTGAAGCAGGCGGTAGATGGCTATGTGAATAATCACTTCATGAAGCGTATAGGCTTTGCTGTGATAGCAAGCGTGGTTAATAGCTTCTTGCAAACTGCACCTATCATAGCTCTAGATAAACTCATAGGCCTTGGCAAAGGCAGAAGTGAAAGGACACCTGAATTTAATTACGCTTTGGGTCAAGCTATCAATGGTAGTATGCAAAGTTCAGCTCAGATGTCTAATCAAATTCTAGGGCAACTGATGAATATCCCCCAAGTTTTTACAAAAATGAGGGCGATAGTATTAAGATTCTCACCATGGACGATATTGATTTTAGTGGTGTGTATGATGTTAAAATTGACCAACAAATCTGTGGTAGATGAAATTATCAAACAAAGCACCAAAAACTTTGTCTAGAGAACATGAAGAAATCACCACAGCCCCAAAGGTGGCAATTGATTCAAGAGAAAGGATAAAATATATTCATGTTATTAAACTCGGTTCTTTACAAAATAAAAAGACAAACCAACCTAGGCTCTTCTAGAGGA
+
J(78=AEEC65HR+++*3327H00GD++++FF440.+-64444426ABAB<:=7888((/788P>>LAA8*+')3&++=<////==<4&<>EFHGGIJ66P;;;9;;FE34KHKHP<<11;HK:57678NJ990((&26>PDDJE,,JL>=@@88,8,+>::J88ELF9.-5.45G+@@@NP==??<>455F((<BB===;;EE;3><<;M=>89PLLPP?>KP8+7699>A;ANO===J@'''B;.(...HP?E@@AHGE77MNOO9=OO?>98?DLIMPOG>;=PRKB5H---3;MN&&&&&F?B>;99;8AA53)A<=;>777:<>;;8:LM==))6:@K..M?6?::7,/4444=JK>>HNN=//16@--F@K;9<:6449@BADD;>CD11JE55K;;;=&&%%,3644DL&=:<877..3>344:>>?44*+MN66PG==:;;?0./AGLKF99&&5?>+++JOP333333AC@EBBFBCJ>>HINPMNNCC>>++6:??3344>B=<89:/000::K>A=00@,+-/.,#(LL@>@I555K22221115666666477KML559-,333?GGGKCCP:::PPNPPNP??PPPLLMNOKKFOP2Q&&P7777PM<<<=<6<HPOPPP44?=@=:?BB=89:<<DHI777777645545PPO((((((((C3P??PM0000@NOPJPPFGGL<<<NNGNKGGGGGEELKB'''(((((L===L<<..*--MJ111?PO=788<8GG>>?JJL88,,1CF))??=?M6667PPKAKM&&&&&<?P43?OENPP''''&5579ICIFRPPPPOP>:>>>P888PLPAJDPCCDMMD;9=FBADDJFD7;ALL?,,,,06ID13..000DA4CFJC44,,->ED99;44CJK?42FAB?=CLNO''PJI999&77&&ERP><)))O==D677FP768PA=@@HEE.::NM&&&>O''PO88H@A999P<:?IHL;;;GIIPPMMPPB7777PP>>>>KOPIIEEE<<CL%%5656AAAG<<DDFFGG%%N21778;M&&>>CCL::LKK6.711DGHHMIA@BAJ7>%6700;;=@@?=;J55>>QP<<:>MF;;RPL==JMMPPPQR@@P===;=BM99M>>PPOQGD44777PKKFP=<'''2215566>CG>>HH<<PLJI800CE<<PPPMGNOPMJ>>GG***LCCC777,,@AP>>AOPMFN99ENNMEPP>>>>>>CLPP??66OOKLLP=:>>KMBCPOPP@FKEI<<ML?>EAF>>>LDCD77JK=H>BN==:=<<<:==JN,,,659???8K<:==<4))))))P98>>>>;967777N66@@@AMKKKIKPMG;;AD88HN&&LMIGJOJMGHPC>@5D((((C?9--?8HGCDPNH7?9974;;AC&ABH''#%:=NP:,,9999=GJG>>=>JG21''':9>>>;;MP*****OKKKIE??55PPKJ21:K---///Q11//EN&';;;;:=;00011;IP@@PP11?778JDDMM>>::KKLLKLNONOHDMPKLMIB>>?JP>9;KJL====;8;;;L)))))E@=$$$#.::,,BPJK76B;;F5<<J::K

Error: different_number_of_seq_qual sequence length not equal to quality values
@**!

+

@this_should_work
GGGG
+
****

【问题讨论】:

  • 我对这种处理的需要感到困惑。正确的 fastq 文件将没有您描述的三种边缘情况。根据定义,序列和质量分数的长度相等,每个序列/质量分数只有一行。因此,每个读数应以 4 行表示。此外,根本不应该存在没有序列的读取。如果您要清理旧数据或质量差的数据,那么这样的脚本会很有用,但我建议您首先考虑获取质量更好的数据。

标签: python parsing generator bioinformatics string


【解决方案1】:

您可能应该使用 BioPython。

您的错误似乎是被跳过的读取在其序列中有 129 个碱基,但只有 128 个 qv。因此,您的解析器将下一个 defline 读取为质量行,然后使其太长,因此打印错误。

那么你的州没有考虑到你在step 1 中的情况,但没有看到延迟。因此,您继续阅读覆盖ID 变量的额外行。

但如果你真的想编写自己的解析器:

我会一次解决一个问题。

当序列长度不同于质量值的数量时

这是无效的。 fastq 文件中的每条记录必须具有相同数量的碱基和质量。文件中的不同记录可以有不同的长度,但每条记录必须具有相同的基数和质量。

当有一个空序列或条目时 一个空的 read 将有如下的序列和质量行的空白行:

@SOLEXA1_0007:1:9:610:1983#GATCAG/2

+SOLEXA1_0007:1:9:610:1983#GATCAG/2

@SOLEXA1_0007:2:13:163:254#GATCAG/2
CGTAGTACGATATACGCGCGTGTACTGCTACGTCTCACTTTCGCAAGATTGCTCAGCTCATTGATGCTCAATGCTGGGCCATATCTCTTTTCTTTTTTTC
+SOLEXA1_0007:2:13:163:254#GATCAG/2
HHHHGHHEHHHHHE=HAHCEGEGHAG>CHH>EG5@>5*ECE+>AEEECGG72B&A*)569B+03B72>5.A>+*A>E+7A@G<CAD?@############

当有质量值的行数多于一个时

由于上述第一个答案的要求。我们知道碱基的数量和质量必须匹配。此外,序列块中永远不会有+ 字符。所以我们可以继续解析序列块,直到我们看到以+ 开头的行。然后我们知道我们已经完成了序列的解析。然后我们可以继续解析质量行,直到我们得到与序列中相同数量的质量。我们不能依赖寻找任何特殊字符,因为根据质量编码,@ 可能是有效的质量调用。

顺便说一句,您似乎正在拆分序列定义以解析出可选注释。您必须小心带有空格的 CASAVA 1.8 格式。因此,您可能需要一个正则表达式来查看它是否是 CASAVA 1.8 格式,然后不要拆分空格等。

【讨论】:

    【解决方案2】:

    您是否考虑过使用可用于处理此类数据的强大 python 包之一,而不是从头开始编写解析器?特别是我建议查看HTSeq

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多