forked from xuyk/Rosalind
-
Notifications
You must be signed in to change notification settings - Fork 0
/
103_LAFF.py
77 lines (60 loc) · 2.82 KB
/
103_LAFF.py
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
#!/usr/bin/env python
'''
A solution to a ROSALIND bioinformatics problem.
Problem Title: Local Alignment with Affine Gap Penalty
Rosalind ID: LAFF
Rosalind #: 103
URL: http://rosalind.info/problems/laff/
'''
def local_alignment_affine_gap_penalty(v, w, scoring_matrix, sigma, epsilon):
'''
Returns the score and local alignment substrings for strings v, w with the
given scoring matrix, gap opening penalty sigma, and gap extension penalty epsilon.
'''
# Initialize the matrices.
S_lower = [[0 for j in xrange(len(w)+1)] for i in xrange(len(v)+1)]
S_middle = [[0 for j in xrange(len(w)+1)] for i in xrange(len(v)+1)]
S_upper = [[0 for j in xrange(len(w)+1)] for i in xrange(len(v)+1)]
backtrack = [[0 for j in xrange(len(w)+1)] for i in xrange(len(v)+1)]
# Initialize the maximum score below the lowest possible score.
max_score = -1
max_i, max_j = 0, 0
# Fill in the Score and Backtrack matrices.
for i in xrange(1, len(v)+1):
for j in xrange(1, len(w)+1):
S_lower[i][j] = max([S_lower[i-1][j] - epsilon, S_middle[i-1][j] - sigma])
S_upper[i][j] = max([S_upper[i][j-1] - epsilon, S_middle[i][j-1] - sigma])
middle_scores = [S_lower[i][j], S_middle[i-1][j-1] + scoring_matrix[v[i-1], w[j-1]], S_upper[i][j], 0]
S_middle[i][j] = max(middle_scores)
backtrack[i][j] = middle_scores.index(S_middle[i][j])
if S_middle[i][j] > max_score:
max_score = S_middle[i][j]
max_i, max_j = i, j
# Initialize the indices to start at the position of the high score.
i, j = max_i, max_j
# Initialize the aligned strings as the input strings up to the position of the high score.
v_aligned, w_aligned = v[:i], w[:j]
# Backtrack to start of the local alignment starting at the highest scoring cell.
# Note: the solution format specifically asks for substrings, so no indel insertion necessary.
while backtrack[i][j] != 3 and i*j != 0:
if backtrack[i][j] == 0:
i -= 1
elif backtrack[i][j] == 1:
i -= 1
j -= 1
elif backtrack[i][j] == 2:
j -= 1
# Cut the strings at the ending point of the backtrack.
v_aligned = v_aligned[i:]
w_aligned = w_aligned[j:]
return str(max_score), v_aligned, w_aligned
if __name__ == '__main__':
from scripts import BLOSUM62, ReadFASTA
# Parse the two input protein strings.
s, t = [fasta[1] for fasta in ReadFASTA('data/rosalind_laff.txt')]
# Get the local alignment (given sigma = 11, epsilon = 1 in problem statement).
alignment = local_alignment_affine_gap_penalty(s, t, BLOSUM62(), 11, 1)
# Print and save the answer.
print '\n'.join(alignment)
with open('output/103_LAFF.txt', 'w') as output_data:
output_data.write('\n'.join(alignment))