bfee2 2.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bfee2 might be problematic. Click here for more details.

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