Completed new functions for free energy landscape calculations
This commit is contained in:
parent
9d8965ace9
commit
0968ff214c
@ -2,9 +2,10 @@ from functools import partial
|
|||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike, NDArray
|
||||||
|
from numpy.polynomial.polynomial import Polynomial as Poly
|
||||||
import math
|
import math
|
||||||
import scipy
|
import scipy
|
||||||
from numpy.typing import ArrayLike, NDArray
|
|
||||||
from scipy.spatial import KDTree
|
from scipy.spatial import KDTree
|
||||||
import cmath
|
import cmath
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@ -103,7 +104,13 @@ def find_maxima(
|
|||||||
return maxima_df
|
return maxima_df
|
||||||
|
|
||||||
|
|
||||||
def calc_energies(maxima_indices, maxima_df, bins, box):
|
def _calc_energies(
|
||||||
|
maxima_indices: ArrayLike,
|
||||||
|
maxima_df: pd.DataFrame,
|
||||||
|
bins: ArrayLike,
|
||||||
|
box: NDArray,
|
||||||
|
T: float,
|
||||||
|
) -> NDArray:
|
||||||
points = np.array(maxima_df[["x", "y", "z"]])
|
points = np.array(maxima_df[["x", "y", "z"]])
|
||||||
tree = KDTree(points, boxsize=box)
|
tree = KDTree(points, boxsize=box)
|
||||||
maxima = maxima_df.loc[maxima_indices, ["x", "y", "z"]]
|
maxima = maxima_df.loc[maxima_indices, ["x", "y", "z"]]
|
||||||
@ -119,8 +126,9 @@ def calc_energies(maxima_indices, maxima_df, bins, box):
|
|||||||
if distances.ndim == 1:
|
if distances.ndim == 1:
|
||||||
current_distances = distances[1:][distances[1:] <= bins[-1]]
|
current_distances = distances[1:][distances[1:] <= bins[-1]]
|
||||||
current_indices = indices[1:][distances[1:] <= bins[-1]]
|
current_indices = indices[1:][distances[1:] <= bins[-1]]
|
||||||
energy = -np.log(
|
energy = (
|
||||||
maxima_df.loc[current_indices, "occupation"] / maxima_occupations
|
-np.log(maxima_df.loc[current_indices, "occupation"] / maxima_occupations)
|
||||||
|
* T
|
||||||
)
|
)
|
||||||
energy_hist = np.histogram(current_distances, bins=bins, weights=energy)[0]
|
energy_hist = np.histogram(current_distances, bins=bins, weights=energy)[0]
|
||||||
occupied_bins_hist = np.histogram(current_distances, bins=bins)[0]
|
occupied_bins_hist = np.histogram(current_distances, bins=bins)[0]
|
||||||
@ -130,8 +138,9 @@ def calc_energies(maxima_indices, maxima_df, bins, box):
|
|||||||
current_distances = distances[i, 1:][distances[i, 1:] <= bins[-1]]
|
current_distances = distances[i, 1:][distances[i, 1:] <= bins[-1]]
|
||||||
current_indices = indices[i, 1:][distances[i, 1:] <= bins[-1]]
|
current_indices = indices[i, 1:][distances[i, 1:] <= bins[-1]]
|
||||||
|
|
||||||
energy = -np.log(
|
energy = (
|
||||||
maxima_df.loc[current_indices, "occupation"] / maxima_occupation
|
-np.log(maxima_df.loc[current_indices, "occupation"] / maxima_occupation)
|
||||||
|
* T
|
||||||
)
|
)
|
||||||
energy_hist = np.histogram(current_distances, bins=bins, weights=energy)[0]
|
energy_hist = np.histogram(current_distances, bins=bins, weights=energy)[0]
|
||||||
occupied_bins_hist = np.histogram(current_distances, bins=bins)[0]
|
occupied_bins_hist = np.histogram(current_distances, bins=bins)[0]
|
||||||
@ -141,20 +150,65 @@ def calc_energies(maxima_indices, maxima_df, bins, box):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def add_distances(occupation_df, pore_geometry, origin):
|
def add_distances(
|
||||||
new_df = occupation_df.copy()
|
occupation_df: pd.DataFrame, pore_geometry: str, origin: ArrayLike
|
||||||
if pore_geometry is "cylindrical":
|
) -> pd.DataFrame:
|
||||||
new_df["distance"] = (
|
distance_df = occupation_df.copy()
|
||||||
(new_df["x"] - origin[0]) ** 2 + (new_df["y"] - origin[1]) ** 2
|
if pore_geometry == "cylindrical":
|
||||||
|
distance_df["distance"] = (
|
||||||
|
(distance_df["x"] - origin[0]) ** 2 + (distance_df["y"] - origin[1]) ** 2
|
||||||
) ** (1 / 2)
|
) ** (1 / 2)
|
||||||
elif pore_geometry is "slit":
|
elif pore_geometry == "slit":
|
||||||
new_df["distance"] = np.abs(new_df["z"] - origin[2])
|
distance_df["distance"] = np.abs(distance_df["z"] - origin[2])
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"pore_geometry is {pore_geometry}, should either be "
|
f"pore_geometry is {pore_geometry}, should either be "
|
||||||
f"'cylindrical' or 'slit'"
|
f"'cylindrical' or 'slit'"
|
||||||
)
|
)
|
||||||
return new_df
|
return distance_df
|
||||||
|
|
||||||
|
|
||||||
|
def distance_resolved_energies(
|
||||||
|
maxima_df: pd.DataFrame,
|
||||||
|
distance_bins: ArrayLike,
|
||||||
|
r_bins: ArrayLike,
|
||||||
|
box: NDArray,
|
||||||
|
T: float,
|
||||||
|
) -> pd.DataFrame:
|
||||||
|
results = []
|
||||||
|
for i in range(len(distance_bins) - 1):
|
||||||
|
maxima_indices = np.array(
|
||||||
|
maxima_df.index[
|
||||||
|
(maxima_df["distance"] >= distance_bins[i])
|
||||||
|
* (maxima_df["distance"] < distance_bins[i + 1])
|
||||||
|
* (maxima_df["maxima"] == True)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
results.append(_calc_energies(maxima_indices, maxima_df, r_bins, box, T))
|
||||||
|
|
||||||
|
distances = (distance_bins[:-1] + distance_bins[1:]) / 2
|
||||||
|
radii = (r_bins[:-1] + r_bins[1:]) / 2
|
||||||
|
d = np.array([d for d in distances for r in radii])
|
||||||
|
r = np.array([r for d in distances for r in radii])
|
||||||
|
result = np.array(results).flatten()
|
||||||
|
return pd.DataFrame({"d": d, "r": r, "energy": result})
|
||||||
|
|
||||||
|
|
||||||
|
def find_energy_maxima(
|
||||||
|
energy_df: pd.DataFrame, r_min: float, r_max: float
|
||||||
|
) -> pd.DataFrame:
|
||||||
|
distances = []
|
||||||
|
energies = []
|
||||||
|
for d, data_d in energy_df.groupby("d"):
|
||||||
|
distances.append(d)
|
||||||
|
x = np.array(data_d["r"])
|
||||||
|
y = np.array(data_d["energy"])
|
||||||
|
mask = (x >= r_min) * (x <= r_max)
|
||||||
|
print(x[mask], y[mask])
|
||||||
|
p3 = Poly.fit(x[mask], y[mask], deg=2)
|
||||||
|
print(p3)
|
||||||
|
energies.append(np.max(p3(np.linspace(r_min, r_max, 1000))))
|
||||||
|
return pd.DataFrame({"d": distances, "energy": energies})
|
||||||
|
|
||||||
|
|
||||||
def get_fel(
|
def get_fel(
|
||||||
@ -214,8 +268,8 @@ def get_fel(
|
|||||||
np.save(f"{path}/radiiBins", bins)
|
np.save(f"{path}/radiiBins", bins)
|
||||||
|
|
||||||
energy_differences = np.array(calculate_energy_difference(data, bins, temperature))
|
energy_differences = np.array(calculate_energy_difference(data, bins, temperature))
|
||||||
r = bins[1:] - (bins[1] - bins[0]) / 2
|
d = np.linspace(radiusmin, radiusmax, len(energy_differences))
|
||||||
return r, energy_differences
|
return d, energy_differences
|
||||||
|
|
||||||
|
|
||||||
def fill_bins(traj, path, edge=0.05):
|
def fill_bins(traj, path, edge=0.05):
|
||||||
|
Loading…
Reference in New Issue
Block a user