Reworked while loops to for loops in free_energy_landscape.py
This commit is contained in:
parent
fa2e793354
commit
4efb221a80
@ -360,6 +360,7 @@ class CoordinatesMap:
|
|||||||
self._description = self.function.func.__name__
|
self._description = self.function.func.__name__
|
||||||
else:
|
else:
|
||||||
self._description = self.function.__name__
|
self._description = self.function.__name__
|
||||||
|
self._slice = slice(None)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for frame in self.coordinates:
|
for frame in self.coordinates:
|
||||||
|
@ -4,7 +4,7 @@ import os.path
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
import scipy
|
import scipy
|
||||||
from scipy import spatial as sp
|
from scipy.spatial import KDTree
|
||||||
import cmath
|
import cmath
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
@ -52,7 +52,6 @@ def get_fel(
|
|||||||
"""
|
"""
|
||||||
if geometry not in VALID_GEOMETRY:
|
if geometry not in VALID_GEOMETRY:
|
||||||
raise ValueError("results: status must be one of %r." % VALID_GEOMETRY)
|
raise ValueError("results: status must be one of %r." % VALID_GEOMETRY)
|
||||||
EnergyDifference = []
|
|
||||||
|
|
||||||
if (os.path.exists(f"{path}/radiiData.npy")) & (not overwrite):
|
if (os.path.exists(f"{path}/radiiData.npy")) & (not overwrite):
|
||||||
data = np.load(f"{path}/radiiData.npy")
|
data = np.load(f"{path}/radiiData.npy")
|
||||||
@ -60,17 +59,19 @@ def get_fel(
|
|||||||
# Here the different standard geometries are inserted
|
# Here the different standard geometries are inserted
|
||||||
else:
|
else:
|
||||||
if geometry == "cylindrical":
|
if geometry == "cylindrical":
|
||||||
bins, data = shortAllRadii(
|
bins, data = short_all_radii(
|
||||||
traj, path, edge=edge, radiusmin=radiusmin, radiusmax=radiusmax, z=z
|
traj, path, edge=edge, radiusmin=radiusmin, radiusmax=radiusmax, z=z
|
||||||
)
|
)
|
||||||
if geometry == "slab":
|
elif geometry == "slab":
|
||||||
bins, data = shortAllRadiiSlab(
|
bins, data = short_all_radii_slab(
|
||||||
traj, path, edge=edge, radiusmin=radiusmin, radiusmax=radiusmax, z=z
|
traj, path, edge=edge, radiusmin=radiusmin, radiusmax=radiusmax, z=z
|
||||||
)
|
)
|
||||||
np.save(f"{path}/radiiData", data)
|
np.save(f"{path}/radiiData", data)
|
||||||
np.save(f"{path}/radiiBins", bins)
|
np.save(f"{path}/radiiBins", bins)
|
||||||
|
|
||||||
return CalculateEnergyDifference(data, bins, temperature)
|
energy_differences = np.array(calculate_energy_difference(data, bins, temperature))
|
||||||
|
r = bins[1:] - (bins[1] - bins[0]) / 2
|
||||||
|
return r, energy_differences
|
||||||
|
|
||||||
|
|
||||||
def fill_bins(traj, path, edge=0.05):
|
def fill_bins(traj, path, edge=0.05):
|
||||||
@ -83,7 +84,7 @@ def fill_bins(traj, path, edge=0.05):
|
|||||||
size = math.ceil(len(traj) / 8)
|
size = math.ceil(len(traj) / 8)
|
||||||
|
|
||||||
# Trajectory is split for parallel computing
|
# Trajectory is split for parallel computing
|
||||||
indices = list(Chunksplit(np.arange(0, len(traj), 1), size))
|
indices = list(chunksplit(np.arange(0, len(traj), 1), size))
|
||||||
# indices = list(Chunksplit(np.arange(len(traj)-80, len(traj), 1), size))
|
# indices = list(Chunksplit(np.arange(len(traj)-80, len(traj), 1), size))
|
||||||
fill = partial(help_fill, traj=traj)
|
fill = partial(help_fill, traj=traj)
|
||||||
results = pool.map(fill, indices)
|
results = pool.map(fill, indices)
|
||||||
@ -153,9 +154,6 @@ def help_fill(numberlist, traj, edge=0.05):
|
|||||||
|
|
||||||
|
|
||||||
def calculate_maxima(matbin):
|
def calculate_maxima(matbin):
|
||||||
i = 0
|
|
||||||
j = 0
|
|
||||||
k = 0
|
|
||||||
maxima = []
|
maxima = []
|
||||||
|
|
||||||
z = [-1, 0, 1]
|
z = [-1, 0, 1]
|
||||||
@ -164,13 +162,13 @@ def calculate_maxima(matbin):
|
|||||||
max_j = matbin.shape[1]
|
max_j = matbin.shape[1]
|
||||||
max_k = matbin.shape[2]
|
max_k = matbin.shape[2]
|
||||||
|
|
||||||
# For each element in the matrix all sourrounding 26 elements are compared to
|
# For each element in the matrix all surrounding 26 elements are compared to
|
||||||
# determine the minimum.
|
# determine the minimum.
|
||||||
# Algorithm can definitely improved but is so fast that its not necessary.
|
# Algorithm can definitely be improved but is so fast that it's not necessary.
|
||||||
|
|
||||||
while i < max_i:
|
for i in range(max_i):
|
||||||
while j < max_j:
|
for j in range(max_j):
|
||||||
while k < max_k:
|
for k in range(max_k):
|
||||||
a = matbin[i][j][k]
|
a = matbin[i][j][k]
|
||||||
b = True
|
b = True
|
||||||
for l in z:
|
for l in z:
|
||||||
@ -186,16 +184,10 @@ def calculate_maxima(matbin):
|
|||||||
|
|
||||||
if b:
|
if b:
|
||||||
maxima.append([i, j, k])
|
maxima.append([i, j, k])
|
||||||
|
|
||||||
k += 1
|
|
||||||
k = 0
|
|
||||||
j += 1
|
|
||||||
j = 0
|
|
||||||
i += 1
|
|
||||||
return maxima
|
return maxima
|
||||||
|
|
||||||
|
|
||||||
def ListOfCoordinates(matbin):
|
def list_of_coordinates(matbin):
|
||||||
# Matrix elements are translated back into postion vectors
|
# Matrix elements are translated back into postion vectors
|
||||||
max_i = matbin.shape[0]
|
max_i = matbin.shape[0]
|
||||||
max_j = matbin.shape[1]
|
max_j = matbin.shape[1]
|
||||||
@ -203,28 +195,15 @@ def ListOfCoordinates(matbin):
|
|||||||
|
|
||||||
coord = np.zeros((max_i, max_j, max_k, 3))
|
coord = np.zeros((max_i, max_j, max_k, 3))
|
||||||
|
|
||||||
i = 0
|
for i in range(max_i):
|
||||||
j = 0
|
for j in range(max_j):
|
||||||
k = 0
|
for k in range(max_k):
|
||||||
while i < max_i:
|
|
||||||
while j < max_j:
|
|
||||||
while k < max_k:
|
|
||||||
coord[i][j][k] = [i, j, k]
|
coord[i][j][k] = [i, j, k]
|
||||||
k += 1
|
|
||||||
k = 0
|
|
||||||
j += 1
|
|
||||||
j = 0
|
|
||||||
i += 1
|
|
||||||
return coord
|
return coord
|
||||||
|
|
||||||
|
|
||||||
def calculateTree(coord, box):
|
def sphere_quotient(
|
||||||
coordlist = np.reshape(coord, (-1, 3))
|
|
||||||
tree = sp.cKDTree(coordlist, boxsize=box)
|
|
||||||
return tree
|
|
||||||
|
|
||||||
|
|
||||||
def SphereQuotient(
|
|
||||||
matbin,
|
matbin,
|
||||||
maxima,
|
maxima,
|
||||||
coordlist,
|
coordlist,
|
||||||
@ -293,7 +272,7 @@ def SphereQuotient(
|
|||||||
return b * edge, quotient
|
return b * edge, quotient
|
||||||
|
|
||||||
|
|
||||||
def SphereQuotientSlab(
|
def sphere_quotient_slab(
|
||||||
matbin, maxima, coordlist, tree, radius, box, edge, unitdist, z=[-np.inf, np.inf]
|
matbin, maxima, coordlist, tree, radius, box, edge, unitdist, z=[-np.inf, np.inf]
|
||||||
):
|
):
|
||||||
# Same as SphereQuotient bur for Slabs
|
# Same as SphereQuotient bur for Slabs
|
||||||
@ -349,18 +328,18 @@ def SphereQuotientSlab(
|
|||||||
return z * edge, quotient
|
return z * edge, quotient
|
||||||
|
|
||||||
|
|
||||||
def shortAllRadii(
|
def short_all_radii(
|
||||||
traj, path, edge=0.05, radiusmin=0.05, radiusmax=2.05, z=[-np.inf, np.inf]
|
traj, path, edge=0.05, radiusmin=0.05, radiusmax=2.05, z=[-np.inf, np.inf]
|
||||||
):
|
):
|
||||||
# Shorthand function cylindrical systems
|
# Shorthand function cylindrical systems
|
||||||
matbin = fill_bins(traj, path, edge)
|
matbin = fill_bins(traj, path, edge)
|
||||||
maxima = calculate_maxima(matbin)
|
maxima = calculate_maxima(matbin)
|
||||||
coordinates = ListOfCoordinates(matbin)
|
coordinates = list_of_coordinates(matbin)
|
||||||
tree = calculateTree(coordinates, box=matbin.shape)
|
tree = KDTree(np.reshape(coordinates, (-1, 3)), boxsize=matbin.shape)
|
||||||
bins = []
|
bins = []
|
||||||
data = []
|
data = []
|
||||||
for radius in np.arange(radiusmin, radiusmax, 0.1):
|
for radius in np.arange(radiusmin, radiusmax, 0.1):
|
||||||
b, d = SphereQuotient(
|
b, d = sphere_quotient(
|
||||||
matbin,
|
matbin,
|
||||||
maxima,
|
maxima,
|
||||||
coordinates,
|
coordinates,
|
||||||
@ -376,18 +355,18 @@ def shortAllRadii(
|
|||||||
return bins, data
|
return bins, data
|
||||||
|
|
||||||
|
|
||||||
def shortAllRadiiSlab(
|
def short_all_radii_slab(
|
||||||
traj, path, edge=0.05, radiusmin=0.05, radiusmax=2.05, z=[-np.inf, np.inf]
|
traj, path, edge=0.05, radiusmin=0.05, radiusmax=2.05, z=[-np.inf, np.inf]
|
||||||
):
|
):
|
||||||
# Shorthand function for Slab systems
|
# Shorthand function for Slab systems
|
||||||
matbin = fill_bins(traj, path, edge)
|
matbin = fill_bins(traj, path, edge)
|
||||||
maxima = calculate_maxima(matbin)
|
maxima = calculate_maxima(matbin)
|
||||||
coordinates = ListOfCoordinates(matbin)
|
coordinates = list_of_coordinates(matbin)
|
||||||
tree = calculateTree(coordinates, box=matbin.shape)
|
tree = KDTree(np.reshape(coordinates, (-1, 3)), boxsize=matbin.shape)
|
||||||
bins = []
|
bins = []
|
||||||
data = []
|
data = []
|
||||||
for radius in np.arange(radiusmin, radiusmax, 0.1):
|
for radius in np.arange(radiusmin, radiusmax, 0.1):
|
||||||
c, d = SphereQuotientSlab(
|
c, d = sphere_quotient_slab(
|
||||||
matbin,
|
matbin,
|
||||||
maxima,
|
maxima,
|
||||||
coordinates,
|
coordinates,
|
||||||
@ -403,7 +382,7 @@ def shortAllRadiiSlab(
|
|||||||
return bins, data
|
return bins, data
|
||||||
|
|
||||||
|
|
||||||
def CalculateEnergyDifference(data, bins, temperature):
|
def calculate_energy_difference(data, bins, temperature):
|
||||||
"""
|
"""
|
||||||
Calculates the energy difference between local energy minimum and the
|
Calculates the energy difference between local energy minimum and the
|
||||||
minimum in the center
|
minimum in the center
|
||||||
@ -413,39 +392,39 @@ def CalculateEnergyDifference(data, bins, temperature):
|
|||||||
while i < len(data):
|
while i < len(data):
|
||||||
#
|
#
|
||||||
q = (
|
q = (
|
||||||
GetMinimum(data[0], bins[0])[1] - GetMinimum(data[i], bins[0])[1]
|
get_minimum(data[0], bins[0])[1] - get_minimum(data[i], bins[0])[1]
|
||||||
) * temperature
|
) * temperature
|
||||||
difference.append(q)
|
difference.append(q)
|
||||||
i += 1
|
i += 1
|
||||||
return difference
|
return difference
|
||||||
|
|
||||||
|
|
||||||
def Chunksplit(list_a, chunk_size):
|
def chunksplit(list_a, chunk_size):
|
||||||
for i in range(0, len(list_a), chunk_size):
|
for i in range(0, len(list_a), chunk_size):
|
||||||
yield list_a[i : i + chunk_size]
|
yield list_a[i : i + chunk_size]
|
||||||
|
|
||||||
|
|
||||||
def GetMinimum(data, bins):
|
def get_minimum(data, bins):
|
||||||
# Fits a polynom of order 3 to determine the energy minimum and analytically
|
# Fits a polynom of order 3 to determine the energy minimum and analytically
|
||||||
# calculates the minimum location
|
# calculates the minimum location
|
||||||
y = data[:10]
|
y = data[:10]
|
||||||
x = bins[1:11]
|
x = bins[1:11]
|
||||||
|
|
||||||
popt, pcov = scipy.optimize.curve_fit(Pol3, x, y, maxfev=80000)
|
popt, _ = scipy.optimize.curve_fit(pol3, x, y, maxfev=80000)
|
||||||
|
|
||||||
a, b = SolveQuadratic(3 * popt[0], 2 * popt[1], popt[2])
|
a, b = solve_quadratic(3 * popt[0], 2 * popt[1], popt[2])
|
||||||
|
|
||||||
if 6 * popt[0] * a + 2 * popt[1] > 0:
|
if 6 * popt[0] * a + 2 * popt[1] > 0:
|
||||||
if (np.real(a) < 0) or (np.real(a) > 0.3):
|
if (np.real(a) < 0) or (np.real(a) > 0.3):
|
||||||
return np.real(a), np.average(y)
|
return np.real(a), np.average(y)
|
||||||
return np.real(a), np.real(Pol3(a, *popt))
|
return np.real(a), np.real(pol3(a, *popt))
|
||||||
else:
|
else:
|
||||||
if (np.real(b) < 0) or (np.real(b) > 0.3):
|
if (np.real(b) < 0) or (np.real(b) > 0.3):
|
||||||
return np.real(b), np.average(y)
|
return np.real(b), np.average(y)
|
||||||
return np.real(b), np.real(Pol3(b, *popt))
|
return np.real(b), np.real(pol3(b, *popt))
|
||||||
|
|
||||||
|
|
||||||
def SolveQuadratic(a, b, c):
|
def solve_quadratic(a, b, c):
|
||||||
d = (b**2) - (4 * a * c)
|
d = (b**2) - (4 * a * c)
|
||||||
|
|
||||||
sol1 = (-b - cmath.sqrt(d)) / (2 * a)
|
sol1 = (-b - cmath.sqrt(d)) / (2 * a)
|
||||||
@ -453,5 +432,5 @@ def SolveQuadratic(a, b, c):
|
|||||||
return sol1, sol2
|
return sol1, sol2
|
||||||
|
|
||||||
|
|
||||||
def Pol3(x, a, b, c, d):
|
def pol3(x, a, b, c, d):
|
||||||
return a * x**3 + b * x**2 + c * x + d
|
return a * x**3 + b * x**2 + c * x + d
|
||||||
|
@ -39,7 +39,7 @@ def test_get_fel(trajectory):
|
|||||||
)
|
)
|
||||||
|
|
||||||
oxygens_water = trajectory.subset(atom_name="OW", residue_name="SOL")
|
oxygens_water = trajectory.subset(atom_name="OW", residue_name="SOL")
|
||||||
data = 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",
|
||||||
@ -51,4 +51,4 @@ def test_get_fel(trajectory):
|
|||||||
overwrite=True,
|
overwrite=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert (np.array(data) == test_array).all()
|
assert (energy_differences == test_array).all()
|
||||||
|
Loading…
Reference in New Issue
Block a user