Noobie to Numba here, I'm trying to get faster code from existing function but the result is not faster. 10 times faster would be heaven, but I know nothing about optimization. This is code about parsing gaps in DNA sequences pairwise alignment and doing statistics about it. The code looks like this:
import re
import time
import numpy as np
from numba import autojit, int32, complex64
sstart = 10
send = 52
absoluteRoiStart = 19 #rank of the first nucleotide in the ROI
absoluteRoiStop = 27 #rank of the the first nucleotide after the ROI
#ROI is here 'TATCGA---CAG|TA-----TACTA-C|G--TTGAGAGAGAC-CCCA'
#between | 'T--CGACCAC--|-GATCGAG---ATC|GGCTT--------CTC--A'
source = 'TATCGA---CAGTA-----TACTA-CG--TTGAGAGAGAC-CCCA'
sequence = 'T--CGACCAC---GATCGAG---ATCGGCTT--------CTC--A'
realSource = 'AAGGTTCCAATATCGACAGTATACTACGTTGAGAGAGACCCCACATGACTGACTACGT'
tresholds = {
"DEL" : {
"other" : 2,
"slippage": 2,
"quantity" : 7
},
"INS" : {
"other" : 3,
"slippage": 3,
"quantity" : 7
},
"MUT" : {
"other" : 3,
"slippage": 3,
"quantity" : 7
},
"NA" : {
"other" : 3,
"slippage": 3,
"quantity" : 7
}
}
def getAllGaps(sequence1, sequence2):
starts = []
stops = []
lengths = []
types = []
locations = []
gap = '(\-)+'
x = re.compile(gap)
for m in x.finditer(sequence1):
#Get Gap satrt, stop and length
start,stop = m.span()
#Test if Gap is slippage(compression or extension)
if start > 1 and stop < len(sequence2):
h = sequence2[start-1:stop+1].upper()
i = sequence1[start-1:stop+1]
repetitions = i.replace('-', h[0]).upper(), i.replace('-', h[-1]).upper()
if h == repetitions[0] or h == repetitions[1]:
slippage = True
else:
slippage = False
else:
slippage = False
starts.append(start)
stops.append(stop)
lengths.append(stop-start)
if slippage:
types.append(2)
else:
types.append(1)
locations += range(start, stop)
d = [starts, stops, lengths, types]
return {'locations': locations, 'bounds': d}
def getAlignmentData(source, sequence, sstart, tresholds):
insertionData = getAllGaps(source, sequence)
alignmentLength = len(source)
oneArray = np.ones(alignmentLength)
oneArray[insertionData['locations']] = 0
absoluteIndex = oneArray.cumsum()-1+sstart
relativeIndex = np.arange(alignmentLength)
tf = (absoluteIndex >= absoluteRoiStart) & (absoluteIndex < absoluteRoiStop)
absoluteBounds = absoluteIndex[tf]
relativeBounds = relativeIndex[tf]
relativeRoiStart = int(relativeBounds.min())
relativeRoiStop = int(relativeBounds.max())
events = np.array(insertionData['bounds'], dtype=np.int32)
insertionStartingInRoi = events[:,(events[0] >= relativeRoiStart) & (events[1] <= relativeRoiStop)]
print(insertionStartingInRoi)
deletionData = getAllGaps(sequence, source)
events = np.array(deletionData['bounds'], dtype=np.int32)
deletionOverlappingRoiOrStartingInRoi = events[:,((events[0] <= relativeRoiStart) & (events[1] >= relativeRoiStart)) | ((events[0] >= relativeRoiStart) & (events[1] <= relativeRoiStop))]
print(deletionOverlappingRoiOrStartingInRoi)
t0 = time.time()
getAlignmentData(source, sequence, sstart, tresholds)
t1 = time.time()
getAlignmentData(source, sequence, sstart, tresholds)
t2 = time.time()
print(str(t1-t0)+' to first try')
print(str(t2-t1)+' to second try')
When I add the @jit
decorator on the two functions, I get slower code. Do I need to do something special, like signatures? Can Numba make this code faster or do I need to use Cython?