[3] | 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 ) |
---|