# Student(s): ############################################################################ # Implementation of the Needleman-Wunsch Global Pairwise Alignment algorithm # (to be modified to be the Smith-Waterman Local Pairwise Alignment algorithm) ############################################################################ def buildTable(X, Y, score, gap): """This is responsible for building and returning the table of values.""" # create table of zeros with dimension (1+|X|)-by-(1+|Y|) opt = [ [0] * (1+len(Y)) for _ in range(1+len(X))] for k in range(1+len(Y)): opt[0][k] = k*gap # initialize top row for j in range(1+len(X)): opt[j][0] = j*gap # initialize left column for j in range(1,1+len(X)): for k in range(1, 1+len(Y)): option1 = opt[j-1][k-1] + score(X[j-1],Y[k-1]) # align last chars option2 = opt[j-1][k] + gap # last of X with gap option3 = opt[j][k-1] + gap # last of Y with gap opt[j][k] = max(option1, option2, option3) return opt def optScore(X, Y, table): """This is responsible for returning the maximum score.""" return table[len(X)][len(Y)] # bottom-right corner def reconstructSolution(X, Y, table, score, gap): """This is responsible for returning strings that describe the optimal alignment.""" first = '' # alignment for X second = '' # alignment for Y glue = '' # line showing matches/mismatches # start reconstruction at bottom-right of table j = len(X) k = len(Y) while j>0 or k>0: if j>0 and k>0 and table[j][k] == table[j-1][k-1] + score(X[j-1],Y[k-1]): # option1 above; match X[j-1] with Y[k-1] first = X[j-1] + first second = Y[k-1] + second if X[j-1] == Y[k-1]: glue = '|' + glue # designate match else: glue = '.' + glue # designate mismatch j = j-1 k = k-1 elif j > 0 and table[j][k] == table[j-1][k] + gap: # option2 above; match X[j-1] with a gap in Y first = X[j-1] + first second = '-' + second glue = ' ' + glue j = j-1 else: # option3 above; match gap in X with Y[k-1] first = '-' + first second = Y[k-1] + second glue = ' ' + glue k = k-1 return first,glue,second ############################################################################ # Do NOT change (or even read?) anything below this line ############################################################################ def displayTable(table): for row in table: print(' '.join('%3d' % val for val in row)) def createScoreFunc(match,mismatch): def s(u,v): if u == v: return match else: return mismatch s.__name__ = "match=%d, mismatch=%d" % (match,mismatch) return s # return the newly defined function def performTest(X,Y,score,gap): print('='*30) print('Computing alignment with gap=%d score=%s' % (gap,score.__name__)) table = buildTable(X,Y,score,gap) opt = optScore(X,Y,table) print('Optimal score=%d' % opt) first,glue,second = reconstructSolution(X, Y, table, score, gap) print('') print('Optimal Alignment:') print(first) print(glue) print(second) if max(len(X),len(Y)) <= 100: print('') print('Intermediate table of values:') displayTable(table) print('') if __name__ == '__main__': import sys try: tests = open('tests.txt') lines = tests.readlines() for k in range(len(lines)): line = lines[k] pieces = line.split() if pieces: if len(pieces) != 5: print("Error at line %d; should be five arguments" % (1+k)) else: try: match = int(pieces[0]) mismatch = int(pieces[1]) gap = int(pieces[2]) X = pieces[3] Y = pieces[4] s = createScoreFunc(match,mismatch) performTest(X,Y,s,gap) except ValueError: print("Test line should be of form: [matchVal] [mismatchVal] [gapVal] X Y") except IOError: print('Unable to open tests.txt file')