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