From 579074037c276d76bdf0d44d07e9f3dd206a5cd5 Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 24 Mar 2021 17:56:35 +0900 Subject: [PATCH 01/45] add attribute 'sort' to atomgroup --- package/MDAnalysis/core/groups.py | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 0671bcef3ad..1ab23d28672 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3324,6 +3324,55 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) + def sort(self, **keys): + """Return sorted Atomgroup. + + Example + ------- + + .. code-block:: python + + >>> import MDAnalysis as mda + >>> from MDAnalysisTests.datafiles import PDB_small + >>> ag = sum([u.atoms[3], u.atoms[2], u.atoms[1], u.atoms[0]]) + >>> ag.ids + [4 3 2 1] + >>> ag.ix + [3 2 1 0] + >>> ag = ag.sort(key=lambda atom: atom.id) + >>> ag.ids + [1 2 3 4] + >>> ag.ix + [0 1 2 3] + + Parameters + ---------- + keys: callable object + A function for the parameter of each atom to use for sorting. + Example: lambda atom: atom.id + + Returns + ------- + output: + Sorted atomgroup. + + + .. versionadded:: 2.0.0 + """ + if len(keys) == 0: + raise NameError("argument 'key' is not defined. ") + for key, value in keys.items(): + if key == "key": + n = len(self.atoms) + idx = np.zeros(n) + for i in range(n): + idx[i] = value(self.atoms[i]) + order = np.argsort(idx) + agsorted = self.atoms[order] + return agsorted + else: + raise ValueError("Incorrect parameter: {}") + class ResidueGroup(GroupBase): """ResidueGroup base class. From c9326a3591be33da56ad91fbc49f73820e6eefba Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 24 Mar 2021 17:59:16 +0900 Subject: [PATCH 02/45] Edit CHANGELOG --- package/AUTHORS | 1 + package/CHANGELOG | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package/AUTHORS b/package/AUTHORS index 00076883aa4..e85f8d33993 100644 --- a/package/AUTHORS +++ b/package/AUTHORS @@ -158,6 +158,7 @@ Chronological list of authors - Henrik Jäger - Jan Stevens - Orion Cohen + - Kosuke Kudo External code ------------- diff --git a/package/CHANGELOG b/package/CHANGELOG index 0de5b4a35a4..fdf5bfca12c 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -17,7 +17,7 @@ The rules for this file: lilyminium, daveminh, jbarnoud, yuxuanzhuang, VOD555, ianmkenney, calcraven,xiki-tempula, mieczyslaw, manuel.nuno.melo, PicoCentauri, hanatok, rmeli, aditya-kamath, tirkarthi, LeonardoBarneschi, hejamu, - biogen98, orioncohen + biogen98, orioncohen, 1ut * 2.0.0 @@ -89,6 +89,7 @@ Fixes * Fix syntax warning over comparison of literals using is (Issue #3066) Enhancements + * Added sort method to the atomgroup (Issue #2976) * Added a ValueError raised when not given a gridcenter while providing grid dimensions to DensityAnalysis, also added check for NaN in the input (Issue #3148, PR #3154) From 99d6d701edf5684d2277ac8971c5cccc8c404a11 Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 24 Mar 2021 18:29:36 +0900 Subject: [PATCH 03/45] delete white space according to PEP8 --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 1ab23d28672..ac04eb33b3b 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3348,7 +3348,7 @@ def sort(self, **keys): Parameters ---------- keys: callable object - A function for the parameter of each atom to use for sorting. + A function for the parameter of each atom to use for sorting. Example: lambda atom: atom.id Returns From 315080c87b56fe4c12d372a62bd47f5f87ddd60f Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 25 Mar 2021 12:45:02 +0900 Subject: [PATCH 04/45] Edit docs --- package/MDAnalysis/core/groups.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index ac04eb33b3b..771713c7e25 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3334,16 +3334,17 @@ def sort(self, **keys): >>> import MDAnalysis as mda >>> from MDAnalysisTests.datafiles import PDB_small + >>> u = mda.Universe(PDB_small) >>> ag = sum([u.atoms[3], u.atoms[2], u.atoms[1], u.atoms[0]]) >>> ag.ids - [4 3 2 1] + array([4 3 2 1]) >>> ag.ix - [3 2 1 0] + array([3 2 1 0]) >>> ag = ag.sort(key=lambda atom: atom.id) >>> ag.ids - [1 2 3 4] + array([1 2 3 4]) >>> ag.ix - [0 1 2 3] + array([0 1 2 3]) Parameters ---------- From 6ff70a0f94284317660605ffeeb538a876c9d8b3 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 25 Mar 2021 12:45:33 +0900 Subject: [PATCH 05/45] add a test for atomgroup.sort --- .../MDAnalysisTests/core/test_atomgroup.py | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index 1a3d401f0ee..b5ade8d413a 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -47,7 +47,8 @@ TRZ_psf, TRZ, two_water_gro, TPR_xvf, TRR_xvf, - GRO + GRO, + PDB_helix ) from MDAnalysisTests import make_Universe, no_deprecated_call from MDAnalysisTests.core.util import UnWrapUniverse @@ -1674,3 +1675,25 @@ def test_partial_timestep(self, universe): ag.ts.velocities, self.prec, err_msg="Partial timestep coordinates wrong") + + +class TestAtomGroupSort(object): + """Tests the AtomGroup.sort attribute""" + + @pytest.fixture() + def u(self): + return mda.Universe(PDB_helix) + + @pytest.fixture() + def ag(self, u): + return sum([u.atoms[3], u.atoms[2], u.atoms[1], u.atoms[0]]) + + @pytest.fixture() + def agsort(self, ag): + return ag.sort(key=lambda atom: atom.id) + + def test_sort(self, agsort): + refid = np.array([1, 2, 3, 4]) + refix = np.array([0, 1, 2, 3]) + assert np.array_equal(refid, agsort.ids) + assert np.array_equal(refix, agsort.ix) \ No newline at end of file From dfe7027b375d18c19e37beb766b4b7dbd1f759d0 Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 29 Mar 2021 10:56:53 +0900 Subject: [PATCH 06/45] add changes to atomgroup.sort --- package/MDAnalysis/core/groups.py | 47 ++++++++++++------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 771713c7e25..bd2cfa2ea4d 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3324,8 +3324,18 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) - def sort(self, **keys): - """Return sorted Atomgroup. + def sort(self, key='ix'): + """Return sorted Atomgroup by a key that specifies an attribute of atomgroup. The default key is "ix". + + Parameters + ---------- + keys: + The name for attribute of Atomgroup. (e.g. "ids", "ix") + + Returns + ------- + output: + Sorted atomgroup. Example ------- @@ -3335,44 +3345,23 @@ def sort(self, **keys): >>> import MDAnalysis as mda >>> from MDAnalysisTests.datafiles import PDB_small >>> u = mda.Universe(PDB_small) - >>> ag = sum([u.atoms[3], u.atoms[2], u.atoms[1], u.atoms[0]]) + >>> ag = u.atoms[[3, 2, 1, 0]] >>> ag.ids array([4 3 2 1]) >>> ag.ix array([3 2 1 0]) - >>> ag = ag.sort(key=lambda atom: atom.id) + >>> ag = ag.sort() >>> ag.ids array([1 2 3 4]) >>> ag.ix array([0 1 2 3]) - Parameters - ---------- - keys: callable object - A function for the parameter of each atom to use for sorting. - Example: lambda atom: atom.id - - Returns - ------- - output: - Sorted atomgroup. - - .. versionadded:: 2.0.0 """ - if len(keys) == 0: - raise NameError("argument 'key' is not defined. ") - for key, value in keys.items(): - if key == "key": - n = len(self.atoms) - idx = np.zeros(n) - for i in range(n): - idx[i] = value(self.atoms[i]) - order = np.argsort(idx) - agsorted = self.atoms[order] - return agsorted - else: - raise ValueError("Incorrect parameter: {}") + idx = getattr(self.atoms, key) + order = np.argsort(idx) + agsorted = self.atoms[order] + return agsorted class ResidueGroup(GroupBase): From c86db7a3d59b89a5c7ef979ce0fbbfa0d182eb14 Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 29 Mar 2021 10:57:19 +0900 Subject: [PATCH 07/45] add changes to test case for atomgroup.sort --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index b5ade8d413a..f6b97933a7a 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1686,11 +1686,11 @@ def u(self): @pytest.fixture() def ag(self, u): - return sum([u.atoms[3], u.atoms[2], u.atoms[1], u.atoms[0]]) + return u.atoms[[3, 2, 1, 0]] @pytest.fixture() def agsort(self, ag): - return ag.sort(key=lambda atom: atom.id) + return ag.sort("ids") def test_sort(self, agsort): refid = np.array([1, 2, 3, 4]) From 6db489e8477273dec0df8e47703dd07b1ddf2cb5 Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 29 Mar 2021 12:12:28 +0900 Subject: [PATCH 08/45] edit CHANGELOG --- package/CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/CHANGELOG b/package/CHANGELOG index fdf5bfca12c..7b109359889 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -141,8 +141,12 @@ Enhancements 'protein' selection (#2751 PR #2755) * Added an RDKit converter that works for any input with all hydrogens explicit in the topology (Issue #2468, PR #2775) +<<<<<<< HEAD +======= + +>>>>>>> edit CHANGELOG Changes * 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) From 8b465574264e76d7cda24e516eec3157b7820652 Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 29 Mar 2021 21:25:03 +0900 Subject: [PATCH 09/45] made np.argsort stable --- package/MDAnalysis/core/groups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index bd2cfa2ea4d..109aa92c9b8 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3325,7 +3325,7 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) def sort(self, key='ix'): - """Return sorted Atomgroup by a key that specifies an attribute of atomgroup. The default key is "ix". + """Return stably sorted Atomgroup by a key that specifies an attribute of atomgroup. The default key is "ix". Parameters ---------- @@ -3359,7 +3359,7 @@ def sort(self, key='ix'): .. versionadded:: 2.0.0 """ idx = getattr(self.atoms, key) - order = np.argsort(idx) + order = np.argsort(idx, kind='stable') agsorted = self.atoms[order] return agsorted From b3f045513bd36a80417649ec0be3e8acfd7f3347 Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 29 Mar 2021 21:53:19 +0900 Subject: [PATCH 10/45] Add tests for TestAtomGroupSort --- .../MDAnalysisTests/core/test_atomgroup.py | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index f6b97933a7a..efe136de390 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -47,8 +47,7 @@ TRZ_psf, TRZ, two_water_gro, TPR_xvf, TRR_xvf, - GRO, - PDB_helix + GRO ) from MDAnalysisTests import make_Universe, no_deprecated_call from MDAnalysisTests.core.util import UnWrapUniverse @@ -1681,19 +1680,52 @@ class TestAtomGroupSort(object): """Tests the AtomGroup.sort attribute""" @pytest.fixture() - def u(self): - return mda.Universe(PDB_helix) + def universe(self): + u = mda.Universe.empty( + n_atoms=7, + n_residues=3, + n_segments=2, + atom_resindex=np.array([0, 0, 0, 1, 1, 1, 2]), + residue_segindex=np.array([0, 0, 1]), + trajectory=True, + velocities=True, + forces=True + ) + attributes = ["id", "charge", "mass", "tempfactor"] + + for i in (attributes): + u.add_TopologyAttr(i, [6, 5, 4, 3, 2, 1, 0]) + + u.add_TopologyAttr('resid', [2, 1, 0]) + u.add_TopologyAttr('segid', [1, 0]) + + return u @pytest.fixture() - def ag(self, u): - return u.atoms[[3, 2, 1, 0]] + def ag(self, universe): + return universe.atoms - @pytest.fixture() - def agsort(self, ag): - return ag.sort("ids") - - def test_sort(self, agsort): - refid = np.array([1, 2, 3, 4]) - refix = np.array([0, 1, 2, 3]) - assert np.array_equal(refid, agsort.ids) - assert np.array_equal(refix, agsort.ix) \ No newline at end of file + test_ids = [ + "ix", + "ids", + "resids", + "segids", + "charges", + "masses", + "tempfactors" + ] + + test_data = [ + ("ix", np.array([0, 1, 2, 3, 4, 5, 6])), + ("ids", np.array([6, 5, 4, 3, 2, 1, 0])), + ("resids", np.array([6, 3, 4, 5, 0, 1, 2])), + ("segids", np.array([6, 0, 1, 2, 3, 4, 5])), + ("charges", np.array([6, 5, 4, 3, 2, 1, 0])), + ("masses", np.array([6, 5, 4, 3, 2, 1, 0])), + ("tempfactors", np.array([6, 5, 4, 3, 2, 1, 0])), + ] + + @pytest.mark.parametrize("inputs, expected", test_data, ids=test_ids) + def test_sort(self, ag, inputs, expected): + agsort = ag.sort(inputs) + assert np.array_equal(expected, agsort.ix) \ No newline at end of file From 267a1b46f8643085eb248be8a689921782493a7d Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 29 Mar 2021 22:01:44 +0900 Subject: [PATCH 11/45] add my name to author list of changelog --- package/CHANGELOG | 5 ----- 1 file changed, 5 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index 7b109359889..d8b0b495b97 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -141,12 +141,7 @@ Enhancements 'protein' selection (#2751 PR #2755) * Added an RDKit converter that works for any input with all hydrogens explicit in the topology (Issue #2468, PR #2775) -<<<<<<< HEAD - - -======= ->>>>>>> edit CHANGELOG Changes * 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) From c6d048f8728b759516de2aeba561a66c043e8492 Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 31 Mar 2021 15:36:58 +0900 Subject: [PATCH 12/45] Treat with multiple dimensional array --- package/MDAnalysis/core/groups.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 109aa92c9b8..97e9eebcefb 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3324,13 +3324,17 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) - def sort(self, key='ix'): - """Return stably sorted Atomgroup by a key that specifies an attribute of atomgroup. The default key is "ix". + def sort(self, key='ix', keyfunc=None): + """Return stably sorted Atomgroup by a key that specifies + an attribute of atomgroup. The default key is "ix". Parameters ---------- - keys: + keys: str The name for attribute of Atomgroup. (e.g. "ids", "ix") + keyfunc: function + A function that returns 1 dimension array, a key for sorting the + atomgroup from multiple dimension array that the attribute returns. Returns ------- @@ -3359,7 +3363,22 @@ def sort(self, key='ix'): .. versionadded:: 2.0.0 """ idx = getattr(self.atoms, key) - order = np.argsort(idx, kind='stable') + if idx.ndim == 0: + return self.atoms + elif idx.ndim == 1: + order = np.argsort(idx, kind='stable') + else: + if keyfunc is None: + raise NameError("You have to assign the argument 'keyfunc' " + "a proper function that returns 1D array " + "as the attribute '{}' returns multiple " + "dimension array.".format(key)) + sortkeys = keyfunc(idx) + if sortkeys.ndim != 1: + raise ValueError("The function you assigned to the argument " + "'keyfunc':{} doesn't return 1D array." + .format(keyfunc)) + order = np.argsort(sortkeys, kind='stable') agsorted = self.atoms[order] return agsorted From 044a30255398e09b0431cdf92d114d78678a8fc6 Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 31 Mar 2021 15:37:08 +0900 Subject: [PATCH 13/45] Add testsa for multiple dimensional array --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index efe136de390..c79e96e204c 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1728,4 +1728,14 @@ def ag(self, universe): @pytest.mark.parametrize("inputs, expected", test_data, ids=test_ids) def test_sort(self, ag, inputs, expected): agsort = ag.sort(inputs) - assert np.array_equal(expected, agsort.ix) \ No newline at end of file + assert np.array_equal(expected, agsort.ix) + + def test_sort_position(self, ag): + ag.positions = (-np.arange(21)).reshape(7, 3) + with pytest.raises(ValueError): + ag.sort("positions", keyfunc=lambda x: x) + with pytest.raises(NameError): + ag.sort("positions") + ref = [6, 5, 4, 3, 2, 1, 0] + agsort = ag.sort("positions", keyfunc=lambda x: x[:, 1]) + assert np.array_equal(ref, agsort.ix) \ No newline at end of file From a8b10b04698e1100c4cea170f4f7a534c6072359 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 1 Apr 2021 18:27:18 +0900 Subject: [PATCH 14/45] Check if number of atoms and idx have a same size. --- package/MDAnalysis/core/groups.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 97e9eebcefb..fee04205c10 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3363,6 +3363,10 @@ def sort(self, key='ix', keyfunc=None): .. versionadded:: 2.0.0 """ idx = getattr(self.atoms, key) + if len(idx) != len(self.atoms): + raise ValueError("The array returned by the attribute '{}' " + "must have a same length as the number of " + "atoms".format(key)) if idx.ndim == 0: return self.atoms elif idx.ndim == 1: From b6b9ab48263bd29aa44eda52c7fb720b98e082ae Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 1 Apr 2021 18:29:50 +0900 Subject: [PATCH 15/45] Add tests for non-number of atoms sized attributes --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index c79e96e204c..ec402ad3864 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1732,6 +1732,8 @@ def test_sort(self, ag, inputs, expected): def test_sort_position(self, ag): ag.positions = (-np.arange(21)).reshape(7, 3) + with pytest.raises(ValueError): + ag.sort("angles") with pytest.raises(ValueError): ag.sort("positions", keyfunc=lambda x: x) with pytest.raises(NameError): From 2a64457dc49cb41f9c1ae1e1131c2328f888a860 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 1 Apr 2021 18:31:11 +0900 Subject: [PATCH 16/45] Stop checking if idx is 0 dimension array --- package/MDAnalysis/core/groups.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index fee04205c10..61dbecc2263 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3367,11 +3367,9 @@ def sort(self, key='ix', keyfunc=None): raise ValueError("The array returned by the attribute '{}' " "must have a same length as the number of " "atoms".format(key)) - if idx.ndim == 0: - return self.atoms - elif idx.ndim == 1: + if idx.ndim == 1: order = np.argsort(idx, kind='stable') - else: + elif idx.ndim > 1: if keyfunc is None: raise NameError("You have to assign the argument 'keyfunc' " "a proper function that returns 1D array " From c2e615a3938e90e8c1167ed1343e130f63a5bd08 Mon Sep 17 00:00:00 2001 From: 1ut Date: Fri, 2 Apr 2021 12:50:54 +0900 Subject: [PATCH 17/45] add pr number to CHANGELOG --- package/CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index d8b0b495b97..023047d9a08 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -89,7 +89,7 @@ Fixes * Fix syntax warning over comparison of literals using is (Issue #3066) Enhancements - * Added sort method to the atomgroup (Issue #2976) + * Added sort method to the atomgroup (Issue #2976, PR #3188) * Added a ValueError raised when not given a gridcenter while providing grid dimensions to DensityAnalysis, also added check for NaN in the input (Issue #3148, PR #3154) From 06056e83a31489c5f4d4784583491e1c7fb77673 Mon Sep 17 00:00:00 2001 From: 1ut Date: Sun, 4 Apr 2021 19:06:44 +0900 Subject: [PATCH 18/45] Simplify an example in the docs --- package/MDAnalysis/core/groups.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 61dbecc2263..eacdf42a202 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3350,13 +3350,9 @@ def sort(self, key='ix', keyfunc=None): >>> from MDAnalysisTests.datafiles import PDB_small >>> u = mda.Universe(PDB_small) >>> ag = u.atoms[[3, 2, 1, 0]] - >>> ag.ids - array([4 3 2 1]) >>> ag.ix array([3 2 1 0]) >>> ag = ag.sort() - >>> ag.ids - array([1 2 3 4]) >>> ag.ix array([0 1 2 3]) From 6cf90028ada1b17c209c28318e54a02a514a8b58 Mon Sep 17 00:00:00 2001 From: 1ut Date: Sun, 4 Apr 2021 19:43:29 +0900 Subject: [PATCH 19/45] Add description of kind in argsort --- package/MDAnalysis/core/groups.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index eacdf42a202..55d677040d3 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3356,6 +3356,10 @@ def sort(self, key='ix', keyfunc=None): >>> ag.ix array([0 1 2 3]) + Note + ---- + This sort is stable as it is implemented by `numpy.argsort(kind='stable')`. + .. versionadded:: 2.0.0 """ idx = getattr(self.atoms, key) From fa89e4bc499027d20d01d18923214ca0fdbd45f2 Mon Sep 17 00:00:00 2001 From: 1ut Date: Sun, 4 Apr 2021 19:45:17 +0900 Subject: [PATCH 20/45] removed unnecessary variable --- package/MDAnalysis/core/groups.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 55d677040d3..30206b3e39e 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3381,8 +3381,7 @@ def sort(self, key='ix', keyfunc=None): "'keyfunc':{} doesn't return 1D array." .format(keyfunc)) order = np.argsort(sortkeys, kind='stable') - agsorted = self.atoms[order] - return agsorted + return self.atoms[order] class ResidueGroup(GroupBase): From 5dceb3e069e85402ac115fb310e9f2886bbb0068 Mon Sep 17 00:00:00 2001 From: 1ut Date: Sun, 4 Apr 2021 19:45:59 +0900 Subject: [PATCH 21/45] pep8 --- package/MDAnalysis/core/groups.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 30206b3e39e..7b6f43c0a92 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3358,7 +3358,8 @@ def sort(self, key='ix', keyfunc=None): Note ---- - This sort is stable as it is implemented by `numpy.argsort(kind='stable')`. + This sort is stable as it is implemented by + `numpy.argsort(kind='stable')`. .. versionadded:: 2.0.0 """ From 88a5953e9bc761c1b24af84979127847a69c1465 Mon Sep 17 00:00:00 2001 From: 1ut Date: Sun, 4 Apr 2021 22:43:10 +0900 Subject: [PATCH 22/45] Add match arguments to pytest --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index ec402ad3864..0b8951f8ce6 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1732,11 +1732,14 @@ def test_sort(self, ag, inputs, expected): def test_sort_position(self, ag): ag.positions = (-np.arange(21)).reshape(7, 3) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"The array returned by the" + "attribute.*"): ag.sort("angles") - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"The function you assigned" + ".*"): ag.sort("positions", keyfunc=lambda x: x) - with pytest.raises(NameError): + with pytest.raises(NameError, match=r"You have to assign the argument" + ".*"): ag.sort("positions") ref = [6, 5, 4, 3, 2, 1, 0] agsort = ag.sort("positions", keyfunc=lambda x: x[:, 1]) From a72c726287a79ad9a6cdd90f8e42748080e41c99 Mon Sep 17 00:00:00 2001 From: 1ut Date: Mon, 5 Apr 2021 09:21:09 +0900 Subject: [PATCH 23/45] fix tests that not worked --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index 0b8951f8ce6..612aacc7530 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1698,6 +1698,7 @@ def universe(self): u.add_TopologyAttr('resid', [2, 1, 0]) u.add_TopologyAttr('segid', [1, 0]) + u.add_TopologyAttr('bonds', [(0,1)]) return u @@ -1732,9 +1733,9 @@ def test_sort(self, ag, inputs, expected): def test_sort_position(self, ag): ag.positions = (-np.arange(21)).reshape(7, 3) - with pytest.raises(ValueError, match=r"The array returned by the" + with pytest.raises(ValueError, match=r"The array returned by the " "attribute.*"): - ag.sort("angles") + ag.sort("bonds") with pytest.raises(ValueError, match=r"The function you assigned" ".*"): ag.sort("positions", keyfunc=lambda x: x) From 54b096551e0416bb9d0b01ac6753e4a0d786a557 Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 7 Apr 2021 12:43:02 +0900 Subject: [PATCH 24/45] pep8 --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index 612aacc7530..c63736d1e5c 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1698,7 +1698,7 @@ def universe(self): u.add_TopologyAttr('resid', [2, 1, 0]) u.add_TopologyAttr('segid', [1, 0]) - u.add_TopologyAttr('bonds', [(0,1)]) + u.add_TopologyAttr('bonds', [(0, 1)]) return u @@ -1744,4 +1744,4 @@ def test_sort_position(self, ag): ag.sort("positions") ref = [6, 5, 4, 3, 2, 1, 0] agsort = ag.sort("positions", keyfunc=lambda x: x[:, 1]) - assert np.array_equal(ref, agsort.ix) \ No newline at end of file + assert np.array_equal(ref, agsort.ix) From cc981ad14e5e50fc2a17a60249c9a59da2bfe6c6 Mon Sep 17 00:00:00 2001 From: 1ut Date: Wed, 7 Apr 2021 18:53:43 +0900 Subject: [PATCH 25/45] improve docs --- package/MDAnalysis/core/groups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 7b6f43c0a92..c47230f3913 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3326,12 +3326,12 @@ def write(self, filename=None, file_format=None, def sort(self, key='ix', keyfunc=None): """Return stably sorted Atomgroup by a key that specifies - an attribute of atomgroup. The default key is "ix". + an attribute of atomgroup. Parameters ---------- keys: str - The name for attribute of Atomgroup. (e.g. "ids", "ix") + The name for attribute of Atomgroup. (e.g. "ids", "ix". default="ix".) keyfunc: function A function that returns 1 dimension array, a key for sorting the atomgroup from multiple dimension array that the attribute returns. From cf100fd7d14e6476805da659c8796eb9b08c14b8 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:14:02 +0900 Subject: [PATCH 26/45] Update package/MDAnalysis/core/groups.py Fix docs Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index c47230f3913..456fc19b08a 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3330,7 +3330,7 @@ def sort(self, key='ix', keyfunc=None): Parameters ---------- - keys: str + key: str The name for attribute of Atomgroup. (e.g. "ids", "ix". default="ix".) keyfunc: function A function that returns 1 dimension array, a key for sorting the From 53da2135042fb56fdcc77ef2c5cf5c0c6650feec Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:14:38 +0900 Subject: [PATCH 27/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 456fc19b08a..a1122f7b0c3 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3331,7 +3331,7 @@ def sort(self, key='ix', keyfunc=None): Parameters ---------- key: str - The name for attribute of Atomgroup. (e.g. "ids", "ix". default="ix".) + The name of the ``AtomGroup`` attribute to sort by (e.g. ``ids``, ``ix``. default=``ix``). keyfunc: function A function that returns 1 dimension array, a key for sorting the atomgroup from multiple dimension array that the attribute returns. From baed6185d92e6d95618c007ac15d28a883a6ef26 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:14:57 +0900 Subject: [PATCH 28/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index a1122f7b0c3..6a93d1b4283 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3339,7 +3339,7 @@ def sort(self, key='ix', keyfunc=None): Returns ------- output: - Sorted atomgroup. + Sorted ``AtomGroup``. Example ------- From b726fcc9299fc3b102eb95c071160aea8108ed23 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:15:06 +0900 Subject: [PATCH 29/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 6a93d1b4283..9e81ad7f394 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3358,7 +3358,7 @@ def sort(self, key='ix', keyfunc=None): Note ---- - This sort is stable as it is implemented by + This uses a stable sort as implemented by `numpy.argsort(kind='stable')`. .. versionadded:: 2.0.0 From 65171187b4ee4f7152aa8cda2c24156f774fc706 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:16:05 +0900 Subject: [PATCH 30/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 9e81ad7f394..b434d041c45 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3325,8 +3325,8 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) def sort(self, key='ix', keyfunc=None): - """Return stably sorted Atomgroup by a key that specifies - an attribute of atomgroup. + """Returns a sorted ``AtomGroup`` using a specified attribute as + the key. Parameters ---------- From 6925454bbb873d20b8e19cb39b85817f92014ec6 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:16:47 +0900 Subject: [PATCH 31/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index b434d041c45..050a0fa7d1a 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3333,8 +3333,11 @@ def sort(self, key='ix', keyfunc=None): key: str The name of the ``AtomGroup`` attribute to sort by (e.g. ``ids``, ``ix``. default=``ix``). keyfunc: function - A function that returns 1 dimension array, a key for sorting the - atomgroup from multiple dimension array that the attribute returns. + A function to convert multidimensional arrays to a single + dimension. This 1D array will be used as the sort key and + is required when sorting with an ``AtomGroup`` attribute + key which has multiple dimensions. Note: this argument + is ignored when the attribute is one dimensional. Returns ------- From d367b5c5d928b9b11e2d728aeffbeb00f8ae9879 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:18:08 +0900 Subject: [PATCH 32/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 050a0fa7d1a..d82a3f7caa8 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3369,8 +3369,8 @@ def sort(self, key='ix', keyfunc=None): idx = getattr(self.atoms, key) if len(idx) != len(self.atoms): raise ValueError("The array returned by the attribute '{}' " - "must have a same length as the number of " - "atoms".format(key)) + "must have the same length as the number of " + "atoms in the input AtomGroup".format(key)) if idx.ndim == 1: order = np.argsort(idx, kind='stable') elif idx.ndim > 1: From bdd391c384e45bc0ac1afb29bb1ee5831d67e0c4 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:18:20 +0900 Subject: [PATCH 33/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index d82a3f7caa8..d28e246bc2b 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3381,7 +3381,7 @@ def sort(self, key='ix', keyfunc=None): "dimension array.".format(key)) sortkeys = keyfunc(idx) if sortkeys.ndim != 1: - raise ValueError("The function you assigned to the argument " + raise ValueError("The function assigned to the argument " "'keyfunc':{} doesn't return 1D array." .format(keyfunc)) order = np.argsort(sortkeys, kind='stable') From e0bef58681c2fba19490ceb1d964740f60518e2d Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 11:22:41 +0900 Subject: [PATCH 34/45] Fix error message --- package/MDAnalysis/core/groups.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 9e81ad7f394..51e87b5696f 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3372,10 +3372,11 @@ def sort(self, key='ix', keyfunc=None): order = np.argsort(idx, kind='stable') elif idx.ndim > 1: if keyfunc is None: - raise NameError("You have to assign the argument 'keyfunc' " - "a proper function that returns 1D array " - "as the attribute '{}' returns multiple " - "dimension array.".format(key)) + raise NameError("The {} attribute returns a multidimensional " + "array. In order to sort it, a function " + "returning a 1D array (to be used as the sort " + "key) must be passed to the keyfunc argument" + .format(key)) sortkeys = keyfunc(idx) if sortkeys.ndim != 1: raise ValueError("The function you assigned to the argument " From 52b677a50c2977a0df07f40ba462c230f01974fb Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 11:41:40 +0900 Subject: [PATCH 35/45] separate tests --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index c63736d1e5c..6356687a35c 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1704,7 +1704,9 @@ def universe(self): @pytest.fixture() def ag(self, universe): - return universe.atoms + ag = universe.atoms + ag.positions = (-np.arange(21)).reshape(7, 3) + return ag test_ids = [ "ix", @@ -1731,17 +1733,22 @@ def test_sort(self, ag, inputs, expected): agsort = ag.sort(inputs) assert np.array_equal(expected, agsort.ix) - def test_sort_position(self, ag): - ag.positions = (-np.arange(21)).reshape(7, 3) + def test_sort_bonds(self, ag): with pytest.raises(ValueError, match=r"The array returned by the " "attribute.*"): ag.sort("bonds") + + def test_sort_positions_2D(self, ag): with pytest.raises(ValueError, match=r"The function you assigned" ".*"): ag.sort("positions", keyfunc=lambda x: x) + + def test_sort_position_no_keyfunc(self, ag): with pytest.raises(NameError, match=r"You have to assign the argument" ".*"): ag.sort("positions") + + def test_sort_position(self, ag): ref = [6, 5, 4, 3, 2, 1, 0] agsort = ag.sort("positions", keyfunc=lambda x: x[:, 1]) assert np.array_equal(ref, agsort.ix) From 338417e2ea1c71d908d22037412a8d7d5c014b72 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 11:49:30 +0900 Subject: [PATCH 36/45] FIx error messages --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index 6356687a35c..eabb89ad9b7 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1739,12 +1739,13 @@ def test_sort_bonds(self, ag): ag.sort("bonds") def test_sort_positions_2D(self, ag): - with pytest.raises(ValueError, match=r"The function you assigned" + with pytest.raises(ValueError, match=r"The function assigned to" ".*"): ag.sort("positions", keyfunc=lambda x: x) def test_sort_position_no_keyfunc(self, ag): - with pytest.raises(NameError, match=r"You have to assign the argument" + with pytest.raises(NameError, match=r"The .* attribute returns a " + "multidimensional array. In order to sort it, " ".*"): ag.sort("positions") From 170ce403a5a5eceed97e1d2086c3ed7b338126ac Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 13:30:39 +0900 Subject: [PATCH 37/45] pep8 --- package/MDAnalysis/core/groups.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 9934d15ef70..f479e91d712 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3331,7 +3331,8 @@ def sort(self, key='ix', keyfunc=None): Parameters ---------- key: str - The name of the ``AtomGroup`` attribute to sort by (e.g. ``ids``, ``ix``. default=``ix``). + The name of the ``AtomGroup`` attribute to sort by (e.g. ``ids``, + ``ix``. default=``ix``). keyfunc: function A function to convert multidimensional arrays to a single dimension. This 1D array will be used as the sort key and From 072b15908a9537766f77c630b5357a24c8c32730 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 13:53:01 +0900 Subject: [PATCH 38/45] Add example in the docs --- package/MDAnalysis/core/groups.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index f479e91d712..05c3c40a256 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3359,6 +3359,17 @@ def sort(self, key='ix', keyfunc=None): >>> ag = ag.sort() >>> ag.ix array([0 1 2 3]) + >>> ag.positions + array([[-11.921, 26.307, 10.41 ], + [-11.447, 26.741, 9.595], + [-12.44 , 27.042, 10.926], + [-12.632, 25.619, 10.046]], dtype=float32) + >>> ag = ag.sort("positions", lambda x: x[:, 1]) + >>> ag.positions + array([[-12.632, 25.619, 10.046], + [-11.921, 26.307, 10.41 ], + [-11.447, 26.741, 9.595], + [-12.44 , 27.042, 10.926]], dtype=float32) Note ---- From 18d36eedeaf8fe62f70ce494009138953b5aa004 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 15:53:35 +0900 Subject: [PATCH 39/45] edit docs --- package/MDAnalysis/core/groups.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 05c3c40a256..18667058889 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3325,15 +3325,15 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) def sort(self, key='ix', keyfunc=None): - """Returns a sorted ``AtomGroup`` using a specified attribute as + """Returns a sorted ``AtomGroup`` using a specified attribute as \ the key. Parameters ---------- - key: str + key: str, optional The name of the ``AtomGroup`` attribute to sort by (e.g. ``ids``, - ``ix``. default=``ix``). - keyfunc: function + ``ix``. default= ``ix`` ). + keyfunc: callable, optional A function to convert multidimensional arrays to a single dimension. This 1D array will be used as the sort key and is required when sorting with an ``AtomGroup`` attribute From 1e9d9e4c52debf4087193b182cff99bf163793a3 Mon Sep 17 00:00:00 2001 From: 1ut Date: Thu, 8 Apr 2021 16:22:56 +0900 Subject: [PATCH 40/45] edit docs --- package/MDAnalysis/core/groups.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 18667058889..49fc8c954a5 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3341,12 +3341,12 @@ def sort(self, key='ix', keyfunc=None): is ignored when the attribute is one dimensional. Returns - ------- - output: + ---------- + Group Sorted ``AtomGroup``. Example - ------- + ---------- .. code-block:: python @@ -3372,7 +3372,7 @@ def sort(self, key='ix', keyfunc=None): [-12.44 , 27.042, 10.926]], dtype=float32) Note - ---- + ---------- This uses a stable sort as implemented by `numpy.argsort(kind='stable')`. From 325a3d9655889201c95dea4099a4c24b4e7472ec Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Fri, 9 Apr 2021 18:44:18 +0900 Subject: [PATCH 41/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 49fc8c954a5..b147853535e 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3342,7 +3342,7 @@ def sort(self, key='ix', keyfunc=None): Returns ---------- - Group + :class:`AtomGroup` Sorted ``AtomGroup``. Example From 1de2d9748893fd759903f52dadbd0659bc3a4ab1 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Fri, 9 Apr 2021 18:44:30 +0900 Subject: [PATCH 42/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 1 + 1 file changed, 1 insertion(+) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index b147853535e..5fbe511a762 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3376,6 +3376,7 @@ def sort(self, key='ix', keyfunc=None): This uses a stable sort as implemented by `numpy.argsort(kind='stable')`. + .. versionadded:: 2.0.0 """ idx = getattr(self.atoms, key) From 705cdd72f21fb8a340e029582d424bdd5d6f5846 Mon Sep 17 00:00:00 2001 From: 1ut <69892398+1ut@users.noreply.github.com> Date: Fri, 9 Apr 2021 18:44:38 +0900 Subject: [PATCH 43/45] Update package/MDAnalysis/core/groups.py Co-authored-by: Irfan Alibay --- package/MDAnalysis/core/groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 5fbe511a762..7d057151cc8 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3396,7 +3396,7 @@ def sort(self, key='ix', keyfunc=None): sortkeys = keyfunc(idx) if sortkeys.ndim != 1: raise ValueError("The function assigned to the argument " - "'keyfunc':{} doesn't return 1D array." + "'keyfunc':{} doesn't return a 1D array." .format(keyfunc)) order = np.argsort(sortkeys, kind='stable') return self.atoms[order] From 33776558e9dc6ce659dfc57537d98aeb80209ea7 Mon Sep 17 00:00:00 2001 From: 1ut Date: Fri, 9 Apr 2021 18:49:40 +0900 Subject: [PATCH 44/45] Unecessary \ --- package/MDAnalysis/core/groups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 7d057151cc8..53e9e8529b6 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -3325,8 +3325,8 @@ def write(self, filename=None, file_format=None, raise ValueError("No writer found for format: {}".format(filename)) def sort(self, key='ix', keyfunc=None): - """Returns a sorted ``AtomGroup`` using a specified attribute as \ - the key. + """ + Returns a sorted ``AtomGroup`` using a specified attribute as the key. Parameters ---------- From c2f734260ee05bd387572144b5a0a15463cf53e0 Mon Sep 17 00:00:00 2001 From: 1ut Date: Fri, 9 Apr 2021 18:54:42 +0900 Subject: [PATCH 45/45] remove unnecessary .* --- testsuite/MDAnalysisTests/core/test_atomgroup.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/testsuite/MDAnalysisTests/core/test_atomgroup.py b/testsuite/MDAnalysisTests/core/test_atomgroup.py index eabb89ad9b7..a719ccdfbb5 100644 --- a/testsuite/MDAnalysisTests/core/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/core/test_atomgroup.py @@ -1735,18 +1735,16 @@ def test_sort(self, ag, inputs, expected): def test_sort_bonds(self, ag): with pytest.raises(ValueError, match=r"The array returned by the " - "attribute.*"): + "attribute"): ag.sort("bonds") def test_sort_positions_2D(self, ag): - with pytest.raises(ValueError, match=r"The function assigned to" - ".*"): + with pytest.raises(ValueError, match=r"The function assigned to"): ag.sort("positions", keyfunc=lambda x: x) def test_sort_position_no_keyfunc(self, ag): with pytest.raises(NameError, match=r"The .* attribute returns a " - "multidimensional array. In order to sort it, " - ".*"): + "multidimensional array. In order to sort it, "): ag.sort("positions") def test_sort_position(self, ag):