def test_typing(): im61 = Molecule.from_smiles('C[n+]1cn(cc1)CCCCCC') im2eben = Molecule.from_smiles('C[n+]1cn(cc1)CCc1ccccc1') im2bben = Molecule.from_smiles('C[n+]1cn(cc1)CCCc1ccccc1') dca = Molecule.from_smiles('N#C[N-]C#N') fsi = Molecule.from_smiles('FS(=O)(=O)[N-]S(=O)(=O)F') tfsi = Molecule.from_smiles('FC(F)(F)S(=O)(=O)[N-]S(=O)(=O)C(F)(F)(F)') top = Topology([im61, im2eben, im2bben, dca, fsi, tfsi]) typer = ZftTyper(cwd + '/files/CLP-define.zft') typer.type(top) assert [atom.type for atom in im61.atoms] == ( ['C1', 'NA', 'CR', 'NA', 'CW', 'CW', 'C1', 'C2', 'CS', 'CS', 'CS', 'CT'] + ['H1', 'H1', 'H1', 'HCR', 'HCW', 'HCW'] + ['H1', 'H1'] + ['HC'] * 11) assert [atom.type for atom in im2eben.atoms] == ( ['C1', 'NA', 'CR', 'NA', 'CW', 'CW', 'C_4H2_NA', 'C_4H2_CA', 'CAT', 'CAO', 'CAM', 'CAP', 'CAM', 'CAO'] + ['H1', 'H1', 'H1', 'HCR', 'HCW', 'HCW'] + ['H1', 'H1', 'HT', 'HT'] + ['HAT'] * 5) assert [atom.type for atom in dca.atoms] == ['NZA', 'CZA', 'N3A', 'CZA', 'NZA'] assert [atom.type for atom in fsi.atoms] == ( ['FSI', 'SBT', 'OBT', 'OBT', 'NBT', 'SBT', 'OBT', 'OBT', 'FSI']) assert [atom.type for atom in tfsi.atoms] == ( ['F1', 'CBT', 'F1', 'F1', 'SBT', 'OBT', 'OBT', 'NBT', 'SBT', 'OBT', 'OBT', 'CBT', 'F1', 'F1', 'F1'])
def make_system(molecules, numbers, ff, box=None, virtual_sites=False, drudes=False): from shutil import which from mstools.wrapper import Packmol packmol_path = which("packmol") packmol = Packmol(packmol_path) # convert to nm - nargs gives a list if len(box) == 1: box = [b / 10 for b in box] * 3 else: box = [b / 10 for b in box] top = Topology(molecules) top.generate_angle_dihedral_improper() if virtual_sites: top.generate_virtual_sites(ff) if drudes: top.generate_drude_particles(ff) top.assign_charge_from_ff(ff) top.cell.set_box(box) top.scale_with_packmol(numbers, packmol) return System(top, ff)
def test_typing(): im2eben = Molecule.from_smiles('C[n+]1cn(cc1)CCc1ccccc1') fsi = Molecule.from_smiles('FS(=O)(=O)[N-]S(=O)(=O)F') top = Topology([im2eben, fsi]) if os.path.exists(r'D:\Projects\DFF\Developing'): dff_root = pathlib.Path(r'D:\Projects\DFF\Developing') else: path = shutil.which('dffjob.exe') if path is not None: dff_root = pathlib.Path(path).parent.parent else: print('DFF not found') assert 0 dff = DFF(dff_root) typer = DffTyper(dff, dff_root.joinpath('database/TEAMFF.ref/IL/IL.ext')) typer.type(top) assert [atom.type for atom in im2eben.atoms] == ([ 'c_4nph3', 'n_35+da', 'c_35an2', 'n_35+da', 'c_35an', 'c_35an', 'c_4np', 'c_4h2', 'c_3ac', 'c_3a', 'c_3a', 'c_3a', 'c_3a', 'c_3a' ] + ['h_1'] * 15) assert [atom.type for atom in fsi.atoms] == ([ 'f_1', 's_4o', 'o_1', 'o_1', 'n_2-', 's_4o', 'o_1', 'o_1', 'f_1' ])
def test_write(): zmat = Topology.open(cwd + '/files/Im11.zmat') tmp = os.path.join(tmpdir, 'zmat-out.xyz') zmat.write(tmp) assert filecmp.cmp(tmp, cwd + '/files/baselines/zmat-out.xyz') mol = Molecule.from_smiles('C[n+]1cn(cc1)CCCC[B-](F)(F)F') top = Topology([mol]) tmp = os.path.join(tmpdir, 'smi-out.xyz') top.write(tmp) filecmp.cmp(tmp, cwd + '/files/baselines/smi-out.xyz')
def test_write_swm4(): ff = ForceField.open(cwd + '/../forcefield/files/SWM4-NDP.zfp') mol = Topology.open(cwd + '/files/TIP3P.zmat').molecules[0] mol.generate_virtual_sites(ff) mol.generate_drude_particles(ff) mol.assign_charge_from_ff(ff) top = Topology([mol], numbers=[10]) tmp = os.path.join(tmpdir, 'swm4-out.psf') top.write(tmp) assert filecmp.cmp(tmp, cwd + '/files/baselines/swm4-out.psf')
def test_gmx_tip4p(): mol = Topology.open(cwd + '/../topology/files/TIP3P.zmat').molecules[0] ff = ForceField.open(cwd + '/../forcefield/files/TIP4P.zfp') mol.generate_virtual_sites(ff) mol.assign_charge_from_ff(ff) top = Topology([mol], numbers=[100], cell=UnitCell([3, 3, 3])) top.set_positions(Topology.open(cwd + '/files/100-TIP4P.pdb').positions) system = System(top, ff) tmpgro = os.path.join(tmpdir, 'conf-vsite.gro') tmptop = os.path.join(tmpdir, 'topol-vsite.top') tmpmdp = os.path.join(tmpdir, 'grompp-vsite.mdp') system.export_gromacs(gro_out=tmpgro, top_out=tmptop, mdp_out=tmpmdp) assert filecmp.cmp(tmpgro, cwd + '/files/baselines/conf-vsite.gro') assert filecmp.cmp(tmptop, cwd + '/files/baselines/topol-vsite.top') assert filecmp.cmp(tmpmdp, cwd + '/files/baselines/grompp-vsite.mdp')
def test_tip4p(): mol = Topology.open(cwd + '/../topology/files/TIP3P.zmat').molecules[0] ff = ForceField.open(cwd + '/../forcefield/files/TIP4P.zfp') mol.generate_virtual_sites(ff) mol.assign_charge_from_ff(ff) top = Topology([mol], numbers=[100], cell=UnitCell([3, 3, 3])) top.set_positions(Topology.open(cwd + '/files/100-TIP4P.pdb').positions) system = System(top, ff) context = mm.Context(system.to_omm_system(), *get_omm_integrator_platform()) context.setPositions(top.positions) print_energy_terms(context) pe = context.getState(getEnergy=True).getPotentialEnergy().value_in_unit(kJ_mol) assert pytest.approx(pe, rel=0.001) == 383.796 # results of GROMACS
def test_compress(): top = Topology.open(cwd + '/files/10-H2O-5-C3H6.lmp', improper_center=3) molecules = top.molecules for mol in molecules[4:]: for atom in mol.atoms: atom.charge *= 2 top = Topology.open(cwd + '/files/Im11.zmat') molecules += top.molecules top = Topology.open(cwd + '/files/10-H2O-5-C3H6.lmp', improper_center=3) molecules += top.molecules top = Topology.open(cwd + '/files/Im11.zmat') molecules += top.molecules top = Topology() top.update_molecules(molecules) mols_unique = top.get_unique_molecules() for mol, count in mols_unique.items(): print(str(mol), count) assert list(mols_unique.values()) == [4, 6, 5, 1, 10, 5, 1]
if len(args.input) != len(args.number): raise Exception('input and number inconsistent') if args.typer is not None: typer = ZftTyper(args.typer) else: typer = None molecules = [] for inp, n in zip(args.input, args.number): if inp.startswith(':'): if typer is None: raise Exception('--typer is required for SMILES input') top = Topology.open(inp) molecules += top.molecules * n top = Topology(molecules) top.remove_drude_particles() top.remove_virtual_sites() if args.trj is not None: frame = Trajectory.read_frame_from_file(args.trj, -1) if frame.cell.volume != 0: top.cell.set_box(frame.cell.vectors) if args.box is not None: top.cell.set_box(args.box) ff = ForceField.open(*args.forcefield) if args.nodrude: ff.polarizable_terms.clear() ff.virtual_site_terms.clear()
parser.add_argument('--box', nargs=3, default=[-1, -1, -1], type=float, help='overwrite the box dimensions') parser.add_argument('--shift', nargs=3, default=[0, 0, 0], type=float, help='shift the positions of all atoms') args = parser.parse_args() top = Topology.open(args.input) if args.ignore != []: molecules = [mol for mol in top.molecules if mol.name not in args.ignore] top = Topology(molecules) print('Topology info: ', top.n_atom, 'atoms;', top.n_molecule, 'molecules') if args.qscale != 1: for atom in top.atoms: if atom.type in args.qscaleignoreatom or atom.molecule.name in args.qscaleignore: continue atom.charge *= args.qscale box = [ args.box[k] if args.box[k] != -1 else top.cell.size[k] for k in range(3) ] top.cell.set_box(box) if top.has_position and set(args.shift) != {0}: for atom in top.atoms:
def mol2dgl_ff_pairs(mol_list, ff_file, dist_list, distinguish_pairs=False): top = Topology(mol_list) ff = ForceField.open(ff_file) top.assign_charge_from_ff(ff, transfer_bci_terms=True) system = System(top, ff, transfer_bonded_terms=True, suppress_pbc_warning=True) top, ff = system.topology, system.ff graph_list = [] feats_node_list = [] feats_p12_list = [] feats_p13_list = [] feats_p14_list = [] feats_edge_length = len(dist_list[0]) for i, (mol, df) in enumerate(zip(top.molecules, dist_list)): if i % 1000 == 0: print('Processing molecule %i / %i' % (i, len(dist_list))) pairs12, pairs13, pairs14 = mol.get_12_13_14_pairs() edges = list(zip(*[(p[0].id_in_mol, p[1].id_in_mol) for p in pairs12])) u12, v12 = edges[0] + edges[1], edges[1] + edges[0] edges = list(zip(*[(p[0].id_in_mol, p[1].id_in_mol) for p in pairs13])) u13, v13 = tuple(), tuple() if len(pairs13) > 0: u13, v13 = edges[0] + edges[1], edges[1] + edges[0] edges = list(zip(*[(p[0].id_in_mol, p[1].id_in_mol) for p in pairs14])) u14, v14 = tuple(), tuple() if len(pairs14) > 0: u14, v14 = edges[0] + edges[1], edges[1] + edges[0] if distinguish_pairs: graph = dgl.heterograph({ ('atom', 'pair12', 'atom'): (u12, v12), ('atom', 'pair13', 'atom'): (u13, v13), ('atom', 'pair14', 'atom'): (u14, v14), }) else: uv_self = tuple(range(mol.n_atom)) graph = dgl.heterograph({ ('atom', 'pair', 'atom'): (u12 + u13 + u14 + uv_self, v12 + v13 + v14 + uv_self) }) graph_list.append(graph) feats_node = np.zeros((mol.n_atom, 3)) for i, atom in enumerate(mol.atoms): atype = ff.atom_types[atom.type] vdw = ff.get_vdw_term(atype, atype) feats_node[i] = vdw.sigma, vdw.epsilon, atom.charge feats_node_list.append(feats_node) feats_p12 = np.zeros( (len(pairs12) * 2, feats_edge_length)) # bidirectional feats_p13 = np.zeros( (len(pairs13) * 2, feats_edge_length)) # bidirectional feats_p14 = np.zeros( (len(pairs14) * 2, feats_edge_length)) # bidirectional for i, pair in enumerate(pairs12): key = '%s-%s' % (pair[0].name, pair[1].name) feats_p12[i][:] = feats_p12[i + len(pairs12)][:] = df[key].values / 10 for i, pair in enumerate(pairs13): key = '%s-%s' % (pair[0].name, pair[1].name) feats_p13[i][:] = feats_p13[i + len(pairs13)][:] = df[key].values / 10 for i, pair in enumerate(pairs14): key = '%s-%s' % (pair[0].name, pair[1].name) feats_p14[i][:] = feats_p14[i + len(pairs14)][:] = df[key].values / 10 feats_p12_list.append(feats_p12) feats_p13_list.append(feats_p13) feats_p14_list.append(feats_p14) if distinguish_pairs: feats_edges = { 'pair12': [feats[:, 2:13] for feats in feats_p12_list], 'pair13': [feats[:, 7:18] for feats in feats_p13_list], 'pair14': [feats[:, 12:23] for feats in feats_p14_list], } else: feats_self_list = [ np.zeros((mol.n_atom, feats_edge_length)) for mol in top.molecules ] feats_edges = { 'pair': [ np.concatenate(x)[:, 2:23] for x in zip(feats_p12_list, feats_p13_list, feats_p14_list, feats_self_list) ] } return graph_list, feats_node_list, feats_edges
def msd2dgl_ff(mol_list, ff_file): top = Topology(mol_list) ff = ForceField.open(ff_file) top.assign_charge_from_ff(ff, transfer_bci_terms=True) system = System(top, ff, transfer_bonded_terms=True, suppress_pbc_warning=True) top, ff = system.topology, system.ff graph_list = [] feats_node_list = [] feats_bond_list = [] feats_angle_list = [] feats_dihedral_list = [] for mol in top.molecules: feats_node = np.zeros((mol.n_atom, 4)) feats_bond = np.zeros((mol.n_bond * 2, 2)) # bidirectional feats_angle = np.zeros((mol.n_angle * 2, 2)) # bidirectional feats_dihedral = np.zeros((mol.n_dihedral * 2, 3)) # bidirectional for i, atom in enumerate(mol.atoms): atype = ff.atom_types[atom.type] vdw = ff.get_vdw_term(atype, atype) feats_node[i] = vdw.sigma, vdw.epsilon, atom.charge, 0 for i, bond in enumerate(mol.bonds): term = system.bond_terms[id(bond)] inv_k = 1e5 / term.k if not term.fixed else 0 feats_bond[i] = feats_bond[i + mol.n_bond] = term.length * 10, inv_k for i, angle in enumerate(mol.angles): term = system.angle_terms[id(angle)] inv_k = 100 / term.k if not term.fixed else 0 feats_angle[i] = feats_angle[i + mol.n_angle] = term.theta / 100, inv_k for i, dihedral in enumerate(mol.dihedrals): term = system.dihedral_terms[id(dihedral)] k1, k2, k3, k4 = term.get_opls_parameters() feats_dihedral[i] = feats_dihedral[ i + mol.n_dihedral] = k1 / 10, k2 / 10, k3 / 10 for i, improper in enumerate(mol.impropers): term = system.improper_terms[id(improper)] feats_node[improper.atom1.id_in_mol][-1] = term.k / 10 feats_node_list.append(feats_node) feats_bond_list.append(feats_bond) feats_angle_list.append(feats_angle) feats_dihedral_list.append(feats_dihedral) bonds = [(bond.atom1.id_in_mol, bond.atom2.id_in_mol) for bond in mol.bonds] edges = list(zip(*bonds)) u = torch.tensor(edges[0] + edges[1]) # bidirectional v = torch.tensor(edges[1] + edges[0]) graph_data = {('atom', 'bond', 'atom'): (u, v)} angles = [(angle.atom1.id_in_mol, angle.atom3.id_in_mol) for angle in mol.angles] edges = list(zip(*angles)) u = torch.tensor(edges[0] + edges[1]) # bidirectional v = torch.tensor(edges[1] + edges[0]) graph_data.update({('atom', 'angle', 'atom'): (u, v)}) dihedrals = [(dihedral.atom1.id_in_mol, dihedral.atom4.id_in_mol) for dihedral in mol.dihedrals] edges = list(zip(*dihedrals)) u = torch.tensor(edges[0] + edges[1]) # bidirectional v = torch.tensor(edges[1] + edges[0]) graph_data.update({('atom', 'dihedral', 'atom'): (u, v)}) graph = dgl.heterograph(graph_data) graph_list.append(graph) return graph_list, feats_node_list, { 'bond': feats_bond_list, 'angle': feats_angle_list, 'dihedral': feats_dihedral_list }
default=[-1, -1, -1], type=float, help='overwrite the box dimensions') parser.add_argument('--shift', nargs=3, default=[0, 0, 0], type=float, help='shift the positions of all atoms') args = parser.parse_args() top = Topology.open(args.topology) if args.topignore != []: molecules = [ mol for mol in top.molecules if mol.name not in args.topignore ] top = Topology() top.update_molecules(molecules) print('Topology info: ', top.n_atom, 'atoms;', top.n_molecule, 'molecules') trj = Trajectory.open(args.input) print('Trajectory info: ', trj.n_atom, 'atoms;', trj.n_frame, 'frames') if (top.n_atom != trj.n_atom): raise Exception( 'Number of atoms in topology and trajectory files do not match') trj_out = Trajectory.open(args.output, 'w') if args.ignore != []: subset = [ atom.id for atom in top.atoms if atom.type not in args.ignoreatom and atom.molecule.name not in args.ignore
h_1 c_4 c_4h2 c_4h3 ''' typer = ZftTyper(io.StringIO(definition)) butane = Molecule.from_smiles('CCCC butane') typer.type_molecule(butane) # Load force field parameters from ZFP file ff = ForceField.open('alkane.zfp') # Initialize a topology with periodic boundary condition # For now, it contains only one butane molecule top = Topology([butane], cell=UnitCell([3, 3, 3])) # Assign atomic charges based on the charge parameters in the force field top.assign_charge_from_ff(ff) # Call Packmol to build a configuration containing 100 butane molecules packmol = Packmol(r'/path/of/packmol') top.scale_with_packmol([100], packmol=packmol) # Associate force field parameters to the topology # And then export input files for simulation engines system = System(top, ff) system.export_gromacs() system.export_lammps() system.export_charmm()