def test_buffer_not_c_contiguous(self): # source code was lightly adapted from jmborr # https://github.com/Amber-MD/pytraj/issues/991 traj = pt.load('data/issue991/short.dcd', 'data/issue991/pdb.gz', mask='(!:1-256)&(@H1,@H2,@H3,@H4,@H5)') # Trajectory of the center of mass of the first two residues minitraj = np.empty((2, traj.n_frames, 3)) minitraj[0] = pt.center_of_mass(traj, mask=':1') minitraj[1] = pt.center_of_mass(traj, mask=':2') minitraj = minitraj.transpose((1, 0, 2)) # "topology" using the first two atoms minitop = traj.top['@1,2'] # Save trajectory # make sure there is no ValueError # something is wrong with pdb, crd extension when loading with # minitop (poor topology?) # make issue in cpptraj too? for ext in ['nc', 'dcd', 'mdcrd', 'crd', 'pdb', 'trr']: fn = 'output/junk.' + ext pt.write_traj(filename=fn, traj=minitraj, top=minitop, overwrite=True) # load coord back to make sure we correctly write it new_traj = pt.iterload(fn, minitop) # mdcrd, crd, pdb has only 3 digits after decimal decimal = 5 if ext in ['nc', 'dcd', 'trr'] else 3 aa_eq(minitraj, new_traj.xyz, decimal=decimal)
def test_center(self): traj = pt.iterload(fn('tz2.ortho.nc'), fn('tz2.ortho.parm7')) pt.load(fn("tz2.center_mass.nc"), traj.top) fa = traj[:] fa2 = traj[:].copy() pt.center(fa, mask=':1', mass=True) aa_eq(fa.xyz, fa.xyz, decimal=5) # raise if center not in 'origin', 'box' with pytest.raises(ValueError): pt.center(fa, center='oh') # center to point pt.center(fa, ':1', center=[0, 1, 2], mass=True) aa_eq(pt.center_of_mass(fa, ':1')[0], [0, 1, 2]) pt.center(fa, ':1', center=[0, 1, 2], mass=False) aa_eq(pt.center_of_geometry(fa, ':1')[0], [0, 1, 2]) fa2.center(':1', center=[0, 1, 2], mass=False) aa_eq(pt.center_of_geometry(fa2, ':1')[0], [0, 1, 2]) # on_disk traj_on_disk = pt.iterload(fn('tz2.ortho.nc'), fn('tz2.ortho.parm7')) pt.center(traj_on_disk, ':1', center=[0, 1, 2], mass=True) aa_eq(pt.center_of_mass(traj_on_disk, ':1')[0], [0, 1, 2])
def test_thread_get_frame_amber(self): """Tests thread.get_frame method with md_engine = 'amber' and frame = -1""" settings = configure('../../data/atesa.config') settings.topology = '../test_data/test.prmtop' settings.md_engine = 'amber' settings.degeneracy = 1 allthreads = main.init_threads(settings) allthreads[0].jobids.append('01234') allthreads[0].history.prod_trajs.append(['../test_data/test.nc']) compare_traj = pytraj.iterload('../test_data/test.rst7', allthreads[0].topology) test_frame = allthreads[0].get_frame( allthreads[0].history.prod_trajs[0][0], -1, settings) query_traj = pytraj.iterload(test_frame, allthreads[0].topology) assert query_traj.n_frames == compare_traj.n_frames assert pytraj.center_of_mass(query_traj) == pytest.approx( pytraj.center_of_mass(compare_traj), 1e-3)
def test_timecorr(): with tempfolder(): # center of mass trajin = """ parm {} trajin {} vector center v0 timecorr vec1 v0 """.format(tc5b_top, tc5b_trajin) state = pt.load_cpptraj_state(trajin) state.run() cpptraj_output = state.data traj = pt.iterload(tc5b_trajin, tc5b_top) dslist0 = pt.center_of_mass(traj) data = pt.timecorr(dslist0, dslist0) aa_eq(data, cpptraj_output[-1].values) # 2 vectors cm = """ parm {} trajin {} vector v0 :2 :5 vector v1 :3 :7 timecorr vec1 v0 vec2 v1 """.format(tc5b_top, tc5b_trajin) state = pt.load_cpptraj_state(cm) state.run() cpptraj_output = state.data dslist0 = pt.vector.vector(traj, [':2 :5', ':3 :7']) data = pt.timecorr(dslist0[0], dslist0[1]) aa_eq(data, cpptraj_output[-1].values) # corrplane cm = """ parm {} trajin {} vector v0 @2,@5,@9 corrplane vector v1 @3,@7,@20 corrplane timecorr vec1 v0 vec2 v1 """.format(tc5b_top, tc5b_trajin) state = pt.load_cpptraj_state(cm) state.run() cpptraj_output = state.data dslist0 = pt.vector.vector(traj, ['@2,@5,@9 corrplane', '@3,@7,@20 corrplane']) dslist1 = pt.vector.corrplane(traj, ['@2,@5,@9', '@3,@7,@20']) data0 = pt.timecorr(dslist0[0], dslist0[1]) data1 = pt.timecorr(dslist1[0], dslist1[1]) aa_eq(data0, cpptraj_output[-1].values) aa_eq(data1, cpptraj_output[-1].values)
def test_0(self): # center of mass trajin = """ parm data/Tc5b.top trajin data/Tc5b.x vector center v0 timecorr vec1 v0 """ state = pt.load_cpptraj_state(trajin) state.run() cpptraj_output = state.data traj = pt.iterload("./data/Tc5b.x", "./data/Tc5b.top") dslist0 = pt.center_of_mass(traj) data = pt.timecorr(dslist0, dslist0) aa_eq(data, cpptraj_output[-1].values) # 2 vectors cm = """ parm data/Tc5b.top trajin data/Tc5b.x vector v0 :2 :5 vector v1 :3 :7 timecorr vec1 v0 vec2 v1 """ state = pt.load_cpptraj_state(cm) state.run() cpptraj_output = state.data dslist0 = pt.calc_vector(traj, [':2 :5', ':3 :7']) data = pt.timecorr(dslist0[0], dslist0[1]) aa_eq(data, cpptraj_output[-1].values) # corrplane cm = """ parm data/Tc5b.top trajin data/Tc5b.x vector v0 @2,@5,@9 corrplane vector v1 @3,@7,@20 corrplane timecorr vec1 v0 vec2 v1 """ state = pt.load_cpptraj_state(cm) state.run() cpptraj_output = state.data dslist0 = pt.calc_vector(traj, ['@2,@5,@9 corrplane', '@3,@7,@20 corrplane']) dslist1 = pt.vector.corrplane(traj, ['@2,@5,@9', '@3,@7,@20']) data0 = pt.timecorr(dslist0[0], dslist0[1]) data1 = pt.timecorr(dslist1[0], dslist1[1]) aa_eq(data0, cpptraj_output[-1].values) aa_eq(data1, cpptraj_output[-1].values)
def standard_orientation(stripped_domains, mask_A, mask_B, out): ''' Calculates standard orientation for two domains given as masks A and B applied to trajectory traj. Standard orientations are calculated as the orientation where the lowest moment of inertia eigenvector of the domain is aligned with z, the x axis is as close to the vector bewtween the centers of mass of the two domains as possible. The y vector is calculated as the negative crossproduct of the z-vector (lowest eigenvector) and x-vector(projection of com vector), giving a right handed coordinate system. The whole domain is alligned to this coordinate system in such a way that the center of mass is in the origin. The coordinates of the two alligned domains are returned. The full reference structure is used for the calculation of the coordinate system, but the coordinates are stripped before output according to masks A/B -> coordinate system only dependant on refstructure, not on the necessary mask for further alignment This is necessary, because crystal structure files might contain fewer residues than the reference structure which would mess up the alignment Parameters ---- Requires: stripped_domains, a list containing two pytraj trajectories corresponding to domains A (entry 0) and B (entry 1) mask_A, a str giving the cpptraj/pytraj mask corresponding to domain A in the trajectory - note that this mask mask_B, a str giving the cpptraj/pytraj mask corresponding to domain B in the trajectory Returns: transformed_coordinates_A; a numpy array of shape (n_atoms, 3), giving the reoriented coordinates of domain A to be used as reference orientation for ABangle calculations transformed_coordinates_B; a numpy array of shape (n_atoms, 3), giving the reoriented coordinates of domain B to be used as reference orientation for ABangle calculations ''' ### Apply both masks and calculate masses, com, coordinates and a reference point coms = [ pt.center_of_mass(stripped_domains[0]), pt.center_of_mass(stripped_domains[1]) ] x_vec = [1, 0, 0] y_vec = [0, 1, 0] z_vec = [0, 0, 1] origin = [0, 0, 0] masks = [mask_A, mask_B] unit_vectors = np.array([x_vec, y_vec, z_vec, origin]) #Orderd xyz results = [] for i, domain in enumerate(stripped_domains): partner = 0 if i == 1 else 1 #selects index of partnered domain mask = masks[i] ### Strip down coordinates to mask, does not affect calculation of coordinate system / moment of inertia tensor, just the reference coordinate data to be returned ### This is used in case the reference structure has more residues in it than the sample structure (see function new_maks) try: if mask != None: traj_stripped = domain[:].strip('!(' + mask + ')') else: traj_stripped = domain except: print( 'WARNING: Reference structure could not be further stripped. This generally happens if the trajectory contains more residues than the reference structure. ' ) traj_stripped = domain traj_partner = stripped_domains[partner] masses = domain.top.mass com_traj = coms[i] com_partner = coms[partner] ref_coordinates = domain.xyz ref_point = domain.xyz[0, 0] inertia_tensor = compute_inertia_tensor( ref_coordinates - np.expand_dims(com_traj, axis=1), masses) evals, evecs = np.linalg.eigh(inertia_tensor[0]) ### Reorder evecs to conform to xyz orientation. Largest evec should be x, lowest z evals = evals[::-1] evecs = evecs.T[::-1] evecs = orient_evecs(evecs, com_traj[0], ref_point, com_partner[0]) evec_orientation = np.append( evecs + com_traj[0], [com_traj[0]], axis=0 ) #add center of mass to evec array to conform to xyz+origin ordering, same as unit_vectors ### Apply first transformation: Aligns eigenvectors of inertia tensor with xyz unit vectors. The center of mass is now in the origin transformation = compute_transformation(evec_orientation, unit_vectors) z_aligned_ref_coords = transformation.transform(traj_stripped.xyz[0]) ### Calculate vectors for second transformation: new_com_partner is the transformed partner com, which is then projected onto the xy plane and stored as a unitvector. new_com_vector = transformation.transform(com_partner[0]) new_com_vector[2] = 0 #projection on xy plane new_com_vector = unit_vec(new_com_vector) orthogonal_vector = -np.cross(new_com_vector, z_vec) ### Check angle of z-vec to com vector to make sure the coordinate system makes sense, they should be roughly orthogonal if abs(np.dot(z_vec, new_com_vector)) > 0.25: print( 'WARNING: Ange between center axis and Vectors in domain {} is lower than $\pm$ 75 degrees. Please consider checking visualizations of the coordinate system to ensure that this works for your purpose.' ) ### Do second transformation. Lowest eigenvector is still z, x is now the projection of the com vector -> closest possible alignment of x and com while keeping x orthogonal to z reference_orientation = np.array([ unit_vec(new_com_vector), unit_vec(orthogonal_vector), z_vec, origin ]) second_transformation = compute_transformation(reference_orientation, unit_vectors) x_z_aligned_ref_coords = second_transformation.transform( z_aligned_ref_coords) results.append(x_z_aligned_ref_coords) transformed_coordinates_A = results[0] transformed_coordinates_B = results[1] return transformed_coordinates_A, transformed_coordinates_B #Reference coordinates A and B
# datafiles and this test.py were provided by jmborr # issue #991: # Error "ValueError: Buffer not C contiguous" # https://github.com/Amber-MD/pytraj/issues/991 import os import argparse import numpy import pytraj from pdb import set_trace as tr traj = pytraj.load('short.dcd', 'pdb', mask='(!:1-256)&(@H1,@H2,@H3,@H4,@H5)') # Trajectory of the center of mass of the first two residues minitraj = numpy.empty((2,traj.n_frames,3)) minitraj[0] = pytraj.center_of_mass(traj,mask=':1') minitraj[1] = pytraj.center_of_mass(traj,mask=':2') minitraj = minitraj.transpose((1,0,2)) # "topology" using the first two atoms minitop = traj.top['@1,2'] # Save trajectory pytraj.write_traj(filename='/tmp/junk.crd', traj=minitraj, top=minitop, overwrite=True)
masktop = traj.top[p_args.mask] #topology of the mask atoms CMselection = list() #Used only for the output PDB file if p_args.aggregate == 'byres': nres = masktop.n_residues CoM = numpy.empty((nres,traj.n_frames,3)) ires = 0 for residue in masktop.residues: try: resnum = residue.resnum except: resnum = int(residue.name) presidue = ptop.residues[resnum-1] first_atom = presidue[0] # selected atom to represent the whole residue in the output PDB file CMselection.append('@{0}'.format(first_atom.number)) #Next, calculate CM for given residue in all frames v = pytraj.center_of_mass(traj,mask='({0})&(:{1})'.format(p_args.mask,resnum)) CoM[ires] = v ires += 1 CoM = CoM.transpose((1,0,2)) #shape=(n_frames, n_residues, 3) CMselection = ','.join(CMselection) # mask containing the first atoms of each considered residue else: CoM = pytraj.center_of_mass(traj) CoM = CoM.reshape((traj.n_frames, 1, 3)) first_residue = ptop.residues[0] first_atom = first_residue[0] CMselection = '@{0}'.format(first_atom.number) outtop = traj.top[CMselection] for i in range(outtop.n_atoms): atom = outtop[i] atom.set_mol(0) stripped_traj = traj[CMselection]
# datafiles and this test.py were provided by jmborr # issue #991: # Error "ValueError: Buffer not C contiguous" # https://github.com/Amber-MD/pytraj/issues/991 import numpy import pytraj traj = pytraj.load('short.dcd', 'pdb', mask='(!:1-256)&(@H1,@H2,@H3,@H4,@H5)') # Trajectory of the center of mass of the first two residues minitraj = numpy.empty((2, traj.n_frames, 3)) minitraj[0] = pytraj.center_of_mass(traj, mask=':1') minitraj[1] = pytraj.center_of_mass(traj, mask=':2') minitraj = minitraj.transpose((1, 0, 2)) # "topology" using the first two atoms minitop = traj.top['@1,2'] # Save trajectory pytraj.write_traj(filename='/tmp/junk.crd', traj=minitraj, top=minitop, overwrite=True)
import pytraj as pt # use iterload for memory saving traj = pt.iterload("../tests/data/Tc5b.x", "../tests/data/Tc5b.top") # print(pt.center_of_mass(traj))