From e8637a9773a989cdd8b0827f313fa50bdb6faa66 Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Sun, 21 Apr 2024 08:16:10 -0600 Subject: [PATCH 1/4] MAINT: shims for array copy semantics (#4482) * MAINT: shims for array copy semantics * Fixes #4481 * this gets rid of segfaults/many test failurse against latest NumPy `main` while still passing the full suite against NumPy `1.26.4`; it is pretty hard to test since needs special branch of SciPy (for the same reason, upstream hasn't fully resolved copy semantics) * I still see 2-3 test failures against `main` locally, but likely still a large improvement; may want to let this sit a little bit while the upstream storm settles, but I suspect this is the gist of the shims we'd want * MAINT: PR 4482 revisions * abstract the array copy semantics (NumPy 1.x vs. 2.x) handling to a utility function to reduce code duplication * add a missing `dtype=None` to an `__array__` signature, for more formal correctness with NumPy 2.x * MAINT: PR 4482 revisions * Update `vector_of_best_fit()` function in the helix analysis code to avoid use of `np.linalg.linalg` namespace, which is deprecated/private in NumPy `2.x`. Instead, just access `svd` via the public `np.linalg` namespace. * This fixes the last two remaining test failures for MDAnalysis against NumPy `2.0.0rc1`. * Switch the array `copy` shim to use the more appropriate `NumpyVersion` rather than a raw string check for version `2`. --- package/MDAnalysis/analysis/helix_analysis.py | 2 +- package/MDAnalysis/lib/formats/cython_util.pyx | 6 ++++-- package/MDAnalysis/lib/transformations.py | 13 +++++++------ package/MDAnalysis/lib/util.py | 8 ++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/package/MDAnalysis/analysis/helix_analysis.py b/package/MDAnalysis/analysis/helix_analysis.py index 7bf07b8f231..da57fbc1ab6 100644 --- a/package/MDAnalysis/analysis/helix_analysis.py +++ b/package/MDAnalysis/analysis/helix_analysis.py @@ -121,7 +121,7 @@ def vector_of_best_fit(coordinates): """ centered = coordinates - coordinates.mean(axis=0) Mt_M = np.matmul(centered.T, centered) - u, s, vh = np.linalg.linalg.svd(Mt_M) + u, s, vh = np.linalg.svd(Mt_M) vector = vh[0] # does vector face first local helix origin? diff --git a/package/MDAnalysis/lib/formats/cython_util.pyx b/package/MDAnalysis/lib/formats/cython_util.pyx index 3c9b90d02e9..26c694a40fd 100644 --- a/package/MDAnalysis/lib/formats/cython_util.pyx +++ b/package/MDAnalysis/lib/formats/cython_util.pyx @@ -26,6 +26,8 @@ cimport numpy as cnp from libc.stdlib cimport free from cpython cimport PyObject, Py_INCREF +from MDAnalysis.lib.util import no_copy_shim + cnp.import_array() @@ -71,7 +73,7 @@ cdef class ArrayWrapper: self.data_type = data_type self.ndim = ndim - def __array__(self): + def __array__(self, dtype=None, copy=None): """ Here we use the __array__ method, that is called when numpy tries to get an array from the object.""" ndarray = cnp.PyArray_SimpleNewFromData(self.ndim, @@ -110,7 +112,7 @@ cdef cnp.ndarray ptr_to_ndarray(void* data_ptr, cnp.int64_t[:] dim, int data_typ array_wrapper = ArrayWrapper() array_wrapper.set_data( data_ptr, &dim[0], dim.size, data_type) - cdef cnp.ndarray ndarray = np.array(array_wrapper, copy=False) + cdef cnp.ndarray ndarray = np.array(array_wrapper, copy=no_copy_shim) # Assign our object to the 'base' of the ndarray object ndarray[:] = array_wrapper.__array__() # Increment the reference count, as the above assignement was done in diff --git a/package/MDAnalysis/lib/transformations.py b/package/MDAnalysis/lib/transformations.py index 3498f655120..5c386a01047 100644 --- a/package/MDAnalysis/lib/transformations.py +++ b/package/MDAnalysis/lib/transformations.py @@ -170,6 +170,7 @@ from numpy.linalg import norm from .mdamath import angle as vecangle +from MDAnalysis.lib.util import no_copy_shim def identity_matrix(): """Return 4x4 identity/unit matrix. @@ -326,7 +327,7 @@ def rotation_matrix(angle, direction, point=None): M[:3, :3] = R if point is not None: # rotation not around origin - point = np.array(point[:3], dtype=np.float64, copy=False) + point = np.array(point[:3], dtype=np.float64, copy=no_copy_shim) M[:3, 3] = point - np.dot(R, point) return M @@ -497,7 +498,7 @@ def projection_matrix(point, normal, direction=None, """ M = np.identity(4) - point = np.array(point[:3], dtype=np.float64, copy=False) + point = np.array(point[:3], dtype=np.float64, copy=no_copy_shim) normal = unit_vector(normal[:3]) if perspective is not None: # perspective projection @@ -515,7 +516,7 @@ def projection_matrix(point, normal, direction=None, M[3, 3] = np.dot(perspective, normal) elif direction is not None: # parallel projection - direction = np.array(direction[:3], dtype=np.float64, copy=False) + direction = np.array(direction[:3], dtype=np.float64, copy=no_copy_shim) scale = np.dot(direction, normal) M[:3, :3] -= np.outer(direction, normal) / scale M[:3, 3] = direction * (np.dot(point, normal) / scale) @@ -970,8 +971,8 @@ def superimposition_matrix(v0, v1, scaling=False, usesvd=True): True """ - v0 = np.array(v0, dtype=np.float64, copy=False)[:3] - v1 = np.array(v1, dtype=np.float64, copy=False)[:3] + v0 = np.array(v0, dtype=np.float64, copy=no_copy_shim)[:3] + v1 = np.array(v1, dtype=np.float64, copy=no_copy_shim)[:3] if v0.shape != v1.shape or v0.shape[1] < 3: raise ValueError("vector sets are of wrong shape or type") @@ -1314,7 +1315,7 @@ def quaternion_from_matrix(matrix, isprecise=False): True """ - M = np.array(matrix, dtype=np.float64, copy=False)[:4, :4] + M = np.array(matrix, dtype=np.float64, copy=no_copy_shim)[:4, :4] if isprecise: q = np.empty((4, ), dtype=np.float64) t = np.trace(M) diff --git a/package/MDAnalysis/lib/util.py b/package/MDAnalysis/lib/util.py index 072be67ee2b..fcbc6872ba9 100644 --- a/package/MDAnalysis/lib/util.py +++ b/package/MDAnalysis/lib/util.py @@ -2552,3 +2552,11 @@ def wrapper(self, *args, **kwargs): self._kwargs[key] = arg return func(self, *args, **kwargs) return wrapper + + +def no_copy_shim(): + if np.lib.NumpyVersion >= "2.0.0rc1": + copy = None + else: + copy = False + return copy From 82904849a39a4e372461ee9e5708a0af658f4732 Mon Sep 17 00:00:00 2001 From: Lily Wang <31115101+lilyminium@users.noreply.github.com> Date: Mon, 22 Apr 2024 00:22:17 +1000 Subject: [PATCH 2/4] Fix citation notation in README.rst (#4571) Current rst notation was parsing the `R.`, `M.` initials, etc. as further enumeration in a list item. It also wasn't reading the DOI links. This escapes the dots and adds a space before the DOI link to correct rendering. --- README.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index c539704e74a..339829ef056 100644 --- a/README.rst +++ b/README.rst @@ -102,19 +102,18 @@ Citation When using MDAnalysis in published work, please cite the following two papers: -* R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, - M. N. Melo, S. L. Seyler, D. L. Dotson, J. Domanski, - S. Buchoux, I. M. Kenney, and O. Beckstein. MDAnalysis: +* R\. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, + M\. N. Melo, S. L. Seyler, D. L. Dotson, J. Domanski, + S\. Buchoux, I. M. Kenney, and O. Beckstein. MDAnalysis: A Python package for the rapid analysis of molecular dynamics simulations. In S. Benthall and S. Rostrup, editors, Proceedings of the 15th Python in Science Conference, pages 102-109, Austin, TX, 2016. SciPy. - doi:`10.25080/Majora-629e541a-00e`_ - + doi: `10.25080/Majora-629e541a-00e`_ * N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein. MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. *J. Comput. Chem.* **32** (2011), 2319--2327. - doi:`10.1002/jcc.21787`_ + doi: `10.1002/jcc.21787`_ For citations of included algorithms and sub-modules please see the references_. @@ -194,4 +193,4 @@ For citations of included algorithms and sub-modules please see the references_. .. |discussions| image:: https://img.shields.io/github/discussions/MDAnalysis/MDAnalysis :alt: GitHub Discussions - :target: https://github.com/MDAnalysis/mdanalysis/discussions \ No newline at end of file + :target: https://github.com/MDAnalysis/mdanalysis/discussions From b91c44e808464b845466b9b7d650300d2222802b Mon Sep 17 00:00:00 2001 From: Irfan Alibay Date: Mon, 22 Apr 2024 07:27:33 +0100 Subject: [PATCH 3/4] Don't fail on codecov upload error (#4575) --- .github/workflows/gh-ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-ci.yaml b/.github/workflows/gh-ci.yaml index 16c2d300d38..b6d0ba22133 100644 --- a/.github/workflows/gh-ci.yaml +++ b/.github/workflows/gh-ci.yaml @@ -127,7 +127,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} file: coverage.xml - fail_ci_if_error: True + fail_ci_if_error: False verbose: True From 804b6073fdfaee0c5be1e2be659c2280ee4d0cda Mon Sep 17 00:00:00 2001 From: Irfan Alibay Date: Mon, 22 Apr 2024 07:49:40 +0100 Subject: [PATCH 4/4] Fix sdist CI tests for package name normalization (#4572) --- .github/workflows/gh-ci.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gh-ci.yaml b/.github/workflows/gh-ci.yaml index b6d0ba22133..d705012a4d6 100644 --- a/.github/workflows/gh-ci.yaml +++ b/.github/workflows/gh-ci.yaml @@ -259,13 +259,13 @@ jobs: - name: check_package_build run: | - DISTRIBUTION=$(ls -t1 dist/MDAnalysis-*.tar.gz | head -n1) + DISTRIBUTION=$(ls -t1 dist/mdanalysis-*.tar.gz | head -n1) test -n "${DISTRIBUTION}" || { echo "no distribution dist/MDAnalysis-*.tar.gz found"; exit 1; } twine check $DISTRIBUTION - name: check_testsuite_build run: | - DISTRIBUTION=$(ls -t1 dist/MDAnalysisTests-*.tar.gz | head -n1) + DISTRIBUTION=$(ls -t1 dist/mdanalysistests-*.tar.gz | head -n1) test -n "${DISTRIBUTION}" || { echo "no distribution dist/MDAnalysisTests-*.tar.gz found"; exit 1; } twine check $DISTRIBUTION @@ -273,8 +273,8 @@ jobs: working-directory: ./dist run: | ls -a . - python -m pip install MDAnalysis-*.tar.gz - python -m pip install MDAnalysisTests-*.tar.gz + python -m pip install mdanalysis-*.tar.gz + python -m pip install mdanalysistests-*.tar.gz - name: run tests working-directory: ./dist