Added new function for calculating the occupation matrix

This commit is contained in:
Sebastian Kloth 2023-12-08 17:20:06 +01:00
parent 5267f6abac
commit c40ea052b8
2 changed files with 74 additions and 23 deletions

View File

@ -9,10 +9,61 @@ import cmath
import pandas as pd import pandas as pd
import multiprocessing as mp import multiprocessing as mp
VALID_GEOMETRY = {"cylindrical", "slab"} VALID_GEOMETRY = {"cylindrical", "slab"}
def occupation_matrix(trajectory, edge_length=0.05, segments=1000, skip=0.1, nodes=8):
frame_indices = np.unique(
np.int_(np.linspace(len(trajectory) * skip, len(trajectory) - 1, num=segments))
)
box = trajectory[0].box
x_bins = np.arange(0, box[0][0] + edge_length, edge_length)
y_bins = np.arange(0, box[1][1] + edge_length, edge_length)
z_bins = np.arange(0, box[2][2] + edge_length, edge_length)
bins = [x_bins, y_bins, z_bins]
# Trajectory is split for parallel computing
size = math.ceil(len(frame_indices) / nodes)
indices = [
np.arange(len(frame_indices))[i : i + size]
for i in range(0, len(frame_indices), size)
]
pool = mp.Pool(nodes)
results = pool.map(
partial(_calc_histogram, trajectory=trajectory, bins=bins), indices
)
pool.close()
matbin = np.sum(results, axis=0)
x = (x_bins[:-1] + x_bins[1:]) / 2
y = (y_bins[:-1] + y_bins[1:]) / 2
z = (z_bins[:-1] + z_bins[1:]) / 2
coords = np.array(np.meshgrid(x, y, z, indexing="ij"))
coords = np.array([x.flatten() for x in coords])
matbin_new = matbin.flatten()
occupation_df = pd.DataFrame(
{"x": coords[0], "y": coords[1], "z": coords[2], "occupation": matbin_new}
)
occupation_df = occupation_df.query("occupation != 0")
return occupation_df
def _calc_histogram(numberlist, trajectory, bins):
matbin = None
for index in range(0, len(numberlist), 1000):
try:
indices = numberlist[index : index + 1000]
except IndexError:
indices = numberlist[index:]
frames = np.concatenate(np.array([trajectory.pbc[i] for i in indices]))
hist, _ = np.histogramdd(frames, bins=bins)
if matbin is None:
matbin = hist
else:
matbin += hist
return matbin
def get_fel( def get_fel(
traj, traj,
path, path,

View File

@ -9,39 +9,39 @@ from mdevaluate import free_energy_landscape as fel
@pytest.fixture @pytest.fixture
def trajectory(request): def trajectory(request):
return mdevaluate.open(os.path.join(os.path.dirname(__file__), 'data/pore')) return mdevaluate.open(os.path.join(os.path.dirname(__file__), "data/pore"))
def test_get_fel(trajectory): def test_get_fel(trajectory):
test_array = np.array( test_array = np.array(
[ [
0.0, 0.0,
13.162354034697204, 12.87438176,
5.327100985208421, 4.95868203,
9.558746399158396, 11.02055197,
4.116475238453127, 5.44195534,
6.305715728953043, 6.73933442,
3.231102391108276, 3.30971789,
5.896478799115712, 6.10424055,
8.381981206446293, 8.56153733,
5.1191684352849816, 5.45777331,
5.361112857237105, 5.64545817,
8.053932845998895, 8.42100423,
6.895396051256847, 6.28132121,
7.588888886900885, 7.4777172,
11.223429636542576, 11.64839354,
3.779149304024221, 4.52566354,
40.64319010769286, 40.84730838,
93.1120609754045, 93.86241602,
136.99287780099627, 140.3039937,
171.4403749377496, 173.55970021,
] ]
) )
oxygens_water = trajectory.subset(atom_name="OW", residue_name="SOL") oxygens_water = trajectory.subset(atom_name="OW", residue_name="SOL")
r, energy_differences = fel.get_fel( r, energy_differences = fel.get_fel(
oxygens_water, oxygens_water,
os.path.join(os.path.dirname(__file__), 'data/pore'), os.path.join(os.path.dirname(__file__), "data/pore"),
"cylindrical", "cylindrical",
225, 225,
edge=0.05, edge=0.05,
@ -51,4 +51,4 @@ def test_get_fel(trajectory):
overwrite=True, overwrite=True,
) )
assert (energy_differences == test_array).all() assert (np.round(energy_differences) == np.round(test_array)).all()