查询需要根据前面建立的索引来做。 
这是一个比较复杂的过程,我也是看了bowtie的作者的ppt才慢慢弄懂的,感觉自己也不可能三言两语就说清楚,一般都是辅助图片,动画,再经过多方交流才能慢慢理解。 所以大家呢,就自己去看ppt,看懂那个查询算法。(ppt及代码在我的群里面有共享,欢迎大家加群交流) 这里我简单讲讲我的程序 首先读取索引文件,统计好A,C,G,T的总数 然后把查询序列从最后一个字符往前面回溯。 我创建了一个子函数,专门来处理回溯的问题 每次接受四个参数(左右两端的碱基,上下的阈值),并返回两个参数(新的上下两个阈值) 
大家要看懂阈值是如何更新迭代,这样动态的一个个回溯字符串,一个个迭代阈值。 直到四种临界情况的出现。 
第一是上下阈值已经相等了,但是我们还没有回溯完全,那就说明字符串只能查找后几个字符,前面还有字符是无法匹配的 第二种情况是上下阈值已经相等了,正巧我们也回溯到了最后一个字符串,那么我们就找到了精确匹配。 第三种情况是已经进行到了最后一个字符串,但是上下阈值还有差值,那么就找到了多个精确匹配点。 最后一种情况是各种非法字符。 然后我简单的测序了一下在病毒的5K基因组里面的精确匹配情况,好像效果还挺好的 
但是在酵母里面还有一个问题没有解决,就是取前二十个字符串排序的问题,不够精确,需要重新审视排序结果进行局部优化,可能是需要用堆排序发,具体我还得考虑一个星期,只能等下周上课再看看了,平时太忙了,基本没时间码代码。 这里贴上我的代码给大家看看, 1 | $a = 'CGCTATGTACTGGATGCGCTGGCAAACGAGCCTGCCGTAAG' ; |
9 | $hash_count_atcg { $F [0]}++; |
15 | $all_a = $hash_count_atcg { 'A' }; |
17 | $all_c = $hash_count_atcg { 'C' }; |
19 | $all_g = $hash_count_atcg { 'G' }; |
21 | $all_t = $hash_count_atcg { 'T' }; |
23 | #print '$all_a\t$all_c\t$all_g\t$all_t\n'; |
29 | print 'your query is $a\n' ; |
31 | print 'and the length of your query is $len_a \n' ; |
33 | foreach ( reverse (0.. $end_a )){ |
35 | $after = substr ( $a , $_ ,1); |
37 | $before = substr ( $a , $_ -1,1); |
39 | #对第一个字符进行找阈值的时候,我们需要人为的定义起始点! |
51 | elsif ( $after eq 'C' ) { |
59 | elsif ( $after eq 'G' ) { |
61 | $start = $all_a + $all_c +1; |
63 | $end = $all_a + $all_c + $all_g ; |
69 | $start = $all_a + $all_c + $all_g +1; |
71 | $end = $all_a + $all_c + $all_g + $all_t ; |
75 | else { print 'error !!! we just need A T C G !!!\n' ; exit ;} |
79 | #如果阈值已经无法继续分割,但是字符串还未查询完 |
81 | if ( $_ > 0 && $start == $end ) { |
83 | $find_char = substr ( $a , $_ ); |
85 | $find_len = length $find_char ; |
89 | print 'we can just find the last $find_len char ,and it is $find_char \n' ; |
101 | print 'It is just one perfect match ! \n' ; |
103 | my @F_start = split /\s+/, $hash { $start }; |
105 | print 'The index is $F_start[1]\n' ; |
113 | print 'we find more than one perfect match!!!\n' ; |
115 | #print '$start\t$end\n'; |
117 | foreach ( $start .. $end ) { |
119 | my @F_start = split /\s+/, $hash { $_ }; |
121 | print 'One of the index is $F_start[1]\n' ; |
131 | ( $start , $end )=&find_level( $after , $before , $start , $end ); |
137 | my ( $after , $before , $start , $end )= @_ ; |
139 | my @F_start = split /\s+/, $hash { $start }; |
141 | my @F_end = split /\s+/, $hash { $end }; |
145 | return ( $F_start [2], $F_end [2]); |
149 | elsif ( $before eq 'C' ) { |
151 | return ( $all_a + $F_start [3], $all_a + $F_end [3]); |
155 | elsif ( $before eq 'G' ) { |
157 | return ( $all_a + $all_c + $F_start [4], $all_a + $all_c + $F_end [4]); |
161 | elsif ( $before eq 'T' ) { |
163 | return ( $all_a + $all_c + $all_g + $F_start [5], $all_a + $all_c + $all_g + $F_end [5]); |
167 | else { print 'sorry , I can't find the right match!!!\n' ;} |
171 | #perl -alne '{next if />/;$all.=$_;}END{print substr($all,308,10)}' lambda_virus.fa |
|