Skip to content

Commit

Permalink
Replaced numpy.testing.assert_almost_equal to numpy.testing.assert_al…
Browse files Browse the repository at this point in the history
…lclose (MDAnalysis#4438)

* fixes part of MDAnalysis#3743 
* replaced assert_almost_equal() with assert_allclose() for  more consistent floating point comparisons;
   replaced decimal={N} with atol=0 rtol=1.5e-{N}
* updated authors file and changelog
  • Loading branch information
aditya292002 authored Feb 24, 2024
1 parent 3a5339c commit 2c1aa4b
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 108 deletions.
2 changes: 2 additions & 0 deletions package/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ Chronological list of authors
- Lawson Woods
- Johannes Stöckelmaier
- Jenna M. Swarthout Goddard
2024
- Aditya Keshari

External code
-------------
Expand Down
6 changes: 5 additions & 1 deletion package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The rules for this file:

-------------------------------------------------------------------------------
??/??/?? IAlibay, HeetVekariya, marinegor, lilyminium, RMeli,
ljwoods2
ljwoods2, aditya292002

* 2.8.0

Expand All @@ -40,6 +40,10 @@ Changes
* As per NEP29, the minimum version of numpy has been raised to 1.23.
We have opted to pin to 1.23.2 to ensure the same minimum numpy version
is used from python 3.9 to 3.11 (Issue #4401, PR #4402)
* updated tests that used assert_almost_equal(..., decimal={N}) with
equivalent assert_allclose(... rtol=0, atol=1.5e-{N}) (issue modernize
testing code #3743, PR Replaced numpy.testing.assert_almost_equal to
numpy.testing.assert_allclose #4438)

Deprecations
* The MDAnalysis.analysis.waterdynamics module has been deprecated in favour
Expand Down
4 changes: 2 additions & 2 deletions package/MDAnalysis/visualization/streamlines_3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ def point_in_cube(array_point_coordinates, list_cube_vertices, cube_centroid):
cube_half_side_length = scipy.spatial.distance.pdist(array_cube_vertices, 'euclidean').min() / 2.0
array_cube_vertex_distances_from_centroid = scipy.spatial.distance.cdist(array_cube_vertices,
cube_centroid[np.newaxis, :])
np.testing.assert_almost_equal(array_cube_vertex_distances_from_centroid.min(),
array_cube_vertex_distances_from_centroid.max(), decimal=4,
np.testing.assert_allclose(array_cube_vertex_distances_from_centroid.min(),
array_cube_vertex_distances_from_centroid.max(), rtol=0, atol=1.5e-4,
err_msg="not all cube vertex to centroid distances are the same, "
"so not a true cube")
absolute_delta_coords = np.absolute(np.subtract(array_point_coordinates, cube_centroid))
Expand Down
79 changes: 38 additions & 41 deletions testsuite/MDAnalysisTests/analysis/test_align.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@
from MDAnalysisTests.datafiles import (PSF, DCD, CRD, FASTA, ALIGN_BOUND,
ALIGN_UNBOUND, PDB_helix)
from numpy.testing import (
assert_almost_equal,
assert_equal,
assert_array_equal,
assert_array_almost_equal,
assert_allclose,
)

Expand Down Expand Up @@ -167,7 +165,7 @@ def test_subselection_alignto(self, universe, reference, subselection, expectati

with expectation:
rmsd = align.alignto(universe, reference, subselection=subselection)
assert_almost_equal(rmsd[1], 0.0, decimal=9)
assert_allclose(rmsd[1], 0.0, rtol=0, atol=1.5e-9)

def test_no_atom_masses(self, universe):
#if no masses are present
Expand Down Expand Up @@ -199,25 +197,25 @@ def test_rmsd(self, universe, reference):
first_frame = bb.positions
universe.trajectory[-1]
last_frame = bb.positions
assert_almost_equal(rms.rmsd(first_frame, first_frame), 0.0, 5,
err_msg="error: rmsd(X,X) should be 0")
assert_allclose(rms.rmsd(first_frame, first_frame), 0.0, rtol=0, atol=1.5e-5,
err_msg="error: rmsd(X,X) should be 0")
# rmsd(A,B) = rmsd(B,A) should be exact but spurious failures in the
# 9th decimal have been observed (see Issue 57 comment #1) so we relax
# the test to 6 decimals.
rmsd = rms.rmsd(first_frame, last_frame, superposition=True)
assert_almost_equal(
rms.rmsd(last_frame, first_frame, superposition=True), rmsd, 6,
assert_allclose(
rms.rmsd(last_frame, first_frame, superposition=True), rmsd, rtol=0, atol=1.5e-6,
err_msg="error: rmsd() is not symmetric")
assert_almost_equal(rmsd, 6.820321761927005, 5,
err_msg="RMSD calculation between 1st and last AdK frame gave wrong answer")
assert_allclose(rmsd, 6.820321761927005, rtol=0, atol=1.5e-5,
err_msg="RMSD calculation between 1st and last AdK frame gave wrong answer")
# test masses as weights
last_atoms_weight = universe.atoms.masses
A = universe.trajectory[0]
B = reference.trajectory[-1]
rmsd = align.alignto(universe, reference, weights='mass')
rmsd_sup_weight = rms.rmsd(A, B, weights=last_atoms_weight, center=True,
superposition=True)
assert_almost_equal(rmsd[1], rmsd_sup_weight, 6)
assert_allclose(rmsd[1], rmsd_sup_weight, rtol=0, atol=1.5e-6)

def test_rmsd_custom_mass_weights(self, universe, reference):
last_atoms_weight = universe.atoms.masses
Expand All @@ -227,15 +225,15 @@ def test_rmsd_custom_mass_weights(self, universe, reference):
weights=reference.atoms.masses)
rmsd_sup_weight = rms.rmsd(A, B, weights=last_atoms_weight, center=True,
superposition=True)
assert_almost_equal(rmsd[1], rmsd_sup_weight, 6)
assert_allclose(rmsd[1], rmsd_sup_weight, rtol=0, atol=1.5e-6)

def test_rmsd_custom_weights(self, universe, reference):
weights = np.zeros(universe.atoms.n_atoms)
ca = universe.select_atoms('name CA')
weights[ca.indices] = 1
rmsd = align.alignto(universe, reference, select='name CA')
rmsd_weights = align.alignto(universe, reference, weights=weights)
assert_almost_equal(rmsd[1], rmsd_weights[1], 6)
assert_allclose(rmsd[1], rmsd_weights[1], rtol=0, atol=1.5e-6)

def test_AlignTraj_outfile_default(self, universe, reference, tmpdir):
with tmpdir.as_cwd():
Expand Down Expand Up @@ -285,8 +283,8 @@ def test_AlignTraj(self, universe, reference, tmpdir):
x = align.AlignTraj(universe, reference, filename=outfile).run()
fitted = mda.Universe(PSF, outfile)

assert_almost_equal(x.results.rmsd[0], 6.9290, decimal=3)
assert_almost_equal(x.results.rmsd[-1], 5.2797e-07, decimal=3)
assert_allclose(x.results.rmsd[0], 6.9290, rtol=0, atol=1.5e-3)
assert_allclose(x.results.rmsd[-1], 5.2797e-07, rtol=0, atol=1.5e-3)

# RMSD against the reference frame
# calculated on Mac OS X x86 with MDA 0.7.2 r689
Expand All @@ -299,8 +297,8 @@ def test_AlignTraj_weighted(self, universe, reference, tmpdir):
x = align.AlignTraj(universe, reference,
filename=outfile, weights='mass').run()
fitted = mda.Universe(PSF, outfile)
assert_almost_equal(x.results.rmsd[0], 0, decimal=3)
assert_almost_equal(x.results.rmsd[-1], 6.9033, decimal=3)
assert_allclose(x.results.rmsd[0], 0, rtol=0, atol=1.5e-3)
assert_allclose(x.results.rmsd[-1], 6.9033, rtol=0, atol=1.5e-3)

self._assert_rmsd(reference, fitted, 0, 0.0,
weights=universe.atoms.masses)
Expand All @@ -319,16 +317,16 @@ def test_AlignTraj_custom_weights(self, universe, reference, tmpdir):
x_weights = align.AlignTraj(universe, reference,
filename=outfile, weights=weights).run()

assert_array_almost_equal(x.results.rmsd, x_weights.results.rmsd)
assert_allclose(x.results.rmsd, x_weights.results.rmsd, rtol=0, atol=1.5e-7)

def test_AlignTraj_custom_mass_weights(self, universe, reference, tmpdir):
outfile = str(tmpdir.join('align_test.dcd'))
x = align.AlignTraj(universe, reference,
filename=outfile,
weights=reference.atoms.masses).run()
fitted = mda.Universe(PSF, outfile)
assert_almost_equal(x.results.rmsd[0], 0, decimal=3)
assert_almost_equal(x.results.rmsd[-1], 6.9033, decimal=3)
assert_allclose(x.results.rmsd[0], 0, rtol=0, atol=1.5e-3)
assert_allclose(x.results.rmsd[-1], 6.9033, rtol=0, atol=1.5e-3)

self._assert_rmsd(reference, fitted, 0, 0.0,
weights=universe.atoms.masses)
Expand All @@ -348,8 +346,8 @@ def test_AlignTraj_in_memory(self, universe, reference, tmpdir):
x = align.AlignTraj(universe, reference, filename=outfile,
in_memory=True).run()
assert x.filename is None
assert_almost_equal(x.results.rmsd[0], 6.9290, decimal=3)
assert_almost_equal(x.results.rmsd[-1], 5.2797e-07, decimal=3)
assert_allclose(x.results.rmsd[0], 6.9290, rtol=0, atol=1.5e-3)
assert_allclose(x.results.rmsd[-1], 5.2797e-07, rtol=0, atol=1.5e-3)

# check in memory trajectory
self._assert_rmsd(reference, universe, 0, 6.929083044751061)
Expand All @@ -359,7 +357,7 @@ def _assert_rmsd(self, reference, fitted, frame, desired, weights=None):
fitted.trajectory[frame]
rmsd = rms.rmsd(reference.atoms.positions, fitted.atoms.positions,
superposition=True)
assert_almost_equal(rmsd, desired, decimal=5,
assert_allclose(rmsd, desired, rtol = 0, atol=1.5e-5,
err_msg="frame {0:d} of fit does not have "
"expected RMSD".format(frame))

Expand Down Expand Up @@ -394,8 +392,8 @@ def test_alignto_partial_universe(self, universe, reference):
segB_free.translate(segB_bound.centroid() - segB_free.centroid())

align.alignto(u_free, u_bound, select=selection)
assert_array_almost_equal(segB_bound.positions, segB_free.positions,
decimal=3)
assert_allclose(segB_bound.positions, segB_free.positions,
rtol=0, atol=1.5e-3)


def _get_aligned_average_positions(ref_files, ref, select="all", **kwargs):
Expand Down Expand Up @@ -438,31 +436,30 @@ def test_average_structure_deprecated_attrs(self, universe, reference):
def test_average_structure(self, universe, reference):
ref, rmsd = _get_aligned_average_positions(self.ref_files, reference)
avg = align.AverageStructure(universe, reference).run()
assert_almost_equal(avg.results.universe.atoms.positions, ref,
decimal=4)
assert_almost_equal(avg.results.rmsd, rmsd)
assert_allclose(avg.results.universe.atoms.positions, ref, rtol=0, atol=1.5e-4)
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)

def test_average_structure_mass_weighted(self, universe, reference):
ref, rmsd = _get_aligned_average_positions(self.ref_files, reference, weights='mass')
avg = align.AverageStructure(universe, reference, weights='mass').run()
assert_almost_equal(avg.results.universe.atoms.positions, ref,
decimal=4)
assert_almost_equal(avg.results.rmsd, rmsd)
assert_allclose(avg.results.universe.atoms.positions, ref,
rtol=0, atol=1.5e-4)
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)

def test_average_structure_select(self, universe, reference):
select = 'protein and name CA and resid 3-5'
ref, rmsd = _get_aligned_average_positions(self.ref_files, reference, select=select)
avg = align.AverageStructure(universe, reference, select=select).run()
assert_almost_equal(avg.results.universe.atoms.positions, ref,
decimal=4)
assert_almost_equal(avg.results.rmsd, rmsd)
assert_allclose(avg.results.universe.atoms.positions, ref,
rtol=0, atol=1.5e-4)
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)

def test_average_structure_no_ref(self, universe):
ref, rmsd = _get_aligned_average_positions(self.ref_files, universe)
avg = align.AverageStructure(universe).run()
assert_almost_equal(avg.results.universe.atoms.positions, ref,
decimal=4)
assert_almost_equal(avg.results.rmsd, rmsd)
assert_allclose(avg.results.universe.atoms.positions, ref,
rtol=0, atol=1.5e-4)
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)

def test_average_structure_no_msf(self, universe):
avg = align.AverageStructure(universe).run()
Expand All @@ -485,15 +482,15 @@ def test_average_structure_ref_frame(self, universe):
universe.trajectory[0]
ref, rmsd = _get_aligned_average_positions(self.ref_files, u)
avg = align.AverageStructure(universe, ref_frame=ref_frame).run()
assert_almost_equal(avg.results.universe.atoms.positions, ref,
decimal=4)
assert_almost_equal(avg.results.rmsd, rmsd)
assert_allclose(avg.results.universe.atoms.positions, ref,
rtol=0, atol=1.5e-4)
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)

def test_average_structure_in_memory(self, universe):
avg = align.AverageStructure(universe, in_memory=True).run()
reference_coordinates = universe.trajectory.timeseries().mean(axis=1)
assert_almost_equal(avg.results.universe.atoms.positions,
reference_coordinates, decimal=4)
assert_allclose(avg.results.universe.atoms.positions,
reference_coordinates, rtol=0, atol=1.5e-4)
assert avg.filename is None


Expand Down
8 changes: 4 additions & 4 deletions testsuite/MDAnalysisTests/analysis/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import numpy as np

from numpy.testing import assert_equal, assert_almost_equal
from numpy.testing import assert_equal, assert_allclose

import MDAnalysis as mda
from MDAnalysis.analysis import base
Expand Down Expand Up @@ -194,7 +194,7 @@ def test_start_stop_step(u, run_kwargs, frames):
assert an.n_frames == len(frames)
assert_equal(an.found_frames, frames)
assert_equal(an.frames, frames, err_msg=FRAMES_ERR)
assert_almost_equal(an.times, frames+1, decimal=4, err_msg=TIMES_ERR)
assert_allclose(an.times, frames+1, rtol=0, atol=1.5e-4, err_msg=TIMES_ERR)


@pytest.mark.parametrize('run_kwargs, frames', [
Expand Down Expand Up @@ -251,7 +251,7 @@ def test_frames_times():
assert an.n_frames == len(frames)
assert_equal(an.found_frames, frames)
assert_equal(an.frames, frames, err_msg=FRAMES_ERR)
assert_almost_equal(an.times, frames*100, decimal=4, err_msg=TIMES_ERR)
assert_allclose(an.times, frames*100, rtol=0, atol=1.5e-4, err_msg=TIMES_ERR)


def test_verbose(u):
Expand Down Expand Up @@ -372,7 +372,7 @@ def test_AnalysisFromFunction_args_content(u):
ans = base.AnalysisFromFunction(mass_xyz, protein, another, masses)
assert len(ans.args) == 3
result = np.sum(ans.run().results.timeseries)
assert_almost_equal(result, -317054.67757345125, decimal=6)
assert_allclose(result, -317054.67757345125, rtol=0, atol=1.5e-6)
assert (ans.args[0] is protein) and (ans.args[1] is another)
assert ans._trajectory is protein.universe.trajectory

Expand Down
23 changes: 13 additions & 10 deletions testsuite/MDAnalysisTests/analysis/test_bat.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from __future__ import absolute_import

import numpy as np
from numpy.testing import assert_equal, assert_almost_equal
from numpy.testing import assert_equal, assert_allclose
import pytest
import copy

Expand Down Expand Up @@ -66,35 +66,38 @@ def test_bat_number_of_frames(self, bat):

def test_bat_coordinates(self, bat):
test_bat = np.load(BATArray)
assert_almost_equal(
assert_allclose(
bat,
test_bat,
5,
rtol=0,
atol=1.5e-5,
err_msg="error: BAT coordinates should match test values")

def test_bat_coordinates_single_frame(self, selected_residues):
bat = BAT(selected_residues).run(start=1, stop=2).results.bat
test_bat = [np.load(BATArray)[1]]
assert_almost_equal(
assert_allclose(
bat,
test_bat,
5,
rtol=0,
atol=1.5e-5,
err_msg="error: BAT coordinates should match test values")

def test_bat_reconstruction(self, selected_residues, bat):
R = BAT(selected_residues)
XYZ = R.Cartesian(bat[0])
assert_almost_equal(XYZ, selected_residues.positions, 5,
assert_allclose(XYZ, selected_residues.positions, rtol=0, atol=1.5e-5,
err_msg="error: Reconstructed Cartesian coordinates " + \
"don't match original")

def test_bat_IO(self, bat_npz, selected_residues, bat):
R2 = BAT(selected_residues, filename=bat_npz)
test_bat = R2.results.bat
assert_almost_equal(
assert_allclose(
bat,
test_bat,
5,
rtol=0,
atol=1.5e-5,
err_msg="error: Loaded BAT coordinates should match test values")

def test_bat_nobonds(self):
Expand Down Expand Up @@ -133,7 +136,7 @@ def test_Cartesian_does_not_modify_input(self, selected_residues, bat):
R = BAT(selected_residues)
pre_transformation = copy.deepcopy(bat[0])
R.Cartesian(bat[0])
assert_almost_equal(
pre_transformation, bat[0],
assert_allclose(
pre_transformation, bat[0], rtol=0, atol=1.5e-7,
err_msg="BAT.Cartesian modified input data"
)
Loading

0 comments on commit 2c1aa4b

Please sign in to comment.