def calculate_phi_psi(u, start, stop, cyclic): u_protein = u.select_atoms("protein") num_res = len(u_protein.residues) num_dihedral = num_res * 2 ags_phi = [res.phi_selection() for res in u_protein.residues[1:]] ags_psi = [res.psi_selection() for res in u_protein.residues[0:-1]] if cyclic: ags_phi = [u_protein.select_atoms("resid %d and name C" % num_res, \ "resid 1 and name N", \ "resid 1 and name CA", \ "resid 1 and name C")] + ags_phi ags_psi += [u_protein.select_atoms("resid %d and name N" % num_res, \ "resid %d and name CA" % num_res, \ "resid 1 and name C", \ "resid 1 and name N")] R_phi = Dihedral(ags_phi).run(start=start, stop=stop) R_psi = Dihedral(ags_psi).run(start=start, stop=stop) phi = R_phi.angles psi = R_psi.angles dihedral_angle = np.hstack((phi, psi)) return dihedral_angle
def calculate_phi_psi(u, start, stop): u_protein = u.select_atoms("protein") num_res = len(u_protein.residues) num_dihedral = num_res * 2 ags_phi = [res.phi_selection() for res in u_protein.residues[1:]] ags_psi = [res.psi_selection() for res in u_protein.residues[0:-1]] R_phi = Dihedral(ags_phi).run(start=start, stop=stop) R_psi = Dihedral(ags_psi).run(start=start, stop=stop) last_psi_group = u_protein.select_atoms("resid " + str(num_res) +\ " and name N", "resid " +\ str(num_res) +\ " and name CA", "resid " +\ str(num_res) +\ " and name C", "resid 1 and name N") first_phi_group = u_protein.select_atoms("resid " +\ str(num_res) +\ " and name C", "resid 1 and name N", "resid 1 and name CA", "resid 1 and name C") first_phi = Dihedral([first_phi_group]).run(start=start, stop=stop) last_psi = Dihedral([last_psi_group]).run(start=start, stop=stop) phi = np.hstack((first_phi.angles, R_phi.angles)) psi = np.hstack((R_psi.angles, last_psi.angles)) dihedral_angle = np.hstack((phi, psi)) return dihedral_angle
def calculate_chirality(u, start, stop): u_protein = u.select_atoms('protein') num_frame = len(u.trajectory) sequence = [str(i)[9:12] for i in u_protein.residues] chirality = np.ones((num_frame, 1)) for i, aa in enumerate(sequence, start=1): if aa == "GLY": chirality_temp = np.empty((num_frame, 1), dtype=str) chirality_temp.fill("L") chirality = np.hstack((chirality, chirality_temp)) else: ags_improper = u_protein.select_atoms("resid %d and name CA" % i, \ "resid %d and name N" % i, \ "resid %d and name C" % i, \ "resid %d and name CB" % i) improper_angles = Dihedral([ags_improper]).run(start=start, stop=stop).angles chirality_temp = np.empty((num_frame, 1), dtype=str) for i, angle in enumerate(improper_angles): if angle == 0: sys.exit( "\nExiting...Ambigious Improper Dihedral Angle...\n") elif angle > 0: chirality_temp[i] = "L" else: chirality_temp[i] = "D" chirality = np.hstack((chirality, chirality_temp)) return chirality[:, 1:]
def torsion_trajectory_analysis(self): torsion_stats = {} for torsion_name, torsion_values in self.env["torsions"]["vars"].items( ): torsion_stats[torsion_name] = {} for torsion_type, torsion_selection in torsion_values.items(): torsion_stats[torsion_name][torsion_type] = {} try: atom_indexes = torsion_selection.split() mda_atom_selection = self.mda_universe.select_atoms( "index " + atom_indexes[0], "index " + atom_indexes[1], "index " + atom_indexes[2], "index " + atom_indexes[3], ) except: mda_atom_selection = self.mda_universe.select_atoms( torsion_selection) mda_dihedral = Dihedral([mda_atom_selection]) torsion_angles = self.atom_selection_torsions_for_trajectory( mda_dihedral) torsion_name_dir = self._set_torsion_angles_dir(torsion_name) torsion_type_file_path = os.path.join(torsion_name_dir, torsion_type + ".dat") self._write_trajectory_atom_selection_torsions_to_file( torsion_angles, torsion_type_file_path) torsion_stats[torsion_name][ torsion_type] = self.stats_analysis(torsion_angles) torsion_stats[torsion_name][torsion_type][ "torsion_angles"] = torsion_angles time_series = np.arange(0, self.get_trajectory_time_in_ns(), self.ns_per_frame()) self.time_series_scatter(time_series, torsion_angles, torsion_name_dir, torsion_type) self.probability_histogram(torsion_angles, torsion_name_dir, torsion_type) torsion_stats_file_path = os.path.join( torsion_name_dir, torsion_name + "_torsion_angle_stats.txt") self._write_torsion_stats(torsion_stats, torsion_stats_file_path) self._create_additional_torsional_plots(torsion_name, torsion_name_dir, torsion_stats)
def test_atomgroup_list(self, atomgroup): dihedral = Dihedral([atomgroup, atomgroup]).run() test_dihedral = np.load(DihedralsArray) assert_almost_equal(dihedral.angles, test_dihedral, 5, err_msg="error: dihedral angles should " "match test values")
def test_dihedral_single_frame(self, atomgroup): dihedral = Dihedral([atomgroup]).run(start=5, stop=6) test_dihedral = [np.load(DihedralArray)[5]] assert_almost_equal(dihedral.angles, test_dihedral, 5, err_msg="error: dihedral angles should " "match test vales")
def calculate_omega(u, start, stop, cyclic): u_protein = u.select_atoms('protein') num_res = len(u_protein.residues) ags_omega = [res.omega_selection() for res in u_protein.residues[:-1]] if cyclic: ags_omega += [u_protein.select_atoms("resid %d and name CA" % num_res, \ "resid %d and name C" % num_res, \ "resid 1 and name N", \ "resid 1 and name CA")] R_omega = Dihedral(ags_omega).run(start=start, stop=stop) return R_omega.angles
def main(): ref, traj, at = parser() u = Universe(ref, traj) if at == 'X2': atomgroups = chi2_selection(u) elif at == 'X1': atomgroups = [res.chi1_selection() for res in u.residues] atomgroups = [ ele for ele in atomgroups if ele ] # this is for eliminating None element from atomgroups. "if ele" works only if ele is not empty (None). elif at == 'CH3': atomgroups = rotCH3(u) columns = make_columns(atomgroups) #for table's column # Each atom group must contain 4 atoms. R = Dihedral(atomgroups).run() # values are stored in R.angles df = pd.DataFrame(R.angles, columns=columns) df.to_csv(f'{at}.csv')
def compute_simple_protein_features(u, key_res): """ This function takes the PDB code, chain id and certain coordinates of a kinase from a command line and returns its structural features. Parameters ---------- u : object A MDAnalysis.core.universe.Universe object of the input structure (a pdb file or a simulation trajectory). key_res : dict of int A dictionary (with keys 'group0' ... 'group4') of feature-related residue indices in five feature groups. Returns ------- features: list of floats A list (single structure) or lists (multiple frames in a trajectory) of 72 features in 5 groups (A-loop, P-loop, aC, DFG, FRET) .. todo :: Use kwargs with sensible defaults instead of relying only on positional arguments. """ from MDAnalysis.core.groups import AtomGroup from MDAnalysis.analysis.dihedrals import Dihedral from MDAnalysis.analysis.distances import dist import numpy as np import pandas as pd # get the array of atom indices for the calculation of: # * seven dihedrals (a 7*4 array where each row contains indices of the four atoms for each dihedral) # * two ditances (a 2*2 array where each row contains indices of the two atoms for each dihedral) dih = np.zeros(shape=(7, 4), dtype=int, order="C") dis = np.zeros(shape=(2, 2), dtype=int, order="C") # name list of the dihedrals and distances dih_names = ["xDFG_phi", "xDFG_psi", "dFG_phi", "dFG_psi", "DfG_phi", "DfG_psi", "DfG_chi1"] dis_names = ["DFG_conf1", "DFG_conf2", "DFG_conf3", "DFG_conf4"] # parse the topology info (0-based atom indices) ### dihedrals (feature group 3) # dihedral 0 & 1: X-DFG Phi & Psi dih[0][0] = int(u.select_atoms(f"resid {key_res['group3'][0]-1} and name C")[0].ix) # xxDFG C dih[0][1] = int(u.select_atoms(f"resid {key_res['group3'][0]} and name N")[0].ix) # xDFG N dih[0][2] = int(u.select_atoms(f"resid {key_res['group3'][0]} and name CA")[0].ix) # xDFG CA dih[0][3] = int(u.select_atoms(f"resid {key_res['group3'][0]} and name C")[0].ix) # xDFG C dih[1][0] = dih[0][1] # xDFG N dih[1][1] = dih[0][2] # xDFG CA dih[1][2] = dih[0][3] # xDFG C dih[1][3] = int(u.select_atoms(f"resid {key_res['group3'][1]} and name N")[0].ix) # DFG-Asp N # dihedral 2 & 3: DFG-Asp Phi & Psi dih[2][0] = dih[0][3] # xDFG C dih[2][1] = dih[1][3] # DFG-Asp N dih[2][2] = int( u.select_atoms(f"resid {key_res['group3'][1]} and name CA")[0].ix ) # DFG-Asp CA dih[2][3] = int(u.select_atoms(f"resid {key_res['group3'][1]} and name C")[0].ix) # DFG-Asp C dih[3][0] = dih[2][1] # DFG-Asp N dih[3][1] = dih[2][2] # DFG-Asp CA dih[3][2] = dih[2][3] # DFG-Asp C dih[3][3] = int(u.select_atoms(f"resid {key_res['group3'][2]} and name N")[0].ix) # DFG-Phe N # dihedral 4 & 5: DFG-Phe Phi & Psi dih[4][0] = dih[2][3] # DFG-Asp C dih[4][1] = dih[3][3] # DFG-Phe N dih[4][2] = int( u.select_atoms(f"resid {key_res['group3'][2]} and name CA")[0].ix ) # DFG-Phe CA dih[4][3] = int(u.select_atoms(f"resid {key_res['group3'][2]} and name C")[0].ix) # DFG-Phe C dih[5][0] = dih[4][1] # DFG-Phe N dih[5][1] = dih[4][2] # DFG-Phe CA dih[5][2] = dih[4][3] # DFG-Phe C dih[5][3] = int( u.select_atoms(f"resid {key_res['group3'][2]+1} and name N")[0].ix ) # DFG-Gly N # dihedral 6: DFG-Phe Chi1 dih[6][0] = dih[3][3] # DFG-Phe N dih[6][1] = dih[4][2] # DFG-Phe CA dih[6][2] = int( u.select_atoms(f"resid {key_res['group3'][2]} and name CB")[0].ix ) # DFG-Phe CB dih[6][3] = int( u.select_atoms(f"resid {key_res['group3'][2]} and name CG")[0].ix ) # DFG-Phe CG ### distances ## Dunbrack distances D1, D2 dis[0][0] = int(u.select_atoms(f"resid {key_res['group3'][3]} and name CA")[0].ix) # ExxxX CA dis[0][1] = int( u.select_atoms(f"resid {key_res['group3'][2]} and name CZ")[0].ix ) # DFG-Phe CZ dis[1][0] = int( u.select_atoms(f"resid {key_res['group2'][3]} and name CA")[0].ix ) # K in beta III CA dis[1][1] = dis[0][1] # DFG-Phe CZ # check if there is any missing coordinates; if so, skip dihedral/distance calculation for those residues check_flag = 1 for i in range(len(dih)): if 0 in dih[i]: dih[i] = [0, 0, 0, 0] check_flag = 0 for i in range(len(dis)): if 0 in dis[i]: dis[i] = [0, 0] check_flag = 0 if check_flag: print("There is no missing coordinates. All dihedrals and distances will be computed.") # compute dihedrals and distances distances = list() dih_ags = list() for i in range(7): # for each of the dihedrals dih_ags.append(AtomGroup(dih[i], u)) dihedrals = Dihedral(dih_ags).run().angles each_frame = list() for i in range(2): ag0 = AtomGroup([dis[i][0]], u) # first atom in each atom pair ag1 = AtomGroup([dis[i][1]], u) # second atom in each atom pair each_frame.append(dist(ag0, ag1)[-1][0]) each_frame = np.array(each_frame) distances.append(each_frame) # clean up del u, dih, dis return dihedrals, distances
def __init__( self, atom_group, cache_path="", start=None, stop=None, step=None, ): """ :param atom_group: MDAnalysis atom group :param cache_path: Allows to define a path where the calculated variables can be cached. :param start: first frame to analyze :param stop: last frame to analyze :param step: step of the analyzes """ self.universe = atom_group.universe self.sorted_atoms = self.universe.atoms[[ atom.ix for atom in sorted(atom_group.atoms, key=self.sort_key) ]] self.central_atom_indices = [ i for i, atom in enumerate(self.sorted_atoms) if atom.name in ["N", "CA", "C"] ] self.central_atoms = self.sorted_atoms[self.central_atom_indices] # Cartesians: try: self.cartesians = np.load( os.path.join(cache_path, "cartesians.npy")) print("Loaded cartesians from {}".format(cache_path)) except FileNotFoundError: print("Loading Cartesians...") positions = Positions(self.sorted_atoms, verbose=True).run(start=start, stop=stop, step=step) self.cartesians = positions.result.astype(np.float32) if cache_path: np.save(os.path.join(create_dir(cache_path), "cartesians.npy"), self.cartesians) self.central_cartesians = self.cartesians[:, self.central_atom_indices] # Dihedrals: try: self.dihedrals = np.load(os.path.join(cache_path, "dihedrals.npy")) print("Loaded dihedrals from {}".format(cache_path)) except FileNotFoundError: print("Calculating dihedrals...") dihedral_atoms = [] for i in OrderedDict.fromkeys(self.sorted_atoms.resnums): phi_atoms = (self.sorted_atoms.select_atoms( "resnum {} and name C".format(i - 1) ) + self.sorted_atoms.select_atoms( "resnum {} and (name N or name CA or name C)".format(i))) if len(phi_atoms) == 4: dihedral_atoms.append(phi_atoms.dihedral) psi_atoms = (self.sorted_atoms.select_atoms( "resnum {} and (name N or name CA or name C)".format(i)) + self.sorted_atoms.select_atoms( "resnum {} and name N".format(i + 1))) if len(psi_atoms) == 4: dihedral_atoms.append(psi_atoms.dihedral) omega_atoms = ( self.sorted_atoms.select_atoms( "resnum {} and (name CA or name C)".format(i)) + self.sorted_atoms.select_atoms( "resnum {} and (name N or name CA)".format(i + 1))) if len(psi_atoms) == 4: dihedral_atoms.append(omega_atoms.dihedral) dihedrals = Dihedral(dihedral_atoms, verbose=True).run(start=start, stop=stop, step=step) self.dihedrals = dihedrals.angles.astype(np.float32) self.dihedrals *= pi / 180 if cache_path: np.save(os.path.join(cache_path, "dihedrals.npy"), self.dihedrals) # Angles: try: self.angles = np.load(os.path.join(cache_path, "angles.npy")) print("Loaded angles from {}".format(cache_path)) except FileNotFoundError: print("Calculating angles...") angle_atoms = [] for i in range(len(self.central_atom_indices) - 2): angle_atoms.append( self.sorted_atoms[self.central_atom_indices[i:i + 3]]) angles = Angles(angle_atoms, verbose=True).run(start=start, stop=stop, step=step) self.angles = angles.result.astype(np.float32) if cache_path: np.save(os.path.join(create_dir(cache_path), "angles.npy"), self.angles) # Lengths: try: self.lengths = np.load(os.path.join(cache_path, "lengths.npy")) print("Loaded lengths from {}".format(cache_path)) except FileNotFoundError: print("Calculating lengths...") vecs = self.central_cartesians[:, : -1] - self.central_cartesians[:, 1:] self.lengths = np.linalg.norm(vecs, axis=2) if cache_path: np.save(os.path.join(create_dir(cache_path), "lengths.npy"), self.lengths) assert self.lengths.shape[1] == self.central_cartesians.shape[1] - 1 assert self.angles.shape[1] == self.central_cartesians.shape[1] - 2 assert self.dihedrals.shape[1] == self.central_cartesians.shape[1] - 3
def test_enough_atoms(self, atomgroup): with pytest.raises(ValueError): dihedral = Dihedral([atomgroup[:2]]).run()
end driver maxiter 50 # maximum number of geometry optimization steps end task scf optimize task esp #ESP with restraints (RESP) """ mol = mda.Universe(TOPOLOGY_FILE, TRAJECTORY_FILE) mol_deselect = mol.select_atoms(ATOM_SELECTION) di = mol_deselect.dihedrals all_di_angles = np.round_(Dihedral(di).run().angles, 5).astype(str) di_indices = (di.indices + 1).astype(str) # dihedral indices n_dih = len(di_indices) # number of dihedral angles in molecule di_indices = np.append(np.array([['Torsion']] * n_dih), di_indices, axis=1) names = mol.atoms.names.astype(str).reshape(-1, 1) # atom names print('#' * 52) print('Writing', mol.atoms.n_atoms, 'atom coordinates in', mol.trajectory.n_frames, 'frames') print('Constraining', n_dih, 'out of', len(mol.dihedrals.indices), 'dihedral angles') print('#' * 52) for i, name in enumerate(names): names[i] = name[0][0]