bfee2 2.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bfee2 might be problematic. Click here for more details.
- BFEE2/__init__.py +0 -0
- BFEE2/commonTools/__init__.py +0 -0
- BFEE2/commonTools/commonSlots.py +48 -0
- BFEE2/commonTools/fileParser.py +327 -0
- BFEE2/commonTools/ploter.py +218 -0
- BFEE2/doc/Doc.pdf +0 -0
- BFEE2/doc/__init__.py +1 -0
- BFEE2/gui.py +2136 -0
- BFEE2/inputGenerator.py +2857 -0
- BFEE2/postTreatment.py +502 -0
- BFEE2/templates_gromacs/000.colvars.template +37 -0
- BFEE2/templates_gromacs/000.generate_tpr_sh.template +31 -0
- BFEE2/templates_gromacs/000.mdp.template +70 -0
- BFEE2/templates_gromacs/001.colvars.template +76 -0
- BFEE2/templates_gromacs/001.generate_tpr_sh.template +31 -0
- BFEE2/templates_gromacs/001.mdp.template +70 -0
- BFEE2/templates_gromacs/001.readme.template +1 -0
- BFEE2/templates_gromacs/002.colvars.template +101 -0
- BFEE2/templates_gromacs/002.generate_tpr_sh.template +31 -0
- BFEE2/templates_gromacs/002.mdp.template +70 -0
- BFEE2/templates_gromacs/003.colvars.template +125 -0
- BFEE2/templates_gromacs/003.generate_tpr_sh.template +36 -0
- BFEE2/templates_gromacs/003.mdp.template +70 -0
- BFEE2/templates_gromacs/004.colvars.template +148 -0
- BFEE2/templates_gromacs/004.generate_tpr_sh.template +37 -0
- BFEE2/templates_gromacs/004.mdp.template +70 -0
- BFEE2/templates_gromacs/005.colvars.template +170 -0
- BFEE2/templates_gromacs/005.generate_tpr_sh.template +38 -0
- BFEE2/templates_gromacs/005.mdp.template +70 -0
- BFEE2/templates_gromacs/006.colvars.template +192 -0
- BFEE2/templates_gromacs/006.generate_tpr_sh.template +39 -0
- BFEE2/templates_gromacs/006.mdp.template +70 -0
- BFEE2/templates_gromacs/007.colvars.template +210 -0
- BFEE2/templates_gromacs/007.generate_tpr_sh.template +40 -0
- BFEE2/templates_gromacs/007.mdp.template +69 -0
- BFEE2/templates_gromacs/007_eq.colvars.template +169 -0
- BFEE2/templates_gromacs/007_eq.generate_tpr_sh.template +64 -0
- BFEE2/templates_gromacs/007_min.mdp.template +58 -0
- BFEE2/templates_gromacs/008.colvars.template +42 -0
- BFEE2/templates_gromacs/008.generate_tpr_sh.template +31 -0
- BFEE2/templates_gromacs/008.mdp.template +70 -0
- BFEE2/templates_gromacs/008_eq.generate_tpr_sh.template +31 -0
- BFEE2/templates_gromacs/BFEEGromacs.py +1244 -0
- BFEE2/templates_gromacs/__init__.py +0 -0
- BFEE2/templates_gromacs/find_min_max.awk +27 -0
- BFEE2/templates_namd/__init__.py +0 -0
- BFEE2/templates_namd/configTemplate.py +1094 -0
- BFEE2/templates_namd/fep.tcl +299 -0
- BFEE2/templates_namd/scriptTemplate.py +149 -0
- BFEE2/templates_namd/solvate.tcl +9 -0
- BFEE2/templates_namd/solvate_mem.tcl +9 -0
- BFEE2/templates_namd/updateCenters.py +311 -0
- BFEE2/templates_readme/Readme_Gromacs_Geometrical.txt +25 -0
- BFEE2/templates_readme/Readme_NAMD_Alchemical.txt +20 -0
- BFEE2/templates_readme/Readme_NAMD_Geometrical.txt +34 -0
- BFEE2/templates_readme/__init__.py +1 -0
- BFEE2/third_party/__init__.py +0 -0
- BFEE2/third_party/py_bar.py +335 -0
- BFEE2/version.py +2 -0
- bfee2-2.5.0.data/scripts/BFEE2Gui.py +18 -0
- bfee2-2.5.0.dist-info/LICENSE +677 -0
- bfee2-2.5.0.dist-info/METADATA +76 -0
- bfee2-2.5.0.dist-info/RECORD +65 -0
- bfee2-2.5.0.dist-info/WHEEL +5 -0
- bfee2-2.5.0.dist-info/top_level.txt +1 -0
BFEE2/gui.py
ADDED
|
@@ -0,0 +1,2136 @@
|
|
|
1
|
+
# the GUI of new BFEE
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
import sys
|
|
6
|
+
import webbrowser
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
# use appdirs to manage persistent configuration
|
|
10
|
+
from appdirs import user_config_dir
|
|
11
|
+
from PySide2 import QtCore
|
|
12
|
+
from PySide2.QtGui import QFont, QIcon
|
|
13
|
+
from PySide2.QtWidgets import (QAction, QApplication, QCheckBox, QComboBox,
|
|
14
|
+
QFileDialog, QGridLayout, QGroupBox,
|
|
15
|
+
QHBoxLayout, QLabel, QLineEdit, QListWidget,
|
|
16
|
+
QMainWindow, QMessageBox, QPushButton,
|
|
17
|
+
QSplitter, QTabWidget, QToolBar, QVBoxLayout,
|
|
18
|
+
QWidget, QSpacerItem)
|
|
19
|
+
|
|
20
|
+
import BFEE2.inputGenerator as inputGenerator
|
|
21
|
+
import BFEE2.postTreatment as postTreatment
|
|
22
|
+
import BFEE2.templates_gromacs.BFEEGromacs as BFEEGromacs
|
|
23
|
+
from BFEE2.commonTools import commonSlots, fileParser, ploter
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import importlib.resources as pkg_resources
|
|
27
|
+
except ImportError:
|
|
28
|
+
# Try backported to PY<37 `importlib_resources`.
|
|
29
|
+
import importlib_resources as pkg_resources
|
|
30
|
+
|
|
31
|
+
import BFEE2.version
|
|
32
|
+
from BFEE2 import doc
|
|
33
|
+
|
|
34
|
+
__PROGRAM_NAME__ = f'BFEEstimator v{BFEE2.version.__VERSION__}'
|
|
35
|
+
__NAMD_VERSION__ = f'v{BFEE2.version.__NAMD_VERSION__}'
|
|
36
|
+
|
|
37
|
+
class mainSettings(QWidget):
|
|
38
|
+
"""settings in the menubar
|
|
39
|
+
set pathes of third-party softwares (VMD, gmx and tleap)
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
super().__init__()
|
|
44
|
+
self.config_dir = user_config_dir('BFEE2', 'chinfo')
|
|
45
|
+
# test if config directory exists
|
|
46
|
+
if not os.path.exists(self.config_dir):
|
|
47
|
+
# create it if not exists
|
|
48
|
+
os.makedirs(self.config_dir)
|
|
49
|
+
self._initUI()
|
|
50
|
+
self._initSingalsSlots()
|
|
51
|
+
self.setWindowTitle('Settings')
|
|
52
|
+
self._readConfig()
|
|
53
|
+
#self.setGeometry(0,0,0,0)
|
|
54
|
+
#self.show()
|
|
55
|
+
|
|
56
|
+
def _initUI(self):
|
|
57
|
+
"""settings GUI
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
self.mainLayout = QVBoxLayout()
|
|
61
|
+
|
|
62
|
+
self.thirdPartySoftware = QGroupBox('Third party software:')
|
|
63
|
+
self.thirdPartySoftwareLayout = QVBoxLayout()
|
|
64
|
+
|
|
65
|
+
# settings grid
|
|
66
|
+
self.settingsGridLayout = QGridLayout()
|
|
67
|
+
|
|
68
|
+
# vmd
|
|
69
|
+
self.vmdLabel = QLabel('VMD:')
|
|
70
|
+
self.vmdLineEdit = QLineEdit()
|
|
71
|
+
self.vmdButton = QPushButton('Browse')
|
|
72
|
+
self.settingsGridLayout.addWidget(self.vmdLabel, 0, 0)
|
|
73
|
+
self.settingsGridLayout.addWidget(self.vmdLineEdit, 0, 1)
|
|
74
|
+
self.settingsGridLayout.addWidget(self.vmdButton, 0, 2)
|
|
75
|
+
|
|
76
|
+
# gmx
|
|
77
|
+
#self.gromacsLayout = QHBoxLayout()
|
|
78
|
+
#self.gromacsLabel = QLabel('Gromacs:')
|
|
79
|
+
#self.gromacsLineEdit = QLineEdit()
|
|
80
|
+
#self.gromacsButton = QPushButton('Browse')
|
|
81
|
+
#self.settingsGridLayout.addWidget(self.gromacsLabel, 1, 0)
|
|
82
|
+
#self.settingsGridLayout.addWidget(self.gromacsLineEdit,1 ,1)
|
|
83
|
+
#self.settingsGridLayout.addWidget(self.gromacsButton, 1, 2)
|
|
84
|
+
|
|
85
|
+
# tleap
|
|
86
|
+
#self.tleapLayout = QHBoxLayout()
|
|
87
|
+
#self.tleapLabel = QLabel('tleap:')
|
|
88
|
+
#self.tleapLineEdit = QLineEdit()
|
|
89
|
+
#self.tleapButton = QPushButton('Browse')
|
|
90
|
+
#self.settingsGridLayout.addWidget(self.tleapLabel, 2, 0)
|
|
91
|
+
#self.settingsGridLayout.addWidget(self.tleapLineEdit, 2, 1)
|
|
92
|
+
#self.settingsGridLayout.addWidget(self.tleapButton, 2, 2)
|
|
93
|
+
|
|
94
|
+
# OK and Cancel
|
|
95
|
+
self.settingsButtonLayout = QHBoxLayout()
|
|
96
|
+
self.settingsOKButton = QPushButton('OK')
|
|
97
|
+
#self.settingsCancelButton = QPushButton('Cancel')
|
|
98
|
+
self.settingsButtonLayout.addWidget(QSplitter())
|
|
99
|
+
self.settingsButtonLayout.addWidget(self.settingsOKButton)
|
|
100
|
+
#self.settingsButtonLayout.addWidget(self.settingsCancelButton)
|
|
101
|
+
|
|
102
|
+
self.thirdPartySoftwareLayout.addLayout(self.settingsGridLayout)
|
|
103
|
+
self.thirdPartySoftwareLayout.addLayout(self.settingsButtonLayout)
|
|
104
|
+
|
|
105
|
+
self.thirdPartySoftware.setLayout(self.thirdPartySoftwareLayout)
|
|
106
|
+
self.mainLayout.addWidget(self.thirdPartySoftware)
|
|
107
|
+
self.setLayout(self.mainLayout)
|
|
108
|
+
|
|
109
|
+
def _initSingalsSlots(self):
|
|
110
|
+
"""initialize singals and slots
|
|
111
|
+
"""
|
|
112
|
+
self.vmdButton.clicked.connect(commonSlots.openFileDialog('exe', self.vmdLineEdit))
|
|
113
|
+
#self.gromacsButton.clicked.connect(commonSlots.openFileDialog('exe', self.gromacsLineEdit))
|
|
114
|
+
#self.tleapButton.clicked.connect(commonSlots.openFileDialog('exe', self.tleapLineEdit))
|
|
115
|
+
self.settingsOKButton.clicked.connect(self._OKSlot())
|
|
116
|
+
|
|
117
|
+
def _readConfig(self):
|
|
118
|
+
"""read the config saving paths for third-party softwares
|
|
119
|
+
"""
|
|
120
|
+
if not os.path.exists(f'{self.config_dir}/3rdSoft.ini'):
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
with open(f'{self.config_dir}/3rdSoft.ini', 'r') as cFile:
|
|
124
|
+
line = cFile.readline()
|
|
125
|
+
self.vmdLineEdit.setText(line.strip())
|
|
126
|
+
#line = cFile.readline()
|
|
127
|
+
#self.gromacsLineEdit.setText(line.strip())
|
|
128
|
+
#line = cFile.readline()
|
|
129
|
+
#self.tleapLineEdit.setText(line.strip())
|
|
130
|
+
|
|
131
|
+
def _writeConfig(self):
|
|
132
|
+
"""write the config saving paths for third-party softwares
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
with open(f'{self.config_dir}/3rdSoft.ini', 'w') as cFile:
|
|
136
|
+
cFile.write(self.vmdLineEdit.text() + '\n')
|
|
137
|
+
#cFile.write(self.gromacsLineEdit.text() + '\n')
|
|
138
|
+
#cFile.write(self.tleapLineEdit.text() + '\n')
|
|
139
|
+
|
|
140
|
+
def _OKSlot(self):
|
|
141
|
+
"""the slot corresponding the OK button
|
|
142
|
+
"""
|
|
143
|
+
def f():
|
|
144
|
+
self._writeConfig()
|
|
145
|
+
self.close()
|
|
146
|
+
return f
|
|
147
|
+
|
|
148
|
+
class geometricAdvancedSettings(QWidget):
|
|
149
|
+
"""advanced settings for the geometric route
|
|
150
|
+
set pulling direction, non-standard solvent
|
|
151
|
+
and number of stratification windows
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
def __init__(self):
|
|
155
|
+
super().__init__()
|
|
156
|
+
self._initUI()
|
|
157
|
+
self._initSingalsSlots()
|
|
158
|
+
self.setWindowTitle('Geometric advanced settings')
|
|
159
|
+
self.setGeometry(0,0,0,0)
|
|
160
|
+
#self.show()
|
|
161
|
+
|
|
162
|
+
def _initUI(self):
|
|
163
|
+
"""initialize UI for the geometric advanced settings
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
self.mainLayout = QVBoxLayout()
|
|
167
|
+
|
|
168
|
+
# user-defined pulling direction
|
|
169
|
+
self.userDefinedDirection = QGroupBox('User-defined separation direction')
|
|
170
|
+
self.userDefinedDirectionLayout = QHBoxLayout()
|
|
171
|
+
|
|
172
|
+
self.userDefinedDirectionLabel = QLabel('Reference:')
|
|
173
|
+
self.userDefinedDirectionLineEdit = QLineEdit()
|
|
174
|
+
self.userDefinedDirectionLayout.addWidget(self.userDefinedDirectionLabel)
|
|
175
|
+
self.userDefinedDirectionLayout.addWidget(self.userDefinedDirectionLineEdit)
|
|
176
|
+
|
|
177
|
+
self.userDefinedDirection.setLayout(self.userDefinedDirectionLayout)
|
|
178
|
+
|
|
179
|
+
# non-standard solvent
|
|
180
|
+
self.nonStandardSolvent = QGroupBox('User-provided large box')
|
|
181
|
+
self.nonStandardSolventLayout = QGridLayout()
|
|
182
|
+
|
|
183
|
+
self.nonStandardSolventPsfLabel = QLabel('psf/parm file:')
|
|
184
|
+
self.nonStandardSolventPsfLineEdit = QLineEdit()
|
|
185
|
+
self.nonStandardSolventPsfButton = QPushButton('Browse')
|
|
186
|
+
self.nonStandardSolventPdbLabel = QLabel('pdb/rst7 file:')
|
|
187
|
+
self.nonStandardSolventPdbLineEdit = QLineEdit()
|
|
188
|
+
self.nonStandardSolventPdbButton = QPushButton('Browse')
|
|
189
|
+
self.nonStandardSolventLayout.addWidget(self.nonStandardSolventPsfLabel, 0, 0)
|
|
190
|
+
self.nonStandardSolventLayout.addWidget(self.nonStandardSolventPsfLineEdit, 0, 1)
|
|
191
|
+
self.nonStandardSolventLayout.addWidget(self.nonStandardSolventPsfButton, 0, 2)
|
|
192
|
+
self.nonStandardSolventLayout.addWidget(self.nonStandardSolventPdbLabel, 1, 0)
|
|
193
|
+
self.nonStandardSolventLayout.addWidget(self.nonStandardSolventPdbLineEdit, 1, 1)
|
|
194
|
+
self.nonStandardSolventLayout.addWidget(self.nonStandardSolventPdbButton, 1, 2)
|
|
195
|
+
|
|
196
|
+
self.nonStandardSolvent.setLayout(self.nonStandardSolventLayout)
|
|
197
|
+
|
|
198
|
+
# stratification
|
|
199
|
+
self.stratification = QGroupBox('Stratification (number of strata)')
|
|
200
|
+
self.stratificationLayout = QGridLayout()
|
|
201
|
+
|
|
202
|
+
self.stratificationRMSDBoundLabel = QLabel('RMSD(Bound):')
|
|
203
|
+
self.stratificationRMSDBoundLineEdit = QLineEdit('1')
|
|
204
|
+
self.stratificationTheta = QLabel('Theta:')
|
|
205
|
+
self.stratificationThetaLineEdit = QLineEdit('1')
|
|
206
|
+
self.stratificationPhiLabel = QLabel('Phi:')
|
|
207
|
+
self.stratificationPhiLineEdit = QLineEdit('1')
|
|
208
|
+
self.stratificationPsiLabel = QLabel('Psi:')
|
|
209
|
+
self.stratificationPsiLineEdit = QLineEdit('1')
|
|
210
|
+
self.stratificationthetaLabel = QLabel('theta:')
|
|
211
|
+
self.stratificationthetaLineEdit = QLineEdit('1')
|
|
212
|
+
self.stratificationphiLabel = QLabel('phi:')
|
|
213
|
+
self.stratificationphiLineEdit = QLineEdit('1')
|
|
214
|
+
self.stratificationRLabel = QLabel('r:')
|
|
215
|
+
self.stratificationRLineEdit = QLineEdit('1')
|
|
216
|
+
self.stratificationRMSDUnboundLabel = QLabel('RMSD(Unbound):')
|
|
217
|
+
self.stratificationRMSDUnboundLineEdit = QLineEdit('1')
|
|
218
|
+
|
|
219
|
+
self.stratificationLayout.addWidget(self.stratificationRMSDBoundLabel, 0, 0)
|
|
220
|
+
self.stratificationLayout.addWidget(self.stratificationRMSDBoundLineEdit, 0, 1)
|
|
221
|
+
self.stratificationLayout.addWidget(self.stratificationTheta, 0, 2)
|
|
222
|
+
self.stratificationLayout.addWidget(self.stratificationThetaLineEdit, 0, 3)
|
|
223
|
+
self.stratificationLayout.addWidget(self.stratificationPhiLabel, 0, 4)
|
|
224
|
+
self.stratificationLayout.addWidget(self.stratificationPhiLineEdit, 0, 5)
|
|
225
|
+
self.stratificationLayout.addWidget(self.stratificationPsiLabel, 0, 6)
|
|
226
|
+
self.stratificationLayout.addWidget(self.stratificationPsiLineEdit, 0, 7)
|
|
227
|
+
self.stratificationLayout.addWidget(self.stratificationthetaLabel, 1, 0)
|
|
228
|
+
self.stratificationLayout.addWidget(self.stratificationthetaLineEdit, 1, 1)
|
|
229
|
+
self.stratificationLayout.addWidget(self.stratificationphiLabel, 1, 2)
|
|
230
|
+
self.stratificationLayout.addWidget(self.stratificationphiLineEdit, 1, 3)
|
|
231
|
+
self.stratificationLayout.addWidget(self.stratificationRLabel, 1, 4)
|
|
232
|
+
self.stratificationLayout.addWidget(self.stratificationRLineEdit, 1, 5)
|
|
233
|
+
self.stratificationLayout.addWidget(self.stratificationRMSDUnboundLabel, 1, 6)
|
|
234
|
+
self.stratificationLayout.addWidget(self.stratificationRMSDUnboundLineEdit, 1, 7)
|
|
235
|
+
|
|
236
|
+
self.stratification.setLayout(self.stratificationLayout)
|
|
237
|
+
|
|
238
|
+
# compatibility
|
|
239
|
+
self.compatibility = QGroupBox('Compatibility')
|
|
240
|
+
self.compatibilityLayout = QGridLayout()
|
|
241
|
+
|
|
242
|
+
self.pinDownProCheckbox = QCheckBox('Pinning down the protein')
|
|
243
|
+
self.pinDownProCheckbox.setChecked(True)
|
|
244
|
+
|
|
245
|
+
self.useOldCvCheckbox = QCheckBox('Use quaternion-based CVs')
|
|
246
|
+
self.useOldCvCheckbox.setChecked(False)
|
|
247
|
+
|
|
248
|
+
self.reflectingBoundaryCheckbox = QCheckBox('Use reflecting boundary')
|
|
249
|
+
self.reflectingBoundaryCheckbox.setChecked(True)
|
|
250
|
+
|
|
251
|
+
self.useCUDASOAIntegrator = QCheckBox('Use CUDASOA integrator')
|
|
252
|
+
self.useCUDASOAIntegrator.setChecked(False)
|
|
253
|
+
|
|
254
|
+
self.compatibilityLayout.addWidget(self.pinDownProCheckbox, 0, 0)
|
|
255
|
+
self.compatibilityLayout.addWidget(self.useOldCvCheckbox, 0, 1)
|
|
256
|
+
self.compatibilityLayout.addWidget(self.reflectingBoundaryCheckbox, 1, 0)
|
|
257
|
+
self.compatibilityLayout.addWidget(self.useCUDASOAIntegrator, 1, 1)
|
|
258
|
+
self.compatibility.setLayout(self.compatibilityLayout)
|
|
259
|
+
|
|
260
|
+
# force field settings
|
|
261
|
+
self.FFSettings = QGroupBox('Force field settings')
|
|
262
|
+
self.FFSettingsLayout = QHBoxLayout()
|
|
263
|
+
|
|
264
|
+
self.OPLSMixingRuleCheckbox = QCheckBox('OPLS mixing rules')
|
|
265
|
+
self.OPLSMixingRuleCheckbox.setChecked(False)
|
|
266
|
+
|
|
267
|
+
self.timestepLayout = QHBoxLayout()
|
|
268
|
+
self.timestepLabel = QLabel(' Timestep:')
|
|
269
|
+
self.timestepLineEdit = QLineEdit('2.0')
|
|
270
|
+
self.timestepLayout.addWidget(self.timestepLabel)
|
|
271
|
+
self.timestepLayout.addWidget(self.timestepLineEdit)
|
|
272
|
+
|
|
273
|
+
self.FFSettingsLayout.addWidget(self.OPLSMixingRuleCheckbox)
|
|
274
|
+
self.FFSettingsLayout.addLayout(self.timestepLayout)
|
|
275
|
+
self.FFSettings.setLayout(self.FFSettingsLayout)
|
|
276
|
+
|
|
277
|
+
# strategy settings
|
|
278
|
+
self.strategy = QGroupBox('Strategy settings')
|
|
279
|
+
self.strategyLayout = QHBoxLayout()
|
|
280
|
+
|
|
281
|
+
self.considerRMSDCVCheckbox = QCheckBox('Take into account RMSD CV')
|
|
282
|
+
self.considerRMSDCVCheckbox.setChecked(True)
|
|
283
|
+
|
|
284
|
+
self.useGaWTMCheckbox = QCheckBox('Use GaWTM-eABF')
|
|
285
|
+
self.useGaWTMCheckbox.setChecked(False)
|
|
286
|
+
|
|
287
|
+
self.strategyLayout.addWidget(self.considerRMSDCVCheckbox)
|
|
288
|
+
self.strategyLayout.addWidget(self.useGaWTMCheckbox)
|
|
289
|
+
self.strategy.setLayout(self.strategyLayout)
|
|
290
|
+
|
|
291
|
+
# membrane protein
|
|
292
|
+
self.modeling = QGroupBox('Modeling (avaiable for CHARMM FF)')
|
|
293
|
+
self.modelingLayout = QVBoxLayout()
|
|
294
|
+
|
|
295
|
+
self.memProCheckbox = QCheckBox('Membrane protein')
|
|
296
|
+
self.memProCheckbox.setChecked(False)
|
|
297
|
+
|
|
298
|
+
self.neutralizeLigOnlyLayout = QHBoxLayout()
|
|
299
|
+
self.neutralizeLigOnlyLabel = QLabel('Auto-neutralize ligand-only system by:')
|
|
300
|
+
self.neutralizeLigOnlyCombobox = QComboBox()
|
|
301
|
+
self.neutralizeLigOnlyCombobox.addItem('NaCl')
|
|
302
|
+
self.neutralizeLigOnlyCombobox.addItem('KCl')
|
|
303
|
+
self.neutralizeLigOnlyCombobox.addItem('CaCl2')
|
|
304
|
+
self.neutralizeLigOnlyCombobox.addItem('None')
|
|
305
|
+
self.neutralizeLigOnlyLayout.addWidget(self.neutralizeLigOnlyLabel)
|
|
306
|
+
self.neutralizeLigOnlyLayout.addWidget(self.neutralizeLigOnlyCombobox)
|
|
307
|
+
|
|
308
|
+
self.modelingLayout.addWidget(self.memProCheckbox)
|
|
309
|
+
self.modelingLayout.addLayout(self.neutralizeLigOnlyLayout)
|
|
310
|
+
self.modeling.setLayout(self.modelingLayout)
|
|
311
|
+
|
|
312
|
+
# parallel runs for error estimation
|
|
313
|
+
self.parallelRuns = QGroupBox('Parallel runs')
|
|
314
|
+
self.parallelRunsLayout = QHBoxLayout()
|
|
315
|
+
|
|
316
|
+
self.parallelRunsLabel = QLabel('Number of parallel runs: ')
|
|
317
|
+
self.parallelRunsLineEdit = QLineEdit('1')
|
|
318
|
+
|
|
319
|
+
self.parallelRunsLayout.addWidget(self.parallelRunsLabel)
|
|
320
|
+
self.parallelRunsLayout.addWidget(self.parallelRunsLineEdit)
|
|
321
|
+
self.parallelRuns.setLayout(self.parallelRunsLayout)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
self.geometricAdvancedSettingsButtonLayout = QHBoxLayout()
|
|
325
|
+
self.geometricAdvancedSettingsOKButton = QPushButton('OK')
|
|
326
|
+
#self.geometricAdvancedSettingsCancelButton = QPushButton('Cancel')
|
|
327
|
+
self.geometricAdvancedSettingsButtonLayout.addWidget(QSplitter())
|
|
328
|
+
self.geometricAdvancedSettingsButtonLayout.addWidget(self.geometricAdvancedSettingsOKButton)
|
|
329
|
+
#self.geometricAdvancedSettingsButtonLayout.addWidget(self.geometricAdvancedSettingsCancelButton)
|
|
330
|
+
|
|
331
|
+
self.mainLayout.addWidget(self.userDefinedDirection)
|
|
332
|
+
self.mainLayout.addWidget(self.nonStandardSolvent)
|
|
333
|
+
self.mainLayout.addWidget(self.stratification)
|
|
334
|
+
self.mainLayout.addWidget(self.compatibility)
|
|
335
|
+
self.mainLayout.addWidget(self.FFSettings)
|
|
336
|
+
self.mainLayout.addWidget(self.strategy)
|
|
337
|
+
self.mainLayout.addWidget(self.modeling)
|
|
338
|
+
self.mainLayout.addWidget(self.parallelRuns)
|
|
339
|
+
self.mainLayout.addLayout(self.geometricAdvancedSettingsButtonLayout)
|
|
340
|
+
self.setLayout(self.mainLayout)
|
|
341
|
+
|
|
342
|
+
def _initSingalsSlots(self):
|
|
343
|
+
"""initialize (connect) signial and slots for geometric advanced settings
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
self.nonStandardSolventPsfButton.clicked.connect(
|
|
347
|
+
commonSlots.openFileDialog(
|
|
348
|
+
'psf/parm/top',
|
|
349
|
+
self.nonStandardSolventPsfLineEdit
|
|
350
|
+
)
|
|
351
|
+
)
|
|
352
|
+
self.nonStandardSolventPdbButton.clicked.connect(
|
|
353
|
+
commonSlots.openFileDialog(
|
|
354
|
+
'pdb/gro',
|
|
355
|
+
self.nonStandardSolventPdbLineEdit
|
|
356
|
+
)
|
|
357
|
+
)
|
|
358
|
+
self.geometricAdvancedSettingsOKButton.clicked.connect(self.close)
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class alchemicalAdvancedSettings(QWidget):
|
|
362
|
+
"""advanced settings for the alchemical route
|
|
363
|
+
set the number of stratification windows
|
|
364
|
+
"""
|
|
365
|
+
|
|
366
|
+
def __init__(self):
|
|
367
|
+
super().__init__()
|
|
368
|
+
self._initUI()
|
|
369
|
+
self._initSingalsSlots()
|
|
370
|
+
self.setWindowTitle('Alchemical advanced settings')
|
|
371
|
+
self.setGeometry(0,0,0,0)
|
|
372
|
+
#self.show()
|
|
373
|
+
|
|
374
|
+
def _initUI(self):
|
|
375
|
+
"""initialize UI for the alchemical advanced settings
|
|
376
|
+
"""
|
|
377
|
+
|
|
378
|
+
self.mainLayout = QVBoxLayout()
|
|
379
|
+
|
|
380
|
+
# stratification windows
|
|
381
|
+
self.stratification = QGroupBox('Stratification (number of strata)')
|
|
382
|
+
self.stratificationLayout = QGridLayout()
|
|
383
|
+
|
|
384
|
+
self.boundLigandLabel = QLabel('Ligand/Bound state:')
|
|
385
|
+
self.boundLigandLineEdit = QLineEdit('50')
|
|
386
|
+
self.unboundLigandLabel = QLabel('Ligand/Unbound state:')
|
|
387
|
+
self.unboundLigandLineEdit = QLineEdit('20')
|
|
388
|
+
self.boundRestraintsLabel = QLabel('Restraints/Bound state:')
|
|
389
|
+
self.boundRestraintsLineEdit = QLineEdit('50')
|
|
390
|
+
self.unboundRestraintsLabel = QLabel('Restraints/Unbound state:')
|
|
391
|
+
self.unboundRestraintsLineEdit = QLineEdit('20')
|
|
392
|
+
|
|
393
|
+
self.stratificationLayout.addWidget(self.boundLigandLabel, 0, 0)
|
|
394
|
+
self.stratificationLayout.addWidget(self.boundLigandLineEdit, 0, 1)
|
|
395
|
+
self.stratificationLayout.addWidget(self.unboundLigandLabel, 0, 2)
|
|
396
|
+
self.stratificationLayout.addWidget(self.unboundLigandLineEdit, 0, 3)
|
|
397
|
+
self.stratificationLayout.addWidget(self.boundRestraintsLabel, 1, 0)
|
|
398
|
+
self.stratificationLayout.addWidget(self.boundRestraintsLineEdit, 1, 1)
|
|
399
|
+
self.stratificationLayout.addWidget(self.unboundRestraintsLabel, 1, 2)
|
|
400
|
+
self.stratificationLayout.addWidget(self.unboundRestraintsLineEdit, 1, 3)
|
|
401
|
+
|
|
402
|
+
self.stratification.setLayout(self.stratificationLayout)
|
|
403
|
+
|
|
404
|
+
# double-wide simulation
|
|
405
|
+
self.doubleWide = QGroupBox('Double-wide sampling simulation')
|
|
406
|
+
self.doubleWideLayout = QGridLayout()
|
|
407
|
+
|
|
408
|
+
self.doubleWideCheckbox = QCheckBox('Generate input files for double-wide sampling')
|
|
409
|
+
self.doubleWideCheckbox.setChecked(False)
|
|
410
|
+
self.doubleWideLayout.addWidget(self.doubleWideCheckbox)
|
|
411
|
+
self.doubleWide.setLayout(self.doubleWideLayout)
|
|
412
|
+
|
|
413
|
+
# minimize before sampling in each window
|
|
414
|
+
self.minBeforeSample = QGroupBox('Minimization before sampling')
|
|
415
|
+
self.minBeforeSampleLayout = QVBoxLayout()
|
|
416
|
+
|
|
417
|
+
self.minBeforeSampleCheckbox = QCheckBox('Minimize before sampling in each window')
|
|
418
|
+
self.minBeforeSampleCheckbox.setChecked(False)
|
|
419
|
+
self.minBeforeSampleLayout.addWidget(self.minBeforeSampleCheckbox)
|
|
420
|
+
self.minBeforeSample.setLayout(self.minBeforeSampleLayout)
|
|
421
|
+
|
|
422
|
+
# compatibility
|
|
423
|
+
self.compatibility = QGroupBox('Compatibility')
|
|
424
|
+
self.compatibilityLayout = QGridLayout()
|
|
425
|
+
|
|
426
|
+
self.pinDownProCheckbox = QCheckBox('Pinning down the protein')
|
|
427
|
+
self.pinDownProCheckbox.setChecked(True)
|
|
428
|
+
|
|
429
|
+
self.useOldCvCheckbox = QCheckBox('Use quaternion-based CVs')
|
|
430
|
+
self.useOldCvCheckbox.setChecked(False)
|
|
431
|
+
|
|
432
|
+
self.useCUDASOAIntegrator = QCheckBox('Use CUDASOA integrator')
|
|
433
|
+
self.useCUDASOAIntegrator.setChecked(False)
|
|
434
|
+
|
|
435
|
+
self.compatibilityLayout.addWidget(self.pinDownProCheckbox, 0, 0)
|
|
436
|
+
self.compatibilityLayout.addWidget(self.useOldCvCheckbox, 0, 1)
|
|
437
|
+
self.compatibilityLayout.addWidget(self.useCUDASOAIntegrator, 1, 0)
|
|
438
|
+
self.compatibility.setLayout(self.compatibilityLayout)
|
|
439
|
+
|
|
440
|
+
# force field settings
|
|
441
|
+
self.FFSettings = QGroupBox('Force field settings')
|
|
442
|
+
self.FFSettingsLayout = QHBoxLayout()
|
|
443
|
+
|
|
444
|
+
self.OPLSMixingRuleCheckbox = QCheckBox('OPLS mixing rules')
|
|
445
|
+
self.OPLSMixingRuleCheckbox.setChecked(False)
|
|
446
|
+
|
|
447
|
+
self.timestepLayout = QHBoxLayout()
|
|
448
|
+
self.timestepLabel = QLabel(' Timestep:')
|
|
449
|
+
self.timestepLineEdit = QLineEdit('2.0')
|
|
450
|
+
self.timestepLayout.addWidget(self.timestepLabel)
|
|
451
|
+
self.timestepLayout.addWidget(self.timestepLineEdit)
|
|
452
|
+
|
|
453
|
+
self.FFSettingsLayout.addWidget(self.OPLSMixingRuleCheckbox)
|
|
454
|
+
self.FFSettingsLayout.addLayout(self.timestepLayout)
|
|
455
|
+
self.FFSettings.setLayout(self.FFSettingsLayout)
|
|
456
|
+
|
|
457
|
+
# strategy settings
|
|
458
|
+
self.strategy = QGroupBox('Strategy settings')
|
|
459
|
+
self.strategyLayout = QHBoxLayout()
|
|
460
|
+
|
|
461
|
+
self.considerRMSDCVCheckbox = QCheckBox('Take into account RMSD CV')
|
|
462
|
+
self.considerRMSDCVCheckbox.setChecked(True)
|
|
463
|
+
|
|
464
|
+
self.reEqCheckbox = QCheckBox('Re-equilibration after histogram')
|
|
465
|
+
self.reEqCheckbox.setChecked(False)
|
|
466
|
+
|
|
467
|
+
self.strategyLayout.addWidget(self.considerRMSDCVCheckbox)
|
|
468
|
+
self.strategyLayout.addWidget(self.reEqCheckbox)
|
|
469
|
+
self.strategy.setLayout(self.strategyLayout)
|
|
470
|
+
|
|
471
|
+
# membrane protein
|
|
472
|
+
self.modeling = QGroupBox('Modeling (avaiable for CHARMM FF)')
|
|
473
|
+
self.modelingLayout = QVBoxLayout()
|
|
474
|
+
|
|
475
|
+
self.memProCheckbox = QCheckBox('Membrane protein')
|
|
476
|
+
self.memProCheckbox.setChecked(False)
|
|
477
|
+
|
|
478
|
+
self.neutralizeLigOnlyLayout = QHBoxLayout()
|
|
479
|
+
self.neutralizeLigOnlyLabel = QLabel('Auto-neutralize ligand-only system by:')
|
|
480
|
+
self.neutralizeLigOnlyCombobox = QComboBox()
|
|
481
|
+
self.neutralizeLigOnlyCombobox.addItem('NaCl')
|
|
482
|
+
self.neutralizeLigOnlyCombobox.addItem('KCl')
|
|
483
|
+
self.neutralizeLigOnlyCombobox.addItem('CaCl2')
|
|
484
|
+
self.neutralizeLigOnlyCombobox.addItem('None')
|
|
485
|
+
self.neutralizeLigOnlyLayout.addWidget(self.neutralizeLigOnlyLabel)
|
|
486
|
+
self.neutralizeLigOnlyLayout.addWidget(self.neutralizeLigOnlyCombobox)
|
|
487
|
+
|
|
488
|
+
self.modelingLayout.addWidget(self.memProCheckbox)
|
|
489
|
+
self.modelingLayout.addLayout(self.neutralizeLigOnlyLayout)
|
|
490
|
+
self.modeling.setLayout(self.modelingLayout)
|
|
491
|
+
|
|
492
|
+
self.alchemicalAdvancedSettingsButtonLayout = QHBoxLayout()
|
|
493
|
+
self.alchemicalAdvancedSettingsOKButton = QPushButton('OK')
|
|
494
|
+
#self.alchemicalAdvancedSettingsCancelButton = QPushButton('Cancel')
|
|
495
|
+
self.alchemicalAdvancedSettingsButtonLayout.addWidget(QSplitter())
|
|
496
|
+
self.alchemicalAdvancedSettingsButtonLayout.addWidget(self.alchemicalAdvancedSettingsOKButton)
|
|
497
|
+
#self.alchemicalAdvancedSettingsButtonLayout.addWidget(self.alchemicalAdvancedSettingsCancelButton)
|
|
498
|
+
|
|
499
|
+
self.mainLayout.addWidget(self.stratification)
|
|
500
|
+
self.mainLayout.addWidget(self.doubleWide)
|
|
501
|
+
self.mainLayout.addWidget(self.compatibility)
|
|
502
|
+
self.mainLayout.addWidget(self.FFSettings)
|
|
503
|
+
self.mainLayout.addWidget(self.strategy)
|
|
504
|
+
self.mainLayout.addWidget(self.minBeforeSample)
|
|
505
|
+
self.mainLayout.addWidget(self.modeling)
|
|
506
|
+
self.mainLayout.addLayout(self.alchemicalAdvancedSettingsButtonLayout)
|
|
507
|
+
self.setLayout(self.mainLayout)
|
|
508
|
+
|
|
509
|
+
def _initSingalsSlots(self):
|
|
510
|
+
"""initialize (connect) signals and slots for the alchemical advanced settings
|
|
511
|
+
"""
|
|
512
|
+
|
|
513
|
+
self.alchemicalAdvancedSettingsOKButton.clicked.connect(self.close)
|
|
514
|
+
|
|
515
|
+
class mainUI(QMainWindow):
|
|
516
|
+
"""the main window UI
|
|
517
|
+
include the preTreatment, postTreatment and QuickPlot tab
|
|
518
|
+
the preTreatment tab include NAMD and Gromacs tab
|
|
519
|
+
the postTreatment tab include geometric and alchemical tab
|
|
520
|
+
"""
|
|
521
|
+
|
|
522
|
+
def __init__(self):
|
|
523
|
+
super().__init__()
|
|
524
|
+
|
|
525
|
+
self._initActions()
|
|
526
|
+
|
|
527
|
+
self._initNAMDTab()
|
|
528
|
+
self._initGromacsTab()
|
|
529
|
+
self._initPreTreatmentTab()
|
|
530
|
+
self._initQuickPlotTab()
|
|
531
|
+
|
|
532
|
+
self._initGeometricTab()
|
|
533
|
+
self._initAlchemicalTab()
|
|
534
|
+
self._initPostTreatmentTab()
|
|
535
|
+
|
|
536
|
+
self._initSingalsSlots()
|
|
537
|
+
|
|
538
|
+
self._initMainUI()
|
|
539
|
+
|
|
540
|
+
# other dialogs
|
|
541
|
+
self.mainSettings = mainSettings()
|
|
542
|
+
self.alchemicalAdvancedSettings = alchemicalAdvancedSettings()
|
|
543
|
+
self.geometricAdvancedSettings = geometricAdvancedSettings()
|
|
544
|
+
|
|
545
|
+
self.setGeometry(0,0,0,0)
|
|
546
|
+
self.setWindowTitle(__PROGRAM_NAME__)
|
|
547
|
+
self.setWindowIcon(QIcon("BFEE2/icon/icon.png"))
|
|
548
|
+
self.show()
|
|
549
|
+
|
|
550
|
+
self._showNAMDVersionWarning()
|
|
551
|
+
|
|
552
|
+
def _showNAMDVersionWarning(self):
|
|
553
|
+
''' show a message box ask for the latest NAMD version '''
|
|
554
|
+
QMessageBox.warning(self,
|
|
555
|
+
'Warning',
|
|
556
|
+
f'\
|
|
557
|
+
{__PROGRAM_NAME__} is fully compatible with NAMD {__NAMD_VERSION__}. \n\
|
|
558
|
+
Please use the same or a later version of NAMD if you have any problem.\n'
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
def _initActions(self):
|
|
562
|
+
''' initialize actions for menubar '''
|
|
563
|
+
|
|
564
|
+
# settings
|
|
565
|
+
self.settingsAction = QAction('&Settings', self)
|
|
566
|
+
self.settingsAction.setStatusTip('Set pathes for third-party softwares')
|
|
567
|
+
self.settingsAction.triggered.connect(self._mainSettings())
|
|
568
|
+
|
|
569
|
+
# exit
|
|
570
|
+
self.exitAction = QAction('&Exit', self)
|
|
571
|
+
self.exitAction.setStatusTip('Exit application')
|
|
572
|
+
self.exitAction.triggered.connect(QApplication.quit)
|
|
573
|
+
|
|
574
|
+
# help
|
|
575
|
+
self.helpAction = QAction('&Help', self)
|
|
576
|
+
self.helpAction.setStatusTip('Open user manual')
|
|
577
|
+
self.helpAction.triggered.connect(self._openDocFile)
|
|
578
|
+
|
|
579
|
+
# python API
|
|
580
|
+
self.pythonAPIAction = QAction('&Python API', self)
|
|
581
|
+
self.pythonAPIAction.setStatusTip('Open Python API Documentation')
|
|
582
|
+
self.pythonAPIAction.triggered.connect(self._openPythonAPIFile)
|
|
583
|
+
|
|
584
|
+
# about
|
|
585
|
+
self.aboutAction = QAction('&About', self)
|
|
586
|
+
self.aboutAction.setStatusTip('About BFEEstimator')
|
|
587
|
+
self.aboutAction.triggered.connect(self._showAboutBox())
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
def _initMainUI(self):
|
|
591
|
+
"""initialize main window
|
|
592
|
+
"""
|
|
593
|
+
|
|
594
|
+
# status bar
|
|
595
|
+
#self.statusBar()
|
|
596
|
+
|
|
597
|
+
# menu bar
|
|
598
|
+
menubar = self.menuBar()
|
|
599
|
+
menubar.setNativeMenuBar(False)
|
|
600
|
+
self.fileMenu = menubar.addMenu('&File')
|
|
601
|
+
self.fileMenu.addAction(self.settingsAction)
|
|
602
|
+
self.fileMenu.addSeparator()
|
|
603
|
+
self.fileMenu.addAction(self.exitAction)
|
|
604
|
+
|
|
605
|
+
self.helpMenu = menubar.addMenu('&Help')
|
|
606
|
+
self.helpMenu.addAction(self.helpAction)
|
|
607
|
+
self.helpMenu.addAction(self.pythonAPIAction)
|
|
608
|
+
self.helpMenu.addSeparator()
|
|
609
|
+
self.helpMenu.addAction(self.aboutAction)
|
|
610
|
+
|
|
611
|
+
# main layout
|
|
612
|
+
self.mainLayout = QVBoxLayout()
|
|
613
|
+
|
|
614
|
+
# title
|
|
615
|
+
self.title = QLabel('Binding Free Energy Estimator')
|
|
616
|
+
titleFont = QFont()
|
|
617
|
+
titleFont.setBold(True)
|
|
618
|
+
self.title.setFont(titleFont)
|
|
619
|
+
self.titleBox = QGroupBox()
|
|
620
|
+
self.titleBoxLayout = QVBoxLayout()
|
|
621
|
+
self.titleBoxLayout.addWidget(self.title, alignment=QtCore.Qt.AlignCenter)
|
|
622
|
+
self.titleBox.setLayout(self.titleBoxLayout)
|
|
623
|
+
|
|
624
|
+
# tabs
|
|
625
|
+
self.mainTabs = QTabWidget()
|
|
626
|
+
#self.preTreatmentTab = QWidget()
|
|
627
|
+
#self.postTreatmentTab = QWidget()
|
|
628
|
+
#self.quickPlot = QWidget()
|
|
629
|
+
|
|
630
|
+
self.mainTabs.addTab(self.preTreatmentTab, 'Pre-treatment')
|
|
631
|
+
self.mainTabs.addTab(self.postTreatmentTab, 'Post-treatment')
|
|
632
|
+
self.mainTabs.addTab(self.quickPlot, 'Quick-Plot')
|
|
633
|
+
|
|
634
|
+
# main layout
|
|
635
|
+
#self.mainLayout.addWidget(self.titleBox)
|
|
636
|
+
self.mainLayout.addWidget(self.mainTabs)
|
|
637
|
+
self.mainWidgit = QWidget()
|
|
638
|
+
self.mainWidgit.setLayout(self.mainLayout)
|
|
639
|
+
self.setCentralWidget(self.mainWidgit)
|
|
640
|
+
|
|
641
|
+
def _initPreTreatmentTab(self):
|
|
642
|
+
"""initialize pre-treatment tab
|
|
643
|
+
"""
|
|
644
|
+
|
|
645
|
+
self.preTreatmentTab = QWidget()
|
|
646
|
+
|
|
647
|
+
# pre-treatment tabs
|
|
648
|
+
# NAMD and gromacs
|
|
649
|
+
self.preTreatmentMainTabs = QTabWidget()
|
|
650
|
+
|
|
651
|
+
self.preTreatmentMainTabs.addTab(self.NAMDTab, 'NAMD/Gromacs(CHARMM/Amber files)')
|
|
652
|
+
self.preTreatmentMainTabs.addTab(self.GromacsTab, 'Gromacs(Gromacs files)')
|
|
653
|
+
|
|
654
|
+
self.preTreatmentMainLayout = QVBoxLayout()
|
|
655
|
+
self.preTreatmentMainLayout.addWidget(self.preTreatmentMainTabs)
|
|
656
|
+
|
|
657
|
+
# other parameters
|
|
658
|
+
self.otherParameters = QGroupBox('Other parameters')
|
|
659
|
+
self.otherParametersLayout = QVBoxLayout()
|
|
660
|
+
|
|
661
|
+
# temperature, selection protein and ligand layout
|
|
662
|
+
self.otherParametersChildLayout = QGridLayout()
|
|
663
|
+
|
|
664
|
+
# temperature
|
|
665
|
+
self.temperatureLabel = QLabel('Temperature: ')
|
|
666
|
+
self.temperatureLineEdit = QLineEdit('300')
|
|
667
|
+
self.otherParametersChildLayout.addWidget(self.temperatureLabel, 0, 0)
|
|
668
|
+
self.otherParametersChildLayout.addWidget(self.temperatureLineEdit, 0, 1)
|
|
669
|
+
|
|
670
|
+
# select protein
|
|
671
|
+
self.selectProteinLabel = QLabel('Select protein: ')
|
|
672
|
+
self.selectProteineLineEdit = QLineEdit('segid SH3D')
|
|
673
|
+
self.otherParametersChildLayout.addWidget(self.selectProteinLabel, 1, 0)
|
|
674
|
+
self.otherParametersChildLayout.addWidget(self.selectProteineLineEdit, 1, 1)
|
|
675
|
+
|
|
676
|
+
# select ligand
|
|
677
|
+
self.selectLigandLabel = QLabel('Select ligand: ')
|
|
678
|
+
self.selectLigandLineEdit = QLineEdit('segid PPRO')
|
|
679
|
+
self.otherParametersChildLayout.addWidget(self.selectLigandLabel, 2, 0)
|
|
680
|
+
self.otherParametersChildLayout.addWidget(self.selectLigandLineEdit, 2, 1)
|
|
681
|
+
|
|
682
|
+
# select strategy
|
|
683
|
+
self.selectStrategyLayout = QHBoxLayout()
|
|
684
|
+
|
|
685
|
+
self.selectStrategyLabel = QLabel('Select MD engine and strategy: ')
|
|
686
|
+
self.selectStrategyCombobox = QComboBox()
|
|
687
|
+
self.selectStrategyCombobox.addItem('Geometric')
|
|
688
|
+
self.selectStrategyCombobox.addItem('Alchemical')
|
|
689
|
+
self.selectStrategyAdvancedButton = QPushButton('Advanced settings')
|
|
690
|
+
|
|
691
|
+
self.selectMDEngineCombobox = QComboBox()
|
|
692
|
+
self.selectMDEngineCombobox.addItem('NAMD')
|
|
693
|
+
self.selectMDEngineCombobox.addItem('Gromacs')
|
|
694
|
+
|
|
695
|
+
self.selectStrategyChildLayout = QHBoxLayout()
|
|
696
|
+
self.selectStrategyChildLayout.addWidget(self.selectMDEngineCombobox)
|
|
697
|
+
self.selectStrategyChildLayout.addWidget(self.selectStrategyCombobox)
|
|
698
|
+
self.selectStrategyChildLayout.addWidget(self.selectStrategyAdvancedButton)
|
|
699
|
+
|
|
700
|
+
self.selectStrategyLayout.addWidget(self.selectStrategyLabel)
|
|
701
|
+
self.selectStrategyLayout.addLayout(self.selectStrategyChildLayout)
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
# generate input button
|
|
705
|
+
self.generateInputButton = QPushButton('Generate Inputs')
|
|
706
|
+
|
|
707
|
+
self.otherParametersLayout.addLayout(self.otherParametersChildLayout)
|
|
708
|
+
self.otherParametersLayout.addLayout(self.selectStrategyLayout)
|
|
709
|
+
self.otherParameters.setLayout(self.otherParametersLayout)
|
|
710
|
+
|
|
711
|
+
self.preTreatmentMainLayout.addWidget(self.otherParameters)
|
|
712
|
+
self.preTreatmentMainLayout.addWidget(self.generateInputButton)
|
|
713
|
+
|
|
714
|
+
self.preTreatmentTab.setLayout(self.preTreatmentMainLayout)
|
|
715
|
+
|
|
716
|
+
def _initNAMDTab(self):
|
|
717
|
+
"""initialize NAMD Tab in pre-treatment Tab
|
|
718
|
+
"""
|
|
719
|
+
|
|
720
|
+
self.NAMDTab = QWidget()
|
|
721
|
+
self.NAMDTabMainLayout = QVBoxLayout()
|
|
722
|
+
|
|
723
|
+
# inputs for the complex
|
|
724
|
+
self.inputsForComplex = QGroupBox('Inputs for complex')
|
|
725
|
+
self.inputsForComplexLayout = QGridLayout()
|
|
726
|
+
|
|
727
|
+
# psf/parm
|
|
728
|
+
self.psfLabel = QLabel('psf/parm file:')
|
|
729
|
+
self.psfLineEdit = QLineEdit()
|
|
730
|
+
self.psfButton = QPushButton('Browse')
|
|
731
|
+
self.inputsForComplexLayout.addWidget(self.psfLabel, 0, 0)
|
|
732
|
+
self.inputsForComplexLayout.addWidget(self.psfLineEdit, 0, 1)
|
|
733
|
+
self.inputsForComplexLayout.addWidget(self.psfButton, 0, 2)
|
|
734
|
+
|
|
735
|
+
# coor
|
|
736
|
+
self.coorLabel = QLabel('pdb/rst file:')
|
|
737
|
+
self.coorLineEdit = QLineEdit()
|
|
738
|
+
self.coorButton = QPushButton('Browse')
|
|
739
|
+
self.inputsForComplexLayout.addWidget(self.coorLabel, 1, 0)
|
|
740
|
+
self.inputsForComplexLayout.addWidget(self.coorLineEdit, 1, 1)
|
|
741
|
+
self.inputsForComplexLayout.addWidget(self.coorButton, 1, 2)
|
|
742
|
+
|
|
743
|
+
# force fields
|
|
744
|
+
self.forceFields = QGroupBox('Force fields')
|
|
745
|
+
self.forceFieldsLayout = QVBoxLayout()
|
|
746
|
+
|
|
747
|
+
# force field type
|
|
748
|
+
self.forceFieldTypeLayout = QHBoxLayout()
|
|
749
|
+
self.forceFieldTypeLabel = QLabel('Force field type:')
|
|
750
|
+
self.forceFieldCombobox = QComboBox()
|
|
751
|
+
self.forceFieldCombobox.addItem('CHARMM')
|
|
752
|
+
self.forceFieldCombobox.addItem('Amber')
|
|
753
|
+
|
|
754
|
+
self.forceFieldTypeLayout.addWidget(self.forceFieldTypeLabel)
|
|
755
|
+
self.forceFieldTypeLayout.addWidget(self.forceFieldCombobox)
|
|
756
|
+
|
|
757
|
+
# CHARMM force field files
|
|
758
|
+
self.forceFieldFilesLayout = QVBoxLayout()
|
|
759
|
+
self.forceFieldFilesLabel = QLabel('Force field files:')
|
|
760
|
+
self.forceFieldFilesBox = QListWidget()
|
|
761
|
+
self.forceFieldFilesChildLayout = QHBoxLayout()
|
|
762
|
+
self.forceFieldAddButton = QPushButton('Add')
|
|
763
|
+
self.forceFieldClearButton = QPushButton('Clear')
|
|
764
|
+
self.forceFieldFilesChildLayout.addWidget(self.forceFieldAddButton)
|
|
765
|
+
self.forceFieldFilesChildLayout.addWidget(self.forceFieldClearButton)
|
|
766
|
+
self.forceFieldFilesLayout.addWidget(self.forceFieldFilesLabel)
|
|
767
|
+
self.forceFieldFilesLayout.addWidget(self.forceFieldFilesBox)
|
|
768
|
+
self.forceFieldFilesLayout.addLayout(self.forceFieldFilesChildLayout)
|
|
769
|
+
|
|
770
|
+
self.forceFieldsLayout.addLayout(self.forceFieldTypeLayout)
|
|
771
|
+
self.forceFieldsLayout.addLayout(self.forceFieldFilesLayout)
|
|
772
|
+
|
|
773
|
+
self.inputsForComplex.setLayout(self.inputsForComplexLayout)
|
|
774
|
+
self.forceFields.setLayout(self.forceFieldsLayout)
|
|
775
|
+
self.NAMDTabMainLayout.addWidget(self.inputsForComplex)
|
|
776
|
+
self.NAMDTabMainLayout.addWidget(self.forceFields)
|
|
777
|
+
self.NAMDTab.setLayout(self.NAMDTabMainLayout)
|
|
778
|
+
|
|
779
|
+
def _initGromacsTab(self):
|
|
780
|
+
"""initialize GMX Tab in pre-treatment Tab
|
|
781
|
+
"""
|
|
782
|
+
|
|
783
|
+
self.GromacsTab = QWidget()
|
|
784
|
+
self.GromacsTabMainLayout = QVBoxLayout()
|
|
785
|
+
|
|
786
|
+
# inputs for the complex
|
|
787
|
+
self.GromacsInputsForComplex = QGroupBox('Inputs for complex')
|
|
788
|
+
self.GromacsInputsForComplexLayout = QGridLayout()
|
|
789
|
+
|
|
790
|
+
# top
|
|
791
|
+
self.topLabel = QLabel('Topology file: ')
|
|
792
|
+
self.topLineEdit = QLineEdit()
|
|
793
|
+
self.topButton = QPushButton('Browse')
|
|
794
|
+
self.GromacsInputsForComplexLayout.addWidget(self.topLabel, 0, 0)
|
|
795
|
+
self.GromacsInputsForComplexLayout.addWidget(self.topLineEdit, 0, 1)
|
|
796
|
+
self.GromacsInputsForComplexLayout.addWidget(self.topButton, 0, 2)
|
|
797
|
+
|
|
798
|
+
# gro
|
|
799
|
+
self.gromacsPdbLabel = QLabel('Structure file: ')
|
|
800
|
+
self.gromacsPdbLineEdit = QLineEdit()
|
|
801
|
+
self.gromacsPdbButton = QPushButton('Browse')
|
|
802
|
+
self.GromacsInputsForComplexLayout.addWidget(self.gromacsPdbLabel, 1, 0)
|
|
803
|
+
self.GromacsInputsForComplexLayout.addWidget(self.gromacsPdbLineEdit, 1, 1)
|
|
804
|
+
self.GromacsInputsForComplexLayout.addWidget(self.gromacsPdbButton, 1, 2)
|
|
805
|
+
|
|
806
|
+
# structure file format
|
|
807
|
+
self.gromacsStructureFileFormatLayout = QHBoxLayout()
|
|
808
|
+
self.gromacsStructureFileFormatLabel = QLabel('Structure file format:')
|
|
809
|
+
self.gromacsStructureFileFormatCombobox = QComboBox()
|
|
810
|
+
self.gromacsStructureFileFormatCombobox.addItem('pdb')
|
|
811
|
+
self.gromacsStructureFileFormatCombobox.addItem('xpdb')
|
|
812
|
+
self.gromacsStructureFileFormatCombobox.setToolTip('Select "<b>xpdb</b>" if your PDB file has more than 9,999 number of residues')
|
|
813
|
+
self.gromacsStructureFileFormatLayout.addWidget(self.gromacsStructureFileFormatLabel)
|
|
814
|
+
self.gromacsStructureFileFormatLayout.addWidget(self.gromacsStructureFileFormatCombobox)
|
|
815
|
+
self.GromacsInputsForComplexLayout.addLayout(self.gromacsStructureFileFormatLayout, 2, 0, 1, 3)
|
|
816
|
+
|
|
817
|
+
self.GromacsInputsForComplexLayout.addWidget(QSplitter(), 3, 1)
|
|
818
|
+
self.GromacsInputsForComplex.setLayout(self.GromacsInputsForComplexLayout)
|
|
819
|
+
|
|
820
|
+
# inputs for the ligand-only system
|
|
821
|
+
self.GromacsInputsLigandOnly = QGroupBox('Inputs for ligand-only system')
|
|
822
|
+
self.GromacsInputsLigandOnlyLayout = QGridLayout()
|
|
823
|
+
|
|
824
|
+
# top
|
|
825
|
+
self.gromacsLigandOnlyTopLabel = QLabel('Topology file: ')
|
|
826
|
+
self.gromacsLigandOnlyTopLineEdit = QLineEdit()
|
|
827
|
+
self.gromacsLigandOnlyTopButton = QPushButton('Browse')
|
|
828
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(self.gromacsLigandOnlyTopLabel, 0, 0)
|
|
829
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(self.gromacsLigandOnlyTopLineEdit, 0, 1)
|
|
830
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(self.gromacsLigandOnlyTopButton, 0, 2)
|
|
831
|
+
|
|
832
|
+
# gro
|
|
833
|
+
self.gromacsLigandOnlyPdbLabel = QLabel('Structure file: ')
|
|
834
|
+
self.gromacsLigandOnlyPdbLineEdit = QLineEdit()
|
|
835
|
+
self.gromacsLigandOnlyPdbButton = QPushButton('Browse')
|
|
836
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(self.gromacsLigandOnlyPdbLabel, 1, 0)
|
|
837
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(self.gromacsLigandOnlyPdbLineEdit, 1, 1)
|
|
838
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(self.gromacsLigandOnlyPdbButton, 1, 2)
|
|
839
|
+
|
|
840
|
+
# structure file format
|
|
841
|
+
self.gromacsLigandOnlyStructureFileFormatLayout = QHBoxLayout()
|
|
842
|
+
self.gromacsLigandOnlyStructureFileFormatLabel = QLabel('Structure file format:')
|
|
843
|
+
self.gromacsLigandOnlyStructureFileFormatCombobox = QComboBox()
|
|
844
|
+
self.gromacsLigandOnlyStructureFileFormatCombobox.addItem('pdb')
|
|
845
|
+
self.gromacsLigandOnlyStructureFileFormatCombobox.addItem('xpdb')
|
|
846
|
+
self.gromacsLigandOnlyStructureFileFormatCombobox.setToolTip('Select "<b>xpdb</b>" if your PDB file has more than 9,999 number of residues')
|
|
847
|
+
self.gromacsLigandOnlyStructureFileFormatLayout.addWidget(self.gromacsLigandOnlyStructureFileFormatLabel)
|
|
848
|
+
self.gromacsLigandOnlyStructureFileFormatLayout.addWidget(self.gromacsLigandOnlyStructureFileFormatCombobox)
|
|
849
|
+
self.GromacsInputsLigandOnlyLayout.addLayout(self.gromacsLigandOnlyStructureFileFormatLayout, 2, 0, 1, 3)
|
|
850
|
+
|
|
851
|
+
self.GromacsInputsLigandOnlyLayout.addWidget(QSplitter(), 3, 1)
|
|
852
|
+
self.GromacsInputsLigandOnly.setLayout(self.GromacsInputsLigandOnlyLayout)
|
|
853
|
+
|
|
854
|
+
self.GromacsTabMainLayout.addWidget(self.GromacsInputsForComplex)
|
|
855
|
+
self.GromacsTabMainLayout.addWidget(self.GromacsInputsLigandOnly)
|
|
856
|
+
|
|
857
|
+
self.GromacsTab.setLayout(self.GromacsTabMainLayout)
|
|
858
|
+
|
|
859
|
+
def _initPostTreatmentTab(self):
|
|
860
|
+
"""initialize pre-treatment tab
|
|
861
|
+
"""
|
|
862
|
+
|
|
863
|
+
self.postTreatmentTab = QWidget()
|
|
864
|
+
|
|
865
|
+
# post-treatment tabs
|
|
866
|
+
# Geometric and alchemical
|
|
867
|
+
self.postTreatmentMainTabs = QTabWidget()
|
|
868
|
+
|
|
869
|
+
self.postTreatmentMainTabs.addTab(self.geometricTab, 'Geometric')
|
|
870
|
+
self.postTreatmentMainTabs.addTab(self.alchemicalTab, 'Alchemical')
|
|
871
|
+
|
|
872
|
+
self.postTreatmentMainLayout = QVBoxLayout()
|
|
873
|
+
self.postTreatmentMainLayout.addWidget(self.postTreatmentMainTabs)
|
|
874
|
+
|
|
875
|
+
self.calculateButton = QPushButton('Calculate binding free energy')
|
|
876
|
+
self.postTreatmentMainLayout.addWidget(self.calculateButton)
|
|
877
|
+
|
|
878
|
+
self.postTreatmentTab.setLayout(self.postTreatmentMainLayout)
|
|
879
|
+
|
|
880
|
+
def _initGeometricTab(self):
|
|
881
|
+
"""initialize geometric tab of post-treatment
|
|
882
|
+
"""
|
|
883
|
+
|
|
884
|
+
self.geometricTab = QWidget()
|
|
885
|
+
self.geometricTabLayout = QVBoxLayout()
|
|
886
|
+
|
|
887
|
+
# pmf inputs
|
|
888
|
+
self.pmfInputs = QGroupBox('PMF inputs (.czar.pmf/.UI.pmf):')
|
|
889
|
+
self.pmfInputsLayout = QVBoxLayout()
|
|
890
|
+
|
|
891
|
+
# bound stats
|
|
892
|
+
self.boundStateLabel = QLabel('Bound state:')
|
|
893
|
+
self.boundStateLayout = QGridLayout()
|
|
894
|
+
|
|
895
|
+
# RMSD
|
|
896
|
+
self.rmsdBoundLabel = QLabel('RMSD: ')
|
|
897
|
+
self.rmsdBoundLineEdit = QLineEdit()
|
|
898
|
+
self.rmsdBoundButton = QPushButton('Browse')
|
|
899
|
+
self.boundStateLayout.addWidget(self.rmsdBoundLabel, 0, 0)
|
|
900
|
+
self.boundStateLayout.addWidget(self.rmsdBoundLineEdit, 0, 1)
|
|
901
|
+
self.boundStateLayout.addWidget(self.rmsdBoundButton, 0, 2)
|
|
902
|
+
|
|
903
|
+
# Theta
|
|
904
|
+
self.ThetaLabel = QLabel('Theta:')
|
|
905
|
+
self.ThetaLineEdit = QLineEdit()
|
|
906
|
+
self.ThetaButton = QPushButton('Browse')
|
|
907
|
+
self.boundStateLayout.addWidget(self.ThetaLabel, 1, 0)
|
|
908
|
+
self.boundStateLayout.addWidget(self.ThetaLineEdit, 1, 1)
|
|
909
|
+
self.boundStateLayout.addWidget(self.ThetaButton, 1, 2)
|
|
910
|
+
|
|
911
|
+
# Phi
|
|
912
|
+
self.PhiLabel = QLabel('Phi: ')
|
|
913
|
+
self.PhiLineEdit = QLineEdit()
|
|
914
|
+
self.PhiButton = QPushButton('Browse')
|
|
915
|
+
self.boundStateLayout.addWidget(self.PhiLabel, 2, 0)
|
|
916
|
+
self.boundStateLayout.addWidget(self.PhiLineEdit, 2, 1)
|
|
917
|
+
self.boundStateLayout.addWidget(self.PhiButton, 2, 2)
|
|
918
|
+
|
|
919
|
+
# Psi
|
|
920
|
+
self.PsiLabel = QLabel('Psi: ')
|
|
921
|
+
self.PsiLineEdit = QLineEdit()
|
|
922
|
+
self.PsiButton = QPushButton('Browse')
|
|
923
|
+
self.boundStateLayout.addWidget(self.PsiLabel, 3, 0)
|
|
924
|
+
self.boundStateLayout.addWidget(self.PsiLineEdit, 3, 1)
|
|
925
|
+
self.boundStateLayout.addWidget(self.PsiButton, 3, 2)
|
|
926
|
+
|
|
927
|
+
# theta
|
|
928
|
+
self.thetaLayout = QHBoxLayout()
|
|
929
|
+
self.thetaLabel = QLabel('theta:')
|
|
930
|
+
self.thetaLineEdit = QLineEdit()
|
|
931
|
+
self.thetaButton = QPushButton('Browse')
|
|
932
|
+
self.boundStateLayout.addWidget(self.thetaLabel, 4, 0)
|
|
933
|
+
self.boundStateLayout.addWidget(self.thetaLineEdit, 4, 1)
|
|
934
|
+
self.boundStateLayout.addWidget(self.thetaButton, 4, 2)
|
|
935
|
+
|
|
936
|
+
# phi
|
|
937
|
+
self.phiLayout = QHBoxLayout()
|
|
938
|
+
self.phiLabel = QLabel('phi: ')
|
|
939
|
+
self.phiLineEdit = QLineEdit()
|
|
940
|
+
self.phiButton = QPushButton('Browse')
|
|
941
|
+
self.boundStateLayout.addWidget(self.phiLabel, 5, 0)
|
|
942
|
+
self.boundStateLayout.addWidget(self.phiLineEdit, 5, 1)
|
|
943
|
+
self.boundStateLayout.addWidget(self.phiButton, 5, 2)
|
|
944
|
+
|
|
945
|
+
# r
|
|
946
|
+
self.rLabel = QLabel('r: ')
|
|
947
|
+
self.rLineEdit = QLineEdit()
|
|
948
|
+
self.rButton = QPushButton('Browse')
|
|
949
|
+
self.boundStateLayout.addWidget(self.rLabel, 6, 0)
|
|
950
|
+
self.boundStateLayout.addWidget(self.rLineEdit, 6, 1)
|
|
951
|
+
self.boundStateLayout.addWidget(self.rButton, 6, 2)
|
|
952
|
+
|
|
953
|
+
self.unboundStateLabel = QLabel('Unbound state:')
|
|
954
|
+
|
|
955
|
+
# RMSD unbound
|
|
956
|
+
self.rmsdUnboundLayout = QHBoxLayout()
|
|
957
|
+
self.rmsdUnboundLabel = QLabel('RMSD: ')
|
|
958
|
+
self.rmsdUnboundLineEdit = QLineEdit()
|
|
959
|
+
self.rmsdUnboundButton = QPushButton('Browse')
|
|
960
|
+
self.rmsdUnboundLayout.addWidget(self.rmsdUnboundLabel)
|
|
961
|
+
self.rmsdUnboundLayout.addWidget(self.rmsdUnboundLineEdit)
|
|
962
|
+
self.rmsdUnboundLayout.addWidget(self.rmsdUnboundButton)
|
|
963
|
+
|
|
964
|
+
self.pmfInputsLayout.addWidget(self.boundStateLabel)
|
|
965
|
+
self.pmfInputsLayout.addLayout(self.boundStateLayout)
|
|
966
|
+
self.pmfInputsLayout.addWidget(self.unboundStateLabel)
|
|
967
|
+
self.pmfInputsLayout.addLayout(self.rmsdUnboundLayout)
|
|
968
|
+
|
|
969
|
+
self.pmfInputs.setLayout(self.pmfInputsLayout)
|
|
970
|
+
|
|
971
|
+
# force constants
|
|
972
|
+
self.forceConstants = QGroupBox('Force constants (in Colvars unit):')
|
|
973
|
+
self.forceConstantsLayout = QGridLayout()
|
|
974
|
+
|
|
975
|
+
self.fcBoundStateLabel = QLabel('Bound state:')
|
|
976
|
+
|
|
977
|
+
# all widgets
|
|
978
|
+
self.fcRMSDLabel = QLabel('RMSD:')
|
|
979
|
+
self.fcRMSDLineEdit = QLineEdit('10')
|
|
980
|
+
self.fcThetaLabel = QLabel('Theta:')
|
|
981
|
+
self.fcThetaLineEdit = QLineEdit('0.1')
|
|
982
|
+
self.fcPhiLabel = QLabel('Phi:')
|
|
983
|
+
self.fcPhiLineEdit = QLineEdit('0.1')
|
|
984
|
+
self.fcPsiLabel = QLabel('Psi:')
|
|
985
|
+
self.fcPsiLineEdit = QLineEdit('0.1')
|
|
986
|
+
self.fcthetaLabel = QLabel('theta:')
|
|
987
|
+
self.fcthetaLineEdit = QLineEdit('0.1')
|
|
988
|
+
self.fcphiLabel = QLabel('phi:')
|
|
989
|
+
self.fcphiLineEdit = QLineEdit('0.1')
|
|
990
|
+
|
|
991
|
+
self.forceConstantsLayout.addWidget(self.fcRMSDLabel, 0, 0)
|
|
992
|
+
self.forceConstantsLayout.addWidget(self.fcRMSDLineEdit, 0, 1)
|
|
993
|
+
self.forceConstantsLayout.addWidget(self.fcThetaLabel, 0, 2)
|
|
994
|
+
self.forceConstantsLayout.addWidget(self.fcThetaLineEdit, 0, 3)
|
|
995
|
+
self.forceConstantsLayout.addWidget(self.fcPhiLabel, 0, 4)
|
|
996
|
+
self.forceConstantsLayout.addWidget(self.fcPhiLineEdit, 0, 5)
|
|
997
|
+
self.forceConstantsLayout.addWidget(self.fcPsiLabel, 1, 0)
|
|
998
|
+
self.forceConstantsLayout.addWidget(self.fcPsiLineEdit, 1, 1)
|
|
999
|
+
self.forceConstantsLayout.addWidget(self.fcthetaLabel, 1, 2)
|
|
1000
|
+
self.forceConstantsLayout.addWidget(self.fcthetaLineEdit, 1, 3)
|
|
1001
|
+
self.forceConstantsLayout.addWidget(self.fcphiLabel, 1, 4)
|
|
1002
|
+
self.forceConstantsLayout.addWidget(self.fcphiLineEdit, 1, 5)
|
|
1003
|
+
|
|
1004
|
+
self.forceConstants.setLayout(self.forceConstantsLayout)
|
|
1005
|
+
|
|
1006
|
+
# other parameters
|
|
1007
|
+
self.postOtherParams = QGroupBox('Other parameters:')
|
|
1008
|
+
self.postOtherParamsLayout = QHBoxLayout()
|
|
1009
|
+
|
|
1010
|
+
self.postTemperatureLabel = QLabel('temperature:')
|
|
1011
|
+
self.postTemperatureLineEdit = QLineEdit('300')
|
|
1012
|
+
self.postRstarLabel = QLabel(' r*:')
|
|
1013
|
+
self.postRstarLineEdit = QLineEdit('30')
|
|
1014
|
+
self.postPMFTypeLabel = QLabel(' PMF type:')
|
|
1015
|
+
self.postPMFTypeBox = QComboBox()
|
|
1016
|
+
self.postPMFTypeBox.addItem('NAMD')
|
|
1017
|
+
self.postPMFTypeBox.addItem('Gromacs')
|
|
1018
|
+
|
|
1019
|
+
self.postOtherParamsLayout.addWidget(self.postTemperatureLabel)
|
|
1020
|
+
self.postOtherParamsLayout.addWidget(self.postTemperatureLineEdit)
|
|
1021
|
+
self.postOtherParamsLayout.addWidget(self.postRstarLabel)
|
|
1022
|
+
self.postOtherParamsLayout.addWidget(self.postRstarLineEdit)
|
|
1023
|
+
self.postOtherParamsLayout.addWidget(self.postPMFTypeLabel)
|
|
1024
|
+
self.postOtherParamsLayout.addWidget(self.postPMFTypeBox)
|
|
1025
|
+
|
|
1026
|
+
self.postOtherParams.setLayout(self.postOtherParamsLayout)
|
|
1027
|
+
|
|
1028
|
+
self.fcBoundStateLabel = QLabel('Bound state:')
|
|
1029
|
+
|
|
1030
|
+
self.geometricTabLayout.addWidget(self.pmfInputs)
|
|
1031
|
+
self.geometricTabLayout.addWidget(self.forceConstants)
|
|
1032
|
+
self.geometricTabLayout.addWidget(self.postOtherParams)
|
|
1033
|
+
self.geometricTab.setLayout(self.geometricTabLayout)
|
|
1034
|
+
|
|
1035
|
+
def _initAlchemicalTab(self):
|
|
1036
|
+
"""initialize alchemical tab of post-treatment
|
|
1037
|
+
"""
|
|
1038
|
+
|
|
1039
|
+
self.alchemicalTab = QWidget()
|
|
1040
|
+
self.alchemicalTabLayout = QVBoxLayout()
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
self.restraintInputs = QGroupBox('Inputs for alchemical simulations (.fepout/.log):')
|
|
1044
|
+
self.restraintInputsLayout = QVBoxLayout()
|
|
1045
|
+
|
|
1046
|
+
# bound state
|
|
1047
|
+
self.alchemicalBoundStateLabel = QLabel('Atoms/Bound state (.fepout):')
|
|
1048
|
+
self.alchemicalBoundStateLayout = QGridLayout()
|
|
1049
|
+
|
|
1050
|
+
self.alchemicalForwardLabel1 = QLabel('Forward:')
|
|
1051
|
+
self.alchemicalForwardLineEdit1 = QLineEdit()
|
|
1052
|
+
self.alchemicalForwardButton1 = QPushButton('Browse')
|
|
1053
|
+
self.alchemicalBoundStateLayout.addWidget(self.alchemicalForwardLabel1, 0, 0)
|
|
1054
|
+
self.alchemicalBoundStateLayout.addWidget(self.alchemicalForwardLineEdit1, 0, 1)
|
|
1055
|
+
self.alchemicalBoundStateLayout.addWidget(self.alchemicalForwardButton1, 0, 2)
|
|
1056
|
+
|
|
1057
|
+
self.alchemicalBackwardLabel1 = QLabel('Backward:')
|
|
1058
|
+
self.alchemicalBackwardLineEdit1 = QLineEdit()
|
|
1059
|
+
self.alchemicalBackwardButton1 = QPushButton('Browse')
|
|
1060
|
+
self.alchemicalBoundStateLayout.addWidget(self.alchemicalBackwardLabel1, 1, 0)
|
|
1061
|
+
self.alchemicalBoundStateLayout.addWidget(self.alchemicalBackwardLineEdit1, 1, 1)
|
|
1062
|
+
self.alchemicalBoundStateLayout.addWidget(self.alchemicalBackwardButton1, 1, 2)
|
|
1063
|
+
|
|
1064
|
+
self.alchemicalBoundStateLabel2 = QLabel('Restraints/Bound state (.log):')
|
|
1065
|
+
self.alchemicalBoundStateLayout2 = QGridLayout()
|
|
1066
|
+
|
|
1067
|
+
self.alchemicalForwardLabel2 = QLabel('Forward:')
|
|
1068
|
+
self.alchemicalForwardLineEdit2 = QLineEdit()
|
|
1069
|
+
self.alchemicalForwardButton2 = QPushButton('Browse')
|
|
1070
|
+
self.alchemicalBoundStateLayout2.addWidget(self.alchemicalForwardLabel2, 0, 0)
|
|
1071
|
+
self.alchemicalBoundStateLayout2.addWidget(self.alchemicalForwardLineEdit2, 0, 1)
|
|
1072
|
+
self.alchemicalBoundStateLayout2.addWidget(self.alchemicalForwardButton2, 0, 2)
|
|
1073
|
+
|
|
1074
|
+
self.alchemicalBackwardLabel2 = QLabel('Backward:')
|
|
1075
|
+
self.alchemicalBackwardLineEdit2 = QLineEdit()
|
|
1076
|
+
self.alchemicalBackwardButton2 = QPushButton('Browse')
|
|
1077
|
+
self.alchemicalBoundStateLayout2.addWidget(self.alchemicalBackwardLabel2, 1, 0)
|
|
1078
|
+
self.alchemicalBoundStateLayout2.addWidget(self.alchemicalBackwardLineEdit2, 1, 1)
|
|
1079
|
+
self.alchemicalBoundStateLayout2.addWidget(self.alchemicalBackwardButton2, 1, 2)
|
|
1080
|
+
|
|
1081
|
+
# unbound state
|
|
1082
|
+
|
|
1083
|
+
self.alchemicalUnboundStateLabel = QLabel('Atoms/Unbound state (.fepout):')
|
|
1084
|
+
self.alchemicalUnboundStateLayout = QGridLayout()
|
|
1085
|
+
|
|
1086
|
+
self.alchemicalForwardLabel3 = QLabel('Forward:')
|
|
1087
|
+
self.alchemicalForwardLineEdit3 = QLineEdit()
|
|
1088
|
+
self.alchemicalForwardButton3 = QPushButton('Browse')
|
|
1089
|
+
self.alchemicalUnboundStateLayout.addWidget(self.alchemicalForwardLabel3, 0, 0)
|
|
1090
|
+
self.alchemicalUnboundStateLayout.addWidget(self.alchemicalForwardLineEdit3, 0, 1)
|
|
1091
|
+
self.alchemicalUnboundStateLayout.addWidget(self.alchemicalForwardButton3, 0, 2)
|
|
1092
|
+
|
|
1093
|
+
self.alchemicalBackwardLabel3 = QLabel('Backward:')
|
|
1094
|
+
self.alchemicalBackwardLineEdit3 = QLineEdit()
|
|
1095
|
+
self.alchemicalBackwardButton3 = QPushButton('Browse')
|
|
1096
|
+
self.alchemicalUnboundStateLayout.addWidget(self.alchemicalBackwardLabel3, 1, 0)
|
|
1097
|
+
self.alchemicalUnboundStateLayout.addWidget(self.alchemicalBackwardLineEdit3, 1, 1)
|
|
1098
|
+
self.alchemicalUnboundStateLayout.addWidget(self.alchemicalBackwardButton3, 1, 2)
|
|
1099
|
+
|
|
1100
|
+
self.alchemicalUnboundStateLabel2 = QLabel('Restraints/Unbound state (.log):')
|
|
1101
|
+
self.alchemicalUnboundStateLayout2 = QGridLayout()
|
|
1102
|
+
|
|
1103
|
+
self.alchemicalForwardLabel4 = QLabel('Forward:')
|
|
1104
|
+
self.alchemicalForwardLineEdit4 = QLineEdit()
|
|
1105
|
+
self.alchemicalForwardButton4 = QPushButton('Browse')
|
|
1106
|
+
self.alchemicalUnboundStateLayout2.addWidget(self.alchemicalForwardLabel4, 0, 0)
|
|
1107
|
+
self.alchemicalUnboundStateLayout2.addWidget(self.alchemicalForwardLineEdit4, 0, 1)
|
|
1108
|
+
self.alchemicalUnboundStateLayout2.addWidget(self.alchemicalForwardButton4, 0, 2)
|
|
1109
|
+
|
|
1110
|
+
self.alchemicalBackwardLabel4 = QLabel('Backward:')
|
|
1111
|
+
self.alchemicalBackwardLineEdit4 = QLineEdit()
|
|
1112
|
+
self.alchemicalBackwardButton4 = QPushButton('Browse')
|
|
1113
|
+
self.alchemicalUnboundStateLayout2.addWidget(self.alchemicalBackwardLabel4, 1, 0)
|
|
1114
|
+
self.alchemicalUnboundStateLayout2.addWidget(self.alchemicalBackwardLineEdit4, 1, 1)
|
|
1115
|
+
self.alchemicalUnboundStateLayout2.addWidget(self.alchemicalBackwardButton4, 1, 2)
|
|
1116
|
+
|
|
1117
|
+
self.restraintInputsLayout.addWidget(self.alchemicalBoundStateLabel)
|
|
1118
|
+
self.restraintInputsLayout.addLayout(self.alchemicalBoundStateLayout)
|
|
1119
|
+
self.restraintInputsLayout.addWidget(self.alchemicalBoundStateLabel2)
|
|
1120
|
+
self.restraintInputsLayout.addLayout(self.alchemicalBoundStateLayout2)
|
|
1121
|
+
self.restraintInputsLayout.addWidget(self.alchemicalUnboundStateLabel)
|
|
1122
|
+
self.restraintInputsLayout.addLayout(self.alchemicalUnboundStateLayout)
|
|
1123
|
+
self.restraintInputsLayout.addWidget(self.alchemicalUnboundStateLabel2)
|
|
1124
|
+
self.restraintInputsLayout.addLayout(self.alchemicalUnboundStateLayout2)
|
|
1125
|
+
self.restraintInputs.setLayout(self.restraintInputsLayout)
|
|
1126
|
+
|
|
1127
|
+
# alchemical force constants
|
|
1128
|
+
self.alchemicalForceConstants = QGroupBox('Force constants (in Colvars unit):')
|
|
1129
|
+
|
|
1130
|
+
# all widgets
|
|
1131
|
+
self.alchemicalFCLayout = QHBoxLayout()
|
|
1132
|
+
self.alchemicalfcThetaLabel = QLabel('Theta:')
|
|
1133
|
+
self.alchemicalfcThetaLineEdit = QLineEdit('0.1')
|
|
1134
|
+
self.alchemicalfcPhiLabel = QLabel(' Phi: ')
|
|
1135
|
+
self.alchemicalfcPhiLineEdit = QLineEdit('0.1')
|
|
1136
|
+
self.alchemicalfcPsiLabel = QLabel('Psi: ')
|
|
1137
|
+
self.alchemicalfcPsiLineEdit = QLineEdit('0.1')
|
|
1138
|
+
self.alchemicalfcthetaLabel = QLabel('theta:')
|
|
1139
|
+
self.alchemicalfcthetaLineEdit = QLineEdit('0.1')
|
|
1140
|
+
self.alchemicalfcphiLabel = QLabel(' phi: ')
|
|
1141
|
+
self.alchemicalfcphiLineEdit = QLineEdit('0.1')
|
|
1142
|
+
self.alchemicalfcRLabel = QLabel('r: ')
|
|
1143
|
+
self.alchemicalfcRLineEdit = QLineEdit('10')
|
|
1144
|
+
|
|
1145
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcThetaLabel)
|
|
1146
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcThetaLineEdit)
|
|
1147
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcPhiLabel)
|
|
1148
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcPhiLineEdit)
|
|
1149
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcPsiLabel)
|
|
1150
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcPsiLineEdit)
|
|
1151
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcthetaLabel)
|
|
1152
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcthetaLineEdit)
|
|
1153
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcphiLabel)
|
|
1154
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcphiLineEdit)
|
|
1155
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcRLabel)
|
|
1156
|
+
self.alchemicalFCLayout.addWidget(self.alchemicalfcRLineEdit)
|
|
1157
|
+
|
|
1158
|
+
self.alchemicalForceConstants.setLayout(self.alchemicalFCLayout)
|
|
1159
|
+
|
|
1160
|
+
# alchemical restraint centers
|
|
1161
|
+
self.alchemicalRestraintCenters = QGroupBox('Restraint centers (in Colvars unit), temperature and others:')
|
|
1162
|
+
|
|
1163
|
+
# all widgets
|
|
1164
|
+
self.alchemicalRCLayout = QHBoxLayout()
|
|
1165
|
+
self.alchemicalRCThetaLabel = QLabel('Theta:')
|
|
1166
|
+
self.alchemicalRCThetaLineEdit = QLineEdit('0')
|
|
1167
|
+
self.alchemicalRCthetaLabel = QLabel('theta:')
|
|
1168
|
+
self.alchemicalRCthetaLineEdit = QLineEdit('90')
|
|
1169
|
+
self.alchemicalRCRLabel = QLabel('r: ')
|
|
1170
|
+
self.alchemicalRCRLineEdit = QLineEdit('8')
|
|
1171
|
+
self.alchemicalPostTemperatureLabel = QLabel('temperature:')
|
|
1172
|
+
self.alchemicalPostTemperatureLineEdit = QLineEdit('300')
|
|
1173
|
+
self.alchemicalPostTypeLabel = QLabel('Post-treatment type:')
|
|
1174
|
+
self.alchemicalPostTypeBox = QComboBox()
|
|
1175
|
+
self.alchemicalPostTypeBox.addItem('FEP')
|
|
1176
|
+
self.alchemicalPostTypeBox.addItem('BAR')
|
|
1177
|
+
|
|
1178
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalRCThetaLabel)
|
|
1179
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalRCThetaLineEdit)
|
|
1180
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalRCthetaLabel)
|
|
1181
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalRCthetaLineEdit)
|
|
1182
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalRCRLabel)
|
|
1183
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalRCRLineEdit)
|
|
1184
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalPostTemperatureLabel)
|
|
1185
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalPostTemperatureLineEdit)
|
|
1186
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalPostTypeLabel)
|
|
1187
|
+
self.alchemicalRCLayout.addWidget(self.alchemicalPostTypeBox)
|
|
1188
|
+
|
|
1189
|
+
self.alchemicalRestraintCenters.setLayout(self.alchemicalRCLayout)
|
|
1190
|
+
|
|
1191
|
+
self.alchemicalTabLayout.addWidget(self.restraintInputs)
|
|
1192
|
+
self.alchemicalTabLayout.addWidget(self.alchemicalForceConstants)
|
|
1193
|
+
self.alchemicalTabLayout.addWidget(self.alchemicalRestraintCenters)
|
|
1194
|
+
self.alchemicalTab.setLayout(self.alchemicalTabLayout)
|
|
1195
|
+
|
|
1196
|
+
def _initQuickPlotTab(self):
|
|
1197
|
+
"""initialize quick-plot tab
|
|
1198
|
+
"""
|
|
1199
|
+
|
|
1200
|
+
self.quickPlot = QWidget()
|
|
1201
|
+
self.quickPlotLayout = QVBoxLayout()
|
|
1202
|
+
|
|
1203
|
+
# plot a (stratified) pmf
|
|
1204
|
+
self.plotPmf = QGroupBox('Plot (stratified) PMFs:')
|
|
1205
|
+
self.plotPmfLayout = QVBoxLayout()
|
|
1206
|
+
|
|
1207
|
+
self.plotPmfLabel = QLabel('PMF files:')
|
|
1208
|
+
self.plotPmfBox = QListWidget()
|
|
1209
|
+
self.plotPmfChildLayout = QHBoxLayout()
|
|
1210
|
+
self.plotPmfAddButton = QPushButton('Add')
|
|
1211
|
+
self.plotPmfClearButton = QPushButton('Clear')
|
|
1212
|
+
self.plotPmfPlotButton = QPushButton('Plot')
|
|
1213
|
+
self.plotPmfChildLayout.addWidget(self.plotPmfAddButton)
|
|
1214
|
+
self.plotPmfChildLayout.addWidget(self.plotPmfClearButton)
|
|
1215
|
+
self.plotPmfChildLayout.addWidget(self.plotPmfPlotButton)
|
|
1216
|
+
|
|
1217
|
+
self.plotPmfLayout.addWidget(self.plotPmfLabel)
|
|
1218
|
+
self.plotPmfLayout.addWidget(self.plotPmfBox)
|
|
1219
|
+
self.plotPmfLayout.addLayout(self.plotPmfChildLayout)
|
|
1220
|
+
self.plotPmf.setLayout(self.plotPmfLayout)
|
|
1221
|
+
|
|
1222
|
+
# calculate pmf RMSD convergence
|
|
1223
|
+
self.plotPmfConvergence = QGroupBox('Calculate PMF RMSD convergence:')
|
|
1224
|
+
self.plotPmfConvergenceLayout = QVBoxLayout()
|
|
1225
|
+
|
|
1226
|
+
self.plotPmfConvergenceLabel = QLabel('history file:')
|
|
1227
|
+
self.plotPmfConvergenceBox = QLineEdit()
|
|
1228
|
+
self.plotPmfConvergenceChildLayout = QHBoxLayout()
|
|
1229
|
+
self.plotPmfConvergenceBrowseButton = QPushButton('Browse')
|
|
1230
|
+
self.plotPmfConvergencePlotButton = QPushButton('Plot')
|
|
1231
|
+
self.plotPmfConvergenceChildLayout.addWidget(self.plotPmfConvergenceBrowseButton)
|
|
1232
|
+
self.plotPmfConvergenceChildLayout.addWidget(self.plotPmfConvergencePlotButton)
|
|
1233
|
+
|
|
1234
|
+
self.plotPmfConvergenceLayout.addWidget(self.plotPmfConvergenceLabel)
|
|
1235
|
+
self.plotPmfConvergenceLayout.addWidget(self.plotPmfConvergenceBox)
|
|
1236
|
+
self.plotPmfConvergenceLayout.addLayout(self.plotPmfConvergenceChildLayout)
|
|
1237
|
+
self.plotPmfConvergence.setLayout(self.plotPmfConvergenceLayout)
|
|
1238
|
+
|
|
1239
|
+
# merge a (stratified) pmf
|
|
1240
|
+
self.mergePmf = QGroupBox('Merge (stratified) PMFs:')
|
|
1241
|
+
self.mergePmfLayout = QVBoxLayout()
|
|
1242
|
+
|
|
1243
|
+
self.mergePmfLabel = QLabel('PMF files:')
|
|
1244
|
+
self.mergePmfBox = QListWidget()
|
|
1245
|
+
self.mergePmfChildLayout = QHBoxLayout()
|
|
1246
|
+
self.mergePmfAddButton = QPushButton('Add')
|
|
1247
|
+
self.mergePmfClearButton = QPushButton('Clear')
|
|
1248
|
+
self.mergePmfmergeButton = QPushButton('Merge')
|
|
1249
|
+
self.mergePmfChildLayout.addWidget(self.mergePmfAddButton)
|
|
1250
|
+
self.mergePmfChildLayout.addWidget(self.mergePmfClearButton)
|
|
1251
|
+
self.mergePmfChildLayout.addWidget(self.mergePmfmergeButton)
|
|
1252
|
+
|
|
1253
|
+
self.mergePmfLayout.addWidget(self.mergePmfLabel)
|
|
1254
|
+
self.mergePmfLayout.addWidget(self.mergePmfBox)
|
|
1255
|
+
self.mergePmfLayout.addLayout(self.mergePmfChildLayout)
|
|
1256
|
+
self.mergePmf.setLayout(self.mergePmfLayout)
|
|
1257
|
+
|
|
1258
|
+
# plot hysteresis between forward and backward simulations
|
|
1259
|
+
self.plotHysteresis = QGroupBox('Plot hysteresis between bidirectional simulations:')
|
|
1260
|
+
self.plotHysteresisLayout = QVBoxLayout()
|
|
1261
|
+
|
|
1262
|
+
self.plotHysteresisForwardLayout = QHBoxLayout()
|
|
1263
|
+
self.plotHysteresisForwardLabel = QLabel('Forward (fepout/log): ')
|
|
1264
|
+
self.plotHysteresisForwardLineEdit = QLineEdit()
|
|
1265
|
+
self.plotHysteresisForwardButton = QPushButton('Browse')
|
|
1266
|
+
self.plotHysteresisForwardLayout.addWidget(self.plotHysteresisForwardLabel)
|
|
1267
|
+
self.plotHysteresisForwardLayout.addWidget(self.plotHysteresisForwardLineEdit)
|
|
1268
|
+
self.plotHysteresisForwardLayout.addWidget(self.plotHysteresisForwardButton)
|
|
1269
|
+
|
|
1270
|
+
self.plotHysteresisBackwardLayout = QHBoxLayout()
|
|
1271
|
+
self.plotHysteresisBackwardLabel = QLabel('Backward (fepout/log):')
|
|
1272
|
+
self.plotHysteresisBackwardLineEdit = QLineEdit()
|
|
1273
|
+
self.plotHysteresisBackwardButton = QPushButton('Browse')
|
|
1274
|
+
self.plotHysteresisBackwardLayout.addWidget(self.plotHysteresisBackwardLabel)
|
|
1275
|
+
self.plotHysteresisBackwardLayout.addWidget(self.plotHysteresisBackwardLineEdit)
|
|
1276
|
+
self.plotHysteresisBackwardLayout.addWidget(self.plotHysteresisBackwardButton)
|
|
1277
|
+
|
|
1278
|
+
self.plotHysteresisPlotButton = QPushButton('Plot')
|
|
1279
|
+
|
|
1280
|
+
self.plotHysteresisLayout.addLayout(self.plotHysteresisForwardLayout)
|
|
1281
|
+
self.plotHysteresisLayout.addLayout(self.plotHysteresisBackwardLayout)
|
|
1282
|
+
self.plotHysteresisLayout.addWidget(self.plotHysteresisPlotButton)
|
|
1283
|
+
|
|
1284
|
+
self.plotHysteresis.setLayout(self.plotHysteresisLayout)
|
|
1285
|
+
|
|
1286
|
+
self.quickPlotLayout.addWidget(self.plotPmf)
|
|
1287
|
+
self.quickPlotLayout.addWidget(self.mergePmf)
|
|
1288
|
+
self.quickPlotLayout.addWidget(self.plotPmfConvergence)
|
|
1289
|
+
self.quickPlotLayout.addWidget(self.plotHysteresis)
|
|
1290
|
+
self.quickPlot.setLayout(self.quickPlotLayout)
|
|
1291
|
+
|
|
1292
|
+
# slots are defined below
|
|
1293
|
+
# otherwise they are defined in slots.py
|
|
1294
|
+
def _mainSettings(self):
|
|
1295
|
+
"""call main settings
|
|
1296
|
+
"""
|
|
1297
|
+
def f():
|
|
1298
|
+
self.mainSettings.show()
|
|
1299
|
+
return f
|
|
1300
|
+
|
|
1301
|
+
def _advancedSettings(self, comboBox):
|
|
1302
|
+
"""call advanced settings in pre-treatment
|
|
1303
|
+
the returned function is depended on the comboBox(strategy type)
|
|
1304
|
+
"""
|
|
1305
|
+
|
|
1306
|
+
def f():
|
|
1307
|
+
if comboBox.currentText() == 'Geometric':
|
|
1308
|
+
self.geometricAdvancedSettings.show()
|
|
1309
|
+
elif comboBox.currentText() == 'Alchemical':
|
|
1310
|
+
self.alchemicalAdvancedSettings.show()
|
|
1311
|
+
|
|
1312
|
+
return f
|
|
1313
|
+
|
|
1314
|
+
def _changeFFButtonState(self):
|
|
1315
|
+
"""enable/disable the add and clear button of force field section
|
|
1316
|
+
"""
|
|
1317
|
+
|
|
1318
|
+
if self.forceFieldCombobox.currentText() == 'CHARMM':
|
|
1319
|
+
self.forceFieldAddButton.setEnabled(True)
|
|
1320
|
+
self.forceFieldClearButton.setEnabled(True)
|
|
1321
|
+
self.forceFieldFilesBox.setEnabled(True)
|
|
1322
|
+
elif self.forceFieldCombobox.currentText() == 'Amber':
|
|
1323
|
+
self.forceFieldAddButton.setEnabled(False)
|
|
1324
|
+
self.forceFieldClearButton.setEnabled(False)
|
|
1325
|
+
self.forceFieldFilesBox.setEnabled(False)
|
|
1326
|
+
|
|
1327
|
+
def _changeStrategySettingState(self):
|
|
1328
|
+
"""enable/disable the alchemical route and some advanced settings based on the MD engine
|
|
1329
|
+
"""
|
|
1330
|
+
|
|
1331
|
+
if self.selectMDEngineCombobox.currentText() == 'NAMD':
|
|
1332
|
+
self.selectStrategyCombobox.setEnabled(True)
|
|
1333
|
+
self.geometricAdvancedSettings.useOldCvCheckbox.setEnabled(True)
|
|
1334
|
+
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.setEnabled(True)
|
|
1335
|
+
self.geometricAdvancedSettings.useGaWTMCheckbox.setEnabled(True)
|
|
1336
|
+
|
|
1337
|
+
elif self.selectMDEngineCombobox.currentText() == 'Gromacs':
|
|
1338
|
+
index = self.selectStrategyCombobox.findText('Geometric', QtCore.Qt.MatchFixedString)
|
|
1339
|
+
if index >= 0:
|
|
1340
|
+
self.selectStrategyCombobox.setCurrentIndex(index)
|
|
1341
|
+
self.selectStrategyCombobox.setEnabled(False)
|
|
1342
|
+
|
|
1343
|
+
self.geometricAdvancedSettings.useOldCvCheckbox.setChecked(False)
|
|
1344
|
+
self.geometricAdvancedSettings.useOldCvCheckbox.setEnabled(False)
|
|
1345
|
+
|
|
1346
|
+
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.setChecked(False)
|
|
1347
|
+
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.setEnabled(False)
|
|
1348
|
+
|
|
1349
|
+
self.geometricAdvancedSettings.useGaWTMCheckbox.setEnabled(False)
|
|
1350
|
+
self.geometricAdvancedSettings.useGaWTMCheckbox.setChecked(False)
|
|
1351
|
+
|
|
1352
|
+
def _changeStrategySettingStateForOldGromacs(self):
|
|
1353
|
+
"""enable/disable a lot of options for the old Gromacs tab
|
|
1354
|
+
"""
|
|
1355
|
+
|
|
1356
|
+
if self.preTreatmentMainTabs.currentWidget() == self.NAMDTab:
|
|
1357
|
+
self.selectStrategyAdvancedButton.setEnabled(True)
|
|
1358
|
+
self.selectMDEngineCombobox.setEnabled(True)
|
|
1359
|
+
|
|
1360
|
+
elif self.preTreatmentMainTabs.currentWidget() == self.GromacsTab:
|
|
1361
|
+
index = self.selectMDEngineCombobox.findText('Gromacs', QtCore.Qt.MatchFixedString)
|
|
1362
|
+
if index >= 0:
|
|
1363
|
+
self.selectMDEngineCombobox.setCurrentIndex(index)
|
|
1364
|
+
|
|
1365
|
+
index = self.selectStrategyCombobox.findText('Geometric', QtCore.Qt.MatchFixedString)
|
|
1366
|
+
if index >= 0:
|
|
1367
|
+
self.selectStrategyCombobox.setCurrentIndex(index)
|
|
1368
|
+
|
|
1369
|
+
self.selectMDEngineCombobox.setEnabled(False)
|
|
1370
|
+
self.selectStrategyCombobox.setEnabled(False)
|
|
1371
|
+
self.selectStrategyAdvancedButton.setEnabled(False)
|
|
1372
|
+
|
|
1373
|
+
def _openDocFile(self):
|
|
1374
|
+
"""open Documentation file
|
|
1375
|
+
"""
|
|
1376
|
+
|
|
1377
|
+
webbrowser.open('https://www.nature.com/articles/s41596-021-00676-1')
|
|
1378
|
+
|
|
1379
|
+
def _openPythonAPIFile(self):
|
|
1380
|
+
"""open Python API Documentation file
|
|
1381
|
+
"""
|
|
1382
|
+
|
|
1383
|
+
webbrowser.open('https://fhh2626.github.io/BFEE2APIDocs/')
|
|
1384
|
+
|
|
1385
|
+
def _showAboutBox(self):
|
|
1386
|
+
"""the about message box
|
|
1387
|
+
|
|
1388
|
+
Returns:
|
|
1389
|
+
function obj: a slot function that shows that about message box
|
|
1390
|
+
"""
|
|
1391
|
+
|
|
1392
|
+
def f():
|
|
1393
|
+
QMessageBox.about(
|
|
1394
|
+
self,
|
|
1395
|
+
'About',
|
|
1396
|
+
f'<center><b>{__PROGRAM_NAME__}</b></center><br>'+r'''
|
|
1397
|
+
Binding free energy estimator (BFEE) is a python-based software
|
|
1398
|
+
that automates absolute binding free energy calculations through
|
|
1399
|
+
either the alchemical or geometric route by molecular dynamics
|
|
1400
|
+
simulations.<br>
|
|
1401
|
+
<b>Authors:</b><br>
|
|
1402
|
+
Haohao Fu (<a href="mailto:fhh2626@gmail.com">fhh2626@gmail.com</a>)<br>
|
|
1403
|
+
Haochuan Chen (<a href="mailto:summersnow9403@gmail.com">summersnow9403@gmail.com</a>)<br>
|
|
1404
|
+
<b>License:</b><br>
|
|
1405
|
+
BFEE2 is free software: you can redistribute it and/or modify it
|
|
1406
|
+
under the terms of the GNU General Public License as published by
|
|
1407
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
1408
|
+
(at your option) any later version.<br>
|
|
1409
|
+
<b>Reference:</b><br>
|
|
1410
|
+
<b>BFEE2:</b> Fu et al. Nat. Protoc. 2022, 17, 1114-1141 and Fu et al. J. Chem. Inf. Model. 2021, 61, 2116–2123<br>
|
|
1411
|
+
<b>Alchemical and geometric routes:</b> Gumbart et al. J. Chem. Theory Comput. 2013, 9, 794–802<br>
|
|
1412
|
+
<b>WTM-eABF:</b> Fu et al. Acc. Chem. Res. 2019, 52, 3254–3264 and Fu et al. J. Phys. Chem. Lett. 2018, 9, 4738–4745<br>
|
|
1413
|
+
<b>Collective variables:</b> Fu et al. J. Chem. Theory Comput. 2017, 13, 5173–5178<br>
|
|
1414
|
+
<b>Streamlined geometric route:</b> Fu et al. J. Chem. Inf. Model. 2023, 63, 2512–2519<br>
|
|
1415
|
+
''')
|
|
1416
|
+
return f
|
|
1417
|
+
|
|
1418
|
+
def _showGeometricResults(self, unit):
|
|
1419
|
+
''' calculate binding from the geometric route,
|
|
1420
|
+
parameters in the Geometric tab will be read.
|
|
1421
|
+
Show a QMessageBox for the result
|
|
1422
|
+
Inputs:
|
|
1423
|
+
unit (string): 'namd' or 'gromacs' '''
|
|
1424
|
+
|
|
1425
|
+
pTreat = postTreatment.postTreatment(
|
|
1426
|
+
float(self.postTemperatureLineEdit.text()), unit, 'geometric')
|
|
1427
|
+
|
|
1428
|
+
pmfs = [
|
|
1429
|
+
self.rmsdBoundLineEdit.text(),
|
|
1430
|
+
self.ThetaLineEdit.text(),
|
|
1431
|
+
self.PhiLineEdit.text(),
|
|
1432
|
+
self.PsiLineEdit.text(),
|
|
1433
|
+
self.thetaLineEdit.text(),
|
|
1434
|
+
self.phiLineEdit.text(),
|
|
1435
|
+
self.rLineEdit.text(),
|
|
1436
|
+
self.rmsdUnboundLineEdit.text()
|
|
1437
|
+
]
|
|
1438
|
+
|
|
1439
|
+
try:
|
|
1440
|
+
parameters = [
|
|
1441
|
+
float(self.fcRMSDLineEdit.text()),
|
|
1442
|
+
float(self.fcThetaLineEdit.text()),
|
|
1443
|
+
float(self.fcPhiLineEdit.text()),
|
|
1444
|
+
float(self.fcPsiLineEdit.text()),
|
|
1445
|
+
float(self.fcthetaLineEdit.text()),
|
|
1446
|
+
float(self.fcphiLineEdit.text()),
|
|
1447
|
+
float(self.postRstarLineEdit.text()),
|
|
1448
|
+
float(self.fcRMSDLineEdit.text())
|
|
1449
|
+
]
|
|
1450
|
+
except:
|
|
1451
|
+
QMessageBox.warning(self, 'Error', f'Force constant or r* input error!')
|
|
1452
|
+
return
|
|
1453
|
+
|
|
1454
|
+
# check inputs
|
|
1455
|
+
for index, item in enumerate(pmfs):
|
|
1456
|
+
if (index != 0) and (index != 7) and (not os.path.exists(item)):
|
|
1457
|
+
QMessageBox.warning(self, 'Error', f'file {item} does not exist!')
|
|
1458
|
+
return
|
|
1459
|
+
if (index == 7) and (not os.path.exists(item)):
|
|
1460
|
+
QMessageBox.warning(self, 'Warning', f'Supposing dealing with a rigid ligand!')
|
|
1461
|
+
|
|
1462
|
+
# calculate free energies
|
|
1463
|
+
try:
|
|
1464
|
+
result = pTreat.geometricBindingFreeEnergy(pmfs, parameters)
|
|
1465
|
+
except postTreatment.RStarTooLargeError:
|
|
1466
|
+
QMessageBox.warning(
|
|
1467
|
+
self,
|
|
1468
|
+
'Error',
|
|
1469
|
+
f'\
|
|
1470
|
+
r_star cannot be larger than r_max of step 7!\n'
|
|
1471
|
+
)
|
|
1472
|
+
return
|
|
1473
|
+
except Exception as e:
|
|
1474
|
+
print(e)
|
|
1475
|
+
QMessageBox.warning(
|
|
1476
|
+
self,
|
|
1477
|
+
'Error',
|
|
1478
|
+
f'\
|
|
1479
|
+
Unknown error! The error message is: \n\
|
|
1480
|
+
{e}\n'
|
|
1481
|
+
)
|
|
1482
|
+
return
|
|
1483
|
+
|
|
1484
|
+
QMessageBox.about(
|
|
1485
|
+
self,
|
|
1486
|
+
'Result',
|
|
1487
|
+
f'\
|
|
1488
|
+
Results:\n\
|
|
1489
|
+
ΔG(site,c) = {result[0]:.2f} kcal/mol\n\
|
|
1490
|
+
ΔG(site,eulerTheta) = {result[1]:.2f} kcal/mol\n\
|
|
1491
|
+
ΔG(site,eulerPhi) = {result[2]:.2f} kcal/mol\n\
|
|
1492
|
+
ΔG(site,eulerPsi) = {result[3]:.2f} kcal/mol\n\
|
|
1493
|
+
ΔG(site,polarTheta) = {result[4]:.2f} kcal/mol\n\
|
|
1494
|
+
ΔG(site,polarPhi) = {result[5]:.2f} kcal/mol\n\
|
|
1495
|
+
(1/beta)*ln(S*I*C0) = {result[6]:.2f} kcal/mol\n\
|
|
1496
|
+
ΔG(bulk,c) = {result[7]:.2f} kcal/mol\n\
|
|
1497
|
+
ΔG(bulk,o) = {result[8]:.2f} kcal/mol\n\
|
|
1498
|
+
\n\
|
|
1499
|
+
Standard Binding Free Energy:\n\
|
|
1500
|
+
ΔG(total) = {result[9]:.2f} kcal/mol\n'
|
|
1501
|
+
)
|
|
1502
|
+
|
|
1503
|
+
def _showAlchemicalResults(self, unit):
|
|
1504
|
+
"""calculate binding from the alchemical route,
|
|
1505
|
+
parameters in the alchemical tab will be read.
|
|
1506
|
+
Show a QMessageBox for the result
|
|
1507
|
+
|
|
1508
|
+
Args:
|
|
1509
|
+
unit (str): 'namd' or 'gromacs'
|
|
1510
|
+
"""
|
|
1511
|
+
|
|
1512
|
+
pTreat = postTreatment.postTreatment(
|
|
1513
|
+
float(self.alchemicalPostTemperatureLineEdit.text()), unit, 'alchemical')
|
|
1514
|
+
|
|
1515
|
+
# alchemical outputs
|
|
1516
|
+
files = [
|
|
1517
|
+
self.alchemicalForwardLineEdit1.text(),
|
|
1518
|
+
self.alchemicalBackwardLineEdit1.text(),
|
|
1519
|
+
self.alchemicalForwardLineEdit2.text(),
|
|
1520
|
+
self.alchemicalBackwardLineEdit2.text(),
|
|
1521
|
+
self.alchemicalForwardLineEdit3.text(),
|
|
1522
|
+
self.alchemicalBackwardLineEdit3.text(),
|
|
1523
|
+
self.alchemicalForwardLineEdit4.text(),
|
|
1524
|
+
self.alchemicalBackwardLineEdit4.text()
|
|
1525
|
+
]
|
|
1526
|
+
|
|
1527
|
+
try:
|
|
1528
|
+
parameters = [
|
|
1529
|
+
float(self.alchemicalRCThetaLineEdit.text()),
|
|
1530
|
+
float(self.alchemicalRCthetaLineEdit.text()),
|
|
1531
|
+
float(self.alchemicalRCRLineEdit.text()),
|
|
1532
|
+
float(self.alchemicalfcThetaLineEdit.text()),
|
|
1533
|
+
float(self.alchemicalfcPhiLineEdit.text()),
|
|
1534
|
+
float(self.alchemicalfcPsiLineEdit.text()),
|
|
1535
|
+
float(self.alchemicalfcthetaLineEdit.text()),
|
|
1536
|
+
float(self.alchemicalfcphiLineEdit.text()),
|
|
1537
|
+
float(self.alchemicalfcRLineEdit.text())
|
|
1538
|
+
]
|
|
1539
|
+
temperature = float(self.alchemicalPostTemperatureLineEdit.text())
|
|
1540
|
+
except:
|
|
1541
|
+
QMessageBox.warning(self, 'Error', f'Force constant or restraint center or temperature input error!')
|
|
1542
|
+
return
|
|
1543
|
+
if self.alchemicalPostTypeBox.currentText() == 'FEP':
|
|
1544
|
+
jobType = 'fep'
|
|
1545
|
+
elif self.alchemicalPostTypeBox.currentText() == 'BAR':
|
|
1546
|
+
jobType = 'bar'
|
|
1547
|
+
|
|
1548
|
+
# check inputs
|
|
1549
|
+
rigid_ligand = False
|
|
1550
|
+
for index, item in enumerate([
|
|
1551
|
+
self.alchemicalBackwardLineEdit1.text(),
|
|
1552
|
+
self.alchemicalBackwardLineEdit2.text(),
|
|
1553
|
+
self.alchemicalBackwardLineEdit3.text(),
|
|
1554
|
+
self.alchemicalBackwardLineEdit4.text()
|
|
1555
|
+
]):
|
|
1556
|
+
if (not os.path.exists(item)) and (index != 3):
|
|
1557
|
+
QMessageBox.warning(self, 'Error', f'backward file {item} does not exist and is not empty!')
|
|
1558
|
+
return
|
|
1559
|
+
|
|
1560
|
+
for index, item in enumerate([
|
|
1561
|
+
self.alchemicalForwardLineEdit1.text(),
|
|
1562
|
+
self.alchemicalForwardLineEdit2.text(),
|
|
1563
|
+
self.alchemicalForwardLineEdit3.text(),
|
|
1564
|
+
self.alchemicalForwardLineEdit4.text(),
|
|
1565
|
+
]):
|
|
1566
|
+
if (not os.path.exists(item)) and (index != 3):
|
|
1567
|
+
QMessageBox.warning(self, 'Error', f'file {item} does not exist!')
|
|
1568
|
+
return
|
|
1569
|
+
elif (not os.path.exists(item)) and (index == 3):
|
|
1570
|
+
QMessageBox.warning(self, 'Warning', f'Supposing dealing with a rigid ligand!')
|
|
1571
|
+
rigid_ligand = True
|
|
1572
|
+
|
|
1573
|
+
# calculate free energies
|
|
1574
|
+
result, errors = pTreat.alchemicalBindingFreeEnergy(files, parameters, temperature, jobType, rigid_ligand)
|
|
1575
|
+
|
|
1576
|
+
QMessageBox.about(
|
|
1577
|
+
self,
|
|
1578
|
+
'Result',
|
|
1579
|
+
f'\
|
|
1580
|
+
Results:\n\
|
|
1581
|
+
ΔG(site,couple) = {result[0]:.2f} ± {errors[0]:.2f} kcal/mol\n\
|
|
1582
|
+
ΔG(site,c+o+a+r) = {result[1]:.2f} ± {errors[1]:.2f} kcal/mol\n\
|
|
1583
|
+
ΔG(bulk,decouple) = {result[2]:.2f} ± {errors[2]:.2f} kcal/mol\n\
|
|
1584
|
+
ΔG(bulk,c) = {result[3]:.2f} ± {errors[3]:.2f} kcal/mol\n\
|
|
1585
|
+
ΔG(bulk,o+a+r) = {result[4]:.2f} kcal/mol\n\
|
|
1586
|
+
\n\
|
|
1587
|
+
Standard Binding Free Energy:\n\
|
|
1588
|
+
ΔG(total) = {result[5]:.2f} ± {errors[5]:.2f} kcal/mol\n'
|
|
1589
|
+
)
|
|
1590
|
+
|
|
1591
|
+
def _showFinalResults(self):
|
|
1592
|
+
"""calculate binding free energy and show the final results
|
|
1593
|
+
|
|
1594
|
+
Returns:
|
|
1595
|
+
function obj: a slot function that calculates binding free energy and show the final results
|
|
1596
|
+
"""
|
|
1597
|
+
|
|
1598
|
+
def f():
|
|
1599
|
+
if self.postPMFTypeBox.currentText() == 'NAMD':
|
|
1600
|
+
unit = 'namd'
|
|
1601
|
+
elif self.postPMFTypeBox.currentText() == 'Gromacs':
|
|
1602
|
+
unit = 'gromacs'
|
|
1603
|
+
|
|
1604
|
+
if self.postTreatmentMainTabs.currentIndex() == 0:
|
|
1605
|
+
jobType = 'geometric'
|
|
1606
|
+
elif self.postTreatmentMainTabs.currentIndex() == 1:
|
|
1607
|
+
jobType = 'alchemical'
|
|
1608
|
+
|
|
1609
|
+
if jobType == 'geometric':
|
|
1610
|
+
self._showGeometricResults(unit)
|
|
1611
|
+
elif jobType == 'alchemical':
|
|
1612
|
+
self._showAlchemicalResults(unit)
|
|
1613
|
+
|
|
1614
|
+
return f
|
|
1615
|
+
|
|
1616
|
+
def _generateInputFiles(self):
|
|
1617
|
+
"""generate input files for binding free energy simulation
|
|
1618
|
+
|
|
1619
|
+
Returens:
|
|
1620
|
+
function obj: a slot function that generates input files for binding free energy simulation
|
|
1621
|
+
"""
|
|
1622
|
+
|
|
1623
|
+
def f():
|
|
1624
|
+
path = QFileDialog.getExistingDirectory(None, 'Select a directory')
|
|
1625
|
+
# cancel
|
|
1626
|
+
if path == '':
|
|
1627
|
+
return
|
|
1628
|
+
|
|
1629
|
+
iGenerator = inputGenerator.inputGenerator()
|
|
1630
|
+
|
|
1631
|
+
# third-party softwares and user-provided solvation boxes
|
|
1632
|
+
for item in [
|
|
1633
|
+
self.mainSettings.vmdLineEdit.text(),
|
|
1634
|
+
#self.mainSettings.gromacsLineEdit.text(),
|
|
1635
|
+
#self.mainSettings.tleapLineEdit.text(),
|
|
1636
|
+
self.geometricAdvancedSettings.nonStandardSolventPdbLineEdit.text(),
|
|
1637
|
+
self.geometricAdvancedSettings.nonStandardSolventPsfLineEdit.text()
|
|
1638
|
+
]:
|
|
1639
|
+
if ((not os.path.exists(item)) and item != ''):
|
|
1640
|
+
QMessageBox.warning(self, 'Error', f'file {item} does not exist!')
|
|
1641
|
+
return
|
|
1642
|
+
|
|
1643
|
+
if self.preTreatmentMainTabs.currentIndex() == 0:
|
|
1644
|
+
# force fields
|
|
1645
|
+
forceFieldFiles = [self.forceFieldFilesBox.item(i).text() for i in range(self.forceFieldFilesBox.count())]
|
|
1646
|
+
|
|
1647
|
+
# NAMD files
|
|
1648
|
+
for item in [self.psfLineEdit.text(), self.coorLineEdit.text()] + forceFieldFiles:
|
|
1649
|
+
if not os.path.exists(item):
|
|
1650
|
+
QMessageBox.warning(self, 'Error', f'file {item} does not exist!')
|
|
1651
|
+
return
|
|
1652
|
+
|
|
1653
|
+
# check inputs
|
|
1654
|
+
try:
|
|
1655
|
+
float(self.temperatureLineEdit.text())
|
|
1656
|
+
stratification = [
|
|
1657
|
+
int(self.geometricAdvancedSettings.stratificationRMSDBoundLineEdit.text()),
|
|
1658
|
+
int(self.geometricAdvancedSettings.stratificationThetaLineEdit.text()),
|
|
1659
|
+
int(self.geometricAdvancedSettings.stratificationPhiLineEdit.text()),
|
|
1660
|
+
int(self.geometricAdvancedSettings.stratificationPsiLineEdit.text()),
|
|
1661
|
+
int(self.geometricAdvancedSettings.stratificationthetaLineEdit.text()),
|
|
1662
|
+
int(self.geometricAdvancedSettings.stratificationphiLineEdit.text()),
|
|
1663
|
+
int(self.geometricAdvancedSettings.stratificationRLineEdit.text()),
|
|
1664
|
+
int(self.geometricAdvancedSettings.stratificationRMSDUnboundLineEdit.text())
|
|
1665
|
+
]
|
|
1666
|
+
alchemicalStratification = [
|
|
1667
|
+
int(self.alchemicalAdvancedSettings.boundLigandLineEdit.text()),
|
|
1668
|
+
int(self.alchemicalAdvancedSettings.boundRestraintsLineEdit.text()),
|
|
1669
|
+
int(self.alchemicalAdvancedSettings.unboundLigandLineEdit.text()),
|
|
1670
|
+
int(self.alchemicalAdvancedSettings.unboundRestraintsLineEdit.text())
|
|
1671
|
+
]
|
|
1672
|
+
except:
|
|
1673
|
+
QMessageBox.warning(self, 'Error', f'Force constant or r* input error!')
|
|
1674
|
+
return
|
|
1675
|
+
|
|
1676
|
+
# job type
|
|
1677
|
+
if self.forceFieldCombobox.currentText() == 'CHARMM':
|
|
1678
|
+
forceFieldType = 'charmm'
|
|
1679
|
+
elif self.forceFieldCombobox.currentText() == 'Amber':
|
|
1680
|
+
forceFieldType = 'amber'
|
|
1681
|
+
|
|
1682
|
+
# make sure there are CHARMM FF files
|
|
1683
|
+
if forceFieldFiles == [] and forceFieldType == 'charmm':
|
|
1684
|
+
QMessageBox.warning(
|
|
1685
|
+
self,
|
|
1686
|
+
'Error',
|
|
1687
|
+
f'\
|
|
1688
|
+
CHARMM force field files must be specified!'
|
|
1689
|
+
)
|
|
1690
|
+
return
|
|
1691
|
+
|
|
1692
|
+
if self.selectStrategyCombobox.currentText() == 'Geometric':
|
|
1693
|
+
|
|
1694
|
+
if self.selectMDEngineCombobox.currentText().lower() == 'gromacs':
|
|
1695
|
+
QMessageBox.warning(
|
|
1696
|
+
self, 'Warning', f'Please pay attention if you use the new Gromacs interface: \n\
|
|
1697
|
+
1. Occationally, the atom number in complex.ndx do not correct. If so, just modify it manually; \n\
|
|
1698
|
+
2. Make sure in complex.gro, the center of box is approximately at (x/2, y/2, z/2) rather than (0, 0, 0); \n\
|
|
1699
|
+
3. Gromacs patched by the latest (master branch) version of Colvars is needed.'
|
|
1700
|
+
)
|
|
1701
|
+
|
|
1702
|
+
# for the amber force field, files of large box must be provided
|
|
1703
|
+
if forceFieldType == 'amber':
|
|
1704
|
+
|
|
1705
|
+
if self.geometricAdvancedSettings.nonStandardSolventPdbLineEdit.text() == '' or \
|
|
1706
|
+
self.geometricAdvancedSettings.nonStandardSolventPsfLineEdit.text() == '':
|
|
1707
|
+
QMessageBox.warning(
|
|
1708
|
+
self,
|
|
1709
|
+
'Error',
|
|
1710
|
+
f'\
|
|
1711
|
+
Coordinate and topology files of large box must be \
|
|
1712
|
+
provided in "Advanced Settings"when using the Amber \
|
|
1713
|
+
force fields!'
|
|
1714
|
+
)
|
|
1715
|
+
return
|
|
1716
|
+
|
|
1717
|
+
if self.geometricAdvancedSettings.useGaWTMCheckbox.isChecked():
|
|
1718
|
+
|
|
1719
|
+
if self.geometricAdvancedSettings.useCUDASOAIntegrator.isChecked():
|
|
1720
|
+
QMessageBox.warning(self, 'Error',
|
|
1721
|
+
f'\
|
|
1722
|
+
GaWTM-eABF is not compatible with CUDASOAIntegrator in NAMD! \n'
|
|
1723
|
+
)
|
|
1724
|
+
return
|
|
1725
|
+
|
|
1726
|
+
QMessageBox.warning(self, 'Warning',
|
|
1727
|
+
f'\
|
|
1728
|
+
The feature of using GaWTM-eABF as the workhorse engine is \
|
|
1729
|
+
experimental! Please always use the latest devel version of NAMD!\n'
|
|
1730
|
+
)
|
|
1731
|
+
|
|
1732
|
+
try:
|
|
1733
|
+
iGenerator.generateNAMDGeometricFiles(
|
|
1734
|
+
path,
|
|
1735
|
+
self.psfLineEdit.text(),
|
|
1736
|
+
self.coorLineEdit.text(),
|
|
1737
|
+
forceFieldType,
|
|
1738
|
+
forceFieldFiles,
|
|
1739
|
+
float(self.temperatureLineEdit.text()),
|
|
1740
|
+
self.selectProteineLineEdit.text(),
|
|
1741
|
+
self.selectLigandLineEdit.text(),
|
|
1742
|
+
self.geometricAdvancedSettings.userDefinedDirectionLineEdit.text(),
|
|
1743
|
+
self.geometricAdvancedSettings.nonStandardSolventPsfLineEdit.text(),
|
|
1744
|
+
self.geometricAdvancedSettings.nonStandardSolventPdbLineEdit.text(),
|
|
1745
|
+
stratification,
|
|
1746
|
+
self.geometricAdvancedSettings.memProCheckbox.isChecked(),
|
|
1747
|
+
self.geometricAdvancedSettings.neutralizeLigOnlyCombobox.currentText(),
|
|
1748
|
+
self.geometricAdvancedSettings.pinDownProCheckbox.isChecked(),
|
|
1749
|
+
self.geometricAdvancedSettings.useOldCvCheckbox.isChecked(),
|
|
1750
|
+
int(self.geometricAdvancedSettings.parallelRunsLineEdit.text()),
|
|
1751
|
+
self.mainSettings.vmdLineEdit.text(),
|
|
1752
|
+
self.geometricAdvancedSettings.reflectingBoundaryCheckbox.isChecked(),
|
|
1753
|
+
self.selectMDEngineCombobox.currentText().lower(),
|
|
1754
|
+
self.geometricAdvancedSettings.OPLSMixingRuleCheckbox.isChecked(),
|
|
1755
|
+
self.geometricAdvancedSettings.considerRMSDCVCheckbox.isChecked(),
|
|
1756
|
+
self.geometricAdvancedSettings.useGaWTMCheckbox.isChecked(),
|
|
1757
|
+
self.geometricAdvancedSettings.useCUDASOAIntegrator.isChecked(),
|
|
1758
|
+
float(self.geometricAdvancedSettings.timestepLineEdit.text())
|
|
1759
|
+
)
|
|
1760
|
+
except fileParser.SelectionError:
|
|
1761
|
+
QMessageBox.warning(
|
|
1762
|
+
self,
|
|
1763
|
+
'Error',
|
|
1764
|
+
f'\
|
|
1765
|
+
Selection corresponding to nothing!\n\
|
|
1766
|
+
Check your selection again!'
|
|
1767
|
+
)
|
|
1768
|
+
if os.path.exists(f'{path}/BFEE'):
|
|
1769
|
+
shutil.rmtree(f'{path}/BFEE')
|
|
1770
|
+
return
|
|
1771
|
+
except inputGenerator.DirectoryExistError:
|
|
1772
|
+
QMessageBox.warning(
|
|
1773
|
+
self,
|
|
1774
|
+
'Error',
|
|
1775
|
+
f'\
|
|
1776
|
+
./BFEE* directory already exists!'
|
|
1777
|
+
)
|
|
1778
|
+
return
|
|
1779
|
+
except inputGenerator.FileTypeUnknownError:
|
|
1780
|
+
QMessageBox.warning(
|
|
1781
|
+
self,
|
|
1782
|
+
'Error',
|
|
1783
|
+
f'\
|
|
1784
|
+
Unkwn input file types! The following file types are supported:\n\
|
|
1785
|
+
psf, parm, prm7, parm7, prmtop, pdb, coor, rst, rst7, inpcrd '
|
|
1786
|
+
)
|
|
1787
|
+
return
|
|
1788
|
+
except PermissionError:
|
|
1789
|
+
QMessageBox.warning(
|
|
1790
|
+
self,
|
|
1791
|
+
'Error',
|
|
1792
|
+
f'\
|
|
1793
|
+
Cannot read input files due to the permission reason!\n\
|
|
1794
|
+
Restart the program or check the authority of the files!'
|
|
1795
|
+
)
|
|
1796
|
+
return
|
|
1797
|
+
except Exception as e:
|
|
1798
|
+
print(e)
|
|
1799
|
+
QMessageBox.warning(
|
|
1800
|
+
self,
|
|
1801
|
+
'Error',
|
|
1802
|
+
f'\
|
|
1803
|
+
Unknown error! The error message is: \n\
|
|
1804
|
+
{e}\n'
|
|
1805
|
+
)
|
|
1806
|
+
return
|
|
1807
|
+
|
|
1808
|
+
elif self.selectStrategyCombobox.currentText() == 'Alchemical':
|
|
1809
|
+
|
|
1810
|
+
try:
|
|
1811
|
+
iGenerator.generateNAMDAlchemicalFiles(
|
|
1812
|
+
path,
|
|
1813
|
+
self.psfLineEdit.text(),
|
|
1814
|
+
self.coorLineEdit.text(),
|
|
1815
|
+
forceFieldType,
|
|
1816
|
+
forceFieldFiles,
|
|
1817
|
+
float(self.temperatureLineEdit.text()),
|
|
1818
|
+
self.selectProteineLineEdit.text(),
|
|
1819
|
+
self.selectLigandLineEdit.text(),
|
|
1820
|
+
alchemicalStratification,
|
|
1821
|
+
self.alchemicalAdvancedSettings.doubleWideCheckbox.isChecked(),
|
|
1822
|
+
self.alchemicalAdvancedSettings.minBeforeSampleCheckbox.isChecked(),
|
|
1823
|
+
self.alchemicalAdvancedSettings.memProCheckbox.isChecked(),
|
|
1824
|
+
self.alchemicalAdvancedSettings.neutralizeLigOnlyCombobox.currentText(),
|
|
1825
|
+
self.alchemicalAdvancedSettings.pinDownProCheckbox.isChecked(),
|
|
1826
|
+
self.alchemicalAdvancedSettings.useOldCvCheckbox.isChecked(),
|
|
1827
|
+
self.mainSettings.vmdLineEdit.text(),
|
|
1828
|
+
self.alchemicalAdvancedSettings.OPLSMixingRuleCheckbox.isChecked(),
|
|
1829
|
+
self.alchemicalAdvancedSettings.considerRMSDCVCheckbox.isChecked(),
|
|
1830
|
+
self.alchemicalAdvancedSettings.useCUDASOAIntegrator.isChecked(),
|
|
1831
|
+
float(self.alchemicalAdvancedSettings.timestepLineEdit.text()),
|
|
1832
|
+
self.alchemicalAdvancedSettings.reEqCheckbox.isChecked()
|
|
1833
|
+
)
|
|
1834
|
+
except PermissionError:
|
|
1835
|
+
QMessageBox.warning(
|
|
1836
|
+
self,
|
|
1837
|
+
'Error',
|
|
1838
|
+
f'\
|
|
1839
|
+
Cannot read input files due to the permission reason!\n\
|
|
1840
|
+
Restart the program or check the authority of the files!'
|
|
1841
|
+
)
|
|
1842
|
+
return
|
|
1843
|
+
except fileParser.SelectionError:
|
|
1844
|
+
QMessageBox.warning(
|
|
1845
|
+
self,
|
|
1846
|
+
'Error',
|
|
1847
|
+
f'\
|
|
1848
|
+
Selection corresponding to nothing!\n\
|
|
1849
|
+
Check your selection again!'
|
|
1850
|
+
)
|
|
1851
|
+
if os.path.exists(f'{path}/BFEE'):
|
|
1852
|
+
shutil.rmtree(f'{path}/BFEE')
|
|
1853
|
+
return
|
|
1854
|
+
except inputGenerator.DirectoryExistError:
|
|
1855
|
+
QMessageBox.warning(
|
|
1856
|
+
self,
|
|
1857
|
+
'Error',
|
|
1858
|
+
f'\
|
|
1859
|
+
./BFEE directory already exists!'
|
|
1860
|
+
)
|
|
1861
|
+
return
|
|
1862
|
+
except inputGenerator.FileTypeUnknownError:
|
|
1863
|
+
QMessageBox.warning(
|
|
1864
|
+
self,
|
|
1865
|
+
'Error',
|
|
1866
|
+
f'\
|
|
1867
|
+
Unkwn input file types! The following file types are supported:\n\
|
|
1868
|
+
psf, parm, prm7, parm7, prmtop, pdb, coor, rst, rst7, inpcrd '
|
|
1869
|
+
)
|
|
1870
|
+
return
|
|
1871
|
+
except Exception as e:
|
|
1872
|
+
print(e)
|
|
1873
|
+
QMessageBox.warning(
|
|
1874
|
+
self,
|
|
1875
|
+
'Error',
|
|
1876
|
+
f'\
|
|
1877
|
+
Unknown error! The error message is: \n\
|
|
1878
|
+
{e}\n'
|
|
1879
|
+
)
|
|
1880
|
+
return
|
|
1881
|
+
|
|
1882
|
+
# gromacs
|
|
1883
|
+
if self.preTreatmentMainTabs.currentIndex() == 1:
|
|
1884
|
+
|
|
1885
|
+
QMessageBox.warning(
|
|
1886
|
+
self, 'Warning', ('<ol>\
|
|
1887
|
+
<li>Any setting in "Advanced settings" is not supported\
|
|
1888
|
+
when using Gromacs-formatted files as inputs!</li>\
|
|
1889
|
+
<li>C-rescale pressure coupling (pcoupl) is used for all simulations, \
|
|
1890
|
+
GROMACS version >= 2021 with Colvars module is required. \
|
|
1891
|
+
You may need to download it from the \
|
|
1892
|
+
<a href=\'https://github.com/Colvars/colvars/\'>Colvars website</a>.</li></ol>'))
|
|
1893
|
+
|
|
1894
|
+
for item in [
|
|
1895
|
+
self.topLineEdit.text(),
|
|
1896
|
+
self.gromacsPdbLineEdit.text(),
|
|
1897
|
+
self.gromacsLigandOnlyPdbLineEdit.text(),
|
|
1898
|
+
self.gromacsLigandOnlyTopLineEdit.text()
|
|
1899
|
+
]:
|
|
1900
|
+
if not os.path.exists(item):
|
|
1901
|
+
QMessageBox.warning(self, 'Error', f'file {item} does not exist!')
|
|
1902
|
+
return
|
|
1903
|
+
|
|
1904
|
+
if self.selectStrategyCombobox.currentText() == 'Geometric':
|
|
1905
|
+
try:
|
|
1906
|
+
iGenerator.generateGromacsGeometricFiles(
|
|
1907
|
+
path=path,
|
|
1908
|
+
topFile=self.topLineEdit.text(),
|
|
1909
|
+
pdbFile=self.gromacsPdbLineEdit.text(),
|
|
1910
|
+
pdbFileFormat=self.gromacsStructureFileFormatCombobox.currentText(),
|
|
1911
|
+
ligandOnlyTopFile=self.gromacsLigandOnlyTopLineEdit.text(),
|
|
1912
|
+
ligandOnlyPdbFile=self.gromacsLigandOnlyPdbLineEdit.text(),
|
|
1913
|
+
ligandOnlyPdbFileFormat=self.gromacsLigandOnlyStructureFileFormatCombobox.currentText(),
|
|
1914
|
+
selectionPro=self.selectProteineLineEdit.text(),
|
|
1915
|
+
selectionLig=self.selectLigandLineEdit.text(),
|
|
1916
|
+
temperature=float(self.temperatureLineEdit.text())
|
|
1917
|
+
)
|
|
1918
|
+
except inputGenerator.DirectoryExistError:
|
|
1919
|
+
QMessageBox.warning(
|
|
1920
|
+
self,
|
|
1921
|
+
'Error',
|
|
1922
|
+
f'\
|
|
1923
|
+
./BFEE directory already exists!'
|
|
1924
|
+
)
|
|
1925
|
+
return
|
|
1926
|
+
except BFEEGromacs.SelectionError:
|
|
1927
|
+
QMessageBox.warning(
|
|
1928
|
+
self,
|
|
1929
|
+
'Error',
|
|
1930
|
+
f'\
|
|
1931
|
+
Selection corresponding to nothing!\n\
|
|
1932
|
+
Check your selection again!'
|
|
1933
|
+
)
|
|
1934
|
+
if os.path.exists(f'{path}/BFEE'):
|
|
1935
|
+
shutil.rmtree(f'{path}/BFEE')
|
|
1936
|
+
return
|
|
1937
|
+
except Exception as e:
|
|
1938
|
+
print(e)
|
|
1939
|
+
QMessageBox.warning(
|
|
1940
|
+
self,
|
|
1941
|
+
'Error',
|
|
1942
|
+
f'\
|
|
1943
|
+
Unknown error!'
|
|
1944
|
+
)
|
|
1945
|
+
return
|
|
1946
|
+
elif self.selectStrategyCombobox.currentText() == 'Alchemical':
|
|
1947
|
+
QMessageBox.warning(self, 'Error', f'Alchemical route is not supported using Gromacs!')
|
|
1948
|
+
return
|
|
1949
|
+
|
|
1950
|
+
QMessageBox.information(self, 'Input generation', f'Input files have been generated successfully!')
|
|
1951
|
+
|
|
1952
|
+
del iGenerator
|
|
1953
|
+
|
|
1954
|
+
return f
|
|
1955
|
+
|
|
1956
|
+
def _mergePMFs(self):
|
|
1957
|
+
"""merge a series of overlapped pmfs
|
|
1958
|
+
|
|
1959
|
+
Returns:
|
|
1960
|
+
function obj: a slot function that merges a series of overlapped pmfs
|
|
1961
|
+
"""
|
|
1962
|
+
|
|
1963
|
+
def f():
|
|
1964
|
+
if self.mergePmfBox.count() == 0:
|
|
1965
|
+
QMessageBox.warning(self, 'Warning', f'Warning, no PMF selected!')
|
|
1966
|
+
return
|
|
1967
|
+
|
|
1968
|
+
path, _ = QFileDialog.getSaveFileName(None, 'Set the name of merged PMF')
|
|
1969
|
+
|
|
1970
|
+
pmfFiles = [self.mergePmfBox.item(i).text() for i in range(self.mergePmfBox.count())]
|
|
1971
|
+
|
|
1972
|
+
if not ploter.isGaWTM(pmfFiles):
|
|
1973
|
+
pmfs = [ploter.readPMF(item) for item in pmfFiles]
|
|
1974
|
+
else:
|
|
1975
|
+
pmfFiles = [item for item in pmfFiles if not item.endswith('.reweightamd1.cumulant.pmf')]
|
|
1976
|
+
try:
|
|
1977
|
+
pmfs = [ploter.correctGaWTM(item) for item in pmfFiles]
|
|
1978
|
+
except ploter.NoCorrectionFileError:
|
|
1979
|
+
QMessageBox.warning(self, 'Error', f'A PMF file does not have corresponding correction!')
|
|
1980
|
+
return
|
|
1981
|
+
|
|
1982
|
+
mergedPMF = ploter.mergePMF(pmfs)
|
|
1983
|
+
ploter.writePMF(path, mergedPMF)
|
|
1984
|
+
QMessageBox.information(self, 'Merge PMFs', f'PMF merged successfully!')
|
|
1985
|
+
return f
|
|
1986
|
+
|
|
1987
|
+
def _plotPMFs(self):
|
|
1988
|
+
"""plot a series of overlapped pmfs
|
|
1989
|
+
|
|
1990
|
+
Returns:
|
|
1991
|
+
function obj: a slot function that plots a series of overlapped pmfs
|
|
1992
|
+
"""
|
|
1993
|
+
|
|
1994
|
+
def f():
|
|
1995
|
+
if self.plotPmfBox.count() == 0:
|
|
1996
|
+
QMessageBox.warning(self, 'Warning', f'Warning, no PMF selected!')
|
|
1997
|
+
return
|
|
1998
|
+
|
|
1999
|
+
pmfFiles = [self.plotPmfBox.item(i).text() for i in range(self.plotPmfBox.count())]
|
|
2000
|
+
|
|
2001
|
+
if not ploter.isGaWTM(pmfFiles):
|
|
2002
|
+
pmfs = [ploter.readPMF(item) for item in pmfFiles]
|
|
2003
|
+
else:
|
|
2004
|
+
pmfFiles = [item for item in pmfFiles if not item.endswith('.reweightamd1.cumulant.pmf')]
|
|
2005
|
+
try:
|
|
2006
|
+
pmfs = [ploter.correctGaWTM(item) for item in pmfFiles]
|
|
2007
|
+
except ploter.NoCorrectionFileError:
|
|
2008
|
+
QMessageBox.warning(self, 'Error', f'A PMF file does not have corresponding correction!')
|
|
2009
|
+
return
|
|
2010
|
+
|
|
2011
|
+
mergedPMF = ploter.mergePMF(pmfs)
|
|
2012
|
+
ploter.plotPMF(mergedPMF)
|
|
2013
|
+
return f
|
|
2014
|
+
|
|
2015
|
+
def _plotRMSDConvergence(self):
|
|
2016
|
+
"""plot time evolution of PMF rmsd with respect to zero array
|
|
2017
|
+
|
|
2018
|
+
Returns:
|
|
2019
|
+
function obj: a slot function that plots time evolution of PMF rmsd with respect to zero array
|
|
2020
|
+
"""
|
|
2021
|
+
|
|
2022
|
+
def f():
|
|
2023
|
+
path = self.plotPmfConvergenceBox.text()
|
|
2024
|
+
if not os.path.exists(path):
|
|
2025
|
+
QMessageBox.warning(self, 'Error', f'file {path} does not exist!')
|
|
2026
|
+
return
|
|
2027
|
+
|
|
2028
|
+
rmsds = ploter.parseHistFile(path)
|
|
2029
|
+
ploter.plotConvergence(rmsds)
|
|
2030
|
+
return f
|
|
2031
|
+
|
|
2032
|
+
def _plotHysteresis(self):
|
|
2033
|
+
"""plot hysteresis between forward and backward alchemical transformations
|
|
2034
|
+
|
|
2035
|
+
Returns:
|
|
2036
|
+
function obj: a slot function that plot hysteresis between forward and backward alchemical transformations
|
|
2037
|
+
"""
|
|
2038
|
+
|
|
2039
|
+
def f():
|
|
2040
|
+
forwardFilePath = self.plotHysteresisForwardLineEdit.text()
|
|
2041
|
+
backwardFilePath = self.plotHysteresisBackwardLineEdit.text()
|
|
2042
|
+
if not os.path.exists(forwardFilePath):
|
|
2043
|
+
QMessageBox.warning(self, 'Error', f'file {forwardFilePath} does not exist!')
|
|
2044
|
+
return
|
|
2045
|
+
if not os.path.exists(backwardFilePath):
|
|
2046
|
+
QMessageBox.warning(self, 'Error', f'file {backwardFilePath} does not exist!')
|
|
2047
|
+
return
|
|
2048
|
+
|
|
2049
|
+
forwardPostfix = os.path.splitext(forwardFilePath)[-1]
|
|
2050
|
+
backwardPostfix = os.path.splitext(backwardFilePath)[-1]
|
|
2051
|
+
|
|
2052
|
+
if forwardPostfix != '.fepout' and forwardPostfix != '.log' \
|
|
2053
|
+
and backwardPostfix != '.fepout' and forwardPostfix != '.log':
|
|
2054
|
+
QMessageBox.warning(self, 'Error', f'File type not correct!')
|
|
2055
|
+
return
|
|
2056
|
+
|
|
2057
|
+
if forwardPostfix != backwardPostfix:
|
|
2058
|
+
QMessageBox.warning(self, 'Error', f'File types of forward and backward simulations are not the same!')
|
|
2059
|
+
return
|
|
2060
|
+
|
|
2061
|
+
pTreat = postTreatment.postTreatment(float(self.alchemicalPostTemperatureLineEdit.text()), 'namd', 'alchemical')
|
|
2062
|
+
if forwardPostfix == '.fepout':
|
|
2063
|
+
forwardProfile = np.transpose(pTreat._fepoutFile(forwardFilePath))
|
|
2064
|
+
backwardProfile = np.transpose(pTreat._fepoutFile(backwardFilePath))
|
|
2065
|
+
backwardProfile[:,1] *= -1
|
|
2066
|
+
elif forwardPostfix == '.log':
|
|
2067
|
+
forwardProfile = np.transpose(pTreat._tiLogFile(forwardFilePath))
|
|
2068
|
+
backwardProfile = np.transpose(pTreat._tiLogFile(backwardFilePath))
|
|
2069
|
+
ploter.plotHysteresis(forwardProfile, backwardProfile)
|
|
2070
|
+
return f
|
|
2071
|
+
|
|
2072
|
+
|
|
2073
|
+
def _initSingalsSlots(self):
|
|
2074
|
+
"""initialize (connect) singals and slots
|
|
2075
|
+
"""
|
|
2076
|
+
|
|
2077
|
+
# pre-treatment tab
|
|
2078
|
+
self.selectStrategyAdvancedButton.clicked.connect(self._advancedSettings(self.selectStrategyCombobox))
|
|
2079
|
+
self.preTreatmentMainTabs.currentChanged.connect(self._changeStrategySettingStateForOldGromacs)
|
|
2080
|
+
|
|
2081
|
+
# NAMD tab
|
|
2082
|
+
self.psfButton.clicked.connect(commonSlots.openFileDialog('psf/parm', self.psfLineEdit))
|
|
2083
|
+
self.coorButton.clicked.connect(commonSlots.openFileDialog('pdb/rst', self.coorLineEdit))
|
|
2084
|
+
|
|
2085
|
+
# force field selection
|
|
2086
|
+
self.forceFieldCombobox.currentTextChanged.connect(self._changeFFButtonState)
|
|
2087
|
+
self.forceFieldAddButton.clicked.connect(commonSlots.openFilesDialog('prm', self.forceFieldFilesBox))
|
|
2088
|
+
self.forceFieldClearButton.clicked.connect(self.forceFieldFilesBox.clear)
|
|
2089
|
+
|
|
2090
|
+
# MD engine
|
|
2091
|
+
self.selectMDEngineCombobox.currentTextChanged.connect(self._changeStrategySettingState)
|
|
2092
|
+
|
|
2093
|
+
# gromacs tab
|
|
2094
|
+
self.gromacsPdbButton.clicked.connect(commonSlots.openFileDialog('pdb', self.gromacsPdbLineEdit))
|
|
2095
|
+
self.topButton.clicked.connect(commonSlots.openFileDialog('top', self.topLineEdit))
|
|
2096
|
+
self.gromacsLigandOnlyPdbButton.clicked.connect(commonSlots.openFileDialog('pdb', self.gromacsLigandOnlyPdbLineEdit))
|
|
2097
|
+
self.gromacsLigandOnlyTopButton.clicked.connect(commonSlots.openFileDialog('top', self.gromacsLigandOnlyTopLineEdit))
|
|
2098
|
+
|
|
2099
|
+
# geometric tab
|
|
2100
|
+
self.rmsdBoundButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.rmsdBoundLineEdit))
|
|
2101
|
+
self.rmsdUnboundButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.rmsdUnboundLineEdit))
|
|
2102
|
+
self.ThetaButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.ThetaLineEdit))
|
|
2103
|
+
self.PhiButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.PhiLineEdit))
|
|
2104
|
+
self.PsiButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.PsiLineEdit))
|
|
2105
|
+
self.thetaButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.thetaLineEdit))
|
|
2106
|
+
self.phiButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.phiLineEdit))
|
|
2107
|
+
self.rButton.clicked.connect(commonSlots.openFileDialog('czar.pmf/UI.pmf', self.rLineEdit))
|
|
2108
|
+
|
|
2109
|
+
# alchemical tab
|
|
2110
|
+
self.alchemicalForwardButton1.clicked.connect(commonSlots.openFileDialog('log', self.alchemicalForwardLineEdit1))
|
|
2111
|
+
self.alchemicalBackwardButton1.clicked.connect(commonSlots.openFileDialog('log', self.alchemicalBackwardLineEdit1))
|
|
2112
|
+
self.alchemicalForwardButton2.clicked.connect(commonSlots.openFileDialog('log', self.alchemicalForwardLineEdit2))
|
|
2113
|
+
self.alchemicalBackwardButton2.clicked.connect(commonSlots.openFileDialog('log', self.alchemicalBackwardLineEdit2))
|
|
2114
|
+
self.alchemicalForwardButton3.clicked.connect(commonSlots.openFileDialog('fepout', self.alchemicalForwardLineEdit3))
|
|
2115
|
+
self.alchemicalBackwardButton3.clicked.connect(commonSlots.openFileDialog('fepout', self.alchemicalBackwardLineEdit3))
|
|
2116
|
+
self.alchemicalForwardButton4.clicked.connect(commonSlots.openFileDialog('fepout', self.alchemicalForwardLineEdit4))
|
|
2117
|
+
self.alchemicalBackwardButton4.clicked.connect(commonSlots.openFileDialog('fepout', self.alchemicalBackwardLineEdit4))
|
|
2118
|
+
|
|
2119
|
+
# generate input files
|
|
2120
|
+
self.generateInputButton.clicked.connect(self._generateInputFiles())
|
|
2121
|
+
|
|
2122
|
+
# calculate binding free energy
|
|
2123
|
+
self.calculateButton.clicked.connect(self._showFinalResults())
|
|
2124
|
+
|
|
2125
|
+
# quick-plot tab
|
|
2126
|
+
self.plotPmfAddButton.clicked.connect(commonSlots.openFilesDialog('pmf', self.plotPmfBox))
|
|
2127
|
+
self.plotPmfClearButton.clicked.connect(self.plotPmfBox.clear)
|
|
2128
|
+
self.plotPmfPlotButton.clicked.connect(self._plotPMFs())
|
|
2129
|
+
self.mergePmfAddButton.clicked.connect(commonSlots.openFilesDialog('pmf', self.mergePmfBox))
|
|
2130
|
+
self.mergePmfClearButton.clicked.connect(self.mergePmfBox.clear)
|
|
2131
|
+
self.mergePmfmergeButton.clicked.connect(self._mergePMFs())
|
|
2132
|
+
self.plotPmfConvergenceBrowseButton.clicked.connect(commonSlots.openFileDialog('pmf', self.plotPmfConvergenceBox))
|
|
2133
|
+
self.plotPmfConvergencePlotButton.clicked.connect(self._plotRMSDConvergence())
|
|
2134
|
+
self.plotHysteresisForwardButton.clicked.connect(commonSlots.openFileDialog('fepout/log', self.plotHysteresisForwardLineEdit))
|
|
2135
|
+
self.plotHysteresisBackwardButton.clicked.connect(commonSlots.openFileDialog('fepout/log', self.plotHysteresisBackwardLineEdit))
|
|
2136
|
+
self.plotHysteresisPlotButton.clicked.connect(self._plotHysteresis())
|