def test_topology_precedence(): """Test to see if topology precedence is properly adhered to. This test uses a force field file where bond, angle, and dihedral parameters are present with different counts of `type` definitions. It checks that: 1. The parameters with the higher number of `type` definitions are assigned (because they are given the highest precedence) 2. That if multiple definitions exist with the same number of `type` definitions, that the convention from OpenMM is followed whereby the definitions that occurs earliest in the XML is assigned. """ ethane = mb.load(get_fn('ethane.mol2')) ff = Forcefield(forcefield_files=get_fn('ethane-topo-precedence.xml')) typed_ethane = ff.apply(ethane) assert len([bond for bond in typed_ethane.bonds if round(bond.type.req, 2) == 1.15]) == 6 assert len([bond for bond in typed_ethane.bonds if round(bond.type.req, 2) == 1.6]) == 1 assert len([angle for angle in typed_ethane.angles if round(angle.type.theteq, 3) == 120.321]) == 6 assert len([angle for angle in typed_ethane.angles if round(angle.type.theteq, 3) == 97.403]) == 6 assert len([rb for rb in typed_ethane.rb_torsions if round(rb.type.c0, 3) == 0.287]) == 9
def test_improper_dihedral(): untyped_benzene = pmd.load_file(get_fn('benzene.mol2'), structure=True) ff_improper = Forcefield(forcefield_files=get_fn('improper_dihedral.xml')) benzene = ff_improper.apply(untyped_benzene, assert_dihedral_params=False) assert len(benzene.dihedrals) == 18 assert len([dih for dih in benzene.dihedrals if dih.improper]) == 6 assert len([dih for dih in benzene.dihedrals if not dih.improper]) == 12
def test_ring_count(): # Two rings fused = pmd.load_file(get_fn('fused.mol2'), structure=True) top, _ = generate_topology(fused) rule = SMARTSGraph(name='test', parser=PARSER, smarts_string='[#6;R2]') match_indices = list(rule.find_matches(top)) for atom_idx in (3, 4): assert atom_idx in match_indices assert len(match_indices) == 2 rule = SMARTSGraph(name='test', parser=PARSER, smarts_string='[#6;R1]') match_indices = list(rule.find_matches(top)) for atom_idx in (0, 1, 2, 5, 6, 7, 8, 9): assert atom_idx in match_indices assert len(match_indices) == 8 # One ring ring = pmd.load_file(get_fn('ring.mol2'), structure=True) top, _ = generate_topology(ring) rule = SMARTSGraph(name='test', parser=PARSER, smarts_string='[#6;R1]') match_indices = list(rule.find_matches(top)) for atom_idx in range(6): assert atom_idx in match_indices assert len(match_indices) == 6
def test_ringness(): ring = pmd.load_file(get_fn('ring.mol2'), structure=True) top, _ = generate_topology(ring) _rule_match(top, '[#6]1[#6][#6][#6][#6][#6]1', True) not_ring = pmd.load_file(get_fn('not_ring.mol2'), structure=True) top, _ = generate_topology(not_ring) _rule_match(top, '[#6]1[#6][#6][#6][#6][#6]1', False)
def test_missing_topo_params(ff_filename, kwargs): """Test that the user is notified if not all topology parameters are found.""" ethane = mb.load(get_fn('ethane.mol2')) oplsaa_with_typo = Forcefield(forcefield_files=get_fn(ff_filename)) with pytest.raises(Exception): ethane = oplsaa_with_typo.apply(ethane) with pytest.warns(UserWarning): ethane = oplsaa_with_typo.apply(ethane, **kwargs)
def test_write_refs_multiple(): mol2 = mb.load(get_fn('ethane.mol2')) oplsaa = Forcefield(forcefield_files=get_fn('refs-multi.xml')) ethane = oplsaa.apply(mol2, references_file='ethane-multi.bib') assert os.path.isfile('ethane-multi.bib') with open(get_fn('ethane-multi.bib')) as file1: with open('ethane-multi.bib') as file2: diff = list(difflib.unified_diff(file1.readlines(), file2.readlines(), n=0)) assert not diff
def test_from_mbuild_customtype(): mol2 = mb.load(get_fn('ethane_customtype.pdb')) customtype_ff = Forcefield(forcefield_files=get_fn('validate_customtypes.xml')) ethane = customtype_ff.apply(mol2) assert sum((1 for at in ethane.atoms if at.type == 'C3')) == 2 assert sum((1 for at in ethane.atoms if at.type == 'Hb')) == 6 assert len(ethane.bonds) == 7 assert all(x.type for x in ethane.bonds) assert len(ethane.angles) == 12 assert all(x.type for x in ethane.angles) assert len(ethane.rb_torsions) == 9 assert all(x.type for x in ethane.dihedrals)
def test_preserve_resname(): untyped_ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) untyped_resname = untyped_ethane.residues[0].name oplsaa = Forcefield(name='oplsaa') typed_ethane = oplsaa.apply(untyped_ethane) typed_resname = typed_ethane.residues[0].name assert typed_resname == untyped_resname
def test_uniqueness(): mol2 = pmd.load_file(get_fn('uniqueness_test.mol2'), structure=True) top, _ = generate_topology(mol2) _rule_match(top, '[#6]1[#6][#6][#6][#6][#6]1', False) _rule_match(top, '[#6]1[#6][#6][#6][#6]1', False) _rule_match(top, '[#6]1[#6][#6][#6]1', True)
def test_missing_overrides(): top = os.path.join(OPLS_TESTFILES_DIR, 'benzene/benzene.top') gro = os.path.join(OPLS_TESTFILES_DIR, 'benzene/benzene.gro') structure = pmd.load_file(top, xyz=gro) forcefield = Forcefield(get_fn('missing_overrides.xml')) with pytest.raises(FoyerError): forcefield.apply(structure)
def test_uniqueness(): mol2 = pmd.load_file(get_fn('uniqueness_test.mol2'), structure=True) top = generate_topology(mol2) atom1 = next(top.atoms()) _rule_match(atom1, '[#6]1[#6][#6][#6][#6][#6]1', False) _rule_match(atom1, '[#6]1[#6][#6][#6][#6]1', False) _rule_match(atom1, '[#6]1[#6][#6][#6]1', True)
def test_hexa_coordinated(): ff = Forcefield(forcefield_files=get_fn('pf6.xml')) mol2 = pmd.load_file(get_fn('pf6.mol2'), structure=True) pf6 = ff.apply(mol2) types = [a.type for a in pf6.atoms] assert types.count('P') == 1 assert types.count('F1') == 2 assert types.count('F2') == 2 assert types.count('F3') == 2 assert len(pf6.bonds) == 6 assert all(bond.type for bond in pf6.bonds) assert len(pf6.angles) == 15 assert all(angle.type for angle in pf6.angles)
def test_cycle_finding_multiple(): fullerene = pmd.load_file(get_fn('fullerene.pdb'), structure=True) top, _ = generate_topology(fullerene) _prepare_atoms(top, compute_cycles=True) cycle_lengths = [list(map(len, atom.cycles)) for atom in top.atoms()] expected = [5, 6, 6] assert all(sorted(lengths) == expected for lengths in cycle_lengths)
def test_fused_ring(): fused = pmd.load_file(get_fn('fused.mol2'), structure=True) top, _ = generate_topology(fused) rule = SMARTSGraph(name='test', parser=PARSER, smarts_string='[#6]12[#6][#6][#6][#6][#6]1[#6][#6][#6][#6]2') match_indices = list(rule.find_matches(top)) assert 3 in match_indices assert 4 in match_indices assert len(match_indices) == 2
def test_from_parmed(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) oplsaa = Forcefield(name='oplsaa') ethane = oplsaa.apply(mol2) assert sum((1 for at in ethane.atoms if at.type == 'opls_135')) == 2 assert sum((1 for at in ethane.atoms if at.type == 'opls_140')) == 6 assert len(ethane.bonds) == 7 assert all(x.type for x in ethane.bonds) assert len(ethane.angles) == 12 assert all(x.type for x in ethane.angles) assert len(ethane.rb_torsions) == 9 assert all(x.type for x in ethane.dihedrals) mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) mol2.box_vectors = [[2, 0, 0], [0, 2, 0], [0, 0, 2]] oplsaa = Forcefield(name='oplsaa') ethane = oplsaa.apply(mol2) assert ethane.box_vectors == mol2.box_vectors
def test_not(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top = generate_topology(mol2) atom1 = next(top.atoms()) checks = {'[!O]': True, '[!#5]': True, '[!C]': False, '[!#6]': False, } for smart, result in checks.items(): _rule_match(atom1, smart, result)
def test_precedence(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top, _ = generate_topology(mol2) checks = {'[C,O;C]': 2, '[C&O;C]': 0, '[!C;O,C]': 0, '[!C&O,C]': 2, } for smart, result in checks.items(): _rule_match_count(top, smart, result)
def test_fused_ring(): fused = pmd.load_file(get_fn('fused.mol2'), structure=True) top = generate_topology(fused) atoms = list(top.atoms()) rule = Rule('test', parser=PARSER, smarts_string='[#6]12[#6][#6][#6][#6][#6]1[#6][#6][#6][#6]2') assert rule.matches(atoms[2]) is False for _ in range(10): # Traversal order during matching is stochastic. assert rule.matches(atoms[3]) is True assert rule.matches(atoms[4]) is True assert rule.matches(atoms[5]) is False
def test_lazy_cycle_finding(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top, _ = generate_topology(mol2) rule = SMARTSGraph(smarts_string='[C]') list(rule.find_matches(top)) assert not any([hasattr(a, 'cycles') for a in top.atoms()]) ring_tokens = ['R1', 'r6'] for token in ring_tokens: rule = SMARTSGraph(smarts_string='[C;{}]'.format(token)) list(rule.find_matches(top)) assert all([hasattr(a, 'cycles') for a in top.atoms()])
def test_precedence(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top = generate_topology(mol2) atom1 = next(top.atoms()) checks = {'[C,H;C]': True, '[C&H;C]': False, '[!C;H,C]': False, '[!C&H,C]': True, } for smart, result in checks.items(): _rule_match(atom1, smart, result)
def test_not(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top, _ = generate_topology(mol2) checks = {'[!O]': 8, '[!#5]': 8, '[!C]': 6, '[!#6]': 6, '[!C&!H]': 0, '[!C;!H]': 0, } for smart, result in checks.items(): _rule_match_count(top, smart, result)
def test_from_mbuild(): mol2 = mb.load(get_fn('ethane.mol2')) oplsaa = Forcefield(name='oplsaa') ethane = oplsaa.apply(mol2) assert sum((1 for at in ethane.atoms if at.type == 'opls_135')) == 2 assert sum((1 for at in ethane.atoms if at.type == 'opls_140')) == 6 assert len(ethane.bonds) == 7 assert all(x.type for x in ethane.bonds) assert len(ethane.angles) == 12 assert all(x.type for x in ethane.angles) assert len(ethane.rb_torsions) == 9 assert all(x.type for x in ethane.dihedrals)
def test_uniqueness(): mol2 = pmd.load_file(get_fn('uniqueness_test.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in mol2.atoms } _rule_match(mol2, typemap, '[#6]1[#6][#6][#6][#6][#6]1', False) _rule_match(mol2, typemap, '[#6]1[#6][#6][#6][#6]1', False) _rule_match(mol2, typemap, '[#6]1[#6][#6][#6]1', True)
def test_precedence(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top = generate_topology(mol2) atom1 = next(top.atoms()) checks = { '[C,H;C]': True, '[C&H;C]': False, '[!C;H,C]': False, '[!C&H,C]': True, } for smart, result in checks.items(): _rule_match(atom1, smart, result)
def test_from_mbuild(self, oplsaa): mol2 = mb.load(get_fn("ethane.mol2"), backend="parmed") ethane = oplsaa.apply(mol2, assert_improper_params=False) assert (sum((1 for at in ethane.sites if at.atom_type.name == "opls_135")) == 2) assert (sum((1 for at in ethane.sites if at.atom_type.name == "opls_140")) == 6) assert len(ethane.bonds) == 7 assert all(x.bond_type for x in ethane.bonds) assert len(ethane.angles) == 12 assert all(x.angle_type for x in ethane.angles) assert len(ethane.dihedrals) == 9 assert all(x.dihedral_type for x in ethane.dihedrals)
def test_from_mbuild(): import mbuild as mb mol2 = mb.load(get_fn('ethane.mol2')) oplsaa = Forcefield(name='oplsaa') ethane = oplsaa.apply(mol2) assert sum((1 for at in ethane.atoms if at.type == 'opls_135')) == 2 assert sum((1 for at in ethane.atoms if at.type == 'opls_140')) == 6 assert len(ethane.bonds) == 7 assert all(x.type for x in ethane.bonds) assert len(ethane.angles) == 12 assert all(x.type for x in ethane.angles) assert len(ethane.rb_torsions) == 9 assert all(x.type for x in ethane.dihedrals)
def test_not(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) top, _ = generate_topology(mol2) checks = { '[!O]': 8, '[!#5]': 8, '[!C]': 6, '[!#6]': 6, '[!C&!H]': 0, '[!C;!H]': 0, } for smart, result in checks.items(): _rule_match_count(top, smart, result)
def test_write_refs_multiple(requests_mock): import mbuild as mb register_mock_request( mocker=requests_mock, url='http://api.crossref.org/', path='works/10.1021/ja9621760/transform/application/x-bibtex', headers={'accept': 'application/x-bibtex'}, text=RESPONSE_BIB_ETHANE_JA962170) register_mock_request( mocker=requests_mock, url='http://api.crossref.org/', path='works/10.1021/jp0484579/transform/application/x-bibtex', headers={'accept': 'application/x-bibtex'}, text=RESPONSE_BIB_ETHANE_JP0484579) mol2 = mb.load(get_fn('ethane.mol2')) oplsaa = Forcefield(forcefield_files=get_fn('refs-multi.xml')) ethane = oplsaa.apply(mol2, references_file='ethane-multi.bib') assert os.path.isfile('ethane-multi.bib') with open(get_fn('ethane-multi.bib')) as file1: with open('ethane-multi.bib') as file2: diff = list( difflib.unified_diff(file1.readlines(), file2.readlines(), n=0)) assert not diff
def test_ringness(): ring_mol2 = pmd.load_file(get_fn('ring.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in ring_mol2.atoms } _rule_match(ring_mol2, typemap, '[#6]1[#6][#6][#6][#6][#6]1', True) not_ring_mol2 = pmd.load_file(get_fn('not_ring.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in not_ring_mol2.atoms } _rule_match(not_ring_mol2, typemap, '[#6]1[#6][#6][#6][#6][#6]1', False)
def test_uniqueness(): mol2 = pmd.load_file(get_fn('uniqueness_test.mol2'), structure=True) top, _ = generate_topology(mol2) typemap = { atom.index: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in top.atoms() } _rule_match(top, typemap, '[#6]1[#6][#6][#6][#6][#6]1', False) _rule_match(top, typemap, '[#6]1[#6][#6][#6][#6]1', False) _rule_match(top, typemap, '[#6]1[#6][#6][#6]1', True)
def test_residue_map(): ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) ethane *= 2 oplsaa = Forcefield(name='oplsaa') topo, NULL = generate_topology(ethane) with_map = pmd.openmm.load_topology( topo, oplsaa.createSystem(topo, use_residue_map=True)) without_map = pmd.openmm.load_topology( topo, oplsaa.createSystem(topo, use_residue_map=False)) for atom_with, atom_without in zip(with_map.atoms, without_map.atoms): assert atom_with.type == atom_without.type b_with = atom_with.bond_partners b_without = atom_without.bond_partners assert [a0.type for a0 in b_with] == [a1.type for a1 in b_without] assert [a0.idx for a0 in b_with] == [a1.idx for a1 in b_without]
def test_remove_untyped(self): mol2 = mb.load(get_fn("ethane.mol2"), backend="parmed") # test removal of untyped each class of connection seperately oplsaa_bond = Forcefield( forcefield_files=get_fn("ethane-missing_bond.xml"), strict=False) oplsaa_angle = Forcefield( forcefield_files=get_fn("ethane-missing_angle.xml"), strict=False) oplsaa_dihedral = Forcefield( forcefield_files=get_fn("ethane-missing_dihedral.xml"), strict=False) ethane1 = oplsaa_bond.apply( mol2, assert_improper_params=False, assert_bond_params=False, remove_untyped_connections=True, ) ethane2 = oplsaa_angle.apply( mol2, assert_improper_params=False, assert_angle_params=False, remove_untyped_connections=True, ) ethane3 = oplsaa_dihedral.apply( mol2, assert_improper_params=False, assert_dihedral_params=False, remove_untyped_connections=True, ) assert ethane1.n_bonds == 1 assert ethane2.n_angles == 6 assert ethane3.n_dihedrals == 0
def test_residue_map(): ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) ethane *= 2 oplsaa = Forcefield(name='oplsaa') topo, NULL = generate_topology(ethane) topo_with = oplsaa.run_atomtyping(topo, use_residue_map=True) topo_without = oplsaa.run_atomtyping(topo, use_residue_map=False) assert all([a.id for a in topo_with.atoms()][0]) assert all([a.id for a in topo_without.atoms()][0]) struct_with = pmd.openmm.load_topology(topo_with, oplsaa.createSystem(topo_with)) struct_without = pmd.openmm.load_topology(topo_without, oplsaa.createSystem(topo_without)) for atom_with, atom_without in zip(struct_with.atoms, struct_without.atoms): assert atom_with.type == atom_without.type b_with = atom_with.bond_partners b_without = atom_without.bond_partners assert [a0.type for a0 in b_with] == [a1.type for a1 in b_without] assert [a0.idx for a0 in b_with] == [a1.idx for a1 in b_without]
def test_write_xml_overrides(): #Test xml_writer new overrides and comments features mol = pmd.load_file(get_fn('styrene.mol2'), structure=True) oplsaa = Forcefield(name='oplsaa') typed = oplsaa.apply(mol, assert_dihedral_params=False) typed.write_foyer(filename='opls-styrene.xml', forcefield=oplsaa, unique=True) styrene = ET.parse('opls-styrene.xml') atom_types = styrene.getroot().find('AtomTypes').findall('Type') for item in atom_types: attributes = item.attrib if attributes['name'] == 'opls_145': assert attributes['overrides'] == 'opls_142' assert str(item.xpath('comment()')) in {'[<!--Note: original overrides="opls_141,opls_142"-->]', '[<!--Note: original overrides="opls_142,opls_141"-->]'} elif attributes['name'] == 'opls_146': assert attributes['overrides'] == 'opls_144' assert str(item.xpath('comment()')) == '[<!--Note: original overrides="opls_144"-->]'
def test_cycle_finding_multiple(): mol2 = pmd.load_file(get_fn('fullerene.pdb'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in mol2.atoms } _prepare_atoms(mol2, typemap, compute_cycles=True) cycle_lengths = [ list(map(len, typemap[atom.idx]['cycles'])) for atom in mol2.atoms ] expected = [5, 6, 6] assert all(sorted(lengths) == expected for lengths in cycle_lengths)
def test_not(self, rule_match_count): mol2 = pmd.load_file(get_fn("ethane.mol2"), structure=True) typemap = { atom.idx: {"whitelist": set(), "blacklist": set(), "atomtype": None} for atom in mol2.atoms } mol2_graph = TopologyGraph.from_parmed(mol2) checks = { "[!O]": 8, "[!#5]": 8, "[!C]": 6, "[!#6]": 6, "[!C&!H]": 0, "[!C;!H]": 0, } for smart, result in checks.items(): rule_match_count(mol2_graph, typemap, smart, result)
def test_combining_rule(self, ff_name, expected_combining_rule, expected_14_sigma): import mbuild as mb ff = Forcefield(get_fn(ff_name)) benzene = mb.load("c1ccccc1", smiles=True) out = ff.apply(benzene) assert out.combining_rule == expected_combining_rule for adj in out.adjusts: if adj.atom1.name == "C" and adj.atom2.name == "H": break found_14_sigma = adj.type.sigma assert abs(found_14_sigma - expected_14_sigma) < 1e-10
def test_residue_map(): ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) ethane *= 2 oplsaa = Forcefield(name='oplsaa') map_with = oplsaa.run_atomtyping(ethane, use_residue_map=True) map_without = oplsaa.run_atomtyping(ethane, use_residue_map=False) assert all([a['atomtype'] for a in map_with.values()]) assert all([a['atomtype'] for a in map_without.values()]) struct_with = ethane struct_without = ethane oplsaa._apply_typemap(struct_with, map_with) oplsaa._apply_typemap(struct_without, map_without) for atom_with, atom_without in zip(struct_with.atoms, struct_without.atoms): assert atom_with.type == atom_without.type b_with = atom_with.bond_partners b_without = atom_without.bond_partners assert [a0.type for a0 in b_with] == [a1.type for a1 in b_without] assert [a0.idx for a0 in b_with] == [a1.idx for a1 in b_without]
def test_charmm_improper(): system = mb.Compound() first = mb.Particle(name='_CTL2',pos=[-1,0,0]) second = mb.Particle(name='_CL', pos=[0,0,0]) third = mb.Particle(name='_OBL', pos=[1,0,0]) fourth = mb.Particle(name='_OHL', pos = [0,1,0]) system.add([first, second, third, fourth]) system.add_bond((first,second)) system.add_bond((second, third)) system.add_bond((second, fourth)) ff = Forcefield(forcefield_files=[get_fn('charmm36_cooh.xml')]) struc = ff.apply(system, assert_angle_params=False, asset_dihedral_params=False, assert_improper_params=False) assert len(struc.impropers) == 1 assert len(struc.dihedrals) == 0
def test_cycle_finding_multiple(): fullerene = pmd.load_file(get_fn('fullerene.pdb'), structure=True) top, _ = generate_topology(fullerene) typemap = { atom.index: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in top.atoms() } _prepare_atoms(top, typemap, compute_cycles=True) #cycle_lengths = [list(map(len, atom.cycles)) for atom in top.atoms()] cycle_lengths = [ list(map(len, typemap[atom.index]['cycles'])) for atom in top.atoms() ] expected = [5, 6, 6] assert all(sorted(lengths) == expected for lengths in cycle_lengths)
def test_fused_ring(self, smarts_parser): mol2 = pmd.load_file(get_fn("fused.mol2"), structure=True) mol2_graph = TopologyGraph.from_parmed(mol2) typemap = { atom.idx: {"whitelist": set(), "blacklist": set(), "atomtype": None} for atom in mol2.atoms } rule = SMARTSGraph( name="test", parser=smarts_parser, smarts_string="[#6]12[#6][#6][#6][#6][#6]1[#6][#6][#6][#6]2", typemap=typemap, ) match_indices = list(rule.find_matches(mol2_graph, typemap)) assert 3 in match_indices assert 4 in match_indices assert len(match_indices) == 2
def test_apply_nbfix_bad_atom_type(self, oplsaa): ethane = pmd.load_file(get_fn("ethane.mol2"), structure=True) ethane = oplsaa.apply(ethane) with pytest.raises(ValueError): apply_nbfix( struct=ethane, atom_type1="opls__typo_135", atom_type2="opls_140", sigma=0.4, epsilon=50.0, ) with pytest.raises(ValueError): apply_nbfix( struct=ethane, atom_type1="opls_135", atom_type2="opls_141", sigma=0.4, epsilon=50.0, )
def test_residue_map(): ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) ethane *= 2 oplsaa = Forcefield(name='oplsaa') topo, NULL = generate_topology(ethane) topo_with = oplsaa.run_atomtyping(topo, use_residue_map=True) topo_without = oplsaa.run_atomtyping(topo, use_residue_map=False) assert all([a.id for a in topo_with.atoms()][0]) assert all([a.id for a in topo_without.atoms()][0]) struct_with = pmd.openmm.load_topology(topo_with, oplsaa.createSystem(topo_with)) struct_without = pmd.openmm.load_topology( topo_without, oplsaa.createSystem(topo_without)) for atom_with, atom_without in zip(struct_with.atoms, struct_without.atoms): assert atom_with.type == atom_without.type b_with = atom_with.bond_partners b_without = atom_without.bond_partners assert [a0.type for a0 in b_with] == [a1.type for a1 in b_without] assert [a0.idx for a0 in b_with] == [a1.idx for a1 in b_without]
def test_precedence(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in mol2.atoms } checks = { '[C,O;C]': 2, '[C&O;C]': 0, '[!C;O,C]': 0, '[!C&O,C]': 2, } for smart, result in checks.items(): _rule_match_count(mol2, typemap, smart, result)
def test_apply_nbfix_bad_atom_type(): opls = Forcefield(name='oplsaa') ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) ethane = opls.apply(ethane) with pytest.raises(ValueError): apply_nbfix( struct=ethane, atom_type1='opls__typo_135', atom_type2='opls_140', sigma=0.4, epsilon=50.0, ) with pytest.raises(ValueError): apply_nbfix( struct=ethane, atom_type1='opls_135', atom_type2='opls_141', sigma=0.4, epsilon=50.0, )
def test_write_xml_overrides(self, oplsaa): # Test xml_writer new overrides and comments features mol = pmd.load_file(get_fn("styrene.mol2"), structure=True) typed = oplsaa.apply(mol, assert_dihedral_params=False) typed.write_foyer(filename="opls-styrene.xml", forcefield=oplsaa, unique=True) styrene = ET.parse("opls-styrene.xml") atom_types = styrene.getroot().find("AtomTypes").findall("Type") for item in atom_types: attributes = item.attrib if attributes["name"] == "opls_145": assert attributes["overrides"] == "opls_142" assert str(item.xpath("comment()")) in { '[<!--Note: original overrides="opls_141,opls_142"-->]', '[<!--Note: original overrides="opls_142,opls_141"-->]', } elif attributes["name"] == "opls_146": assert attributes["overrides"] == "opls_144" assert (str(item.xpath("comment()")) == '[<!--Note: original overrides="opls_144"-->]')
def test_not(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in mol2.atoms } checks = { '[!O]': 8, '[!#5]': 8, '[!C]': 6, '[!#6]': 6, '[!C&!H]': 0, '[!C;!H]': 0, } for smart, result in checks.items(): _rule_match_count(mol2, typemap, smart, result)
def test_fused_ring(): mol2 = pmd.load_file(get_fn('fused.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in mol2.atoms } rule = SMARTSGraph( name='test', parser=PARSER, smarts_string='[#6]12[#6][#6][#6][#6][#6]1[#6][#6][#6][#6]2', typemap=typemap) match_indices = list(rule.find_matches(mol2, typemap)) assert 3 in match_indices assert 4 in match_indices assert len(match_indices) == 2
def test_lazy_cycle_finding(): mol2 = pmd.load_file(get_fn('ethane.mol2'), structure=True) typemap = { atom.idx: { 'whitelist': set(), 'blacklist': set(), 'atomtype': None } for atom in mol2.atoms } rule = SMARTSGraph(smarts_string='[C]', typemap=typemap) list(rule.find_matches(mol2, typemap)) assert not any(['cycles' in typemap[a.idx] for a in mol2.atoms]) ring_tokens = ['R1', 'r6'] for token in ring_tokens: rule = SMARTSGraph(smarts_string='[C;{}]'.format(token), typemap=typemap) list(rule.find_matches(mol2, typemap)) assert all(['cycles' in typemap[a.idx] for a in mol2.atoms])
def test_urey_bradley(self): system = mb.Compound() first = mb.Particle(name="_CTL2", pos=[-1, 0, 0]) second = mb.Particle(name="_CL", pos=[0, 0, 0]) third = mb.Particle(name="_OBL", pos=[1, 0, 0]) fourth = mb.Particle(name="_OHL", pos=[0, 1, 0]) system.add([first, second, third, fourth]) system.add_bond((first, second)) system.add_bond((second, third)) system.add_bond((second, fourth)) ff = Forcefield(forcefield_files=[get_fn("charmm36_cooh.xml")], strict=False) struc = ff.apply( system, assert_angle_params=False, assert_dihedral_params=False, assert_improper_params=False, ) assert len(struc.angles) == 3 assert len(struc.angle_types) == 3 # 1 harmonic, 2 Urey Bradley
def test_apply_nbfix(): opls = Forcefield(name='oplsaa') ethane = pmd.load_file(get_fn('ethane.mol2'), structure=True) ethane = opls.apply(ethane) ethane_tweaked = apply_nbfix( struct=ethane, atom_type1='opls_135', atom_type2='opls_140', sigma=0.4, epsilon=50.0, ) assert not ethane.has_NBFIX() assert ethane_tweaked.has_NBFIX() # 0.44898.... is rmin, which parmed uses internally in place of sigma for atom in ethane_tweaked: if atom.atom_type.name == 'opls_135': assert np.allclose(atom.atom_type.nbfix['opls_140'][:2], [0.44898481932374923, 50.0]) elif atom.atom_type.name == 'opls_140': assert np.allclose(atom.atom_type.nbfix['opls_135'][:2], [0.44898481932374923, 50.0])
def test_charmm_improper(self): system = mb.Compound() first = mb.Particle(name="_CTL2", pos=[-1, 0, 0]) second = mb.Particle(name="_CL", pos=[0, 0, 0]) third = mb.Particle(name="_OBL", pos=[1, 0, 0]) fourth = mb.Particle(name="_OHL", pos=[0, 1, 0]) system.add([first, second, third, fourth]) system.add_bond((first, second)) system.add_bond((second, third)) system.add_bond((second, fourth)) ff = Forcefield(forcefield_files=[get_fn("charmm36_cooh.xml")], strict=False) struc = ff.apply( system, assert_angle_params=False, assert_dihedral_params=False, assert_improper_params=False, remove_untyped_connections=False, ) assert len(struc.impropers) == 1 assert len(struc.dihedrals) == 0
def test_apply_subfuncs(self, oplsaa): mol2 = mb.load(get_fn("ethane.mol2"), backend="parmed") ethane = oplsaa.apply(mol2, assert_improper_params=False) typemap = oplsaa._run_atomtyping(mol2, use_residue_map=False) ethane2 = oplsaa._parametrize(mol2, typemap=typemap, assert_improper_params=False) assert ethane.box == ethane2.box assert (ethane.positions == ethane2.positions).all for a1, a2 in zip(ethane.sites, ethane2.sites): assert a1.name == a2.name assert ethane.get_index(a1) == ethane2.get_index(a2) assert a1.atom_type == a2.atom_type for b1, b2 in zip(ethane.bonds, ethane2.bonds): assert (b1.connection_members[0].atom_type == b2.connection_members[0].atom_type) assert (b1.connection_members[1].atom_type == b2.connection_members[1].atom_type) assert b1.bond_type == b2.bond_type
def test_fullerene(): fullerene = pmd.load_file(get_fn('fullerene.pdb'), structure=True) forcefield = Forcefield(get_fn('fullerene.xml')) forcefield.apply(fullerene, assert_dihedral_params=False)
def test_polymer(): peg100 = mb.load(get_fn('peg100.mol2')) forcefield = Forcefield(name='oplsaa') forcefield.apply(peg100)
def test_write_refs(): mol2 = mb.load(get_fn('ethane.mol2')) oplsaa = Forcefield(name='oplsaa') ethane = oplsaa.apply(mol2, references_file='ethane.bib') assert os.path.isfile('ethane.bib')
import parmed as pmd from foyer import Forcefield from foyer.tests.utils import get_fn if __name__ == '__main__': mol2_path = get_fn('ethane.mol2') untyped_ethane = pmd.load_file(mol2_path, structure=True) oplsaa = Forcefield(name='oplsaa') ethane = oplsaa.apply(untyped_ethane, references_file='ethane.bib') print("Atoms:") for atom in ethane.atoms: print('Atom {} is typed as {}'.format(atom, atom.type)) print("Bonds:") for bond in ethane.bonds: print('{} '.format(bond)) print("Angles:") for angle in ethane.angles: print('{} '.format(angle)) print("Dihedrals:") for dihedral in ethane.dihedrals: print('{} '.format(dihedral)) # Save to GROMACS ethane.save('ethane.gro') ethane.save('ethane.top') # Within the `Forcefield.apply` method, an intermediate OpenMM system is
def test_missing_definition(): structure = pmd.load_file(get_fn('silly_chemistry.mol2'), structure=True) forcefield = Forcefield(get_fn('missing_overrides.xml')) with pytest.raises(FoyerError): forcefield.apply(structure)
smarts_graph = SMARTSGraph(smarts_string, parser=self.smarts_parser, name=name, overrides=r.attrib.get('overrides')) for atom_expr in nx.get_node_attributes(smarts_graph, 'atom').values(): labels = atom_expr.select('has_label') for label in labels: atom_type = label.tail[0][1:] if atom_type not in atom_types: raise ValidationError( "Reference to undefined atomtype {} in SMARTS string" " '{}' at line {}".format( atom_type, r.attrib['def'], r.sourceline), None, r.sourceline) warn("The following atom types do not have smarts definitions: {}".format(', '.join(missing_smarts)), ValidationWarning) def validate_overrides(self, ff_tree): results = ff_tree.xpath('/ForceField/AtomTypes/Type[@name]') for r in results: smarts_string = r.attrib['def'] print(smarts_string) print(r.sourceline) # make sure smarts string can be parsed self.smarts.parse(smarts_string) if __name__ == '__main__': # ff_file_name = join(split(abspath(__file__))[0], 'forcefields', 'oplsaa.xml') from foyer.tests.utils import get_fn v = Validator(get_fn('smarts_preprocess.xml'))
def test_surface(): surface = mb.load(get_fn('silica.mol2')) forcefield = Forcefield(get_fn('opls-silica.xml')) forcefield.apply(surface, assert_bond_params=False)