def find_best_chain(current_chain, chars, max_lookahead, ch_score):

    # The first char has to be popped because it processed that char.
    global current_lookahead
    if not current_lookahead == 0:
        chars = chars[1:]

    # If there is only 1 char left we've arrived at the end of a chain.
    if len(chars) == 1 or current_lookahead == max_lookahead:


        # Add the last char to the amino chain.
        current_chain.chain_list.append(Amino(chars[0], 0, current_chain.chain_list[-1].get_fold_coordinates()))

        # Calculate the matrix (needed for the score.) and the score
        matrix, xy_offset = get_matrix_efficient(current_chain.chain_list)
        score = get_score_efficient(current_chain.chain_list, matrix, xy_offset, ch_score)

        global best_score
        global best_chain

        # IF this score is the best score, save this score + chain as a global.
        if score < best_score:
            best_score = score
            best_chain = copy.deepcopy(current_chain.chain_list)

        # Abort that chain if it isnt the best score. remove amino we just added
        del current_chain.chain_list[-1]
        return None

    # Get legal moves on the position of that amino
    legal_moves = get_legal_moves_nomirror(current_chain.chain_list[-1].get_fold_coordinates(), current_chain)

    # If no legals move left, abort the chain. The protein got "stuck"
    if not legal_moves:
        return None

    # Go recursively through all legal moves and its child legal moves etc.
    else:
        for move in legal_moves:

            # Find best chain needs a new updated chain, but the old chain also needs to be remembered.
            last_amino = current_chain.chain_list[-1]

            # Append the next amino and increase current lookahead
            current_lookahead += 1
            current_chain.chain_list.append(Amino(chars[0], move, last_amino.get_fold_coordinates()))

            current_chain.update_mirror_status()
            find_best_chain(current_chain, chars, max_lookahead, ch_score)
            current_chain.update_mirror_status_reverse()

            # After the algo the lookahead should return to last value and the amino we just added should be removed again.
            current_lookahead -= 1
            del current_chain.chain_list[-1]
Ejemplo n.º 2
0
def find_best_chain(current_chain, chars, ch_score):

    # The first char has to be popped because it processes that char in the last loop
    # Note: popping the first loop is also valid because the first char is build before loading the fold_selector.
    chars = chars[1:]

    # If there is only 1 char left we've arrived at the end of a chain.
    if len(chars) == 1:

        # Add the last char to the amino chain.
        current_chain.chain_list.append(Amino(chars[0], 0, current_chain.chain_list[-1].get_fold_coordinates()))

        # Calculate the matrix (needed for the score.) and the score
        matrix, xy_offset = get_matrix_efficient(current_chain.chain_list)
        score = get_score_efficient(current_chain.chain_list, matrix, xy_offset, ch_score)

        global best_score
        global best_chain

        # IF this score is the best score, save this score + chain as a global.
        if score < best_score:
            print("New best score: " + str(score))
            best_score = score
            best_chain = copy.deepcopy(current_chain.chain_list)

        # Abort that chain if it isnt the best score.
        del current_chain.chain_list[-1]
        return None

    # Get legal moves on the position of that amino
    legal_moves = get_legal_moves_nomirror(current_chain.chain_list[-1].get_fold_coordinates(), current_chain)

    # If no legals move left, abort the chain. The protein got "stuck"
    if not legal_moves:
        return None

    # Go recursively through all legal moves and its child legal moves etc.
    else:
        for move in legal_moves:

            # Find best chain needs a new updated chain, but the old chain also needs to be remembered.
            last_amino = current_chain.chain_list[-1]
            current_chain.chain_list.append(Amino(chars[0], move, last_amino.get_fold_coordinates()))
            
            current_chain.update_mirror_status()
            find_best_chain(current_chain, chars, ch_score)
            current_chain.update_mirror_status_reverse()

            del current_chain.chain_list[-1]
def find_best_chain(current_chain, chars, ch_score, current_score):

    global best_score

    # The first char has to be popped because it processes that char in the last loop
    # Note: popping the first loop is also valid because the first char is build before loading the fold_selector.
    chars = chars[1:]

    # If there is only 1 char left we've arrived at the end of a chain.
    if len(chars) == 1:

        # Add the last char to the amino chain AND the recusrive chain matrix
        last_amino = current_chain.chain_list[-1]
        new_amino_x, new_amino_y = last_amino.get_fold_coordinates()
        new_amino = Amino(chars[0], 0, [new_amino_x, new_amino_y])
        current_chain.chain_list.append(new_amino)
        current_chain.matrix[new_amino_y][new_amino_x] = new_amino

        # Get the new score by building on the last score
        new_score = get_score_iterative(current_chain.chain_list,
                                        current_chain.matrix, current_score)

        # Calculate the matrix (needed for the score.) and the score
        score = new_score

        global best_score
        global best_chain

        # IF this score is the best score, save this score + chain as a global.
        if score < best_score:
            print("New best score: " + str(score))
            best_score = score
            best_chain = copy.deepcopy(current_chain.chain_list)

        # Abort that chain if it isnt the best score. also remove it from the matrix
        current_chain.matrix[new_amino_y][new_amino_x] = " "
        del current_chain.chain_list[-1]
        return None

    # Get legal moves on the position of that amino
    legal_moves = get_legal_moves_nomirror(
        current_chain.chain_list[-1].get_fold_coordinates(), current_chain)

    # If no legals move left, abort the chain. The protein got "stuck"
    if not legal_moves:
        return None

    # Go recursively through all legal moves and its child legal moves etc.
    else:
        for move in legal_moves:

            # Find best chain needs a new updated chain, but the old chain also needs to be remembered.
            last_amino = current_chain.chain_list[-1]
            new_amino_x, new_amino_y = last_amino.get_fold_coordinates()
            new_amino = Amino(chars[0], move, [new_amino_x, new_amino_y])
            current_chain.chain_list.append(new_amino)

            # Also add that amino to the matrix, and update the mirror starus
            current_chain.matrix[new_amino_y][new_amino_x] = new_amino
            current_chain.update_mirror_status()

            # Calculate new score
            new_score = get_score_iterative(current_chain.chain_list,
                                            current_chain.matrix,
                                            current_score)

            find_best_chain(current_chain, chars, ch_score, new_score)

            # Reverse the matrix and mirror status
            current_chain.matrix[new_amino_y][new_amino_x] = " "
            current_chain.update_mirror_status_reverse()

            del current_chain.chain_list[-1]
Ejemplo n.º 4
0
def find_best_chain(current_chain, chars, ch_score, current_score):

    global best_score

    # The first char has to be popped because it processes that char in the last loop.
    # Note: popping the first loop is also valid because the first char is build before loading the fold_selector.
    chars = chars[1:]

    mode_3d = is_chain_3d(current_chain.chain_list)

    # If there is only 1 char left we've arrived at the end of a chain.
    if len(chars) == 1:
        # Add the last char to the amino chain AND the recusrive chain matrix
        last_amino = current_chain.chain_list[-1]
        coordinates = last_amino.get_fold_coordinates()
        new_amino = Amino(chars[0], 0, coordinates)
        current_chain.chain_list.append(new_amino)

        if mode_3d:
            current_chain.matrix[coordinates[2]][coordinates[1]][
                coordinates[0]] = new_amino
        else:
            current_chain.matrix[coordinates[1]][coordinates[0]] = new_amino

        new_score = get_score_iterative(current_chain.chain_list,
                                        current_chain.matrix, current_score)

        # Calculate the matrix (needed for the score.) and the score.
        score = new_score

        global best_chain

        # IF this score is the best score, save this score + chain as a global.
        if score < best_score:
            print("New best score: " + str(score))
            best_score = score
            best_chain = copy.deepcopy(current_chain.chain_list)

        # Abort that chain if it isnt the best score. also remove it from the matrix.
        if mode_3d:
            current_chain.matrix[coordinates[2]][coordinates[1]][
                coordinates[0]] = " "
        else:
            current_chain.matrix[coordinates[1]][coordinates[0]] = " "

        del current_chain.chain_list[-1]
        return None

    # Get legal moves on the position of that amino.
    legal_moves = get_legal_moves_nomirror(
        current_chain.chain_list[-1].get_fold_coordinates(), current_chain)

    # If no legals move left, abort the chain. The protein got "stuck".
    if not legal_moves:
        return None

    # Go recursively through all legal moves and its child legal moves etc.
    else:
        for move in legal_moves:

            # Find best chain needs a new updated chain, but the old chain also needs to be remembered.
            last_amino = current_chain.chain_list[-1]
            coordinates = last_amino.get_fold_coordinates()
            new_amino = Amino(chars[0], move, coordinates)
            current_chain.chain_list.append(new_amino)

            skip_function = False

            # Also add that amino to the matrix, and update the mirror status.
            if mode_3d:
                current_chain.matrix[coordinates[2]][coordinates[1]][
                    coordinates[0]] = new_amino
            else:
                current_chain.matrix[coordinates[1]][
                    coordinates[0]] = new_amino

            current_chain.update_mirror_status()

            # Calculate new score and and/remove the correct fold spots.
            new_score, spots_to_add, spots_to_remove, spots_to_add_C, spots_to_remove_C = get_score_iterative_and_spots(
                current_chain, current_chain.matrix, current_score)

            # Remove the spots that are now filled by aminos.
            current_chain.remove_fold_spots(spots_to_remove, "H")
            current_chain.remove_fold_spots(spots_to_remove_C, "C")

            # Change odd/even.
            current_chain.odd = not current_chain.odd

            # Add the spots that were newly created.
            current_chain.add_fold_spots(spots_to_add, "H")
            current_chain.add_fold_spots(spots_to_add_C, "C")

            # Calculate max extra score and prune spots that are too far away.
            extra_score_possible, removed_even, removed_odd, removed_even_C, removed_odd_C = current_chain.get_max_possible_extra_score(
                chars[1:])
            max_possible = new_score + extra_score_possible

            # Of a new best score cant be reached, abandon chain.
            if max_possible >= best_score:

                skip_function = True

            global partial_energies
            current_depth = len(current_chain.chain_list)

            # If it is the new best score for that depth.
            if new_score <= partial_energies[current_depth][0]:
                if new_score < partial_energies[current_depth][0]:
                    partial_energies[current_depth][0] = new_score

                partial_energies[current_depth][1] = calculate_average(
                    partial_energies[current_depth][1],
                    partial_energies[current_depth][2], new_score)
                partial_energies[current_depth][2] += 1

            # The score is below average (so better) for that depth.
            elif new_score <= partial_energies[current_depth][1]:
                global p_below_average
                random_number = random.uniform(0, 1)

                if random_number > p_below_average:
                    skip_function = True

                else:
                    partial_energies[current_depth][1] = calculate_average(
                        partial_energies[current_depth][1],
                        partial_energies[current_depth][2], new_score)
                    partial_energies[current_depth][2] += 1

            # The score is above average (so worse) for that depth.
            else:
                global p_above_average
                random_number = random.uniform(0, 1)

                if random_number > p_above_average:
                    skip_function = True

                else:
                    partial_energies[current_depth][1] = calculate_average(
                        partial_energies[current_depth][1],
                        partial_energies[current_depth][2], new_score)
                    partial_energies[current_depth][2] += 1

            if not skip_function:
                # The actual recursive function.
                find_best_chain(current_chain, chars, ch_score, new_score)

            # Undo all the changed to the spots that were made before calling the recursive function.
            current_chain.add_back_even(removed_even, "H")
            current_chain.add_back_odd(removed_odd, "H")
            current_chain.add_back_even(removed_even_C, "C")
            current_chain.add_back_odd(removed_odd_C, "C")
            current_chain.remove_fold_spots(spots_to_add, "H")
            current_chain.remove_fold_spots(spots_to_add_C, "C")

            # Change odd/even back.
            current_chain.odd = not current_chain.odd

            # Reverse the fold spots.
            current_chain.add_fold_spots(spots_to_remove, "H")
            current_chain.add_fold_spots(spots_to_remove_C, "C")

            # Reverse the matrix and mirror status.
            if mode_3d:
                current_chain.matrix[coordinates[2]][coordinates[1]][
                    coordinates[0]]
            else:
                current_chain.matrix[coordinates[1]][coordinates[0]] = " "
            current_chain.update_mirror_status_reverse()

            # Undo the added amino.
            del current_chain.chain_list[-1]
def find_best_chain(current_chain, chars, ch_score, current_score, max_lookahead):


    global best_score
    global current_lookahead
    

    # The first char has to be popped because it processes that char in the last loop
    # Note: popping the first loop is also valid because the first char is build before loading the fold_selector.
    chars = chars[1:]

    mode_3d = is_chain_3d(current_chain)
    # If there is only 1 char left we've arrived at the end of a chain.
    if len(chars) == 1 or current_lookahead == max_lookahead:
        # Add the last char to the amino chain AND the recusrive chain matrix
        last_amino = current_chain.chain_list[-1]
        coordinates = last_amino.get_fold_coordinates()
        new_amino = Amino(chars[0], 0, coordinates)
        current_chain.chain_list.append(new_amino)
        
        if mode_3d:
            current_chain.matrix[coordinates[2]][coordinates[1]][coordinates[0]] = new_amino
        else:
            current_chain.matrix[coordinates[1]][coordinates[0]] = new_amino
        
        new_score = get_score_iterative(current_chain.chain_list, current_chain.matrix, current_score)

        # Calculate the matrix (needed for the score.) and the score
        score = new_score

        global best_chain


        # IF this score is the best score, save this score + chain as a global.
        if score < best_score:
            print("New best score: " + str(score))
            best_score = score
            best_chain = copy.deepcopy(current_chain.chain_list)
            for amino in current_chain.chain_list:
                print(amino, end='')
            print()


        # Abort that chain if it isnt the best score. also remove it from the matrix
        
        if mode_3d:
            current_chain.matrix[coordinates[2]][coordinates[1]][coordinates[0]] = " "
        else:
            current_chain.matrix[coordinates[1]][coordinates[0]] = " "
        del current_chain.chain_list[-1]
        return None

    # Get legal moves on the position of that amino
    legal_moves = get_legal_moves_nomirror(current_chain.chain_list[-1].get_fold_coordinates(), current_chain)

    # If no legals move left, abort the chain. The protein got "stuck"
    if not legal_moves:
        return None
    

    # Go recursively through all legal moves and its child legal moves etc.
    else:
        for move in legal_moves:
            # for amino in current_chain.chain_list:
            #     print(amino, end="")
            # print()
            
            # print(str(current_chain.available_bonds_even_H), str(current_chain.available_bonds_odd_H))
            # Find best chain needs a new updated chain, but the old chain also needs to be remembered.
            last_amino = current_chain.chain_list[-1]
            coordinates = last_amino.get_fold_coordinates()
            new_amino = Amino(chars[0], move, coordinates)
            current_chain.chain_list.append(new_amino)

            current_lookahead += 1

            
            

            # Also add that amino to the matrix, and update the mirror starus
            if mode_3d:
                current_chain.matrix[coordinates[2]][coordinates[1]][coordinates[0]] = new_amino
            else:
                current_chain.matrix[coordinates[1]][coordinates[0]] = new_amino

            current_chain.update_mirror_status()
            
            # Calculate new score and and/remove the correct fold spots
            new_score, spots_to_add, spots_to_remove, spots_to_add_C, spots_to_remove_C = get_score_iterative_and_spots(current_chain, current_chain.matrix, current_score)


            # Remove the spots that are now filled by aminos.
            try:
                current_chain.remove_fold_spots(spots_to_remove, "H")
                
            except:
                print(spots_to_remove)
                print(spots_to_remove)

                print(current_chain.available_bonds_odd_H)
                print(current_chain.available_bonds_odd_C)
                print(current_chain.available_bonds_even_H)
                print(current_chain.available_bonds_even_C)
                for amino in current_chain.chain_list:
                    print(amino, end="")
                    print(amino.coordinates)

                raise Exception()
            current_chain.remove_fold_spots(spots_to_remove_C, "C")

            # Change odd/even
            current_chain.odd = not current_chain.odd
            
            # Add the spots that were newly created.
            current_chain.add_fold_spots(spots_to_add, "H")
            current_chain.add_fold_spots(spots_to_add_C, "C")

            

            
            # Calculate max extra score and prune spots that are too far away.
            extra_score_possible, removed_even, removed_odd, removed_even_C, removed_odd_C = current_chain.get_max_possible_extra_score(chars[1:])
            
           
            max_possible = new_score + extra_score_possible
            
            # Of a new best score cant be reached, abandon chain.
            if max_possible >= best_score:

                # Undo all the changes that were made to the spots.
                current_chain.add_back_even(removed_even, "H")
                current_chain.add_back_odd(removed_odd, "H")
                current_chain.add_back_even(removed_even_C, "C")
                current_chain.add_back_odd(removed_odd_C, "C")
                
                current_chain.remove_fold_spots(spots_to_add, "H")
                current_chain.remove_fold_spots(spots_to_add_C, "C")

                
                # Change odd/even back
                current_chain.odd = not current_chain.odd

                # Reverse the fold spots
                current_chain.add_fold_spots(spots_to_remove, "H")
                current_chain.add_fold_spots(spots_to_remove_C, "C")

                # Reverse the matrix and mirror status
                if mode_3d:
                    current_chain.matrix[coordinates[2]][coordinates[1]][coordinates[0]]
                else:
                    current_chain.matrix[coordinates[1]][coordinates[0]] = " "

                current_chain.update_mirror_status_reverse()
                
                # Remove the last amino
                del current_chain.chain_list[-1]
                continue

            # print(str(new_score) + " + " + str(extra_score_possible) + " = " + str(max_possible))
            
          
            # print("max possible score: " + str(extra_score_possible + new_score))
            # print(str(removed_even), str(removed_odd))
            # print(new_score)
            # print()

            # The actual recursive function
            find_best_chain(current_chain, chars, ch_score, new_score, max_lookahead)

            # Undo all the changed to the spots that were made before calling the recursive function.
            current_chain.add_back_even(removed_even, "H")
            current_chain.add_back_odd(removed_odd, "H")
            current_chain.add_back_even(removed_even_C, "C")
            current_chain.add_back_odd(removed_odd_C, "C")
            current_chain.remove_fold_spots(spots_to_add, "H")
            current_chain.remove_fold_spots(spots_to_add_C, "C")
            
                    
            # Change odd/even back
            current_chain.odd = not current_chain.odd

            # Reverse the fold spots
            current_chain.add_fold_spots(spots_to_remove, "H")
            current_chain.add_fold_spots(spots_to_remove_C, "C")
            
            
            # Reverse the matrix and mirror status
            if mode_3d:
                current_chain.matrix[coordinates[2]][coordinates[1]][coordinates[0]]
            else:
                current_chain.matrix[coordinates[1]][coordinates[0]] = " "
            current_chain.update_mirror_status_reverse()
            
            current_lookahead -= 1
            del current_chain.chain_list[-1]