Skip to content

Commit c83d030

Browse files
ENH: tpx 137 (GROMACS 2025.0) support (#4919)
* ENH: tpx 137 support * Add support for GROMACS `2025.0` `.tpr` version 137, which mostly involves accounting for the new PyTorch neural network potential field, `F_ENNPOT`. Most of the other changes are similar to the approach I previously used for bumping `.tpr` version support in gh-4866. * Some other `.tpr` additions are noted at #4888, but we don't appear to need to use those within the context of our current `.tpr` parsing tests. It may be sensible to occasionally generate `.tpr` test files that use those extra bells and whistles to see how we fare, though as a first pass here the full testsuite passes for us if we simply do the usual `gmx convert-tpr` at the latest stable GROMACS release tag `v2025.0` and propagate our current TPR testing to additionally use the converted files. * TST: Add GROMACS 2025.0 TPR with NNpot * Generated input file with random set of features enabled Using inputs from gromacs/src/testutils/simulationdatabase/ `gmx grompp -f tt6710474.mdp -c ala.gro -n ala.ndx -p ala.top -o ala_nnpot_gmx_2025_0.tpr` * Add Andrey to `CHANGELOG` * Apply suggestions from code review --------- Co-authored-by: Andrey Alekseenko <al42and@gmail.com>
1 parent 0eb54dd commit c83d030

File tree

10 files changed

+54
-7
lines changed

10 files changed

+54
-7
lines changed

package/CHANGELOG

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ The rules for this file:
1515

1616
-------------------------------------------------------------------------------
1717
??/??/?? IAlibay, ChiahsinChu, RMeli, tanishy7777, talagayev, tylerjereddy,
18-
marinegor, hmacdope, jauy123
18+
marinegor, hmacdope, jauy123, al42and
1919

2020
* 2.9.0
2121

2222
Fixes
23-
* Add support for TPR files produced by GROMACS 2024.4
23+
* Add support for TPR files produced by GROMACS 2024.4 and GROMACS 2025.0
2424
* Fixes invalid default unit from Angstrom to Angstrom^{-3} for convert_density() function. (Issue #4829)
2525
* Fixes deprecation warning Array to scalar convertion. Replaced atan2() with np.arctan2() (Issue #4339)
2626
* Replaced mutable defaults with None and initialized them within

package/MDAnalysis/topology/TPRParser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
129 28 2023 yes
6969
133 28 2024.1 yes
7070
134 28 2024.4 yes
71+
137 28 2025.0 yes
7172
========== ============== ==================== =====
7273
7374
.. [*] Files generated by the beta versions of Gromacs 2020 are NOT supported.

package/MDAnalysis/topology/tpr/setting.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
129,
5454
133,
5555
134,
56+
137,
5657
)
5758

5859
# Some constants
@@ -94,12 +95,12 @@
9495
F_DIHRESVIOL, F_CONSTR, F_CONSTRNC, F_SETTLE, F_VSITE1,
9596
F_VSITE2, F_VSITE2FD, F_VSITE3, F_VSITE3FD, F_VSITE3FAD,
9697
F_VSITE3OUT, F_VSITE4FD, F_VSITE4FDN, F_VSITEN,
97-
F_COM_PULL, F_DENSITYFITTING, F_EQM, F_EPOT, F_EKIN,
98+
F_COM_PULL, F_DENSITYFITTING, F_EQM, F_ENNPOT, F_EPOT, F_EKIN,
9899
F_ETOT, F_ECONSERVED, F_TEMP, F_VTEMP_NOLONGERUSED,
99100
F_PDISPCORR, F_PRES, F_DHDL_CON, F_DVDL,
100101
F_DKDL, F_DVDL_COUL, F_DVDL_VDW, F_DVDL_BONDED,
101102
F_DVDL_RESTRAINT, F_DVDL_TEMPERATURE, F_NRE
102-
) = list(range(95))
103+
) = list(range(96))
103104
# fmt: on
104105

105106
#: Function types from ``<gromacs_dir>/src/gmxlib/tpxio.c``
@@ -127,6 +128,7 @@
127128
(tpxv_GenericInternalParameters, F_DENSITYFITTING),
128129
(tpxv_VSite1, F_VSITE1),
129130
(tpxv_VSite2FD, F_VSITE2FD),
131+
(137, F_ENNPOT),
130132
]
131133
# fmt: on
132134

package/MDAnalysis/topology/tpr/utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,10 @@ def do_iparams(data, functypes, fver):
702702
elif i in [setting.F_CMAP]:
703703
data.unpack_int() # cmap.cmapA
704704
data.unpack_int() # cmap.cmapB
705+
elif i in [setting.F_ENNPOT]:
706+
# TODO: handle the new neural network potentials
707+
# supported from GROMACS 2025.0
708+
pass
705709
else:
706710
raise NotImplementedError(f"unknown functype: {i}")
707711
return
503 KB
Binary file not shown.
10.7 KB
Binary file not shown.
5.07 KB
Binary file not shown.
Binary file not shown.

testsuite/MDAnalysisTests/datafiles.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
"TPR2023",
134134
"TPR2024",
135135
"TPR2024_4",
136+
"TPR2025_0",
136137
"TPR510_bonded",
137138
"TPR2016_bonded",
138139
"TPR2018_bonded",
@@ -147,6 +148,7 @@
147148
"TPR2023_bonded",
148149
"TPR2024_bonded",
149150
"TPR2024_4_bonded",
151+
"TPR2025_0_bonded",
150152
"TPR_EXTRA_2021",
151153
"TPR_EXTRA_2020",
152154
"TPR_EXTRA_2018",
@@ -156,6 +158,8 @@
156158
"TPR_EXTRA_2023",
157159
"TPR_EXTRA_2024",
158160
"TPR_EXTRA_2024_4",
161+
"TPR_EXTRA_2025_0",
162+
"TPR_NNPOT_2025_0",
159163
"PDB_sub_sol",
160164
"PDB_sub_dry", # TRRReader sub selection
161165
"TRR_sub_sol",
@@ -553,6 +557,7 @@
553557
TPR2023 = (_data_ref / "tprs/2lyz_gmx_2023.tpr").as_posix()
554558
TPR2024 = (_data_ref / "tprs/2lyz_gmx_2024.tpr").as_posix()
555559
TPR2024_4 = (_data_ref / "tprs/2lyz_gmx_2024_4.tpr").as_posix()
560+
TPR2025_0 = (_data_ref / "tprs/2lyz_gmx_2025_0.tpr").as_posix()
556561
# double precision
557562
TPR455Double = (_data_ref / "tprs/drew_gmx_4.5.5.double.tpr").as_posix()
558563
TPR460 = (_data_ref / "tprs/ab42_gmx_4.6.tpr").as_posix()
@@ -584,7 +589,11 @@
584589
TPR2023_bonded = (_data_ref / "tprs/all_bonded/dummy_2023.tpr").as_posix()
585590
TPR2024_bonded = (_data_ref / "tprs/all_bonded/dummy_2024.tpr").as_posix()
586591
TPR2024_4_bonded = (_data_ref / "tprs/all_bonded/dummy_2024_4.tpr").as_posix()
592+
TPR2025_0_bonded = (_data_ref / "tprs/all_bonded/dummy_2025_0.tpr").as_posix()
587593
# all interactions
594+
TPR_EXTRA_2025_0 = (
595+
_data_ref / "tprs/virtual_sites/extra-interactions-2025_0.tpr"
596+
).as_posix()
588597
TPR_EXTRA_2024_4 = (
589598
_data_ref / "tprs/virtual_sites/extra-interactions-2024_4.tpr"
590599
).as_posix()
@@ -612,6 +621,8 @@
612621
TPR_EXTRA_407 = (
613622
_data_ref / "tprs/virtual_sites/extra-interactions-4.0.7.tpr"
614623
).as_posix()
624+
# ALA dipeptide with neural network potential and a few other options
625+
TPR_NNPOT_2025_0 = (_data_ref / "tprs/ala_nnpot_gmx_2025_0.tpr").as_posix()
615626

616627
XYZ_psf = (_data_ref / "2r9r-1b.psf").as_posix()
617628
XYZ_bz2 = (_data_ref / "2r9r-1b.xyz.bz2").as_posix()

testsuite/MDAnalysisTests/topology/test_tprparser.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@
3434
TPR2016, TPR2018, TPR2019B3, TPR2020,
3535
TPR2020B2, TPR2021, TPR2022RC1,
3636
TPR2023, TPR2024, TPR2024_4,
37+
TPR2025_0,
3738
TPR_EXTRA_407, TPR_EXTRA_2016,
3839
TPR_EXTRA_2018, TPR_EXTRA_2020,
3940
TPR_EXTRA_2021, TPR_EXTRA_2022RC1,
4041
TPR_EXTRA_2023, TPR_EXTRA_2024,
4142
TPR_EXTRA_2024_4, XTC, TPR334_bonded,
43+
TPR_EXTRA_2025_0,
4244
TPR455Double, TPR510_bonded,
4345
TPR2016_bonded, TPR2018_bonded,
4446
TPR2019B3_bonded, TPR2020_bonded,
@@ -47,7 +49,8 @@
4749
TPR2021_bonded, TPR2021_double_bonded,
4850
TPR2021Double, TPR2022RC1_bonded,
4951
TPR2023_bonded, TPR2024_4_bonded,
50-
TPR2024_bonded)
52+
TPR2025_0_bonded, TPR2024_bonded,
53+
TPR_NNPOT_2025_0)
5154
from numpy.testing import assert_equal
5255

5356
# fmt: on
@@ -66,6 +69,8 @@
6669
TPR2023_bonded,
6770
TPR2024_bonded,
6871
TPR2024_4_bonded,
72+
TPR2025_0_bonded,
73+
TPR_EXTRA_2025_0,
6974
TPR_EXTRA_2024_4,
7075
TPR_EXTRA_2024,
7176
TPR_EXTRA_2023,
@@ -148,7 +153,8 @@ class TestTPRGromacsVersions(TPRAttrs):
148153
TPR400, TPR402, TPR403, TPR404, TPR405, TPR406, TPR407, TPR450,
149154
TPR451, TPR452, TPR453, TPR454, TPR455, TPR502, TPR504, TPR505,
150155
TPR510, TPR2016, TPR2018, TPR2019B3, TPR2020, TPR2020Double,
151-
TPR2021, TPR2021Double, TPR2022RC1, TPR2023, TPR2024, TPR2024_4
156+
TPR2021, TPR2021Double, TPR2022RC1, TPR2023, TPR2024, TPR2024_4,
157+
TPR2025_0,
152158
]
153159
)
154160
# fmt: on
@@ -206,6 +212,19 @@ def filename(self, request):
206212
return request.param
207213

208214

215+
class TestTPRNnpot(TPRAttrs):
216+
expected_n_atoms = 23
217+
expected_n_residues = 2
218+
expected_n_segments = 1
219+
ref_moltypes = np.array(["Protein_chain_A"] * 2, dtype=object)
220+
ref_molnums = np.array([0] * 2)
221+
ref_chainIDs = ["A"]
222+
223+
@pytest.fixture(params=[TPR_NNPOT_2025_0])
224+
def filename(self, request):
225+
return request.param
226+
227+
209228
def _test_is_in_topology(name, elements, topology_path, topology_section):
210229
"""
211230
Test if an interaction appears as expected in the topology
@@ -315,7 +334,7 @@ def test_all_impropers(topology, impr):
315334
@pytest.fixture(params=(
316335
TPR400, TPR402, TPR403, TPR404, TPR405, TPR406, TPR407, TPR450,
317336
TPR451, TPR452, TPR453, TPR454, TPR502, TPR504, TPR505, TPR510,
318-
TPR2016, TPR2018, TPR2023, TPR2024, TPR2024_4,
337+
TPR2016, TPR2018, TPR2023, TPR2024, TPR2024_4, TPR2025_0,
319338
)
320339
)
321340
# fmt: on
@@ -338,6 +357,16 @@ def test_settle(bonds_water):
338357
assert bonds_water[-1][1] == 2262
339358

340359

360+
@pytest.mark.parametrize("tpr_path", [TPR_NNPOT_2025_0])
361+
def test_ala2(tpr_path):
362+
topology = MDAnalysis.topology.TPRParser.TPRParser(tpr_path).parse()
363+
# Check that bonds etc are read correctly
364+
assert len(topology.bonds.values) == 22 # 12 Bond + 10 Connect
365+
assert len(topology.angles.values) == 21 # 21 Angle
366+
assert len(topology.dihedrals.values) == 26 # 26 Proper Dih.
367+
assert len(topology.impropers.values) == 1 # 1 Per. Imp. Dih.
368+
369+
341370
@pytest.mark.parametrize(
342371
"tpr_path, expected_exception",
343372
(

0 commit comments

Comments
 (0)