Coverage for tests/test_membrane_curvature.py : 89%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Unit and regression test for the membrane_curvature package.
3"""
6import pytest
7from membrane_curvature.surface import normalized_grid, derive_surface, get_z_surface
8from membrane_curvature.curvature import mean_curvature, gaussian_curvature
9import numpy as np
10from numpy.testing import assert_almost_equal
11import MDAnalysis as mda
12from membrane_curvature.tests.datafiles import (GRO_PO4_SMALL, XTC_PO4_SMALL)
13from membrane_curvature.base import MembraneCurvature
15# Reference data from datafile
16MEMBRANE_CURVATURE_DATA = {
18 'z_avg_coords': np.array([[15.52998744, 15.68577027, 15.54460264, 15.42630775, 15.41610875,
19 15.5227999, 15.40030259, 15.47866627, 15.5402739, 15.58982381],
20 [15.7210999, 15.66186774, 15.66852082, 15.5650629, 15.59180416,
21 15.52540419, 15.43453586, 15.31625871, 15.53287837, 15.72669662],
22 [15.65202988, 15.87587967, 15.80443607, 15.2156001, 15.9012679,
23 15.61628637, 15.54388155, 15.51714352, 15.56670715, 15.67794791],
24 [15.79848438, 15.86021965, 15.91864504, 15.69624091, 16.07622673,
25 15.55569959, 15.33016631, 15.51812384, 15.57359306, 15.74745874],
26 [15.99946331, 15.80777305, 15.93547516, 16.06895507, 16.49331617,
27 16.47925099, 15.74151387, 15.63836954, 15.72500532, 15.91917461],
28 [16.00306618, 15.44807954, 14.91708903, 15.62196315, 15.63327226,
29 16.56862831, 16.11996038, 15.89331185, 15.83679604, 15.98079948],
30 [15.76326987, 15.64245421, 15.52017543, 15.47039083, 14.88002689,
31 15.53698847, 15.80894958, 15.80674416, 15.7546208, 15.88995425],
32 [15.70029967, 15.61600719, 15.53771198, 15.47668145, 15.19293903,
33 15.41956353, 15.66099601, 15.71207747, 15.80128901, 15.71542822],
34 [15.68171964, 15.63995413, 15.53009812, 15.21636634, 15.27028742,
35 15.38000841, 15.51385563, 15.64464232, 15.79420718, 15.77794963],
36 [11.9375362, 15.67473274, 15.56693593, 15.28816211, 15.26380259,
37 15.34311786, 15.50101777, 15.5245863, 13.5766693, 15.69553947]]),
39 'z_ref': {
40 'small': np.array([[10., 11., 12.], [15., 20, 25], [15., 40, 50]]),
41 'all': np.array([[15.96339989, 16.36299992, 16.57025003, 16.30183315, 16.14233398,
42 15.94885731, 15.99250078, 16.17940025, 16.08424997, 15.93374944],
43 [15.9995718, 16.48649979, 16.59700012, 16.3276666, 16.26959991,
44 15.77983316, 15.67449999, 15.59950042, 16.05650028, 16.11733341],
45 [15.9301672, 16.04720001, 16.24383338, 16.38975, 16.05666653,
46 15.71950006, 15.7414999, 15.65285724, 15.71783352, 15.91666635],
47 [15.87350019, 16.0994997, 16.45200014, 16.38366667, 15.91100025,
48 15.44099998, 15.55220013, 15.74933386, 15.7957499, 15.93225002],
49 [15.89100003, 16.01559982, 16.45950031, 16.68450022, 16.34674978,
50 16.27950001, 15.97475028, 16.0142498, 16.07933331, 15.96724939],
51 [15.81012511, 15.84583362, 16.09700036, 15.98525, 15.49299908,
52 16.36499977, 16.20639992, 15.8682003, 15.82559967, 15.87400055],
53 [15.73475003, 15.67866707, 15.85220013, 15.60228566, 15.12299967,
54 15.70033328, 15.87920036, 15.80550003, 15.60928576, 15.8010006],
55 [15.79039974, 15.91499996, 15.97549987, 15.80860004, 15.73637486,
56 15.51133362, 15.80240021, 15.78233337, 15.65516663, 15.72000027],
57 [15.8411665, 16.13249969, 16.48759995, 16.25674987, 15.78233369,
58 15.71450011, 15.33062541, 15.99500027, 15.83737516, 15.74500052],
59 [15.82900023, 16.06166649, 16.2973334, 16.43733342, 16.12957178,
60 16.09366608, 15.95349979, 16.22599983, 16.17750025, 16.00225067]])},
62 'gaussian_curvature': {
63 'small': np.array([[-2.19478738e-02, -2.32254318e-03, -5.47176909e-04],
64 [-1.38453218e-01, -1.21945074e-03, -1.35208221e-04],
65 [-9.72884280e-04, -3.94840040e-04, -1.32808172e-04]]),
67 'all': np.array([[-0.00189129, 0.04934495, 0.04660196, -0.00351411, -0.01943406,
68 -0.03893078, -0.0246221, -0.03280081, -0.12642188, -0.03525892],
69 [-0.00693942, 0.03182844, 0.00120618, -0.00352255, 0.00342091,
70 -0.00142247, 0.02465936, 0.04605395, -0.0106348, -0.00313678],
71 [-0.01649198, 0.00168855, -0.02731173, -0.01564413, -0.00973393,
72 0.02368517, -0.00604347, 0.0169452, 0.0113627, -0.00027235],
73 [0.00088378, -0.00464509, 0.0075489, 0.02877688, -0.00328288,
74 0.07988983, 0.02487373, -0.00071568, -0.0050775, -0.02188734],
75 [-0.013283, -0.01107469, 0.02580236, 0.0847512, -0.07205011,
76 -0.05251712, -0.03977956, -0.03174133, 0.0151017, 0.00278634],
77 [-0.00688401, -0.01030927, -0.03964658, -0.01066038, 0.01942349,
78 0.01216024, 0.05635031, -0.0138591, -0.00547026, -0.02372161],
79 [0.00552771, 0.00111084, -0.0688243, 0.0081551, 0.14126933,
80 -0.01476609, -0.00715425, -0.0059002, 0.02781192, 0.00485525],
81 [-0.02954713, -0.01709626, -0.01171343, -0.00766876, -0.01780511,
82 -0.04009694, -0.00779307, -0.04735893, 0.00799721, -0.00961057],
83 [-0.0033638, 0.009781, 0.06724205, 0.00795326, 0.00034145,
84 0.02682387, 0.10108879, -0.01423631, -0.01802192, -0.00922448],
85 [-0.00313899, -0.00418259, 0.03487913, -0.04456535, -0.00768992,
86 -0.00642677, 0.0254065, -0.01830984, -0.00904487, -0.01182518]])},
88 'mean_curvature': {
89 'small': np.array([[-0.16037507, -0.04033506, -0.02057139],
90 [-0.99647932, -0.14502529, -0.04590719],
91 [-0.05019947, -0.26763173, -0.16841648]]),
93 'all': np.array([[-0.06396822, -0.2254189, -0.22399141, -0.02498465, -0.05090628,
94 0.09999741, 0.10476551, 0.05358351, -0.12631834, -0.09827992],
95 [-0.09151143, -0.19973338, -0.13808081, -0.04574428, -0.10289627,
96 0.04137634, 0.18304112, 0.2249239, -0.04760685, -0.16729716],
97 [0.01779114, 0.04597901, 0.00778294, -0.09933345, 0.03402726,
98 0.16382893, 0.09622266, 0.15120851, 0.13753756, 0.04029748],
99 [0.0369991, -0.00233226, -0.16181129, -0.18932471, 0.01349983,
100 0.28269057, 0.16712506, -0.01942325, 0.03927295, 0.03811465],
101 [0.06309625, 0.00820666, -0.16715942, -0.29301601, -0.21669994,
102 -0.07393958, 0.0129063, -0.04319332, -0.14495082, -0.07021294],
103 [0.05875299, 0.04393517, -0.0837562, 0.05789939, 0.19497179,
104 -0.25517884, -0.25387131, 0.03625653, 0.03502722, 0.01136375],
105 [0.08988405, 0.10299823, 0.04910499, 0.21748747, 0.41463502,
106 0.03913769, -0.1765791, 0.03554145, 0.1677006, 0.10516181],
107 [-0.0095539, -0.0364163, -0.00168944, 0.06394463, 0.04456537,
108 0.25037463, 0.03814847, 0.02531541, 0.11902046, 0.10177806],
109 [-0.00184591, -0.12102329, -0.28902913, -0.0966804, 0.03156109,
110 0.16964647, 0.336664, -0.03280685, -0.03212416, 0.08340905],
111 [-0.01478105, -0.08136444, -0.23413597, -0.1472945, 0.06672947,
112 0.09468121, 0.21140388, -0.03506431, -0.03308529, 0.01943328]])},
114 'grid': {'small':
115 {'upper': np.array([[15., 15., np.nan], [15., np.nan, np.nan], [15., np.nan, np.nan]]),
116 'lower': np.array([[np.nan, np.nan, 12.], [np.nan, 12., 12.], [np.nan, 12., 12.]])}},
118 'beads': {'small':
119 {'upper': {'POPC': [0, 1, 2, 3]},
120 'lower': {'POPC': [4, 5, 6, 7, 8]}}}
122}
125@pytest.fixture
126def small_grofile():
127 u = mda.Universe(GRO_PO4_SMALL)
128 sel = u.select_atoms('name PO4')
129 return sel
132def test_gaussian_curvature_small():
133 K_test = gaussian_curvature(MEMBRANE_CURVATURE_DATA['z_ref']['small'])
134 for k, k_test in zip(MEMBRANE_CURVATURE_DATA['gaussian_curvature']['small'], K_test):
135 assert_almost_equal(k, k_test)
138def test_mean_curvature_small():
139 H_test = mean_curvature(MEMBRANE_CURVATURE_DATA['z_ref']['small'])
140 for h, h_test in zip(MEMBRANE_CURVATURE_DATA['mean_curvature']['small'], H_test):
141 assert_almost_equal(h, h_test)
144def test_gaussian_curvature_all():
145 K_test = gaussian_curvature(MEMBRANE_CURVATURE_DATA['z_ref']['all'])
146 for k, k_test in zip(MEMBRANE_CURVATURE_DATA['gaussian_curvature']['all'], K_test):
147 assert_almost_equal(k, k_test)
150def test_mean_curvature_all():
151 H_test = mean_curvature(MEMBRANE_CURVATURE_DATA['z_ref']['all'])
152 for h, h_test in zip(MEMBRANE_CURVATURE_DATA['mean_curvature']['all'], H_test):
153 assert_almost_equal(h, h_test)
156@pytest.mark.parametrize('n_cells, grid_z_coords', [
157 (3, np.full((3, 3), 10.)),
158 (3, np.array([[10., 20., 30.], [10., 20., 30.], [10., 20., 30.]], dtype=float))
159])
160def test_normalized_grid_identity_other_values(n_cells, grid_z_coords):
161 unit = np.ones([n_cells, n_cells])
162 z_avg = normalized_grid(grid_z_coords, unit)
163 assert_almost_equal(z_avg, grid_z_coords)
166def test_normalized_grid_more_beads():
167 # sum of z coordinate in grid,
168 grid_z_coords = np.full((3, 3), 10.)
169 # grid number of beads per unit
170 norm_grid = np.array([[2., 1., 1.], [1., 2., 1.], [1., 1., 2.]])
171 # avg z coordinate in grid
172 expected_normalized_surface = np.array([[5., 10., 10.], [10., 5., 10.], [10., 10., 5.]])
173 average_surface = normalized_grid(grid_z_coords, norm_grid)
174 assert_almost_equal(average_surface, expected_normalized_surface)
177def test_derive_surface(small_grofile):
178 n_cells, max_width = 3, 30
179 expected_surface = np.array(([150., 150., 120.], [150., 120., 120.], [150., 120., 120.]))
180 max_width_x = max_width_y = max_width
181 surface = derive_surface(small_grofile, n_cells, n_cells, max_width_x, max_width_y)
182 assert_almost_equal(surface, expected_surface)
185def test_derive_surface_from_numpy():
186 dummy_array = np.array([[0., 0., 150.], [100., 0., 150.], [200., 0., 150.],
187 [0., 100., 150.], [100., 100., 120.], [200., 100., 120.],
188 [0., 200., 120.], [100., 200., 120.], [200., 200., 120.]])
189 x_bin = y_bin = 3
190 x_range = y_range = (0, 300)
191 expected_surface = np.array(([150., 150., 120.], [150., 120., 120.], [150., 120., 120.]))
192 surface = get_z_surface(dummy_array, x_bin, y_bin, x_range, y_range)
193 assert_almost_equal(surface, expected_surface)
196@pytest.mark.parametrize('x_bin, y_bin, x_range, y_range, expected_surface', [
197 (3, 3, (0, 300), (0, 300), np.array(([150., np.nan, 150.],
198 [np.nan, 150., 150.],
199 [150., 150., 150.]))),
200 (3, 4, (0, 300), (0, 400), np.array([[150., np.nan, 150., np.nan],
201 [np.nan, 150., 150., np.nan],
202 [150., 150., 150., np.nan]]))
203])
204def test_get_z_surface(x_bin, y_bin, x_range, y_range, expected_surface):
205 dummy_array = np.array([[0., 0., 150.], [0., 0., 150.], [200., 0., 150.],
206 [0., 0., 150.], [100., 100., 150.], [200., 100., 150.],
207 [0., 200., 150.], [100., 200., 150.], [200., 200., 150.]])
208 surface = get_z_surface(dummy_array, x_bin, y_bin, x_range, y_range)
209 assert_almost_equal(surface, expected_surface)
212class TestMembraneCurvature(object):
213 @pytest.fixture()
214 def universe(self):
215 return mda.Universe(GRO_PO4_SMALL)
217 @pytest.fixture()
218 def universe_dummy(self):
219 a = np.array([[0., 0., 150.], [0., 0., 150.], [200., 0., 150.],
220 [0., 0., 150.], [100., 100., 150.], [200., 100., 150.],
221 [0., 200., 150.], [100., 200., 150.], [200., 200., 150.]])
223 u = mda.Universe(a, n_atoms=9)
224 u.dimensions = [300, 300, 300, 90., 90., 90.]
226 return u
228 @pytest.fixture()
229 def universe_dummy_full(self):
230 a = np.array([[0., 0., 150.], [100., 0., 150.], [200., 0., 150.],
231 [0., 200., 150.], [100., 200., 120.], [200., 200., 120.],
232 [0., 100., 120.], [100., 100., 120.], [200., 100., 120.]])
234 u = mda.Universe(a, n_atoms=9)
235 u.dimensions = [300, 300, 300, 90., 90., 90.]
237 return u
239 @pytest.fixture()
240 def universe_dummy_wrap(self):
241 # Atoms out of bounds in x
242 # +-----------+
243 # | | 8 | 9 | 7
244 # +-----------+
245 # 6 | 4 | 5 | |
246 # +-----------+
247 # | | 2 | 3 | 1
248 # +-----------+
249 a = np.array([[300., 0., 110.], [100., 0., 150.], [200., 0., 150.],
250 [0., 100., 150.], [100., 100., 150.], [-100., 100., 150.],
251 [300., 200., 110.], [100., 200., 150.], [200., 200., 150.]])
253 u = mda.Universe(a, n_atoms=9)
254 u.dimensions = [300, 300, 300, 90., 90., 90.]
255 return u
257 # Equivalent to universe_dummy_wrap when wrapping is applied.
258 # Atoms out of bounds in x and y
259 @pytest.fixture()
260 def universe_dummy_wrap_xy(self):
261 a = np.array([[300., 0., 110.], [100., 0., 150.], [200., 0., 150.],
262 [0., -200., 150.], [100., -200., 150.], [-100., 100., 150.],
263 [300., 200., 110.], [100., 200., 150.], [200., 200., 150.]])
265 u = mda.Universe(a, n_atoms=9)
266 u.dimensions = [300, 300, 300, 90., 90., 90.]
268 return u
270 @pytest.fixture()
271 def dummy_surface(self):
272 surface = np.array([[110., 150., 110.],
273 [150., 150., 150.],
274 [150., 150., 150.]])
275 return surface
277 @pytest.fixture()
278 def curvature_unwrapped_universe(self, universe_dummy_wrap):
279 return MembraneCurvature(universe_dummy_wrap,
280 n_x_bins=3,
281 n_y_bins=3).run()
283 @pytest.fixture()
284 def curvature_unwrapped_universe_xy(self, universe_dummy_wrap_xy):
285 return MembraneCurvature(universe_dummy_wrap_xy,
286 n_x_bins=3,
287 n_y_bins=3).run()
289 def test_invalid_selection(self, universe):
290 with pytest.raises(ValueError, match=r'Invalid selection'):
291 MembraneCurvature(universe, select='name P')
293 def test_grid_bigger_than_simulation_box_x_dim(self, universe):
294 regex = (r"Grid range in x does not cover entire "
295 r"dimensions of simulation box.\n Minimum dimensions "
296 r"must be equal to simulation box.")
297 with pytest.warns(UserWarning, match=regex):
298 MembraneCurvature(universe, select='name PO4', x_range=(0, 10))
300 def test_grid_bigger_than_simulation_box_y_dim(self, universe):
301 regex = (r"Grid range in y does not cover entire "
302 r"dimensions of simulation box.\n Minimum dimensions "
303 r"must be equal to simulation box.")
304 with pytest.warns(UserWarning, match=regex):
305 MembraneCurvature(universe, select='name PO4', y_range=(0, 10))
307 @pytest.mark.parametrize('x_bin, y_bin, x_range, y_range, expected_surface', [
308 (3, 3, (0, 300), (0, 300), np.array(([150., np.nan, 150.],
309 [np.nan, 150., 150.],
310 [150., 150., 150.]))),
311 (3, 4, (0, 300), (0, 400), np.array([[150., np.nan, 150., np.nan],
312 [np.nan, 150., 150., np.nan],
313 [150., 150., 150., np.nan]]))
314 ])
315 def test_analysis_get_z_surface_dummy(self, universe_dummy, x_bin, y_bin, x_range, y_range, expected_surface):
316 u = universe_dummy
317 mc = MembraneCurvature(u, select='all',
318 n_x_bins=x_bin,
319 n_y_bins=y_bin,
320 x_range=x_range,
321 y_range=y_range).run()
323 avg_surface = mc.results.average_z_surface
324 assert_almost_equal(avg_surface, expected_surface)
326 @pytest.mark.xfail(reason="Wrapping coordinates not applied.")
327 @pytest.mark.parametrize('x_bin, y_bin, expected_surface', [
328 (3, 3,
329 np.array([[150., 150., 120.],
330 [150., 120., 120.],
331 [150., 120., 120.]])),
332 (4, 4,
333 np.array([[150., 150., 135., 120.],
334 [150., 120., 120., np.nan],
335 [150., 120., 120., 120.],
336 [150., np.nan, 120., 120.]])),
337 (5, 5,
338 np.array([[150., 150., 150., 120., 120.],
339 [150., 120., np.nan, 120., np.nan],
340 [150., np.nan, 120., np.nan, 120.],
341 [150., 120., np.nan, 120., np.nan],
342 [150., np.nan, 120., np.nan, 120.]]))
343 ])
344 def test_analysis_get_z_surface(self, universe, x_bin, y_bin, expected_surface):
345 mc = MembraneCurvature(universe,
346 select='name PO4',
347 n_x_bins=x_bin,
348 n_y_bins=y_bin).run()
349 avg_surface = mc.results.average_z_surface
350 assert_almost_equal(avg_surface, expected_surface)
352 # test using wrap=True with test grofile
353 def test_analysis_mean_wrap(self, universe):
354 expected_mean = np.array([[7.50000000e+00, 1.33985392e-01, 2.77315457e-04],
355 [-2.77315457e-04, -3.53944270e-01, -7.50000000e+00],
356 [-2.77315457e-04, -5.01100068e-01, -7.50000000e+00]])
357 mc = MembraneCurvature(universe,
358 select='name PO4',
359 n_x_bins=3,
360 n_y_bins=3).run()
361 avg_mean = mc.results.average_mean
362 assert_almost_equal(avg_mean, expected_mean)
364 # test using wrap=False with test grofile
365 def test_analysis_mean_no_wrap(self, universe):
366 expected_mean = np.array([[7.50000000e+00, 1.33985392e-01, 2.77315457e-04],
367 [-2.77315457e-04, -3.53944270e-01, -7.50000000e+00],
368 [-2.77315457e-04, -5.01100068e-01, -7.50000000e+00]])
369 mc = MembraneCurvature(universe,
370 select='name PO4',
371 n_x_bins=3,
372 n_y_bins=3,
373 wrap=False).run()
374 avg_mean = mc.results.average_mean
375 assert_almost_equal(avg_mean, expected_mean)
377 # test using dummy Universe with atoms out of boounds
378 # with wrap=True (default)
379 # +-----------+ +-----------+
380 # | | 8 | 9 | 7 | 7 | 8 | 9 |
381 # +-----------+ +-----------+
382 # 6 | 4 | 5 | | ---> | 4 | 5 | 6 |
383 # +-----------+ +-----------+
384 # | | 2 | 3 | 1 | 1 | 2 | 3 |
385 # +-----------+ +-----------+
386 #
387 # test surface in universe with atoms out of bounds in x
388 def test_analysis_get_z_surface_wrap(self, curvature_unwrapped_universe, dummy_surface):
389 avg_surface = curvature_unwrapped_universe.results.average_z_surface
390 assert_almost_equal(avg_surface, dummy_surface)
392 # test surface in universe with atoms out of bounds in x and y
393 def test_analysis_get_z_surface_wrap_xy(self, universe_dummy_wrap_xy, dummy_surface):
394 x_bin = y_bin = 3
395 mc = MembraneCurvature(universe_dummy_wrap_xy,
396 n_x_bins=x_bin,
397 n_y_bins=y_bin).run()
398 avg_surface = mc.results.average_z_surface
399 assert_almost_equal(avg_surface, dummy_surface)
401 # test mean curvature
402 def test_analysis_mean_wrap(self, curvature_unwrapped_universe, dummy_surface):
403 avg_mean = curvature_unwrapped_universe.results.average_mean
404 expected_mean = mean_curvature(dummy_surface)
405 assert_almost_equal(avg_mean, expected_mean)
407 def test_analysis_mean_wrap_xy(self, curvature_unwrapped_universe, dummy_surface):
408 avg_mean = curvature_unwrapped_universe.results.average_mean
409 expected_mean = mean_curvature(dummy_surface)
410 assert_almost_equal(avg_mean, expected_mean)
412 # test gaussian
413 def test_analysis_gaussian_wrap(self, curvature_unwrapped_universe, dummy_surface):
414 avg_gaussian = curvature_unwrapped_universe.results.average_gaussian
415 expected_gaussian = gaussian_curvature(dummy_surface)
416 assert_almost_equal(avg_gaussian, expected_gaussian)
418 def test_analysis_mean_gaussian_wrap_xy(self, curvature_unwrapped_universe, dummy_surface):
419 avg_gaussian = curvature_unwrapped_universe.results.average_gaussian
420 expected_gaussian = gaussian_curvature(dummy_surface)
421 assert_almost_equal(avg_gaussian, expected_gaussian)
423 # test using dummy Universe with atoms out of boounds
424 # with wrap=False
425 # +-----------+
426 # | | 8 | 9 | 7
427 # +-----------+
428 # 6 | 4 | 5 | |
429 # +-----------+
430 # | | 2 | 3 | 1
431 # +-----------+
432 # test surface
433 # with wrap=False in universe with atoms out of bounds in x
434 def test_analysis_get_z_surface_no_wrap(self, universe_dummy_wrap):
435 expected_surface = [[np.nan, 150., np.nan],
436 [150., 150., 150.],
437 [150., np.nan, 150.]]
438 x_bin = y_bin = 3
439 mc = MembraneCurvature(universe_dummy_wrap,
440 n_x_bins=x_bin,
441 n_y_bins=y_bin,
442 wrap=False).run()
443 avg_surface = mc.results.average_z_surface
444 assert_almost_equal(avg_surface, expected_surface)
446 # test surface in universe with atoms out of bounds in x and y
447 def test_analysis_get_z_surface_no_wrap_xy(self, universe_dummy_wrap_xy):
448 expected_surface = [[np.nan, np.nan, np.nan],
449 [150., np.nan, 150.],
450 [150., np.nan, 150.]]
451 x_bin = y_bin = 3
452 mc = MembraneCurvature(universe_dummy_wrap_xy,
453 n_x_bins=x_bin,
454 n_y_bins=y_bin,
455 wrap=False).run()
456 avg_surface = mc.results.average_z_surface
457 assert_almost_equal(avg_surface, expected_surface)
459 # test mean
460 def test_analysis_mean_no_wrap(self, universe_dummy_wrap):
461 expected_mean = np.array(np.full((3, 3), np.nan))
462 x_bin = y_bin = 3
463 mc = MembraneCurvature(universe_dummy_wrap,
464 n_x_bins=x_bin,
465 n_y_bins=y_bin,
466 wrap=False).run()
467 avg_mean = mc.results.average_mean
468 assert_almost_equal(avg_mean, expected_mean)
470 def test_analysis_mean_no_wrap(self, universe_dummy_wrap_xy):
471 expected_mean = np.array(np.full((3, 3), np.nan))
472 x_bin = y_bin = 3
473 mc = MembraneCurvature(universe_dummy_wrap_xy,
474 n_x_bins=x_bin,
475 n_y_bins=y_bin,
476 wrap=False).run()
477 avg_mean = mc.results.average_mean
478 assert_almost_equal(avg_mean, expected_mean)
480 # test gaussian
481 def test_analysis_gaussian_no_wrap(self, universe_dummy_wrap):
482 expected_gaussian = np.array(np.full((3, 3), np.nan))
483 x_bin = y_bin = 3
484 mc = MembraneCurvature(universe_dummy_wrap,
485 n_x_bins=x_bin,
486 n_y_bins=y_bin,
487 wrap=False).run()
488 avg_gaussian = mc.results.average_gaussian
489 assert_almost_equal(avg_gaussian, expected_gaussian)
491 def test_analysis_gaussian_no_wrap(self, universe_dummy_wrap_xy):
492 expected_gaussian = np.array(np.full((3, 3), np.nan))
493 x_bin = y_bin = 3
494 mc = MembraneCurvature(universe_dummy_wrap_xy,
495 n_x_bins=x_bin,
496 n_y_bins=y_bin,
497 wrap=False).run()
498 avg_gaussian = mc.results.average_gaussian
499 assert_almost_equal(avg_gaussian, expected_gaussian)
501 @pytest.mark.parametrize('x_bin, y_bin, expected_surface', [
502 (3, 3,
503 np.array([[150., 120., 150.],
504 [150., 120., 120.],
505 [150., 120., 120.]])),
506 (4, 4,
507 np.array([[150., 120., 150., np.nan],
508 [150., 120., 120., np.nan],
509 [150., 120., 120., np.nan],
510 [np.nan, np.nan, np.nan, np.nan]])),
511 (5, 5,
512 np.array([[150., 120., np.nan, 150., np.nan],
513 [150., 120., np.nan, 120., np.nan],
514 [np.nan, np.nan, np.nan, np.nan, np.nan],
515 [150., 120., np.nan, 120., np.nan],
516 [np.nan, np.nan, np.nan, np.nan, np.nan]]))
518 ])
519 def test_analysis_get_z_surface(self, universe_dummy_full, x_bin, y_bin, expected_surface):
520 mc = MembraneCurvature(universe_dummy_full,
521 n_x_bins=x_bin,
522 n_y_bins=y_bin).run()
523 avg_surface = mc.results.average_z_surface
524 assert_almost_equal(avg_surface, expected_surface)
526 def test_analysis_mean(self, universe_dummy_full):
527 expected_mean = np.array([[5.54630914e-04, 1.50000000e+01, -8.80203593e-02],
528 [2.77315457e-04, 2.20748929e-03, 5.01100068e-01],
529 [2.77315457e-04, 2.20748929e-03, 1.50000000e+01]])
530 mc = MembraneCurvature(universe_dummy_full,
531 n_x_bins=3,
532 n_y_bins=3).run()
533 avg_mean = mc.results.average_mean
534 assert_almost_equal(avg_mean, expected_mean)
536 @pytest.mark.parametrize('x_bin, y_bin, box_dim, dummy_array, expected_surface', [
537 # test with negative z coordinates with 3 bins
538 (3, 3, 300, np.array([[0., 0., -150.], [100., 0., -150.], [200., 0., -150.],
539 [0., 100., -150.], [100., 100., 120.], [200., 100., 120.],
540 [0., 200., 120.], [100., 200., 120.], [200., 200., 120.]]),
541 np.array([[150., 150., 120.],
542 [150., 120., 120.],
543 [150., 120., 120.]])),
544 # test with negative z coordinates with 4 bins
545 (4, 4, 400, np.array([[0., 0., -150.], [100., 0., -150.], [200., 0., -150.], [300., 0., -150.],
546 [0., 100., -150.], [100., 100., 120.], [200., 100., 120.], [300., 100., -150.],
547 [0., 200., 120.], [100., 200., 120.], [200., 200., 120.], [300., 200., -150.],
548 [0., 300., -150.], [100., 300., -150.], [200., 300., -150.], [300., 300., -150.]]),
549 np.array([[150., 150., 120., 150.],
550 [150., 120., 120., 150.],
551 [150., 120., 120., 150.],
552 [150., 150., 150., 150.]]))
553 ])
554 def test_analysis_wrapping_coordinates(self, x_bin, y_bin, box_dim, dummy_array, expected_surface):
555 x_range, y_range = (0, box_dim), (0, box_dim)
556 u = mda.Universe(dummy_array, n_atoms=len(dummy_array))
557 u.dimensions = [box_dim, box_dim, 300, 90., 90., 90.]
558 # Check with wrapped coords in base
559 mc = MembraneCurvature(u, select='all',
560 n_x_bins=x_bin,
561 n_y_bins=y_bin,
562 x_range=x_range,
563 y_range=y_range).run()
564 avg_surface = mc.results.average_z_surface
565 # assert if default values of wrapped coords in z_surface returns correctly
566 assert_almost_equal(avg_surface, expected_surface)
568 def test_test_analysis_no_wrapping(self, universe):
569 regex = (r"`wrap == False` may result in inaccurate calculation")
570 with pytest.warns(UserWarning, match=regex):
571 MembraneCurvature(universe, wrap=False)
573 @pytest.mark.parametrize('x_bin, y_bin, box_dim, dummy_array', [
574 # test too large x coordinates 2 bins
575 (2, 2, 200, np.array([[0., 0., 150.], [200., 0., 150.],
576 [0., 100., 150.], [100., 100., 120.]])),
577 # test too large y coordinates 2 bins
578 (2, 2, 200, np.array([[0., 0., 150.], [100., 0., 150.],
579 [0., 200., 150.], [100., 100., 150.]])),
580 # test too large y coordinates with 3 bins
581 (3, 3, 300, np.array([[0., 0., 150.], [100., 0., 150.], [200., 0., 150.],
582 [0., 300., 150.], [100., 100., 120.], [200., 100., 120.],
583 [0., 350., 120.], [100., 200., 120.], [200., 200., 120.]]))
584 ])
585 def test_positive_coordinates_exceed_grid(self, x_bin, y_bin, box_dim, dummy_array):
586 u = mda.Universe(dummy_array, n_atoms=len(dummy_array))
587 u.dimensions = [box_dim, box_dim, 300, 90., 90., 90.]
588 regex = (r"exceed boundaries | size of grid")
589 with pytest.warns(UserWarning, match=regex):
590 MembraneCurvature(u, select='all',
591 n_x_bins=x_bin,
592 n_y_bins=y_bin,
593 wrap=False).run()
595 @pytest.mark.parametrize('x_bin, y_bin, box_dim, dummy_array', [
596 # test negative x coordinates 2 bins
597 (2, 2, 200, np.array([[-150., 0., 150.], [100., 0., 150.],
598 [0., 100., 150.], [100., 100., 150.]])),
599 # test negative y coordinates 2 bins
600 (2, 2, 200, np.array([[0., 0., 150.], [200., 0., 150.],
601 [0., -150., 150.], [100., 100., 120.]])),
602 # test negative x coordinates with 3 bins
603 (3, 3, 300, np.array([[0., 0., 150.], [-100., 0., 150.], [200., 0., 150.],
604 [0., 100., 150.], [100., 100., 120.], [200., 100., 120.],
605 [0., 200., 120.], [100., 200., 120.], [300., 200., 120.]]))
606 ])
607 def test_negative_coordinates_exceed_grid(self, x_bin, y_bin, box_dim, dummy_array):
608 u = mda.Universe(dummy_array, n_atoms=len(dummy_array))
609 u.dimensions = [box_dim, box_dim, 300, 90., 90., 90.]
610 regex = (r"exceed boundaries | coordinates falls")
611 with pytest.warns(UserWarning, match=regex):
612 MembraneCurvature(u, select='all',
613 n_x_bins=x_bin,
614 n_y_bins=y_bin,
615 wrap=False).run()