def assert_equal_topology(top, new_top, traj): import pytraj as pt assert new_top.n_atoms == top.n_atoms, 'same n_atoms' assert new_top.n_residues == top.n_residues, 'same n_residues' assert new_top.n_mols == top.n_mols, 'same n_mols' # there are inverted bond indices [5292 5291] vs [5291 5292] # so use distance to assert aa_eq( pt.distance(traj, new_top.bond_indices), pt.distance(traj, top.bond_indices)) # same for dihedral_indices aa_eq( pt.dihedral(traj, new_top.dihedral_indices), pt.dihedral(traj, top.dihedral_indices)) aa_eq(new_top.dihedral_indices, top.dihedral_indices) aa_eq(new_top.mass, top.mass) aa_eq(new_top.charge, top.charge) aa_eq(new_top.box.values, top.box.values) assert [res.name for res in top.residues ] == [res.name for res in new_top.residues], 'equal resnames' assert [atom.name for atom in top.atoms ] == [atom.name for atom in new_top.atoms], 'equal resnames' for res, res_new in zip(top.residues, new_top.residues): assert res.first_atom_index == res_new.first_atom_index, 'first atom' assert res.last_atom_index == res_new.last_atom_index, 'last atom'
def assert_equal_topology(top, new_top, traj): import pytraj as pt assert new_top.n_atoms == top.n_atoms, 'same n_atoms' assert new_top.n_residues == top.n_residues, 'same n_residues' assert new_top.n_mols == top.n_mols, 'same n_mols' # there are inverted bond indices [5292 5291] vs [5291 5292] # so use distance to assert aa_eq(pt.distance(traj, new_top.bond_indices), pt.distance(traj, top.bond_indices)) # same for dihedral_indices aa_eq(pt.dihedral(traj, new_top.dihedral_indices), pt.dihedral(traj, top.dihedral_indices)) aa_eq(new_top.dihedral_indices, top.dihedral_indices) aa_eq(new_top.mass, top.mass) aa_eq(new_top.charge, top.charge) aa_eq(new_top.box.values, top.box.values) assert [res.name for res in top.residues ] == [res.name for res in new_top.residues], 'equal resnames' assert [atom.name for atom in top.atoms ] == [atom.name for atom in new_top.atoms], 'equal resnames' for res, res_new in zip(top.residues, new_top.residues): assert res.first_atom_index == res_new.first_atom_index, 'first atom' assert res.last_atom_index == res_new.last_atom_index, 'last atom'
def test_crank(self): traj = pt.iterload("data/tz2.nc", "data/tz2.parm7") dihedrals = pt.dihedral(traj, [':1@C :2@N :2@CA :2@C', ':2@C :3@N :3@CA :3@C']) state = pt.load_cpptraj_state(cm) state.run() # TODO: assert please # cpptraj does not dump data to Dataset pt.crank(dihedrals[0], dihedrals[1], mode='angle')
def test_0(self): traj = pt.iterload("./data/Test_NAstruct/adh026.3.pdb") d = pt.calc_delta(traj, resrange='1').values d1 = pt.dihedral(traj, ":1@C5' :1@C4' :1@C3' :1@O3'") d2 = pt._dihedral_res(traj, ("C5'", "C4'", "C3'", "O3'")) aa_eq(d, d1) aa_eq(d, d2)
def test_crank(self): traj = pt.iterload(fn('tz2.nc'), fn('tz2.parm7')) dihedrals = pt.dihedral( traj, [':1@C :2@N :2@CA :2@C', ':2@C :3@N :3@CA :3@C']) state = pt.load_cpptraj_state(cm) with capture_stdout() as (out, _): state.run() data = pt.crank(dihedrals[0], dihedrals[1], mode='angle') assert out.read() == data
def test_0(self): traj = pt.iterload(fn('Test_NAstruct/adh026.3.pdb')) d = pt.calc_delta(traj, resrange='1').values d1 = pt.dihedral(traj, ":1@C5' :1@C4' :1@C3' :1@O3'") d2 = pt._dihedral_res(traj, ("C5'", "C4'", "C3'", "O3'")) aa_eq(d, d1) aa_eq(d, d2)
def test_crank(self): traj = pt.iterload("data/tz2.nc", "data/tz2.parm7") dihedrals = pt.dihedral( traj, [':1@C :2@N :2@CA :2@C', ':2@C :3@N :3@CA :3@C']) state = pt.load_cpptraj_state(cm) state.run() # TODO: assert please # cpptraj does not dump data to Dataset pt.crank(dihedrals[0], dihedrals[1], mode='angle')
def test_0(self): traj = pt.iterload(fn('Tc5b.x'), fn('Tc5b.top')) # convert to mutable traj t0 = traj[:1] for deg in range(-170, 170, 10): pt.rotate_dihedral(t0, "custom:3:phi:" + str(deg)) _deg = pt.calc_phi(t0, '3', dtype='ndarray')[0] dih = pt.dihedral(t0, ':2@C :3@N :3@CA :3@C')[0] aa_eq(deg, _deg) aa_eq(deg, dih) aa_eq(pt.calc_psi(traj[:1]).values, pt.calc_psi(t0).values)
def test_0(self): traj = pt.iterload("./data/Tc5b.x", "./data/Tc5b.top") # convert to mutable traj t0 = traj[:1] for deg in range(-170, 170, 10): pt.rotate_dihedral(t0, "custom:3:phi:" + str(deg)) _deg = pt.calc_phi(t0, '3', dtype='ndarray')[0] dih = pt.dihedral(t0, ':2@C :3@N :3@CA :3@C')[0] aa_eq(deg, _deg) aa_eq(deg, dih) aa_eq(pt.calc_psi(traj[:1]).values, pt.calc_psi(t0).values)
def cal_dih(top, trajectory, dih_mask, dihnum): ''' top is an amber topology file trajectory is an amber trajectorty, it can be both netcdf or ascii dih_mask is the dihedral atom number mask e.g @2 @3 @5 @8 dihnum is the number of dihedral being fitted cal_dih() returns dihedral values for a given mask ''' # first load trajectory traj = pt.Trajectory(trajectory, top) # if only one dihedral then if dihnum == 1: dih_data = pt.dihedral(traj, '%s' % (dih_mask)) return dih_data # we have multiple dihedrals else: dih_data = [] # calculate all dihedrals for mask in dih_mask: data = pt.dihedral(traj, '%s' % (mask)) dih_data.append(data) return dih_data
def test_1(self): # different from test_0 a bit in `mask` traj = pt.iterload("./data/Tc5b.x", "./data/Tc5b.top") # convert to mutable traj t0 = traj[:1] for deg in range(-170, 170, 10): pt.rotate_dihedral(t0, "3:phi:" + str(deg)) _deg = pt.calc_phi(t0, '3', dtype='ndarray')[0] dih = pt.dihedral(t0, ':2@C :3@N :3@CA :3@C')[0] aa_eq(deg, _deg) aa_eq(deg, dih) aa_eq(pt.calc_psi(traj[:1]).values, pt.calc_psi(t0).values)
def test_dihedral(self): import numpy as np traj = pt.iterload(fn('Tc5b.x'), fn('Tc5b.top')) fa = traj[:] mask = ':2@CA :14@CA :15@CA :16@CA' txt = ''' parm {} trajin {} dihedral {} '''.format(tc5b_top, tc5b_trajin, mask) d0 = pt.dihedral(traj, mask, dtype='dataset').to_ndarray() d1 = pt.dihedral(traj, mask) d2 = pt.calc_dihedral(fa, mask) state = pt.load_cpptraj_state(txt) state.run() dcpp = state.data[1:].values aa_eq(d0, d1) aa_eq(d0, d2) aa_eq(d0, dcpp) Nsize = 10 np.random.seed(1) arr = np.random.randint(0, 300, size=Nsize * 4).reshape(Nsize, 4) d3 = pt.calc_dihedral(fa, arr) d4 = pt.dihedral(traj, arr) d5 = pt.dihedral(traj, arr) d6 = pt.dihedral(fa, arr) d7 = pt.dihedral([fa, traj], arr, n_frames=2 * fa.n_frames) aa_eq(d3, d4) aa_eq(d3, d5) aa_eq(d3, d6) aa_eq(d3.T, d7.T[:fa.n_frames]) aa_eq(d3.T, d7.T[fa.n_frames:]) d8 = pt.dihedral(traj, mask, dtype='dataset') d9 = pt.tools.dict_to_ndarray(pt.dihedral(traj, mask, dtype='dict')) aa_eq(d0, d8.values) aa_eq([d0], d9) # raise with pytest.raises(ValueError): pt.dihedrals(traj, [[0, 3, 2]])
def test_dihedral(self): import numpy as np traj = mdio.iterload("./data/Tc5b.x", "./data/Tc5b.top") fa = traj[:] mask = ':2@CA :14@CA :15@CA :16@CA' txt = ''' parm ./data/Tc5b.top trajin ./data/Tc5b.x dihedral %s ''' % mask d0 = pt.dihedral(traj, mask, dtype='dataset').to_ndarray() d1 = pt.dihedral(traj, mask) d2 = pt.calc_dihedral(fa, mask) state = pt.load_cpptraj_state(txt) state.run() dcpp = state.data[1:].values aa_eq(d0, d1) aa_eq(d0, d2) aa_eq(d0, dcpp) Nsize = 10 np.random.seed(1) arr = np.random.randint(0, 300, size=Nsize * 4).reshape(Nsize, 4) d3 = pt.calc_dihedral(fa, arr) d4 = pt.dihedral(traj, arr) d5 = pt.dihedral(traj, arr) d6 = pt.dihedral(fa, arr) d7 = pt.dihedral([fa, traj], arr, n_frames=2 * fa.n_frames) aa_eq(d3, d4) aa_eq(d3, d5) aa_eq(d3, d6) aa_eq(d3.T, d7.T[:fa.n_frames]) aa_eq(d3.T, d7.T[fa.n_frames:]) d8 = pt.dihedral(traj, mask, dtype='dataset') d9 = pt.tools.dict_to_ndarray(pt.dihedral(traj, mask, dtype='dict')) aa_eq(d0, d8.values) aa_eq(d0, d9) # raise self.assertRaises(ValueError, lambda: pt.dihedrals(traj, [[0, 3, 2]]))
def test_openmm_cb6but_sim(num_rests=0, guest_pos='guest_inside'): path = './cb6-but_test/' + guest_pos + '/' topology = 'cb6-but-dum.prmtop' coordinates = 'cb6-but-dum.rst7' if num_rests > 0: md_out = 'cb6_but_openmm_rest_{:02d}.csv'.format(num_rests) traj_out = 'cb6_but_openmm_rest_{:02d}.nc'.format(num_rests) else: md_out = 'cb6_but_openmm.csv' traj_out = 'cb6_but_openmm.nc' structure = pmd.load_file(path + topology, path + coordinates, structure=True) traj = pt.load(path + coordinates, path + topology) host = ":CB6" guest = ":BUT" H = [host + "@C7", host + "@C31", host + "@C19"] G = [guest + "@C", guest + "@C3"] D = [":DM1", ":DM2", ":DM3"] H_i = [0, 0, 0] G_i = [0, 0] D_i = [0, 0, 0] # Get indices for atom masks for i, mask in enumerate(H): H_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0] for i, mask in enumerate(G): G_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0] for i, mask in enumerate(D): D_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0] # Set mass of Dummy atoms to 0 so they are non-interacting for i, atom in enumerate(structure.atoms): if atom.name == 'DUM': atom.mass = 0.0 topology_0m = 'cb6-but-dum-0m.prmtop' coordinates_0m = 'cb6-but-dum-0m.rst7' structure.save(path + topology_0m, overwrite=True) structure.save(path + coordinates_0m, overwrite=True) prmtop = app.AmberPrmtopFile(path + topology_0m) inpcrd = app.AmberInpcrdFile(path + coordinates_0m) settings = { 'nonbonded_method': app.NoCutoff, 'temperature': 298.15 * unit.kelvin, 'friction': 1 / unit.picosecond, 'timestep': 0.002 * unit.picosecond, 'implicit_solvent': app.HCT, 'dist_fc': 5.0, 'angle_fc': 100.0, 'numsteps': 500000, } system = prmtop.createSystem( nonbondedMethod=settings['nonbonded_method'], implicitSolvent=settings['implicit_solvent'], removeCMMotion=False, ) integrator = LangevinIntegrator(settings['temperature'], settings['friction'], settings['timestep']) # Create Positional Restraints for Dummy atoms pos_restraint = mm.CustomExternalForce('k*((x-x0)^2+(y-y0)^2+(z-z0)^2)') pos_restraint.addGlobalParameter( 'k', 50.0 * unit.kilocalories_per_mole / unit.angstroms**2) pos_restraint.addPerParticleParameter('x0') pos_restraint.addPerParticleParameter('y0') pos_restraint.addPerParticleParameter('z0') for i, atom in enumerate(structure.positions): if structure.atoms[i].name == 'DUM': pos_restraint.addParticle(i, atom.value_in_unit(unit.nanometers)) static_restraints = [] # Create Distance Restraint static_distance_rest = [D[0], H[0]] static_init_dist = pt.distance(traj, D[0] + ' ' + H[0])[0] dist_restraint = mm.CustomBondForce('k*(r-r0)^2') dist_restraint.addPerBondParameter('k') dist_restraint.addPerBondParameter('r0') r0 = static_init_dist * unit.angstroms k = settings['dist_fc'] * unit.kilocalories_per_mole / unit.angstroms**2 dist_restraint.addBond(D_i[0], H_i[0], [k, r0]) static_restraints.append(dist_restraint) # Create Angle Restraint 1 static_angle_rest_1 = [D[1], D[0], H[0]] static_init_angle_1 = pt.angle(traj, D[1] + ' ' + D[0] + ' ' + H[0])[0] angle_restraint_1 = mm.CustomAngleForce('0.5*k*(theta-theta0)^2') angle_restraint_1.addPerAngleParameter('k') angle_restraint_1.addPerAngleParameter('theta0') theta0 = static_init_angle_1 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 angle_restraint_1.addAngle(D_i[1], D_i[0], H_i[0], [k, theta0]) static_restraints.append(angle_restraint_1) # Create Dihedral Restraint 1 static_dihedral_rest_1 = [D[2], D[1], D[0], H[0]] static_init_dihedral_1 = pt.dihedral( traj, D[2] + ' ' + D[1] + ' ' + D[0] + ' ' + H[0])[0] dihedral_restraint_1 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2') dihedral_restraint_1.addPerTorsionParameter('k') dihedral_restraint_1.addPerTorsionParameter('theta0') theta0 = static_init_dihedral_1 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 dihedral_restraint_1.addTorsion(D_i[2], D_i[1], D_i[0], H_i[0], [k, theta0]) static_restraints.append(dihedral_restraint_1) # Create Angle Restraint 2 static_angle_rest_2 = [D[0], H[0], H[1]] static_init_angle_2 = pt.angle(traj, D[0] + ' ' + H[0] + ' ' + H[1])[0] angle_restraint_2 = mm.CustomAngleForce('0.5*k*(theta-theta0)^2') angle_restraint_2.addPerAngleParameter('k') angle_restraint_2.addPerAngleParameter('theta0') theta0 = static_init_angle_2 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 angle_restraint_2.addAngle(D_i[0], H_i[0], H_i[1], [k, theta0]) static_restraints.append(angle_restraint_2) # Create Dihedral Restraint 2 static_dihedral_rest_2 = [D[1], D[0], H[0], H[1]] static_init_dihedral_2 = pt.dihedral( traj, D[1] + ' ' + D[0] + ' ' + H[0] + ' ' + H[1])[0] dihedral_restraint_2 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2') dihedral_restraint_2.addPerTorsionParameter('k') dihedral_restraint_2.addPerTorsionParameter('theta0') theta0 = static_init_dihedral_2 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 dihedral_restraint_2.addTorsion(D_i[1], D_i[0], H_i[0], H_i[1], [k, theta0]) static_restraints.append(dihedral_restraint_2) # Create Dihedral Restraint 3 static_dihedral_rest_3 = [D[0], H[0], H[1], H[2]] static_init_dihedral_3 = pt.dihedral( traj, D[0] + ' ' + H[0] + ' ' + H[1] + ' ' + H[2])[0] dihedral_restraint_3 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2') dihedral_restraint_3.addPerTorsionParameter('k') dihedral_restraint_3.addPerTorsionParameter('theta0') theta0 = static_init_dihedral_3 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 dihedral_restraint_3.addTorsion(D_i[0], H_i[0], H_i[1], H_i[2], [k, theta0]) static_restraints.append(dihedral_restraint_3) #system.addForce(pos_restraint) if num_rests > 0: for rest in static_restraints[0:num_rests]: system.addForce(rest) simulation = app.Simulation(prmtop.topology, system, integrator, mm.Platform.getPlatformByName('CPU')) simulation.context.setPositions(inpcrd.positions) simulation.reporters.append(NetCDFReporter(path + traj_out, 250)) simulation.reporters.append( app.StateDataReporter(path + md_out, 250, step=True, time=True, potentialEnergy=True, kineticEnergy=True, totalEnergy=True, temperature=True, volume=True, density=True)) simulation.step(settings['numsteps'])
def main(traj, top): ''' 用户选择计算模式 调用pytraj计算 调用xlsxwriter保存数据文件 Paramters ---------- traj: MD轨迹 Pytraj对象 top: MD拓扑文件PATH ''' print(''' 请输入计算模式: 1.计算原子间距离(键长)变化 2.计算键角变化 3.计算二面角变化 0.退出 ''') while True: flag = input().strip() if re.match('[0123]', flag): flag = int(flag) break else: print('输入代号无效,请重新输入\n') if flag == 0: sys.exit() lis = get_mask(flag) topfile = pt.load_topology(top) masks = '' for i in lis: masks += i + ' ' judge(i, topfile) print('\nProcessing and Saving Data...') disangxlsx = xlsxwriter.Workbook( './pynalysis/dis_ang/distance_angle_data.xlsx') def save(sheet, mask, data): # 保存数据 sheet.write(0, 0, mask) col = 0 row = 1 for i in data: sheet.write(row, col, i) row += 1 if flag == 1: dis = pt.distance(traj, masks) print('\nDistance Data:\n', dis) distance_sheet = disangxlsx.add_worksheet('Distance') save(distance_sheet, masks, dis) if flag == 2: angle = pt.angle(traj, masks) print('Angel Data:\n', angle) angel_sheet = disangxlsx.add_worksheet('Angel') save(angel_sheet, masks, angle) if flag == 3: dihedral = pt.dihedral(traj, masks) print('Dihedral Data:\n', dihedral) dihedral_sheet = disangxlsx.add_worksheet('Dihedral') save(dihedral_sheet, masks, dihedral) disangxlsx.close() print('\ndistance_angle_data.xlsx Data Saved.', end='\n')
# Angle restraint 1 static_angle_rest1 = [D[1], D[0], H[0]] static_init_angle1 = pt.angle(traj, D[1] + ' ' + D[0] + ' ' + H[0])[0] angle_restraint1 = mm.CustomAngleForce('0.5*k*(theta-theta_0)^2') angle_restraint1.addPerAngleParameter('k') angle_restraint1.addPerAngleParameter('theta_0') theta_0 = static_init_angle1 * degrees k = 100 * kilojoules_per_mole / angstroms**2 angle_restraint1.addAngle(D_i[1], D_i[0], H_i[0], [k, theta_0]) # Dihedral restraint 1 static_dihedral_rest1 = [D[2], D[1], D[0], H[0]] static_init_dihedral1 = pt.dihedral( traj, D[2] + ' ' + D[1] + ' ' + D[0] + ' ' + H[0])[0] dihedral_restraint1 = mm.CustomTorsionForce('0.5*k*(theta-theta_0)^2') dihedral_restraint1.addPerTorsionParameter('k') dihedral_restraint1.addPerTorsionParameter('theta_0') theta_0 = static_init_dihedral1 * degrees k = 100 * kilojoules_per_mole / angstroms**2 dihedral_restraint1.addTorsion(D_i[2], D_i[1], D_i[0], H_i[0], [k, theta_0]) # Angle restraint 2 static_angle_rest2 = [D[0], H[0], H[1]] static_init_angle2 = pt.angle(traj, D[0] + ' ' + H[0] + ' ' + H[1])[0] angle_restraint2 = mm.CustomAngleForce('0.5*k*(theta-theta_0)^2')
def static_DAT_restraint( restraint_mask_list, num_window_list, ref_structure, force_constant, continuous_apr=True, amber_index=False, ): """ Create a restraint whose value does not change during a calculation. Parameters ---------- restraint_mask_list: list A list of masks for which this restraint applies. num_window_list: list A list of windows during which this restraint will be applied, which should be in the form: [attach windows, pull windows, release windows]. ref_structure: Path-like or parmed Amber object The reference structure that is used to determine the initial, **static** value for this restraint. force_constant: float The force constant for this restraint. continuous_apr: bool Whether this restraint uses ``continuous_apr``. This must be consistent with existing restraints. amber_index: bool Whether the atom indices for the restraint should be AMBER-style (+1) or not. Returns ------- rest: ``DAT_restraint`` A static restraint. """ # Check num_window_list if len(num_window_list) != 3: raise ValueError( "The num_window_list needs to contain three integers corresponding to the number of windows in the " "attach, pull, and release phase, respectively ") rest = DAT_restraint() rest.continuous_apr = continuous_apr rest.amber_index = amber_index if isinstance(ref_structure, pmd.amber._amberparm.AmberParm): reference_trajectory = pt.load_parmed(ref_structure, traj=True) rest.topology = ref_structure elif isinstance(ref_structure, str): reference_trajectory = pt.iterload(ref_structure, traj=True) rest.topology = pmd.load_file(ref_structure, structure=True) else: raise TypeError( "static_DAT_restraint does not support the type associated with ref_structure:" + type(ref_structure)) rest.mask1 = restraint_mask_list[0] rest.mask2 = restraint_mask_list[1] if len(restraint_mask_list) >= 3: rest.mask3 = restraint_mask_list[2] if len(restraint_mask_list) == 4: rest.mask4 = restraint_mask_list[3] # Target value mask_string = " ".join(restraint_mask_list) if len(restraint_mask_list) == 2: # Distance restraint if reference_trajectory.top.has_box(): target = pt.distance(reference_trajectory, mask_string, image=True)[0] logger.debug("Calculating distance with 'image = True' ...") else: target = pt.distance(reference_trajectory, mask_string, image=False)[0] logger.debug("Calculating distance with 'image = False' ...") elif len(restraint_mask_list) == 3: # Angle restraint target = pt.angle(reference_trajectory, mask_string)[0] elif len(restraint_mask_list) == 4: # Dihedral restraint target = pt.dihedral(reference_trajectory, mask_string)[0] else: raise IndexError( f"The number of masks -- {len(restraint_mask_list)} -- is not 2, 3, or 4 and thus is not one of the " f"supported types: distance, angle, or dihedral.") # Attach phase if num_window_list[0] is not None and num_window_list[0] != 0: rest.attach["target"] = target rest.attach["fc_initial"] = force_constant rest.attach["fc_final"] = force_constant rest.attach["num_windows"] = num_window_list[0] # Pull phase if num_window_list[1] is not None and num_window_list[1] != 0: rest.pull["fc"] = force_constant rest.pull["target_initial"] = target rest.pull["target_final"] = target rest.pull["num_windows"] = num_window_list[1] # Release phase if num_window_list[2] is not None and num_window_list[2] != 0: rest.release["target"] = target rest.release["fc_initial"] = force_constant rest.release["fc_final"] = force_constant rest.release["num_windows"] = num_window_list[2] rest.initialize() return rest
def candidatevalues_rc_eval(coord_file, index, settings): """ Evaluate the index'th candidate OP values from the coordinates given by the coord_file This code is copied from the atesa.py function of the same name, and modified to accept a single coordinate file rather than a thread as its argument, as well as to return only the index'th OP as a float rather than every OP as a space-separated string. This function may appear "unused"; this is because it is only actually called indirectly within eval() calls. It is necessary! This function is only capable of returning order parameter rate of change values when the literal_ops Boolean is True. This will change in future versions. Parameters ---------- coord_file : str The name of the coordinate file from which the candidate OP should be read. index : int The zero-indexed index corresponding to the desired OP. Returns ------- float The evaluation of the desired candidate OP. """ def increment_coords(coord_file): # Modified from revvels() to increment coordinate values by velocities, rather than reversing velocities. # Returns the name of the newly-created coordinate file byline = open(coord_file).readlines() pattern = re.compile( '[-0-9.]+' ) # regex to match numbers including decimals and negatives pattern2 = re.compile( '\s[-0-9.]+' ) # regex to match numbers including decimals and negatives, with one space in front n_atoms = pattern.findall(byline[1])[ 0] # number of atoms indicated on second line of .rst file shutil.copyfile(coord_file, 'temp' + settings.committor_suffix + '.rst') for i, line in enumerate( fileinput.input('temp' + settings.committor_suffix + '.rst', inplace=1)): if int(n_atoms) / 2 + 2 > i >= 2: newline = line coords = pattern2.findall(newline) # line of coordinates vels = pattern2.findall( byline[i + int(math.ceil(int(n_atoms) / 2))]) # corresponding velocities for index in range(len(coords)): length = len( coords[index] ) # length of string representing this coordinate replace_string = ' ' + str( float(coords[index]) + float(vels[index]))[0:length - 1] while len(replace_string) < length: replace_string += '0' newline = newline.replace(coords[index], replace_string) sys.stdout.write(newline) else: sys.stdout.write(line) return 'temp' + settings.committor_suffix + '.rst' try: null = settings.committor_suffix except AttributeError: settings.committor_suffix = '' try: traj = pytraj.iterload(coord_file, settings.topology) except ValueError: sys.exit('Error: coordinate file name ' + coord_file + ' is invalid.') if settings.literal_ops: try: # assuming this is not a rate of change OP... output = float(eval(settings.candidateops[index])) except IndexError: # this is a rate of change OP after all, so... v_0 = float( eval(settings.candidateops[int(index - len(settings.candidateops))]) ) # value of relevant OP at t = 0 traj = pytraj.iterload( increment_coords(coord_file), settings.topology) # new traj for evaluation of OPs v_1 = float( eval(settings.candidateops[int(index - len(settings.candidateops))]) ) # value of OP at t = 1/20.455 ps output = float( v_1 - v_0) # subtract value of op from value 1/20.455 ps earlier else: if len(settings.candidateops ) == 4: # settings.candidateops contains dihedrals if settings.candidateops[3][index]: # if this OP is a dihedral value = pytraj.dihedral(traj, mask=settings.candidateops[0][index] + ' ' + settings.candidateops[1][index] + ' ' + settings.candidateops[2][index] + ' ' + settings.candidateops[3][index]) elif settings.candidateops[2][index]: # if this OP is an angle value = pytraj.angle(traj, mask=settings.candidateops[0][index] + ' ' + settings.candidateops[1][index] + ' ' + settings.candidateops[2][index]) else: # if this OP is a distance value = pytraj.distance(traj, mask=settings.candidateops[0][index] + ' ' + settings.candidateops[1][index]) output = float(value) elif len( settings.candidateops ) == 3: # settings.candidateops contains angles but not dihedrals if settings.candidateops[2][index]: # if this OP is an angle value = pytraj.angle(traj, mask=settings.candidateops[0][index] + ' ' + settings.candidateops[1][index] + ' ' + settings.candidateops[2][index]) else: # if this OP is a distance value = pytraj.distance(traj, mask=settings.candidateops[0][index] + ' ' + settings.candidateops[1][index]) output = float(value) else: # settings.candidateops contains only distances value = pytraj.distance(traj, mask=settings.candidateops[0][index] + ' ' + settings.candidateops[1][index]) output = float(value) # Before returning the result, we want to convert to a reduced variable z = (r-rmin)/(rmax-rmin) if settings.rc_minmax: try: if not settings.rc_minmax[0][index] or not settings.rc_minmax[1][ index]: # if there's a blank entry in rc_minmax sys.exit('\nError: rc_definition contains reference to CV' + str(index + 1) + ' without a corresponding entry in rc_minmax') except IndexError: # if there's no entry at all sys.exit('\nError: rc_definition contains reference to CV' + str(index + 1) + ' without a corresponding entry in rc_minmax') raw_output = output output = (output - settings.rc_minmax[0][index]) / ( settings.rc_minmax[1][index] - settings.rc_minmax[0][index]) if not -0.01 <= output <= 1.01: # For debugging # print(raw_output) # print(v_0) # print(v_1) if settings.minmax_error_behavior == 'exit': sys.exit( '\nError: reduced variable at index ' + str(index) + ' (zero-indexed) in coordinate file ' + coord_file + ' is not between 0 and 1 (value is ' + str(output) + '). ' 'minmax_error_behavior = exit, so exiting. Check that rc_minmax is correct.' ) elif settings.minmax_error_behavior == 'skip': print( '\nWarning: reduced variable at index ' + str(index) + ' (zero-indexed) in coordinate file ' + coord_file + ' is not between 0 and 1 (value is ' + str(output) + '). minmax_error_behavior' ' = skip, so this file is being skipped and will not appear in rc_eval' + settings.committor_suffix + '.out') return 'SKIP' elif settings.minmax_error_behavior == 'accept': print( '\nWarning: reduced variable at index ' + str(index) + ' (zero-indexed) in coordinate file ' + coord_file + ' is not between 0 and 1 (value is ' + str(output) + '). minmax_error_behavior' ' = accept, so this file is NOT being skipped and will appear in rc_eval' + settings.committor_suffix + '.out') return output
def main(args): parser = argparse.ArgumentParser( description= r'Calculates the Jensen-Shannon divergence between the probability ' r'distributions of backbone dihedral angles and generates .pml files' r'that can be loaded using pymol.') parser.add_argument( 'top', help='topology file of first sturcture in prmtop format.') parser.add_argument( 'traj', help='trajectory file of first structure in netcdf format.') parser.add_argument( '-d', dest='dihedral_angle', help= 'A dihedral angles defined as in AmberTools, e.g. :26@CA,:27@CA,:34@CA,:50@CA\'' ) parser.add_argument( '-p', dest='pymol_script', help='Name of pymol script file (default: top_1 + _js.pml)') parser.add_argument( '-s', dest='scatter', help='Name of scatter plot file (default: top_1 + .png)') parser.add_argument('-f', dest='frames', help='Size of frame window', default="") args = parser.parse_args() # file name of first topology will be used for output file names top_1_name = splitext(basename(args.top))[0] traj = pt.iterload(args.traj, args.top) last_k = 0 histograms = [] x_ticks = [] for k in range(int(args.frames), int(traj.n_frames) + int(args.frames), int(args.frames)): if k >= traj.n_frames: k = traj.n_frames - 1 angles = pt.dihedral(traj, mask=args.dihedral_angle.replace(',', ' '), top=args.top, frame_indices=range(last_k, k + 1)) hist = list(np.histogram(angles, bins=np.arange(-180, 181, 10))[0]) histograms.append(hist) x_ticks.append( str(last_k // 1000) + "k -> " + str(k // 1000) + "k to " + str((k + 1) // 1000) + "k -> " + str((k + int(args.frames)) // 1000) + "k") last_k = k + 1 js_distances = [] for c in range(len(histograms) - 1): js_distances.append(jensenshannon(histograms[c], histograms[c + 1])) print(js_distances) plt.scatter(x_ticks[:-1], js_distances) plt.xticks(x_ticks[:-1], rotation=30, ha='right') plt.ylabel('Jensen Shannon Divergence') plt.xlabel('Compared frame windows') plt.tight_layout() plt.savefig(top_1_name + ".png")
def cal_dih(traj, mask): '''mask is dihedral mask''' data = [] if mask != 'empty': # not all residues have same chis, so return empty for those using the dihmask function above data = pt.dihedral(traj, mask) return data
def create_PDBdf(pdb_list, tot_res): ''' pdb_list is a list of pdb e.g ['2qnp', '1hhp']. They must be stored in a directory name PDB tot_res is the total number of residues function return a dictionary name pdb. it can be called as pdb[pdbname] e.g pdb['1hhp'] ''' # populate a dataframe for each PDB that contains all the dihedrals pdb = {} #dictionary #get each pdb # strip the less using comma delimiter list_pdb = np.genfromtxt(pdb_list, dtype=str, delimiter=',') for i in list_pdb: # convert to lower case i = i.lower() i = i.strip() # get the PDB path #print (i) j = 'PDB/%s.pdb' %(i) # define PDB as topology using pytraj top = pt.load_topology(j) traj = pt.iterload(j) # set up a dataframe that have residue#, residue name, and the dihedrals up to chi5 data_df = pd.DataFrame(index = np.arange(1, tot_res, 1), columns=["res#", "resname", "phi", "psi", "chi1", "chi2", "chi3", "chi4", "chi5"]) # populate the column residue # data_df['res#'] = np.arange(1, tot_res, 1) # we will calculate the dihedrals for each residued and make a map, k is residue # for k in np.arange(1, tot_res, 1): # cheap method to get the residues, a hack but works residues, ss, _ = pt.dssp(traj, ":%s" %(k)) res = residues[0][0:3] #print (res) # put the residue name in the dataframe data_df.at[k, 'resname'] = '%s' %(res) # do phi first if k != 1 : #no phi for first residue # get the index for phi indx = '%s' %(dihmask(int(k), 'phi', res)) # calculate the dihedral value, and store in data data = cal_dih(traj, indx) data_df.at[k, 'phi'] = data[0] #print (data) # do psi after if k != tot_res: # no psi for last residue # get the index for pytraj dihedral function indx = '%s' %(dihmask(int(k), 'psi', res)) # calculate the dihedral value data = pt.dihedral(traj, indx) data_df.at[k, 'psi'] = data[0] #print (data) # now do chi's chis = ['chi1', 'chi2', 'chi3', 'chi4', 'chi5'] for chi in chis: indx = '%s' %(dihmask(int(k), chi, res)) # calculate the dihedral value if indx != 'empty': data = pt.dihedral(traj, indx) data_df.at[k, chi] = data[0] #make a directory to store reference value os.system("mkdir reference_values") data_df.to_csv("./reference_values/%s_ref.dat" %(i), float_format='%.4f') pdb[i] = data_df # set pdb dataframes return pdb
def static_DAT_restraint( restraint_mask_list, num_window_list, ref_structure, force_constant, continuous_apr=True, amber_index=False, ): """ Create a static restraint """ # Setup reference structure if isinstance(ref_structure, str): ref_structure = utils.return_parmed_structure(ref_structure) elif isinstance(ref_structure, pmd.structure.Structure): pass else: raise Exception( "static_DAT_restraint does not support the type associated with ref_structure:" + type(ref_structure)) ref_traj = pt.load_parmed(ref_structure, traj=True) # Check num_window_list if len(num_window_list) != 3: raise Exception( "The num_window_list needs to contain three integers corresponding to the number of windows in the attach, pull, and release phase, respectively" ) # Setup restraint rest = DAT_restraint() rest.continuous_apr = continuous_apr rest.amber_index = amber_index rest.topology = ref_structure rest.mask1 = restraint_mask_list[0] rest.mask2 = restraint_mask_list[1] if len(restraint_mask_list) >= 3: rest.mask3 = restraint_mask_list[2] if len(restraint_mask_list) == 4: rest.mask4 = restraint_mask_list[3] # Target value mask_string = " ".join(restraint_mask_list) if len(restraint_mask_list) == 2: # Distance restraint target = pt.distance(ref_traj, mask_string)[0] elif len(restraint_mask_list) == 3: # Angle restraint target = pt.angle(ref_traj, mask_string)[0] elif len(restraint_mask_list) == 4: # Dihedral restraint target = pt.dihedral(ref_traj, mask_string)[0] else: raise Exception( "The number of masks (" + str(len(restraint_mask_list)) + ") in restraint_mask_list is not 2, 3, or 4 and thus is not one of the supported types: distance, angle, dihedral" ) # Attach phase if num_window_list[0] is not None and num_window_list[0] != 0: rest.attach["target"] = target rest.attach["fc_initial"] = force_constant rest.attach["fc_final"] = force_constant rest.attach["num_windows"] = num_window_list[0] # Pull phase if num_window_list[1] is not None and num_window_list[1] != 0: rest.pull["fc"] = force_constant rest.pull["target_initial"] = target rest.pull["target_final"] = target rest.pull["num_windows"] = num_window_list[1] # Release phase if num_window_list[2] is not None and num_window_list[2] != 0: rest.release["target"] = target rest.release["fc_initial"] = force_constant rest.release["fc_final"] = force_constant rest.release["num_windows"] = num_window_list[2] rest.initialize() return rest