def BB_connectivity(at_connections,cg_connections, cg_residues, at_residues, residue_number, N_ter, C_ter): #### connect to preceeding backbone bead in chain new_chain=False try: xyz_cur = cg_residues[residue_number]['BB']['coord'] xyz_prev = cg_residues[residue_number-1]['BB']['coord'] dist=gen.calculate_distance(xyz_prev, xyz_cur) if dist < 5: cg_n = cg_residues[residue_number-1]['BB']['coord'] at_n = at_residues[N_ter]['coord'] cg_connections.append(cg_n) at_connections.append(at_n) except: pass #### connect to next backbone bead in chain try: xyz_cur = cg_residues[residue_number]['BB']['coord'] xyz_next = cg_residues[residue_number+1]['BB']['coord'] dist=gen.calculate_distance(xyz_next, xyz_cur) if dist < 5: cg_c = cg_residues[residue_number+1]['BB']['coord'] at_c = at_residues[C_ter]['coord'] cg_connections.append(cg_c) at_connections.append(at_c) else: new_chain=True except: new_chain=True pass return at_connections,cg_connections, new_chain
def check_hydrogens(residue): #### finds the connecting carbons and their associated carbons [carbon atom, hydrogen ref number, connecting ref number] for atom_num, atom in enumerate(residue): resname=residue[atom]['res_type'] break for atom in g_var.hydrogen[resname]: h_coord = [] for group in g_var.sorted_connect[resname]: if atom in g_var.sorted_connect[resname][group]: for hydrogen in g_var.hydrogen[resname][atom]: h_coord.append(residue[hydrogen]['coord']) h_com=np.mean(np.array(h_coord), axis=0) for heavy_bond in g_var.heavy_bond[resname][atom]: for group_check in g_var.sorted_connect[resname]: if heavy_bond in g_var.sorted_connect[resname][group_check] and group_check != group: skip = False if heavy_bond in residue: con_heavy_atom = heavy_bond con_heavy_atom_co = residue[con_heavy_atom]['coord'] else: skip = True if not skip: #### vector between H COM and bonded carbon vector=np.array([h_com[0]-residue[atom]['coord'][0],h_com[1]-residue[atom]['coord'][1],h_com[2]-residue[atom]['coord'][2]]) h_com_f=h_com+vector*2 d1 = gen.calculate_distance(h_com, con_heavy_atom_co) d2 = gen.calculate_distance(h_com_f, con_heavy_atom_co) if d2 < d1: for h_at in g_var.hydrogen[resname][atom]: residue[h_at]['coord']=residue[h_at]['coord']-vector*2 return residue
def shift_sulphur(residue_number, disul_at_info, disul_cg_info, at_residues, cg_residues ): #### to shift sidechains roughly equally the 1st sidechain is shifted to within 3.2A and the second to 2A (pdb2gmx cutoff) if disul_cg_info > residue_number: xyz_cur=np.array([cg_residues[disul_cg_info]['SC1']['coord'][0],cg_residues[disul_cg_info]['SC1']['coord'][1],cg_residues[disul_cg_info]['SC1']['coord'][2]]) cutoff=3.2 else: xyz_cur=np.array([at_residues[disul_cg_info][disul_at_info]['coord'][0],at_residues[disul_cg_info][disul_at_info]['coord'][1],at_residues[disul_cg_info][disul_at_info]['coord'][2]]) cutoff=2 xyz_check=np.array([at_residues[residue_number][disul_at_info]['coord'][0],at_residues[residue_number][disul_at_info]['coord'][1],at_residues[residue_number][disul_at_info]['coord'][2]]) dist=gen.calculate_distance(xyz_check,xyz_cur) #### moves sidechains closer together in increments of 5% of the length of the vector offset=0 if dist >= cutoff: vector=xyz_cur-xyz_check x=0.05 while True: xyz_check_new = xyz_check + ( vector * x ) dist=gen.calculate_distance(xyz_check_new,xyz_cur) if dist >= cutoff: x+=0.05 else: offset = vector * x break #### applies final shift to the rest of the atoms in the sidechain for atom in at_residues[residue_number]: at_residues[residue_number][atom]['coord']=at_residues[residue_number][atom]['coord']+offset return at_residues[residue_number]
def find_connect(coord, P_R, HN, O, at_start, count): disres = [] tree = cKDTree(HN[:, 1:]) for carbonyl in O: ndx = tree.query_ball_point(carbonyl[1:], r=3) if len(ndx) > 0: for at in ndx: HN_resid = coord[int(HN[at][0]) - 1]['residue_id'] O_resid = coord[int(carbonyl[0]) - 1]['residue_id'] if HN_resid in P_R and O_resid in P_R and HN_resid not in [ O_resid - 1, O_resid, O_resid + 1 ]: count += 1 xyz1 = [ coord[int(carbonyl[0]) - 1]['x'], coord[int(carbonyl[0]) - 1]['y'], coord[int(carbonyl[0]) - 1]['z'] ] xyz2 = [ coord[int(HN[at][0]) - 1]['x'], coord[int(HN[at][0]) - 1]['y'], coord[int(HN[at][0]) - 1]['z'] ] dist = (gen.calculate_distance(xyz1, xyz2) / 10) - 0.05 disres.append( '{0:10}{1:10}{2:3}{3:12}{4:12}{5:^12}{6:14}{7:14}{8:5}\n' .format(str(at_start + int(HN[at][0])), str(at_start + int(carbonyl[0])), '1', str(count), '2', '0', str(np.round(dist, 4)), str(np.round(dist + 0.01, 4)), '1')) return count, disres
def check_ringed_lipids(protein): print('Checking for ringed lipids') if not os.path.exists(g_var.merged_directory+'checked_ringed_lipid_de_novo.pdb'): if not os.path.exists(g_var.merged_directory+'merged_cg2at_threaded.pdb'): os.chdir(g_var.merged_directory) merge, merge_coords = read_in_merged_pdbs([], [], protein) ringed=False lipid_atoms = [] with open(g_var.merged_directory+'threaded_lipids.dat', 'w') as ring_ouput: for at_val, atom in enumerate(merge): resname = get_np_resname(at_val) if resname in g_var.np_residues: offset = fetch_start_of_residue_np(at_val, resname) if atom['atom_number']-offset in g_var.heavy_bond[resname]: for at_bond in g_var.heavy_bond[resname][atom['atom_number']-offset]: at_bond -=1 if merge[at_bond+offset]['atom_number'] > merge[at_val]['atom_number']: merge[at_bond+offset]['x'], merge[at_bond+offset]['y'], merge[at_bond+offset]['z'] = np.array(read_in.brute_mic(merge_coords[at_val],merge_coords[at_bond+offset])) merge_coords[at_bond+offset] = merge[at_bond+offset]['x'], merge[at_bond+offset]['y'], merge[at_bond+offset]['z'] dist = gen.calculate_distance(merge_coords[at_val], merge_coords[at_bond+offset]) if 2 < dist < 6: lipid_atoms.append([at_val, at_bond+offset, (np.array(merge_coords[at_val])+np.array(merge_coords[at_bond+offset]))/2]) ring_ouput.write('{0:6}{1:6}{2:2}{3:4}{4:2}{5:7}{6:5}{7:5}{8:5}{9:5}{10:5}{11:5}\n'.format( 'distance: ',str(np.round(dist,2)),'residue: ', merge[at_val]['residue_name'], merge[at_val]['residue_id'], ' atom_1: ', merge[at_val]['atom_name'], 'atom_2: ', merge[at_bond+offset]['atom_name'], 'rough line num: ', at_val, at_bond+offset)) ringed = True if ringed or os.path.exists(g_var.merged_directory+'merged_cg2at_threaded.pdb'): print('Found '+str(len(lipid_atoms))+' abnormal bonds, now attempting to fix.') print('See this file for a complete list: '+g_var.merged_directory+'threaded_lipids.dat') fix_threaded_lipids(lipid_atoms, merge, merge_coords) else: gen.file_copy_and_check(g_var.merged_directory+'MIN/merged_cg2at_de_novo_minimised.pdb', g_var.merged_directory+'checked_ringed_lipid_de_novo.pdb')
def BB_connectivity(at_connections,cg_connections, cg_residues, at_residues, residue_number, BB_bead, resname): con_atoms = {} for atom in at_residues: # resname = at_residues[atom]['res_type'] if at_residues[atom]['atom'] in g_var.res_top[resname]['CONNECT'][BB_bead]['atom']: con_atoms[g_var.res_top[resname]['CONNECT'][BB_bead]['atom'].index(at_residues[atom]['atom'])]=atom new_chain=False for con in con_atoms: con_resid = residue_number+g_var.res_top[resname]['CONNECT'][BB_bead]['dir'][con] if con_resid in cg_residues: xyz_cur = cg_residues[residue_number][BB_bead]['coord'] if g_var.res_top[resname]['CONNECT'][BB_bead]['Con_Bd'][con] in cg_residues[con_resid]: xyz_con = cg_residues[con_resid][g_var.res_top[resname]['CONNECT'][BB_bead]['Con_Bd'][con]]['coord'] if gen.calculate_distance(xyz_con, xyz_cur) < 6: cg_connections.append(xyz_con) at_connections.append(at_residues[con_atoms[con]]['coord']) else: if g_var.res_top[resname]['CONNECT'][BB_bead]['dir'][con] > 0: new_chain=True else: if g_var.res_top[resname]['CONNECT'][BB_bead]['dir'][con] > 0: new_chain=True else: if g_var.res_top[resname]['CONNECT'][BB_bead]['dir'][con] > 0: new_chain=True return at_connections,cg_connections, new_chain
def write_disres(coord, chain, file, at_start, count): P_R = np.array([]) if chain in g_var.atomistic_protein_input_aligned: for key in g_var.atomistic_protein_input_aligned[chain].keys(): P_R = np.append(P_R, np.arange(int(key.split(':')[0]), int(key.split(':')[1])+1)) header = True if not os.path.exists(g_var.working_dir+'PROTEIN/PROTEIN_disres.itp') else False with open(g_var.working_dir+'PROTEIN/PROTEIN_disres.itp', 'a') as disres_out: if header: disres_out.write(';backbone hydrogen bonding distance restraints\n\n') disres_out.write('[ intermolecular_interactions ]\n[ distance_restraints ]\n') disres_out.write('; i j type label funct lo up1 up2 weight') HN, O = [],[] for atom in coord: if atom['residue_name'] in g_var.p_residues and atom['atom_name'] == g_var.res_top[atom['residue_name']]['amide_h']: HN.append([int(atom['atom_number']), atom['x'], atom['y'], atom['z']]) if atom['residue_name'] in g_var.p_residues and atom['atom_name'] == 'O': O.append([int(atom['atom_number']), atom['x'], atom['y'], atom['z']]) HN, O = np.array(HN), np.array(O) tree = cKDTree(HN[:,1:]) for carbonyl in O: ndx = tree.query_ball_point(carbonyl[1:], r=3) if len(ndx) > 0: for at in ndx: if coord[int(HN[at][0])-1]['residue_id'] in P_R and coord[int(carbonyl[0])-1]['residue_id'] in P_R: if coord[int(HN[at][0])-1]['residue_id'] < coord[int(carbonyl[0])-1]['residue_id']-1 or \ coord[int(HN[at][0])-1]['residue_id'] > coord[int(carbonyl[0])-1]['residue_id']+1: count+=1 xyz1 = [coord[int(carbonyl[0])-1]['x'], coord[int(carbonyl[0])-1]['y'], coord[int(carbonyl[0])-1]['z']] xyz2 = [coord[int(HN[at][0])-1]['x'], coord[int(HN[at][0])-1]['y'], coord[int(HN[at][0])-1]['z']] dist = (gen.calculate_distance(xyz1, xyz2)/10)-0.05 disres_out.write('\n{0:10}{1:10}{2:3}{3:12}{4:12}{5:^12}{6:14}{7:14}{8:5}'.format(str(at_start+int(HN[at][0])), str(at_start+int(carbonyl[0])), '1', str(count),'2', '0', str(np.round(dist,4)), str(np.round(dist+0.01,4)), '1')) return len(coord)+at_start, count
def brute_mic(p1, p2): result = None n = 2 if gen.calculate_distance(p1, p2) > 10: for x in range(-n, n + 1): for y in range(-n, n + 1): for z in range(-n, n + 1): rp = p2 + np.dot(g_var.r_b_vec, [x, y, z]) d = gen.calculate_distance(p1, rp) if (result is None) or (result[1] > d): result = (rp, d) if result[1] < 10: return result[0] else: return p2 else: return p2
def read_in_atomistic(protein): #### reset location and check if pdb exists os.chdir(g_var.start_dir) if not os.path.exists(protein): sys.exit('cannot find atomistic protein : '+protein) #### read in atomistic fragments into dictionary residue_list[0]=x,y,z,atom_name atomistic_protein_input={} if g_var.input_directory in protein: chain_count=g_var.chain_count else: chain_count = 0 #### read in pdb ter_residues=[] r_b_vec, r_b_inv = real_box_vectors(g_var.box_vec) with open(protein, 'r') as pdb_input: pdb_lines_atoms = filter_input(pdb_input.readlines(), False) atomistic_protein_input[chain_count]={} for line_nr, line_sep in enumerate(pdb_lines_atoms): if line_sep['residue_name'] in g_var.alt_res_name: line_sep['residue_name'] = g_var.alt_res_name[line_sep['residue_name']] if not gen.is_hydrogen(line_sep['atom_name']) or line_sep['residue_name'] in g_var.mod_residues: if line_sep['residue_name'] in g_var.p_residues: #### sorts out wrong atoms in terminal residues if line_sep['atom_name'] in ['OT', 'O1', 'O2']: line_sep['atom_name']='O' #### makes C_terminal connecting atom variable if 'prev_atom_coord' in locals(): line_sep['x'],line_sep['y'],line_sep['z'] = brute_mic(prev_atom_coord, [line_sep['x'],line_sep['y'],line_sep['z']], r_b_vec) if line_sep['atom_name'] in g_var.res_top[line_sep['residue_name']]['CONNECT']['atoms']: if g_var.res_top[line_sep['residue_name']]['CONNECT']['atoms'][line_sep['atom_name']] > 0: if 'C_ter' in locals() and len(g_var.res_top[line_sep['residue_name']]['CONNECT']['atoms']) <=1: ter_residues.append(line_sep['residue_id']) chain_count+=1 atomistic_protein_input[chain_count]={} C_ter=[line_sep['x'],line_sep['y'],line_sep['z']] C_resid=line_sep['residue_id'] elif 'C_ter' in locals(): N_resid=line_sep['residue_id'] N_ter=[line_sep['x'],line_sep['y'],line_sep['z']] dist=gen.calculate_distance(N_ter, C_ter) if C_resid != N_resid and dist > 3.5: del N_ter, C_ter ter_residues.append(line_sep['residue_id']) chain_count+=1 atomistic_protein_input[chain_count]={} ### new chain key prev_atom_coord = [line_sep['x'],line_sep['y'],line_sep['z']] if line_sep['residue_id'] not in atomistic_protein_input[chain_count]: ## if protein does not exist add to dict atomistic_protein_input[chain_count][line_sep['residue_id']]={} #### adds atom to dictionary, every atom is given a initial mass of zero atomistic_protein_input[chain_count][line_sep['residue_id']][line_sep['atom_number']]={'coord':np.array([line_sep['x'],line_sep['y'],line_sep['z']]),'atom':line_sep['atom_name'], 'res_type':line_sep['residue_name'],'frag_mass':0, 'resid':line_sep['residue_id']} #### if atom is in the backbone list then its mass is updated to the correct one if line_sep['atom_name'] in g_var.res_top[line_sep['residue_name']]['ATOMS']: if line_sep['atom_name'] in line_sep['atom_name'] in g_var.res_top[line_sep['residue_name']]['atom_masses']: atomistic_protein_input[chain_count][line_sep['residue_id']][line_sep['atom_number']]['frag_mass']=g_var.res_top[line_sep['residue_name']]['atom_masses'][line_sep['atom_name']] return atomistic_protein_input, chain_count+1
def get_atom_move(merge_temp, resname, residue, chiral_group, chiral_atoms): stat = merge_temp[chiral_atoms[residue][chiral_group]].copy() atom_move = {'stat':np.array([stat['x'],stat['y'],stat['z']]), 'm':'', 'c1':'', 'c2':'', 'c3':''} for chir_atom in atom_move: if chir_atom != 'stat': test = merge_temp[chiral_atoms[residue][g_var.res_top[resname]['CHIRAL'][chiral_group][chir_atom]]].copy() atom_move[chir_atom]= np.array([test['x'],test['y'],test['z']]) if gen.calculate_distance(atom_move['stat'], atom_move[chir_atom]) > 10: atom_move[chir_atom] = np.array(read_in.brute_mic(atom_move['stat'],atom_move[chir_atom])) return atom_move
def shrink_coordinates(c1, c2): vector = c1 - c2 scale = 0.05 while True: new_c1 = c1 - (vector * scale) new_c2 = c2 + (vector * scale) dist = gen.calculate_distance(new_c1, new_c2) if dist > 2.1: scale += 0.0025 elif dist < 1.9: scale -= 0.001 else: return new_c1, new_c2
def rotate(at_connections, cg_connections, same): xyz_rot_apply = [] #### iterates through rotation matrices for xyz_rot in [f_loc.x_rot, f_loc.y_rot, f_loc.z_rot]: dist = [] #### iterates through rotation matrices for rot_val, rotation in enumerate(xyz_rot): #### applies matrix to coordinates saved as check check = at_connections.dot(rotation) #### for each connection the distance is calculated and added to list individual_connections = [] for connect in range(len(cg_connections)): individual_connections.append( gen.calculate_distance(check[connect], cg_connections[connect])) #### for each rotation the connection distances are added to dist list dist.append(individual_connections) #### the RMS is calculated for each rotation dist = np.array(dist) inter = np.sqrt(np.mean(dist**2, axis=1)) if len(dist[0]) == 2: if np.all(cg_connections[0] == cg_connections[1]): ratio = dist / np.min(dist, axis=1)[:, np.newaxis] rotation_index = np.argmin(inter[np.where( np.sum(ratio, axis=1) < np.min(np.sum(ratio, axis=1)) * 1.02)]) for i in range(len(ratio)): if np.all(ratio[i] < 1.05): if 'rotation_RMS' in locals(): if inter[i] < rotation_RMS: rotation_RMS = inter[i] rotation_index = i else: rotation_RMS = inter[i] rotation_index = i else: rotation_index = np.argmin(inter) else: rotation_index = np.argmin(inter) #### the rotation with the lowest RMS applied to the at_connections at_connections = at_connections.dot(xyz_rot[rotation_index]) #### the optimal rotation is added to xyz_rot_apply list as radians xyz_rot_apply.append(np.radians(rotation_index * 5)) return xyz_rot_apply
def find_closest_cysteine(at_connections, cg_connections, cg_residues, group, residue_number): disulphide, atom_number=False, 0 for res_id in cg_residues: try: #### checks distance between cysteines if closer than 7A then adds another connection between the S and the sidechain of the other cysteine CG bead if cg_residues[res_id]['SC1']['residue_name'] == 'CYS' and res_id not in [residue_number-1, residue_number, residue_number+1]: xyz_cur=[cg_residues[residue_number]['SC1']['coord'][0],cg_residues[residue_number]['SC1']['coord'][1],cg_residues[residue_number]['SC1']['coord'][2]] ### cysteine of interest xyz_check=[cg_residues[res_id]['SC1']['coord'][0],cg_residues[res_id]['SC1']['coord'][1],cg_residues[res_id]['SC1']['coord'][2]] ### cysteine to check distance dist = gen.calculate_distance(xyz_check, xyz_cur) if dist < g_var.cys: for atom_number in group['SC1']: if group['SC1'][atom_number]['atom']==f_loc.backbone[cg_residues[residue_number]['SC1']['residue_name']]['sul']: ### if sulphur at_connections.append(group['SC1'][atom_number]['coord']) ### add at centered coordinates cg_connections.append(cg_residues[res_id]['SC1']['coord']) ### add cg centered coordinates disulphide=True break except: pass return at_connections, cg_connections, disulphide, atom_number, res_id
def read_in_atomistic(protein, cg_chain_count, sequence, check_alignment): #### reset location and check if pdb exists os.chdir(g_var.start_dir) if not os.path.exists(protein): sys.exit('cannot find atomistic protein : '+protein) #### read in atomistic fragments into dictionary residue_list[0]=x,y,z,atom_name atomistic_protein_input={} chain_count=0 #### read in pdb ter_residues=[] with open(protein, 'r') as pdb_input: atomistic_protein_input[chain_count]={} for line_nr, line in enumerate(pdb_input.readlines()): #### separate line run=False ## turns to true is line is a bead/atom if line.startswith('ATOM'): line_sep = gen.pdbatom(line) # print(line_sep['atom_name']) if line_sep['residue_name'] in f_loc.mod_residues: run=True elif str.isdigit(line_sep['atom_name'][0]) and line_sep['atom_name'][1] != 'H': run=True elif not str.isdigit(line_sep['atom_name'][0]) and not line_sep['atom_name'].startswith('H'): run=True #### if line is correct if run: if line_sep['residue_name'] in f_loc.p_residues or line_sep['residue_name'] in f_loc.mod_residues: if not line_sep['atom_name'].startswith('H') or line_sep['residue_name'] in f_loc.mod_residues: #### sorts out wrong atoms in terminal residues if line_sep['atom_name'] in ['OT', 'O1', 'O2']: line_sep['atom_name']='O' #### makes C_terminal connecting atom variable if line_sep['atom_name'] == f_loc.backbone[line_sep['residue_name']]['C_ter']: C_ter=[line_sep['x'],line_sep['y'],line_sep['z']] C_resid=line_sep['residue_id'] C=True try: #### tries to make a N_terminal connecting atom variable if line_sep['atom_name'] == f_loc.backbone[line_sep['residue_name']]['N_ter']: N_resid=line_sep['residue_id'] N_ter=[line_sep['x'],line_sep['y'],line_sep['z']] N=True #### measures distance between N and C atoms. if the bond is over 3 A it counts as a new protein dist=gen.calculate_distance(N_ter, C_ter) if N and C and C_resid != N_resid and dist > 3.5:# and aas[line_sep['residue_name']] != sequence[chain_count][line_sep['residue_id']]: N_ter, C_ter=False, False ter_residues.append(line_sep['residue_id']) chain_count+=1 atomistic_protein_input[chain_count]={} ### new chain key except: pass if line_sep['residue_id'] not in atomistic_protein_input[chain_count]: ## if protein does not exist add to dict atomistic_protein_input[chain_count][line_sep['residue_id']]={} #### adds atom to dictionary, every atom is given a initial mass of zero atomistic_protein_input[chain_count][line_sep['residue_id']][line_sep['atom_number']]={'coord':np.array([line_sep['x'],line_sep['y'],line_sep['z']]),'atom':line_sep['atom_name'], 'res_type':line_sep['residue_name'],'frag_mass':0, 'resid':line_sep['residue_id']} #### if atom is in the backbone list then its mass is updated to the correct one if line_sep['atom_name'] in f_loc.backbone[line_sep['residue_name']]['atoms']: for atom in line_sep['atom_name']: if atom in g_var.mass: atomistic_protein_input[chain_count][line_sep['residue_id']][line_sep['atom_number']]['frag_mass']=g_var.mass[atom] else: if check_alignment: sys.exit('The residue '+line_sep['residue_name']+' does not exist in the fragment database') if check_alignment: seq_user = check_sequence(atomistic_protein_input, chain_count+1) atomistic_protein_input = align_chains(atomistic_protein_input, seq_user, sequence) #### check if number of monomers is the same elif chain_count+1 != cg_chain_count: sys.exit('number of chains in atomistic protein input ('+str(chain_count+1)+') does not match CG representation ('+str(cg_chain_count)+')') return atomistic_protein_input
def fix_chirality(merge, merge_temp, merged_coords, residue_type): #### fixes chiral groups r_b_vec, r_b_inv = read_in.real_box_vectors(g_var.box_vec) chiral_atoms, coord = fetch_chiral_coord(merge_temp, residue_type) for residue in chiral_atoms: if residue_type in ['PROTEIN', 'OTHER']: for atom in chiral_atoms[residue]: resname = merge_temp[chiral_atoms[residue] [atom]]['residue_name'] break else: resname = residue_type for chiral_group in g_var.res_top[resname]['CHIRAL']: if chiral_group != 'atoms': stat = merge_temp[chiral_atoms[residue][chiral_group]].copy() atom_move = { 'stat': np.array([stat['x'], stat['y'], stat['z']]), 'm': '', 'c1': '', 'c2': '', 'c3': '' } for chir_atom in atom_move: if chir_atom != 'stat': test = merge_temp[chiral_atoms[residue] [g_var.res_top[resname]['CHIRAL'] [chiral_group][chir_atom]]].copy() atom_move[chir_atom] = np.array( [test['x'], test['y'], test['z']]) if gen.calculate_distance(atom_move['stat'], atom_move[chir_atom]) > 10: atom_move[chir_atom] = np.array( read_in.brute_mic(atom_move['stat'], atom_move[chir_atom], r_b_vec)) S_M = atom_move['m'] - atom_move['stat'] rotation = align_to_vector(S_M, [0, 0, 1]) c1_coord = (atom_move['c1'] - atom_move['stat']).dot(rotation) c2_coord = (atom_move['c2'] - atom_move['stat']).dot(rotation) c3_coord = (atom_move['c3'] - atom_move['stat']).dot(rotation) if gen.angle_clockwise(c1_coord[0:2], c2_coord[0:2]) > gen.angle_clockwise( c1_coord[0:2], c3_coord[0:2]): for ax_val, axis in enumerate(['x', 'y', 'z']): merge_temp[chiral_atoms[residue][ g_var.res_top[resname]['CHIRAL'][chiral_group] ['m']]][axis] = merge_temp[chiral_atoms[residue][ g_var.res_top[resname]['CHIRAL'][chiral_group] ['m']]][axis] - (3 * S_M[ax_val]) merge_temp[chiral_atoms[residue] [chiral_group]][axis] = merge_temp[ chiral_atoms[residue] [chiral_group]][axis] - (S_M[ax_val]) coord[chiral_atoms[residue] [g_var.res_top[resname]['CHIRAL'][chiral_group] ['m']]] -= (2 * S_M) #move_coord - coord[chiral_atoms[residue][chiral_group]] -= ( 0.25 * S_M) #stat_coord - merge += merge_temp merged_coords += coord return merge, merged_coords