From b8fe34b73c9df9330c1608229b2f8cddc6e275b4 Mon Sep 17 00:00:00 2001 From: Rocco Meli Date: Tue, 31 Dec 2024 05:20:55 +0100 Subject: [PATCH] [fmt] utils, import, viz tests (#4875) --- .../MDAnalysisTests/import/fork_called.py | 3 +- .../MDAnalysisTests/import/test_import.py | 17 +- .../MDAnalysisTests/utils/test_authors.py | 5 +- .../MDAnalysisTests/utils/test_datafiles.py | 35 +- .../MDAnalysisTests/utils/test_duecredit.py | 104 +++-- .../MDAnalysisTests/utils/test_failure.py | 11 +- .../MDAnalysisTests/utils/test_imports.py | 22 +- testsuite/MDAnalysisTests/utils/test_log.py | 7 +- testsuite/MDAnalysisTests/utils/test_meta.py | 40 +- .../MDAnalysisTests/utils/test_modelling.py | 175 +++++--- .../MDAnalysisTests/utils/test_persistence.py | 27 +- .../MDAnalysisTests/utils/test_pickleio.py | 123 +++--- .../MDAnalysisTests/utils/test_qcprot.py | 113 +++-- .../MDAnalysisTests/utils/test_selections.py | 107 +++-- .../MDAnalysisTests/utils/test_streamio.py | 223 ++++++---- .../utils/test_transformations.py | 391 +++++++++++------- testsuite/MDAnalysisTests/utils/test_units.py | 138 ++++--- .../visualization/test_streamlines.py | 136 +++--- testsuite/pyproject.toml | 3 + 19 files changed, 1068 insertions(+), 612 deletions(-) diff --git a/testsuite/MDAnalysisTests/import/fork_called.py b/testsuite/MDAnalysisTests/import/fork_called.py index 823f122a4e..5bfb6b390f 100644 --- a/testsuite/MDAnalysisTests/import/fork_called.py +++ b/testsuite/MDAnalysisTests/import/fork_called.py @@ -26,6 +26,7 @@ """Tests whether os.fork() is called as a side effect when importing MDAnalysis. See PR #1794 for details.""" -with mock.patch('os.fork') as os_dot_fork: +with mock.patch("os.fork") as os_dot_fork: import MDAnalysis + assert not os_dot_fork.called diff --git a/testsuite/MDAnalysisTests/import/test_import.py b/testsuite/MDAnalysisTests/import/test_import.py index d8065f4ac1..9794b716ef 100644 --- a/testsuite/MDAnalysisTests/import/test_import.py +++ b/testsuite/MDAnalysisTests/import/test_import.py @@ -27,8 +27,10 @@ """Test if importing MDAnalysis has unwanted side effects (PR #1794).""" -@pytest.mark.skipif(os.name == 'nt', - reason="fork-related import checks irrelevant on Windows") + +@pytest.mark.skipif( + os.name == "nt", reason="fork-related import checks irrelevant on Windows" +) class TestMDAImport(object): # Tests concerning importing MDAnalysis. def test_os_dot_fork_not_called(self): @@ -37,7 +39,7 @@ def test_os_dot_fork_not_called(self): # no previously imported modules interfere with it. It is therefore # offloaded to the script "fork_called.py". loc = os.path.dirname(os.path.realpath(__file__)) - script = os.path.join(loc, 'fork_called.py') + script = os.path.join(loc, "fork_called.py") encoding = sys.stdout.encoding if encoding is None: encoding = "utf-8" @@ -47,16 +49,17 @@ def test_os_dot_fork_not_called(self): # CalledProcessError. That error's output member then contains the # failed script's stderr and we can print it: try: - out = subprocess.check_output([sys.executable, script], - stderr=subprocess.STDOUT)\ - .decode(encoding) + out = subprocess.check_output( + [sys.executable, script], stderr=subprocess.STDOUT + ).decode(encoding) except subprocess.CalledProcessError as err: print(err.output) - raise(err) + raise (err) def test_os_dot_fork_not_none(self): # In MDAnalysis.core.universe, os.fork is set to None prior to importing # the uuid module and restored afterwards (see PR #1794 for details). # This tests asserts that os.fork has been restored. import MDAnalysis + assert os.fork is not None diff --git a/testsuite/MDAnalysisTests/utils/test_authors.py b/testsuite/MDAnalysisTests/utils/test_authors.py index 7e1a69960d..13563dadfd 100644 --- a/testsuite/MDAnalysisTests/utils/test_authors.py +++ b/testsuite/MDAnalysisTests/utils/test_authors.py @@ -24,5 +24,8 @@ import MDAnalysis + def test_package_authors(): - assert len(MDAnalysis.__authors__) > 0, 'Could not find the list of authors' + assert ( + len(MDAnalysis.__authors__) > 0 + ), "Could not find the list of authors" diff --git a/testsuite/MDAnalysisTests/utils/test_datafiles.py b/testsuite/MDAnalysisTests/utils/test_datafiles.py index 92caf2348f..7b79bb8640 100644 --- a/testsuite/MDAnalysisTests/utils/test_datafiles.py +++ b/testsuite/MDAnalysisTests/utils/test_datafiles.py @@ -29,10 +29,10 @@ def test_failed_import(monkeypatch): # Putting this test first to avoid datafiles already being loaded errmsg = "MDAnalysisTests package not installed." - monkeypatch.setitem(sys.modules, 'MDAnalysisTests.datafiles', None) + monkeypatch.setitem(sys.modules, "MDAnalysisTests.datafiles", None) - if 'MDAnalysis.tests.datafiles' in sys.modules: - monkeypatch.delitem(sys.modules, 'MDAnalysis.tests.datafiles') + if "MDAnalysis.tests.datafiles" in sys.modules: + monkeypatch.delitem(sys.modules, "MDAnalysis.tests.datafiles") with pytest.raises(ImportError, match=errmsg): import MDAnalysis.tests.datafiles @@ -42,20 +42,35 @@ def test_import(): try: import MDAnalysis.tests.datafiles except ImportError: - pytest.fail("Failed to 'import MDAnalysis.tests.datafiles --- install MDAnalysisTests") + pytest.fail( + "Failed to 'import MDAnalysis.tests.datafiles --- install MDAnalysisTests" + ) def test_all_exports(): import MDAnalysisTests.datafiles - missing = [name for name in dir(MDAnalysisTests.datafiles) - if - not name.startswith('_') and name not in MDAnalysisTests.datafiles.__all__ and name != 'MDAnalysisTests'] + + missing = [ + name + for name in dir(MDAnalysisTests.datafiles) + if not name.startswith("_") + and name not in MDAnalysisTests.datafiles.__all__ + and name != "MDAnalysisTests" + ] assert_equal(missing, [], err_msg="Variables need to be added to __all__.") def test_export_variables(): import MDAnalysisTests.datafiles import MDAnalysis.tests.datafiles - missing = [name for name in MDAnalysisTests.datafiles.__all__ - if name not in dir(MDAnalysis.tests.datafiles)] - assert_equal(missing, [], err_msg="Variables not exported to MDAnalysis.tests.datafiles") + + missing = [ + name + for name in MDAnalysisTests.datafiles.__all__ + if name not in dir(MDAnalysis.tests.datafiles) + ] + assert_equal( + missing, + [], + err_msg="Variables not exported to MDAnalysis.tests.datafiles", + ) diff --git a/testsuite/MDAnalysisTests/utils/test_duecredit.py b/testsuite/MDAnalysisTests/utils/test_duecredit.py index d567d256f5..f0224a9a73 100644 --- a/testsuite/MDAnalysisTests/utils/test_duecredit.py +++ b/testsuite/MDAnalysisTests/utils/test_duecredit.py @@ -35,48 +35,68 @@ # duecredit itself is not needed in the name space but this is a # convenient way to skip all tests if duecredit is not installed # (see https://github.com/MDAnalysis/mdanalysis/issues/1906) -pytest.importorskip('duecredit') +pytest.importorskip("duecredit") -@pytest.mark.skipif((os.environ.get('DUECREDIT_ENABLE', 'yes').lower() - in ('no', '0', 'false')), - reason= - "duecredit is explicitly disabled with DUECREDIT_ENABLE=no") + +@pytest.mark.skipif( + ( + os.environ.get("DUECREDIT_ENABLE", "yes").lower() + in ("no", "0", "false") + ), + reason="duecredit is explicitly disabled with DUECREDIT_ENABLE=no", +) class TestDuecredit(object): def test_duecredit_active(self): assert mda.due.active == True - @pytest.mark.parametrize("module,path,citekey", [ - ("MDAnalysis", "MDAnalysis", "10.25080/majora-629e541a-00e"), - ("MDAnalysis", "MDAnalysis", "10.1002/jcc.21787"), - ]) + @pytest.mark.parametrize( + "module,path,citekey", + [ + ("MDAnalysis", "MDAnalysis", "10.25080/majora-629e541a-00e"), + ("MDAnalysis", "MDAnalysis", "10.1002/jcc.21787"), + ], + ) def test_duecredit_collector_primary(self, module, path, citekey): assert mda.due.citations[(path, citekey)].cites_module == True # note: citekeys are *all lower case* - @pytest.mark.parametrize("module,path,citekey", [ - ("MDAnalysis.analysis.psa", - "pathsimanalysis.psa", - "10.1371/journal.pcbi.1004568"), - ("MDAnalysis.analysis.hydrogenbonds.hbond_autocorrel", - "MDAnalysis.analysis.hydrogenbonds.hbond_autocorrel", - "10.1063/1.4922445"), - ("MDAnalysis.analysis.leaflet", - "MDAnalysis.analysis.leaflet", - "10.1002/jcc.21787"), - ("MDAnalysis.lib.qcprot", - "MDAnalysis.lib.qcprot", - "10.1107/s0108767305015266"), - ("MDAnalysis.lib.qcprot", - "MDAnalysis.lib.qcprot", - "qcprot2"), - ("MDAnalysis.analysis.encore", - "MDAnalysis.analysis.encore", - "10.1371/journal.pcbi.1004415"), - ("MDAnalysis.analysis.dssp", - "MDAnalysis.analysis.dssp", - "10.1002/bip.360221211") - ]) + @pytest.mark.parametrize( + "module,path,citekey", + [ + ( + "MDAnalysis.analysis.psa", + "pathsimanalysis.psa", + "10.1371/journal.pcbi.1004568", + ), + ( + "MDAnalysis.analysis.hydrogenbonds.hbond_autocorrel", + "MDAnalysis.analysis.hydrogenbonds.hbond_autocorrel", + "10.1063/1.4922445", + ), + ( + "MDAnalysis.analysis.leaflet", + "MDAnalysis.analysis.leaflet", + "10.1002/jcc.21787", + ), + ( + "MDAnalysis.lib.qcprot", + "MDAnalysis.lib.qcprot", + "10.1107/s0108767305015266", + ), + ("MDAnalysis.lib.qcprot", "MDAnalysis.lib.qcprot", "qcprot2"), + ( + "MDAnalysis.analysis.encore", + "MDAnalysis.analysis.encore", + "10.1371/journal.pcbi.1004415", + ), + ( + "MDAnalysis.analysis.dssp", + "MDAnalysis.analysis.dssp", + "10.1002/bip.360221211", + ), + ], + ) def test_duecredit_collector_analysis_modules(self, module, path, citekey): importlib.import_module(module) assert mda.due.citations[(path, citekey)].cites_module == True @@ -85,17 +105,21 @@ def test_duecredit_mmtf(self): # doesn't trigger on import but on use of either parser or reader u = mda.Universe(MMTF) - assert mda.due.citations[('MDAnalysis.coordinates.MMTF', - '10.1371/journal.pcbi.1005575')].cites_module - assert mda.due.citations[('MDAnalysis.topology.MMTFParser', - '10.1371/journal.pcbi.1005575')].cites_module + assert mda.due.citations[ + ("MDAnalysis.coordinates.MMTF", "10.1371/journal.pcbi.1005575") + ].cites_module + assert mda.due.citations[ + ("MDAnalysis.topology.MMTFParser", "10.1371/journal.pcbi.1005575") + ].cites_module @pytest.mark.skipif(not HAS_H5PY, reason="h5py not installed") def test_duecredit_h5md(self): # doesn't trigger on import but on use of either reader or writer u = mda.Universe(TPR_xvf, H5MD_xvf) - assert mda.due.citations[('MDAnalysis.coordinates.H5MD', - '10.25080/majora-1b6fd038-005')].cites_module - assert mda.due.citations[('MDAnalysis.coordinates.H5MD', - '10.1016/j.cpc.2014.01.018')].cites_module + assert mda.due.citations[ + ("MDAnalysis.coordinates.H5MD", "10.25080/majora-1b6fd038-005") + ].cites_module + assert mda.due.citations[ + ("MDAnalysis.coordinates.H5MD", "10.1016/j.cpc.2014.01.018") + ].cites_module diff --git a/testsuite/MDAnalysisTests/utils/test_failure.py b/testsuite/MDAnalysisTests/utils/test_failure.py index b1ec9f1e86..494e84cdb9 100644 --- a/testsuite/MDAnalysisTests/utils/test_failure.py +++ b/testsuite/MDAnalysisTests/utils/test_failure.py @@ -24,9 +24,10 @@ def test_failure(): - """Fail if the MDA_FAILURE_TEST environment variable is set. - """ - if u'MDA_FAILURE_TEST' in os.environ: + """Fail if the MDA_FAILURE_TEST environment variable is set.""" + if "MDA_FAILURE_TEST" in os.environ: # Have a file open to trigger an output from the open_files plugin. - f = open('./failure.txt', 'w') - raise AssertionError("the MDA_FAILURE_TEST environment variable is set") + f = open("./failure.txt", "w") + raise AssertionError( + "the MDA_FAILURE_TEST environment variable is set" + ) diff --git a/testsuite/MDAnalysisTests/utils/test_imports.py b/testsuite/MDAnalysisTests/utils/test_imports.py index bd343e2b99..016388e324 100644 --- a/testsuite/MDAnalysisTests/utils/test_imports.py +++ b/testsuite/MDAnalysisTests/utils/test_imports.py @@ -29,11 +29,11 @@ path_to_testing_modules = MDAnalysisTests.__path__[0] # Exclusion path relative to MDAnalysisTests -exclusions = ['/plugins', '/data'] +exclusions = ["/plugins", "/data"] def is_excluded(path): - leaf = path[len(path_to_testing_modules):] + leaf = path[len(path_to_testing_modules) :] return leaf in exclusions @@ -42,7 +42,7 @@ def get_file_paths(): for dirpath, dirnames, files in os.walk(path_to_testing_modules): if is_excluded(dirpath): continue - for f in filter(lambda x: x.endswith('.py'), files): + for f in filter(lambda x: x.endswith(".py"), files): fpath = os.path.join(dirpath, f) if is_excluded(fpath): continue @@ -50,12 +50,18 @@ def get_file_paths(): return paths -@pytest.mark.parametrize('testing_module', get_file_paths()) +@pytest.mark.parametrize("testing_module", get_file_paths()) def test_relative_import(testing_module): - with open(testing_module, 'r') as test_module_file_object: + with open(testing_module, "r") as test_module_file_object: for lineno, line in enumerate(test_module_file_object, start=1): - if 'from .' in line and 'import' in line \ - and not 'test_imports' in testing_module: + if ( + "from ." in line + and "import" in line + and not "test_imports" in testing_module + ): raise AssertionError( "A relative import statement was found in " - "module {testing_module} at linenumber {lineno}.".format(**vars())) + "module {testing_module} at linenumber {lineno}.".format( + **vars() + ) + ) diff --git a/testsuite/MDAnalysisTests/utils/test_log.py b/testsuite/MDAnalysisTests/utils/test_log.py index 2e95edb39b..0abaed2795 100644 --- a/testsuite/MDAnalysisTests/utils/test_log.py +++ b/testsuite/MDAnalysisTests/utils/test_log.py @@ -68,5 +68,8 @@ def buffer(): def _assert_in(output, string): - assert string in output, "Output '{0}' does not match required format '{1}'.".format(output.replace('\r', '\\r'), string.replace('\r', '\\r')) - + assert ( + string in output + ), "Output '{0}' does not match required format '{1}'.".format( + output.replace("\r", "\\r"), string.replace("\r", "\\r") + ) diff --git a/testsuite/MDAnalysisTests/utils/test_meta.py b/testsuite/MDAnalysisTests/utils/test_meta.py index def0a35e74..b6e536ef00 100644 --- a/testsuite/MDAnalysisTests/utils/test_meta.py +++ b/testsuite/MDAnalysisTests/utils/test_meta.py @@ -24,33 +24,47 @@ import MDAnalysisTests + def test_import(): try: import MDAnalysis except ImportError: - raise AssertionError('Failed to import module MDAnalysis. Install MDAnalysis' - 'first to run the tests, e.g. "pip install mdanalysis"') + raise AssertionError( + "Failed to import module MDAnalysis. Install MDAnalysis" + 'first to run the tests, e.g. "pip install mdanalysis"' + ) def test_matching_versions(): import MDAnalysis.version - assert MDAnalysis.version.__version__ == MDAnalysisTests.__version__, \ - "MDAnalysis release {0} must be installed to have meaningful tests, not {1}".format( - MDAnalysisTests.__version__, MDAnalysis.__version__) + + assert ( + MDAnalysis.version.__version__ == MDAnalysisTests.__version__ + ), "MDAnalysis release {0} must be installed to have meaningful tests, not {1}".format( + MDAnalysisTests.__version__, MDAnalysis.__version__ + ) def test_version_format(version=None): if version is None: import MDAnalysis.version + version = MDAnalysis.version.__version__ # see https://github.com/MDAnalysis/mdanalysis/wiki/SemanticVersioning for format definition - m = re.match(r'(?P\d+)\.(?P\d+)\.(?P\d+)(-(?P\w+))?$', - version) - assert m, "version {0} does not match the MAJOR.MINOR.PATCH(-suffix) format".format(version) + m = re.match( + r"(?P\d+)\.(?P\d+)\.(?P\d+)(-(?P\w+))?$", + version, + ) + assert ( + m + ), "version {0} does not match the MAJOR.MINOR.PATCH(-suffix) format".format( + version + ) def test_version_at_packagelevel(): import MDAnalysis + try: version = MDAnalysis.__version__ except: @@ -61,24 +75,24 @@ def test_version_at_packagelevel(): # The following allow testing of the memleak tester plugin. # Keep commented out unless you suspect the plugin # might be misbehaving. Apparently python3 is immune to these leaks!""" -#from numpy.testing import TestCase -#class A(): +# from numpy.testing import TestCase +# class A(): # """This is a small leaky class that won't break anything.""" # def __init__(self): # self.self_ref = self # def __del__(self): # pass # -#def test_that_memleaks(): +# def test_that_memleaks(): # """Test that memleaks (Issue 323)""" # a = A() # -#class TestML1(TestCase): +# class TestML1(TestCase): # def test_that_memleaks(self): # """Test that memleaks (Issue 323)""" # self.a = A() # -#class TestML2(TestCase): +# class TestML2(TestCase): # def setUp(self): # a = A() # def test_that_memleaks(self): diff --git a/testsuite/MDAnalysisTests/utils/test_modelling.py b/testsuite/MDAnalysisTests/utils/test_modelling.py index bae825da3a..c014c9f4d0 100644 --- a/testsuite/MDAnalysisTests/utils/test_modelling.py +++ b/testsuite/MDAnalysisTests/utils/test_modelling.py @@ -32,7 +32,7 @@ capping_nma, merge_protein, merge_ligand, - merge_water + merge_water, ) import MDAnalysis.core.groups from MDAnalysis.core.groups import AtomGroup @@ -55,22 +55,39 @@ def capping(ref, ace, nma, output): # TODO pick the first residue in the protein (how should we cap the chains?) # TODO consider a case when the protein resid is 1 and all peptide has to be shifted by +1, put that in docs as a # post-processing step - alignto(ace, ref, select={ + alignto( + ace, + ref, + select={ "mobile": "resid {0} and backbone".format(resid_min), - "reference": "resid {0} and backbone".format(resid_min)}, - strict=True) - alignto(nma, ref, select={ - "mobile": "resid {0} and backbone and not (resname NMA NME)".format(resid_max), - "reference": "resid {0} and (backbone or name OT2)".format(resid_max)}, - strict=True) + "reference": "resid {0} and backbone".format(resid_min), + }, + strict=True, + ) + alignto( + nma, + ref, + select={ + "mobile": "resid {0} and backbone and not (resname NMA NME)".format( + resid_max + ), + "reference": "resid {0} and (backbone or name OT2)".format( + resid_max + ), + }, + strict=True, + ) # TODO remove the Hydrogen closest to ACE's oxygen nma.residues.resids = 16 - u = Merge(ace.select_atoms("resname ACE"), - ref.select_atoms( - "not (resid {0} and name HT*) and not (resid {1} and (name HT* OT1))" - "".format(resid_min, resid_max)), - nma.select_atoms("resname NME NMA")) + u = Merge( + ace.select_atoms("resname ACE"), + ref.select_atoms( + "not (resid {0} and name HT*) and not (resid {1} and (name HT* OT1))" + "".format(resid_min, resid_max) + ), + nma.select_atoms("resname NME NMA"), + ) u.trajectory.ts.dimensions = ref.trajectory.ts.dimensions u.atoms.write(output) return u @@ -84,11 +101,13 @@ def test_capping_file(self, tmpdir): ace = MDAnalysis.Universe(capping_ace) nma = MDAnalysis.Universe(capping_nma) - outfile = str(tmpdir.join('test.pdb')) + outfile = str(tmpdir.join("test.pdb")) u = capping(peptide, ace, nma, outfile) - assert_equal(len(u.select_atoms("not name H*")), - len(ref.select_atoms("not name H*"))) + assert_equal( + len(u.select_atoms("not name H*")), + len(ref.select_atoms("not name H*")), + ) u = MDAnalysis.Universe(outfile) @@ -99,8 +118,9 @@ def test_capping_file(self, tmpdir): assert_equal(ace.resids[0], 1) assert_equal(nma.resids[0], 16) - assert_array_equal(peptide.trajectory.ts.dimensions, - u.trajectory.ts.dimensions) + assert_array_equal( + peptide.trajectory.ts.dimensions, u.trajectory.ts.dimensions + ) def test_capping_inmemory(self, tmpdir): peptide = MDAnalysis.Universe(capping_input) @@ -108,10 +128,12 @@ def test_capping_inmemory(self, tmpdir): ace = MDAnalysis.Universe(capping_ace) nma = MDAnalysis.Universe(capping_nma) - outfile = str(tmpdir.join('test.pdb')) + outfile = str(tmpdir.join("test.pdb")) u = capping(peptide, ace, nma, outfile) - assert_equal(len(u.select_atoms("not name H*")), - len(ref.select_atoms("not name H*"))) + assert_equal( + len(u.select_atoms("not name H*")), + len(ref.select_atoms("not name H*")), + ) ace = u.select_atoms("resname ACE") nma = u.select_atoms("resname NMA") @@ -120,8 +142,9 @@ def test_capping_inmemory(self, tmpdir): assert_equal(ace.resids[0], 1) assert_equal(nma.resids[0], 16) - assert_array_equal(peptide.trajectory.ts.dimensions, - u.trajectory.ts.dimensions) + assert_array_equal( + peptide.trajectory.ts.dimensions, u.trajectory.ts.dimensions + ) @pytest.fixture() @@ -138,6 +161,7 @@ def u_ligand(): def u_water(): return MDAnalysis.Universe(merge_water) + @pytest.fixture() def u_without_coords(): return MDAnalysis.Universe(PSF) @@ -145,18 +169,35 @@ def u_without_coords(): class TestMerge(object): def test_merge(self, u_protein, u_ligand, u_water, tmpdir): - ids_before = [a.index for u in [u_protein, u_ligand, u_water] for a in u.atoms] + ids_before = [ + a.index for u in [u_protein, u_ligand, u_water] for a in u.atoms + ] # Do the merge u0 = MDAnalysis.Merge(u_protein.atoms, u_ligand.atoms, u_water.atoms) # Check that the output Universe has the same number of atoms as the # starting AtomGroups - assert_equal(len(u0.atoms), (len(u_protein.atoms) + len(u_ligand.atoms) + len(u_water.atoms))) + assert_equal( + len(u0.atoms), + (len(u_protein.atoms) + len(u_ligand.atoms) + len(u_water.atoms)), + ) # Check that the output Universe has the same number of residues and # segments as the starting AtomGroups - assert_equal(len(u0.residues), (len(u_protein.residues) + len(u_ligand.residues) + - len(u_water.residues))) - assert_equal(len(u0.segments), (len(u_protein.segments) + len(u_ligand.segments) + - len(u_water.segments))) + assert_equal( + len(u0.residues), + ( + len(u_protein.residues) + + len(u_ligand.residues) + + len(u_water.residues) + ), + ) + assert_equal( + len(u0.segments), + ( + len(u_protein.segments) + + len(u_ligand.segments) + + len(u_water.segments) + ), + ) # Make sure that all the atoms in the new universe are assigned to only # one, new Universe @@ -167,15 +208,20 @@ def test_merge(self, u_protein, u_ligand, u_water, tmpdir): # Make sure that the atom ids of the original universes are unchanged, # ie we didn't make the original Universes 'dirty' - ids_after = [a.index for u in [u_protein, u_ligand, u_water] for a in u.atoms] - assert_equal(len(ids_after), (len(u_protein.atoms) + len(u_ligand.atoms) + len(u_water.atoms))) + ids_after = [ + a.index for u in [u_protein, u_ligand, u_water] for a in u.atoms + ] + assert_equal( + len(ids_after), + (len(u_protein.atoms) + len(u_ligand.atoms) + len(u_water.atoms)), + ) assert_equal(ids_before, ids_after) # Test that we have a same number of atoms in a different way ids_new = [a.index for a in u0.atoms] assert_equal(len(ids_new), len(ids_before)) - outfile = str(tmpdir.join('test.pdb')) + outfile = str(tmpdir.join("test.pdb")) u0.atoms.write(outfile) u = MDAnalysis.Universe(outfile) @@ -183,20 +229,28 @@ def test_merge(self, u_protein, u_ligand, u_water, tmpdir): assert_equal(ids_new, ids_new2) def test_merge_same_universe(self, u_protein): - u0 = MDAnalysis.Merge(u_protein.atoms, u_protein.atoms, u_protein.atoms) + u0 = MDAnalysis.Merge( + u_protein.atoms, u_protein.atoms, u_protein.atoms + ) assert_equal(len(u0.atoms), 3 * len(u_protein.atoms)) assert_equal(len(u0.residues), 3 * len(u_protein.residues)) assert_equal(len(u0.segments), 3 * len(u_protein.segments)) def test_residue_references(self, u_protein, u_ligand): m = Merge(u_protein.atoms, u_ligand.atoms) - assert_equal(m.atoms.residues[0].universe, m, - "wrong universe reference for residues after Merge()") + assert_equal( + m.atoms.residues[0].universe, + m, + "wrong universe reference for residues after Merge()", + ) def test_segment_references(self, u_protein, u_ligand): m = Merge(u_protein.atoms, u_ligand.atoms) - assert_equal(m.atoms.segments[0].universe, m, - "wrong universe reference for segments after Merge()") + assert_equal( + m.atoms.segments[0].universe, + m, + "wrong universe reference for segments after Merge()", + ) def test_empty_ValueError(self): with pytest.raises(ValueError): @@ -204,7 +258,7 @@ def test_empty_ValueError(self): def test_nonsense_TypeError(self): with pytest.raises(TypeError): - Merge(['1', 2]) + Merge(["1", 2]) def test_emptyAG_ValueError(self, u_protein): a = AtomGroup([], u_protein) @@ -215,8 +269,8 @@ def test_emptyAG_ValueError(self, u_protein): def test_merge_without_coords(self, u_without_coords): subset = MDAnalysis.Merge(u_without_coords.atoms[:10]) - assert(isinstance(subset, MDAnalysis.Universe)) - assert_equal(len(subset.atoms) , 10) + assert isinstance(subset, MDAnalysis.Universe) + assert_equal(len(subset.atoms), 10) class TestMergeTopology(object): @@ -233,36 +287,45 @@ def test_merge_with_topology(self, u): u_merge = MDAnalysis.Merge(ag1, ag2) - assert(len(u_merge.atoms) == 30) - assert(len(u_merge.atoms.bonds) == 28) - assert(len(u_merge.atoms.angles) == 47) - assert(len(u_merge.atoms.dihedrals) == 53) - assert(len(u_merge.atoms.impropers) == 1) + assert len(u_merge.atoms) == 30 + assert len(u_merge.atoms.bonds) == 28 + assert len(u_merge.atoms.angles) == 47 + assert len(u_merge.atoms.dihedrals) == 53 + assert len(u_merge.atoms.impropers) == 1 # All these bonds are in the merged Universe - assert(len(ag1[0].bonds) == len(u_merge.atoms[0].bonds)) + assert len(ag1[0].bonds) == len(u_merge.atoms[0].bonds) # One of these bonds isn't in the merged Universe - assert(len(ag2[0].bonds) - 1 == len(u_merge.atoms[20].bonds)) + assert len(ag2[0].bonds) - 1 == len(u_merge.atoms[20].bonds) def test_merge_with_topology_from_different_universes(self, u, u_ligand): u_merge = MDAnalysis.Merge(u.atoms[:110], u_ligand.atoms) # merge_protein doesn't contain bond topology, so merged universe # shouldn't have one either - assert not hasattr(u_merge.atoms, 'bonds') + assert not hasattr(u_merge.atoms, "bonds") # PDB reader yields empty Bonds group, which means bonds from # PSF/DCD survive the merge # assert(not hasattr(u_merge.atoms, 'bonds') or len(u_merge.atoms.bonds) == 0) - assert(not hasattr(u_merge.atoms, 'angles') or len(u_merge.atoms.bonds) == 0) - assert(not hasattr(u_merge.atoms, 'dihedrals') or len(u_merge.atoms.bonds) == 0) - assert(not hasattr(u_merge.atoms, 'impropers') or len(u_merge.atoms.bonds) == 0) + assert ( + not hasattr(u_merge.atoms, "angles") + or len(u_merge.atoms.bonds) == 0 + ) + assert ( + not hasattr(u_merge.atoms, "dihedrals") + or len(u_merge.atoms.bonds) == 0 + ) + assert ( + not hasattr(u_merge.atoms, "impropers") + or len(u_merge.atoms.bonds) == 0 + ) def test_merge_without_topology(self, u): # This shouldn't have topology as we merged single atoms u_merge = MDAnalysis.Merge(u.atoms[0:1], u.atoms[10:11]) - assert(len(u_merge.atoms) == 2) - assert(len(u_merge.atoms.bonds) == 0) - assert(len(u_merge.atoms.angles) == 0) - assert(len(u_merge.atoms.dihedrals) == 0) - assert(len(u_merge.atoms.impropers) == 0) + assert len(u_merge.atoms) == 2 + assert len(u_merge.atoms.bonds) == 0 + assert len(u_merge.atoms.angles) == 0 + assert len(u_merge.atoms.dihedrals) == 0 + assert len(u_merge.atoms.impropers) == 0 diff --git a/testsuite/MDAnalysisTests/utils/test_persistence.py b/testsuite/MDAnalysisTests/utils/test_persistence.py index c2c00e7396..ca9ca19e6e 100644 --- a/testsuite/MDAnalysisTests/utils/test_persistence.py +++ b/testsuite/MDAnalysisTests/utils/test_persistence.py @@ -24,10 +24,7 @@ import pickle import MDAnalysis as mda -from numpy.testing import ( - TestCase, - assert_equal -) +from numpy.testing import TestCase, assert_equal import gc @@ -89,24 +86,22 @@ def test_pickle_unpickle_empty(self, universe): def test_unpickle_two_ag(self, pickle_str_two_ag): newag, newag2 = pickle.loads(pickle_str_two_ag) - assert newag.universe is newag2.universe, ( - "Two AtomGroups are unpickled to two different Universes" - ) + assert ( + newag.universe is newag2.universe + ), "Two AtomGroups are unpickled to two different Universes" - def test_unpickle_ag_with_universe_f(self, - pickle_str_ag_with_universe_f): + def test_unpickle_ag_with_universe_f(self, pickle_str_ag_with_universe_f): newu, newag = pickle.loads(pickle_str_ag_with_universe_f) assert newag.universe is newu, ( "AtomGroup is not unpickled to the bound Universe" "when Universe is pickled first" ) - def test_unpickle_ag_with_universe(self, - pickle_str_ag_with_universe): + def test_unpickle_ag_with_universe(self, pickle_str_ag_with_universe): newag, newu = pickle.loads(pickle_str_ag_with_universe) assert newag.universe is newu, ( - "AtomGroup is not unpickled to the bound Universe" - "when AtomGroup is pickled first" + "AtomGroup is not unpickled to the bound Universe" + "when AtomGroup is pickled first" ) @@ -119,15 +114,15 @@ def u(): def test_pickling_uag(self, u): ag = u.atoms[:100] - uag = ag.select_atoms('name C', updating=True) + uag = ag.select_atoms("name C", updating=True) pickle_str = pickle.dumps(uag, protocol=pickle.HIGHEST_PROTOCOL) new_uag = pickle.loads(pickle_str) assert_equal(uag.indices, new_uag.indices) def test_pickling_uag_of_uag(self, u): - uag1 = u.select_atoms('name C or name H', updating=True) - uag2 = uag1.select_atoms('name C', updating=True) + uag1 = u.select_atoms("name C or name H", updating=True) + uag2 = uag1.select_atoms("name C", updating=True) pickle_str = pickle.dumps(uag2, protocol=pickle.HIGHEST_PROTOCOL) new_uag2 = pickle.loads(pickle_str) diff --git a/testsuite/MDAnalysisTests/utils/test_pickleio.py b/testsuite/MDAnalysisTests/utils/test_pickleio.py index 64dc6a9a66..ae6c342cec 100644 --- a/testsuite/MDAnalysisTests/utils/test_pickleio.py +++ b/testsuite/MDAnalysisTests/utils/test_pickleio.py @@ -36,25 +36,16 @@ bz2_pickle_open, gzip_pickle_open, ) -from MDAnalysis.coordinates.GSD import ( - GSDPicklable, - gsd_pickle_open, - HAS_GSD -) +from MDAnalysis.coordinates.GSD import GSDPicklable, gsd_pickle_open, HAS_GSD from MDAnalysis.coordinates.TRJ import ( NCDFPicklable, ) -from MDAnalysis.coordinates.chemfiles import ( - check_chemfiles_version -) +from MDAnalysis.coordinates.chemfiles import check_chemfiles_version + if check_chemfiles_version(): - from MDAnalysis.coordinates.chemfiles import ( - ChemfilesPicklable - ) + from MDAnalysis.coordinates.chemfiles import ChemfilesPicklable from MDAnalysis.coordinates.H5MD import HAS_H5PY -from MDAnalysis.coordinates.H5MD import ( - H5PYPicklable -) +from MDAnalysis.coordinates.H5MD import H5PYPicklable from MDAnalysis.tests.datafiles import ( PDB, @@ -65,17 +56,19 @@ GSD, NCDF, TPR_xvf, - H5MD_xvf + H5MD_xvf, ) -@pytest.fixture(params=[ - # filename mode - (PDB, 'r'), - (PDB, 'rt'), - (XYZ_bz2, 'rt'), - (GMS_ASYMOPT, 'rt') -]) +@pytest.fixture( + params=[ + # filename mode + (PDB, "r"), + (PDB, "rt"), + (XYZ_bz2, "rt"), + (GMS_ASYMOPT, "rt"), + ] +) def f_text(request): filename, mode = request.param return anyopen(filename, mode) @@ -96,12 +89,14 @@ def test_offset_text_same(f_text): assert_equal(f_text_pickled.tell(), f_text.tell()) -@pytest.fixture(params=[ - # filename mode ref_class - (PDB, 'rb', BufferIOPicklable), - (XYZ_bz2, 'rb', BZ2Picklable), - (MMTF_gz, 'rb', GzipPicklable) -]) +@pytest.fixture( + params=[ + # filename mode ref_class + (PDB, "rb", BufferIOPicklable), + (XYZ_bz2, "rb", BZ2Picklable), + (MMTF_gz, "rb", GzipPicklable), + ] +) def f_byte(request): filename, mode, ref_reader_class = request.param return anyopen(filename, mode), ref_reader_class @@ -136,14 +131,16 @@ def test_fileio_pickle(): assert_equal(raw_io.readlines(), raw_io_pickled.readlines()) -@pytest.fixture(params=[ - # filename mode open_func open_class - ('test.pdb', 'w', pickle_open, FileIOPicklable), - ('test.pdb', 'x', pickle_open, FileIOPicklable), - ('test.pdb', 'a', pickle_open, FileIOPicklable), - ('test.bz2', 'w', bz2_pickle_open, BZ2Picklable), - ('test.gz', 'w', gzip_pickle_open, GzipPicklable), -]) +@pytest.fixture( + params=[ + # filename mode open_func open_class + ("test.pdb", "w", pickle_open, FileIOPicklable), + ("test.pdb", "x", pickle_open, FileIOPicklable), + ("test.pdb", "a", pickle_open, FileIOPicklable), + ("test.bz2", "w", bz2_pickle_open, BZ2Picklable), + ("test.gz", "w", gzip_pickle_open, GzipPicklable), + ] +) def unpicklable_f(request): filename, mode, open_func, open_class = request.param return filename, mode, open_func, open_class @@ -162,26 +159,28 @@ def test_pickle_with_write_mode(unpicklable_f, tmpdir): f_pickled = pickle.loads(pickle.dumps(f_open_by_class)) -@pytest.mark.skipif(not HAS_GSD, reason='gsd not installed') +@pytest.mark.skipif(not HAS_GSD, reason="gsd not installed") def test_GSD_pickle(): - gsd_io = gsd_pickle_open(GSD, mode='r') + gsd_io = gsd_pickle_open(GSD, mode="r") gsd_io_pickled = pickle.loads(pickle.dumps(gsd_io)) - assert_equal(gsd_io[0].particles.position, - gsd_io_pickled[0].particles.position) + assert_equal( + gsd_io[0].particles.position, gsd_io_pickled[0].particles.position + ) -@pytest.mark.skipif(not HAS_GSD, reason='gsd not installed') +@pytest.mark.skipif(not HAS_GSD, reason="gsd not installed") def test_GSD_with_write_mode(tmpdir): with pytest.raises(ValueError, match=r"Only read mode"): - gsd_io = gsd_pickle_open(tmpdir.mkdir("gsd").join('t.gsd'), - mode='w') + gsd_io = gsd_pickle_open(tmpdir.mkdir("gsd").join("t.gsd"), mode="w") def test_NCDF_pickle(): ncdf_io = NCDFPicklable(NCDF, mmap=None) ncdf_io_pickled = pickle.loads(pickle.dumps(ncdf_io)) - assert_equal(ncdf_io.variables['coordinates'][0], - ncdf_io_pickled.variables['coordinates'][0]) + assert_equal( + ncdf_io.variables["coordinates"][0], + ncdf_io_pickled.variables["coordinates"][0], + ) def test_NCDF_mmap_pickle(): @@ -190,8 +189,9 @@ def test_NCDF_mmap_pickle(): assert_equal(ncdf_io_pickled.use_mmap, False) -@pytest.mark.skipif(not check_chemfiles_version(), - reason="Wrong version of chemfiles") +@pytest.mark.skipif( + not check_chemfiles_version(), reason="Wrong version of chemfiles" +) def test_Chemfiles_pickle(): chemfiles_io = ChemfilesPicklable(XYZ) chemfiles_io_pickled = pickle.loads(pickle.dumps(chemfiles_io)) @@ -199,29 +199,34 @@ def test_Chemfiles_pickle(): # As opposed to `chemfiles_io.read().positions) frame = chemfiles_io.read() frame_pickled = chemfiles_io_pickled.read() - assert_equal(frame.positions[:], - frame_pickled.positions[:]) + assert_equal(frame.positions[:], frame_pickled.positions[:]) -@pytest.mark.skipif(not check_chemfiles_version(), - reason="Wrong version of chemfiles") +@pytest.mark.skipif( + not check_chemfiles_version(), reason="Wrong version of chemfiles" +) def test_Chemfiles_with_write_mode(tmpdir): with pytest.raises(ValueError, match=r"Only read mode"): - chemfiles_io = ChemfilesPicklable(tmpdir.mkdir("xyz").join('t.xyz'), - mode='w') + chemfiles_io = ChemfilesPicklable( + tmpdir.mkdir("xyz").join("t.xyz"), mode="w" + ) @pytest.mark.skipif(not HAS_H5PY, reason="h5py not installed") def test_H5MD_pickle(): - h5md_io = H5PYPicklable(H5MD_xvf, 'r') + h5md_io = H5PYPicklable(H5MD_xvf, "r") h5md_io_pickled = pickle.loads(pickle.dumps(h5md_io)) - assert_equal(h5md_io['particles/trajectory/position/value'][0], - h5md_io_pickled['particles/trajectory/position/value'][0]) + assert_equal( + h5md_io["particles/trajectory/position/value"][0], + h5md_io_pickled["particles/trajectory/position/value"][0], + ) @pytest.mark.skipif(not HAS_H5PY, reason="h5py not installed") def test_H5MD_pickle_with_driver(): - h5md_io = H5PYPicklable(H5MD_xvf, 'r', driver='core') + h5md_io = H5PYPicklable(H5MD_xvf, "r", driver="core") h5md_io_pickled = pickle.loads(pickle.dumps(h5md_io)) - assert_equal(h5md_io['particles/trajectory/position/value'][0], - h5md_io_pickled['particles/trajectory/position/value'][0]) + assert_equal( + h5md_io["particles/trajectory/position/value"][0], + h5md_io_pickled["particles/trajectory/position/value"][0], + ) diff --git a/testsuite/MDAnalysisTests/utils/test_qcprot.py b/testsuite/MDAnalysisTests/utils/test_qcprot.py index 484fb78c59..8ee971c227 100644 --- a/testsuite/MDAnalysisTests/utils/test_qcprot.py +++ b/testsuite/MDAnalysisTests/utils/test_qcprot.py @@ -47,12 +47,17 @@ @pytest.fixture() def atoms_a(): - return np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], dtype=np.float64) + return np.array( + [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], dtype=np.float64 + ) @pytest.fixture() def atoms_b(): - return np.array([[13,14,15], [16,17,18], [19,20,21], [22,23,24]], dtype=np.float64) + return np.array( + [[13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24]], + dtype=np.float64, + ) # Calculate rmsd after applying rotation @@ -125,23 +130,35 @@ def test_CalcRMSDRotationalMatrix(): # Calculate rmsd and rotation matrix qcp_rmsd = qcp.CalcRMSDRotationalMatrix(frag_a.T, frag_b.T, N, rot, None) - #print 'qcp rmsd = ',rmsd - #print 'rotation matrix:' - #print rot.reshape((3,3)) + # print 'qcp rmsd = ',rmsd + # print 'rotation matrix:' + # print rot.reshape((3,3)) # rotate frag_b to obtain optimal alignment frag_br = np.dot(frag_b.T, rot.reshape((3, 3))) aligned_rmsd = rmsd(frag_br.T, frag_a) - #print 'rmsd after applying rotation: ',rmsd - - assert_almost_equal(aligned_rmsd, 0.719106, 6, "RMSD between fragments A and B does not match excpected value.") - - expected_rot = np.array([ - [0.72216358, -0.52038257, -0.45572112], - [0.69118937, 0.51700833, 0.50493528], - [-0.0271479, -0.67963547, 0.73304748]]) - assert_almost_equal(rot.reshape((3, 3)), expected_rot, 6, - "Rotation matrix for aliging B to A does not have expected values.") + # print 'rmsd after applying rotation: ',rmsd + + assert_almost_equal( + aligned_rmsd, + 0.719106, + 6, + "RMSD between fragments A and B does not match excpected value.", + ) + + expected_rot = np.array( + [ + [0.72216358, -0.52038257, -0.45572112], + [0.69118937, 0.51700833, 0.50493528], + [-0.0271479, -0.67963547, 0.73304748], + ] + ) + assert_almost_equal( + rot.reshape((3, 3)), + expected_rot, + 6, + "Rotation matrix for aliging B to A does not have expected values.", + ) def test_innerproduct(atoms_a, atoms_b): @@ -158,29 +175,63 @@ def test_innerproduct(atoms_a, atoms_b): def test_RMSDmatrix(atoms_a, atoms_b): number_of_atoms = 4 rotation = np.zeros(9, dtype=np.float64) - rmsd = qcp.CalcRMSDRotationalMatrix(atoms_a, atoms_b, number_of_atoms, rotation, None) # no weights + rmsd = qcp.CalcRMSDRotationalMatrix( + atoms_a, atoms_b, number_of_atoms, rotation, None + ) # no weights rmsd_ref = 20.73219522556076 assert_almost_equal(rmsd_ref, rmsd) - rotation_ref = np.array([0.9977195, 0.02926979, 0.06082009, -.0310942, 0.9990878, 0.02926979, -0.05990789, -.0310942, 0.9977195]) + rotation_ref = np.array( + [ + 0.9977195, + 0.02926979, + 0.06082009, + -0.0310942, + 0.9990878, + 0.02926979, + -0.05990789, + -0.0310942, + 0.9977195, + ] + ) assert_array_almost_equal(rotation, rotation_ref, 6) def test_RMSDmatrix_simple(atoms_a, atoms_b): number_of_atoms = 4 rotation = np.zeros(9, dtype=np.float64) - rmsd = qcp.CalcRMSDRotationalMatrix(atoms_a, atoms_b, number_of_atoms, rotation, None) # no weights + rmsd = qcp.CalcRMSDRotationalMatrix( + atoms_a, atoms_b, number_of_atoms, rotation, None + ) # no weights rmsd_ref = 20.73219522556076 assert_almost_equal(rmsd_ref, rmsd) - rotation_ref = np.array([0.9977195, 0.02926979, 0.06082009, -.0310942, 0.9990878, 0.02926979, -0.05990789, -.0310942, 0.9977195]) + rotation_ref = np.array( + [ + 0.9977195, + 0.02926979, + 0.06082009, + -0.0310942, + 0.9990878, + 0.02926979, + -0.05990789, + -0.0310942, + 0.9977195, + ] + ) assert_array_almost_equal(rotation, rotation_ref, 6) - + def test_rmsd(atoms_a, atoms_b): - rotation_m = np.array([[.9977195, .02926979, .06082009], [-.0310942, .9990878, .02926979], [-.05990789, -.0310942, .9977195]]) + rotation_m = np.array( + [ + [0.9977195, 0.02926979, 0.06082009], + [-0.0310942, 0.9990878, 0.02926979], + [-0.05990789, -0.0310942, 0.9977195], + ] + ) atoms_b_aligned = np.dot(atoms_b, rotation_m) rmsd = rms.rmsd(atoms_b_aligned, atoms_a) rmsd_ref = 20.73219522556076 @@ -189,11 +240,25 @@ def test_rmsd(atoms_a, atoms_b): def test_weights(atoms_a, atoms_b): no_of_atoms = 4 - weights = np.array([1,2,3,4], dtype=np.float64) + weights = np.array([1, 2, 3, 4], dtype=np.float64) rotation = np.zeros(9, dtype=np.float64) - rmsd = qcp.CalcRMSDRotationalMatrix(atoms_a, atoms_b, no_of_atoms, rotation, weights) + rmsd = qcp.CalcRMSDRotationalMatrix( + atoms_a, atoms_b, no_of_atoms, rotation, weights + ) assert_almost_equal(rmsd, 32.798779202159416) - rotation_ref = np.array([0.99861395, .022982, .04735006, -.02409085, .99944556, .022982, -.04679564, -.02409085, .99861395]) + rotation_ref = np.array( + [ + 0.99861395, + 0.022982, + 0.04735006, + -0.02409085, + 0.99944556, + 0.022982, + -0.04679564, + -0.02409085, + 0.99861395, + ] + ) np.testing.assert_almost_equal(rotation_ref, rotation) diff --git a/testsuite/MDAnalysisTests/utils/test_selections.py b/testsuite/MDAnalysisTests/utils/test_selections.py index d271f2f09f..212bce97da 100644 --- a/testsuite/MDAnalysisTests/utils/test_selections.py +++ b/testsuite/MDAnalysisTests/utils/test_selections.py @@ -42,7 +42,9 @@ class _SelectionWriter(object): filename = None - max_number = 357 # to keep fixtures smallish, only select CAs up to number 357 + max_number = ( + 357 # to keep fixtures smallish, only select CAs up to number 357 + ) @staticmethod @pytest.fixture() @@ -54,7 +56,9 @@ def namedfile(self): return NamedStream(StringIO(), self.filename) def _selection(self, universe): - return universe.select_atoms("protein and name CA and bynum 1-{0}".format(self.max_number)) + return universe.select_atoms( + "protein and name CA and bynum 1-{0}".format(self.max_number) + ) def _write(self, universe, namedfile, **kwargs): g = self._selection(universe) @@ -72,9 +76,13 @@ def _write_with(self, universe, namedfile, **kwargs): outfile.write(g) return g - def test_write_bad_mode(self, universe, namedfile,): + def test_write_bad_mode( + self, + universe, + namedfile, + ): with pytest.raises(ValueError): - self._write(universe, namedfile, name=self.ref_name, mode='a+') + self._write(universe, namedfile, name=self.ref_name, mode="a+") def test_write(self, universe, namedfile): self._write(universe, namedfile, name=self.ref_name) @@ -105,18 +113,25 @@ class TestSelectionWriter_Gromacs(_SelectionWriter): filename = "CA.ndx" ref_name = "CA_selection" ref_indices = ndx2array( - [ '5 22 46 65 84 103 122 129 141 153 160 170 \n', - '177 199 206 220 237 247 264 284 303 320 335 357 \n', - ] - ) + [ + "5 22 46 65 84 103 122 129 141 153 160 170 \n", + "177 199 206 220 237 247 264 284 303 320 335 357 \n", + ] + ) def _assert_selectionstring(self, namedfile): header = namedfile.readline().strip() - assert_equal(header, "[ {0} ]".format(self.ref_name), - err_msg="NDX file has wrong selection name") + assert_equal( + header, + "[ {0} ]".format(self.ref_name), + err_msg="NDX file has wrong selection name", + ) indices = ndx2array(namedfile.readlines()) - assert_array_equal(indices, self.ref_indices, - err_msg="indices were not written correctly") + assert_array_equal( + indices, + self.ref_indices, + err_msg="indices were not written correctly", + ) class TestSelectionWriter_Charmm(_SelectionWriter): @@ -124,8 +139,9 @@ class TestSelectionWriter_Charmm(_SelectionWriter): writer = MDAnalysis.selections.charmm.SelectionWriter filename = "CA.str" ref_name = "CA_selection" - ref_selectionstring = lines2one([ - """! MDAnalysis CHARMM selection + ref_selectionstring = lines2one( + [ + """! MDAnalysis CHARMM selection DEFINE CA_selection SELECT - BYNUM 5 .or. BYNUM 22 .or. BYNUM 46 .or. BYNUM 65 .or. - BYNUM 84 .or. BYNUM 103 .or. BYNUM 122 .or. BYNUM 129 .or. - @@ -133,12 +149,17 @@ class TestSelectionWriter_Charmm(_SelectionWriter): BYNUM 177 .or. BYNUM 199 .or. BYNUM 206 .or. BYNUM 220 .or. - BYNUM 237 .or. BYNUM 247 .or. BYNUM 264 .or. BYNUM 284 .or. - BYNUM 303 .or. BYNUM 320 .or. BYNUM 335 .or. BYNUM 357 END - """]) + """ + ] + ) def _assert_selectionstring(self, namedfile): selectionstring = lines2one(namedfile.readlines()) - assert_equal(selectionstring, self.ref_selectionstring, - err_msg="Charmm selection was not written correctly") + assert_equal( + selectionstring, + self.ref_selectionstring, + err_msg="Charmm selection was not written correctly", + ) class TestSelectionWriter_PyMOL(_SelectionWriter): @@ -146,18 +167,24 @@ class TestSelectionWriter_PyMOL(_SelectionWriter): writer = MDAnalysis.selections.pymol.SelectionWriter filename = "CA.pml" ref_name = "CA_selection" - ref_selectionstring = lines2one([ - """# MDAnalysis PyMol selection\n select CA_selection, \\ + ref_selectionstring = lines2one( + [ + """# MDAnalysis PyMol selection\n select CA_selection, \\ index 5 | index 22 | index 46 | index 65 | index 84 | index 103 | \\ index 122 | index 129 | index 141 | index 153 | index 160 | index 170 | \\ index 177 | index 199 | index 206 | index 220 | index 237 | index 247 | \\ index 264 | index 284 | index 303 | index 320 | index 335 | index 357 - """]) + """ + ] + ) def _assert_selectionstring(self, namedfile): selectionstring = lines2one(namedfile.readlines()) - assert_equal(selectionstring, self.ref_selectionstring, - err_msg="PyMOL selection was not written correctly") + assert_equal( + selectionstring, + self.ref_selectionstring, + err_msg="PyMOL selection was not written correctly", + ) class TestSelectionWriter_VMD(_SelectionWriter): @@ -165,21 +192,27 @@ class TestSelectionWriter_VMD(_SelectionWriter): writer = MDAnalysis.selections.vmd.SelectionWriter filename = "CA.vmd" ref_name = "CA_selection" - ref_selectionstring = lines2one([ - """# MDAnalysis VMD selection atomselect macro CA_selection {index 4 21 45 64 83 102 121 128 \\ + ref_selectionstring = lines2one( + [ + """# MDAnalysis VMD selection atomselect macro CA_selection {index 4 21 45 64 83 102 121 128 \\ 140 152 159 169 176 198 205 219 \\ 236 246 263 283 302 319 334 356 } - """]) + """ + ] + ) def _assert_selectionstring(self, namedfile): selectionstring = lines2one(namedfile.readlines()) - assert_equal(selectionstring, self.ref_selectionstring, - err_msg="PyMOL selection was not written correctly") + assert_equal( + selectionstring, + self.ref_selectionstring, + err_msg="PyMOL selection was not written correctly", + ) def spt2array(line): """Get name of and convert Jmol SPT definition to integer array""" - match = re.search(r'\@~(\w+) \(\{([\d\s]*)\}\)', line) + match = re.search(r"\@~(\w+) \(\{([\d\s]*)\}\)", line) return match.group(1), np.array(match.group(2).split(), dtype=int) @@ -188,16 +221,22 @@ class TestSelectionWriter_Jmol(_SelectionWriter): writer = MDAnalysis.selections.jmol.SelectionWriter filename = "CA.spt" ref_name, ref_indices = spt2array( - ( '@~ca ({4 21 45 64 83 102 121 128 140 152 159 169 176 198 205 219 236' - ' 246 263 283 302 319 334 356});') + ( + "@~ca ({4 21 45 64 83 102 121 128 140 152 159 169 176 198 205 219 236" + " 246 263 283 302 319 334 356});" ) + ) def _assert_selectionstring(self, namedfile): header, indices = spt2array(namedfile.readline()) - assert_equal(header, self.ref_name, - err_msg="SPT file has wrong selection name") - assert_array_equal(indices, self.ref_indices, - err_msg="SPT indices were not written correctly") + assert_equal( + header, self.ref_name, err_msg="SPT file has wrong selection name" + ) + assert_array_equal( + indices, + self.ref_indices, + err_msg="SPT indices were not written correctly", + ) class TestSelections: diff --git a/testsuite/MDAnalysisTests/utils/test_streamio.py b/testsuite/MDAnalysisTests/utils/test_streamio.py index 53eb1a95c8..56a421dda7 100644 --- a/testsuite/MDAnalysisTests/utils/test_streamio.py +++ b/testsuite/MDAnalysisTests/utils/test_streamio.py @@ -20,13 +20,26 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # -from os.path import abspath, basename, dirname, expanduser, normpath, relpath, split, splitext +from os.path import ( + abspath, + basename, + dirname, + expanduser, + normpath, + relpath, + split, + splitext, +) from io import StringIO import pytest import numpy as np -from numpy.testing import assert_equal, assert_almost_equal, assert_array_almost_equal +from numpy.testing import ( + assert_equal, + assert_almost_equal, + assert_array_almost_equal, +) import MDAnalysis @@ -77,7 +90,7 @@ class TestNamedStream(object): text = [ "The Jabberwock, with eyes of flame,\n", "Came whiffling through the tulgey wood,\n", - "And burbled as it came!" + "And burbled as it came!", ] textname = "jabberwock.txt" @@ -110,7 +123,7 @@ def test_StringIO_read(self): ns.close(force=True) def test_File_read(self): - obj = open(self.filename, 'r') + obj = open(self.filename, "r") ns = util.NamedStream(obj, self.filename) assert_equal(ns.name, self.filename) assert_equal(str(ns), self.filename) @@ -148,15 +161,17 @@ def test_File_write(self, tmpdir): def test_matryoshka(self): obj = StringIO() - ns = util.NamedStream(obj, 'r') + ns = util.NamedStream(obj, "r") with pytest.warns(RuntimeWarning): - ns2 = util.NamedStream(ns, 'f') + ns2 = util.NamedStream(ns, "f") assert not isinstance(ns2.stream, util.NamedStream) - assert ns2.name == 'f' + assert ns2.name == "f" class TestNamedStream_filename_behavior(object): - textname = os.path.join("~", "stories", "jabberwock.txt") # with tilde ~ to test regular expanduser() + textname = os.path.join( + "~", "stories", "jabberwock.txt" + ) # with tilde ~ to test regular expanduser() # note: no setUp() because classes with generators would run it # *for each generated test* and we need it for the generator method @@ -166,7 +181,9 @@ def create_NamedStream(self, name=None): obj = StringIO() return util.NamedStream(obj, name) - @pytest.mark.parametrize('func', ( + @pytest.mark.parametrize( + "func", + ( abspath, basename, dirname, @@ -174,8 +191,9 @@ def create_NamedStream(self, name=None): normpath, relpath, split, - splitext - )) + splitext, + ), + ) def test_func(self, func): # - "expandvars" gave Segmentation fault (OS X 10.6, Python 2.7.11 -- orbeckst) # - "expanduser" will either return a string if it carried out interpolation @@ -186,9 +204,13 @@ def test_func(self, func): fn = self.textname reference = func(fn) value = func(ns) - assert_equal(value, reference, - err_msg=("os.path.{0}() does not work with " - "NamedStream").format(func.__name__)) + assert_equal( + value, + reference, + err_msg=("os.path.{0}() does not work with " "NamedStream").format( + func.__name__ + ), + ) def test_join(self, tmpdir, funcname="join"): # join not included because of different call signature @@ -198,62 +220,86 @@ def test_join(self, tmpdir, funcname="join"): fn = self.textname reference = str(tmpdir.join(fn)) value = os.path.join(str(tmpdir), ns) - assert_equal(value, reference, - err_msg=("os.path.{0}() does not work with " - "NamedStream").format(funcname)) + assert_equal( + value, + reference, + err_msg=("os.path.{0}() does not work with " "NamedStream").format( + funcname + ), + ) def test_expanduser_noexpansion_returns_NamedStream(self): - ns = self.create_NamedStream("de/zipferlack.txt") # no tilde ~ in name! + ns = self.create_NamedStream( + "de/zipferlack.txt" + ) # no tilde ~ in name! reference = ns.name value = os.path.expanduser(ns) - assert_equal(value, reference, - err_msg=("os.path.expanduser() without '~' did not " - "return NamedStream --- weird!!")) - - @pytest.mark.skipif("HOME" not in os.environ, reason='It is needed') + assert_equal( + value, + reference, + err_msg=( + "os.path.expanduser() without '~' did not " + "return NamedStream --- weird!!" + ), + ) + + @pytest.mark.skipif("HOME" not in os.environ, reason="It is needed") def test_expandvars(self): name = "${HOME}/stories/jabberwock.txt" ns = self.create_NamedStream(name) reference = os.path.expandvars(name) value = os.path.expandvars(ns) - assert_equal(value, reference, - err_msg="os.path.expandvars() did not expand HOME") + assert_equal( + value, + reference, + err_msg="os.path.expandvars() did not expand HOME", + ) def test_expandvars_noexpansion_returns_NamedStream(self): - ns = self.create_NamedStream() # no $VAR constructs + ns = self.create_NamedStream() # no $VAR constructs reference = ns.name value = os.path.expandvars(ns) - assert_equal(value, reference, - err_msg=("os.path.expandvars() without '$VARS' did not " - "return NamedStream --- weird!!")) + assert_equal( + value, + reference, + err_msg=( + "os.path.expandvars() without '$VARS' did not " + "return NamedStream --- weird!!" + ), + ) def test_add(self): ns = self.create_NamedStream() try: assert_equal(ns + "foo", self.textname + "foo") except TypeError: - raise pytest.fail("NamedStream does not support " - "string concatenation, NamedStream + str") + raise pytest.fail( + "NamedStream does not support " + "string concatenation, NamedStream + str" + ) def test_radd(self): ns = self.create_NamedStream() try: assert_equal("foo" + ns, "foo" + self.textname) except TypeError: - raise pytest.fail("NamedStream does not support right " - "string concatenation, str + NamedStream") + raise pytest.fail( + "NamedStream does not support right " + "string concatenation, str + NamedStream" + ) class _StreamData(object): """Data for StreamIO functions.""" + filenames = { - 'PSF': datafiles.PSF, - 'CRD': datafiles.CRD, - 'PDB': datafiles.PDB_small, - 'PQR': datafiles.PQR, - 'GRO': datafiles.GRO_velocity, - 'MOL2': datafiles.mol2_molecules, - 'PDBQT': datafiles.PDBQT_input, + "PSF": datafiles.PSF, + "CRD": datafiles.CRD, + "PDB": datafiles.PDB_small, + "PQR": datafiles.PQR, + "GRO": datafiles.GRO_velocity, + "MOL2": datafiles.mol2_molecules, + "PDBQT": datafiles.PDBQT_input, } def __init__(self): @@ -261,8 +307,10 @@ def __init__(self): for name, fn in self.filenames.items(): with open(fn) as filed: self.buffers[name] = "".join(filed.readlines()) - self.filenames['XYZ_PSF'] = u"bogus/path/mini.psf" - self.buffers['XYZ_PSF'] = u"""\ + self.filenames["XYZ_PSF"] = "bogus/path/mini.psf" + self.buffers[ + "XYZ_PSF" + ] = """\ PSF CMAP 1 !NTITLE @@ -278,8 +326,10 @@ def __init__(self): 7 A 380 THR C C 0.510000 12.0110 0 8 A 380 THR O O -0.510000 15.9990 0 """ - self.filenames['XYZ'] = "bogus/path/mini.xyz" - self.buffers['XYZ'] = """\ + self.filenames["XYZ"] = "bogus/path/mini.xyz" + self.buffers[ + "XYZ" + ] = """\ 8 frame 1 N 0.93100 17.31800 16.42300 @@ -320,7 +370,7 @@ def as_NamedStream(self, name): return util.NamedStream(self.as_StringIO(name), self.filenames[name]) -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def streamData(): return _StreamData() @@ -328,72 +378,97 @@ def streamData(): # possibly add tests to individual readers instead? class TestStreamIO(RefAdKSmall): def test_PrimitivePDBReader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('PDB')) + u = MDAnalysis.Universe(streamData.as_NamedStream("PDB")) assert_equal(u.atoms.n_atoms, self.ref_n_atoms) def test_PDBReader(self, streamData): try: - u = MDAnalysis.Universe(streamData.as_NamedStream('PDB')) + u = MDAnalysis.Universe(streamData.as_NamedStream("PDB")) except Exception as err: raise pytest.fail("StreamIO not supported:\n>>>>> {0}".format(err)) assert_equal(u.atoms.n_atoms, self.ref_n_atoms) def test_CRDReader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('CRD')) + u = MDAnalysis.Universe(streamData.as_NamedStream("CRD")) assert_equal(u.atoms.n_atoms, self.ref_n_atoms) def test_PSFParser(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('PSF')) + u = MDAnalysis.Universe(streamData.as_NamedStream("PSF")) assert_equal(u.atoms.n_atoms, self.ref_n_atoms) def test_PSF_CRD(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('PSF'), - streamData.as_NamedStream('CRD')) + u = MDAnalysis.Universe( + streamData.as_NamedStream("PSF"), streamData.as_NamedStream("CRD") + ) assert_equal(u.atoms.n_atoms, self.ref_n_atoms) def test_PQRReader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('PQR')) + u = MDAnalysis.Universe(streamData.as_NamedStream("PQR")) assert_equal(u.atoms.n_atoms, self.ref_n_atoms) - assert_almost_equal(u.atoms.total_charge(), self.ref_charmm_totalcharge, 3, - "Total charge (in CHARMM) does not match expected value.") - assert_almost_equal(u.atoms.select_atoms('name H').charges, self.ref_charmm_Hcharges, 3, - "Charges for H atoms do not match.") + assert_almost_equal( + u.atoms.total_charge(), + self.ref_charmm_totalcharge, + 3, + "Total charge (in CHARMM) does not match expected value.", + ) + assert_almost_equal( + u.atoms.select_atoms("name H").charges, + self.ref_charmm_Hcharges, + 3, + "Charges for H atoms do not match.", + ) def test_PDBQTReader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('PDBQT')) - sel = u.select_atoms('backbone') + u = MDAnalysis.Universe(streamData.as_NamedStream("PDBQT")) + sel = u.select_atoms("backbone") assert_equal(sel.n_atoms, 796) - sel = u.select_atoms('segid A') + sel = u.select_atoms("segid A") assert_equal(sel.n_atoms, 909, "failed to select segment A") - sel = u.select_atoms('segid B') + sel = u.select_atoms("segid B") assert_equal(sel.n_atoms, 896, "failed to select segment B") def test_GROReader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('GRO')) + u = MDAnalysis.Universe(streamData.as_NamedStream("GRO")) assert_equal(u.atoms.n_atoms, 6) - assert_almost_equal(u.atoms[3].position, - 10. * np.array([1.275, 0.053, 0.622]), 3, # manually convert nm -> A - err_msg="wrong coordinates for water 2 OW") - assert_almost_equal(u.atoms[3].velocity, - 10. * np.array([0.2519, 0.3140, -0.1734]), 3, # manually convert nm/ps -> A/ps - err_msg="wrong velocity for water 2 OW") + assert_almost_equal( + u.atoms[3].position, + 10.0 * np.array([1.275, 0.053, 0.622]), + 3, # manually convert nm -> A + err_msg="wrong coordinates for water 2 OW", + ) + assert_almost_equal( + u.atoms[3].velocity, + 10.0 * np.array([0.2519, 0.3140, -0.1734]), + 3, # manually convert nm/ps -> A/ps + err_msg="wrong velocity for water 2 OW", + ) def test_MOL2Reader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('MOL2')) + u = MDAnalysis.Universe(streamData.as_NamedStream("MOL2")) assert_equal(len(u.atoms), 49) assert_equal(u.trajectory.n_frames, 200) u.trajectory[199] - assert_array_almost_equal(u.atoms.positions[0], [1.7240, 11.2730, 14.1200]) + assert_array_almost_equal( + u.atoms.positions[0], [1.7240, 11.2730, 14.1200] + ) def test_XYZReader(self, streamData): - u = MDAnalysis.Universe(streamData.as_NamedStream('XYZ_PSF'), - streamData.as_NamedStream('XYZ')) + u = MDAnalysis.Universe( + streamData.as_NamedStream("XYZ_PSF"), + streamData.as_NamedStream("XYZ"), + ) assert_equal(len(u.atoms), 8) assert_equal(u.trajectory.n_frames, 3) - assert_equal(u.trajectory.frame, 0) # weird, something odd with XYZ reader + assert_equal( + u.trajectory.frame, 0 + ) # weird, something odd with XYZ reader u.trajectory.next() # (should really only need one next()... ) assert_equal(u.trajectory.frame, 1) # !!!! ??? u.trajectory.next() # frame 2 assert_equal(u.trajectory.frame, 2) - assert_almost_equal(u.atoms[2].position, np.array([0.45600, 18.48700, 16.26500]), 3, - err_msg="wrong coordinates for atom CA at frame 2") + assert_almost_equal( + u.atoms[2].position, + np.array([0.45600, 18.48700, 16.26500]), + 3, + err_msg="wrong coordinates for atom CA at frame 2", + ) diff --git a/testsuite/MDAnalysisTests/utils/test_transformations.py b/testsuite/MDAnalysisTests/utils/test_transformations.py index 8a3a4baec9..72d6831cd1 100644 --- a/testsuite/MDAnalysisTests/utils/test_transformations.py +++ b/testsuite/MDAnalysisTests/utils/test_transformations.py @@ -24,8 +24,12 @@ import numpy as np import pytest -from numpy.testing import (assert_allclose, assert_equal, assert_almost_equal, - assert_array_equal) +from numpy.testing import ( + assert_allclose, + assert_equal, + assert_almost_equal, + assert_array_equal, +) from MDAnalysis.lib import transformations as t @@ -50,10 +54,7 @@ _ATOL = 1e-06 -@pytest.mark.parametrize('f', [ - t._py_identity_matrix, - t.identity_matrix -]) +@pytest.mark.parametrize("f", [t._py_identity_matrix, t.identity_matrix]) def test_identity_matrix(f): I = f() assert_allclose(I, np.dot(I, I)) @@ -61,10 +62,13 @@ def test_identity_matrix(f): assert_allclose(I, np.identity(4, dtype=np.float64)) -@pytest.mark.parametrize('f', [ - t._py_translation_matrix, - t.translation_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_translation_matrix, + t.translation_matrix, + ], +) def test_translation_matrix(f): v = np.array([0.2, 0.2, 0.2]) assert_allclose(v, f(v)[:3, 3]) @@ -77,15 +81,18 @@ def test_translation_from_matrix(): assert_allclose(v0, v1) -@pytest.mark.parametrize('f', [ - t._py_reflection_matrix, - t.reflection_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_reflection_matrix, + t.reflection_matrix, + ], +) def test_reflection_matrix(f): v0 = np.array([0.2, 0.2, 0.2, 1.0]) # arbitrary values v1 = np.array([0.4, 0.4, 0.4]) R = f(v0, v1) - assert_allclose(2., np.trace(R)) + assert_allclose(2.0, np.trace(R)) assert_allclose(v0, np.dot(R, v0)) v2 = v0.copy() v2[:3] += v1 @@ -103,13 +110,16 @@ def test_reflection_from_matrix(): assert_equal(t.is_same_transform(M0, M1), True) -@pytest.mark.parametrize('f', [ - t._py_rotation_matrix, - t.rotation_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_rotation_matrix, + t.rotation_matrix, + ], +) def test_rotation_matrix(f): R = f(np.pi / 2.0, [0, 0, 1], [1, 0, 0]) - assert_allclose(np.dot(R, [0, 0, 0, 1]), [1., -1., 0., 1.]) + assert_allclose(np.dot(R, [0, 0, 0, 1]), [1.0, -1.0, 0.0, 1.0]) angle = 0.2 * 2 * np.pi # arbitrary value direc = np.array([0.2, 0.2, 0.2]) point = np.array([0.4, 0.4, 0.4]) @@ -121,7 +131,7 @@ def test_rotation_matrix(f): assert_equal(t.is_same_transform(R0, R1), True) I = np.identity(4, np.float64) assert_allclose(I, f(np.pi * 2, direc), atol=_ATOL) - assert_allclose(2., np.trace(f(np.pi / 2, direc, point))) + assert_allclose(2.0, np.trace(f(np.pi / 2, direc, point))) def test_rotation_from_matrix(): @@ -134,10 +144,13 @@ def test_rotation_from_matrix(): assert_equal(t.is_same_transform(R0, R1), True) -@pytest.mark.parametrize('f', [ - t._py_scale_matrix, - t.scale_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_scale_matrix, + t.scale_matrix, + ], +) def test_scale_matrix(f): v = np.array([14.1, 15.1, 16.1, 1]) S = f(-1.234) @@ -157,10 +170,14 @@ def test_scale_from_matrix(): S1 = t.scale_matrix(factor, origin, direction) assert_equal(t.is_same_transform(S0, S1), True) -@pytest.mark.parametrize('f', [ - t._py_projection_matrix, - t.projection_matrix, -]) + +@pytest.mark.parametrize( + "f", + [ + t._py_projection_matrix, + t.projection_matrix, + ], +) class TestProjectionMatrix(object): def test_projection_matrix_1(self, f): P = f((0, 0, 0), (1, 0, 0)) @@ -187,7 +204,6 @@ def test_projection_matrix_3(self, f): assert_allclose(v1[0], 3.0 - v1[1], atol=_ATOL) - class TestProjectionFromMatrix(object): @staticmethod @pytest.fixture() @@ -215,25 +231,27 @@ def test_projection_from_matrix_2(self, data): def test_projection_from_matrix_3(self, data): point, normal, direct, persp = data P0 = t.projection_matrix( - point, normal, perspective=persp, pseudo=False) + point, normal, perspective=persp, pseudo=False + ) result = t.projection_from_matrix(P0, pseudo=False) P1 = t.projection_matrix(*result) assert_equal(t.is_same_transform(P0, P1), True) def test_projection_from_matrix_4(self, data): point, normal, direct, persp = data - P0 = t.projection_matrix( - point, normal, perspective=persp, pseudo=True) + P0 = t.projection_matrix(point, normal, perspective=persp, pseudo=True) result = t.projection_from_matrix(P0, pseudo=True) P1 = t.projection_matrix(*result) assert_equal(t.is_same_transform(P0, P1), True) - -@pytest.mark.parametrize('f', [ - t._py_clip_matrix, - t.clip_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_clip_matrix, + t.clip_matrix, + ], +) class TestClipMatrix(object): def test_clip_matrix_1(self, f): frustrum = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6]) # arbitrary values @@ -243,10 +261,12 @@ def test_clip_matrix_1(self, f): M = f(perspective=False, *frustrum) assert_allclose( np.dot(M, [frustrum[0], frustrum[2], frustrum[4], 1.0]), - np.array([-1., -1., -1., 1.])) + np.array([-1.0, -1.0, -1.0, 1.0]), + ) assert_allclose( np.dot(M, [frustrum[1], frustrum[3], frustrum[5], 1.0]), - np.array([1., 1., 1., 1.])) + np.array([1.0, 1.0, 1.0, 1.0]), + ) def test_clip_matrix_2(self, f): frustrum = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6]) # arbitrary values @@ -255,33 +275,36 @@ def test_clip_matrix_2(self, f): frustrum[5] += frustrum[4] M = f(perspective=True, *frustrum) v = np.dot(M, [frustrum[0], frustrum[2], frustrum[4], 1.0]) - assert_allclose(v / v[3], np.array([-1., -1., -1., 1.])) + assert_allclose(v / v[3], np.array([-1.0, -1.0, -1.0, 1.0])) v = np.dot(M, [frustrum[1], frustrum[3], frustrum[4], 1.0]) - assert_allclose(v / v[3], np.array([1., 1., -1., 1.])) + assert_allclose(v / v[3], np.array([1.0, 1.0, -1.0, 1.0])) def test_clip_matrix_frustrum_left_right_bounds(self, f): - '''ValueError should be raised if left > right.''' + """ValueError should be raised if left > right.""" frustrum = np.array([0.4, 0.3, 0.3, 0.7, 0.5, 1.1]) with pytest.raises(ValueError): f(*frustrum) def test_clip_matrix_frustrum_bottom_top_bounds(self, f): - '''ValueError should be raised if bottom > top.''' + """ValueError should be raised if bottom > top.""" frustrum = np.array([0.1, 0.3, 0.71, 0.7, 0.5, 1.1]) with pytest.raises(ValueError): f(*frustrum) def test_clip_matrix_frustrum_near_far_bounds(self, f): - '''ValueError should be raised if near > far.''' + """ValueError should be raised if near > far.""" frustrum = np.array([0.1, 0.3, 0.3, 0.7, 1.5, 1.1]) with pytest.raises(ValueError): f(*frustrum) -@pytest.mark.parametrize('f', [ - t._py_shear_matrix, - t.shear_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_shear_matrix, + t.shear_matrix, + ], +) def test_shear_matrix(f): angle = 0.2 * 4 * np.pi # arbitrary values direct = np.array([0.2, 0.2, 0.2]) @@ -345,13 +368,16 @@ def test_compose_matrix(): assert_equal(t.is_same_transform(M0, M1), True) -@pytest.mark.parametrize('f', [ - t._py_orthogonalization_matrix, - t.orthogonalization_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_orthogonalization_matrix, + t.orthogonalization_matrix, + ], +) class TestOrthogonalizationMatrix(object): def test_orthogonalization_matrix_1(self, f): - O = f((10., 10., 10.), (90., 90., 90.)) + O = f((10.0, 10.0, 10.0), (90.0, 90.0, 90.0)) assert_allclose(O[:3, :3], np.identity(3, float) * 10, atol=_ATOL) def test_orthogonalization_matrix_2(self, f): @@ -359,10 +385,13 @@ def test_orthogonalization_matrix_2(self, f): assert_allclose(np.sum(O), 43.063229, atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_superimposition_matrix, - t.superimposition_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_superimposition_matrix, + t.superimposition_matrix, + ], +) def test_superimposition_matrix(f): v0 = np.sin(np.linspace(0, 0.99, 30)).reshape(3, 10) # arbitrary values M = f(v0, v0) @@ -397,13 +426,16 @@ def test_superimposition_matrix(f): assert_allclose(v1, np.dot(M, v[:, :, 0]), atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_euler_matrix, - t.euler_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_euler_matrix, + t.euler_matrix, + ], +) class TestEulerMatrix(object): def test_euler_matrix_1(self, f): - R = f(1, 2, 3, 'syxz') + R = f(1, 2, 3, "syxz") assert_allclose(np.sum(R[0]), -1.34786452) def test_euler_matrix_2(self, f): @@ -411,15 +443,18 @@ def test_euler_matrix_2(self, f): assert_allclose(np.sum(R[0]), -0.383436184) -@pytest.mark.parametrize('f', [ - t._py_euler_from_matrix, - t.euler_from_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_euler_from_matrix, + t.euler_from_matrix, + ], +) class TestEulerFromMatrix(object): def test_euler_from_matrix_1(self, f): - R0 = t.euler_matrix(1, 2, 3, 'syxz') - al, be, ga = f(R0, 'syxz') - R1 = t.euler_matrix(al, be, ga, 'syxz') + R0 = t.euler_matrix(1, 2, 3, "syxz") + al, be, ga = f(R0, "syxz") + R1 = t.euler_matrix(al, be, ga, "syxz") assert_allclose(R0, R1) def test_euler_from_matrix_2(self, f): @@ -435,28 +470,37 @@ def test_euler_from_quaternion(): assert_allclose(angles, [0.123, 0, 0], atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_quaternion_from_euler, - t.quaternion_from_euler, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_from_euler, + t.quaternion_from_euler, + ], +) def test_quaternion_from_euler(f): - q = f(1, 2, 3, 'ryxz') + q = f(1, 2, 3, "ryxz") assert_allclose(q, [0.435953, 0.310622, -0.718287, 0.444435], atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_quaternion_about_axis, - t.quaternion_about_axis, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_about_axis, + t.quaternion_about_axis, + ], +) def test_quaternion_about_axis(f): q = f(0.123, (1, 0, 0)) assert_allclose(q, [0.99810947, 0.06146124, 0, 0], atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_quaternion_matrix, - t.quaternion_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_matrix, + t.quaternion_matrix, + ], +) class TestQuaternionMatrix(object): def test_quaternion_matrix_1(self, f): M = f([0.99810947, 0.06146124, 0, 0]) @@ -471,40 +515,53 @@ def test_quaternion_matrix_3(self, f): assert_allclose(M, np.diag([1, -1, -1, 1]), atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_quaternion_from_matrix, - t.quaternion_from_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_from_matrix, + t.quaternion_from_matrix, + ], +) class TestQuaternionFromMatrix(object): def test_quaternion_from_matrix_1(self, f): q = f(t.identity_matrix(), True) - assert_allclose(q, [1., 0., 0., 0.], atol=_ATOL) + assert_allclose(q, [1.0, 0.0, 0.0, 0.0], atol=_ATOL) def test_quaternion_from_matrix_2(self, f): - q = f(np.diag([1., -1., -1., 1.])) - check = (np.allclose( - q, [0, 1, 0, 0], atol=_ATOL) or np.allclose( - q, [0, -1, 0, 0], atol=_ATOL)) + q = f(np.diag([1.0, -1.0, -1.0, 1.0])) + check = np.allclose(q, [0, 1, 0, 0], atol=_ATOL) or np.allclose( + q, [0, -1, 0, 0], atol=_ATOL + ) assert_equal(check, True) def test_quaternion_from_matrix_3(self, f): R = t.rotation_matrix(0.123, (1, 2, 3)) q = f(R, True) assert_allclose( - q, [0.9981095, 0.0164262, 0.0328524, 0.0492786], atol=_ATOL) + q, [0.9981095, 0.0164262, 0.0328524, 0.0492786], atol=_ATOL + ) def test_quaternion_from_matrix_4(self, f): - R = [[-0.545, 0.797, 0.260, 0], [0.733, 0.603, -0.313, 0], - [-0.407, 0.021, -0.913, 0], [0, 0, 0, 1]] + R = [ + [-0.545, 0.797, 0.260, 0], + [0.733, 0.603, -0.313, 0], + [-0.407, 0.021, -0.913, 0], + [0, 0, 0, 1], + ] q = f(R) assert_allclose(q, [0.19069, 0.43736, 0.87485, -0.083611], atol=_ATOL) def test_quaternion_from_matrix_5(self, f): - R = [[0.395, 0.362, 0.843, 0], [-0.626, 0.796, -0.056, 0], - [-0.677, -0.498, 0.529, 0], [0, 0, 0, 1]] + R = [ + [0.395, 0.362, 0.843, 0], + [-0.626, 0.796, -0.056, 0], + [-0.677, -0.498, 0.529, 0], + [0, 0, 0, 1], + ] q = f(R) assert_allclose( - q, [0.82336615, -0.13610694, 0.46344705, -0.29792603], atol=_ATOL) + q, [0.82336615, -0.13610694, 0.46344705, -0.29792603], atol=_ATOL + ) def test_quaternion_from_matrix_6(self, f): R = t.random_rotation_matrix() @@ -512,19 +569,25 @@ def test_quaternion_from_matrix_6(self, f): assert_equal(t.is_same_transform(R, t.quaternion_matrix(q)), True) -@pytest.mark.parametrize('f', [ - t._py_quaternion_multiply, - t.quaternion_multiply, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_multiply, + t.quaternion_multiply, + ], +) def test_quaternion_multiply(f): q = f([4, 1, -2, 3], [8, -5, 6, 7]) assert_allclose(q, [28, -44, -14, 48]) -@pytest.mark.parametrize('f', [ - t._py_quaternion_conjugate, - t.quaternion_conjugate, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_conjugate, + t.quaternion_conjugate, + ], +) def test_quaternion_conjugate(f): q0 = t.random_quaternion() q1 = f(q0) @@ -532,10 +595,13 @@ def test_quaternion_conjugate(f): assert_equal(check, True) -@pytest.mark.parametrize('f', [ - t._py_quaternion_inverse, - t.quaternion_inverse, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_inverse, + t.quaternion_inverse, + ], +) def test_quaternion_inverse(f): q0 = t.random_quaternion() q1 = f(q0) @@ -550,10 +616,13 @@ def test_quaternion_imag(): assert_allclose(t.quaternion_imag([3.0, 0.0, 1.0, 2.0]), [0.0, 1.0, 2.0]) -@pytest.mark.parametrize('f', [ - t._py_quaternion_slerp, - t.quaternion_slerp, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_quaternion_slerp, + t.quaternion_slerp, + ], +) def test_quaternion_slerp(f): q0 = t.random_quaternion() q1 = t.random_quaternion() @@ -566,16 +635,20 @@ def test_quaternion_slerp(f): q = f(q0, q1, 0.5) angle = np.arccos(np.dot(q0, q)) - check = (np.allclose(2.0, np.arccos(np.dot(q0, q1)) / angle) or - np.allclose(2.0, np.arccos(-np.dot(q0, q1)) / angle)) + check = np.allclose(2.0, np.arccos(np.dot(q0, q1)) / angle) or np.allclose( + 2.0, np.arccos(-np.dot(q0, q1)) / angle + ) assert_equal(check, True) -@pytest.mark.parametrize('f', [ - t._py_random_quaternion, - t.random_quaternion, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_random_quaternion, + t.random_quaternion, + ], +) class TestRandomQuaternion(object): def test_random_quaternion_1(self, f): q = f() @@ -587,21 +660,27 @@ def test_random_quaternion_2(self, f): assert_equal(q.shape[0] == 4, True) -@pytest.mark.parametrize('f', [ - t._py_random_rotation_matrix, - t.random_rotation_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_random_rotation_matrix, + t.random_rotation_matrix, + ], +) def test_random_rotation_matrix(f): R = f() assert_allclose(np.dot(R.T, R), np.identity(4), atol=_ATOL) -@pytest.mark.parametrize('f', [ - t._py_inverse_matrix, - t.inverse_matrix, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_inverse_matrix, + t.inverse_matrix, + ], +) class TestInverseMatrix(object): - @pytest.mark.parametrize('size', list(range(1, 7))) + @pytest.mark.parametrize("size", list(range(1, 7))) def test_inverse(self, size, f): # Create a known random state to generate numbers from # these numbers will then be uncorrelated but deterministic @@ -616,10 +695,13 @@ def test_inverse_matrix(self, f): assert_allclose(M1, np.linalg.inv(M0.T)) -@pytest.mark.parametrize('f', [ - t._py_is_same_transform, - t.is_same_transform, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_is_same_transform, + t.is_same_transform, + ], +) class TestIsSameTransform(object): def test_is_same_transform_1(self, f): assert_equal(f(np.identity(4), np.identity(4)), True) @@ -628,10 +710,13 @@ def test_is_same_transform_2(self, f): assert_equal(f(t.random_rotation_matrix(), np.identity(4)), False) -@pytest.mark.parametrize('f', [ - t._py_random_vector, - t.random_vector, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_random_vector, + t.random_vector, + ], +) class TestRandomVector(object): def test_random_vector_1(self, f): v = f(1000) @@ -644,10 +729,13 @@ def test_random_vector_2(self, f): assert_equal(np.any(v0 == v1), False) -@pytest.mark.parametrize('f', [ - t._py_unit_vector, - t.unit_vector, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_unit_vector, + t.unit_vector, + ], +) class TestUnitVector(object): def test_unit_vector_1(self, f): v0 = np.array([0.2, 0.2, 0.2]) @@ -680,10 +768,13 @@ def test_unit_vector_6(self, f): assert_equal(list(f([1.0])), [1.0]) -@pytest.mark.parametrize('f', [ - t._py_vector_norm, - t.vector_norm, -]) +@pytest.mark.parametrize( + "f", + [ + t._py_vector_norm, + t.vector_norm, + ], +) class TestVectorNorm(object): def test_vector_norm_1(self, f): v = np.array([0.2, 0.2, 0.2]) @@ -743,9 +834,13 @@ def test_rotaxis_equal_vectors(): def test_rotaxis_different_vectors(): # use random coordinate system e = np.eye(3) - r = np.array([[0.69884766, 0.59804425, -0.39237102], - [0.18784672, 0.37585347, 0.90744023], - [0.69016342, -0.7078681, 0.15032367]]) + r = np.array( + [ + [0.69884766, 0.59804425, -0.39237102], + [0.18784672, 0.37585347, 0.90744023], + [0.69016342, -0.7078681, 0.15032367], + ] + ) re = np.dot(r, e) for i, j, l in permutations(range(3)): diff --git a/testsuite/MDAnalysisTests/utils/test_units.py b/testsuite/MDAnalysisTests/utils/test_units.py index 7789df1359..8121188c1c 100644 --- a/testsuite/MDAnalysisTests/utils/test_units.py +++ b/testsuite/MDAnalysisTests/utils/test_units.py @@ -31,15 +31,17 @@ class TestUnitEncoding(object): def test_unicode(self): try: - assert_equal(units.lengthUnit_factor[u"\u212b"], 1.0) + assert_equal(units.lengthUnit_factor["\u212b"], 1.0) except KeyError: raise AssertionError("Unicode symbol for Angtrom not supported") def test_unicode_encoding_with_symbol(self): try: - assert_equal(units.lengthUnit_factor[u"Å"], 1.0) + assert_equal(units.lengthUnit_factor["Å"], 1.0) except KeyError: - raise AssertionError("UTF-8-encoded symbol for Angtrom not supported") + raise AssertionError( + "UTF-8-encoded symbol for Angtrom not supported" + ) class TestConstants(object): @@ -48,91 +50,111 @@ class TestConstants(object): # Add a reference value to this dict for every entry in # units.constants constants_reference = ( - ('N_Avogadro', 6.02214129e+23), # mol**-1 - ('elementary_charge', 1.602176565e-19), # As - ('calorie', 4.184), # J - ('Boltzmann_constant', 8.314462159e-3), # KJ (mol K)**-1 - ('Boltzman_constant', 8.314462159e-3), # remove in 2.8.0 - ('electric_constant', 5.526350e-3), # As (Angstroms Volts)**-1 + ("N_Avogadro", 6.02214129e23), # mol**-1 + ("elementary_charge", 1.602176565e-19), # As + ("calorie", 4.184), # J + ("Boltzmann_constant", 8.314462159e-3), # KJ (mol K)**-1 + ("Boltzman_constant", 8.314462159e-3), # remove in 2.8.0 + ("electric_constant", 5.526350e-3), # As (Angstroms Volts)**-1 ) - @pytest.mark.parametrize('name, value', constants_reference) + @pytest.mark.parametrize("name, value", constants_reference) def test_constant(self, name, value): assert_almost_equal(units.constants[name], value) def test_boltzmann_typo_deprecation(self): - wmsg = ("Please use 'Boltzmann_constant' henceforth. The key " - "'Boltzman_constant' was a typo and will be removed " - "in MDAnalysis 2.8.0.") + wmsg = ( + "Please use 'Boltzmann_constant' henceforth. The key " + "'Boltzman_constant' was a typo and will be removed " + "in MDAnalysis 2.8.0." + ) with pytest.warns(DeprecationWarning, match=wmsg): - units.constants['Boltzman_constant'] + units.constants["Boltzman_constant"] class TestConversion(object): @staticmethod def _assert_almost_equal_convert(value, u1, u2, ref): val = units.convert(value, u1, u2) - assert_almost_equal(val, ref, - err_msg="Conversion {0} --> {1} failed".format(u1, u2)) + assert_almost_equal( + val, ref, err_msg="Conversion {0} --> {1} failed".format(u1, u2) + ) nm = 12.34567 - A = nm * 10. - @pytest.mark.parametrize('quantity, unit1, unit2, ref', ( - (nm, 'nm', 'A', A), - (A, 'Angstrom', 'nm', nm), - )) + A = nm * 10.0 + + @pytest.mark.parametrize( + "quantity, unit1, unit2, ref", + ( + (nm, "nm", "A", A), + (A, "Angstrom", "nm", nm), + ), + ) def test_length(self, quantity, unit1, unit2, ref): self._assert_almost_equal_convert(quantity, unit1, unit2, ref) - @pytest.mark.parametrize('quantity, unit1, unit2, ref', ( - (1, 'ps', 'AKMA', 20.45482949774598), - (1, 'AKMA', 'ps', 0.04888821), - (1, 'ps', 'ms', 1e-9), - (1, 'ms', 'ps', 1e9), - (1, 'ps', 'us', 1e-6), - (1, 'us', 'ps', 1e6), - )) + @pytest.mark.parametrize( + "quantity, unit1, unit2, ref", + ( + (1, "ps", "AKMA", 20.45482949774598), + (1, "AKMA", "ps", 0.04888821), + (1, "ps", "ms", 1e-9), + (1, "ms", "ps", 1e9), + (1, "ps", "us", 1e-6), + (1, "us", "ps", 1e6), + ), + ) def test_time(self, quantity, unit1, unit2, ref): self._assert_almost_equal_convert(quantity, unit1, unit2, ref) - @pytest.mark.parametrize('quantity, unit1, unit2, ref', ( - (1, 'kcal/mol', 'kJ/mol', 4.184), - (1, 'kcal/mol', 'eV', 0.0433641), - )) + @pytest.mark.parametrize( + "quantity, unit1, unit2, ref", + ( + (1, "kcal/mol", "kJ/mol", 4.184), + (1, "kcal/mol", "eV", 0.0433641), + ), + ) def test_energy(self, quantity, unit1, unit2, ref): self._assert_almost_equal_convert(quantity, unit1, unit2, ref) - @pytest.mark.parametrize('quantity, unit1, unit2, ref', ( - (1, 'kJ/(mol*A)', 'J/m', 1.66053892103219e-11), - (2.5, 'kJ/(mol*nm)', 'kJ/(mol*A)', 0.25), - (1, 'kcal/(mol*Angstrom)', 'kJ/(mol*Angstrom)', 4.184), - )) + @pytest.mark.parametrize( + "quantity, unit1, unit2, ref", + ( + (1, "kJ/(mol*A)", "J/m", 1.66053892103219e-11), + (2.5, "kJ/(mol*nm)", "kJ/(mol*A)", 0.25), + (1, "kcal/(mol*Angstrom)", "kJ/(mol*Angstrom)", 4.184), + ), + ) def test_force(self, quantity, unit1, unit2, ref): self._assert_almost_equal_convert(quantity, unit1, unit2, ref) - @pytest.mark.parametrize('quantity, unit1, unit2, ref', ( - (1, 'A/ps', 'm/s', 1e-10/1e-12), - (1, 'A/ps', 'nm/ps', 0.1), - (1, 'A/ps', 'pm/ps', 1e2), - (1, 'A/ms', 'A/ps', 1e9), - (1, 'A/us', 'A/ps', 1e6), - (1, 'A/fs', 'A/ps', 1e-3), - (1, 'A/AKMA', 'A/ps', 1/4.888821e-2), - )) + @pytest.mark.parametrize( + "quantity, unit1, unit2, ref", + ( + (1, "A/ps", "m/s", 1e-10 / 1e-12), + (1, "A/ps", "nm/ps", 0.1), + (1, "A/ps", "pm/ps", 1e2), + (1, "A/ms", "A/ps", 1e9), + (1, "A/us", "A/ps", 1e6), + (1, "A/fs", "A/ps", 1e-3), + (1, "A/AKMA", "A/ps", 1 / 4.888821e-2), + ), + ) def test_speed(self, quantity, unit1, unit2, ref): self._assert_almost_equal_convert(quantity, unit1, unit2, ref) - @pytest.mark.parametrize('quantity, unit1, unit2', ((nm, 'Stone', 'nm'), - (nm, 'nm', 'Stone'))) + @pytest.mark.parametrize( + "quantity, unit1, unit2", ((nm, "Stone", "nm"), (nm, "nm", "Stone")) + ) def test_unit_unknown(self, quantity, unit1, unit2): with pytest.raises(ValueError): units.convert(quantity, unit1, unit2) def test_unit_unconvertable(self): nm = 12.34567 - A = nm * 10. + A = nm * 10.0 with pytest.raises(ValueError): - units.convert(A, 'A', 'ps') + units.convert(A, "A", "ps") class TestBaseUnits: @@ -141,12 +163,14 @@ class TestBaseUnits: def ref(): # This is a copy of the dictionary we expect. # We want to know if base units are added or altered. - ref = {"length": "A", - "time": "ps", - "energy": "kJ/mol", - "charge": "e", - "force": "kJ/(mol*A)", - "speed": "A/ps"} + ref = { + "length": "A", + "time": "ps", + "energy": "kJ/mol", + "charge": "e", + "force": "kJ/(mol*A)", + "speed": "A/ps", + } return ref def test_MDANALYSIS_BASE_UNITS_correct(self, ref): diff --git a/testsuite/MDAnalysisTests/visualization/test_streamlines.py b/testsuite/MDAnalysisTests/visualization/test_streamlines.py index 767903c74a..437ccfd97e 100644 --- a/testsuite/MDAnalysisTests/visualization/test_streamlines.py +++ b/testsuite/MDAnalysisTests/visualization/test_streamlines.py @@ -23,8 +23,7 @@ import numpy as np from numpy.testing import assert_allclose import MDAnalysis -from MDAnalysis.visualization import (streamlines, - streamlines_3D) +from MDAnalysis.visualization import streamlines, streamlines_3D from MDAnalysis.coordinates.XTC import XTCWriter from MDAnalysisTests.datafiles import Martini_membrane_gro import pytest @@ -32,50 +31,69 @@ import matplotlib.pyplot as plt import os + @pytest.fixture(scope="session") def univ(): u = MDAnalysis.Universe(Martini_membrane_gro) return u + @pytest.fixture(scope="session") def membrane_xtc(tmpdir_factory, univ): - x_delta, y_delta, z_delta = 0.5, 0.3, 0.2 - tmp_xtc = tmpdir_factory.mktemp('streamlines').join('dummy.xtc') + x_delta, y_delta, z_delta = 0.5, 0.3, 0.2 + tmp_xtc = tmpdir_factory.mktemp("streamlines").join("dummy.xtc") with XTCWriter(str(tmp_xtc), n_atoms=univ.atoms.n_atoms) as xtc_writer: for i in range(5): - univ.atoms.translate([x_delta, y_delta, z_delta]) - xtc_writer.write(univ.atoms) - x_delta += 0.1 - y_delta += 0.08 - z_delta += 0.02 + univ.atoms.translate([x_delta, y_delta, z_delta]) + xtc_writer.write(univ.atoms) + x_delta += 0.1 + y_delta += 0.08 + z_delta += 0.02 return str(tmp_xtc) + def test_streamplot_2D(membrane_xtc, univ): # regression test the data structures # generated by the 2D streamplot code - u1, v1, avg, std = streamlines.generate_streamlines(topology_file_path=Martini_membrane_gro, - trajectory_file_path=membrane_xtc, - grid_spacing=20, - MDA_selection='name PO4', - start_frame=1, - end_frame=2, - xmin=univ.atoms.positions[...,0].min(), - xmax=univ.atoms.positions[...,0].max(), - ymin=univ.atoms.positions[...,1].min(), - ymax=univ.atoms.positions[...,1].max(), - maximum_delta_magnitude=2.0, - num_cores=1) - assert_allclose(u1, np.array([[0.79999924, 0.79999924, 0.80000687, 0.79999542, 0.79998779], - [0.80000019, 0.79999542, 0.79999924, 0.79999542, 0.80001068], - [0.8000021, 0.79999924, 0.80001068, 0.80000305, 0.79999542], - [0.80000019, 0.79999542, 0.80001068, 0.80000305, 0.80000305], - [0.79999828, 0.80000305, 0.80000305, 0.80000305, 0.79999542]])) - assert_allclose(v1, np.array([[0.53999901, 0.53999996, 0.53999996, 0.53999996, 0.54000092], - [0.5399971, 0.54000092, 0.54000092, 0.54000092, 0.5399971 ], - [0.54000473, 0.54000473, 0.54000092, 0.5399971, 0.54000473], - [0.54000092, 0.53999329, 0.53999329, 0.53999329, 0.54000092], - [0.54000092, 0.53999329, 0.53999329, 0.54000092, 0.53999329]])) + u1, v1, avg, std = streamlines.generate_streamlines( + topology_file_path=Martini_membrane_gro, + trajectory_file_path=membrane_xtc, + grid_spacing=20, + MDA_selection="name PO4", + start_frame=1, + end_frame=2, + xmin=univ.atoms.positions[..., 0].min(), + xmax=univ.atoms.positions[..., 0].max(), + ymin=univ.atoms.positions[..., 1].min(), + ymax=univ.atoms.positions[..., 1].max(), + maximum_delta_magnitude=2.0, + num_cores=1, + ) + assert_allclose( + u1, + np.array( + [ + [0.79999924, 0.79999924, 0.80000687, 0.79999542, 0.79998779], + [0.80000019, 0.79999542, 0.79999924, 0.79999542, 0.80001068], + [0.8000021, 0.79999924, 0.80001068, 0.80000305, 0.79999542], + [0.80000019, 0.79999542, 0.80001068, 0.80000305, 0.80000305], + [0.79999828, 0.80000305, 0.80000305, 0.80000305, 0.79999542], + ] + ), + ) + assert_allclose( + v1, + np.array( + [ + [0.53999901, 0.53999996, 0.53999996, 0.53999996, 0.54000092], + [0.5399971, 0.54000092, 0.54000092, 0.54000092, 0.5399971], + [0.54000473, 0.54000473, 0.54000092, 0.5399971, 0.54000473], + [0.54000092, 0.53999329, 0.53999329, 0.53999329, 0.54000092], + [0.54000092, 0.53999329, 0.53999329, 0.54000092, 0.53999329], + ] + ), + ) assert avg == pytest.approx(0.965194167) assert std == pytest.approx(4.444808820e-06) @@ -84,18 +102,20 @@ def test_streamplot_2D_zero_return(membrane_xtc, univ, tmpdir): # simple roundtrip test to ensure that # zeroed arrays are returned by the 2D streamplot # code when called with an empty selection - u1, v1, avg, std = streamlines.generate_streamlines(topology_file_path=Martini_membrane_gro, - trajectory_file_path=membrane_xtc, - grid_spacing=20, - MDA_selection='name POX', - start_frame=1, - end_frame=2, - xmin=univ.atoms.positions[...,0].min(), - xmax=univ.atoms.positions[...,0].max(), - ymin=univ.atoms.positions[...,1].min(), - ymax=univ.atoms.positions[...,1].max(), - maximum_delta_magnitude=2.0, - num_cores=1) + u1, v1, avg, std = streamlines.generate_streamlines( + topology_file_path=Martini_membrane_gro, + trajectory_file_path=membrane_xtc, + grid_spacing=20, + MDA_selection="name POX", + start_frame=1, + end_frame=2, + xmin=univ.atoms.positions[..., 0].min(), + xmax=univ.atoms.positions[..., 0].max(), + ymin=univ.atoms.positions[..., 1].min(), + ymax=univ.atoms.positions[..., 1].max(), + maximum_delta_magnitude=2.0, + num_cores=1, + ) assert_allclose(u1, np.zeros((5, 5))) assert_allclose(v1, np.zeros((5, 5))) assert avg == approx(0.0) @@ -107,20 +127,22 @@ def test_streamplot_3D(membrane_xtc, univ, tmpdir): # for a roundtrip plotting test, simply # aim to check for sensible values # returned by generate_streamlines_3d - dx, dy, dz = streamlines_3D.generate_streamlines_3d(topology_file_path=Martini_membrane_gro, - trajectory_file_path=membrane_xtc, - grid_spacing=20, - MDA_selection='name PO4', - start_frame=1, - end_frame=2, - xmin=univ.atoms.positions[...,0].min(), - xmax=univ.atoms.positions[...,0].max(), - ymin=univ.atoms.positions[...,1].min(), - ymax=univ.atoms.positions[...,1].max(), - zmin=univ.atoms.positions[...,2].min(), - zmax=univ.atoms.positions[...,2].max(), - maximum_delta_magnitude=2.0, - num_cores=1) + dx, dy, dz = streamlines_3D.generate_streamlines_3d( + topology_file_path=Martini_membrane_gro, + trajectory_file_path=membrane_xtc, + grid_spacing=20, + MDA_selection="name PO4", + start_frame=1, + end_frame=2, + xmin=univ.atoms.positions[..., 0].min(), + xmax=univ.atoms.positions[..., 0].max(), + ymin=univ.atoms.positions[..., 1].min(), + ymax=univ.atoms.positions[..., 1].max(), + zmin=univ.atoms.positions[..., 2].min(), + zmax=univ.atoms.positions[..., 2].max(), + maximum_delta_magnitude=2.0, + num_cores=1, + ) assert dx.shape == (5, 5, 2) assert dy.shape == (5, 5, 2) assert dz.shape == (5, 5, 2) diff --git a/testsuite/pyproject.toml b/testsuite/pyproject.toml index 63450efa74..8e9ed99802 100644 --- a/testsuite/pyproject.toml +++ b/testsuite/pyproject.toml @@ -171,6 +171,9 @@ setup\.py | MDAnalysisTests/formats/.*\.py | MDAnalysisTests/parallelism/.*\.py | MDAnalysisTests/scripts/.*\.py +| MDAnalysisTests/import/.*\.py +| MDAnalysisTests/utils/.*\.py +| MDAnalysisTests/visualization/.*\.py ) ''' extend-exclude = '''