Example #1
0
def mutate(child1, child2, p, proti):
    """
    Causes random mutations of the directions in the conformations.
    """

    # convert to lists to make the tuple mutable
    child1_list = list(child1)
    child2_list = list(child2)

    for i in range(len(child1_list)):

        # random number (0,1)
        r1 = random.random()
        r2 = random.random()

        possible = False
        if r1 < p:

            # save copy
            backup = copy.deepcopy(child1_list[i])

            # check if mutation would be possible without making the conformation invalid
            for d in random.sample(['L', 'R', 'S'], 3):
                child1_list[i] = d
                x, y, z = directions(''.join(child1_list))
                if not double(x, y, z):
                    possible = True 
                    break

            # undo the mutation if it would invalidate the conformation
            if not possible:
                child1_list[i] = backup

        possible = False
        if r2 < p:
            backup = copy.deepcopy(child2_list[i])
            for d in random.sample(['L', 'R', 'S'], 3):
                child2_list[i] = d
                x, y, z = directions(''.join(child2_list))
                if not double(x, y, z):
                    possible = True 
                    break
            if not possible:
                child2_list[i] = backup

    child1_list = ''.join(child1_list)
    child2_list = ''.join(child2_list)

    # return the mutated conformations along with their scores
    x1, y1, z1 = directions(child1_list)
    x2, y2, z2 = directions(child2_list)
    return (child1_list, score_it(proti, x1, y1, z1)), \
        (child2_list, score_it(proti, x2, y2, z2))
Example #2
0
def crossover(parent1, parent2):
    """
    Uses crossover to producre a child from two parents.
    """

    # select point of adjoinment at random
    n = random.randint(0, len(parent1[0]) - 1)

    # get the part of one parent up to the nth element
    partial_parent1 = parent1[0][:n]

    # get the part of the other parent from the n+1th elment onwards
    partial_parent2 = parent2[0][n+1:]

    # try different adjoinment directions
    for d in random.sample(['L', 'R', 'S'],3):
        
        child_string = partial_parent1 + d + partial_parent2
        x, y, z = directions(child_string)
        # return is the conformation is valid
        if not double(x, y, z):
            return child_string

    # indicate that the conformation is invalid
    return ('impossible', 1)
Example #3
0
def create_individual(proti):
    
    conformation = ''
    direction = ['L', 'R', 'S']

    i = 1
    while i < proti.length - 1:
        available_directions = []

        for d in direction: 
            x_pos, y_pos, z_pos = directions(conformation + d)     
            if not double(x_pos, y_pos, z_pos):
                available_directions.append(d)
        
        try:
            random_direction = available_directions[random.randint(0,\
                                                    len(available_directions) - 1)]
            conformation += random_direction
        except:
            i = 0
            conformation = ''
    
        i += 1
  
    return conformation
Example #4
0
def genetic_plot(string, score, best_yet, proti):
    """
    Makes a graph of two lists list_x, list_y.
    """
    
    list_x, list_y, list_z = directions(string)

    # differentiate between types of atom
    red_dots_x = []
    red_dots_y = []
    blue_dots_x = []
    blue_dots_y = []
    yellow_dots_x = []
    yellow_dots_y = []

    # search through protein and place each atom in the appropiate list
    for x, y, p in zip(list_x, list_y, proti.listed):

        if p == 'H':
            red_dots_x.append(x)
            red_dots_y.append(y)
        if p == 'P':
            blue_dots_x.append(x)
            blue_dots_y.append(y)       
        if p == 'C':
            yellow_dots_x.append(x)
            yellow_dots_y.append(y)

    # create graphs with colors
    fig, (ax1, ax2) = plt.subplots(2, 1)
  
    ax1.plot(list_x, list_y, '--', color='darkgrey')
    ax1.plot(red_dots_x, red_dots_y, 'or', markersize=17)
    ax1.plot(blue_dots_x, blue_dots_y, 'ob', markersize=17)
    ax1.plot(yellow_dots_x, yellow_dots_y, 'oy', markersize=17)
    ax1.axis('equal')
    ax1.set_title(f'Folded protein of length {proti.length}, score: {score}')

    ax2.plot(best_yet)
    ax2.set_title('Lowest score per iteration')

    plt.show()
Example #5
0
def initial_population(n, proti):
    """
    Initialize population for tree.
    """
    
    conformations_list = []
    return_list = []

    for i in range(2 * n):
        conformation_string = create_individual(proti)
        x, y, z = directions(conformation_string)
        score = score_it(proti=proti, list_x=x, list_y=y, list_z=z)
        conformation = (conformation_string, score)
        conformations_list.append(conformation)

    conformations_list.sort(key=operator.itemgetter(1))

    for i in range(n):
        return_list.append(conformations_list[i])

    return return_list
Example #6
0
def run(proti):
    # start timer
    start = timeit.default_timer()

    bar  = Bar('Progress', max=proti.length)
    bar.next()
    bar.next()
    k = 0
    amino_time = []

    # specifications for depth first tree building
    depth = proti.length - 2
    q = queue.Queue()
    q.put('')
    final_configurations = []
    
    # keep track of scores per substring
    lowest_score_k = {}
    all_scores_k = {}
    lowest_score = 0
    
    # (0,1) probabilities of pruning a path, lower is more exact but less fast
    p1 = 1
    p2 = 1

    # set inital values
    for i in range(proti.length + 1):
        lowest_score_k[i] = 0
        all_scores_k[i] = [0]

    amino_start = timeit.default_timer()
    # create a breadth first tree
    while not q.empty():

        state = q.get()
        # if all aminos are placed, put the string in a list
        state_x, state_y, state_z = directions(state)
        if len(state) == depth and not double(state_x, state_y, state_z):
            final_configurations.append(state)
      
        if len(state) < depth:
            for i in ['L', 'R', 'S', 'U', 'D']:

                # substring
                child = copy.deepcopy(state) 

                # string after potentialy placing the next amino
                child += i 
                
                child_x, child_y, child_z = directions(child)
                # discard the string folding into themselves
                if double(child_x, child_y, child_z):
                    continue
                
                if len(child) + 1 > k:
                    amino_stop = timeit.default_timer()
                    amino_time.append(amino_stop-amino_start)
                    bar.next()
                    amino_start = timeit.default_timer()

                # identify how for into the string it is
                k = len(child) + 1
                
                # P's are always placed, rest have some conditions
                if not proti.listed[k] == 'P':

                    # score if placed 
                    score = score_it(proti, child_x, child_y, child_z)

                    # min score to get from remaining aminos
                    possible_score = possible_score_func_dee(proti.listed[k+1:],\
                                                         score, proti.min_score, proti)

                    if score + possible_score > lowest_score:
                        continue

                    # random number between 0 and 1
                    r = random.random()

                    # avergage of all strings of the same length
                    average_score_k = sum(all_scores_k[k]) / len(all_scores_k[k])

                    # conditions for pruning
                    if score > average_score_k and r < p1:
                        continue
                    elif (average_score_k >= score and score > lowest_score_k[k])\
                         and r < p2:
                        continue
                    
                    # add to tree
                    q.put(child) 
                    all_scores_k[k].append(score)

                    if score < lowest_score_k[k]:
                        lowest_score_k[k] = copy.deepcopy(score)
                    
                    if score < lowest_score:
                        lowest_score = copy.deepcopy(score)
                        
                else:
                    q.put(child) 

    lowest_score = 0

    # weed out the best configuration from the remaining strings
    for c in final_configurations:
        c_x, c_y, c_z = directions(c)
        if score_it(proti, c_x, c_y, c_z) < lowest_score:
            best_config = copy.deepcopy(c)
            lowest_score = copy.deepcopy(score_it(proti, c_x, c_y, c_z))

    best_x, best_y, best_z = directions(best_config)

    bar.finish()
    # plot the result
    stop = timeit.default_timer()
    print(f'Length: {proti.length}')
    print(f'Score: {lowest_score}')
    print(f'Time: {stop - start}')
    print(f'Conformation: {best_config}')
    plot(proti, lowest_score, best_x, best_y,'Time per amino placement', 'Amino', 'Time[s]', best_z, scores=amino_time)