Expected behavior
AnalysisBase.run() should interpret Python and NumPy boolean masks in the same way. For example:
frames = [True, False, True, False] AND frames = np.array([True, False, True, False], dtype=bool)
should equally select as output frames [0, 2].
Actual behavior
The case with the Python boolean list correctly selects frames [0, 2] as we expect, but an equivalent NumPy boolean array misinterpret them as integer frame indices and processes [1, 0, 1, 0].
This happens without throwing any error and can produce plausible-looking analysis results calculated from the wrong frames.
Code to reproduce the behavior
import numpy as np
import MDAnalysis as mda
from MDAnalysis.analysis.base import AnalysisFromFunction
# We create a trajectory with one atom and four frames.
coordinates = np.zeros((4, 1, 3), dtype=np.float32)
# Encode the frame number in the atom's x coordinate:
coordinates[:, 0, 0] = [0, 1, 2, 3]
u = mda.Universe.empty(n_atoms=1)
u.load_new(coordinates, format="MEMORY")
def read_x(atomgroup):
"""Return the x coordinate of the only atom."""
return atomgroup.positions[0, 0]
# Both masks should select frames 0 and 2.
python_mask = [True, False, True, False]
numpy_mask = np.array([True, False, True, False], dtype=bool)
with_python_mask = AnalysisFromFunction(
read_x,
u.trajectory,
u.atoms,
).run(frames=python_mask)
with_numpy_mask = AnalysisFromFunction(
read_x,
u.trajectory,
u.atoms,
).run(frames=numpy_mask)
print("Python list values:", with_python_mask.results.timeseries)
print("NumPy array values:", with_numpy_mask.results.timeseries)
Output:
Python list values: [0. 2.]
NumPy array values: [1. 0. 1. 0.]
Both inputs are boolean masks and should select frames [0, 2]. However, the NumPy mask is interpreted as the integer frame indices [1, 0, 1, 0].
Current version of MDAnalysis
-MDAnalysis: 2.10.0
This behavior was originally noted by @srikarjy while working on #5459.
Expected behavior
AnalysisBase.run() should interpret Python and NumPy boolean masks in the same way. For example:
frames = [True, False, True, False] AND frames = np.array([True, False, True, False], dtype=bool)
should equally select as output frames [0, 2].
Actual behavior
The case with the Python boolean list correctly selects frames [0, 2] as we expect, but an equivalent NumPy boolean array misinterpret them as integer frame indices and processes [1, 0, 1, 0].
This happens without throwing any error and can produce plausible-looking analysis results calculated from the wrong frames.
Code to reproduce the behavior
Output:
Both inputs are boolean masks and should select frames
[0, 2]. However, the NumPy mask is interpreted as the integer frame indices[1, 0, 1, 0].Current version of MDAnalysis
-MDAnalysis: 2.10.0
This behavior was originally noted by @srikarjy while working on #5459.