1 | """ |
---|
2 | Utility functions for working with `Bitset`s and treating lists of (start,end) |
---|
3 | as `Bitset`s. |
---|
4 | """ |
---|
5 | |
---|
6 | from bx.bitset import * |
---|
7 | |
---|
8 | def bitset_intersect( ex1, ex2 ): |
---|
9 | bits1 = list2bits( ex1 ) |
---|
10 | bits2 = list2bits( ex2 ) |
---|
11 | bits1.iand( bits2 ) |
---|
12 | return bits2list( bits1 ) |
---|
13 | |
---|
14 | def bitset_subtract( ex1, ex2 ): |
---|
15 | bits1 = list2bits( ex1 ) |
---|
16 | bits2 = list2bits( ex2 ) |
---|
17 | bits2.invert() |
---|
18 | bits1.iand( bits2 ) |
---|
19 | return bits2list( bits1 ) |
---|
20 | |
---|
21 | def list2bits( ex ): |
---|
22 | bits = BinnedBitSet(MAX) |
---|
23 | for start,end in ex: |
---|
24 | bits.set_range( start, end - start ) |
---|
25 | return bits |
---|
26 | |
---|
27 | def bits2list( bits ): |
---|
28 | ex = [] |
---|
29 | end = 0 |
---|
30 | while 1: |
---|
31 | start = bits.next_set( end ) |
---|
32 | if start == bits.size: break |
---|
33 | end = bits.next_clear( start ) |
---|
34 | ex.append( (start, end) ) |
---|
35 | return ex |
---|
36 | |
---|
37 | def bitset_complement( exons ): |
---|
38 | bits = BinnedBitSet(MAX) |
---|
39 | introns = [] |
---|
40 | for start, end in exons: |
---|
41 | bits.set_range( start, end - start ) |
---|
42 | bits.invert() |
---|
43 | |
---|
44 | # only complement within the range of the list |
---|
45 | ex_start = min( [a[0] for a in exons] ) |
---|
46 | ex_end = max( [a[1] for a in exons] ) |
---|
47 | end = ex_start |
---|
48 | len = ex_end |
---|
49 | while 1: |
---|
50 | start = bits.next_set( end ) |
---|
51 | if start == bits.size: break |
---|
52 | end = bits.next_clear( start ) |
---|
53 | if end > len: end = len |
---|
54 | if start != end: |
---|
55 | introns.append( (start,end ) ) |
---|
56 | if end == len: break |
---|
57 | return introns |
---|
58 | |
---|
59 | def bitset_interval_intersect( bits, istart, iend ): |
---|
60 | rval = [] |
---|
61 | end = istart |
---|
62 | len = iend |
---|
63 | while 1: |
---|
64 | start = bits.next_set( end ) |
---|
65 | if start >= len: break |
---|
66 | end = bits.next_clear( start ) |
---|
67 | if start != end: |
---|
68 | rval.append( (start,end) ) |
---|
69 | if end >= len: break |
---|
70 | return rval |
---|
71 | |
---|
72 | def bitset_union( exons ): |
---|
73 | bits = list2bits( exons ) |
---|
74 | return bits2list( bits ) |
---|