From 4fe5f20e2f149a8cb47be2c2558cebcdb74c6324 Mon Sep 17 00:00:00 2001 From: Lily Wang Date: Fri, 12 Mar 2021 20:07:06 -0800 Subject: [PATCH 1/6] add kwarg --- package/MDAnalysis/topology/TPRParser.py | 17 ++++++++++++-- package/MDAnalysis/topology/tpr/utils.py | 14 ++++++++++- .../topology/test_tprparser.py | 23 +++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/package/MDAnalysis/topology/TPRParser.py b/package/MDAnalysis/topology/TPRParser.py index 786f27c94d6..6531e7c0b99 100644 --- a/package/MDAnalysis/topology/TPRParser.py +++ b/package/MDAnalysis/topology/TPRParser.py @@ -176,12 +176,24 @@ class TPRParser(TopologyReaderBase): """ format = 'TPR' - def parse(self, **kwargs): + def parse(self, tpr_resid_from_one=False, **kwargs): """Parse a Gromacs TPR file into a MDAnalysis internal topology structure. + Parameters + ---------- + tpr_resid_from_one: bool (optional) + Toggle whether to index resids from 1 or 0 from TPR files. + TPR files index resids from 0 by default, even though GRO and ITP + files index from 1. + Returns ------- structure : dict + + + .. versionchanged:: 1.0.2 + Added the ``tpr_resid_from_one`` keyword to control if + resids are indexed from 0 or 1. Default ``False``. """ with openany(self.filename, mode='rb') as infile: tprf = infile.read() @@ -219,7 +231,8 @@ def parse(self, **kwargs): tpr_utils.ndo_real(data, state_ngtc) # relevant to Berendsen tcoupl_lambda if th.bTop: - tpr_top = tpr_utils.do_mtop(data, th.fver) + tpr_top = tpr_utils.do_mtop(data, th.fver, + tpr_resid_from_one=tpr_resid_from_one) else: msg = f"{self.filename}: No topology found in tpr file" logger.critical(msg) diff --git a/package/MDAnalysis/topology/tpr/utils.py b/package/MDAnalysis/topology/tpr/utils.py index 5aab588ea1e..6580efbc889 100644 --- a/package/MDAnalysis/topology/tpr/utils.py +++ b/package/MDAnalysis/topology/tpr/utils.py @@ -46,6 +46,8 @@ The module also contains the :func:`do_inputrec` to read the TPR header with. """ +import warnings + import numpy as np import xdrlib import struct @@ -284,7 +286,7 @@ def extract_box_info(data, fver): return obj.Box(box, box_rel, box_v) -def do_mtop(data, fver): +def do_mtop(data, fver, tpr_resid_from_one=False): # mtop: the topology of the whole system symtab = do_symtab(data) do_symstr(data, symtab) # system_name @@ -371,6 +373,16 @@ def do_mtop(data, fver): molnums = np.array(molnums, dtype=np.int32) segids = np.array(segids, dtype=object) resids = np.array(resids, dtype=np.int32) + if tpr_resid_from_one: + resids += 1 + else: + warnings.warn("TPR files index residues from 0. " + "From MDAnalysis version 2.0, resids will start " + "at 1 instead. If you wish to keep indexing " + "resids from 0, please set " + "`tpr_resid_from_one=False` as a keyword argument " + "when you create a new Topology or Universe.", + category=DeprecationWarning) resnames = np.array(resnames, dtype=object) (residx, new_resids, (new_resnames, diff --git a/testsuite/MDAnalysisTests/topology/test_tprparser.py b/testsuite/MDAnalysisTests/topology/test_tprparser.py index 7826a4d6613..aff8b32181c 100644 --- a/testsuite/MDAnalysisTests/topology/test_tprparser.py +++ b/testsuite/MDAnalysisTests/topology/test_tprparser.py @@ -39,6 +39,7 @@ ) from MDAnalysisTests.topology.base import ParserBase import MDAnalysis.topology.TPRParser +import MDAnalysis as mda BONDED_TPRS = ( TPR510_bonded, @@ -287,3 +288,25 @@ def test_elements(): 'H', '', 'Na', 'Na', 'Na', 'Na', ], dtype=object) assert_equal(topology.elements.values[-20:], reference) + + +@pytest.mark.parametrize("resid_from_one,resid_addition", [ + (False, 0), # status quo for 1.x + (True, 1), + ]) +def test_resids(resid_from_one, resid_addition): + u = mda.Universe(TPR, tpr_resid_from_one=resid_from_one) + resids = np.arange(len(u.residues)) + resid_addition + assert_equal(u.residues.resids, resids, + err_msg="tpr_resid_from_one kwarg not switching resids") + + +@pytest.mark.parametrize("kwargs", [ + {}, + {"tpr_resid_from_one": False}, +]) +def test_resid_false_deprecation_warning(kwargs): + err = ("indexing residues from 0 by default will be removed " + "in MDAnalysis version 2.0") + with pytest.warns(DeprecationWarning, match=err): + u = mda.Universe(TPR, **kwargs) From 3b92869e6b3b30de2775c8c0b4b94d896bdb1275 Mon Sep 17 00:00:00 2001 From: Lily Wang Date: Sat, 13 Mar 2021 10:17:45 -0800 Subject: [PATCH 2/6] change default to True for 2.0 --- package/CHANGELOG | 2 ++ package/MDAnalysis/topology/TPRParser.py | 5 ++++- package/MDAnalysis/topology/tpr/utils.py | 11 ++--------- .../MDAnalysisTests/topology/test_tprparser.py | 15 ++------------- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index 7fa27bb5178..f5dc1427089 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -133,6 +133,8 @@ Enhancements explicit in the topology (Issue #2468, PR #2775) Changes + * TPRParser now loads TPR files with `tpr_resid_from_one=True` + by default (PR #3152) * Introduces encore specific C compiler arguments to allow for lowering of optimisations on non-x86 platforms (Issue #1389, PR #3149) * Continuous integration uses mamba rather than conda to install the diff --git a/package/MDAnalysis/topology/TPRParser.py b/package/MDAnalysis/topology/TPRParser.py index 6531e7c0b99..103bfaae425 100644 --- a/package/MDAnalysis/topology/TPRParser.py +++ b/package/MDAnalysis/topology/TPRParser.py @@ -176,7 +176,7 @@ class TPRParser(TopologyReaderBase): """ format = 'TPR' - def parse(self, tpr_resid_from_one=False, **kwargs): + def parse(self, tpr_resid_from_one=True, **kwargs): """Parse a Gromacs TPR file into a MDAnalysis internal topology structure. Parameters @@ -194,6 +194,9 @@ def parse(self, tpr_resid_from_one=False, **kwargs): .. versionchanged:: 1.0.2 Added the ``tpr_resid_from_one`` keyword to control if resids are indexed from 0 or 1. Default ``False``. + + .. versionchanged:: 2.0.0 + Changed to ``tpr_resid_from_one=True`` by default. """ with openany(self.filename, mode='rb') as infile: tprf = infile.read() diff --git a/package/MDAnalysis/topology/tpr/utils.py b/package/MDAnalysis/topology/tpr/utils.py index 6580efbc889..4bd058e0bd8 100644 --- a/package/MDAnalysis/topology/tpr/utils.py +++ b/package/MDAnalysis/topology/tpr/utils.py @@ -286,7 +286,7 @@ def extract_box_info(data, fver): return obj.Box(box, box_rel, box_v) -def do_mtop(data, fver, tpr_resid_from_one=False): +def do_mtop(data, fver, tpr_resid_from_one=True): # mtop: the topology of the whole system symtab = do_symtab(data) do_symstr(data, symtab) # system_name @@ -375,14 +375,7 @@ def do_mtop(data, fver, tpr_resid_from_one=False): resids = np.array(resids, dtype=np.int32) if tpr_resid_from_one: resids += 1 - else: - warnings.warn("TPR files index residues from 0. " - "From MDAnalysis version 2.0, resids will start " - "at 1 instead. If you wish to keep indexing " - "resids from 0, please set " - "`tpr_resid_from_one=False` as a keyword argument " - "when you create a new Topology or Universe.", - category=DeprecationWarning) + resnames = np.array(resnames, dtype=object) (residx, new_resids, (new_resnames, diff --git a/testsuite/MDAnalysisTests/topology/test_tprparser.py b/testsuite/MDAnalysisTests/topology/test_tprparser.py index aff8b32181c..f6435ccf8a4 100644 --- a/testsuite/MDAnalysisTests/topology/test_tprparser.py +++ b/testsuite/MDAnalysisTests/topology/test_tprparser.py @@ -291,22 +291,11 @@ def test_elements(): @pytest.mark.parametrize("resid_from_one,resid_addition", [ - (False, 0), # status quo for 1.x - (True, 1), + (False, 0), + (True, 1), # status quo for 2.x ]) def test_resids(resid_from_one, resid_addition): u = mda.Universe(TPR, tpr_resid_from_one=resid_from_one) resids = np.arange(len(u.residues)) + resid_addition assert_equal(u.residues.resids, resids, err_msg="tpr_resid_from_one kwarg not switching resids") - - -@pytest.mark.parametrize("kwargs", [ - {}, - {"tpr_resid_from_one": False}, -]) -def test_resid_false_deprecation_warning(kwargs): - err = ("indexing residues from 0 by default will be removed " - "in MDAnalysis version 2.0") - with pytest.warns(DeprecationWarning, match=err): - u = mda.Universe(TPR, **kwargs) From a38a651db20d8d913558ea6833a5e80d788abc97 Mon Sep 17 00:00:00 2001 From: Lily Wang Date: Sat, 13 Mar 2021 15:06:30 -0800 Subject: [PATCH 3/6] fix tests to index resids from 0 again --- testsuite/MDAnalysisTests/analysis/test_density.py | 2 +- testsuite/MDAnalysisTests/core/test_atomselections.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testsuite/MDAnalysisTests/analysis/test_density.py b/testsuite/MDAnalysisTests/analysis/test_density.py index 33e2c7c9e73..937f25f03c4 100644 --- a/testsuite/MDAnalysisTests/analysis/test_density.py +++ b/testsuite/MDAnalysisTests/analysis/test_density.py @@ -148,7 +148,7 @@ class DensityParameters(object): @pytest.fixture() def universe(self): - return mda.Universe(self.topology, self.trajectory) + return mda.Universe(self.topology, self.trajectory, tpr_resid_from_one=False) class TestDensityAnalysis(DensityParameters): def check_DensityAnalysis(self, ag, ref_meandensity, diff --git a/testsuite/MDAnalysisTests/core/test_atomselections.py b/testsuite/MDAnalysisTests/core/test_atomselections.py index 831428da852..6d52ccf0a8f 100644 --- a/testsuite/MDAnalysisTests/core/test_atomselections.py +++ b/testsuite/MDAnalysisTests/core/test_atomselections.py @@ -485,7 +485,7 @@ class TestSelectionsTPR(object): @staticmethod @pytest.fixture(scope='class') def universe(): - return MDAnalysis.Universe(TPR,XTC) + return MDAnalysis.Universe(TPR, XTC, tpr_resid_from_one=False) @pytest.mark.parametrize('selstr', [ 'same fragment as bynum 1', @@ -1299,7 +1299,7 @@ def test_mass_sel_warning(u_fake_masses): @pytest.mark.parametrize("selstr,n_res", [ - ("resnum -10 to 3", 14), + ("resnum -10 to 3", 13), ("resnum -5--3", 3), # select -5 to -3 ("resnum -3 : -5", 0), # wrong way around ]) From b1844ebc16a48c081407cce4cbd5291884bedd8a Mon Sep 17 00:00:00 2001 From: Lily Wang <31115101+lilyminium@users.noreply.github.com> Date: Sat, 13 Mar 2021 17:35:22 -0800 Subject: [PATCH 4/6] Update package/CHANGELOG Co-authored-by: Oliver Beckstein --- package/CHANGELOG | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index f5dc1427089..3d2a64b41ee 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -133,8 +133,8 @@ Enhancements explicit in the topology (Issue #2468, PR #2775) Changes - * TPRParser now loads TPR files with `tpr_resid_from_one=True` - by default (PR #3152) + * TPRParser now loads TPR files with `tpr_resid_from_one=True` by default, + which starts TPR resid indexing from 1 (instead of 0 as in 1.x) (Issue #2364, PR #3152) * Introduces encore specific C compiler arguments to allow for lowering of optimisations on non-x86 platforms (Issue #1389, PR #3149) * Continuous integration uses mamba rather than conda to install the From a77e445fc6a978eae0646685ef0525adcc0bad42 Mon Sep 17 00:00:00 2001 From: Lily Wang Date: Sat, 13 Mar 2021 17:36:28 -0800 Subject: [PATCH 5/6] change default arg for TPR utilities and remove warnings --- package/MDAnalysis/topology/tpr/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package/MDAnalysis/topology/tpr/utils.py b/package/MDAnalysis/topology/tpr/utils.py index 4bd058e0bd8..b764e7ec59e 100644 --- a/package/MDAnalysis/topology/tpr/utils.py +++ b/package/MDAnalysis/topology/tpr/utils.py @@ -46,7 +46,6 @@ The module also contains the :func:`do_inputrec` to read the TPR header with. """ -import warnings import numpy as np import xdrlib @@ -286,7 +285,7 @@ def extract_box_info(data, fver): return obj.Box(box, box_rel, box_v) -def do_mtop(data, fver, tpr_resid_from_one=True): +def do_mtop(data, fver, tpr_resid_from_one=False): # mtop: the topology of the whole system symtab = do_symtab(data) do_symstr(data, symtab) # system_name From 76f6cdf93766db1b341e797f021f1c791ca7e2c3 Mon Sep 17 00:00:00 2001 From: Lily Wang Date: Sun, 14 Mar 2021 09:59:38 -0700 Subject: [PATCH 6/6] updated to 1.1.0 --- package/MDAnalysis/topology/TPRParser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/topology/TPRParser.py b/package/MDAnalysis/topology/TPRParser.py index 103bfaae425..6ff6f185847 100644 --- a/package/MDAnalysis/topology/TPRParser.py +++ b/package/MDAnalysis/topology/TPRParser.py @@ -191,7 +191,7 @@ def parse(self, tpr_resid_from_one=True, **kwargs): structure : dict - .. versionchanged:: 1.0.2 + .. versionchanged:: 1.1.0 Added the ``tpr_resid_from_one`` keyword to control if resids are indexed from 0 or 1. Default ``False``.