annotate BSseeker2/bs_align/bs_align_utils.py @ 1:8b26adf64adc draft default tip

V2.0.5
author weilong-guo
date Tue, 05 Nov 2013 01:55:39 -0500
parents e6df770c0e58
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
1 from bs_utils.utils import *
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
2 import re
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
3
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
4
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
5 BAM_MATCH = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
6 BAM_INS = 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
7 BAM_DEL = 2
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
8 BAM_SOFTCLIP = 4
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
9
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
10 CIGAR_OPS = {'M' : BAM_MATCH, 'I' : BAM_INS, 'D' : BAM_DEL, 'S' : BAM_SOFTCLIP}
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
11
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
12
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
13 def N_MIS(r,g):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
14 mismatches = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
15 if len(r)==len(g):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
16 for i in xrange(len(r)):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
17 if r[i] != g[i] and r[i] != "N" and g[i] != "N" and not(r[i] == 'T' and g[i] == 'C'):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
18 mismatches += 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
19 return mismatches
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
20
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
21
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
22 #----------------------------------------------------------------
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
23
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
24 """
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
25 Exmaple:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
26 ========
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
27 Read : ACCGCGTTGATCGAGTACGTACGTGGGTC
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
28 Adapter : ....................ACGTGGGTCCCG
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
29 ========
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
30
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
31 no_mismatch : the maximum number allowed for mismatches
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
32
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
33 Algorithm: (allowing 1 mismatch)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
34 ========
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
35 -Step 1:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
36 ACCGCGTTGATCGAGTACGTACGTGGGTC
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
37 ||XX
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
38 ACGTGGGTCCCG
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
39 -Step 2:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
40 ACCGCGTTGATCGAGTACGTACGTGGGTC
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
41 X||X
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
42 .ACGTGGGTCCCG
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
43 -Step 3:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
44 ACCGCGTTGATCGAGTACGTACGTGGGTC
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
45 XX
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
46 ..ACGTGGGTCCCG
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
47 -Step ...
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
48 -Step N:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
49 ACCGCGTTGATCGAGTACGTACGTGGGTC
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
50 |||||||||
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
51 ....................ACGTGGGTCCCG
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
52 Success & return!
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
53 ========
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
54
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
55 """
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
56
1
weilong-guo
parents: 0
diff changeset
57 # Remove the adapter from 3' end
weilong-guo
parents: 0
diff changeset
58 def RemoveAdapter ( read, adapter, no_mismatch, rm_back=0) :
0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
59 lr = len(read)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
60 la = len(adapter)
1
weilong-guo
parents: 0
diff changeset
61 # Check the empty adapter, namely, the reads start with the 2nd base of adapter,
weilong-guo
parents: 0
diff changeset
62 # not including the 'A' base in front of the adapter.
weilong-guo
parents: 0
diff changeset
63 if adapter[2:] == read[0:(la-1)] :
weilong-guo
parents: 0
diff changeset
64 return ""
weilong-guo
parents: 0
diff changeset
65
0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
66 for i in xrange( lr - no_mismatch ) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
67 read_pos = i
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
68 adapter_pos = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
69 count_no_mis = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
70 while (adapter_pos < la) and (read_pos < lr) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
71 if (read[read_pos] == adapter[adapter_pos]) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
72 read_pos = read_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
73 adapter_pos = adapter_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
74 else :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
75 count_no_mis = count_no_mis + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
76 if count_no_mis > no_mismatch :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
77 break
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
78 else :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
79 read_pos = read_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
80 adapter_pos = adapter_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
81 # while_end
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
82
1
weilong-guo
parents: 0
diff changeset
83 # Cut the extra bases before the adapter
weilong-guo
parents: 0
diff changeset
84 # --C|CG G-- => --CNN+A+<adapter>
weilong-guo
parents: 0
diff changeset
85 # --G GC|C-- --GGC
0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
86 if adapter_pos == la or read_pos == lr :
1
weilong-guo
parents: 0
diff changeset
87 if i <= rm_back :
weilong-guo
parents: 0
diff changeset
88 return ''
weilong-guo
parents: 0
diff changeset
89 else :
weilong-guo
parents: 0
diff changeset
90 return read[:(i-rm_back)]
0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
91 # for_end
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
92 return read
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
93
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
94
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
95 def Remove_5end_Adapter ( read, adapter, no_mismatch) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
96 lr = len(read)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
97 la = len(adapter)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
98 for i in xrange (la - no_mismatch) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
99 read_pos = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
100 adapter_pos = i
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
101 count_no_mis = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
102 while (adapter_pos < la) and (read_pos < lr) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
103 if (read[read_pos] == adapter[adapter_pos]) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
104 adapter_pos = adapter_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
105 read_pos = read_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
106 else :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
107 count_no_mis = count_no_mis + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
108 if count_no_mis > no_mismatch :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
109 break
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
110 else :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
111 read_pos = read_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
112 adapter_pos = adapter_pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
113 # while_end
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
114 if adapter_pos == la :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
115 return read[(la-i):]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
116
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
117
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
118 def next_nuc(seq, pos, n):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
119 """ Returns the nucleotide that is n places from pos in seq. Skips gap symbols.
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
120 """
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
121 i = pos + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
122 while i < len(seq):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
123 if seq[i] != '-':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
124 n -= 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
125 if n == 0: break
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
126 i += 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
127 if i < len(seq) :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
128 return seq[i]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
129 else :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
130 return 'N'
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
131
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
132
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
133
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
134 def methy_seq(read, genome):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
135 H = ['A', 'C', 'T']
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
136 m_seq = []
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
137 xx = "-"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
138 for i in xrange(len(read)):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
139
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
140 if genome[i] == '-':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
141 continue
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
142
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
143 elif read[i] != 'C' and read[i] != 'T':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
144 xx = "-"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
145
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
146 elif read[i] == "T" and genome[i] == "C": #(unmethylated):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
147 nn1 = next_nuc(genome, i, 1)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
148 if nn1 == "G":
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
149 xx = "x"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
150 elif nn1 in H :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
151 nn2 = next_nuc(genome, i, 2)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
152 if nn2 == "G":
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
153 xx = "y"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
154 elif nn2 in H :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
155 xx = "z"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
156
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
157 elif read[i] == "C" and genome[i] == "C": #(methylated):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
158 nn1 = next_nuc(genome, i, 1)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
159
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
160 if nn1 == "G":
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
161 xx = "X"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
162 elif nn1 in H :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
163 nn2 = next_nuc(genome, i, 2)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
164
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
165 if nn2 == "G":
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
166 xx = "Y"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
167 elif nn2 in H:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
168 xx = "Z"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
169 else:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
170 xx = "-"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
171 m_seq.append(xx)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
172
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
173 return ''.join(m_seq)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
174
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
175 def mcounts(mseq, mlst, ulst):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
176 out_mlst=[mlst[0]+mseq.count("X"), mlst[1]+mseq.count("Y"), mlst[2]+mseq.count("Z")]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
177 out_ulst=[ulst[0]+mseq.count("x"), ulst[1]+mseq.count("y"), ulst[2]+mseq.count("z")]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
178 return out_mlst, out_ulst
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
179
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
180
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
181
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
182 def process_aligner_output(filename, pair_end = False):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
183
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
184 #m = re.search(r'-('+'|'.join(supported_aligners) +')-TMP', filename)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
185 m = re.search(r'-('+'|'.join(supported_aligners) +')-.*TMP', filename)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
186 if m is None:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
187 error('The temporary folder path should contain the name of one of the supported aligners: ' + filename)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
188
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
189 format = m.group(1)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
190 try :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
191 input = open(filename)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
192 except IOError:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
193 print "[Error] Cannot open file %s" % filename
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
194 exit(-1)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
195
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
196 QNAME, FLAG, RNAME, POS, MAPQ, CIGAR, RNEXT, PNEXT, TLEN, SEQ, QUAL = range(11)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
197 def parse_SAM(line):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
198 buf = line.split()
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
199 # print buf
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
200 flag = int(buf[FLAG])
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
201
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
202 # skip reads that are not mapped
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
203 # skip reads that have probability of being non-unique higher than 1/10
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
204 if flag & 0x4 : # or int(buf[MAPQ]) < 10:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
205 return None, None, None, None, None, None
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
206 # print "format = ", format
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
207 if format == BOWTIE:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
208 mismatches = int([buf[i][5:] for i in xrange(11, len(buf)) if buf[i][:5] == 'NM:i:'][0]) # get the edit distance
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
209 # --- bug fixed ------
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
210 elif format == BOWTIE2:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
211 if re.search(r'(.)*-e2e-TMP(.*)', filename) is None : # local model
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
212 mismatches = 1-int([buf[i][5:] for i in xrange(11, len(buf)) if buf[i][:5] == 'AS:i:'][0])
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
213 # print "====local=====\n"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
214 ## bowtie2 use AS tag (score) to evaluate the mapping. The higher, the better.
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
215 else : # end-to-end model
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
216 # print "end-to-end\n"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
217 mismatches = int([buf[i][5:] for i in xrange(11, len(buf)) if buf[i][:5] == 'XM:i:'][0])
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
218 # --- Weilong ---------
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
219 elif format == SOAP:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
220 mismatches = 1-buf[MAPQ]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
221 # mismatches = 1/float(buf[MAPQ])
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
222 ## downstream might round (0,1) to 0, so use integer instead
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
223 ## fixed by Weilong
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
224 elif format == RMAP:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
225 # chr16 75728107 75728147 read45 9 -
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
226 # chr16 67934919 67934959 read45 9 -
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
227 mismatches = buf[4]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
228
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
229 return (buf[QNAME], # read ID
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
230 buf[RNAME], # reference ID
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
231 int(buf[POS]) - 1, # position, 0 based (SAM is 1 based)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
232 mismatches, # number of mismatches
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
233 parse_cigar(buf[CIGAR]), # the parsed cigar string
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
234 flag & 0x40 # true if it is the first mate in a pair, false if it is the second mate
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
235 )
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
236
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
237 SOAP_QNAME, SOAP_SEQ, SOAP_QUAL, SOAP_NHITS, SOAP_AB, SOAP_LEN, SOAP_STRAND, SOAP_CHR, SOAP_LOCATION, SOAP_MISMATCHES = range(10)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
238 def parse_SOAP(line):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
239 buf = line.split()
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
240 return (buf[SOAP_QNAME],
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
241 buf[SOAP_CHR],
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
242 int(buf[SOAP_LOCATION]) - 1,
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
243 int(buf[SOAP_MISMATCHES]),
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
244 buf[SOAP_AB],
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
245 buf[SOAP_STRAND],
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
246 parse_cigar(buf[SOAP_LEN]+'M')
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
247 )
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
248
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
249 # chr16 75728107 75728147 read45 9 -
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
250 RMAP_CHR, RMAP_START, RMAP_END, RMAP_QNAME, RMAP_MISMATCH, RMAP_STRAND = range(6)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
251 def parse_RMAP(line):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
252 buf = line.split()
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
253 return ( buf[RMAP_QNAME],
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
254 buf[RMAP_CHR],
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
255 int(buf[RMAP_START]), # to check -1 or not
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
256 int(buf[RMAP_END]) - int(buf[RMAP_START]) + 1,
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
257 int(buf[RMAP_MISMATCH]),
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
258 buf[RMAP_STRAND]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
259 )
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
260
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
261 if format == BOWTIE or format == BOWTIE2:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
262 if pair_end:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
263 for line in input:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
264 header1, chr1, location1, no_mismatch1, cigar1, _ = parse_SAM(line)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
265 header2, _, location2, no_mismatch2, cigar2, mate_no2 = parse_SAM(input.next())
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
266
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
267
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
268 if header1 and header2:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
269 # flip the location info if the second mate comes first in the alignment file
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
270 if mate_no2:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
271 location1, location2 = location2, location1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
272 cigar1, cigar2 = cigar2, cigar1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
273
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
274
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
275 yield header1, chr1, no_mismatch1 + no_mismatch2, location1, cigar1, location2, cigar2
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
276 else:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
277 for line in input:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
278 header, chr, location, no_mismatch, cigar, _ = parse_SAM(line)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
279 if header is not None:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
280 yield header, chr, location, no_mismatch, cigar
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
281 elif format == SOAP:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
282 if pair_end:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
283 for line in input:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
284 header1, chr1, location1, no_mismatch1, mate1, strand1, cigar1 = parse_SOAP(line)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
285 header2, _ , location2, no_mismatch2, _, strand2, cigar2 = parse_SOAP(input.next())
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
286
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
287 if mate1 == 'b':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
288 location1, location2 = location2, location1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
289 strand1, strand2 = strand2, strand1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
290 ciga1, cigar2 = cigar2, cigar1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
291
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
292
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
293 if header1 and header2 and strand1 == '+' and strand2 == '-':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
294 yield header1, chr1, no_mismatch1 + no_mismatch2, location1, cigar1, location2, cigar2
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
295
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
296 else:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
297 for line in input:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
298 header, chr, location, no_mismatch, _, strand, cigar = parse_SOAP(line)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
299 if header and strand == '+':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
300 yield header, chr, location, no_mismatch, cigar
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
301 elif format == RMAP :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
302 if pair_end :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
303 todo = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
304 # to do
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
305 else :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
306 for line in input:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
307 header, chr, location, read_len, no_mismatch, strand = parse_RMAP(line)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
308 cigar = str(read_len) + "M"
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
309 yield header, chr, location, no_mismatch, cigar
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
310
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
311 input.close()
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
312
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
313
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
314 def parse_cigar(cigar_string):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
315 i = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
316 prev_i = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
317 cigar = []
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
318 while i < len(cigar_string):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
319 if cigar_string[i] in CIGAR_OPS:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
320 cigar.append((CIGAR_OPS[cigar_string[i]], int(cigar_string[prev_i:i])))
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
321 prev_i = i + 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
322 i += 1
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
323 return cigar
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
324
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
325 def get_read_start_end_and_genome_length(cigar):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
326 r_start = cigar[0][1] if cigar[0][0] == BAM_SOFTCLIP else 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
327 r_end = r_start
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
328 g_len = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
329 for edit_op, count in cigar:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
330 if edit_op == BAM_MATCH:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
331 r_end += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
332 g_len += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
333 elif edit_op == BAM_INS:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
334 r_end += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
335 elif edit_op == BAM_DEL:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
336 g_len += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
337 return r_start, r_end, g_len # return the start and end in the read and the length of the genomic sequence
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
338 # r_start : start position on the read
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
339 # r_end : end position on the read
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
340 # g_len : length of the mapped region on genome
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
341
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
342
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
343 def cigar_to_alignment(cigar, read_seq, genome_seq):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
344 """ Reconstruct the pairwise alignment based on the CIGAR string and the two sequences
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
345 """
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
346
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
347 # reconstruct the alignment
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
348 r_pos = cigar[0][1] if cigar[0][0] == BAM_SOFTCLIP else 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
349 g_pos = 0
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
350 r_aln = ''
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
351 g_aln = ''
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
352 for edit_op, count in cigar:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
353 if edit_op == BAM_MATCH:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
354 r_aln += read_seq[r_pos : r_pos + count]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
355 g_aln += genome_seq[g_pos : g_pos + count]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
356 r_pos += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
357 g_pos += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
358 elif edit_op == BAM_DEL:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
359 r_aln += '-'*count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
360 g_aln += genome_seq[g_pos : g_pos + count]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
361 g_pos += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
362 elif edit_op == BAM_INS:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
363 r_aln += read_seq[r_pos : r_pos + count]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
364 g_aln += '-'*count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
365 r_pos += count
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
366
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
367 return r_aln, g_aln
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
368
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
369
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
370
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
371 # return sequence is [start, end), not include 'end'
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
372 def get_genomic_sequence(genome, start, end, strand = '+'):
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
373 if strand != '+' and strand != '-' :
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
374 print "[Bug] get_genomic_sequence input should be \'+\' or \'-\'."
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
375 exit(-1)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
376 if start > 1:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
377 prev = genome[start-2:start]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
378 elif start == 1:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
379 prev = 'N'+genome[0]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
380 else:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
381 prev = 'NN'
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
382
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
383 if end < len(genome) - 1:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
384 next = genome[end: end + 2]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
385 elif end == len(genome) - 1:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
386 next = genome[end] + 'N'
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
387 else:
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
388 next = 'NN'
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
389 origin_genome = genome[start:end]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
390
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
391 if strand == '-':
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
392 # reverse complement everything if strand is '-'
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
393 revc = reverse_compl_seq('%s%s%s' % (prev, origin_genome, next))
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
394 prev, origin_genome, next = revc[:2], revc[2:-2], revc[-2:]
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
395
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
396 return origin_genome, next, '%s_%s_%s' % (prev, origin_genome, next)
e6df770c0e58 Initial upload
weilong-guo
parents:
diff changeset
397 # next : next two nucleotides