def get_redundant_internal_coordinates(trajectory, **kwargs): """Compute internal coordinates from the cartesian coordinates This extracts all of the bond lengths, bond angles and dihedral angles from every frame in a trajectory. Parameters ---------- trajectory : msmbuilder.Trajectory Trajectory object containing the internal coordinates Additional Parameters --------------------- ibonds : np.ndarray, optional, shape[n_bonds, 2], dtype=int Each row gives the indices of two atoms involved in a bond iangles : np.ndarray, optional shape[n_angles, 3], dtype=int Each row gives the indices of three atoms which together make an angle idihedrals : np.ndarray, optional, shape[n_dihedrals, 4], dtype=int Each row gives the indices of the four atoms which together make a dihedral Notes ----- ibonds, iangles, and idihedrals will be computed usig the first frame in the trajectory, if not supplied Returns ------- internal_coords : np.ndarray, shape=[n_frames, n_bonds+n_angles+n_dihedrals] All of the internal coordinates collected into a big array, such that internal_coords[i,j] gives the jth coordinate for the ith frame. """ if 'ibonds' in kwargs and 'iangles' in kwargs and 'idihedrals' in kwargs: ibonds = kwargs['ibonds'] iangles = kwargs['iangles'] idihedrals = kwargs['idihedrals'] else: ibonds, iangles, idihedrals = get_connectivity(trajectory) # convert everything to the right shape and C ordering, since # all of these methods are in C and are going to need things to be # the right type. The methods will all do a copy for things that # aren't the right type, but hopefully we can only do the copy once # instead of three times if xyzlist really does need to be reordered # in memory xyzlist = np.array(trajectory['XYZList'], dtype=np.float32, order='c') ibonds = np.array(ibonds, dtype=np.int32, order='c') iangles = np.array(iangles, dtype=np.int32, order='c') idihedrals = np.array(idihedrals, dtype=np.int32, order='c') b = atom_distances(xyzlist, ibonds) a = bond_angles(xyzlist, iangles) d = compute_dihedrals(xyzlist, idihedrals, degrees=False) return np.hstack((b, a, d))
def get_hb(traj): # get accH - donor distance: dists = contact.atom_distances(traj["XYZList"], atom_contacts=which[:, 1:]) # get angles angles = angle.compute_angles(traj, which) hb = ((dists < distance_cutoff) & (angles > angle_cutoff)).astype(int) return hb
def load_trajs(): """Load traejctories from disk """ print 'loading trajs...' # load up ALL of the trajectories trajs = {} atom_indices = np.loadtxt(ATOM_INDICES, int) atom_pairs = np.array(list(itertools.combinations(atom_indices, 2))) traj_filenames = glob.glob(TRAJS_GLOB) # logging.debug('traj filenames %s', traj_filenames) for tfn in traj_filenames: t = mdtraj.trajectory.load(tfn) key = os.path.relpath(tfn, PROJECT_DIR) trajs[key] = contact.atom_distances(t.xyz, atom_pairs) print 'done' return trajs
def contact_reaction_coordinate(trajectory, weights): """ Computes a residue-contact based reaction coordinate. Specifically, the reaction coordinate is a weighted linear combination of the alpha carbon distances for each residue. Weights can take any value, including negative and zero values. Parameters ---------- trajectory : msmbuilder trajectory The trajectory along which to compute the reaction coordinate value weights : nd_array, float The weights to apply to all the inter-residue (Ca-Ca) distances Returns ------- rc_value : nd_array, float The reaction coordinate value for each snapshot of `trajectory` """ if TIME: starttime = time.clock() # make an array of all pairwise C-alpha indices C_alphas = np.where( trajectory['AtomNames'] == 'CA' )[0] # indices of the Ca atoms n_residues = len(C_alphas) atom_contacts = np.zeros(( n_residues**2, 2 )) atom_contacts[:,0] = np.repeat( C_alphas, n_residues ) atom_contacts[:,1] = np.tile( C_alphas, n_residues ) # calculate the distance between all of those pairs distance_array = atom_distances(trajectory['XYZList'], atom_contacts) rc_value = np.sum( distance_array * weights.T, axis=1 ) if TIME: endtime = time.clock() print "Time spent in RC eval", endtime - starttime return rc_value
def test_atom_distances(self): pairs = np.array(list(product(xrange(self.n_atoms), repeat=2))) distances = _contactcalc.atom_distances(self.traj['XYZList'], pairs) same_atom = np.where(pairs[:,0] == pairs[:,1]) flipped_pairs = [] for i in xrange(pairs.shape[0]): for j in xrange(pairs.shape[0]): if (pairs[i,0] == pairs[j,1]) and (pairs[i,1] == pairs[j,0]) \ and (i != j): flipped_pairs.append((i,j)) flipped_pairs = np.array(flipped_pairs) for i in xrange(self.n_frames): eq(distances[i,flipped_pairs[:,0]], distances[i, flipped_pairs[:,1]]) eq(distances[i, same_atom], np.zeros_like(same_atom)) # pair[1] is the distance from atom 0 to atom 1, which should be sqrt(3) # in the first frame (1,1,1) to (2,2,2) eq(pairs[1], np.array([0,1])) eq(distances[0, 1], np.float32(np.sqrt(3)))
def test_atom_distances(self): pairs = np.array(list(product(xrange(self.n_atoms), repeat=2))) distances = _contactcalc.atom_distances(self.traj['XYZList'], pairs) same_atom = np.where(pairs[:, 0] == pairs[:, 1]) flipped_pairs = [] for i in xrange(pairs.shape[0]): for j in xrange(pairs.shape[0]): if (pairs[i,0] == pairs[j,1]) and (pairs[i,1] == pairs[j,0]) \ and (i != j): flipped_pairs.append((i, j)) flipped_pairs = np.array(flipped_pairs) for i in xrange(self.n_frames): npt.assert_array_equal(distances[i, flipped_pairs[:, 0]], distances[i, flipped_pairs[:, 1]]) npt.assert_array_equal(distances[i, same_atom], np.zeros_like(same_atom)) # pair[1] is the distance from atom 0 to atom 1, which should be sqrt(3) # in the first frame (1,1,1) to (2,2,2) npt.assert_array_equal(pairs[1], [0, 1]) npt.assert_almost_equal(distances[0, 1], np.sqrt(3))
def prepare_trajectory(self, trajectory): """Prepare a trajectory for distance calculations based on the contact map. Each frame in the trajectory will be represented by a vector where each entries represents the distance between two residues in the structure. Depending on what contacts you pick to use, this can be a 'native biased' picture or not. Paramters --------- trajectory : msmbuilder.Trajectory The trajectory to prepare Returns ------- pairwise_distances : ndarray 1D array of various residue-residue distances """ xyzlist = trajectory['XYZList'] traj_length = len(xyzlist) num_residues = trajectory.GetNumberOfResidues() num_atoms = trajectory.GetNumberOfAtoms() if self.contacts == 'all': contacts = np.empty( ((num_residues - 2) * (num_residues - 3) / 2, 2), dtype=np.int32) p = 0 for (a, b) in itertools.combinations(range(num_residues), 2): if max(a, b) > min(a, b) + 2: contacts[p, :] = [a, b] p += 1 assert p == len(contacts), 'Something went wrong generating "all"' else: num, width = self.contacts.shape contacts = self.contacts if not width == 2: raise ValueError('contacts must be width 2') if not (0 < len(np.unique(contacts[:, 0])) < num_residues): raise ValueError( 'contacts should refer to zero-based indexing of the residues' ) if not np.all( np.logical_and(0 <= np.unique(contacts), np.unique(contacts) < num_residues)): raise ValueError( 'contacts should refer to zero-based indexing of the residues' ) if self.scheme == 'ca': # not all residues have a CA #alpha_indices = np.where(trajectory['AtomNames'] == 'CA')[0] atom_contacts = np.zeros_like(contacts) residue_to_alpha = np.zeros(num_residues) # zero based indexing for i in range(num_atoms): if trajectory['AtomNames'][i] == 'CA': residue = trajectory['ResidueID'][i] - 1 residue_to_alpha[residue] = i #print 'contacts (residues)', contacts #print 'residue_to_alpja', residue_to_alpha.shape #print 'residue_to_alpja', residue_to_alpha atom_contacts = residue_to_alpha[contacts] #print 'atom_contacts', atom_contacts output = _contactcalc.atom_distances(xyzlist, atom_contacts) elif self.scheme in ['closest', 'closest-heavy']: if self.scheme == 'closest': residue_membership = [None for i in range(num_residues)] for i in range(num_residues): residue_membership[i] = np.where( trajectory['ResidueID'] == i + 1)[0] elif self.scheme == 'closest-heavy': residue_membership = [[] for i in range(num_residues)] for i in range(num_atoms): residue = trajectory['ResidueID'][i] - 1 if not trajectory['AtomNames'][i].lstrip( '0123456789').startswith('H'): residue_membership[residue].append(i) #print 'Residue Membership' #print residue_membership #for row in residue_membership: # for col in row: # print "%s-%s" % (trajectory['AtomNames'][col], trajectory['ResidueID'][col]), # print output = _contactcalc.residue_distances(xyzlist, residue_membership, contacts) else: raise ValueError('This is not supposed to happen!') return np.double(output)
def prepare_trajectory(self, trajectory): length = len(trajectory['XYZList']) ptraj = _contactcalc.atom_distances(trajectory['XYZList'], self.atom_pairs) return np.double(ptraj)
def prepare_trajectory(self, trajectory): """Prepare a trajectory for distance calculations based on the contact map. Each frame in the trajectory will be represented by a vector where each entries represents the distance between two residues in the structure. Depending on what contacts you pick to use, this can be a 'native biased' picture or not. Paramters --------- trajectory : msmbuilder.Trajectory The trajectory to prepare Returns ------- pairwise_distances : ndarray 1D array of various residue-residue distances """ xyzlist = trajectory['XYZList'] traj_length = len(xyzlist) num_residues = trajectory.GetNumberOfResidues() num_atoms = trajectory.GetNumberOfAtoms() if self.contacts == 'all': contacts = np.empty(((num_residues - 2) * (num_residues - 3) / 2, 2), dtype=np.int32) p = 0 for (a, b) in itertools.combinations(range(num_residues), 2): if max(a, b) > min(a, b) + 2: contacts[p, :] = [a, b] p += 1 assert p == len(contacts), 'Something went wrong generating "all"' else: num, width = self.contacts.shape contacts = self.contacts if not width == 2: raise ValueError('contacts must be width 2') if not (0 < len(np.unique(contacts[:, 0])) < num_residues): raise ValueError('contacts should refer to zero-based indexing of the residues') if not np.all(np.logical_and(0 <= np.unique(contacts), np.unique(contacts) < num_residues)): raise ValueError('contacts should refer to zero-based indexing of the residues') if self.scheme == 'ca': # not all residues have a CA #alpha_indices = np.where(trajectory['AtomNames'] == 'CA')[0] atom_contacts = np.zeros_like(contacts) residue_to_alpha = np.zeros(num_residues) # zero based indexing for i in range(num_atoms): if trajectory['AtomNames'][i] == 'CA': residue = trajectory['ResidueID'][i] - 1 residue_to_alpha[residue] = i #print 'contacts (residues)', contacts #print 'residue_to_alpja', residue_to_alpha.shape #print 'residue_to_alpja', residue_to_alpha atom_contacts = residue_to_alpha[contacts] #print 'atom_contacts', atom_contacts output = _contactcalc.atom_distances(xyzlist, atom_contacts) elif self.scheme in ['closest', 'closest-heavy']: if self.scheme == 'closest': residue_membership = [None for i in range(num_residues)] for i in range(num_residues): residue_membership[i] = np.where(trajectory['ResidueID'] == i + 1)[0] elif self.scheme == 'closest-heavy': residue_membership = [[] for i in range(num_residues)] for i in range(num_atoms): residue = trajectory['ResidueID'][i] - 1 if not trajectory['AtomNames'][i].lstrip('0123456789').startswith('H'): residue_membership[residue].append(i) #print 'Residue Membership' #print residue_membership #for row in residue_membership: # for col in row: # print "%s-%s" % (trajectory['AtomNames'][col], trajectory['ResidueID'][col]), # print output = _contactcalc.residue_distances(xyzlist, residue_membership, contacts) else: raise ValueError('This is not supposed to happen!') return np.double(output)