Skip to content

Commit d3ad60b

Browse files
committed
added parse N
1 parent 9386429 commit d3ad60b

1 file changed

Lines changed: 73 additions & 7 deletions

File tree

tgirt_seq_tools/fragment_pairs.pyx

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,43 @@ from cpython cimport bool
77
from pysam.libcalignmentfile cimport AlignmentFile, AlignedSegment
88
import sys
99

10+
11+
cdef class read_fragment:
12+
cdef:
13+
long start, end
14+
15+
def __init__(self, frag_start, frag_end):
16+
self.end = frag_end
17+
self.start = frag_start
18+
19+
def fragment_ends(self):
20+
return self.start, self.end
21+
22+
def start_site(self):
23+
return self.start
24+
25+
def end_site(self):
26+
return self.end
27+
28+
29+
def read_to_fragment(read):
30+
cdef:
31+
long init_pos, start, end, pos
32+
int i
33+
34+
positions = read.get_reference_positions()
35+
init_pos = positions[0]
36+
start = positions[0]
37+
38+
for i, pos in enumerate(positions):
39+
if pos - init_pos > 1:
40+
end = init_pos
41+
yield read_fragment(start, end)
42+
start = pos
43+
init_pos = pos
44+
yield read_fragment(start, init_pos)
45+
46+
1047
cdef bool qualify_pairs(AlignedSegment read1, AlignedSegment read2):
1148
'''
1249
Only extract concordant proper pairs
@@ -16,6 +53,25 @@ cdef bool qualify_pairs(AlignedSegment read1, AlignedSegment read2):
1653
bool forward_fragment = read1.flag == 99 and read2.flag == 147
1754
return reverse_fragment or forward_fragment
1855

56+
57+
def split_fragment_ends(AlignedSegment read1, AlignedSegment read2):
58+
'''
59+
get outer ends of the fragments
60+
'''
61+
cdef:
62+
long start1, end1, start2, end2
63+
long start, end
64+
read_fragment frag_1, frag_2
65+
bool intersect
66+
67+
for num_frag_1, frag_1 in enumerate(read_to_fragment(read1)):
68+
for num_frag_2, frag_2 in enumerate(read_to_fragment(read2)):
69+
intersect = frag_1.end_site() > frag_2.start_site() and frag_2.end_site() > frag_1.start_site()
70+
if intersect:
71+
start = min(frag_1.start_site(), frag_2.start_site())
72+
end = max(frag_1.end_site(), frag_2.end_site()) + 1
73+
yield start, end
74+
1975
def read_ends(AlignedSegment read):
2076
'''
2177
get read end positions
@@ -59,18 +115,28 @@ def bam_to_bed(bam_file, out_file, int min_size, int max_size):
59115
try:
60116
read_1 = in_bam.next()
61117
read_2 = in_bam.next()
62-
assert read_1.query_name == read_2.query_name, 'Paired not stored together'
118+
assert read_1.query_name == read_2.query_name, 'Paired not stored together: %s, %s' %(read_1.query_name , read_2.query_name)
63119
if qualify_pairs(read_1, read_2):
64120
chrom = read_1.reference_name
65121
strand = '-' if read_1.is_reverse else '+'
66-
start, end = fragment_ends(read_1, read_2)
67-
fragment_size = end - start
68-
if min_size < fragment_size < max_size:
69-
line = '%s\t%i\t%i\t%s\t%i\t%s' %(chrom, start, end,
122+
if 'N' in read_1.cigarstring or 'N' in read_2.cigarstring:
123+
for start, end in split_fragment_ends(read_1, read_2):
124+
fragment_size = end - start
125+
if min_size < fragment_size < max_size:
126+
line = '%s\t%i\t%i\t%s\t%i\t%s' %(chrom, start, end,
127+
read_1.query_name,
128+
fragment_size,strand)
129+
pair_count += 1
130+
print(line, file=out_file)
131+
else:
132+
start, end = fragment_ends(read_1, read_2)
133+
fragment_size = end - start
134+
if min_size < fragment_size < max_size:
135+
line = '%s\t%i\t%i\t%s\t%i\t%s' %(chrom, start, end,
70136
read_1.query_name,
71137
fragment_size,strand)
72-
pair_count += 1
73-
print(line, file=out_file)
138+
pair_count += 1
139+
print(line, file=out_file)
74140
except StopIteration:
75141
break
76142
sys.stderr.write('Witten %i fragments\n' %(pair_count))

0 commit comments

Comments
 (0)