Skip to content

Commit 2c1aa4b

Browse files
authored
Replaced numpy.testing.assert_almost_equal to numpy.testing.assert_allclose (#4438)
* fixes part of #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
1 parent 3a5339c commit 2c1aa4b

File tree

9 files changed

+115
-108
lines changed

9 files changed

+115
-108
lines changed

package/AUTHORS

+2
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ Chronological list of authors
233233
- Lawson Woods
234234
- Johannes Stöckelmaier
235235
- Jenna M. Swarthout Goddard
236+
2024
237+
- Aditya Keshari
236238

237239
External code
238240
-------------

package/CHANGELOG

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The rules for this file:
1515

1616
-------------------------------------------------------------------------------
1717
??/??/?? IAlibay, HeetVekariya, marinegor, lilyminium, RMeli,
18-
ljwoods2
18+
ljwoods2, aditya292002
1919

2020
* 2.8.0
2121

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

4448
Deprecations
4549
* The MDAnalysis.analysis.waterdynamics module has been deprecated in favour

package/MDAnalysis/visualization/streamlines_3D.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ def point_in_cube(array_point_coordinates, list_cube_vertices, cube_centroid):
245245
cube_half_side_length = scipy.spatial.distance.pdist(array_cube_vertices, 'euclidean').min() / 2.0
246246
array_cube_vertex_distances_from_centroid = scipy.spatial.distance.cdist(array_cube_vertices,
247247
cube_centroid[np.newaxis, :])
248-
np.testing.assert_almost_equal(array_cube_vertex_distances_from_centroid.min(),
249-
array_cube_vertex_distances_from_centroid.max(), decimal=4,
248+
np.testing.assert_allclose(array_cube_vertex_distances_from_centroid.min(),
249+
array_cube_vertex_distances_from_centroid.max(), rtol=0, atol=1.5e-4,
250250
err_msg="not all cube vertex to centroid distances are the same, "
251251
"so not a true cube")
252252
absolute_delta_coords = np.absolute(np.subtract(array_point_coordinates, cube_centroid))

testsuite/MDAnalysisTests/analysis/test_align.py

+38-41
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,8 @@
3434
from MDAnalysisTests.datafiles import (PSF, DCD, CRD, FASTA, ALIGN_BOUND,
3535
ALIGN_UNBOUND, PDB_helix)
3636
from numpy.testing import (
37-
assert_almost_equal,
3837
assert_equal,
3938
assert_array_equal,
40-
assert_array_almost_equal,
4139
assert_allclose,
4240
)
4341

@@ -167,7 +165,7 @@ def test_subselection_alignto(self, universe, reference, subselection, expectati
167165

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

172170
def test_no_atom_masses(self, universe):
173171
#if no masses are present
@@ -199,25 +197,25 @@ def test_rmsd(self, universe, reference):
199197
first_frame = bb.positions
200198
universe.trajectory[-1]
201199
last_frame = bb.positions
202-
assert_almost_equal(rms.rmsd(first_frame, first_frame), 0.0, 5,
203-
err_msg="error: rmsd(X,X) should be 0")
200+
assert_allclose(rms.rmsd(first_frame, first_frame), 0.0, rtol=0, atol=1.5e-5,
201+
err_msg="error: rmsd(X,X) should be 0")
204202
# rmsd(A,B) = rmsd(B,A) should be exact but spurious failures in the
205203
# 9th decimal have been observed (see Issue 57 comment #1) so we relax
206204
# the test to 6 decimals.
207205
rmsd = rms.rmsd(first_frame, last_frame, superposition=True)
208-
assert_almost_equal(
209-
rms.rmsd(last_frame, first_frame, superposition=True), rmsd, 6,
206+
assert_allclose(
207+
rms.rmsd(last_frame, first_frame, superposition=True), rmsd, rtol=0, atol=1.5e-6,
210208
err_msg="error: rmsd() is not symmetric")
211-
assert_almost_equal(rmsd, 6.820321761927005, 5,
212-
err_msg="RMSD calculation between 1st and last AdK frame gave wrong answer")
209+
assert_allclose(rmsd, 6.820321761927005, rtol=0, atol=1.5e-5,
210+
err_msg="RMSD calculation between 1st and last AdK frame gave wrong answer")
213211
# test masses as weights
214212
last_atoms_weight = universe.atoms.masses
215213
A = universe.trajectory[0]
216214
B = reference.trajectory[-1]
217215
rmsd = align.alignto(universe, reference, weights='mass')
218216
rmsd_sup_weight = rms.rmsd(A, B, weights=last_atoms_weight, center=True,
219217
superposition=True)
220-
assert_almost_equal(rmsd[1], rmsd_sup_weight, 6)
218+
assert_allclose(rmsd[1], rmsd_sup_weight, rtol=0, atol=1.5e-6)
221219

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

232230
def test_rmsd_custom_weights(self, universe, reference):
233231
weights = np.zeros(universe.atoms.n_atoms)
234232
ca = universe.select_atoms('name CA')
235233
weights[ca.indices] = 1
236234
rmsd = align.alignto(universe, reference, select='name CA')
237235
rmsd_weights = align.alignto(universe, reference, weights=weights)
238-
assert_almost_equal(rmsd[1], rmsd_weights[1], 6)
236+
assert_allclose(rmsd[1], rmsd_weights[1], rtol=0, atol=1.5e-6)
239237

240238
def test_AlignTraj_outfile_default(self, universe, reference, tmpdir):
241239
with tmpdir.as_cwd():
@@ -285,8 +283,8 @@ def test_AlignTraj(self, universe, reference, tmpdir):
285283
x = align.AlignTraj(universe, reference, filename=outfile).run()
286284
fitted = mda.Universe(PSF, outfile)
287285

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

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

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

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

324322
def test_AlignTraj_custom_mass_weights(self, universe, reference, tmpdir):
325323
outfile = str(tmpdir.join('align_test.dcd'))
326324
x = align.AlignTraj(universe, reference,
327325
filename=outfile,
328326
weights=reference.atoms.masses).run()
329327
fitted = mda.Universe(PSF, outfile)
330-
assert_almost_equal(x.results.rmsd[0], 0, decimal=3)
331-
assert_almost_equal(x.results.rmsd[-1], 6.9033, decimal=3)
328+
assert_allclose(x.results.rmsd[0], 0, rtol=0, atol=1.5e-3)
329+
assert_allclose(x.results.rmsd[-1], 6.9033, rtol=0, atol=1.5e-3)
332330

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

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

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

396394
align.alignto(u_free, u_bound, select=selection)
397-
assert_array_almost_equal(segB_bound.positions, segB_free.positions,
398-
decimal=3)
395+
assert_allclose(segB_bound.positions, segB_free.positions,
396+
rtol=0, atol=1.5e-3)
399397

400398

401399
def _get_aligned_average_positions(ref_files, ref, select="all", **kwargs):
@@ -438,31 +436,30 @@ def test_average_structure_deprecated_attrs(self, universe, reference):
438436
def test_average_structure(self, universe, reference):
439437
ref, rmsd = _get_aligned_average_positions(self.ref_files, reference)
440438
avg = align.AverageStructure(universe, reference).run()
441-
assert_almost_equal(avg.results.universe.atoms.positions, ref,
442-
decimal=4)
443-
assert_almost_equal(avg.results.rmsd, rmsd)
439+
assert_allclose(avg.results.universe.atoms.positions, ref, rtol=0, atol=1.5e-4)
440+
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)
444441

445442
def test_average_structure_mass_weighted(self, universe, reference):
446443
ref, rmsd = _get_aligned_average_positions(self.ref_files, reference, weights='mass')
447444
avg = align.AverageStructure(universe, reference, weights='mass').run()
448-
assert_almost_equal(avg.results.universe.atoms.positions, ref,
449-
decimal=4)
450-
assert_almost_equal(avg.results.rmsd, rmsd)
445+
assert_allclose(avg.results.universe.atoms.positions, ref,
446+
rtol=0, atol=1.5e-4)
447+
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)
451448

452449
def test_average_structure_select(self, universe, reference):
453450
select = 'protein and name CA and resid 3-5'
454451
ref, rmsd = _get_aligned_average_positions(self.ref_files, reference, select=select)
455452
avg = align.AverageStructure(universe, reference, select=select).run()
456-
assert_almost_equal(avg.results.universe.atoms.positions, ref,
457-
decimal=4)
458-
assert_almost_equal(avg.results.rmsd, rmsd)
453+
assert_allclose(avg.results.universe.atoms.positions, ref,
454+
rtol=0, atol=1.5e-4)
455+
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)
459456

460457
def test_average_structure_no_ref(self, universe):
461458
ref, rmsd = _get_aligned_average_positions(self.ref_files, universe)
462459
avg = align.AverageStructure(universe).run()
463-
assert_almost_equal(avg.results.universe.atoms.positions, ref,
464-
decimal=4)
465-
assert_almost_equal(avg.results.rmsd, rmsd)
460+
assert_allclose(avg.results.universe.atoms.positions, ref,
461+
rtol=0, atol=1.5e-4)
462+
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)
466463

467464
def test_average_structure_no_msf(self, universe):
468465
avg = align.AverageStructure(universe).run()
@@ -485,15 +482,15 @@ def test_average_structure_ref_frame(self, universe):
485482
universe.trajectory[0]
486483
ref, rmsd = _get_aligned_average_positions(self.ref_files, u)
487484
avg = align.AverageStructure(universe, ref_frame=ref_frame).run()
488-
assert_almost_equal(avg.results.universe.atoms.positions, ref,
489-
decimal=4)
490-
assert_almost_equal(avg.results.rmsd, rmsd)
485+
assert_allclose(avg.results.universe.atoms.positions, ref,
486+
rtol=0, atol=1.5e-4)
487+
assert_allclose(avg.results.rmsd, rmsd, rtol=0, atol=1.5e-7)
491488

492489
def test_average_structure_in_memory(self, universe):
493490
avg = align.AverageStructure(universe, in_memory=True).run()
494491
reference_coordinates = universe.trajectory.timeseries().mean(axis=1)
495-
assert_almost_equal(avg.results.universe.atoms.positions,
496-
reference_coordinates, decimal=4)
492+
assert_allclose(avg.results.universe.atoms.positions,
493+
reference_coordinates, rtol=0, atol=1.5e-4)
497494
assert avg.filename is None
498495

499496

testsuite/MDAnalysisTests/analysis/test_base.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
import numpy as np
2929

30-
from numpy.testing import assert_equal, assert_almost_equal
30+
from numpy.testing import assert_equal, assert_allclose
3131

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

199199

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

256256

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

testsuite/MDAnalysisTests/analysis/test_bat.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from __future__ import absolute_import
2424

2525
import numpy as np
26-
from numpy.testing import assert_equal, assert_almost_equal
26+
from numpy.testing import assert_equal, assert_allclose
2727
import pytest
2828
import copy
2929

@@ -66,35 +66,38 @@ def test_bat_number_of_frames(self, bat):
6666

6767
def test_bat_coordinates(self, bat):
6868
test_bat = np.load(BATArray)
69-
assert_almost_equal(
69+
assert_allclose(
7070
bat,
7171
test_bat,
72-
5,
72+
rtol=0,
73+
atol=1.5e-5,
7374
err_msg="error: BAT coordinates should match test values")
7475

7576
def test_bat_coordinates_single_frame(self, selected_residues):
7677
bat = BAT(selected_residues).run(start=1, stop=2).results.bat
7778
test_bat = [np.load(BATArray)[1]]
78-
assert_almost_equal(
79+
assert_allclose(
7980
bat,
8081
test_bat,
81-
5,
82+
rtol=0,
83+
atol=1.5e-5,
8284
err_msg="error: BAT coordinates should match test values")
8385

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

9193
def test_bat_IO(self, bat_npz, selected_residues, bat):
9294
R2 = BAT(selected_residues, filename=bat_npz)
9395
test_bat = R2.results.bat
94-
assert_almost_equal(
96+
assert_allclose(
9597
bat,
9698
test_bat,
97-
5,
99+
rtol=0,
100+
atol=1.5e-5,
98101
err_msg="error: Loaded BAT coordinates should match test values")
99102

100103
def test_bat_nobonds(self):
@@ -133,7 +136,7 @@ def test_Cartesian_does_not_modify_input(self, selected_residues, bat):
133136
R = BAT(selected_residues)
134137
pre_transformation = copy.deepcopy(bat[0])
135138
R.Cartesian(bat[0])
136-
assert_almost_equal(
137-
pre_transformation, bat[0],
139+
assert_allclose(
140+
pre_transformation, bat[0], rtol=0, atol=1.5e-7,
138141
err_msg="BAT.Cartesian modified input data"
139142
)

0 commit comments

Comments
 (0)