bfee2 3.1.1.post1__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.
Files changed (68) hide show
  1. BFEE2/__init__.py +0 -0
  2. BFEE2/commonTools/__init__.py +0 -0
  3. BFEE2/commonTools/commonSlots.py +48 -0
  4. BFEE2/commonTools/fileParser.py +327 -0
  5. BFEE2/commonTools/ploter.py +218 -0
  6. BFEE2/doc/Doc.pdf +0 -0
  7. BFEE2/doc/__init__.py +1 -0
  8. BFEE2/gui.py +2785 -0
  9. BFEE2/inputGenerator.py +2949 -0
  10. BFEE2/postTreatment.py +676 -0
  11. BFEE2/templates_gromacs/000.colvars.template +37 -0
  12. BFEE2/templates_gromacs/000.generate_tpr_sh.template +31 -0
  13. BFEE2/templates_gromacs/000.mdp.template +74 -0
  14. BFEE2/templates_gromacs/001.colvars.template +76 -0
  15. BFEE2/templates_gromacs/001.generate_tpr_sh.template +31 -0
  16. BFEE2/templates_gromacs/001.mdp.template +73 -0
  17. BFEE2/templates_gromacs/001.readme.template +1 -0
  18. BFEE2/templates_gromacs/002.colvars.template +101 -0
  19. BFEE2/templates_gromacs/002.generate_tpr_sh.template +31 -0
  20. BFEE2/templates_gromacs/002.mdp.template +73 -0
  21. BFEE2/templates_gromacs/003.colvars.template +125 -0
  22. BFEE2/templates_gromacs/003.generate_tpr_sh.template +36 -0
  23. BFEE2/templates_gromacs/003.mdp.template +73 -0
  24. BFEE2/templates_gromacs/004.colvars.template +148 -0
  25. BFEE2/templates_gromacs/004.generate_tpr_sh.template +37 -0
  26. BFEE2/templates_gromacs/004.mdp.template +74 -0
  27. BFEE2/templates_gromacs/005.colvars.template +170 -0
  28. BFEE2/templates_gromacs/005.generate_tpr_sh.template +38 -0
  29. BFEE2/templates_gromacs/005.mdp.template +74 -0
  30. BFEE2/templates_gromacs/006.colvars.template +192 -0
  31. BFEE2/templates_gromacs/006.generate_tpr_sh.template +39 -0
  32. BFEE2/templates_gromacs/006.mdp.template +74 -0
  33. BFEE2/templates_gromacs/007.colvars.template +210 -0
  34. BFEE2/templates_gromacs/007.generate_tpr_sh.template +40 -0
  35. BFEE2/templates_gromacs/007.mdp.template +73 -0
  36. BFEE2/templates_gromacs/007_eq.colvars.template +169 -0
  37. BFEE2/templates_gromacs/007_eq.generate_tpr_sh.template +64 -0
  38. BFEE2/templates_gromacs/007_min.mdp.template +62 -0
  39. BFEE2/templates_gromacs/008.colvars.template +42 -0
  40. BFEE2/templates_gromacs/008.generate_tpr_sh.template +31 -0
  41. BFEE2/templates_gromacs/008.mdp.template +74 -0
  42. BFEE2/templates_gromacs/008_eq.colvars.template +14 -0
  43. BFEE2/templates_gromacs/008_eq.generate_tpr_sh.template +31 -0
  44. BFEE2/templates_gromacs/BFEEGromacs.py +1268 -0
  45. BFEE2/templates_gromacs/__init__.py +0 -0
  46. BFEE2/templates_gromacs/find_min_max.awk +27 -0
  47. BFEE2/templates_namd/__init__.py +0 -0
  48. BFEE2/templates_namd/configTemplate.py +1152 -0
  49. BFEE2/templates_namd/fep.tcl +299 -0
  50. BFEE2/templates_namd/fep_lddm.tcl +312 -0
  51. BFEE2/templates_namd/scriptTemplate.py +304 -0
  52. BFEE2/templates_namd/solvate.tcl +9 -0
  53. BFEE2/templates_namd/solvate_mem.tcl +9 -0
  54. BFEE2/templates_namd/updateCenters.py +312 -0
  55. BFEE2/templates_readme/Readme_Gromacs_Geometrical.txt +25 -0
  56. BFEE2/templates_readme/Readme_NAMD_Alchemical.txt +20 -0
  57. BFEE2/templates_readme/Readme_NAMD_Geometrical.txt +34 -0
  58. BFEE2/templates_readme/__init__.py +1 -0
  59. BFEE2/templates_readme/rags.py +187 -0
  60. BFEE2/third_party/__init__.py +0 -0
  61. BFEE2/third_party/py_bar.py +585 -0
  62. BFEE2/version.py +4 -0
  63. bfee2-3.1.1.post1.data/scripts/BFEE2Gui.py +19 -0
  64. bfee2-3.1.1.post1.dist-info/METADATA +86 -0
  65. bfee2-3.1.1.post1.dist-info/RECORD +68 -0
  66. bfee2-3.1.1.post1.dist-info/WHEEL +5 -0
  67. bfee2-3.1.1.post1.dist-info/licenses/LICENSE +677 -0
  68. bfee2-3.1.1.post1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2949 @@
1
+ # generate all the inputs and define corresponding slots
2
+
3
+ import os
4
+ import shutil
5
+ import subprocess
6
+ import sys
7
+
8
+ import numpy as np
9
+
10
+ from BFEE2.commonTools import fileParser
11
+ from BFEE2.templates_gromacs.BFEEGromacs import BFEEGromacs
12
+ from BFEE2.templates_namd import configTemplate, scriptTemplate
13
+
14
+ try:
15
+ import importlib.resources as pkg_resources
16
+ except ImportError:
17
+ # Try backported to PY<37 `importlib_resources`.
18
+ import importlib_resources as pkg_resources
19
+
20
+ from BFEE2 import templates_namd, templates_readme
21
+
22
+
23
+ # an runtime error
24
+ # directory already exists
25
+ class DirectoryExistError(RuntimeError):
26
+ def __init__(self, arg):
27
+ self.args = arg
28
+
29
+ # an runtime error
30
+ # file type is unknown
31
+ class FileTypeUnknownError(RuntimeError):
32
+ def __init__(self, arg):
33
+ self.args = arg
34
+
35
+ class inputGenerator():
36
+ """generate all the inputs and define corresponding slots
37
+ """
38
+
39
+ def __init__(self):
40
+ """simply initialize the configTemplate objects
41
+ """
42
+
43
+ self.cTemplate = configTemplate.configTemplate()
44
+
45
+ def generateNAMDAlchemicalFiles(
46
+ self,
47
+ path,
48
+ topFile,
49
+ coorFile,
50
+ forceFieldType,
51
+ forceFieldFiles,
52
+ temperature,
53
+ selectionPro,
54
+ selectionLig,
55
+ stratification = [1,1,1,1],
56
+ doubleWide = False,
57
+ minBeforeSample = False,
58
+ membraneProtein = False,
59
+ neutralizeLigOnly = 'NaCl',
60
+ pinDownPro = True,
61
+ useOldCv = True,
62
+ vmdPath = '',
63
+ OPLSMixingRule = False,
64
+ considerRMSDCV = True,
65
+ CUDASOAIntegrator = False,
66
+ timestep = 2.0,
67
+ reEq = False,
68
+ useLDDM = False,
69
+ useLambdaABF = False
70
+ ):
71
+ """generate all the input files for NAMD alchemical simulation
72
+
73
+ Args:
74
+ path (str): the directory for generation of all the files
75
+ topFile (str): the path of the topology (psf, parm) file
76
+ coorFile (str): the path of the coordinate (pdb, rst7) file
77
+ forceFieldType (str): 'charmm' or 'amber'
78
+ forceFieldFiles (list of str): list of CHARMM force field files
79
+ temperature (float): temperature of the simulation
80
+ selectionPro (str): MDAnalysis-style selection of the protein
81
+ selectionLig (str): MDAnalysis-style selection of the ligand
82
+ stratification (list of int, 4, optional): number of windows for each simulation.
83
+ Defaults to [1,1,1,1].
84
+ doubleWide (bool, optional): whether double-wide simulations are carried out.
85
+ Defaults to False.
86
+ minBeforeSample (bool, optional): minimization before sampling in each FEP window.
87
+ Defaults to False.
88
+ membraneProtein (bool, optional): whether simulating a membrane protein.
89
+ Defaults to False.
90
+ neutralizeLigOnly (str or None, optional): 'NaCl', 'KCl', 'CaCl2' or None.
91
+ neutralize the lig-only system using the salt.
92
+ Defaluts to NaCl.
93
+ pinDownPro (bool, optional): whether pinning down the protien. Defaults to True.
94
+ useOldCv (bool, optional): whether used old, custom-function-based cv. Defaults to True.
95
+ vmdPath (str, optional): path to vmd. Defaults to ''.
96
+ OPLSMixingRule (bool, optional): whether use the OPLS mixing rules. Defaults to False.
97
+ considerRMSDCV (bool, optional): Whether consider the RMSD CV. Default to True.
98
+ CUDASOAIntegrator (bool, optional): Whether CUDASOA integrator is used. Default to False.
99
+ timestep (float, optional): timestep of the simulation. Default to 2.0
100
+ reEq (bool, optional): re-equilibration after histogram. Default to False.
101
+ useLDDM (bool, optional): whether the LDDM strategy is used. Default to False.
102
+ useLambdaABF (bool, optional): whether use WTM-lambdaABF instead of FEP. Default to False.
103
+ """
104
+
105
+ assert(len(stratification) == 4)
106
+ assert(forceFieldType == 'charmm' or forceFieldType == 'amber')
107
+
108
+ # determine the type of input top and coor file
109
+ topType, coorType = self._determineFileType(topFile, coorFile)
110
+
111
+ self._makeDirectories(path, 'alchemical', considerRMSDCV=considerRMSDCV, useLDDM=useLDDM)
112
+ # after copying files
113
+ # the coordinate file is converted to pdb
114
+ self._copyFiles(
115
+ path, topFile, topType, coorFile, coorType, forceFieldType, forceFieldFiles,
116
+ selectionPro, selectionLig, selectionPro, '', '',
117
+ 'alchemical', membraneProtein, neutralizeLigOnly, vmdPath,
118
+ considerRMSDCV, useLDDM, temperature, stratification[0])
119
+
120
+ # get relative force field path
121
+ relativeFFPath = []
122
+ for item in forceFieldFiles:
123
+ _, name = os.path.split(item)
124
+ relativeFFPath.append(f'../{name}')
125
+
126
+ self._generateAlchemicalNAMDConfig(
127
+ path, forceFieldType, relativeFFPath, temperature, stratification, doubleWide, minBeforeSample,
128
+ membraneProtein, OPLSMixingRule=OPLSMixingRule, considerRMSDCV=considerRMSDCV,
129
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep, reEq=reEq, useLDDM=useLDDM, useLambdaABF=useLambdaABF
130
+ )
131
+ self._generateAlchemicalColvarsConfig(
132
+ path, topType, 'pdb', selectionPro, selectionLig, selectionPro, stratification, pinDownPro, useOldCv,
133
+ considerRMSDCV=considerRMSDCV, reEq=reEq, useLDDM=useLDDM, useLambdaABF=useLambdaABF
134
+ )
135
+
136
+ def generateNAMDGeometricFiles(
137
+ self,
138
+ path,
139
+ topFile,
140
+ coorFile,
141
+ forceFieldType,
142
+ forceFieldFiles,
143
+ temperature,
144
+ selectionPro,
145
+ selectionLig,
146
+ selectionRef = '',
147
+ userProvidedPullingTop = '',
148
+ userProvidedPullingCoor = '',
149
+ stratification = [1,1,1,1,1,1,1,1],
150
+ membraneProtein = False,
151
+ neutralizeLigOnly = 'NaCl',
152
+ pinDownPro = True,
153
+ useOldCv = True,
154
+ parallelRuns = 1,
155
+ vmdPath = '',
156
+ reflectionBoundary = False,
157
+ MDEngine = 'namd',
158
+ OPLSMixingRule = False,
159
+ considerRMSDCV = True,
160
+ GaWTM = False,
161
+ CUDASOAIntegrator = False,
162
+ timestep = 2.0
163
+ ):
164
+ """generate all the input files for NAMD geometric simulation
165
+
166
+ Args:
167
+ path (str): the directory for generation of all the files
168
+ topFile (str): the path of the topology (psf, parm) file
169
+ coorFile (str): the path of the coordinate (pdb, rst7) file
170
+ forceFieldType (str): 'charmm' or 'amber'
171
+ forceFieldFiles (list of str): list of CHARMM force field files
172
+ temperature (float): temperature of the simulation
173
+ selectionPro (str): MDAnalysis-style selection of the protein
174
+ selectionLig (str): MDAnalysis-style selection of the ligand
175
+ selectionRef (str, optional): MDAnalysis-style selection of the reference group for pulling simulation,
176
+ by default, this is the protein.
177
+ Defaults to ''.
178
+ userProvidedPullingTop (str, optional): user-provided large solvation box for pulling simulation.
179
+ Defaults to ''.
180
+ userProvidedPullingCoor (str, optional): user-provided large solvation box for pulling simulation.
181
+ Defaults to ''.
182
+ stratification (list, optional): number of windows for each simulation.
183
+ Defaults to [1,1,1,1,1,1,1,1].
184
+ membraneProtein (bool, optional): whether simulation a membrane protein. Defaults to False.
185
+ neutralizeLigOnly (str or None, optional): 'NaCl', 'KCl', 'CaCl2' or None.
186
+ neutralize the lig-only system using the salt.
187
+ Defaluts to NaCl.
188
+ pinDownPro (bool, optional): whether pinning down the protien. Defaults to True.
189
+ useOldCv (bool, optional): whether used old, custom-function-based cv. Defaults to True.
190
+ parallelRuns (int, optional): generate files for duplicate runs. Defaults to 1.
191
+ vmdPath (str, optional): path to vmd. Defaults to ''.
192
+ reflectingBoundary (bool, optional): Whether use reflecting boundaries, requires setBoundary on. Default to False.
193
+ MDEngine (str, optional): namd or gromacs. Default to namd.
194
+ OPLSMixingRule (bool, optional): whether use the OPLS mixing rules. Defaults to False.
195
+ considerRMSDCV (bool, optional): Whether consider the RMSD CV. Default to True.
196
+ GaWTM (bool, optional): Whether performing GaWTM-eABF simulations. Default to False.
197
+ CUDASOAIntegrator (bool, optional): Whether CUDASOA integrator is used. Default to False.
198
+ timestep (float, optional): timestep of the simulation. Default to 2.0
199
+ """
200
+
201
+ assert(len(stratification) == 8)
202
+ assert(forceFieldType == 'charmm' or forceFieldType == 'amber')
203
+
204
+ if selectionRef == '':
205
+ selectionRef = selectionPro
206
+
207
+ # determine the type of input top and coor file
208
+ # However, whatever coorType is, NAMD only read pdb as coordinate
209
+ topType, coorType = self._determineFileType(topFile, coorFile)
210
+
211
+ self._makeDirectories(path, 'geometric', considerRMSDCV=considerRMSDCV)
212
+ self._copyFiles(
213
+ path, topFile, topType, coorFile, coorType, forceFieldType, forceFieldFiles,
214
+ selectionPro, selectionLig, selectionRef, userProvidedPullingTop, userProvidedPullingCoor,
215
+ 'geometric', membraneProtein, neutralizeLigOnly, vmdPath, considerRMSDCV=considerRMSDCV)
216
+
217
+ if MDEngine == 'gromacs':
218
+ self._makeGromacsTopGro(path, forceFieldType, forceFieldFiles, 'geometric', vmdPath, considerRMSDCV=considerRMSDCV)
219
+
220
+ # get relative force field path
221
+ relativeFFPath = []
222
+ for item in forceFieldFiles:
223
+ _, name = os.path.split(item)
224
+ relativeFFPath.append(f'../{name}')
225
+
226
+ if MDEngine == 'namd':
227
+ self._generateGeometricNAMDConfig(
228
+ path, forceFieldType, relativeFFPath, temperature, stratification, membraneProtein,
229
+ OPLSMixingRule=OPLSMixingRule, considerRMSDCV=considerRMSDCV, GaWTM=GaWTM,
230
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
231
+ )
232
+ elif MDEngine == 'gromacs':
233
+ self._generateGeometricGromacsConfig(
234
+ path, forceFieldType, temperature, membraneProtein, considerRMSDCV=considerRMSDCV
235
+ )
236
+
237
+ self._generateGeometricColvarsConfig(
238
+ path, topType, coorType, selectionPro, selectionLig, selectionRef,
239
+ stratification, pinDownPro, useOldCv, reflectionBoundary, MDEngine,
240
+ considerRMSDCV=considerRMSDCV, reweightAMD=False
241
+ )
242
+ # for GaWTM-eABF simulations, two colvars config files are needed. One for pre-equilibration
243
+ # and the other for production
244
+ if GaWTM:
245
+ self._generateGeometricColvarsConfig(
246
+ path, topType, coorType, selectionPro, selectionLig, selectionRef,
247
+ stratification, pinDownPro, useOldCv, reflectionBoundary, MDEngine,
248
+ considerRMSDCV=considerRMSDCV, reweightAMD=True
249
+ )
250
+
251
+ self._duplicateFileFolder(path, parallelRuns)
252
+
253
+ def generateGromacsGeometricFiles(
254
+ self,
255
+ path,
256
+ topFile,
257
+ pdbFile,
258
+ pdbFileFormat,
259
+ ligandOnlyTopFile,
260
+ ligandOnlyPdbFile,
261
+ ligandOnlyPdbFileFormat,
262
+ selectionPro,
263
+ selectionLig,
264
+ selectionSol='resname TIP3* or resname SPC* or resname HOH or resname WAT or resname SOL',
265
+ temperature=300.0
266
+ ):
267
+ """generate all the input files for Gromacs Geometric simulation
268
+ This function is based on BFEEGromacs.py
269
+ contributed by Haochuan Chen (yjcoshc_at_mail.nankai.edu.cn)
270
+
271
+ Args:
272
+ path (str): the directory for generation of all the files
273
+ topFile (str): the path of the topology (top) file
274
+ pdbFile (str): the path of the coordinate (pdb) file
275
+ ligandOnlyTopFile (str): the path of the ligand-only topology (top) file
276
+ ligandOnlyPdbFile (str): the path of the ligand-only coordinate (pdb) file
277
+ selectionPro (str): MDAnalysis-style selection of the protein
278
+ selectionLig (str): MDAnalysis-style selection of the ligand
279
+ selectionSol (str, optional): MDAnalysis-style selection of the solvent.
280
+ Defaults to 'resname TIP3* or resname SPC*'.
281
+ temperature (float, optional): Temperature of the simulation. Defaults to 300.0.
282
+
283
+ Raises:
284
+ DirectoryExistError: when {path}/BFEE exists
285
+ """
286
+
287
+ # if the folder already exists, raise an error
288
+ if os.path.exists(f'{path}/BFEE'):
289
+ raise DirectoryExistError('Directory exists')
290
+ os.mkdir(f'{path}/BFEE')
291
+
292
+ # readme file
293
+ with pkg_resources.path(templates_readme, 'Readme_Gromacs_Geometrical.txt') as p:
294
+ shutil.copyfile(p, f'{path}/BFEE/Readme.txt')
295
+
296
+ bfee = BFEEGromacs(
297
+ structureFile=pdbFile,
298
+ topologyFile=topFile,
299
+ ligandOnlyStructureFile=ligandOnlyPdbFile,
300
+ ligandOnlyTopologyFile=ligandOnlyTopFile,
301
+ baseDirectory=f'{path}/BFEE',
302
+ structureFormat=pdbFileFormat,
303
+ ligandOnlyStructureFileFormat=ligandOnlyPdbFileFormat
304
+ )
305
+ bfee.setProteinHeavyAtomsGroup(f'{selectionPro} and not (name H*)')
306
+ bfee.setLigandHeavyAtomsGroup(f'{selectionLig} and not (name H*)')
307
+ bfee.setSolventAtomsGroup(selectionSol)
308
+ bfee.setTemperature(temperature)
309
+ bfee.generate000()
310
+ bfee.generate001()
311
+ bfee.generate002()
312
+ bfee.generate003()
313
+ bfee.generate004()
314
+ bfee.generate005()
315
+ bfee.generate006()
316
+ bfee.generate007()
317
+ bfee.generate008()
318
+
319
+
320
+ def _determineFileType(self, topFile, coorFile):
321
+ """determine the file type of topology and coordinate files
322
+
323
+ Args:
324
+ topFile (str): the path of the topology (psf, parm) file
325
+ coorFile (str): the path of the coordinate (pdb, rst7) file
326
+
327
+ Raises:
328
+ FileTypeUnknownError: if the postfix of topFile is not
329
+ psf, parm, prm7, parm7, prmtop
330
+ or the postfix of coorFile is not
331
+ pdb, coor, rst7, rst, inpcrd
332
+
333
+ Returns:
334
+ tuple of str: (topType, coorType), e.g., (psf, pdb)
335
+ """
336
+
337
+ topPostfix = os.path.splitext(topFile)[-1]
338
+ coorPostfix = os.path.splitext(coorFile)[-1]
339
+
340
+ topType = ''
341
+ coorType = ''
342
+
343
+ if topPostfix == '.psf':
344
+ topType = 'psf'
345
+ elif topPostfix == '.parm' or topPostfix == '.prm7' or topPostfix == '.parm7' or topPostfix == '.prmtop':
346
+ topType = 'parm7'
347
+
348
+ if coorPostfix == '.pdb':
349
+ coorType = 'pdb'
350
+ elif coorPostfix == '.coor':
351
+ coorType = 'namdbin'
352
+ elif coorPostfix == '.rst7' or coorPostfix == '.rst' or coorPostfix == '.inpcrd':
353
+ coorType = 'inpcrd'
354
+
355
+ if topType == '' or coorType == '':
356
+ raise FileTypeUnknownError('File type unknown')
357
+
358
+ return topType, coorType
359
+
360
+ def _makeDirectories(self, path, jobType='geometric', considerRMSDCV=True, useLDDM=False):
361
+ """make directories for BFEE calculation
362
+
363
+ Args:
364
+ path (str): the path for putting BFEE input files into
365
+ jobType (str, optional): geometric or alchemical. Defaults to 'geometric'.
366
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
367
+ useLDDM (bool, optional): whether the LDDM strategy is used. Default to False.
368
+
369
+ Raises:
370
+ DirectoryExistError: if {path}/BFEE exists
371
+ """
372
+
373
+ # if the folder already exists, raise an error
374
+ if os.path.exists(f'{path}/BFEE'):
375
+ raise DirectoryExistError('Directory exists')
376
+ os.mkdir(f'{path}/BFEE')
377
+ os.mkdir(f'{path}/BFEE/000_eq')
378
+ os.mkdir(f'{path}/BFEE/000_eq/output')
379
+ if jobType == 'geometric':
380
+ if considerRMSDCV:
381
+ os.mkdir(f'{path}/BFEE/001_RMSDBound')
382
+ os.mkdir(f'{path}/BFEE/001_RMSDBound/output')
383
+ os.mkdir(f'{path}/BFEE/008_RMSDUnbound')
384
+ os.mkdir(f'{path}/BFEE/008_RMSDUnbound/output')
385
+
386
+ os.mkdir(f'{path}/BFEE/002_EulerTheta')
387
+ os.mkdir(f'{path}/BFEE/003_EulerPhi')
388
+ os.mkdir(f'{path}/BFEE/004_EulerPsi')
389
+ os.mkdir(f'{path}/BFEE/005_PolarTheta')
390
+ os.mkdir(f'{path}/BFEE/006_PolarPhi')
391
+ os.mkdir(f'{path}/BFEE/007_r')
392
+
393
+ os.mkdir(f'{path}/BFEE/002_EulerTheta/output')
394
+ os.mkdir(f'{path}/BFEE/003_EulerPhi/output')
395
+ os.mkdir(f'{path}/BFEE/004_EulerPsi/output')
396
+ os.mkdir(f'{path}/BFEE/005_PolarTheta/output')
397
+ os.mkdir(f'{path}/BFEE/006_PolarPhi/output')
398
+ os.mkdir(f'{path}/BFEE/007_r/output')
399
+
400
+
401
+ if jobType == 'alchemical':
402
+ if considerRMSDCV:
403
+ os.mkdir(f'{path}/BFEE/004_RestraintUnbound')
404
+ os.mkdir(f'{path}/BFEE/004_RestraintUnbound/output')
405
+
406
+ os.mkdir(f'{path}/BFEE/001_MoleculeBound')
407
+ os.mkdir(f'{path}/BFEE/003_MoleculeUnbound')
408
+ os.mkdir(f'{path}/BFEE/001_MoleculeBound/output')
409
+ os.mkdir(f'{path}/BFEE/003_MoleculeUnbound/output')
410
+
411
+ if not useLDDM:
412
+ os.mkdir(f'{path}/BFEE/002_RestraintBound')
413
+ os.mkdir(f'{path}/BFEE/002_RestraintBound/output')
414
+
415
+
416
+
417
+ def _copyFiles(
418
+ self,
419
+ path,
420
+ topFile,
421
+ topType,
422
+ coorFile,
423
+ coorType,
424
+ forceFieldType,
425
+ forceFieldFiles,
426
+ selectionPro,
427
+ selectionLig,
428
+ selectionRef,
429
+ userProvidedPullingTop = '',
430
+ userProvidedPullingCoor = '',
431
+ jobType = 'geometric',
432
+ membraneProtein = False,
433
+ neutralizeLigOnly = 'NaCl',
434
+ vmdPath = '',
435
+ considerRMSDCV = True,
436
+ useLDDM = False,
437
+ LDDMTemperature = 300.0,
438
+ LDDMWindows = 200
439
+ ):
440
+ """copy original and generate necessary topology/structure files
441
+
442
+ Args:
443
+ path (str): the directory for generation of all the files
444
+ topFile (str): the path of the topology (psf, parm) file
445
+ topType (str): the type (psf, parm) of the topology file
446
+ coorFile (str): the path of the coordinate (pdb, rst7) file
447
+ coorType (str): the type (pdb, rst) of the coordinate file
448
+ forceFieldType (str): 'charmm' or 'amber'
449
+ forceFieldFiles (list of str): list of CHARMM force field files
450
+ selectionPro (str): MDAnalysis-style selection of the protein
451
+ selectionLig (str): MDAnalysis-style selection of the ligand
452
+ selectionRef (str): MDAnalysis-style selection of the reference group for pulling simulation
453
+ userProvidedPullingTop (str, optional): user-provided large solvation box for pulling simulation.
454
+ Defaults to ''.
455
+ userProvidedPullingCoor (str, optional): user-provided large solvation box for pulling simulation.
456
+ Defaults to ''.
457
+ jobType (str, optional): 'geometric' or 'alchemical'. Defaults to 'geometric'.
458
+ membraneProtein (bool, optional): whether simulating a membrane protein. Defaults to False.
459
+ neutralizeLigOnly (str or None, optional): 'NaCl', 'KCl', 'CaCl2' or None.
460
+ neutralize the lig-only system using the salt.
461
+ Defaluts to NaCl.
462
+ vmdPath (str, optional): path to vmd, space is forbidden. Defaults to ''.
463
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
464
+ useLDDM (bool, optional): whether the LDDM strategy is used. Default to False.
465
+ LDDMTemperature (float, optional): temperature of LDDM simulation. Default to 300.
466
+ LDDMWindows(int, optional): windows of step 1 of LDDM simulation. Default to 200.
467
+ """
468
+
469
+ # copy force fields
470
+ if forceFieldType == 'charmm':
471
+ for item in forceFieldFiles:
472
+ _, fileName = os.path.split(item)
473
+ shutil.copyfile(item, f'{path}/BFEE/{fileName}')
474
+
475
+ # read the original topology and coordinate file
476
+ fParser = fileParser.fileParser(topFile, coorFile)
477
+
478
+ # check polar angles
479
+ # if theta < 30 or > 150, then rotate 90 degrees to avoid polar angle invarience
480
+ if (fParser.measurePolarAngles(selectionRef, selectionLig)[0] > 150 \
481
+ or fParser.measurePolarAngles(selectionRef, selectionLig)[0] < 30):
482
+ fParser.rotateSystem('x', 90)
483
+
484
+ # normalize/centerize coordinate
485
+ fParser.centerSystem()
486
+
487
+ # write the new topology and structure file
488
+ fParser.saveFile(
489
+ 'all', f'{path}/BFEE/complex.pdb', 'pdb', True,
490
+ f'{path}/BFEE/complex.{topType}'
491
+ )
492
+ # xyz file
493
+ fParser.saveFile(
494
+ 'all', f'{path}/BFEE/complex.xyz', 'xyz'
495
+ )
496
+ # ndx file
497
+ fParser.saveNDX(
498
+ [selectionPro, selectionLig, selectionRef], ['protein', 'ligand', 'reference'],
499
+ f'{path}/BFEE/complex.ndx', True
500
+ )
501
+ # cv definition file
502
+ #shutil.copyfile(f'{sys.path[0]}/scripts/CVs.tcl', f'{path}/BFEE/CVs.tcl')
503
+
504
+ # determine cation and anion
505
+ if neutralizeLigOnly == 'NaCl':
506
+ cation = 'SOD'
507
+ anion = 'CLA'
508
+ elif neutralizeLigOnly == 'KCl':
509
+ cation = 'POT'
510
+ anion = 'CLA'
511
+ elif neutralizeLigOnly == 'CaCl2':
512
+ cation = 'CAL'
513
+ anion = 'CLA'
514
+ else:
515
+ neutralizeLigOnly = None
516
+
517
+ if jobType == 'geometric':
518
+
519
+ # readme file
520
+ with pkg_resources.path(templates_readme, 'Readme_NAMD_Geometrical.txt') as p:
521
+ shutil.copyfile(p, f'{path}/BFEE/Readme.txt')
522
+
523
+ # script to update the center after equilibration
524
+ with pkg_resources.path(templates_namd, 'updateCenters.py') as p:
525
+ shutil.copyfile(p, f'{path}/BFEE/000_eq/000.2_updateCenters.py')
526
+
527
+ # remove protein for step 8
528
+ # this cannot be done in pure python
529
+ if considerRMSDCV:
530
+ if not membraneProtein:
531
+ fParser.saveFile(
532
+ f'not {selectionPro}', f'{path}/BFEE/008_RMSDUnbound/ligandOnly.pdb', 'pdb'
533
+ )
534
+ else:
535
+ # membrane protein
536
+ fParser.saveFile(
537
+ f'{selectionLig}', f'{path}/BFEE/008_RMSDUnbound/ligandOnly.pdb', 'pdb'
538
+ )
539
+ # connect to VMD
540
+ if forceFieldType == 'charmm':
541
+ if not membraneProtein:
542
+ with open( f'{path}/BFEE/008_RMSDUnbound/008.0.1_removeProtein.tcl', 'w') as rScript:
543
+ rScript.write(
544
+ scriptTemplate.removeProteinTemplate.substitute(
545
+ path='../complex', selectionPro=f'{selectionPro}'.replace('segid', 'segname'),
546
+ outputPath=f'./ligandOnly'
547
+ )
548
+ )
549
+ else:
550
+ # membrane protein
551
+ with open( f'{path}/BFEE/008_RMSDUnbound/008.0.1_removeProtein.tcl', 'w') as rScript:
552
+ rScript.write(
553
+ scriptTemplate.removeMemProteinTemplate.substitute(
554
+ path='../complex', selectionLig=f'{selectionLig}'.replace('segid', 'segname'),
555
+ outputPath=f'./ligandOnly'
556
+ )
557
+ )
558
+
559
+ # neutralization
560
+ if neutralizeLigOnly is not None:
561
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.0.2_neutrilize.tcl', 'w') as rScript:
562
+ rScript.write(
563
+ scriptTemplate.neutralizeSystempTemplate.substitute(
564
+ path='./ligandOnly', cationName=cation, anionName=anion,
565
+ extraCommand=''
566
+ )
567
+ )
568
+
569
+ # if vmd path is defined
570
+ # then execute vmd automatically
571
+ if vmdPath != '':
572
+ subprocess.run(
573
+ [vmdPath, '-dispdev', 'text', '-e', f'{path}/BFEE/008_RMSDUnbound/008.0.1_removeProtein.tcl'],
574
+ cwd=f'{path}/BFEE/008_RMSDUnbound'
575
+ )
576
+ if neutralizeLigOnly is not None:
577
+ subprocess.run(
578
+ [vmdPath, '-dispdev', 'text', '-e', f'{path}/BFEE/008_RMSDUnbound/008.0.2_neutrilize.tcl'],
579
+ cwd=f'{path}/BFEE/008_RMSDUnbound'
580
+ )
581
+
582
+ elif forceFieldType == 'amber':
583
+ with open( f'{path}/BFEE/008_RMSDUnbound/008.0.1_removeProtein.cpptraj', 'w') as rScript:
584
+ rScript.write(
585
+ scriptTemplate.removeProteinAmberTemplate.substitute(
586
+ path='../complex',
587
+ residueNum=fParser.getResid(selectionPro),
588
+ outputPath=f'./ligandOnly'
589
+ )
590
+ )
591
+ # xyz and ndx for step 8
592
+ fParserStep8 = fileParser.fileParser(f'{path}/BFEE/008_RMSDUnbound/ligandOnly.pdb')
593
+ if not membraneProtein:
594
+ # otherwise the xyz file will be generated by vmd
595
+ if (vmdPath == '') or (forceFieldType == 'amber'):
596
+ fParserStep8.saveFile('all', f'{path}/BFEE/008_RMSDUnbound/ligandOnly.xyz', 'xyz')
597
+ fParserStep8.saveNDX(
598
+ [selectionLig], ['ligand'], f'{path}/BFEE/008_RMSDUnbound/ligandOnly.ndx', True
599
+ )
600
+
601
+ # add water for step 7
602
+ # this cannot be done in pure python
603
+ # connect to VMD
604
+ if userProvidedPullingTop == '' and userProvidedPullingCoor == '':
605
+ if forceFieldType == 'charmm':
606
+ if not membraneProtein:
607
+ with pkg_resources.path(templates_namd, 'solvate.tcl') as p:
608
+ shutil.copyfile(p, f'{path}/BFEE/007_r/007.0_solvate.tcl')
609
+ else:
610
+ # membrane protein
611
+ with pkg_resources.path(templates_namd, 'solvate_mem.tcl') as p:
612
+ shutil.copyfile(p, f'{path}/BFEE/007_r/007.0_solvate.tcl')
613
+ # if vmd path is defined
614
+ # then execute vmd automatically
615
+ if vmdPath != '':
616
+ subprocess.run(
617
+ [vmdPath, '-dispdev', 'text', '-e', f'{path}/BFEE/007_r/007.0_solvate.tcl'],
618
+ cwd=f'{path}/BFEE/007_r'
619
+ )
620
+ else:
621
+ # copy the user-provided large box
622
+ fParserStep7 = fileParser.fileParser(userProvidedPullingTop, userProvidedPullingCoor)
623
+
624
+ # check polar angles
625
+ # if theta < 30 or > 150, then rotate 90 degrees to avoid polar angle invarience
626
+ if (fParserStep7.measurePolarAngles(selectionRef, selectionLig)[0] > 150 \
627
+ or fParserStep7.measurePolarAngles(selectionRef, selectionLig)[0] < 30):
628
+ fParserStep7.rotateSystem('x', 90)
629
+ fParserStep7.centerSystem()
630
+
631
+ fParserStep7.saveFile(
632
+ 'all', f'{path}/BFEE/007_r/complex_largeBox.pdb', 'pdb',
633
+ True, f'{path}/BFEE/007_r/complex_largeBox.{topType}'
634
+ )
635
+
636
+ fParserStep7.saveFile(
637
+ 'all', f'{path}/BFEE/007_r/complex_largeBox.xyz', 'xyz'
638
+ )
639
+
640
+ if jobType == 'alchemical':
641
+
642
+ # readme file
643
+ if not useLDDM:
644
+ with pkg_resources.path(templates_readme, 'Readme_NAMD_Alchemical.txt') as p:
645
+ shutil.copyfile(p, f'{path}/BFEE/Readme.txt')
646
+ # TODO: add LDDM readme
647
+
648
+ # script to update the center after equilibration
649
+ with pkg_resources.path(templates_namd, 'updateCenters.py') as p:
650
+ shutil.copyfile(p, f'{path}/BFEE/000_eq/000.3_updateCenters.py')
651
+
652
+ # fep file
653
+ fParser.setBeta('all', 0)
654
+ fParser.setBeta(selectionLig, 1)
655
+ fParser.saveFile(
656
+ 'all', f'{path}/BFEE/fep.pdb', 'pdb'
657
+ )
658
+ with pkg_resources.path(templates_namd, 'fep.tcl') as p:
659
+ shutil.copyfile(p, f'{path}/BFEE/fep.tcl')
660
+
661
+ if useLDDM:
662
+ with pkg_resources.path(templates_namd, 'fep_lddm.tcl') as p:
663
+ shutil.copyfile(p, f'{path}/BFEE/001_MoleculeBound/fep_lddm.tcl')
664
+
665
+ if not membraneProtein:
666
+ # otherwise the these files will be generated by vmd
667
+ fParser.saveFile(
668
+ f'not {selectionPro}', f'{path}/BFEE/ligandOnly.pdb', 'pdb'
669
+ )
670
+ fParser.saveFile(
671
+ f'not {selectionPro}', f'{path}/BFEE/fep_ligandOnly.pdb', 'pdb'
672
+ )
673
+ # remove protein for the unbound state
674
+ if forceFieldType == 'charmm':
675
+ if not membraneProtein:
676
+ with open(f'{path}/BFEE/002.3.1_removeProtein.tcl', 'w') as rScript:
677
+ rScript.write(
678
+ scriptTemplate.removeProteinTemplate.substitute(
679
+ path='./complex', selectionPro=f'{selectionPro}'.replace('segid', 'segname'),
680
+ outputPath=f'./ligandOnly'
681
+ )
682
+ )
683
+ else:
684
+ # membrane protein
685
+ # fake ligandOnly.pdb, only used to generate ndx
686
+ # putting this here to guarantee ligandOnly.pdb is currected overwritten
687
+ fParser.saveFile(
688
+ f'{selectionLig}', f'{path}/BFEE/ligandOnly.pdb', 'pdb'
689
+ )
690
+ with open( f'{path}/BFEE/002.3.1_removeProtein.tcl', 'w') as rScript:
691
+ rScript.write(
692
+ scriptTemplate.removeMemProteinFepTemplate.substitute(
693
+ path='./complex', selectionLig=f'{selectionLig}'.replace('segid', 'segname'),
694
+ outputPath=f'./ligandOnly', outputFepPath=f'./fep_ligandOnly'
695
+ )
696
+ )
697
+
698
+ # neutralization
699
+ if neutralizeLigOnly is not None:
700
+ with open(f'{path}/BFEE/002.3.2_neutrilize.tcl', 'w') as rScript:
701
+ rScript.write(
702
+ scriptTemplate.neutralizeSystempTemplate.substitute(
703
+ path='./ligandOnly', cationName=cation, anionName=anion,
704
+ extraCommand='$aa writepdb fep_ligandOnly.pdb'
705
+ )
706
+ )
707
+
708
+ # if vmd path is defined
709
+ # then execute vmd automatically
710
+ if vmdPath != '':
711
+ subprocess.run(
712
+ [vmdPath, '-dispdev', 'text', '-e', f'{path}/BFEE/002.3.1_removeProtein.tcl'],
713
+ cwd=f'{path}/BFEE'
714
+ )
715
+ if neutralizeLigOnly is not None:
716
+ subprocess.run(
717
+ [vmdPath, '-dispdev', 'text', '-e', f'{path}/BFEE/002.3.2_neutrilize.tcl'],
718
+ cwd=f'{path}/BFEE'
719
+ )
720
+ elif forceFieldType == 'amber':
721
+ with open( f'{path}/BFEE/002.3.1_removeProtein.cpptraj', 'w') as rScript:
722
+ rScript.write(
723
+ scriptTemplate.removeProteinAmberTemplate.substitute(
724
+ path='./complex',
725
+ residueNum=fParser.getResid(selectionPro),
726
+ outputPath=f'./ligandOnly'
727
+ )
728
+ )
729
+
730
+ # xyz and ndx
731
+ fParserLigandOnly = fileParser.fileParser( f'{path}/BFEE/ligandOnly.pdb')
732
+ if not membraneProtein:
733
+ # otherwise the xyz file will be generated by vmd
734
+ if (vmdPath == '') or (forceFieldType == 'amber'):
735
+ fParserLigandOnly.saveFile('all', f'{path}/BFEE/ligandOnly.xyz', 'xyz')
736
+ fParserLigandOnly.saveNDX(
737
+ [selectionLig], ['ligand'], f'{path}/BFEE/ligandOnly.ndx', True
738
+ )
739
+
740
+ # LDDM script for generating files
741
+ if useLDDM:
742
+ with open(f'{path}/BFEE/001_MoleculeBound/000_updateForceConstant.py', 'w') as rScript:
743
+ rScript.write(
744
+ scriptTemplate.genarateLDDMFilesTemplate.substitute(
745
+ temperature=LDDMTemperature, windows=LDDMWindows
746
+ )
747
+ )
748
+
749
+ def _makeGromacsTopGro(
750
+ self,
751
+ path,
752
+ forceFieldType,
753
+ forceFieldFiles,
754
+ jobType = 'geometric',
755
+ vmdPath = '',
756
+ considerRMSDCV = True
757
+ ):
758
+ """generate topology and coordinate files from CHARMM/Amber files for gromacs simulation
759
+
760
+ Args:
761
+ path (str): the root directory of simulation files
762
+ forceFieldType (str): 'charmm' or 'amber'
763
+ forceFieldFiles (list of str): list of CHARMM force field files
764
+ jobType (str, optional): 'geometric' or 'alchemical'. Defaults to 'geometric'.
765
+ vmdPath (str, optional): path to vmd, space is forbidden. Defaults to ''.
766
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
767
+ """
768
+
769
+ if forceFieldType == 'charmm':
770
+ topType = 'psf'
771
+ elif forceFieldType == 'amber':
772
+ topType = 'parm7'
773
+ coorType = 'pdb'
774
+
775
+ # read the original topology and coordinate file
776
+ fParser = fileParser.fileParser(f'{path}/BFEE/complex.{topType}', f'{path}/BFEE/complex.{coorType}')
777
+ # pbc
778
+ pbc = fParser.measurePBC()
779
+
780
+ # gromacs assume the center of system is at (x/2, y/2, z/2)
781
+ fParser.moveSystem(-pbc[1] + pbc[0] / 2)
782
+ fParser.saveFile('all', f'{path}/BFEE/complex.{coorType}', coorType)
783
+
784
+ if forceFieldType == 'charmm':
785
+ fileParser.charmmToGromacs(
786
+ f'{path}/BFEE/complex.psf',
787
+ f'{path}/BFEE/complex.pdb',
788
+ forceFieldFiles,
789
+ pbc[0],
790
+ f'{path}/BFEE/complex_gmx'
791
+ )
792
+ elif forceFieldType == 'amber':
793
+ fileParser.amberToGromacs(
794
+ f'{path}/BFEE/complex.parm7', f'{path}/BFEE/complex.pdb', pbc[0], f'{path}/BFEE/complex_gmx'
795
+ )
796
+
797
+
798
+ if forceFieldType == 'charmm':
799
+ if vmdPath != '':
800
+ fParser_7 = fileParser.fileParser(
801
+ f'{path}/BFEE/007_r/complex_largeBox.psf',
802
+ f'{path}/BFEE/007_r/complex_largeBox.pdb'
803
+ )
804
+ pbc_7 = fParser_7.measurePBC()
805
+ fParser_7.moveSystem(-pbc_7[1] + pbc_7[0] / 2)
806
+ fParser_7.saveFile('all', f'{path}/BFEE/007_r/complex_largeBox.pdb', 'pdb')
807
+
808
+ if considerRMSDCV:
809
+ fParser_8 = fileParser.fileParser(
810
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly.psf',
811
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly.pdb'
812
+ )
813
+ pbc_8 = fParser_8.measurePBC()
814
+ fParser_8.moveSystem(-pbc_8[1] + pbc_8[0] / 2)
815
+ fParser_8.saveFile('all', f'{path}/BFEE/008_RMSDUnbound/ligandOnly.pdb', 'pdb')
816
+
817
+ fileParser.charmmToGromacs(
818
+ f'{path}/BFEE/007_r/complex_largeBox.psf',
819
+ f'{path}/BFEE/007_r/complex_largeBox.pdb',
820
+ forceFieldFiles,
821
+ pbc_7[0],
822
+ f'{path}/BFEE/007_r/complex_largeBox_gmx'
823
+ )
824
+
825
+ if considerRMSDCV:
826
+ fileParser.charmmToGromacs(
827
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly.psf',
828
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly.pdb',
829
+ forceFieldFiles,
830
+ pbc_8[0],
831
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly_gmx'
832
+ )
833
+ else:
834
+ with open( f'{path}/BFEE/007_r/007.0.2_genGromacsTop.py', 'w') as rScript:
835
+ rScript.write(
836
+ scriptTemplate.charmmToGromacsTemplate(
837
+ inputPrefix='./complex_largeBox',
838
+ forceFieldList=forceFieldFiles,
839
+ )
840
+ )
841
+
842
+ if considerRMSDCV:
843
+ with open( f'{path}/BFEE/008_RMSDUnbound/008.0.3_genGromacsTop.py', 'w') as rScript:
844
+ rScript.write(
845
+ scriptTemplate.charmmToGromacsTemplate(
846
+ inputPrefix='./ligandOnly',
847
+ forceFieldList=forceFieldFiles,
848
+ )
849
+ )
850
+
851
+ if forceFieldType == 'amber':
852
+
853
+ fParser_7 = fileParser.fileParser(
854
+ f'{path}/BFEE/007_r/complex_largeBox.parm7',
855
+ f'{path}/BFEE/007_r/complex_largeBox.pdb'
856
+ )
857
+ pbc_7 = fParser_7.measurePBC()
858
+ fParser_7.moveSystem(-pbc_7[1] + pbc_7[0] / 2)
859
+ fParser_7.saveFile('all', f'{path}/BFEE/007_r/complex_largeBox.pdb', 'pdb')
860
+
861
+ fileParser.amberToGromacs(
862
+ f'{path}/BFEE/007_r/complex_largeBox.parm7',
863
+ f'{path}/BFEE/007_r/complex_largeBox.pdb',
864
+ pbc_7[0],
865
+ f'{path}/BFEE/007_r/complex_largeBox_gmx'
866
+ )
867
+
868
+ if considerRMSDCV:
869
+ with open( f'{path}/BFEE/008_RMSDUnbound/008.0.2_genGromacsTop.py', 'w') as rScript:
870
+ rScript.write(
871
+ scriptTemplate.amberToGromacsTemplate.substitute(
872
+ inputPrefix='./ligandOnly'
873
+ )
874
+ )
875
+
876
+
877
+ def _generateAlchemicalNAMDConfig(
878
+ self,
879
+ path,
880
+ forceFieldType,
881
+ forceFields,
882
+ temperature,
883
+ stratification = [1,1,1,1],
884
+ doubleWide = False,
885
+ minBeforeSample = False,
886
+ membraneProtein = False,
887
+ OPLSMixingRule = False,
888
+ considerRMSDCV = True,
889
+ CUDASOAIntegrator = False,
890
+ timestep = 2.0,
891
+ reEq = False,
892
+ useLDDM = False,
893
+ useLambdaABF = False
894
+ ):
895
+ """generate NAMD config fils for the alchemical route
896
+
897
+ Args:
898
+ path (str): the directory for generation of all the files
899
+ forceFieldType (str): 'charmm' or 'amber'
900
+ forceFields (list of str): list of CHARMM force field files
901
+ temperature (float): temperature of the simulation
902
+ stratification (list of int, 4, optional): number of windows for each simulation.
903
+ Defaults to [1,1,1,1].
904
+ doubleWide (bool, optional): whether double-wide simulations are carried out.
905
+ Defaults to False.
906
+ minBeforeSample (bool, optional): minimization before sampling in each FEP window.
907
+ Defaults to False.
908
+ membraneProtein (bool, optional): whether simulating a membrane protein.
909
+ Defaults to False.
910
+ OPLSMixingRule (bool, optional): whether use the OPLS mixing rules. Defaults to False.
911
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
912
+ CUDASOAIntegrator (bool, optional): Whether CUDASOA integrator is used. Default to False.
913
+ timestep (float, optional): timestep of the simulation. Default to 2.0.
914
+ reEq (bool, optional): re-equilibration after histogram. Default to False.
915
+ useLDDM (bool, optional): whether the LDDM strategy is used. Default to False.
916
+ useLambdaABF (bool, optional): whether the WTM-LambdaABF method is used instead of FEP. Default to False.
917
+ """
918
+
919
+ if forceFieldType == 'charmm':
920
+ topType = 'psf'
921
+ elif forceFieldType == 'amber':
922
+ topType = 'parm7'
923
+ coorType = 'pdb'
924
+
925
+ # read the original topology and coordinate file
926
+ fParser = fileParser.fileParser(f'{path}/BFEE/complex.{topType}', f'{path}/BFEE/complex.{coorType}')
927
+ # pbc
928
+ pbc = fParser.measurePBC()
929
+
930
+ # read the ligandOnly topology and coordinate file
931
+ if os.path.exists(f'{path}/BFEE/ligandOnly.{topType}'):
932
+ fParserLig = fileParser.fileParser(f'{path}/BFEE/ligandOnly.{topType}', f'{path}/BFEE/ligandOnly.{coorType}')
933
+ # pbc
934
+ pbcLig = fParserLig.measurePBC()
935
+ else:
936
+ pbcLig = pbc
937
+
938
+ # 000_eq
939
+ with open(f'{path}/BFEE/000_eq/000.1_eq.conf', 'w') as namdConfig:
940
+ namdConfig.write(
941
+ self.cTemplate.namdConfigTemplate(
942
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
943
+ '', '', '', pbc,
944
+ 'output/eq', temperature, 50000000, 'colvars.in', '', membraneProtein=membraneProtein,
945
+ OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
946
+ )
947
+ )
948
+
949
+ if reEq:
950
+ with open(f'{path}/BFEE/000_eq/000.1_eq2_re-eq.conf', 'w') as namdConfig:
951
+ namdConfig.write(
952
+ self.cTemplate.namdConfigTemplate(
953
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
954
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc', '',
955
+ 'output/eq2', temperature, 50000000, 'colvars2.in', '', membraneProtein=membraneProtein,
956
+ OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
957
+ )
958
+ )
959
+
960
+ with open(f'{path}/BFEE/000_eq/000.2_eq_ligandOnly.conf', 'w') as namdConfig:
961
+ namdConfig.write(
962
+ self.cTemplate.namdConfigTemplate(
963
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
964
+ '', '', '', pbcLig,
965
+ 'output/eq_ligandOnly', temperature, 10000000, 'colvars_ligandOnly.in',
966
+ '', OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator,
967
+ timestep=timestep
968
+ )
969
+ )
970
+
971
+ # 001_MoleculeBound
972
+ if (not useLDDM) and (not useLambdaABF):
973
+ with open(f'{path}/BFEE/001_MoleculeBound/001.2_fep_forward.conf', 'w') as namdConfig:
974
+ namdConfig.write(
975
+ self.cTemplate.namdConfigTemplate(
976
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
977
+ f'output/fep_backward.coor', f'output/fep_backward.vel', f'output/fep_backward.xsc', '',
978
+ 'output/fep_forward', temperature, 0, 'colvars.in', '', '', '../fep.pdb',
979
+ stratification[0], True, False, minBeforeSample, membraneProtein=membraneProtein,
980
+ OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator,
981
+ timestep=timestep
982
+ )
983
+ )
984
+ with open(f'{path}/BFEE/001_MoleculeBound/001.1_fep_backward.conf', 'w') as namdConfig:
985
+ namdConfig.write(
986
+ self.cTemplate.namdConfigTemplate(
987
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
988
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc', '',
989
+ 'output/fep_backward', temperature, 0, 'colvars.in', '', '', '../fep.pdb',
990
+ stratification[0], False, False, minBeforeSample, membraneProtein=membraneProtein,
991
+ OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator,
992
+ timestep=timestep
993
+ )
994
+ )
995
+
996
+ if doubleWide and (not useLambdaABF):
997
+ with open(f'{path}/BFEE/001_MoleculeBound/001_fep_doubleWide.conf', 'w') as namdConfig:
998
+ namdConfig.write(
999
+ self.cTemplate.namdConfigTemplate(
1000
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1001
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc', '',
1002
+ 'output/fep_doubleWide', temperature, 0, 'colvars.in', '', '', '../fep.pdb',
1003
+ stratification[0], False, True, membraneProtein=membraneProtein,
1004
+ OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator,
1005
+ timestep=timestep, LDDMStep1=useLDDM
1006
+ )
1007
+ )
1008
+
1009
+ if useLambdaABF:
1010
+ with open(f'{path}/BFEE/001_MoleculeBound/001_lambdaABF.conf', 'w') as namdConfig:
1011
+ namdConfig.write(
1012
+ self.cTemplate.namdConfigTemplate(
1013
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1014
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc', '',
1015
+ 'output/lambdaABF', temperature, 100000000, 'colvars.in', '', '', '../fep.pdb',
1016
+ stratification[0], False, False, minBeforeSample, membraneProtein=membraneProtein,
1017
+ OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator,
1018
+ timestep=timestep, lambdaABF=useLambdaABF
1019
+ )
1020
+ )
1021
+
1022
+
1023
+ # 002_RestraintBound
1024
+ if not useLDDM:
1025
+ with open(f'{path}/BFEE/002_RestraintBound/002.2_ti_forward.conf', 'w') as namdConfig:
1026
+ namdConfig.write(
1027
+ self.cTemplate.namdConfigTemplate(
1028
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1029
+ f'output/ti_backward.coor', f'output/ti_backward.vel', f'output/ti_backward.xsc', '',
1030
+ 'output/ti_forward', temperature, f'{500000*(stratification[1]+1)}', 'colvars_forward.in',
1031
+ '', membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1032
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1033
+ )
1034
+ )
1035
+ with open(f'{path}/BFEE/002_RestraintBound/002.1_ti_backward.conf', 'w') as namdConfig:
1036
+ namdConfig.write(
1037
+ self.cTemplate.namdConfigTemplate(
1038
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1039
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc', '',
1040
+ 'output/ti_backward', temperature, f'{500000*(stratification[1]+1)}', 'colvars_backward.in',
1041
+ '', membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1042
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1043
+ )
1044
+ )
1045
+
1046
+ # 003_MoleculeUnbound
1047
+ if considerRMSDCV or useLambdaABF:
1048
+ step3ColvarsConfig = 'colvars.in'
1049
+ else:
1050
+ step3ColvarsConfig = ''
1051
+
1052
+ if not useLDDM and (not useLambdaABF):
1053
+ with open(f'{path}/BFEE/003_MoleculeUnbound/003.2_fep_forward.conf', 'w') as namdConfig:
1054
+ namdConfig.write(
1055
+ self.cTemplate.namdConfigTemplate(
1056
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
1057
+ f'output/fep_backward.coor', f'output/fep_backward.vel',
1058
+ f'output/fep_backward.xsc', '',
1059
+ 'output/fep_forward', temperature, 0, step3ColvarsConfig, '', '', '../fep_ligandOnly.pdb',
1060
+ stratification[2], True, False, minBeforeSample, OPLSMixingRule=OPLSMixingRule,
1061
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1062
+ )
1063
+ )
1064
+ with open(f'{path}/BFEE/003_MoleculeUnbound/003.1_fep_backward.conf', 'w') as namdConfig:
1065
+ namdConfig.write(
1066
+ self.cTemplate.namdConfigTemplate(
1067
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
1068
+ f'../000_eq/output/eq_ligandOnly.coor', f'../000_eq/output/eq_ligandOnly.vel',
1069
+ f'../000_eq/output/eq_ligandOnly.xsc', '',
1070
+ 'output/fep_backward', temperature, 0, step3ColvarsConfig, '', '', '../fep_ligandOnly.pdb',
1071
+ stratification[2], False, False, minBeforeSample, OPLSMixingRule=OPLSMixingRule,
1072
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1073
+ )
1074
+ )
1075
+
1076
+ if doubleWide and (not useLambdaABF):
1077
+ with open(f'{path}/BFEE/003_MoleculeUnbound/003_fep_doubleWide.conf', 'w') as namdConfig:
1078
+ namdConfig.write(
1079
+ self.cTemplate.namdConfigTemplate(
1080
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
1081
+ f'../000_eq/output/eq_ligandOnly.coor', f'../000_eq/output/eq_ligandOnly.vel',
1082
+ f'../000_eq/output/eq_ligandOnly.xsc', '',
1083
+ 'output/fep_doubleWide', temperature, 0, step3ColvarsConfig, '', '', '../fep_ligandOnly.pdb',
1084
+ stratification[2], False, True, OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator,
1085
+ timestep=timestep
1086
+ )
1087
+ )
1088
+
1089
+ if useLambdaABF:
1090
+ with open(f'{path}/BFEE/003_MoleculeUnbound/003_lambdaABF.conf', 'w') as namdConfig:
1091
+ namdConfig.write(
1092
+ self.cTemplate.namdConfigTemplate(
1093
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
1094
+ f'../000_eq/output/eq_ligandOnly.coor', f'../000_eq/output/eq_ligandOnly.vel',
1095
+ f'../000_eq/output/eq_ligandOnly.xsc', '',
1096
+ 'output/lambdaABF', temperature, 100000000, step3ColvarsConfig, '', '', '../fep_ligandOnly.pdb',
1097
+ stratification[2], False, False, minBeforeSample, OPLSMixingRule=OPLSMixingRule,
1098
+ CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep, lambdaABF=useLambdaABF
1099
+ )
1100
+ )
1101
+
1102
+
1103
+ if considerRMSDCV:
1104
+ # 004_RestraintUnbound
1105
+ with open(f'{path}/BFEE/004_RestraintUnbound/004.2_ti_forward.conf', 'w') as namdConfig:
1106
+ namdConfig.write(
1107
+ self.cTemplate.namdConfigTemplate(
1108
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
1109
+ f'output/ti_backward.coor', f'output/ti_backward.vel',
1110
+ f'output/ti_backward.xsc', '',
1111
+ 'output/ti_forward', temperature, f'{500000*(stratification[3]+1)}', 'colvars_forward.in',
1112
+ '', OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1113
+ )
1114
+ )
1115
+ with open(f'{path}/BFEE/004_RestraintUnbound/004.1_ti_backward.conf', 'w') as namdConfig:
1116
+ namdConfig.write(
1117
+ self.cTemplate.namdConfigTemplate(
1118
+ forceFieldType, forceFields, f'../ligandOnly.{topType}', f'../ligandOnly.pdb',
1119
+ f'../000_eq/output/eq_ligandOnly.coor', f'../000_eq/output/eq_ligandOnly.vel',
1120
+ f'../000_eq/output/eq_ligandOnly.xsc', '',
1121
+ 'output/ti_backward', temperature, f'{500000*(stratification[3]+1)}', 'colvars_backward.in',
1122
+ '', OPLSMixingRule=OPLSMixingRule, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1123
+ )
1124
+ )
1125
+
1126
+ def _generateAlchemicalColvarsConfig(
1127
+ self, path, topType, coorType, selectionPro, selectionLig, selectionRef,
1128
+ stratification=[1,1,1,1], pinDownPro=True, useOldCv=True, considerRMSDCV=True,
1129
+ reEq = False, useLDDM = False, useLambdaABF = False
1130
+ ):
1131
+ """generate Colvars config fils for geometric route
1132
+
1133
+ Args:
1134
+ path (str): the directory for generation of all the files
1135
+ topType (str): the type (psf, parm) of the topology file
1136
+ coorType (str): the type (pdb, rst) of the topology file
1137
+ selectionPro (str): MDAnalysis-style selection of the protein
1138
+ selectionLig (str): MDAnalysis-style selection of the ligand
1139
+ selectionRef (str): MDAnalysis-style selection of the reference group for pulling simulation
1140
+ stratification (list of int, 4, optional): number of windows for each simulation.
1141
+ Defaults to [1,1,1,1].
1142
+ pinDownPro (bool, optinal): Whether pinning down the protein. Defaults to True.
1143
+ useOldCv (bool, optional): whether used old, custom-function-based cv. Defaults to True.
1144
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
1145
+ reEq (bool, optional): re-equilibration after histogram. Default to False.
1146
+ useLDDM (bool, optional): whether the LDDM strategy is used. Default to False.
1147
+ useLambdaABF (bool, optional): whether the WTM-LambdaABF method is used instead of FEP. Default to False.
1148
+ """
1149
+
1150
+ assert(len(stratification) == 4)
1151
+
1152
+ # read the original topology and coordinate file
1153
+ fParser = fileParser.fileParser(f'{path}/BFEE/complex.{topType}', f'{path}/BFEE/complex.{coorType}')
1154
+ center = fParser.measureCenter(selectionPro)
1155
+ polarAngles = fParser.measurePolarAngles(selectionRef, selectionLig)
1156
+ distance = fParser.measureDistance(selectionRef, selectionLig)
1157
+
1158
+ # 000_eq
1159
+ with open(f'{path}/BFEE/000_eq/colvars.in', 'w') as colvarsConfig:
1160
+ colvarsConfig.write(
1161
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
1162
+ )
1163
+ colvarsConfig.write(
1164
+ self.cTemplate.cvRMSDTemplate(
1165
+ True, 0, 10, '../complex.xyz',
1166
+ extendedLagrangian = False
1167
+ )
1168
+ )
1169
+ colvarsConfig.write(
1170
+ self.cTemplate.cvAngleTemplate(
1171
+ True, -90, 90, 'eulerTheta', '../complex.xyz', useOldCv,
1172
+ extendedLagrangian = False
1173
+ )
1174
+ )
1175
+ colvarsConfig.write(
1176
+ self.cTemplate.cvAngleTemplate(
1177
+ True, -180, 180, 'eulerPhi', '../complex.xyz', useOldCv,
1178
+ extendedLagrangian = False
1179
+ )
1180
+ )
1181
+ colvarsConfig.write(
1182
+ self.cTemplate.cvAngleTemplate(
1183
+ True, -180, 180, 'eulerPsi', '../complex.xyz', useOldCv,
1184
+ extendedLagrangian = False
1185
+ )
1186
+ )
1187
+ colvarsConfig.write(
1188
+ self.cTemplate.cvAngleTemplate(
1189
+ True, 0, 180, 'polarTheta', '../complex.xyz', useOldCv,
1190
+ extendedLagrangian = False
1191
+ )
1192
+ )
1193
+ colvarsConfig.write(
1194
+ self.cTemplate.cvAngleTemplate(
1195
+ True, -180, 180, 'polarPhi', '../complex.xyz', useOldCv,
1196
+ extendedLagrangian = False
1197
+ )
1198
+ )
1199
+ colvarsConfig.write(
1200
+ self.cTemplate.cvRTemplate(
1201
+ True, (distance - 5 if distance - 5 > 0 else 0),
1202
+ distance + 22, extendedLagrangian = False
1203
+ )
1204
+ )
1205
+ colvarsConfig.write(
1206
+ self.cTemplate.cvHistogramTemplate('RMSD')
1207
+ )
1208
+ colvarsConfig.write(
1209
+ self.cTemplate.cvHistogramTemplate('eulerTheta')
1210
+ )
1211
+ colvarsConfig.write(
1212
+ self.cTemplate.cvHistogramTemplate('eulerPhi')
1213
+ )
1214
+ colvarsConfig.write(
1215
+ self.cTemplate.cvHistogramTemplate('eulerPsi')
1216
+ )
1217
+ colvarsConfig.write(
1218
+ self.cTemplate.cvHistogramTemplate('polarTheta')
1219
+ )
1220
+ colvarsConfig.write(
1221
+ self.cTemplate.cvHistogramTemplate('polarPhi')
1222
+ )
1223
+ colvarsConfig.write(
1224
+ self.cTemplate.cvHistogramTemplate('r')
1225
+ )
1226
+ colvarsConfig.write(
1227
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz')
1228
+ )
1229
+
1230
+ if reEq:
1231
+ with open(f'{path}/BFEE/000_eq/colvars2.in', 'w') as colvarsConfig:
1232
+ colvarsConfig.write(
1233
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
1234
+ )
1235
+ if considerRMSDCV:
1236
+ colvarsConfig.write(
1237
+ self.cTemplate.cvRMSDTemplate(
1238
+ False, '', '', '../complex.xyz',
1239
+ extendedLagrangian = False
1240
+ )
1241
+ )
1242
+ colvarsConfig.write(
1243
+ self.cTemplate.cvAngleTemplate(
1244
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
1245
+ extendedLagrangian = False
1246
+ )
1247
+ )
1248
+ colvarsConfig.write(
1249
+ self.cTemplate.cvAngleTemplate(
1250
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
1251
+ extendedLagrangian = False
1252
+ )
1253
+ )
1254
+ colvarsConfig.write(
1255
+ self.cTemplate.cvAngleTemplate(
1256
+ False, 0, 0, 'eulerPsi', '../complex.xyz', useOldCv,
1257
+ extendedLagrangian = False
1258
+ )
1259
+ )
1260
+ colvarsConfig.write(
1261
+ self.cTemplate.cvAngleTemplate(
1262
+ False, 0, 0, 'polarTheta', '../complex.xyz', useOldCv,
1263
+ extendedLagrangian = False
1264
+ )
1265
+ )
1266
+ colvarsConfig.write(
1267
+ self.cTemplate.cvAngleTemplate(
1268
+ False, 0, 0, 'polarPhi', '../complex.xyz', useOldCv,
1269
+ extendedLagrangian = False
1270
+ )
1271
+ )
1272
+ colvarsConfig.write(
1273
+ self.cTemplate.cvRTemplate(
1274
+ False, 0, 0, extendedLagrangian = False
1275
+ )
1276
+ )
1277
+ if considerRMSDCV:
1278
+ colvarsConfig.write(
1279
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0)
1280
+ )
1281
+ colvarsConfig.write(
1282
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0)
1283
+ )
1284
+ colvarsConfig.write(
1285
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0)
1286
+ )
1287
+ colvarsConfig.write(
1288
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0.1, 0)
1289
+ )
1290
+ colvarsConfig.write(
1291
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0.1, polarAngles[0])
1292
+ )
1293
+ colvarsConfig.write(
1294
+ self.cTemplate.cvHarmonicTemplate('polarPhi', 0.1, polarAngles[1])
1295
+ )
1296
+ colvarsConfig.write(
1297
+ self.cTemplate.cvHarmonicTemplate('r', 10, distance)
1298
+ )
1299
+ if pinDownPro:
1300
+ colvarsConfig.write(
1301
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz')
1302
+ )
1303
+
1304
+ with open(f'{path}/BFEE/000_eq/colvars_ligandOnly.in', 'w') as colvarsConfig:
1305
+ colvarsConfig.write(
1306
+ self.cTemplate.cvHeadTemplate('../ligandOnly.ndx')
1307
+ )
1308
+ colvarsConfig.write(
1309
+ self.cTemplate.cvRMSDTemplate(
1310
+ False, '', '', '../ligandOnly.xyz',
1311
+ extendedLagrangian = False
1312
+ )
1313
+ )
1314
+ if considerRMSDCV:
1315
+ colvarsConfig.write(
1316
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0)
1317
+ )
1318
+
1319
+ # 001_MoleculeBound
1320
+ with open(f'{path}/BFEE/001_MoleculeBound/colvars.in', 'w') as colvarsConfig:
1321
+ colvarsConfig.write(
1322
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
1323
+ )
1324
+ if considerRMSDCV:
1325
+ colvarsConfig.write(
1326
+ self.cTemplate.cvRMSDTemplate(
1327
+ False, '', '', '../complex.xyz',
1328
+ extendedLagrangian = False
1329
+ )
1330
+ )
1331
+ colvarsConfig.write(
1332
+ self.cTemplate.cvAngleTemplate(
1333
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
1334
+ extendedLagrangian = False
1335
+ )
1336
+ )
1337
+ colvarsConfig.write(
1338
+ self.cTemplate.cvAngleTemplate(
1339
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
1340
+ extendedLagrangian = False
1341
+ )
1342
+ )
1343
+ colvarsConfig.write(
1344
+ self.cTemplate.cvAngleTemplate(
1345
+ False, 0, 0, 'eulerPsi', '../complex.xyz', useOldCv,
1346
+ extendedLagrangian = False
1347
+ )
1348
+ )
1349
+ colvarsConfig.write(
1350
+ self.cTemplate.cvAngleTemplate(
1351
+ False, 0, 0, 'polarTheta', '../complex.xyz', useOldCv,
1352
+ extendedLagrangian = False
1353
+ )
1354
+ )
1355
+ colvarsConfig.write(
1356
+ self.cTemplate.cvAngleTemplate(
1357
+ False, 0, 0, 'polarPhi', '../complex.xyz', useOldCv,
1358
+ extendedLagrangian = False
1359
+ )
1360
+ )
1361
+ colvarsConfig.write(
1362
+ self.cTemplate.cvRTemplate(
1363
+ False, 0, 0, extendedLagrangian = False
1364
+ )
1365
+ )
1366
+ if considerRMSDCV:
1367
+ colvarsConfig.write(
1368
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0)
1369
+ )
1370
+ colvarsConfig.write(
1371
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0)
1372
+ )
1373
+ colvarsConfig.write(
1374
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0)
1375
+ )
1376
+ colvarsConfig.write(
1377
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0.1, 0)
1378
+ )
1379
+ colvarsConfig.write(
1380
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0.1, polarAngles[0])
1381
+ )
1382
+ colvarsConfig.write(
1383
+ self.cTemplate.cvHarmonicTemplate('polarPhi', 0.1, polarAngles[1])
1384
+ )
1385
+ colvarsConfig.write(
1386
+ self.cTemplate.cvHarmonicTemplate('r', 10, distance)
1387
+ )
1388
+ if pinDownPro:
1389
+ colvarsConfig.write(
1390
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz')
1391
+ )
1392
+ if useLambdaABF:
1393
+ colvarsConfig.write(
1394
+ self.cTemplate.cvLambdaTemplate(stratification[0])
1395
+ )
1396
+ colvarsConfig.write(
1397
+ self.cTemplate.cvABFTemplate('l', unit = 'namd', czar = False) # currently only NAMD supports WTM-lambdaABF
1398
+ )
1399
+
1400
+ # 002_RestraintBound
1401
+ if not useLDDM:
1402
+ with open(f'{path}/BFEE/002_RestraintBound/colvars_forward.in', 'w') as colvarsConfig:
1403
+ colvarsConfig.write(
1404
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
1405
+ )
1406
+ if considerRMSDCV:
1407
+ colvarsConfig.write(
1408
+ self.cTemplate.cvRMSDTemplate(
1409
+ False, '', '', '../complex.xyz',
1410
+ extendedLagrangian = False
1411
+ )
1412
+ )
1413
+ colvarsConfig.write(
1414
+ self.cTemplate.cvAngleTemplate(
1415
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
1416
+ extendedLagrangian = False
1417
+ )
1418
+ )
1419
+ colvarsConfig.write(
1420
+ self.cTemplate.cvAngleTemplate(
1421
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
1422
+ extendedLagrangian = False
1423
+ )
1424
+ )
1425
+ colvarsConfig.write(
1426
+ self.cTemplate.cvAngleTemplate(
1427
+ False, 0, 0, 'eulerPsi', '../complex.xyz', useOldCv,
1428
+ extendedLagrangian = False
1429
+ )
1430
+ )
1431
+ colvarsConfig.write(
1432
+ self.cTemplate.cvAngleTemplate(
1433
+ False, 0, 0, 'polarTheta', '../complex.xyz', useOldCv,
1434
+ extendedLagrangian = False
1435
+ )
1436
+ )
1437
+ colvarsConfig.write(
1438
+ self.cTemplate.cvAngleTemplate(
1439
+ False, 0, 0, 'polarPhi', '../complex.xyz', useOldCv,
1440
+ extendedLagrangian = False
1441
+ )
1442
+ )
1443
+ colvarsConfig.write(
1444
+ self.cTemplate.cvRTemplate(
1445
+ False, 0, 0, extendedLagrangian = False
1446
+ )
1447
+ )
1448
+ if considerRMSDCV:
1449
+ colvarsConfig.write(
1450
+ self.cTemplate.cvHarmonicTemplate('RMSD', 0, 0, stratification[1], True, 10)
1451
+ )
1452
+ colvarsConfig.write(
1453
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0, 0, stratification[1], True, 0.1)
1454
+ )
1455
+ colvarsConfig.write(
1456
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0, 0, stratification[1], True, 0.1)
1457
+ )
1458
+ colvarsConfig.write(
1459
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0, 0, stratification[1], True, 0.1)
1460
+ )
1461
+ colvarsConfig.write(
1462
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0, polarAngles[0], stratification[1], True, 0.1)
1463
+ )
1464
+ colvarsConfig.write(
1465
+ self.cTemplate.cvHarmonicTemplate('polarPhi', 0, polarAngles[1], stratification[1], True, 0.1)
1466
+ )
1467
+ colvarsConfig.write(
1468
+ self.cTemplate.cvHarmonicTemplate('r', 0, distance, stratification[1], True, 10)
1469
+ )
1470
+ if pinDownPro:
1471
+ colvarsConfig.write(
1472
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz')
1473
+ )
1474
+ with open(f'{path}/BFEE/002_RestraintBound/colvars_backward.in', 'w') as colvarsConfig:
1475
+ colvarsConfig.write(
1476
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
1477
+ )
1478
+ if considerRMSDCV:
1479
+ colvarsConfig.write(
1480
+ self.cTemplate.cvRMSDTemplate(
1481
+ False, '', '', '../complex.xyz', extendedLagrangian = False
1482
+ )
1483
+ )
1484
+ colvarsConfig.write(
1485
+ self.cTemplate.cvAngleTemplate(
1486
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
1487
+ extendedLagrangian = False
1488
+ )
1489
+ )
1490
+ colvarsConfig.write(
1491
+ self.cTemplate.cvAngleTemplate(
1492
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
1493
+ extendedLagrangian = False
1494
+ )
1495
+ )
1496
+ colvarsConfig.write(
1497
+ self.cTemplate.cvAngleTemplate(
1498
+ False, 0, 0, 'eulerPsi', '../complex.xyz', useOldCv,
1499
+ extendedLagrangian = False
1500
+ )
1501
+ )
1502
+ colvarsConfig.write(
1503
+ self.cTemplate.cvAngleTemplate(
1504
+ False, 0, 0, 'polarTheta', '../complex.xyz', useOldCv,
1505
+ extendedLagrangian = False
1506
+ )
1507
+ )
1508
+ colvarsConfig.write(
1509
+ self.cTemplate.cvAngleTemplate(
1510
+ False, 0, 0, 'polarPhi', '../complex.xyz', useOldCv,
1511
+ extendedLagrangian = False
1512
+ )
1513
+ )
1514
+ colvarsConfig.write(
1515
+ self.cTemplate.cvRTemplate(
1516
+ False, 0, 0, extendedLagrangian = False
1517
+ )
1518
+ )
1519
+ if considerRMSDCV:
1520
+ colvarsConfig.write(
1521
+ self.cTemplate.cvHarmonicTemplate('RMSD', 0, 0, stratification[1], False, 10)
1522
+ )
1523
+ colvarsConfig.write(
1524
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0, 0, stratification[1], False, 0.1)
1525
+ )
1526
+ colvarsConfig.write(
1527
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0, 0, stratification[1], False, 0.1)
1528
+ )
1529
+ colvarsConfig.write(
1530
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0, 0, stratification[1], False, 0.1)
1531
+ )
1532
+ colvarsConfig.write(
1533
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0, polarAngles[0], stratification[1], False, 0.1)
1534
+ )
1535
+ colvarsConfig.write(
1536
+ self.cTemplate.cvHarmonicTemplate('polarPhi', 0, polarAngles[1], stratification[1], False, 0.1)
1537
+ )
1538
+ colvarsConfig.write(
1539
+ self.cTemplate.cvHarmonicTemplate('r', 0, distance, stratification[1], False, 10)
1540
+ )
1541
+ if pinDownPro:
1542
+ colvarsConfig.write(
1543
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz')
1544
+ )
1545
+
1546
+ if considerRMSDCV:
1547
+ # 003_MoleculeUnbound
1548
+ with open(f'{path}/BFEE/003_MoleculeUnbound/colvars.in', 'w') as colvarsConfig:
1549
+ colvarsConfig.write(
1550
+ self.cTemplate.cvHeadTemplate('../ligandOnly.ndx')
1551
+ )
1552
+ colvarsConfig.write(
1553
+ self.cTemplate.cvRMSDTemplate(
1554
+ False, '', '', '../ligandOnly.xyz',
1555
+ extendedLagrangian = False
1556
+ )
1557
+ )
1558
+ colvarsConfig.write(
1559
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0)
1560
+ )
1561
+ if useLambdaABF:
1562
+ colvarsConfig.write(
1563
+ self.cTemplate.cvLambdaTemplate(stratification[2])
1564
+ )
1565
+ colvarsConfig.write(
1566
+ self.cTemplate.cvABFTemplate('l', unit = 'namd', czar = False) # currently only NAMD supports WTM-lambdaABF
1567
+ )
1568
+
1569
+ # 004_RestraintUnbound
1570
+ with open(f'{path}/BFEE/004_RestraintUnbound/colvars_forward.in', 'w') as colvarsConfig:
1571
+ colvarsConfig.write(
1572
+ self.cTemplate.cvHeadTemplate('../ligandOnly.ndx')
1573
+ )
1574
+ colvarsConfig.write(
1575
+ self.cTemplate.cvRMSDTemplate(
1576
+ False, '', '', '../ligandOnly.xyz',
1577
+ extendedLagrangian = False
1578
+ )
1579
+ )
1580
+ colvarsConfig.write(
1581
+ self.cTemplate.cvHarmonicTemplate('RMSD', 0, 0, stratification[3], True, 10)
1582
+ )
1583
+ with open(f'{path}/BFEE/004_RestraintUnbound/colvars_backward.in', 'w') as colvarsConfig:
1584
+ colvarsConfig.write(
1585
+ self.cTemplate.cvHeadTemplate('../ligandOnly.ndx')
1586
+ )
1587
+ colvarsConfig.write(
1588
+ self.cTemplate.cvRMSDTemplate(
1589
+ False, '', '', '../ligandOnly.xyz',
1590
+ extendedLagrangian = False
1591
+ )
1592
+ )
1593
+ colvarsConfig.write(
1594
+ self.cTemplate.cvHarmonicTemplate('RMSD', 0, 0, stratification[3], False, 10)
1595
+ )
1596
+
1597
+ else:
1598
+ if useLambdaABF:
1599
+ with open(f'{path}/BFEE/003_MoleculeUnbound/colvars.in', 'w') as colvarsConfig:
1600
+ colvarsConfig.write(
1601
+ self.cTemplate.cvHeadTemplate('../ligandOnly.ndx')
1602
+ )
1603
+ colvarsConfig.write(
1604
+ self.cTemplate.cvLambdaTemplate(stratification[2])
1605
+ )
1606
+ colvarsConfig.write(
1607
+ self.cTemplate.cvABFTemplate('l', unit = 'namd', czar = False) # currently only NAMD supports WTM-lambdaABF
1608
+ )
1609
+
1610
+ def _generateGeometricNAMDConfig(
1611
+ self,
1612
+ path,
1613
+ forceFieldType,
1614
+ forceFields,
1615
+ temperature,
1616
+ stratification = [1,1,1,1,1,1,1,1],
1617
+ membraneProtein = False,
1618
+ OPLSMixingRule = False,
1619
+ considerRMSDCV = True,
1620
+ GaWTM = False,
1621
+ CUDASOAIntegrator = False,
1622
+ timestep = 2.0
1623
+ ):
1624
+ """generate NAMD config fils for the geometric route
1625
+
1626
+ Args:
1627
+ path (str): the directory for generation of all the files
1628
+ forceFieldType (str): 'charmm' or 'amber'
1629
+ forceFieldFiles (list of str): list of CHARMM force field files
1630
+ temperature (float): temperature of the simulation
1631
+ stratification (list of int, 8): number of windows for each simulation.
1632
+ Defaults to [1,1,1,1,1,1,1,1].
1633
+ membraneProtein (bool, optional): whether simulating a membrane protein. Defaults to False.
1634
+ OPLSMixingRule (bool, optional): whether use the OPLS mixing rules. Defaults to False.
1635
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
1636
+ GaWTM (bool, optional): Whether this is an GaWTM-eABF simulation. Default to False
1637
+ CUDASOAIntegrator (bool, optional): Whether CUDASOA integrator is used. Default to False.
1638
+ timestep (float, optional): timestep of the simulation. Default to 2.0
1639
+ """
1640
+
1641
+ if forceFieldType == 'charmm':
1642
+ topType = 'psf'
1643
+ elif forceFieldType == 'amber':
1644
+ topType = 'parm7'
1645
+ coorType = 'pdb'
1646
+
1647
+ # read the original topology and coordinate file
1648
+ fParser = fileParser.fileParser(f'{path}/BFEE/complex.{topType}', f'{path}/BFEE/complex.{coorType}')
1649
+
1650
+ # pbc
1651
+ pbc = fParser.measurePBC()
1652
+
1653
+ # the extended water box
1654
+ # read the ligandOnly topology and coordinate file
1655
+ if os.path.exists(f'{path}/BFEE/007_r/complex_largeBox.{topType}'):
1656
+ fParserLargeBox = fileParser.fileParser(
1657
+ f'{path}/BFEE/007_r/complex_largeBox.{topType}',
1658
+ f'{path}/BFEE/007_r/complex_largeBox.{coorType}'
1659
+ )
1660
+ # pbc
1661
+ pbcStep7 = fParserLargeBox.measurePBC()
1662
+ else:
1663
+ if not membraneProtein:
1664
+ pbcStep7 = pbc + np.array([[24,24,24],[0,0,0]])
1665
+ else:
1666
+ pbcStep7 = pbc + np.array([[0,0,32],[0,0,0]])
1667
+
1668
+ # read the ligandOnly topology and coordinate file
1669
+ if os.path.exists(f'{path}/BFEE/008_RMSDUnbound/ligandOnly.{topType}'):
1670
+ fParserLig = fileParser.fileParser(
1671
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly.{topType}',
1672
+ f'{path}/BFEE/008_RMSDUnbound/ligandOnly.{coorType}'
1673
+ )
1674
+ # pbc
1675
+ pbcLig = fParserLig.measurePBC()
1676
+ else:
1677
+ pbcLig = pbc
1678
+
1679
+
1680
+ # 000_eq
1681
+ with open(f'{path}/BFEE/000_eq/000.1_eq.conf', 'w') as namdConfig:
1682
+ namdConfig.write(
1683
+ self.cTemplate.namdConfigTemplate(
1684
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1685
+ '', '', '', pbc,
1686
+ 'output/eq', temperature, 50000000, 'colvars.in',
1687
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1688
+ GaWTM=False, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1689
+ )
1690
+ )
1691
+
1692
+ # RMSD bound
1693
+ if considerRMSDCV:
1694
+ with open(f'{path}/BFEE/001_RMSDBound/001_abf_1.conf', 'w') as namdConfig:
1695
+ namdConfig.write(
1696
+ self.cTemplate.namdConfigTemplate(
1697
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1698
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc',
1699
+ '', 'output/abf_1', temperature, 5000000, 'colvars_1.in',
1700
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1701
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1702
+ )
1703
+ )
1704
+ with open(f'{path}/BFEE/001_RMSDBound/001_abf_1.extend.conf', 'w') as namdConfig:
1705
+ namdConfig.write(
1706
+ self.cTemplate.namdConfigTemplate(
1707
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1708
+ f'output/abf_1.restart.coor', f'output/abf_1.restart.vel', f'output/abf_1.restart.xsc',
1709
+ '', 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in',
1710
+ CVRestartFile='output/abf_1.restart', membraneProtein=membraneProtein,
1711
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1712
+ timestep=timestep
1713
+ )
1714
+ )
1715
+
1716
+ # stratification
1717
+ if stratification[0] > 1:
1718
+ for i in range(1, stratification[0]):
1719
+ with open(f'{path}/BFEE/001_RMSDBound/001_abf_{i+1}.conf', 'w') as namdConfig:
1720
+ namdConfig.write(
1721
+ self.cTemplate.namdConfigTemplate(
1722
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1723
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
1724
+ f'output/abf_{i}.restart.xsc',
1725
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in',
1726
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1727
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1728
+ )
1729
+ )
1730
+ with open(f'{path}/BFEE/001_RMSDBound/001_abf_{i+1}.extend.conf', 'w') as namdConfig:
1731
+ namdConfig.write(
1732
+ self.cTemplate.namdConfigTemplate(
1733
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1734
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
1735
+ f'output/abf_{i+1}.restart.xsc',
1736
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in',
1737
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
1738
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1739
+ timestep=timestep
1740
+ )
1741
+ )
1742
+
1743
+ # Theta
1744
+ with open(f'{path}/BFEE/002_EulerTheta/002_abf_1.conf', 'w') as namdConfig:
1745
+ namdConfig.write(
1746
+ self.cTemplate.namdConfigTemplate(
1747
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1748
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc',
1749
+ '', 'output/abf_1', temperature, 5000000, 'colvars_1.in', '',
1750
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1751
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1752
+ )
1753
+ )
1754
+ with open(f'{path}/BFEE/002_EulerTheta/002_abf_1.extend.conf', 'w') as namdConfig:
1755
+ namdConfig.write(
1756
+ self.cTemplate.namdConfigTemplate(
1757
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1758
+ f'output/abf_1.restart.coor', f'output/abf_1.restart.vel', f'output/abf_1.restart.xsc',
1759
+ '', 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in', '',
1760
+ CVRestartFile='output/abf_1.restart', membraneProtein=membraneProtein,
1761
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1762
+ timestep=timestep
1763
+ )
1764
+ )
1765
+
1766
+ # stratification
1767
+ if stratification[1] > 1:
1768
+ for i in range(1, stratification[1]):
1769
+ with open(f'{path}/BFEE/002_EulerTheta/002_abf_{i+1}.conf', 'w') as namdConfig:
1770
+ namdConfig.write(
1771
+ self.cTemplate.namdConfigTemplate(
1772
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1773
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
1774
+ f'output/abf_{i}.restart.xsc',
1775
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in', '',
1776
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1777
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1778
+ )
1779
+ )
1780
+ with open(f'{path}/BFEE/002_EulerTheta/002_abf_{i+1}.extend.conf', 'w') as namdConfig:
1781
+ namdConfig.write(
1782
+ self.cTemplate.namdConfigTemplate(
1783
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1784
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
1785
+ f'output/abf_{i+1}.restart.xsc',
1786
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in', '',
1787
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
1788
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1789
+ timestep=timestep
1790
+ )
1791
+ )
1792
+
1793
+ # Phi
1794
+ with open(f'{path}/BFEE/003_EulerPhi/003_abf_1.conf', 'w') as namdConfig:
1795
+ namdConfig.write(
1796
+ self.cTemplate.namdConfigTemplate(
1797
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1798
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc',
1799
+ '', 'output/abf_1', temperature, 5000000, 'colvars_1.in', '',
1800
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1801
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1802
+ )
1803
+ )
1804
+ with open(f'{path}/BFEE/003_EulerPhi/003_abf_1.extend.conf', 'w') as namdConfig:
1805
+ namdConfig.write(
1806
+ self.cTemplate.namdConfigTemplate(
1807
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1808
+ f'output/abf_1.restart.coor', f'output/abf_1.restart.vel', f'output/abf_1.restart.xsc',
1809
+ '', 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in', '',
1810
+ CVRestartFile='output/abf_1.restart', membraneProtein=membraneProtein,
1811
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1812
+ timestep=timestep
1813
+ )
1814
+ )
1815
+
1816
+ # stratification
1817
+ if stratification[2] > 1:
1818
+ for i in range(1, stratification[2]):
1819
+ with open(f'{path}/BFEE/003_EulerPhi/003_abf_{i+1}.conf', 'w') as namdConfig:
1820
+ namdConfig.write(
1821
+ self.cTemplate.namdConfigTemplate(
1822
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1823
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
1824
+ f'output/abf_{i}.restart.xsc',
1825
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in', '',
1826
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1827
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1828
+ )
1829
+ )
1830
+ with open(f'{path}/BFEE/003_EulerPhi/003_abf_{i+1}.extend.conf', 'w') as namdConfig:
1831
+ namdConfig.write(
1832
+ self.cTemplate.namdConfigTemplate(
1833
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1834
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
1835
+ f'output/abf_{i+1}.restart.xsc',
1836
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in', '',
1837
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
1838
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1839
+ timestep=timestep
1840
+ )
1841
+ )
1842
+
1843
+ # Psi
1844
+ with open(f'{path}/BFEE/004_EulerPsi/004_abf_1.conf', 'w') as namdConfig:
1845
+ namdConfig.write(
1846
+ self.cTemplate.namdConfigTemplate(
1847
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1848
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc',
1849
+ '', 'output/abf_1', temperature, 5000000, 'colvars_1.in', '',
1850
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1851
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1852
+ )
1853
+ )
1854
+ with open(f'{path}/BFEE/004_EulerPsi/004_abf_1.extend.conf', 'w') as namdConfig:
1855
+ namdConfig.write(
1856
+ self.cTemplate.namdConfigTemplate(
1857
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1858
+ f'output/abf_1.restart.coor', f'output/abf_1.restart.vel', f'output/abf_1.restart.xsc',
1859
+ '', 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in', '',
1860
+ CVRestartFile='output/abf_1.restart', membraneProtein=membraneProtein,
1861
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1862
+ timestep=timestep
1863
+ )
1864
+ )
1865
+
1866
+ # stratification
1867
+ if stratification[3] > 1:
1868
+ for i in range(1, stratification[3]):
1869
+ with open(f'{path}/BFEE/004_EulerPsi/004_abf_{i+1}.conf', 'w') as namdConfig:
1870
+ namdConfig.write(
1871
+ self.cTemplate.namdConfigTemplate(
1872
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1873
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
1874
+ f'output/abf_{i}.restart.xsc',
1875
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in', '',
1876
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1877
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1878
+ )
1879
+ )
1880
+ with open(f'{path}/BFEE/004_EulerPsi/004_abf_{i+1}.extend.conf', 'w') as namdConfig:
1881
+ namdConfig.write(
1882
+ self.cTemplate.namdConfigTemplate(
1883
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1884
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
1885
+ f'output/abf_{i+1}.restart.xsc',
1886
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in', '',
1887
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
1888
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1889
+ timestep=timestep
1890
+ )
1891
+ )
1892
+
1893
+ # theta
1894
+ with open(f'{path}/BFEE/005_PolarTheta/005_abf_1.conf', 'w') as namdConfig:
1895
+ namdConfig.write(
1896
+ self.cTemplate.namdConfigTemplate(
1897
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1898
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc',
1899
+ '', 'output/abf_1', temperature, 5000000, 'colvars_1.in', '',
1900
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1901
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1902
+ )
1903
+ )
1904
+ with open(f'{path}/BFEE/005_PolarTheta/005_abf_1.extend.conf', 'w') as namdConfig:
1905
+ namdConfig.write(
1906
+ self.cTemplate.namdConfigTemplate(
1907
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1908
+ f'output/abf_1.restart.coor', f'output/abf_1.restart.vel', f'output/abf_1.restart.xsc',
1909
+ '', 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in', '',
1910
+ CVRestartFile='output/abf_1.restart', membraneProtein=membraneProtein,
1911
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1912
+ timestep=timestep
1913
+ )
1914
+ )
1915
+
1916
+
1917
+ # stratification
1918
+ if stratification[4] > 1:
1919
+ for i in range(1, stratification[4]):
1920
+ with open(f'{path}/BFEE/005_PolarTheta/005_abf_{i+1}.conf', 'w') as namdConfig:
1921
+ namdConfig.write(
1922
+ self.cTemplate.namdConfigTemplate(
1923
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1924
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
1925
+ f'output/abf_{i}.restart.xsc',
1926
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in', '',
1927
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1928
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1929
+ )
1930
+ )
1931
+ with open(f'{path}/BFEE/005_PolarTheta/005_abf_{i+1}.extend.conf', 'w') as namdConfig:
1932
+ namdConfig.write(
1933
+ self.cTemplate.namdConfigTemplate(
1934
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1935
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
1936
+ f'output/abf_{i+1}.restart.xsc',
1937
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in', '',
1938
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
1939
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1940
+ timestep=timestep
1941
+ )
1942
+ )
1943
+
1944
+ # phi
1945
+ with open(f'{path}/BFEE/006_PolarPhi/006_abf_1.conf', 'w') as namdConfig:
1946
+ namdConfig.write(
1947
+ self.cTemplate.namdConfigTemplate(
1948
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1949
+ f'../000_eq/output/eq.coor', f'../000_eq/output/eq.vel', f'../000_eq/output/eq.xsc',
1950
+ '', 'output/abf_1', temperature, 5000000, 'colvars_1.in', '',
1951
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1952
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1953
+ )
1954
+ )
1955
+ with open(f'{path}/BFEE/006_PolarPhi/006_abf_1.extend.conf', 'w') as namdConfig:
1956
+ namdConfig.write(
1957
+ self.cTemplate.namdConfigTemplate(
1958
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1959
+ f'output/abf_1.restart.coor', f'output/abf_1.restart.vel', f'output/abf_1.restart.xsc',
1960
+ '', 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in', '',
1961
+ CVRestartFile='output/abf_1.restart', membraneProtein=membraneProtein,
1962
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1963
+ timestep=timestep
1964
+ )
1965
+ )
1966
+
1967
+ # stratification
1968
+ if stratification[5] > 1:
1969
+ for i in range(1, stratification[5]):
1970
+ with open(f'{path}/BFEE/006_PolarPhi/006_abf_{i+1}.conf', 'w') as namdConfig:
1971
+ namdConfig.write(
1972
+ self.cTemplate.namdConfigTemplate(
1973
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1974
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
1975
+ f'output/abf_{i}.restart.xsc',
1976
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in', '',
1977
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
1978
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
1979
+ )
1980
+ )
1981
+ with open(f'{path}/BFEE/006_PolarPhi/006_abf_{i+1}.extend.conf', 'w') as namdConfig:
1982
+ namdConfig.write(
1983
+ self.cTemplate.namdConfigTemplate(
1984
+ forceFieldType, forceFields, f'../complex.{topType}', f'../complex.pdb',
1985
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
1986
+ f'output/abf_{i+1}.restart.xsc',
1987
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in', '',
1988
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
1989
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
1990
+ timestep=timestep
1991
+ )
1992
+ )
1993
+
1994
+ # r
1995
+ # eq
1996
+ with open(f'{path}/BFEE/007_r/007.1_eq.conf', 'w') as namdConfig:
1997
+ namdConfig.write(
1998
+ self.cTemplate.namdConfigTemplate(
1999
+ forceFieldType, forceFields, f'./complex_largeBox.{topType}', f'./complex_largeBox.pdb',
2000
+ '', '', '',
2001
+ pbcStep7,
2002
+ 'output/eq', temperature, 50000000, 'colvars_eq.in', '',
2003
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
2004
+ GaWTM=False, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
2005
+ )
2006
+ )
2007
+ # abf
2008
+ with open(f'{path}/BFEE/007_r/007.2_abf_1.conf', 'w') as namdConfig:
2009
+ namdConfig.write(
2010
+ self.cTemplate.namdConfigTemplate(
2011
+ forceFieldType, forceFields, f'./complex_largeBox.{topType}', f'./complex_largeBox.pdb',
2012
+ 'output/eq.coor', 'output/eq.vel', 'output/eq.xsc', '',
2013
+ 'output/abf_1', temperature, 100000000, 'colvars_1.in', '',
2014
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
2015
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
2016
+ )
2017
+ )
2018
+ with open(f'{path}/BFEE/007_r/007.2_abf_1.extend.conf', 'w') as namdConfig:
2019
+ namdConfig.write(
2020
+ self.cTemplate.namdConfigTemplate(
2021
+ forceFieldType, forceFields, f'./complex_largeBox.{topType}', f'./complex_largeBox.pdb',
2022
+ 'output/abf_1.restart.coor', 'output/abf_1.restart.vel', 'output/abf_1.restart.xsc', '',
2023
+ 'output/abf_1.extend', temperature, 100000000, 'colvars_1.in', '',
2024
+ CVRestartFile=f'output/abf_1.restart', membraneProtein=membraneProtein,
2025
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
2026
+ timestep=timestep
2027
+ )
2028
+ )
2029
+
2030
+ # stratification
2031
+ if stratification[6] > 1:
2032
+ for i in range(1, stratification[6]):
2033
+ with open(f'{path}/BFEE/007_r/007.2_abf_{i+1}.conf', 'w') as namdConfig:
2034
+ namdConfig.write(
2035
+ self.cTemplate.namdConfigTemplate(
2036
+ forceFieldType, forceFields, f'./complex_largeBox.{topType}', f'./complex_largeBox.pdb',
2037
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
2038
+ f'output/abf_{i}.restart.xsc',
2039
+ '', f'output/abf_{i+1}', temperature, 100000000, f'colvars_{i+1}.in', '',
2040
+ membraneProtein=membraneProtein, OPLSMixingRule=OPLSMixingRule,
2041
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
2042
+ )
2043
+ )
2044
+ with open(f'{path}/BFEE/007_r/007.2_abf_{i+1}.extend.conf', 'w') as namdConfig:
2045
+ namdConfig.write(
2046
+ self.cTemplate.namdConfigTemplate(
2047
+ forceFieldType, forceFields, f'./complex_largeBox.{topType}', f'./complex_largeBox.pdb',
2048
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
2049
+ f'output/abf_{i+1}.restart.xsc',
2050
+ '', f'output/abf_{i+1}.extend', temperature, 100000000, f'colvars_{i+1}.in', '',
2051
+ CVRestartFile=f'output/abf_{i+1}.restart', membraneProtein=membraneProtein,
2052
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
2053
+ timestep=timestep
2054
+ )
2055
+ )
2056
+
2057
+ # RMSD unbound
2058
+ if considerRMSDCV:
2059
+ # eq
2060
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.1_eq.conf', 'w') as namdConfig:
2061
+ namdConfig.write(
2062
+ self.cTemplate.namdConfigTemplate(
2063
+ forceFieldType, forceFields, f'./ligandOnly.{topType}', f'./ligandOnly.pdb',
2064
+ '', '', '',
2065
+ pbcLig,
2066
+ 'output/eq', temperature, 1000000, OPLSMixingRule=OPLSMixingRule,
2067
+ GaWTM=False, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
2068
+ )
2069
+ )
2070
+ # abf
2071
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.2_abf_1.conf', 'w') as namdConfig:
2072
+ namdConfig.write(
2073
+ self.cTemplate.namdConfigTemplate(
2074
+ forceFieldType, forceFields, f'./ligandOnly.{topType}', f'./ligandOnly.pdb',
2075
+ 'output/eq.coor', 'output/eq.vel', 'output/eq.xsc', '',
2076
+ 'output/abf_1', temperature, 5000000, 'colvars_1.in',
2077
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
2078
+ timestep=timestep
2079
+ )
2080
+ )
2081
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.2_abf_1.extend.conf', 'w') as namdConfig:
2082
+ namdConfig.write(
2083
+ self.cTemplate.namdConfigTemplate(
2084
+ forceFieldType, forceFields, f'./ligandOnly.{topType}', f'./ligandOnly.pdb',
2085
+ 'output/abf_1.restart.coor', 'output/abf_1.restart.vel', 'output/abf_1.restart.xsc', '',
2086
+ 'output/abf_1.extend', temperature, 5000000, 'colvars_1.in',
2087
+ CVRestartFile=f'output/abf_1.restart', OPLSMixingRule=OPLSMixingRule,
2088
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
2089
+ )
2090
+ )
2091
+
2092
+ # stratification
2093
+ if stratification[7] > 1:
2094
+ for i in range(1, stratification[7]):
2095
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.2_abf_{i+1}.conf', 'w') as namdConfig:
2096
+ namdConfig.write(
2097
+ self.cTemplate.namdConfigTemplate(
2098
+ forceFieldType, forceFields, f'./ligandOnly.{topType}', f'./ligandOnly.pdb',
2099
+ f'output/abf_{i}.restart.coor', f'output/abf_{i}.restart.vel',
2100
+ f'output/abf_{i}.restart.xsc',
2101
+ '', f'output/abf_{i+1}', temperature, 5000000, f'colvars_{i+1}.in',
2102
+ OPLSMixingRule=OPLSMixingRule, GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator,
2103
+ timestep=timestep
2104
+ )
2105
+ )
2106
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.2_abf_{i+1}.extend.conf', 'w') as namdConfig:
2107
+ namdConfig.write(
2108
+ self.cTemplate.namdConfigTemplate(
2109
+ forceFieldType, forceFields, f'./ligandOnly.{topType}', f'./ligandOnly.pdb',
2110
+ f'output/abf_{i+1}.restart.coor', f'output/abf_{i+1}.restart.vel',
2111
+ f'output/abf_{i+1}.restart.xsc',
2112
+ '', f'output/abf_{i+1}.extend', temperature, 5000000, f'colvars_{i+1}.in',
2113
+ CVRestartFile=f'output/abf_{i+1}.restart', OPLSMixingRule=OPLSMixingRule,
2114
+ GaWTM=GaWTM, CUDASOAIntegrator=CUDASOAIntegrator, timestep=timestep
2115
+ )
2116
+ )
2117
+
2118
+ def _generateGeometricGromacsConfig(
2119
+ self,
2120
+ path,
2121
+ forceFieldType,
2122
+ temperature,
2123
+ membraneProtein = False,
2124
+ considerRMSDCV = True
2125
+ ):
2126
+ """generate NAMD config fils for the geometric route
2127
+
2128
+ Args:
2129
+ path (str): the directory for generation of all the files
2130
+ forceFieldType (str): 'charmm' or 'amber'
2131
+ temperature (float): temperature of the simulation
2132
+ membraneProtein (bool, optional): whether simulating a membrane protein. Defaults to False.
2133
+ considerRMSDCV (bool, optional): Whethre consider the RMSD CV. Default to True.
2134
+ """
2135
+
2136
+ # 000_eq
2137
+ with open(f'{path}/BFEE/000_eq/000.1_min.mdp', 'w') as gromacsConfig:
2138
+ gromacsConfig.write(
2139
+ self.cTemplate.gromacsMinimizeConfigTemplate()
2140
+ )
2141
+ with open(f'{path}/BFEE/000_eq/000.2_eq.mdp', 'w') as gromacsConfig:
2142
+ gromacsConfig.write(
2143
+ self.cTemplate.gromacsConfigTemplate(
2144
+ forceFieldType, temperature, 5000000,
2145
+ membraneProtein=membraneProtein,
2146
+ generateVelocities=True
2147
+ )
2148
+ )
2149
+
2150
+ # RMSD bound
2151
+ if considerRMSDCV:
2152
+ with open(f'{path}/BFEE/001_RMSDBound/001_abf.mdp', 'w') as gromacsConfig:
2153
+ gromacsConfig.write(
2154
+ self.cTemplate.gromacsConfigTemplate(
2155
+ forceFieldType, temperature, 5000000,
2156
+ membraneProtein=membraneProtein,
2157
+ generateVelocities=False
2158
+ )
2159
+ )
2160
+
2161
+ # Theta
2162
+ with open(f'{path}/BFEE/002_EulerTheta/002_abf.mdp', 'w') as gromacsConfig:
2163
+ gromacsConfig.write(
2164
+ self.cTemplate.gromacsConfigTemplate(
2165
+ forceFieldType, temperature, 5000000,
2166
+ membraneProtein=membraneProtein,
2167
+ generateVelocities=False
2168
+ )
2169
+ )
2170
+
2171
+ # Phi
2172
+ with open(f'{path}/BFEE/003_EulerPhi/003_abf.mdp', 'w') as gromacsConfig:
2173
+ gromacsConfig.write(
2174
+ self.cTemplate.gromacsConfigTemplate(
2175
+ forceFieldType, temperature, 5000000,
2176
+ membraneProtein=membraneProtein,
2177
+ generateVelocities=False
2178
+ )
2179
+ )
2180
+
2181
+ # Psi
2182
+ with open(f'{path}/BFEE/004_EulerPsi/004_abf.mdp', 'w') as gromacsConfig:
2183
+ gromacsConfig.write(
2184
+ self.cTemplate.gromacsConfigTemplate(
2185
+ forceFieldType, temperature, 5000000,
2186
+ membraneProtein=membraneProtein,
2187
+ generateVelocities=False
2188
+ )
2189
+ )
2190
+
2191
+ # theta
2192
+ with open(f'{path}/BFEE/005_PolarTheta/005_abf.mdp', 'w') as gromacsConfig:
2193
+ gromacsConfig.write(
2194
+ self.cTemplate.gromacsConfigTemplate(
2195
+ forceFieldType, temperature, 5000000,
2196
+ membraneProtein=membraneProtein,
2197
+ generateVelocities=False
2198
+ )
2199
+ )
2200
+
2201
+ # phi
2202
+ with open(f'{path}/BFEE/006_PolarPhi/006_abf.mdp', 'w') as gromacsConfig:
2203
+ gromacsConfig.write(
2204
+ self.cTemplate.gromacsConfigTemplate(
2205
+ forceFieldType, temperature, 5000000,
2206
+ membraneProtein=membraneProtein,
2207
+ generateVelocities=False
2208
+ )
2209
+ )
2210
+
2211
+ # r
2212
+ # eq
2213
+ with open(f'{path}/BFEE/007_r/007.1_min.mdp', 'w') as gromacsConfig:
2214
+ gromacsConfig.write(
2215
+ self.cTemplate.gromacsMinimizeConfigTemplate()
2216
+ )
2217
+ with open(f'{path}/BFEE/007_r/007.2_eq.mdp', 'w') as gromacsConfig:
2218
+ gromacsConfig.write(
2219
+ self.cTemplate.gromacsConfigTemplate(
2220
+ forceFieldType, temperature, 5000000,
2221
+ membraneProtein=membraneProtein,
2222
+ generateVelocities=True
2223
+ )
2224
+ )
2225
+ # abf
2226
+ with open(f'{path}/BFEE/007_r/007.3_abf.mdp', 'w') as gromacsConfig:
2227
+ gromacsConfig.write(
2228
+ self.cTemplate.gromacsConfigTemplate(
2229
+ forceFieldType, temperature, 20000000,
2230
+ membraneProtein=membraneProtein,
2231
+ generateVelocities=False
2232
+ )
2233
+ )
2234
+
2235
+ # RMSD unbound
2236
+ if considerRMSDCV:
2237
+ # eq
2238
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.1_min.mdp', 'w') as gromacsConfig:
2239
+ gromacsConfig.write(
2240
+ self.cTemplate.gromacsMinimizeConfigTemplate()
2241
+ )
2242
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.2_eq.mdp', 'w') as gromacsConfig:
2243
+ gromacsConfig.write(
2244
+ self.cTemplate.gromacsConfigTemplate(
2245
+ forceFieldType, temperature, 1000000,
2246
+ membraneProtein=membraneProtein,
2247
+ generateVelocities=True
2248
+ )
2249
+ )
2250
+ # abf
2251
+ with open(f'{path}/BFEE/008_RMSDUnbound/008.3_abf.mdp', 'w') as gromacsConfig:
2252
+ gromacsConfig.write(
2253
+ self.cTemplate.gromacsConfigTemplate(
2254
+ forceFieldType, temperature, 5000000,
2255
+ membraneProtein=membraneProtein,
2256
+ generateVelocities=False
2257
+ )
2258
+ )
2259
+
2260
+ def _generateGeometricColvarsConfig(
2261
+ self,
2262
+ path,
2263
+ topType,
2264
+ coorType,
2265
+ selectionPro,
2266
+ selectionLig,
2267
+ selectionRef,
2268
+ stratification=[1,1,1,1,1,1,1,1],
2269
+ pinDownPro=True,
2270
+ useOldCv=True,
2271
+ reflectingBoundary=False,
2272
+ unit='namd',
2273
+ considerRMSDCV=True,
2274
+ reweightAMD=False
2275
+ ):
2276
+ """generate Colvars config fils for geometric route
2277
+
2278
+ Args:
2279
+ path (str): the directory for generation of all the files
2280
+ topType (str): the type (psf, parm) of the topology file
2281
+ coorType (str): the type (pdb, rst) of the topology file
2282
+ selectionPro (str): MDAnalysis-style selection of the protein
2283
+ selectionLig (str): MDAnalysis-style selection of the ligand
2284
+ selectionRef (str): MDAnalysis-style selection of the reference group for pulling simulation
2285
+ stratification (list of int, 8, optional): number of windows for each simulation.
2286
+ Defaults to [1,1,1,1,1,1,1,1].
2287
+ pinDownPro (bool, optional): Whether pinning down the protein. Defaults to True.
2288
+ useOldCv (bool, optional): whether used old, custom-function-based cv. Defaults to True.
2289
+ reflectingBoundary (bool, optional): Whether use reflecting boundaries, requires setBoundary on. Default to False
2290
+ unit (str, optional): unit, 'namd' or 'gromacs'. Default to namd.
2291
+ considerRMSDCV (bool, optional): Whether consider the RMSD CV. Default to True.
2292
+ reweightAMD (bool, optional): Whether add reweightAMD action. If this option is on, colvars config files for
2293
+ equilibration will not be generated. Default to False
2294
+ """
2295
+
2296
+ assert(len(stratification) == 8)
2297
+
2298
+ if unit == 'namd':
2299
+ if not reweightAMD:
2300
+ colvarPostfix = 'in'
2301
+ else:
2302
+ colvarPostfix = 'in.amd'
2303
+ elif unit == 'gromacs':
2304
+ colvarPostfix = 'dat'
2305
+ assert(not reweightAMD)
2306
+
2307
+ # read the original topology and coordinate file
2308
+ fParser = fileParser.fileParser(f'{path}/BFEE/complex.{topType}', f'{path}/BFEE/complex.pdb')
2309
+ center = fParser.measureCenter(selectionPro)
2310
+ polarAngles = fParser.measurePolarAngles(selectionRef, selectionLig)
2311
+ distance = fParser.measureDistance(selectionRef, selectionLig)
2312
+
2313
+ if os.path.exists(f'{path}/BFEE/007_r/complex_largeBox.{topType}'):
2314
+ fParserLargeBox = fileParser.fileParser(f'{path}/BFEE/007_r/complex_largeBox.pdb')
2315
+ centerLargeBox = fParserLargeBox.measureCenter(selectionPro)
2316
+ else:
2317
+ centerLargeBox = center
2318
+
2319
+ # 000_eq
2320
+ if not reweightAMD:
2321
+ with open(f'{path}/BFEE/000_eq/colvars.{colvarPostfix}', 'w') as colvarsConfig:
2322
+ colvarsConfig.write(
2323
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
2324
+ )
2325
+ # monitor CVs during equilibration
2326
+ colvarsConfig.write(
2327
+ self.cTemplate.cvRMSDTemplate(
2328
+ True, 0, 10, '../complex.xyz',
2329
+ extendedLagrangian = False,
2330
+ unit = unit
2331
+ )
2332
+ )
2333
+ colvarsConfig.write(
2334
+ self.cTemplate.cvAngleTemplate(
2335
+ True, -90, 90, 'eulerTheta', '../complex.xyz', useOldCv,
2336
+ extendedLagrangian = False
2337
+ )
2338
+ )
2339
+ colvarsConfig.write(
2340
+ self.cTemplate.cvAngleTemplate(
2341
+ True, -180, 180, 'eulerPhi', '../complex.xyz', useOldCv,
2342
+ extendedLagrangian = False
2343
+ )
2344
+ )
2345
+ colvarsConfig.write(
2346
+ self.cTemplate.cvAngleTemplate(
2347
+ True, -180, 180, 'eulerPsi', '../complex.xyz', useOldCv,
2348
+ extendedLagrangian = False
2349
+ )
2350
+ )
2351
+ colvarsConfig.write(
2352
+ self.cTemplate.cvAngleTemplate(
2353
+ True, 0, 180, 'polarTheta', '../complex.xyz', useOldCv,
2354
+ extendedLagrangian = False
2355
+ )
2356
+ )
2357
+ colvarsConfig.write(
2358
+ self.cTemplate.cvAngleTemplate(
2359
+ True, -180, 180, 'polarPhi', '../complex.xyz', useOldCv,
2360
+ extendedLagrangian = False
2361
+ )
2362
+ )
2363
+ colvarsConfig.write(
2364
+ self.cTemplate.cvRTemplate(
2365
+ True, (distance - 5 if distance - 5 > 0 else 0),
2366
+ distance + 22, extendedLagrangian = False,
2367
+ unit = unit
2368
+ )
2369
+ )
2370
+ colvarsConfig.write(
2371
+ self.cTemplate.cvHistogramTemplate('RMSD')
2372
+ )
2373
+ colvarsConfig.write(
2374
+ self.cTemplate.cvHistogramTemplate('eulerTheta')
2375
+ )
2376
+ colvarsConfig.write(
2377
+ self.cTemplate.cvHistogramTemplate('eulerPhi')
2378
+ )
2379
+ colvarsConfig.write(
2380
+ self.cTemplate.cvHistogramTemplate('eulerPsi')
2381
+ )
2382
+ colvarsConfig.write(
2383
+ self.cTemplate.cvHistogramTemplate('polarTheta')
2384
+ )
2385
+ colvarsConfig.write(
2386
+ self.cTemplate.cvHistogramTemplate('polarPhi')
2387
+ )
2388
+ colvarsConfig.write(
2389
+ self.cTemplate.cvHistogramTemplate('r')
2390
+ )
2391
+ colvarsConfig.write(
2392
+ self.cTemplate.cvProteinTemplate(
2393
+ center, '../complex.xyz', unit = unit
2394
+ )
2395
+ )
2396
+
2397
+ # 001_RMSDBound
2398
+ if considerRMSDCV:
2399
+ for i in range(stratification[0]):
2400
+ with open(f'{path}/BFEE/001_RMSDBound/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2401
+ colvarsConfig.write(
2402
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2403
+ )
2404
+ colvarsConfig.write(
2405
+ self.cTemplate.cvRMSDTemplate(
2406
+ True, float(i)/stratification[0] * 3.0, float(i+1)/stratification[0] * 3.0, '../complex.xyz',
2407
+ extendedLagrangian = True, reflectingBoundary = reflectingBoundary,
2408
+ unit = unit
2409
+ )
2410
+ )
2411
+ colvarsConfig.write(
2412
+ self.cTemplate.cvABFTemplate('RMSD', unit = unit)
2413
+ )
2414
+ if reweightAMD:
2415
+ colvarsConfig.write(
2416
+ self.cTemplate.cvReweightAMDTemplate('RMSD')
2417
+ )
2418
+ if not reflectingBoundary:
2419
+ colvarsConfig.write(
2420
+ self.cTemplate.cvHarmonicWallsTemplate(
2421
+ 'RMSD', float(i)/stratification[0] * 3.0, float(i+1)/stratification[0] * 3.0,
2422
+ unit = unit
2423
+ )
2424
+ )
2425
+ if pinDownPro:
2426
+ colvarsConfig.write(
2427
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz', unit = unit)
2428
+ )
2429
+
2430
+ # 002_Theta
2431
+ for i in range(stratification[1]):
2432
+ with open(f'{path}/BFEE/002_EulerTheta/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2433
+ colvarsConfig.write(
2434
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2435
+ )
2436
+ colvarsConfig.write(
2437
+ self.cTemplate.cvRMSDTemplate(
2438
+ False, '', '', '../complex.xyz',
2439
+ extendedLagrangian = False,
2440
+ unit = unit
2441
+ )
2442
+ )
2443
+ colvarsConfig.write(
2444
+ self.cTemplate.cvAngleTemplate(
2445
+ True, float(i)/stratification[1] * 20 - 10, float(i+1)/stratification[1] * 20 - 10,
2446
+ 'eulerTheta', '../complex.xyz', useOldCv, extendedLagrangian = True,
2447
+ reflectingBoundary = reflectingBoundary
2448
+ )
2449
+ )
2450
+ colvarsConfig.write(
2451
+ self.cTemplate.cvABFTemplate('eulerTheta', unit = unit)
2452
+ )
2453
+ if reweightAMD:
2454
+ colvarsConfig.write(
2455
+ self.cTemplate.cvReweightAMDTemplate('eulerTheta')
2456
+ )
2457
+ if not reflectingBoundary:
2458
+ colvarsConfig.write(
2459
+ self.cTemplate.cvHarmonicWallsTemplate(
2460
+ 'eulerTheta',
2461
+ float(i)/stratification[1] * 20 - 10,
2462
+ float(i+1)/stratification[1] * 20 - 10,
2463
+ unit = unit,
2464
+ )
2465
+ )
2466
+ if considerRMSDCV:
2467
+ colvarsConfig.write(
2468
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2469
+ )
2470
+ if pinDownPro:
2471
+ colvarsConfig.write(
2472
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz', unit = unit)
2473
+ )
2474
+
2475
+ # 003_Phi
2476
+ for i in range(stratification[2]):
2477
+ with open(f'{path}/BFEE/003_EulerPhi/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2478
+ colvarsConfig.write(
2479
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2480
+ )
2481
+ colvarsConfig.write(
2482
+ self.cTemplate.cvRMSDTemplate(
2483
+ False, '', '', '../complex.xyz',
2484
+ extendedLagrangian = False,
2485
+ unit = unit
2486
+ )
2487
+ )
2488
+ colvarsConfig.write(
2489
+ self.cTemplate.cvAngleTemplate(
2490
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
2491
+ extendedLagrangian = False
2492
+ )
2493
+ )
2494
+ colvarsConfig.write(
2495
+ self.cTemplate.cvAngleTemplate(
2496
+ True, float(i)/stratification[2] * 20 - 10, float(i+1)/stratification[2] * 20 - 10,
2497
+ 'eulerPhi', '../complex.xyz', useOldCv, extendedLagrangian = True,
2498
+ reflectingBoundary = reflectingBoundary
2499
+ )
2500
+ )
2501
+ colvarsConfig.write(
2502
+ self.cTemplate.cvABFTemplate('eulerPhi', unit = unit)
2503
+ )
2504
+ if reweightAMD:
2505
+ colvarsConfig.write(
2506
+ self.cTemplate.cvReweightAMDTemplate('eulerPhi')
2507
+ )
2508
+ if not reflectingBoundary:
2509
+ colvarsConfig.write(
2510
+ self.cTemplate.cvHarmonicWallsTemplate(
2511
+ 'eulerPhi',
2512
+ float(i)/stratification[2] * 20 - 10,
2513
+ float(i+1)/stratification[2] * 20 - 10,
2514
+ unit = unit,
2515
+ )
2516
+ )
2517
+ if considerRMSDCV:
2518
+ colvarsConfig.write(
2519
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2520
+ )
2521
+ colvarsConfig.write(
2522
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0, unit = unit)
2523
+ )
2524
+ if pinDownPro:
2525
+ colvarsConfig.write(
2526
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz', unit = unit)
2527
+ )
2528
+
2529
+ # 004_Psi
2530
+ for i in range(stratification[3]):
2531
+ with open(f'{path}/BFEE/004_EulerPsi/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2532
+ colvarsConfig.write(
2533
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2534
+ )
2535
+ colvarsConfig.write(
2536
+ self.cTemplate.cvRMSDTemplate(
2537
+ False, '', '', '../complex.xyz',
2538
+ extendedLagrangian = False,
2539
+ unit = unit
2540
+ )
2541
+ )
2542
+ colvarsConfig.write(
2543
+ self.cTemplate.cvAngleTemplate(
2544
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
2545
+ extendedLagrangian = False
2546
+ )
2547
+ )
2548
+ colvarsConfig.write(
2549
+ self.cTemplate.cvAngleTemplate(
2550
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
2551
+ extendedLagrangian = False
2552
+ )
2553
+ )
2554
+ colvarsConfig.write(
2555
+ self.cTemplate.cvAngleTemplate(
2556
+ True, float(i)/stratification[3] * 20 - 10, float(i+1)/stratification[3] * 20 - 10,
2557
+ 'eulerPsi', '../complex.xyz', useOldCv, extendedLagrangian = True,
2558
+ reflectingBoundary = reflectingBoundary
2559
+ )
2560
+ )
2561
+ colvarsConfig.write(
2562
+ self.cTemplate.cvABFTemplate('eulerPsi', unit = unit)
2563
+ )
2564
+ if reweightAMD:
2565
+ colvarsConfig.write(
2566
+ self.cTemplate.cvReweightAMDTemplate('eulerPsi')
2567
+ )
2568
+ if not reflectingBoundary:
2569
+ colvarsConfig.write(
2570
+ self.cTemplate.cvHarmonicWallsTemplate(
2571
+ 'eulerPsi',
2572
+ float(i)/stratification[3] * 20 - 10,
2573
+ float(i+1)/stratification[3] * 20 - 10,
2574
+ unit = unit
2575
+ )
2576
+ )
2577
+ if considerRMSDCV:
2578
+ colvarsConfig.write(
2579
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2580
+ )
2581
+ colvarsConfig.write(
2582
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0, unit = unit)
2583
+ )
2584
+ colvarsConfig.write(
2585
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0, unit = unit)
2586
+ )
2587
+ if pinDownPro:
2588
+ colvarsConfig.write(
2589
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz', unit = unit)
2590
+ )
2591
+
2592
+ # 005_polarTheta
2593
+ for i in range(stratification[4]):
2594
+ with open(f'{path}/BFEE/005_PolarTheta/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2595
+ colvarsConfig.write(
2596
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2597
+ )
2598
+ colvarsConfig.write(
2599
+ self.cTemplate.cvRMSDTemplate(
2600
+ False, '', '', '../complex.xyz',
2601
+ extendedLagrangian = False,
2602
+ unit = unit
2603
+ )
2604
+ )
2605
+ colvarsConfig.write(
2606
+ self.cTemplate.cvAngleTemplate(
2607
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
2608
+ extendedLagrangian = False
2609
+ )
2610
+ )
2611
+ colvarsConfig.write(
2612
+ self.cTemplate.cvAngleTemplate(
2613
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
2614
+ extendedLagrangian = False
2615
+ )
2616
+ )
2617
+ colvarsConfig.write(
2618
+ self.cTemplate.cvAngleTemplate(
2619
+ False, 0, 0, 'eulerPsi', '../complex.xyz', useOldCv,
2620
+ extendedLagrangian = False
2621
+ )
2622
+ )
2623
+ colvarsConfig.write(
2624
+ self.cTemplate.cvAngleTemplate(
2625
+ True, float(i)/stratification[4] * 20 - 10 + polarAngles[0],
2626
+ float(i+1)/stratification[4] * 20 - 10 + polarAngles[0], 'polarTheta',
2627
+ '../complex.xyz', useOldCv, extendedLagrangian = True,
2628
+ reflectingBoundary = reflectingBoundary
2629
+ )
2630
+ )
2631
+ colvarsConfig.write(
2632
+ self.cTemplate.cvABFTemplate('polarTheta', unit = unit)
2633
+ )
2634
+ if reweightAMD:
2635
+ colvarsConfig.write(
2636
+ self.cTemplate.cvReweightAMDTemplate('polarTheta')
2637
+ )
2638
+ if not reflectingBoundary:
2639
+ colvarsConfig.write(
2640
+ self.cTemplate.cvHarmonicWallsTemplate(
2641
+ 'polarTheta', float(i)/stratification[4] * 20 - 10 + polarAngles[0],
2642
+ float(i+1)/stratification[4] * 20 - 10 + polarAngles[0],
2643
+ unit = unit
2644
+ )
2645
+ )
2646
+ if considerRMSDCV:
2647
+ colvarsConfig.write(
2648
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2649
+ )
2650
+ colvarsConfig.write(
2651
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0, unit = unit)
2652
+ )
2653
+ colvarsConfig.write(
2654
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0, unit = unit)
2655
+ )
2656
+ colvarsConfig.write(
2657
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0.1, 0, unit = unit)
2658
+ )
2659
+ if pinDownPro:
2660
+ colvarsConfig.write(
2661
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz', unit = unit)
2662
+ )
2663
+
2664
+ # 006_polarPhi
2665
+ for i in range(stratification[5]):
2666
+ with open(f'{path}/BFEE/006_PolarPhi/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2667
+ colvarsConfig.write(
2668
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2669
+ )
2670
+ colvarsConfig.write(
2671
+ self.cTemplate.cvRMSDTemplate(
2672
+ False, '', '', '../complex.xyz',
2673
+ extendedLagrangian = False,
2674
+ unit = unit
2675
+ )
2676
+ )
2677
+ colvarsConfig.write(
2678
+ self.cTemplate.cvAngleTemplate(
2679
+ False, 0, 0, 'eulerTheta', '../complex.xyz', useOldCv,
2680
+ extendedLagrangian = False
2681
+ )
2682
+ )
2683
+ colvarsConfig.write(
2684
+ self.cTemplate.cvAngleTemplate(
2685
+ False, 0, 0, 'eulerPhi', '../complex.xyz', useOldCv,
2686
+ extendedLagrangian = False
2687
+ )
2688
+ )
2689
+ colvarsConfig.write(
2690
+ self.cTemplate.cvAngleTemplate(
2691
+ False, 0, 0, 'eulerPsi', '../complex.xyz', useOldCv,
2692
+ extendedLagrangian = False
2693
+ )
2694
+ )
2695
+ colvarsConfig.write(
2696
+ self.cTemplate.cvAngleTemplate(
2697
+ False, 0, 0, 'polarTheta', '../complex.xyz', useOldCv,
2698
+ extendedLagrangian = False
2699
+ )
2700
+ )
2701
+ colvarsConfig.write(
2702
+ self.cTemplate.cvAngleTemplate(
2703
+ True, float(i)/stratification[5] * 20 - 10 + polarAngles[1],
2704
+ float(i+1)/stratification[5] * 20 - 10 + polarAngles[1], 'polarPhi',
2705
+ '../complex.xyz', useOldCv, extendedLagrangian = True,
2706
+ reflectingBoundary = reflectingBoundary
2707
+ )
2708
+ )
2709
+ colvarsConfig.write(
2710
+ self.cTemplate.cvABFTemplate('polarPhi', unit = unit)
2711
+ )
2712
+ if reweightAMD:
2713
+ colvarsConfig.write(
2714
+ self.cTemplate.cvReweightAMDTemplate('polarPhi')
2715
+ )
2716
+ if not reflectingBoundary:
2717
+ colvarsConfig.write(
2718
+ self.cTemplate.cvHarmonicWallsTemplate(
2719
+ 'polarPhi', float(i)/stratification[5] * 20 - 10 + polarAngles[1],
2720
+ float(i+1)/stratification[5] * 20 - 10 + polarAngles[1],
2721
+ unit = unit
2722
+ )
2723
+ )
2724
+ if considerRMSDCV:
2725
+ colvarsConfig.write(
2726
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2727
+ )
2728
+ colvarsConfig.write(
2729
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0, unit = unit)
2730
+ )
2731
+ colvarsConfig.write(
2732
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0, unit = unit)
2733
+ )
2734
+ colvarsConfig.write(
2735
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0.1, 0, unit = unit)
2736
+ )
2737
+ colvarsConfig.write(
2738
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0.1, polarAngles[0], unit = unit)
2739
+ )
2740
+ if pinDownPro:
2741
+ colvarsConfig.write(
2742
+ self.cTemplate.cvProteinTemplate(center, '../complex.xyz', unit = unit)
2743
+ )
2744
+
2745
+ # 007_r
2746
+ if not reweightAMD:
2747
+ # eq
2748
+ with open(f'{path}/BFEE/007_r/colvars_eq.{colvarPostfix}', 'w') as colvarsConfig:
2749
+ colvarsConfig.write(
2750
+ self.cTemplate.cvHeadTemplate('../complex.ndx')
2751
+ )
2752
+ colvarsConfig.write(
2753
+ self.cTemplate.cvRMSDTemplate(
2754
+ False, '', '', './complex_largeBox.xyz',
2755
+ extendedLagrangian = False,
2756
+ unit = unit
2757
+ )
2758
+ )
2759
+ colvarsConfig.write(
2760
+ self.cTemplate.cvAngleTemplate(
2761
+ False, 0, 0, 'eulerTheta', './complex_largeBox.xyz', useOldCv,
2762
+ extendedLagrangian = False
2763
+ )
2764
+ )
2765
+ colvarsConfig.write(
2766
+ self.cTemplate.cvAngleTemplate(
2767
+ False, 0, 0, 'eulerPhi', './complex_largeBox.xyz', useOldCv,
2768
+ extendedLagrangian = False
2769
+ )
2770
+ )
2771
+ colvarsConfig.write(
2772
+ self.cTemplate.cvAngleTemplate(
2773
+ False, 0, 0, 'eulerPsi', './complex_largeBox.xyz', useOldCv,
2774
+ extendedLagrangian = False
2775
+ )
2776
+ )
2777
+ colvarsConfig.write(
2778
+ self.cTemplate.cvAngleTemplate(
2779
+ False, 0, 0, 'polarTheta', './complex_largeBox.xyz', useOldCv,
2780
+ extendedLagrangian = False
2781
+ )
2782
+ )
2783
+ colvarsConfig.write(
2784
+ self.cTemplate.cvAngleTemplate(
2785
+ False, 0, 0, 'polarPhi', './complex_largeBox.xyz', useOldCv,
2786
+ extendedLagrangian = False
2787
+ )
2788
+ )
2789
+ colvarsConfig.write(
2790
+ self.cTemplate.cvRTemplate(
2791
+ False, 0, 0, extendedLagrangian = False, unit = unit
2792
+ )
2793
+ )
2794
+ if considerRMSDCV:
2795
+ colvarsConfig.write(
2796
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2797
+ )
2798
+ colvarsConfig.write(
2799
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0, unit = unit)
2800
+ )
2801
+ colvarsConfig.write(
2802
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0, unit = unit)
2803
+ )
2804
+ colvarsConfig.write(
2805
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0.1, 0, unit = unit)
2806
+ )
2807
+ colvarsConfig.write(
2808
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0.1, polarAngles[0], unit = unit)
2809
+ )
2810
+ colvarsConfig.write(
2811
+ self.cTemplate.cvHarmonicTemplate('polarPhi', 0.1, polarAngles[1], unit = unit)
2812
+ )
2813
+ colvarsConfig.write(
2814
+ self.cTemplate.cvProteinTemplate(centerLargeBox, './complex_largeBox.xyz', unit = unit)
2815
+ )
2816
+
2817
+ # abf
2818
+ for i in range(stratification[6]):
2819
+ with open(f'{path}/BFEE/007_r/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2820
+ colvarsConfig.write(
2821
+ self.cTemplate.cvHeadTemplate('../complex.ndx', reweightAMD=reweightAMD)
2822
+ )
2823
+ colvarsConfig.write(
2824
+ self.cTemplate.cvRMSDTemplate(
2825
+ False, '', '', './complex_largeBox.xyz',
2826
+ extendedLagrangian = False,
2827
+ unit = unit
2828
+ )
2829
+ )
2830
+ colvarsConfig.write(
2831
+ self.cTemplate.cvAngleTemplate(
2832
+ False, 0, 0, 'eulerTheta', './complex_largeBox.xyz', useOldCv,
2833
+ extendedLagrangian = False
2834
+ )
2835
+ )
2836
+ colvarsConfig.write(
2837
+ self.cTemplate.cvAngleTemplate(
2838
+ False, 0, 0, 'eulerPhi', './complex_largeBox.xyz', useOldCv,
2839
+ extendedLagrangian = False
2840
+ )
2841
+ )
2842
+ colvarsConfig.write(
2843
+ self.cTemplate.cvAngleTemplate(
2844
+ False, 0, 0, 'eulerPsi', './complex_largeBox.xyz', useOldCv,
2845
+ extendedLagrangian = False
2846
+ )
2847
+ )
2848
+ colvarsConfig.write(
2849
+ self.cTemplate.cvAngleTemplate(
2850
+ False, 0, 0, 'polarTheta', './complex_largeBox.xyz', useOldCv,
2851
+ extendedLagrangian = False
2852
+ )
2853
+ )
2854
+ colvarsConfig.write(
2855
+ self.cTemplate.cvAngleTemplate(
2856
+ False, 0, 0, 'polarPhi', './complex_largeBox.xyz', useOldCv,
2857
+ extendedLagrangian = False
2858
+ )
2859
+ )
2860
+ colvarsConfig.write(
2861
+ self.cTemplate.cvRTemplate(
2862
+ True, float(i)/stratification[6] * 24 - 2 + distance,
2863
+ float(i+1)/stratification[6] * 24 - 2 + distance,
2864
+ extendedLagrangian = True, reflectingBoundary = reflectingBoundary,
2865
+ unit = unit
2866
+ )
2867
+ )
2868
+ colvarsConfig.write(
2869
+ self.cTemplate.cvABFTemplate('r', unit = unit)
2870
+ )
2871
+ if reweightAMD:
2872
+ colvarsConfig.write(
2873
+ self.cTemplate.cvReweightAMDTemplate('r')
2874
+ )
2875
+ if not reflectingBoundary:
2876
+ colvarsConfig.write(
2877
+ self.cTemplate.cvHarmonicWallsTemplate(
2878
+ 'r', float(i)/stratification[6] * 24 - 2 + distance,
2879
+ float(i+1)/stratification[6] * 24 - 2 + distance,
2880
+ unit = unit
2881
+ )
2882
+ )
2883
+ if considerRMSDCV:
2884
+ colvarsConfig.write(
2885
+ self.cTemplate.cvHarmonicTemplate('RMSD', 10, 0, unit = unit)
2886
+ )
2887
+ colvarsConfig.write(
2888
+ self.cTemplate.cvHarmonicTemplate('eulerTheta', 0.1, 0, unit = unit)
2889
+ )
2890
+ colvarsConfig.write(
2891
+ self.cTemplate.cvHarmonicTemplate('eulerPhi', 0.1, 0, unit = unit)
2892
+ )
2893
+ colvarsConfig.write(
2894
+ self.cTemplate.cvHarmonicTemplate('eulerPsi', 0.1, 0, unit = unit)
2895
+ )
2896
+ colvarsConfig.write(
2897
+ self.cTemplate.cvHarmonicTemplate('polarTheta', 0.1, polarAngles[0], unit = unit)
2898
+ )
2899
+ colvarsConfig.write(
2900
+ self.cTemplate.cvHarmonicTemplate('polarPhi', 0.1, polarAngles[1], unit = unit)
2901
+ )
2902
+ if pinDownPro:
2903
+ colvarsConfig.write(
2904
+ self.cTemplate.cvProteinTemplate(centerLargeBox, './complex_largeBox.xyz', unit = unit)
2905
+ )
2906
+
2907
+ # 008_RMSDUnbound
2908
+ if considerRMSDCV:
2909
+ for i in range(stratification[7]):
2910
+ with open(f'{path}/BFEE/008_RMSDUnbound/colvars_{i+1}.{colvarPostfix}', 'w') as colvarsConfig:
2911
+ colvarsConfig.write(
2912
+ self.cTemplate.cvHeadTemplate('./ligandOnly.ndx', reweightAMD=reweightAMD)
2913
+ )
2914
+ colvarsConfig.write(
2915
+ self.cTemplate.cvRMSDTemplate(
2916
+ True, float(i)/stratification[7] * 3.0, float(i+1)/stratification[7] * 3.0, './ligandOnly.xyz',
2917
+ extendedLagrangian = True, reflectingBoundary = reflectingBoundary,
2918
+ unit = unit
2919
+ )
2920
+ )
2921
+ colvarsConfig.write(
2922
+ self.cTemplate.cvABFTemplate('RMSD', unit = unit)
2923
+ )
2924
+ if reweightAMD:
2925
+ colvarsConfig.write(
2926
+ self.cTemplate.cvReweightAMDTemplate('RMSD')
2927
+ )
2928
+ if not reflectingBoundary:
2929
+ colvarsConfig.write(
2930
+ self.cTemplate.cvHarmonicWallsTemplate(
2931
+ 'RMSD', float(i)/stratification[7] * 3.0, float(i+1)/stratification[7] * 3.0,
2932
+ unit = unit
2933
+ )
2934
+ )
2935
+
2936
+ def _duplicateFileFolder(self, path, number):
2937
+ """duplicate the ./BFEE folder
2938
+
2939
+ Args:
2940
+ path (string): the directory for generation of all the files
2941
+ number (int): the number of copies
2942
+
2943
+ Raises:
2944
+ DirectoryExistError: if {path}/BFEE_{i} exists
2945
+ """
2946
+ for i in range(number - 1):
2947
+ if os.path.exists(f'{path}/BFEE_{i}'):
2948
+ raise DirectoryExistError('Directory exists')
2949
+ shutil.copytree(f'{path}/BFEE', f'{path}/BFEE_{i}')