def fill_cell(self, column, row): """Fill a cell using the Needleman-Wunsch algorithm. In this algorithm we calculate the value of each cell i,j as the maximum of: 1. F(i-1, j-1) + s(xi, yj) : The value of cell i-1, j-1 plus the substitution matrix value of the two items (Amino Acids or Nucleotides) held in the cell. 2. F(i, j-1) - d : The value of cell i, j-1 minus the gap penalty. 3. F(i-1, j) - d : The value of cell i-1, j minus the gap penalty. Returns: A DPMatrixCell object that has it's information filled in. """ # test to be sure we aren't falling off the matrix. assert (column >= 0) assert (row >= 0) # most special case, if we are at (0,0) in the matrix, this # is a zero and has no parent if (column == 0) and (row == 0): corner_cell = DPMatrixCell(column, row, "", "") corner_cell.set_value(0) return corner_cell # flags so we know which scores to calculate # default is to calculate them all. calculate1 = 1 calculate2 = 1 calculate3 = 1 # two other special cases, when we are the top row or in the # right-most column, then we only need to calculate a # single score. # Top Row -> only calculate score 3, and this will be our score if (row == 0) and (column != 0): calculate1 = 0 calculate2 = 0 # right-most column -> only calculate score 2 and that is # our score elif (column == 0) and (row != 0): calculate1 = 0 calculate3 = 0 # Now calculate the three scores # Score 1 score1 = None while score1 is None and calculate1 == 1: try: score1 = self.dpmatrix[(column - 1, row - 1)].get_value() + \ self.sub_matrix.get_sub_value(self.seq1[column - 1], self.seq2[row - 1]) # if we get either a key or index error the previous # cell item is not filled and needs to be filled except KeyError, IndexError: diag_cell = self.fill_cell(column - 1, row - 1) self.dpmatrix[(column - 1, row - 1)] = diag_cell
self.dpmatrix[(column - 1, row)] = right_cell # determine which score is highest of the three # first calculate the max of all the scores which are not none. max_list = [] for n in [score1, score2, score3]: if n: max_list.append(n) max_score = max(max_list) # now set the appropriate value and previous item depending on # which score is largest, and return the created cell if max_score == score1: new_cell = DPMatrixCell(column, row, self.seq1[column - 1], self.seq2[row - 1]) new_cell.set_value(max_score) new_cell.set_parent(self.dpmatrix[(column - 1, row - 1)]) return new_cell elif max_score == score2: # two cases to create the new cell. # 1. special case (right column) if score1 is None and score3 is None: new_cell = DPMatrixCell(column, row, "", self.seq2[row - 1]) # 2. normal case (elsewhere in the matrix) else: new_cell = DPMatrixCell(column, row, self.seq1[column - 1], self.seq2[row - 1]) new_cell.set_value(max_score)