fix wham2d sampling regions with inf energy
This commit is contained in:
@@ -3,4 +3,4 @@ from .runner import UmbrellaRunner
|
|||||||
from .wham2d import WHAM2DRunner
|
from .wham2d import WHAM2DRunner
|
||||||
|
|
||||||
__all__ = ['AdaptiveUmbrella']
|
__all__ = ['AdaptiveUmbrella']
|
||||||
__version__ = "0.3.12"
|
__version__ = "0.3.13"
|
||||||
|
|||||||
@@ -85,9 +85,7 @@ class UmbrellaRunner():
|
|||||||
|
|
||||||
def _get_root_frames(self, pmf, frames, E_max):
|
def _get_root_frames(self, pmf, frames, E_max):
|
||||||
""" returns the index of all positions in the pmf where the energy is
|
""" returns the index of all positions in the pmf where the energy is
|
||||||
smaller E_max"""
|
smaller E_max and that have already been sampled"""
|
||||||
|
|
||||||
# select positions of the pmf where E <= E_max and that have already been sampled (frames > 0)
|
|
||||||
selection = np.where((pmf <= E_max) & (frames > 0))
|
selection = np.where((pmf <= E_max) & (frames > 0))
|
||||||
zipped = list(zip(*selection))
|
zipped = list(zip(*selection))
|
||||||
|
|
||||||
@@ -132,33 +130,42 @@ class UmbrellaRunner():
|
|||||||
that have not an assigned energy yet, as well as their corresponding root
|
that have not an assigned energy yet, as well as their corresponding root
|
||||||
frame in the format {new_frame1: root_frame1, new_frame2: root_frame2} """
|
frame in the format {new_frame1: root_frame1, new_frame2: root_frame2} """
|
||||||
|
|
||||||
# find all neighboring frames and create a dict that associates them to the root frame with lowest energy
|
# find all neighboring frames and create a dict
|
||||||
|
# that associates them to the root frame with lowest energy
|
||||||
|
# new_frame -> corresponding root_frame
|
||||||
new_frames = {}
|
new_frames = {}
|
||||||
for frame in root_frames:
|
for root_frame in root_frames:
|
||||||
neighbors = self._generate_neighbor_list(frame)
|
|
||||||
|
|
||||||
# remove neighbors if they are not valid (i.e not part of the pmf)
|
# all frames surrounding this root
|
||||||
|
neighbors = self._generate_neighbor_list(root_frame)
|
||||||
|
|
||||||
|
# remove invalid (i.e not part of the pmf)
|
||||||
neighbors = [n for n in neighbors if self.is_valid_frame(n)]
|
neighbors = [n for n in neighbors if self.is_valid_frame(n)]
|
||||||
|
|
||||||
# for each neighbor, check if its already in the list and compare root frame energy
|
# for every neighbor, we try
|
||||||
for n in neighbors:
|
# to get the root frame energy
|
||||||
|
# see if its already with an associated root in new_frames
|
||||||
|
# if yes, we swap the root frame if the new one has lower energy
|
||||||
|
# if not, KeyError, so the current root is our best candidate so far
|
||||||
|
for neighbor in neighbors:
|
||||||
try:
|
try:
|
||||||
root_energy = pmf[frame]
|
root_energy = pmf[root_frame]
|
||||||
old_root = new_frames[n]
|
old_root = new_frames[neighbor]
|
||||||
old_root_energy = pmf[old_root]
|
old_root_energy = pmf[old_root]
|
||||||
if root_energy < old_root_energy:
|
if root_energy < old_root_energy:
|
||||||
new_frames[n] = frame
|
new_frames[neighbor] = root_frame
|
||||||
except KeyError:
|
except KeyError:
|
||||||
new_frames[n] = frame
|
new_frames[neighbor] = root_frame
|
||||||
|
|
||||||
|
# remove already sampled frames (frames with energy > 0)
|
||||||
# remove already sampled frames (frames > 0)
|
|
||||||
new_frames_list = list(new_frames.keys())
|
new_frames_list = list(new_frames.keys())
|
||||||
for idx in range(len(new_frames_list)):
|
for idx in range(len(new_frames_list)):
|
||||||
new_frame = new_frames_list[idx]
|
new_frame = new_frames_list[idx]
|
||||||
if frames[new_frame] > 0:
|
if frames[new_frame] > 0:
|
||||||
del(new_frames[new_frame])
|
del(new_frames[new_frame])
|
||||||
|
|
||||||
|
# also remove all frames where the root has no energy
|
||||||
|
|
||||||
return new_frames
|
return new_frames
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ class WHAM2DRunner(UmbrellaRunner):
|
|||||||
def load_wham_pmf(self, wham_file):
|
def load_wham_pmf(self, wham_file):
|
||||||
""" Load the new pmf into a pandas dataframe """
|
""" Load the new pmf into a pandas dataframe """
|
||||||
df = pd.read_csv(wham_file, delim_whitespace=True, names=['x', 'y', 'e', 'pro'], skiprows=1, index_col=None)
|
df = pd.read_csv(wham_file, delim_whitespace=True, names=['x', 'y', 'e', 'pro'], skiprows=1, index_col=None)
|
||||||
|
# if e is inf, that means this region is unsampled. we cannot really
|
||||||
|
# tell its energy and set it to NaN
|
||||||
df = df.replace([np.inf, -np.inf], np.nan).dropna(subset=['e'], how='all')
|
df = df.replace([np.inf, -np.inf], np.nan).dropna(subset=['e'], how='all')
|
||||||
return df
|
return df
|
||||||
|
|
||||||
@@ -112,15 +114,13 @@ class WHAM2DRunner(UmbrellaRunner):
|
|||||||
lambdax, lambday = self._get_lambdas_for_index((x, y))
|
lambdax, lambday = self._get_lambdas_for_index((x, y))
|
||||||
reduced = wham_pmf[ (abs(wham_pmf.x-lambdax) < self.cvs[0][2]) & (abs(wham_pmf.y-lambday) < self.cvs[1][2]) ]
|
reduced = wham_pmf[ (abs(wham_pmf.x-lambdax) < self.cvs[0][2]) & (abs(wham_pmf.y-lambday) < self.cvs[1][2]) ]
|
||||||
if len(reduced) == 0:
|
if len(reduced) == 0:
|
||||||
continue
|
self.pmf[x,y] = np.inf
|
||||||
|
else:
|
||||||
reduced['dist'] = reduced.apply(lambda row: np.linalg.norm((lambdax-row['x'], lambday-row['y'])), axis=1)
|
reduced['dist'] = reduced.apply(lambda row: np.linalg.norm((lambdax-row['x'], lambday-row['y'])), axis=1)
|
||||||
min = reduced[reduced.dist == reduced.dist.min()]
|
min = reduced[reduced.dist == reduced.dist.min()]
|
||||||
min_row = reduced[(reduced.x == min.x.iloc[0]) & (reduced.y == min.y.iloc[0])]
|
min_row = reduced[(reduced.x == min.x.iloc[0]) & (reduced.y == min.y.iloc[0])]
|
||||||
self.pmf[x, y] = min_row.e.iloc[0]
|
self.pmf[x, y] = min_row.e.iloc[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_new_pmf(self):
|
def calculate_new_pmf(self):
|
||||||
metafile_path = self.create_metadata_file()
|
metafile_path = self.create_metadata_file()
|
||||||
wham_pmf_file = self.get_wham_output_file()
|
wham_pmf_file = self.get_wham_output_file()
|
||||||
|
|||||||
Reference in New Issue
Block a user