def gen_rot_matrix_ref(parejas): """ Genera la matriz de rotacion por medio de las coordendas de las parejas seleccionadas :param parejas: :return: proteina rotada y trasladada, proteina a comparar, matriz de rotacion, baricentro de parejas """ # aveces truena si los pdbs no tienen los numeros de residuos continuos. coord_new_1 = [[ res.GetAtom('CA').coord for res in res_conclq_1 if i[0] == res.resx ] for i in parejas] coord_new_2 = [[ res.GetAtom('CA').coord for res in res_conclq_2 if i[1] == res.resx ] for i in parejas] coord_new_1 = np.array([y for x in coord_new_1 for y in x], dtype=np.float) coord_new_2 = np.array([y for x in coord_new_2 for y in x], dtype=np.float) bari_new_1 = coord_new_1.mean(0) bari_new_2 = coord_new_2.mean(0) vecs_center_1 = coord_new_1 - bari_new_1 vecs_center_2 = coord_new_2 - bari_new_2 # Se genera matriz de rotacion con vectores centricos de parejas anteriores matriz_R = fc.matrix_R(vecs_center_1, vecs_center_2) matriz_rotacion = fc.rotation_matrix(matriz_R) # se aplica matriz de rotacion a coordenadas de proteina a rotar # la proteina consiste en solo carbonos alfa vector_rotado = fc.rotation_vectors(vecs_center_cnclq_1, matriz_rotacion) protein_trasladado_rotado = vector_rotado + bari_new_2 protein_to_compare = coord_conclq_2 return (protein_trasladado_rotado, protein_to_compare, matriz_rotacion, bari_new_2)
def align_residues(idx, so): clique_in_protein_1 = df_rmsd_1[idx, 3] # se extrae el indice de los cliques clique_in_protein_2 = df_rmsd_1[idx, 4] # se obtienen el numero de residuo de los candidatos los_del_clique_1 = df_new_df_clique1[clique_in_protein_1, [0, 1, 2, 3, 4, 5, 6]] los_del_clique_2 = df_new_df_clique2[clique_in_protein_2, [0, 1, 2, 3, 4, 5, 6]] baricentros_1 = new_df_cliques1.baricentro_clique.values # Comprension de lista lista_vectores_gorro = [[ coord - bari for coord in df_atoms1[(df_atoms1.atom_name == 'CA') & (df_atoms1.residue_number.isin( los_del_clique_1) == False)].vector.values ] for bari in baricentros_1] vectores_gorro_proteina_1 = pd.DataFrame(lista_vectores_gorro) df_vectores_gorro_proteina_1 = vectores_gorro_proteina_1.values # OJO se extrae por indice no por numero de atomos!!! atoms1 = df_atoms1[(df_atoms1.atom_name == 'CA') & ( df_atoms1.residue_number.isin(los_del_clique_1) == False)].index.values atoms2 = df_atoms2[(df_atoms2.atom_name == 'CA') & ( df_atoms2.residue_number.isin(los_del_clique_2) == False)].index.values # se guardan los vectores protein_to_compare = np.array( [vectors for vectors in df_atoms2.iloc[atoms2].vector.values]) matriz_rotacion = df_rmsd_1[ idx, 2] # se obtiene la matriz de rotacion de los cliques candidatos # se obtienen los vectores gorro de la proteina a rotar y trasladar vector_gorro = df_vectores_gorro_proteina_1[clique_in_protein_1] # se aplica la rotacion a vectores gorro coord_vectores_rotados = [ np.matmul(matriz_rotacion, i.reshape(3, 1)).T[0] for i in vector_gorro ] # se obtiene el baricentro de la proteina 2 baricentro_proteina_2 = df_new_df_clique2[clique_in_protein_2, 22] # print(baricentro_proteina_2) # se suma el baricentro a vectores rotados de la proteina 1 protein_trasladado_rotado = coord_vectores_rotados + baricentro_proteina_2 # nuevas coordendas proteina 1 # se quitan residuos que pertenezcan al clique candidato para calcular la distancia y emparejar al mejor. protein_trasladado_rotado_sin_clique = protein_trasladado_rotado protein_to_compare_sin_clique = protein_to_compare residuos_match = [] # aqui se guardan las parejas de residuos # se itera por cada residuo ya rotado y trasladado for residuo_not_in_clique, res_1 in zip( protein_trasladado_rotado_sin_clique, atoms1): for residuo, res_2 in zip(protein_to_compare_sin_clique, atoms2): distancia = pdist(np.array([residuo_not_in_clique, residuo]), metric='euclidean').item() if distancia < 3.5: residuos_match.append([distancia, (res_1, res_2)]) residuos_match = sorted(residuos_match) c1 = [] c2 = [] cand_n = [] for i in residuos_match: if (i[1][0] in c1) or (i[1][1] in c2) or (i[0] > 3.5): continue else: c1.append(i[1][0]) c2.append(i[1][1]) cand_n.append(i) parejas = [i[1] for i in cand_n] def R_ij(i, j, parejas=parejas): valor = sum([ vecs_center_1[pos_res[0], i] * vecs_center_2[pos_res[1], j] for pos_res in parejas ]) return valor def matrix_R(): """cliques a comparar: i,j desde aqui se itera sobre cada i y hay que variar los vectores coordenada Regresa la matriz gigante (matriz simetrica del articulo)""" # primer renglon R11R22R33 = (R_ij(0, 0) + R_ij(1, 1) + R_ij(2, 2)) R23_R32 = (R_ij(1, 2) - R_ij(2, 1)) R31_R13 = (R_ij(2, 0) - R_ij(0, 2)) R12_R21 = (R_ij(0, 1) - R_ij(1, 0)) # segundo renglon R11_R22_R33 = (R_ij(0, 0) - R_ij(1, 1) - R_ij(2, 2)) R12R21 = (R_ij(0, 1) + R_ij(1, 0)) R13R31 = (R_ij(0, 2) + R_ij(2, 0)) # tercer renglon _R11R22_R33 = (-R_ij(0, 0) + R_ij(1, 1) - R_ij(2, 2)) R23R32 = (R_ij(1, 2) + R_ij(2, 1)) # cuarto renglon _R11_R22R33 = (-R_ij(0, 0) - R_ij(1, 1) + R_ij(2, 2)) matriz_R = [[R11R22R33, R23_R32, R31_R13, R12_R21], [R23_R32, R11_R22_R33, R12R21, R13R31], [R31_R13, R12R21, _R11R22_R33, R23R32], [R12_R21, R13R31, R23R32, _R11_R22R33]] return (matriz_R) matriz_R = matrix_R() matriz_rotacion = fc.rotation_matrix(matriz_R) vector_rotado = fc.rotation_vectors(vecs_center_1, matriz_rotacion) vector_rotado_trasladado_a_clique2 = vector_rotado + np.array(bari_2) protein_trasladado_rotado = vector_rotado_trasladado_a_clique2 protein_to_compare = vecs2 residuos_match = [] for residuo_1, res_1 in zip(protein_trasladado_rotado, atoms_numbers1): for residuo_2, res_2 in zip(protein_to_compare, atoms_numbers2): distancia = pdist(np.array([residuo_1, residuo_2]), metric='euclidean').item() if distancia < 3.5: residuos_match.append([distancia, (res_1, res_2)]) residuos_match = sorted(residuos_match) c1 = [] c2 = [] cand_n = [] for i in residuos_match: if (i[1][0] in c1) or (i[1][1] in c2) or (i[0] > 3.5): continue else: c1.append(i[1][0]) c2.append(i[1][1]) cand_n.append(i) df = pd.DataFrame(cand_n, columns=['distancia', 'candigatos']) so_temp = len(cand_n) / number_of_residues_final return idx, so_temp, df, matriz_rotacion
break print('ya termine de alinear residuo a residuo') print(id_so, round(so, 5), df_candidatos.distancia.mean(), df_candidatos) # new_df_cliques1.to_pickle('clique1.pkl') # new_df_cliques2.to_pickle('clique2.pkl') # df_atoms1.to_pickle('clique1_df_atributos.pkl') # df_atoms2.to_pickle('clique2_df_atributos.pkl') # df_candidatos.to_pickle('df_alineados.pkl') # pd.DataFrame(parejas_clique).to_pickle('parejas.pkl') # df_rmsd.to_pickle('df_rmsd.pkl') # matriz_R = matrix_R() # matriz_rotacion = rotation_matrix(matriz_R) vector_rotado = fc.rotation_vectors(vecs_center_1, matriz_rotacion) vector_rotado_trasladado_a_clique2 = vector_rotado + np.array(bari_2) protein_trasladado_rotado = vector_rotado_trasladado_a_clique2 protein_to_compare = vecs2 new_df_atom1 = pd.concat([ df_atoms1, pd.DataFrame(protein_trasladado_rotado, columns=['x', 'y', 'z']) ], 1) new_df_atom1['new_vector'] = [[ new_df_atom1.iloc[i]['x'], new_df_atom1.iloc[i]['y'], new_df_atom1.iloc[i]['z'] ] for i in range(new_df_atom1.shape[0])] for i in pdb11: mask = np.where(i.resi == new_df_atom1.residue_number, True, False)
# print('***********************************************************') # print(val, cand_1, cand_2) res_sinclq_1 = [res for res in pdb11 if res.resx not in cand_1] res_sinclq_2 = [res for res in pdb22 if res.resx not in cand_2] coord_sinclq_1 = np.array( [res.GetAtom('CA').coord for res in res_sinclq_1], dtype=np.float) coord_sinclq_2 = np.array( [res.GetAtom('CA').coord for res in res_sinclq_2], dtype=np.float) bari_1 = coord_sinclq_1.mean(0) bari_2 = coord_sinclq_2.mean(0) vecs_center_1 = coord_sinclq_1 - bari_1 # aplico matriz de rotacion de cliques a vectores centricos sin clique vector_rotado = fc.rotation_vectors(vecs_center_1, mat_rot) protein_trasladado_rotado = vector_rotado + bari_2 protein_to_compare = coord_sinclq_2 # apilo la distancia y la pareja de residuos correspondientes si cumple con que el RMSD sea menor a 3.5 residuos_match = fc.fun_resiudos_match(protein_trasladado_rotado, protein_to_compare, res_sinclq_1, res_sinclq_2) # filtro parejas cand_n = fc.filter_pairs(residuos_match, flag=False) # calculo el SO so_temp = round(len(cand_n) / (number_of_residues_final - 7), 4) # print('PRE_SO:', so_temp) so_temp_plus_1 = 0.0