From 53ccf6def40ca0e1342179269b1dfeef0e4877b4 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 12 Mar 2020 11:26:13 +0100 Subject: [PATCH] Increase coverage of leaflet.py (#2603) Commit title: Increase coverage of leaflet.py (#2603) Contents of commit: ============= 1) This commit adds a series of tests to `analysis/leaflet.py` which cover parts of the code which did not use to be tested (Issue #2600). As of this commit, coverage is now at over 95% for this module. 2) This commit also fixes a missing import for the selection module (#2612). Unaltered commit history: ================= * _get_graph without self.pbc for leaflet.py * using update * add test for leaflet write_selection and fix one missing module in leaflet.py * tyop * check expected lipids contact are returned when pbc on * check leaflet write_selection output * remove unused codes * add more tests on update function * cover three options for sparse * add test on components index in group & add name CHANGELOG * add test on update without cutoff * PEP8 formatting * exclude valueerror in matrix cal from coverage * add author --- package/AUTHORS | 2 +- package/CHANGELOG | 3 +- package/MDAnalysis/analysis/leaflet.py | 5 +- .../MDAnalysisTests/analysis/test_leaflet.py | 107 +++++++++++++++++- 4 files changed, 112 insertions(+), 5 deletions(-) diff --git a/package/AUTHORS b/package/AUTHORS index 05f38057159..00cde2773cb 100644 --- a/package/AUTHORS +++ b/package/AUTHORS @@ -135,7 +135,7 @@ Chronological list of authors - Hugo MacDermott-Opeskin - Anshul Angaria - Shubham Sharma - + - Yuxuan Zhuang External code ------------- diff --git a/package/CHANGELOG b/package/CHANGELOG index 17ef7119be3..fcda3ba8281 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -16,7 +16,7 @@ The rules for this file: mm/dd/yy richardjgowers, kain88-de, lilyminium, p-j-smith, bdice, joaomcteixeira, PicoCentauri, davidercruz, jbarnoud, RMeli, IAlibay, mtiberti, CCook96, Yuan-Yu, xiki-tempula, HTian1997, Iv-Hristov, hmacdope, AnshulAngaria, - ss62171, Luthaf + ss62171, Luthaf, yuxuanzhuang * 0.21.0 @@ -64,6 +64,7 @@ Fixes match TPRParser. (PR #2408) * Added parmed to setup.py * Fixed example docs for polymer persistence length (#2582) + * Added missing selection module to leaflet.py (Issue #2612) Enhancements * Added ability to use Chemfiles as a trajectory reader backend (PR #1862) diff --git a/package/MDAnalysis/analysis/leaflet.py b/package/MDAnalysis/analysis/leaflet.py index e70e2359ee7..0cde51c7d8a 100644 --- a/package/MDAnalysis/analysis/leaflet.py +++ b/package/MDAnalysis/analysis/leaflet.py @@ -79,6 +79,7 @@ from .. import core from . import distances +from .. import selections from ..due import due, Doi @@ -174,7 +175,7 @@ def _get_graph(self): # only try distance array try: adj = distances.contact_matrix(coord, cutoff=self.cutoff, returntype="numpy", box=box) - except ValueError: + except ValueError: # pragma: no cover warnings.warn('N x N matrix too big, use sparse=True or sparse=None', category=UserWarning, stacklevel=2) raise @@ -186,7 +187,7 @@ def _get_graph(self): try: # this works for small-ish systems and depends on system memory adj = distances.contact_matrix(coord, cutoff=self.cutoff, returntype="numpy", box=box) - except ValueError: + except ValueError: # pragma: no cover # but use a sparse matrix method for larger systems for memory reasons warnings.warn( 'N x N matrix too big - switching to sparse matrix method (works fine, but is currently rather ' diff --git a/testsuite/MDAnalysisTests/analysis/test_leaflet.py b/testsuite/MDAnalysisTests/analysis/test_leaflet.py index 143c815fbc5..3cac111e04a 100644 --- a/testsuite/MDAnalysisTests/analysis/test_leaflet.py +++ b/testsuite/MDAnalysisTests/analysis/test_leaflet.py @@ -26,13 +26,16 @@ from numpy.testing import assert_equal, assert_almost_equal import numpy as np +import networkx as NX from MDAnalysis.analysis.leaflet import LeafletFinder, optimize_cutoff from MDAnalysisTests.datafiles import Martini_membrane_gro - LIPID_HEAD_STRING = "name PO4" +def lines2one(lines): + """Join lines and squash all whitespace""" + return " ".join(" ".join(lines).split()) @pytest.fixture() def universe(): @@ -69,3 +72,105 @@ def test_optimize_cutoff(universe, lipid_heads): cutoff, N = optimize_cutoff(universe, lipid_heads, pbc=True) assert N == 2 assert_almost_equal(cutoff, 10.5, decimal=4) + + +def test_pbc_on_off(universe, lipid_heads): + lfls_pbc_on = LeafletFinder(universe, lipid_heads, pbc=True) + lfls_pbc_off = LeafletFinder(universe, lipid_heads, pbc=False) + assert lfls_pbc_on.graph.size() > lfls_pbc_off.graph.size() + + +def test_pbc_on_off_difference(universe, lipid_heads): + lfls_pbc_on = LeafletFinder(universe, lipid_heads, cutoff=7, pbc=True) + lfls_pbc_off = LeafletFinder(universe, lipid_heads, cutoff=7, pbc=False) + pbc_on_graph = lfls_pbc_on.graph + pbc_off_graph = lfls_pbc_off.graph + diff_graph = NX.difference(pbc_on_graph, pbc_off_graph) + assert_equal(set(diff_graph.edges), {(69, 153), (73, 79), + (206, 317), (313, 319)}) + + +@pytest.mark.parametrize("sparse", [True, False, None]) +def test_sparse_on_off_none(universe, lipid_heads, sparse): + lfls_ag = LeafletFinder(universe, lipid_heads, cutoff=15.0, pbc=True, + sparse=sparse) + assert_almost_equal(len(lfls_ag.graph.edges), 1903, decimal=4) + + +def test_cutoff_update(universe, lipid_heads): + lfls_ag = LeafletFinder(universe, lipid_heads, cutoff=15.0, pbc=True) + lfls_ag.update(cutoff=1.0) + assert_almost_equal(lfls_ag.cutoff, 1.0, decimal=4) + assert_almost_equal(len(lfls_ag.groups()), 360, decimal=4) + + +def test_cutoff_update_default(universe, lipid_heads): + lfls_ag = LeafletFinder(universe, lipid_heads, cutoff=15.0, pbc=True) + lfls_ag.update() + assert_almost_equal(lfls_ag.cutoff, 15.0, decimal=4) + assert_almost_equal(len(lfls_ag.groups()), 2, decimal=4) + + +def test_write_selection(universe, lipid_heads, tmpdir): + lfls_ag = LeafletFinder(universe, lipid_heads, cutoff=15.0, pbc=True) + with tmpdir.as_cwd(): + filename = lfls_ag.write_selection('leaflet.vmd') + expected_output = lines2one([ + """# leaflets based on select= cutoff=15.000000 + # MDAnalysis VMD selection + atomselect macro leaflet_1 {index 1 13 25 37 49 61 73 85 \\ + 97 109 121 133 145 157 169 181 \\ + 193 205 217 229 241 253 265 277 \\ + 289 301 313 325 337 349 361 373 \\ + 385 397 409 421 433 445 457 469 \\ + 481 493 505 517 529 541 553 565 \\ + 577 589 601 613 625 637 649 661 \\ + 673 685 697 709 721 733 745 757 \\ + 769 781 793 805 817 829 841 853 \\ + 865 877 889 901 913 925 937 949 \\ + 961 973 985 997 1009 1021 1033 1045 \\ + 1057 1069 1081 1093 1105 1117 1129 1141 \\ + 1153 1165 1177 1189 1201 1213 1225 1237 \\ + 1249 1261 1273 1285 1297 1309 1321 1333 \\ + 1345 1357 1369 1381 1393 1405 1417 1429 \\ + 1441 1453 1465 1477 1489 1501 1513 1525 \\ + 1537 1549 1561 1573 1585 1597 1609 1621 \\ + 1633 1645 1657 1669 1681 1693 1705 1717 \\ + 1729 1741 1753 1765 1777 1789 1801 1813 \\ + 1825 1837 1849 1861 1873 1885 1897 1909 \\ + 1921 1933 1945 1957 1969 1981 1993 2005 \\ + 2017 2029 2041 2053 2065 2077 2089 2101 \\ + 2113 2125 2137 2149 } + # MDAnalysis VMD selection + atomselect macro leaflet_2 {index 2521 2533 2545 2557 2569 2581 2593 2605 \\ + 2617 2629 2641 2653 2665 2677 2689 2701 \\ + 2713 2725 2737 2749 2761 2773 2785 2797 \\ + 2809 2821 2833 2845 2857 2869 2881 2893 \\ + 2905 2917 2929 2941 2953 2965 2977 2989 \\ + 3001 3013 3025 3037 3049 3061 3073 3085 \\ + 3097 3109 3121 3133 3145 3157 3169 3181 \\ + 3193 3205 3217 3229 3241 3253 3265 3277 \\ + 3289 3301 3313 3325 3337 3349 3361 3373 \\ + 3385 3397 3409 3421 3433 3445 3457 3469 \\ + 3481 3493 3505 3517 3529 3541 3553 3565 \\ + 3577 3589 3601 3613 3625 3637 3649 3661 \\ + 3673 3685 3697 3709 3721 3733 3745 3757 \\ + 3769 3781 3793 3805 3817 3829 3841 3853 \\ + 3865 3877 3889 3901 3913 3925 3937 3949 \\ + 3961 3973 3985 3997 4009 4021 4033 4045 \\ + 4057 4069 4081 4093 4105 4117 4129 4141 \\ + 4153 4165 4177 4189 4201 4213 4225 4237 \\ + 4249 4261 4273 4285 4297 4309 4321 4333 \\ + 4345 4357 4369 4381 4393 4405 4417 4429 \\ + 4441 4453 4465 4477 4489 4501 4513 4525 \\ + 4537 4549 4561 4573 4585 4597 4609 4621 \\ + 4633 4645 4657 4669 } + +"""]) + + assert lines2one(open('leaflet.vmd').readlines()) == expected_output + + +def test_component_index_is_not_none(universe, lipid_heads): + lfls_ag = LeafletFinder(universe, lipid_heads, cutoff=15.0, pbc=True) + assert_almost_equal(len(lfls_ag.groups(component_index=0)), 180, decimal=4)