From da3a010230bfa261bab340093b3bf9899be21f9b Mon Sep 17 00:00:00 2001 From: Fabian Gruenewald Date: Thu, 15 Aug 2024 17:33:42 +0200 Subject: [PATCH] fix OPLS ligpargen atomtypes --- polyply/src/gen_ff.py | 31 +++++++- .../gen_ff/PEG_PBE/{in_itp.itp => in.top} | 74 +++++++++++++++++++ polyply/tests/test_gen_ff.py | 10 +-- 3 files changed, 108 insertions(+), 7 deletions(-) rename polyply/tests/test_data/gen_ff/PEG_PBE/{in_itp.itp => in.top} (85%) diff --git a/polyply/src/gen_ff.py b/polyply/src/gen_ff.py index c3cce479..bf87d87a 100644 --- a/polyply/src/gen_ff.py +++ b/polyply/src/gen_ff.py @@ -22,6 +22,27 @@ from polyply.src.charges import balance_charges, set_charges from .load_library import load_ff_library +def is_opls(topology): + atomtypes = list(topology.atom_types.keys()) + if "opls" in atomtypes[0]: + return True + return False + +def _clean_opls_atomtypes(topology): + old_to_new = {} + unique_atypes = {} + + for atype, params in topology.atom_types.items(): + nb_vals = (str(params['nb1']), str(params['nb2'])) + if nb_vals not in unique_atypes: + unique_atypes[nb_vals] = atype + old_to_new[atype] = unique_atypes[nb_vals] + for mol in topology.molecules: + for node in mol.molecule.nodes: + mol.molecule.nodes[node]["atype"] = old_to_new[mol.molecule.nodes[node]["atype"]] + mol.relabel_and_redo_res_graph(mapping={}) + return topology + def _read_itp_file(itppath): """ small wrapper for reading itps @@ -37,7 +58,7 @@ def _read_itp_file(itppath): def gen_ff(itppath, smile_str, outpath, inpath=[], res_charges=None): """ - Main executable for itp to ff tool. + Main executable for gen_ff tool. """ # load FF files if given if inpath: @@ -53,7 +74,13 @@ def gen_ff(itppath, smile_str, outpath, inpath=[], res_charges=None): # read the topology file if itppath.suffix == ".top": top = Topology.from_gmx_topfile(itppath, name="test") - target_mol = top.molecules[0].molecule + # opls specific fix + # in LigParGen each atom get's its own atype even though + # they are the same; pretty strange but this confuses + # the terminal modifications module + if top and is_opls(top): + _clean_opls_atomtypes(top) + target_mol = top.molecules[0].molecule # read itp file elif itppath.suffix == ".itp": top = None diff --git a/polyply/tests/test_data/gen_ff/PEG_PBE/in_itp.itp b/polyply/tests/test_data/gen_ff/PEG_PBE/in.top similarity index 85% rename from polyply/tests/test_data/gen_ff/PEG_PBE/in_itp.itp rename to polyply/tests/test_data/gen_ff/PEG_PBE/in.top index 4fb4521a..1fb1899f 100644 --- a/polyply/tests/test_data/gen_ff/PEG_PBE/in_itp.itp +++ b/polyply/tests/test_data/gen_ff/PEG_PBE/in.top @@ -1,3 +1,73 @@ +[ defaults ] +; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ +1 3 yes 0.5 0.5 + +[ atomtypes ] + opls_814 C814 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_842 H842 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_862 H862 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_818 C818 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_843 H843 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_807 C807 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_836 H836 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_834 H834 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_828 H828 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_806 C806 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_860 H860 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_851 H851 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_812 C812 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_819 O819 1 15.9990 0.000 A 2.90000E-01 5.85760E-01 + opls_815 C815 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_811 C811 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_861 H861 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_827 H827 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_801 C801 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_838 H838 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_844 H844 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_857 H857 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_824 C824 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_830 H830 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_825 C825 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_805 C805 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_848 H848 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_826 H826 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_821 C821 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_837 H837 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_829 H829 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_831 H831 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_832 H832 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_803 C803 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_822 O822 1 15.9990 0.000 A 3.12000E-01 7.11280E-01 + opls_800 C800 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_858 H858 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_846 H846 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_856 H856 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_833 H833 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_810 C810 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_813 C813 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_816 O816 1 15.9990 0.000 A 2.90000E-01 5.85760E-01 + opls_820 C820 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_835 H835 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_841 H841 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_852 H852 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_804 C804 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_855 H855 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_839 H839 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_817 C817 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_809 C809 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_808 C808 1 12.0110 0.000 A 3.50000E-01 2.76144E-01 + opls_850 H850 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_840 H840 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_849 H849 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_823 H823 1 1.0080 0.000 A 0.00000E+00 0.00000E+00 + opls_847 H847 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_853 H853 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_802 C802 1 12.0110 0.000 A 3.55000E-01 3.17984E-01 + opls_845 H845 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_854 H854 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + opls_859 H859 1 1.0080 0.000 A 2.50000E-01 1.25520E-01 + + [ moleculetype ] ; Name nrexcl @@ -571,3 +641,7 @@ PBE_PEO 3 61 62 1 61 63 1 +[system] +test +[molecules] +PBE_PEO 1 diff --git a/polyply/tests/test_gen_ff.py b/polyply/tests/test_gen_ff.py index 8f2c02ae..7bc23fd7 100644 --- a/polyply/tests/test_gen_ff.py +++ b/polyply/tests/test_gen_ff.py @@ -79,11 +79,11 @@ def itp_equal(ref_mol, new_mol): [("OHter", 0), ("PEO", 0)], ), # test case 2 PEO-PBE block cooplymer with two termini - # ("PEG_PBE", - # "in_itp.itp", - # "{[#CH3ter][#PBE]|4[#PEO]|2[#OHter]}.{#PEO=[>]COC[<],#OHter=[<]CO,#CH3ter=[>]C,#PBE=[>]CC[<]C=C}", - # [("CH3ter", 0), ("PBE", 0), ("PEO", 0), ("OHter", 0)], - # ), + ("PEG_PBE", + "in.top", + "{[#CH3ter][#PBE]|4[#PEO]|2[#OHter]}.{#PEO=[>]COC[<],#OHter=[<]CO,#CH3ter=[>]C,#PBE=[>]CC[<]C=C}", + [("CH3ter", 0), ("PBE", 0), ("PEO", 0), ("OHter", 0)], + ), # test case 3 complex sequence with charged ion in the center ("ACOL", "ref.top",