Skip to content

Commit

Permalink
Merge pull request #94 from fhh2626/dev
Browse files Browse the repository at this point in the history
version 2.3.2
  • Loading branch information
fhh2626 authored Feb 9, 2023
2 parents 444b6d8 + 139e299 commit 200795d
Show file tree
Hide file tree
Showing 11 changed files with 739 additions and 490 deletions.
53 changes: 51 additions & 2 deletions BFEE2/commonTools/ploter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,58 @@
# plot figures

import os, math
import numpy as np
import math
import os
import pathlib

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate


# an runtime error
# does not have corresponding correction for a pmf
class NoCorrectionFileError(RuntimeError):
def __init__(self, arg):
self.args = arg

def isGaWTM(pmfFiles):
"""determine whether the input PMFs indicate Gs-WTM simulations
Args:
pmfFiles (list[str]): path to a set of PMFs (and pmf corrections)
Returns:
bool: GaWTM simulation or not
"""

for file in pmfFiles:
if ''.join(pathlib.Path(file).suffixes) == '.reweightamd1.cumulant.pmf':
return True
return False

def correctGaWTM(pmfFile):
"""read a 1D namd PMF file and correct it using cumulant.pmf file
Args:
pmfFile (str): path to the pmf File
Returns:
np.array (N*2): 1D PMF
"""

pmf = np.loadtxt(pmfFile)
correction_pmfFile = pmfFile.replace('.czar.pmf', '') + '.reweightamd1.cumulant.pmf'

if not os.path.exists(correction_pmfFile):
raise NoCorrectionFileError(f'{pmfFile} does not have a corresponding correction!')

correction_data = np.loadtxt(correction_pmfFile)
correction_interpolate = interpolate.interp1d(correction_data[:,0], correction_data[:,1], fill_value="extrapolate")

pmf[:,1] += correction_interpolate(pmf[:,0])

return pmf

def readPMF(pmfFile):
"""read a 1D namd PMF file
Expand Down
79 changes: 70 additions & 9 deletions BFEE2/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,10 @@ def _initUI(self):
self.pinDownProCheckbox.setChecked(True)

self.useOldCvCheckbox = QCheckBox('Use quaternion-based CVs')
self.useOldCvCheckbox.setChecked(True)
self.useOldCvCheckbox.setChecked(False)

self.reflectingBoundaryCheckbox = QCheckBox('Use reflecting boundary')
self.reflectingBoundaryCheckbox.setChecked(False)
self.reflectingBoundaryCheckbox.setChecked(True)

self.compatibilityLayout.addWidget(self.pinDownProCheckbox, 0, 0)
self.compatibilityLayout.addWidget(self.useOldCvCheckbox, 0, 1)
Expand All @@ -261,6 +261,20 @@ def _initUI(self):

self.FFSettingsLayout.addWidget(self.OPLSMixingRuleCheckbox)
self.FFSettings.setLayout(self.FFSettingsLayout)

# strategy settings
self.strategy = QGroupBox('Strategy settings')
self.strategyLayout = QHBoxLayout()

self.considerRMSDCVCheckbox = QCheckBox('Take into account RMSD CV')
self.considerRMSDCVCheckbox.setChecked(True)

self.useGaWTMCheckbox = QCheckBox('Use GaWTM-eABF')
self.useGaWTMCheckbox.setChecked(False)

self.strategyLayout.addWidget(self.considerRMSDCVCheckbox)
self.strategyLayout.addWidget(self.useGaWTMCheckbox)
self.strategy.setLayout(self.strategyLayout)

# membrane protein
self.modeling = QGroupBox('Modeling (avaiable for CHARMM FF)')
Expand Down Expand Up @@ -307,6 +321,7 @@ def _initUI(self):
self.mainLayout.addWidget(self.stratification)
self.mainLayout.addWidget(self.compatibility)
self.mainLayout.addWidget(self.FFSettings)
self.mainLayout.addWidget(self.strategy)
self.mainLayout.addWidget(self.modeling)
self.mainLayout.addWidget(self.parallelRuns)
self.mainLayout.addLayout(self.geometricAdvancedSettingsButtonLayout)
Expand Down Expand Up @@ -400,7 +415,7 @@ def _initUI(self):
self.pinDownProCheckbox.setChecked(True)

self.useOldCvCheckbox = QCheckBox('Use quaternion-based CVs')
self.useOldCvCheckbox.setChecked(True)
self.useOldCvCheckbox.setChecked(False)

self.compatibilityLayout.addWidget(self.pinDownProCheckbox)
self.compatibilityLayout.addWidget(self.useOldCvCheckbox)
Expand Down Expand Up @@ -491,6 +506,7 @@ def __init__(self):

self.setGeometry(0,0,0,0)
self.setWindowTitle(__PROGRAM_NAME__)
self.setWindowIcon(QIcon("BFEE2/icon/icon.png"))
self.show()

def _initActions(self):
Expand Down Expand Up @@ -1266,12 +1282,23 @@ def _changeStrategySettingState(self):
if self.selectMDEngineCombobox.currentText() == 'NAMD':
self.selectStrategyCombobox.setEnabled(True)
self.geometricAdvancedSettings.useOldCvCheckbox.setEnabled(True)
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.setEnabled(True)
self.geometricAdvancedSettings.useGaWTMCheckbox.setEnabled(True)

elif self.selectMDEngineCombobox.currentText() == 'Gromacs':
index = self.selectStrategyCombobox.findText('Geometric', QtCore.Qt.MatchFixedString)
if index >= 0:
self.selectStrategyCombobox.setCurrentIndex(index)
self.selectStrategyCombobox.setEnabled(False)

self.geometricAdvancedSettings.useOldCvCheckbox.setChecked(False)
self.geometricAdvancedSettings.useOldCvCheckbox.setEnabled(False)

self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.setChecked(False)
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.setEnabled(False)

self.geometricAdvancedSettings.useGaWTMCheckbox.setEnabled(False)
self.geometricAdvancedSettings.useGaWTMCheckbox.setChecked(False)

def _changeStrategySettingStateForOldGromacs(self):
"""enable/disable a lot of options for the old Gromacs tab
Expand Down Expand Up @@ -1378,10 +1405,12 @@ def _showGeometricResults(self, unit):
return

# check inputs
for item in pmfs:
if not os.path.exists(item):
for index, item in enumerate(pmfs):
if (index != 0) and (index != 7) and (not os.path.exists(item)):
QMessageBox.warning(self, 'Error', f'file {item} does not exist!')
return
if (index == 7) and (not os.path.exists(item)):
QMessageBox.warning(self, 'Warning', f'Supposing dealing with a rigid ligand!')

# calculate free energies
try:
Expand Down Expand Up @@ -1634,6 +1663,16 @@ def f():
)
return

if self.geometricAdvancedSettings.useGaWTMCheckbox.isChecked():
QMessageBox.warning(self, 'Error',
f'\
The feature of using GaWTM-eABF as the workhorse engine is \
experimental! Known issues:\n \
The config files for extending GaWTM-eABF simulations \
will do pre-equilibration again. This may cause some errors. \
One can revise the config file manually to avoid it'
)

try:
iGenerator.generateNAMDGeometricFiles(
path,
Expand All @@ -1656,7 +1695,9 @@ def f():
self.mainSettings.vmdLineEdit.text(),
self.geometricAdvancedSettings.reflectingBoundaryCheckbox.isChecked(),
self.selectMDEngineCombobox.currentText().lower(),
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.isChecked()
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.isChecked(),
self.geometricAdvancedSettings.considerRMSDCVCheckbox.isChecked(),
self.geometricAdvancedSettings.useGaWTMCheckbox.isChecked()
)
except fileParser.SelectionError:
QMessageBox.warning(
Expand Down Expand Up @@ -1726,7 +1767,7 @@ def f():
self.alchemicalAdvancedSettings.pinDownProCheckbox.isChecked(),
self.alchemicalAdvancedSettings.useOldCvCheckbox.isChecked(),
self.mainSettings.vmdLineEdit.text(),
self.alchemicalAdvancedSettings.OPLSMixingRuleCheckbox.isChecked()
self.alchemicalAdvancedSettings.OPLSMixingRuleCheckbox.isChecked(),
)
except PermissionError:
QMessageBox.warning(
Expand Down Expand Up @@ -1860,7 +1901,17 @@ def f():

path, _ = QFileDialog.getSaveFileName(None, 'Set the name of merged PMF')

pmfs = [ploter.readPMF(self.mergePmfBox.item(i).text()) for i in range(self.mergePmfBox.count())]
pmfFiles = [self.mergePmfBox.item(i).text() for i in range(self.mergePmfBox.count())]

if not ploter.isGaWTM(pmfFiles):
pmfs = [ploter.readPMF(item) for item in pmfFiles]
else:
pmfFiles = [item for item in pmfFiles if not item.endswith('.reweightamd1.cumulant.pmf')]
try:
pmfs = [ploter.correctGaWTM(item) for item in pmfFiles]
except ploter.NoCorrectionFileError:
QMessageBox.warning(self, 'Error', f'A PMF file does not have corresponding correction!')
return

mergedPMF = ploter.mergePMF(pmfs)
ploter.writePMF(path, mergedPMF)
Expand All @@ -1879,8 +1930,18 @@ def f():
QMessageBox.warning(self, 'Warning', f'Warning, no PMF selected!')
return

pmfs = [ploter.readPMF(self.plotPmfBox.item(i).text()) for i in range(self.plotPmfBox.count())]
pmfFiles = [self.plotPmfBox.item(i).text() for i in range(self.plotPmfBox.count())]

if not ploter.isGaWTM(pmfFiles):
pmfs = [ploter.readPMF(item) for item in pmfFiles]
else:
pmfFiles = [item for item in pmfFiles if not item.endswith('.reweightamd1.cumulant.pmf')]
try:
pmfs = [ploter.correctGaWTM(item) for item in pmfFiles]
except ploter.NoCorrectionFileError:
QMessageBox.warning(self, 'Error', f'A PMF file does not have corresponding correction!')
return

mergedPMF = ploter.mergePMF(pmfs)
ploter.plotPMF(mergedPMF)
return f
Expand Down
Binary file added BFEE2/icon/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 200795d

Please sign in to comment.