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