1 #!/bin/env python
2 #
3 # File: OpenFECalculateAbsoluteHydrationFreeEnergy.py
4 # Author: Manish Sud <msud@san.rr.com>
5 #
6 # Copyright (C) 2026 Manish Sud. All rights reserved.
7 #
8 # The functionality available in this script is implemented using OpenFE, an
9 # open source package for alchemical free energy calculations.
10 #
11 # This file is part of MayaChemTools.
12 #
13 # MayaChemTools is free software; you can redistribute it and/or modify it under
14 # the terms of the GNU Lesser General Public License as published by the Free
15 # Software Foundation; either version 3 of the License, or (at your option) any
16 # later version.
17 #
18 # MayaChemTools is distributed in the hope that it will be useful, but without
19 # any warranty; without even the implied warranty of merchantability of fitness
20 # for a particular purpose. See the GNU Lesser General Public License for more
21 # details.
22 #
23 # You should have received a copy of the GNU Lesser General Public License
24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
26 # Boston, MA, 02111-1307, USA.
27 #
28
29 from __future__ import print_function
30
31 import os
32 import sys
33 import time
34 import re
35 import logging
36 import pathlib
37 import pandas as pd
38
39 # OpenFE imports...
40 try:
41 import openfe
42 from openfe.protocols.openmm_afe import AbsoluteSolvationProtocol
43 except ImportError as ErrMsg:
44 sys.stderr.write("\nFailed to import OpenFE related module/package: %s\n" % ErrMsg)
45 sys.stderr.write("Check/update your OpenFE environment and try again.\n\n")
46 sys.exit(1)
47
48 # RDKit imports...
49 try:
50 from rdkit import rdBase
51 except ImportError as ErrMsg:
52 sys.stderr.write("\nFailed to import RDKit module/package: %s\n" % ErrMsg)
53 sys.stderr.write("Check/update your RDKit environment and try again.\n\n")
54 sys.exit(1)
55
56 # MayaChemTools imports...
57 sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "..", "lib", "Python"))
58 try:
59 from docopt import docopt
60 import MiscUtil
61 import OpenFEUtil
62 except ImportError as ErrMsg:
63 sys.stderr.write("\nFailed to import MayaChemTools module/package: %s\n" % ErrMsg)
64 sys.stderr.write("Check/update your MayaChemTools environment and try again.\n\n")
65 sys.exit(1)
66
67 ScriptName = os.path.basename(sys.argv[0])
68 Options = {}
69 OptionsInfo = {}
70
71
72 def main():
73 """Start execution of the script."""
74
75 MiscUtil.PrintInfo(
76 "\n%s (OpenFE v%s; OpenMM v%s; RDKit v%s; MayaChemTools v%s; %s): Starting...\n"
77 % (
78 ScriptName,
79 openfe.version("openfe"),
80 openfe.version("openmm"),
81 rdBase.rdkitVersion,
82 MiscUtil.GetMayaChemToolsVersion(),
83 time.asctime(),
84 )
85 )
86
87 (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime()
88
89 # Retrieve command line arguments and options...
90 RetrieveOptions()
91
92 if Options["--list"]:
93 ProcessListOption()
94 else:
95 # Process and validate command line arguments and options...
96 ProcessOptions()
97
98 # Perform actions required by the script...
99 CalculateAbsoluteHydrationFreeEnergy()
100
101 MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName)
102 MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime))
103
104
105 def CalculateAbsoluteHydrationFreeEnergy():
106 """Calculate absolute hydration free energy."""
107
108 # Process input file...
109 InMols = ProcessInputFile()
110
111 # Process molecule names...
112 Mols = ProcessMoleculeNames(InMols)
113
114 # Check for miising partial charges...
115 CheckMissingPartialCharges(Mols)
116
117 # Initialize AHFE protocols...
118 AHFEProtocol = InitializeAbsoluteSolvationProtocol()
119
120 # Initialize solvent...
121 Solvent = InitializeSolventComponent()
122
123 # Setup transformations...
124 MolTransformations = SetupTransformations(Mols, Solvent, AHFEProtocol)
125
126 # Setup protocol DAGs...
127 MolProtocolDAGs = SetupProtocolDAGs(MolTransformations)
128
129 # Execute protocol DAGs and gather results...
130 MolProtocolResults = ExecuteProtocolDAGsAndGatherResults(MolTransformations, MolProtocolDAGs)
131
132 # Process protocol results...
133 ProcessProtocolResults(MolTransformations, MolProtocolResults)
134
135
136 def InitializeAbsoluteSolvationProtocol():
137 """Initialize absolute solvation protocol."""
138
139 MiscUtil.PrintInfo("\nInitializing absolute solvation protocol...")
140
141 AHFESettings = OpenFEUtil.SetupAbsoluteHydrationFreeEnergySettings("-a, --ahfeParams", OptionsInfo["AHFEParams"])
142 AHFEProtocol = OpenFEUtil.InitializeAbsoluteSolvationFreeEngeryProtocol(AHFESettings)
143
144 return AHFEProtocol
145
146
147 def InitializeSolventComponent():
148 """Initialize solvent component."""
149
150 SolventParams = OptionsInfo["SolventParams"]
151 MiscUtil.PrintInfo(
152 "\nInitializing solvent component (PositiveIon: %s; NegativeIon: %s; Neutralize: %s; IonConcentration: %s)..."
153 % (
154 SolventParams["PositiveIon"],
155 SolventParams["NegativeIon"],
156 SolventParams["Neutralize"],
157 SolventParams["IonConcentration"],
158 )
159 )
160
161 Solvent = OpenFEUtil.InitializeSolventComponent(SolventParams)
162
163 return Solvent
164
165
166 def SetupTransformations(Mols, Solvent, AHFEProtocol):
167 """Set up transformations for molecules."""
168
169 MiscUtil.PrintInfo("\nSetting up transformations (Count: %s)..." % (len(Mols)))
170
171 MolTransformations = []
172
173 for Mol in Mols:
174 # Setup a chemical system for a molecule fully interacting in the solvent...
175 MolSolventSystem = OpenFEUtil.InitializeChemicalSystem(
176 SmallMol=Mol, MacroMol=None, Solvent=Solvent, Name="%s_Solvent" % Mol.name
177 )
178
179 # Setup a system for a molecule fully decoupled in the solvent: Only need to use the solvent....
180 SolventOnlySystem = OpenFEUtil.InitializeChemicalSystem(
181 SmallMol=None, MacroMol=None, Solvent=Solvent, Name="Solvent_Only"
182 )
183
184 # Setup a transformation for absolute solvation protocol from MolSolvent to SolventOnly
185 # as the vacuum modelling is automatically handled by AbsoluteSolvationProtocol...
186 TransformationName = "%s_AbsoluteSolvation" % (Mol.name)
187 MolTransformation = OpenFEUtil.InitializeTransformation(
188 StateA=MolSolventSystem,
189 StateB=SolventOnlySystem,
190 Mapping=None,
191 Protocol=AHFEProtocol,
192 Name=TransformationName,
193 Validate=False,
194 )
195
196 MolTransformations.append(MolTransformation)
197
198 # Write out transformatios...
199 WriteTransformations(MolTransformations)
200
201 return MolTransformations
202
203
204 def WriteTransformations(MolTransformations):
205 """Write out transformations."""
206
207 TransformationsOutDirPath = pathlib.Path(OptionsInfo["TransformationsOutDirPath"])
208
209 MiscUtil.PrintInfo(
210 "Writing transformations files (Files: *.json; Count: %s; Subdirectory: %s)..."
211 % (len(MolTransformations), OptionsInfo["TransformationsOutDir"])
212 )
213
214 for Transformation in MolTransformations:
215 TransformationFilePath = TransformationsOutDirPath.joinpath("%s.json" % Transformation.name)
216 Transformation.dump(TransformationFilePath)
217
218
219 def SetupProtocolDAGs(MolTransformations):
220 """Setup protocol Directed Acyclic Graphs (DAGs) for each transformation to
221 to perform calculations.
222 """
223
224 MiscUtil.PrintInfo("\nSetting up protocol DAGs (Count: %s)..." % len(MolTransformations))
225
226 MolProtocolDAGs = []
227 for Transformation in MolTransformations:
228 ProtocolDAG = OpenFEUtil.InitializeProtocolDAG(Transformation, Name=Transformation.name)
229 MolProtocolDAGs.append(ProtocolDAG)
230
231 return MolProtocolDAGs
232
233
234 def ExecuteProtocolDAGsAndGatherResults(MolTransformations, MolProtocolDAGs):
235 """Execute protocol DAGs and gather results."""
236
237 ResultsSharedOutDirPath = OptionsInfo["ResultsOutDirPath"]
238 ResultsScratchOutDirPath = OptionsInfo["ResultsScratchOutDirPath"]
239 ExecuteDAGParams = OptionsInfo["ExecuteDAGParams"]
240
241 MolProtocolResults = OpenFEUtil.ExecuteProtocolDAGsAndGatherResults(
242 MolTransformations,
243 MolProtocolDAGs,
244 ResultsSharedOutDirPath,
245 ResultsScratchOutDirPath,
246 KeepShared=ExecuteDAGParams["KeepShared"],
247 KeepScratch=ExecuteDAGParams["KeepScratch"],
248 NRetries=ExecuteDAGParams["NRetries"],
249 WriteResults=True,
250 )
251
252 return MolProtocolResults
253
254
255 def ProcessProtocolResults(MolTransformations, MolProtocolResults):
256 """Process protocol results."""
257
258 ResultFileParams = OptionsInfo["ResultFileParams"]
259
260 ResultFile = "%s_AHFE_Results.%s" % (OptionsInfo["OutfilePrefix"], ResultFileParams["Ext"])
261 ResultFilePath = os.path.join(OptionsInfo["OutfileDirPath"], ResultFile)
262 MiscUtil.PrintInfo("\nWriting %s..." % ResultFile)
263
264 Precision = ResultFileParams["Precision"]
265
266 ResultData = []
267 for Index in range(0, len(MolProtocolResults), 1):
268 MolProtocolResult = MolProtocolResults[Index]
269
270 # Setup mol name using transformation...
271 MolTransformation = MolTransformations[Index]
272 Mol = MolTransformation.stateA.components["ligand"]
273 MolName = Mol.name
274
275 if MolProtocolResult is None:
276 DeltaGHydration = "NA"
277 DeltaGHydrationUncertainty = "NA"
278 else:
279 # Setup hydration value without the units...
280 DeltaGHydration = MolProtocolResult.get_estimate()
281 DeltaGHydration = "%.*f" % (Precision, DeltaGHydration.m)
282
283 # Setup uncertainty value without the units...
284 DeltaGHydrationUncertainty = MolProtocolResult.get_uncertainty()
285 DeltaGHydrationUncertainty = "%.*f" % (Precision, DeltaGHydrationUncertainty.m)
286
287 ResultData.append([MolName, DeltaGHydration, DeltaGHydrationUncertainty])
288
289 ResultDF = pd.DataFrame(ResultData, columns=["MolName", "AHFE DeltaG (kcal/mol)", "Uncertainty (kcal/mol)"])
290 ResultDF.to_csv(ResultFilePath, sep=ResultFileParams["Delim"], lineterminator="\n", index=False)
291
292
293 def ProcessInputFile():
294 """Process input file."""
295
296 # Read small molecule input file...
297 MiscUtil.PrintInfo("\nReading small molecule file %s..." % OptionsInfo["Infile"])
298 Mols, MolCount, ValidMolCount = OpenFEUtil.ReadAndValidateMolecules(
299 OptionsInfo["InfilePath"], **OptionsInfo["InfileParams"]
300 )
301
302 MiscUtil.PrintInfo("\nTotal number of molecules: %d" % MolCount)
303 MiscUtil.PrintInfo("Number of valid molecules: %d" % ValidMolCount)
304 MiscUtil.PrintInfo("Number of ignored molecules: %d" % (MolCount - ValidMolCount))
305
306 if ValidMolCount == 0:
307 MiscUtil.PrintInfo("")
308 MiscUtil.PrintError("No valid molecules found in small molecule input file.\n")
309
310 return Mols
311
312
313 def ProcessMoleculeNames(Mols):
314 """Process molecule names."""
315
316 SpecifiedMols = []
317 if OptionsInfo["FirstMoleculeMode"]:
318 SpecifiedMols.append(Mols[0])
319 elif OptionsInfo["AllMoleculesMode"]:
320 SpecifiedMols = Mols
321 elif OptionsInfo["MoleculesNamesMode"]:
322 SpecifiedMols = OpenFEUtil.ProcessMoleculeNames(Mols, OptionsInfo["MoleculeNamesList"])
323
324 return SpecifiedMols
325
326
327 def CheckMissingPartialCharges(Mols):
328 """Check missing partial charges for small molecules."""
329
330 MiscUtil.PrintInfo("\nChecking missing partial charges for small molecules...")
331
332 MissingChargesMolCount = OpenFEUtil.GetMissingPartialChargesMolCount(Mols)
333 MiscUtil.PrintInfo("Number of molecules with missing partial charges: %s" % MissingChargesMolCount)
334
335 if MissingChargesMolCount == 0:
336 return
337
338 if re.match("^Stop$", OptionsInfo["MissingChargeMode"], re.I):
339 MiscUtil.PrintInfo("")
340 MiscUtil.PrintError(
341 'The small molecule input file contains molecules with missing partial charges. The execution of the script has been terminated for "Stop" value of "--missingChargedMode" option. You may continue the execution of the script by specifying "Calculate" value for "--missingChargedMode" option.\n\nThe missing charges will be automatically calculated by OpenFE AbsoluteSolvationProtocol module during the calculation of AHFE. You may control the calculation of partial charges by specifying values for partialCharge* parameters using "--ahfeParams" option. Alternatively, you may employ the OpenFECalculatePartialCharges.py script to calculate partial charges and use the small molecule input file containing charges to calculate AHFE.\n'
342 )
343 else:
344 MiscUtil.PrintInfo("")
345 MiscUtil.PrintWarning(
346 'The small molecule input file contains molecules with missing partial charges. The missing charges will be automatically calculated by OpenFE AbsoluteSolvationProtocol module during the calculation of AHFE. You may control the calculation of partial charges by specifying values for partialCharge* parameters using "--ahfeParams" option. Alternatively, you may employ the OpenFECalculatePartialCharges.py script to calculate partial charges and use the small molecule input file containing charges to calculate AHFE.\n'
347 )
348
349
350 def ProcessMoleculeNamesOption():
351 """Process molecule names Option."""
352
353 OptionsInfo["MoleculeNames"] = Options["--moleculeNames"]
354 OptionsInfo["MoleculeNamesList"] = None
355
356 if OptionsInfo["MoleculeNames"] is None:
357 return
358
359 MoleculeNamesList = []
360 for MoleculeName in OptionsInfo["MoleculeNames"].split(","):
361 MoleculeNamesList.append(MoleculeName.strip())
362
363 OptionsInfo["MoleculeNamesList"] = MoleculeNamesList
364
365
366 def ProcessOutfilePrefixOption():
367 """Process outfile prefix option."""
368
369 OutfilePrefix = Options["--outfilePrefix"]
370
371 if re.match("^auto$", OutfilePrefix, re.I):
372 OutfilePrefix = OptionsInfo["InfileRoot"]
373
374 OptionsInfo["OutfilePrefix"] = OutfilePrefix
375
376
377 def ProcessOutfileDirOption():
378 """Process outfile directory Option."""
379
380 # Setup output directory...
381 OutfileDir = Options["--outfileDir"]
382 OutfileDirPath = os.path.abspath(OutfileDir)
383 if not os.path.exists(OutfileDir):
384 MiscUtil.PrintInfo("\nCreating output directory %s..." % (OutfileDir))
385 os.mkdir(OutfileDirPath)
386 OptionsInfo["OutfileDir"] = OutfileDir
387 OptionsInfo["OutfileDirPath"] = OutfileDirPath
388
389 # Setup a transformations subdirectory...
390 TransformationsOutDir = "Transformations"
391 TransformationsOutDirPath = os.path.join(OptionsInfo["OutfileDirPath"], TransformationsOutDir)
392 if not os.path.exists(TransformationsOutDirPath):
393 os.mkdir(TransformationsOutDirPath)
394 OptionsInfo["TransformationsOutDir"] = TransformationsOutDir
395 OptionsInfo["TransformationsOutDirPath"] = TransformationsOutDirPath
396
397 # Setup a results subdirectory...
398 ResultsOutDir = "Results"
399 ResultsOutDirPath = os.path.join(OptionsInfo["OutfileDirPath"], ResultsOutDir)
400 if not os.path.exists(ResultsOutDirPath):
401 os.mkdir(ResultsOutDirPath)
402 OptionsInfo["ResultsOutDir"] = ResultsOutDir
403 OptionsInfo["ResultsOutDirPath"] = ResultsOutDirPath
404
405 # Use results subdirectory for scratch results...
406 OptionsInfo["ResultsScratchOutDir"] = ResultsOutDir
407 OptionsInfo["ResultsScratchOutDirPath"] = ResultsOutDirPath
408
409
410 def ProcessListOption():
411 """Process list protocol settings option."""
412
413 AHFESettings = AbsoluteSolvationProtocol.default_settings()
414
415 MiscUtil.PrintInfo("\nListing AHFE settings...")
416 OpenFEUtil.ListOpenFESettings(AHFESettings)
417
418
419 def ConfigureLogging():
420 """Configure logging."""
421
422 OptionsInfo["LoggingLevel"] = Options["--loggingLevel"]
423
424 if re.match("^Error$", OptionsInfo["LoggingLevel"], re.I):
425 LoggingLevel = logging.ERROR
426 elif re.match("^Warning$", OptionsInfo["LoggingLevel"], re.I):
427 LoggingLevel = logging.WARNING
428 else:
429 LoggingLevel = logging.INFO
430
431 logging.basicConfig(format="%(levelname)s: %(message)s", level=LoggingLevel)
432
433 # Turn warnings issued by warnings.warn() into log message to avoid display
434 # of a stack trace...
435 logging.captureWarnings(True)
436
437
438 def ProcessOptions():
439 """Process and validate command line arguments and options."""
440
441 MiscUtil.PrintInfo("Processing options...")
442
443 # Validate options...
444 ValidateOptions()
445
446 # Configure logging...
447 ConfigureLogging()
448
449 OptionsInfo["Infile"] = Options["--infile"]
450 OptionsInfo["InfilePath"] = os.path.abspath(OptionsInfo["Infile"])
451 FileDir, FileName, FileExt = MiscUtil.ParseFileName(OptionsInfo["Infile"])
452 OptionsInfo["InfileRoot"] = FileName
453
454 ParamsDefaultInfoOverride = {"RemoveHydrogens": False}
455 OptionsInfo["InfileParams"] = MiscUtil.ProcessOptionInfileParameters(
456 "--infileParams",
457 Options["--infileParams"],
458 InfileName=Options["--infile"],
459 ParamsDefaultInfo=ParamsDefaultInfoOverride,
460 )
461
462 ParamsDefaultInfoOverride = {"SolventEngineComputePlatform": "CPU", "VacuumEngineComputePlatform": "CPU"}
463 ParamsDefaultInfoOverride = None
464 OptionsInfo["AHFEParams"] = OpenFEUtil.ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters(
465 "--ahfeParams", Options["--ahfeParams"], ParamsDefaultInfo=ParamsDefaultInfoOverride
466 )
467
468 OptionsInfo["ExecuteDAGParams"] = OpenFEUtil.ProcessOptionOpenFEExecuteDAGParameters(
469 "--executeDAGParams", Options["--executeDAGParams"]
470 )
471 OptionsInfo["LoggingLevel"] = Options["--loggingLevel"]
472
473 OptionsInfo["Mode"] = OpenFEUtil.ProcessOptionOpenFEAbsoluteFreeEnergyMode("-m, --mode", Options["--mode"])
474 OptionsInfo["FirstMoleculeMode"] = True if re.match("^FirstMolecule$", OptionsInfo["Mode"], re.I) else False
475 OptionsInfo["AllMoleculesMode"] = True if re.match("^AllMolecules$", OptionsInfo["Mode"], re.I) else False
476 OptionsInfo["MoleculesNamesMode"] = True if re.match("^MoleculeNames$", OptionsInfo["Mode"], re.I) else False
477
478 OptionsInfo["MissingChargeMode"] = OpenFEUtil.ProcessOptionOpenFEMissingChargeMode(
479 "--missingChargeMode", Options["--missingChargeMode"]
480 )
481
482 ProcessMoleculeNamesOption()
483
484 OptionsInfo["ResultFileParams"] = OpenFEUtil.ProcessOptionOpenFEResultFileParameters(
485 "--resultFileParams", Options["--resultFileParams"]
486 )
487 OptionsInfo["SolventParams"] = OpenFEUtil.ProcessOptionOpenFESolventParameters(
488 "--solventParams", Options["--solventParams"]
489 )
490
491 ProcessOutfilePrefixOption()
492 ProcessOutfileDirOption()
493
494 OptionsInfo["Overwrite"] = Options["--overwrite"]
495
496 # Track top level working directory...
497 OptionsInfo["TopWorkingDir"] = os.getcwd()
498
499
500 def RetrieveOptions():
501 """Retrieve command line arguments and options."""
502
503 # Get options...
504 global Options
505 Options = docopt(_docoptUsage_)
506
507 # Set current working directory to the specified directory...
508 WorkingDir = Options["--workingdir"]
509 if WorkingDir:
510 os.chdir(WorkingDir)
511
512 # Handle examples option...
513 if "--examples" in Options and Options["--examples"]:
514 MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(_docoptUsage_))
515 sys.exit(0)
516
517
518 def ValidateOptions():
519 """Validate option values."""
520
521 MiscUtil.ValidateOptionFilePath("-i, --infile", Options["--infile"])
522 MiscUtil.ValidateOptionFileExt("-i, --infile", Options["--infile"], "sdf sd")
523
524 MiscUtil.ValidateOptionDirPath("-o, --outfileDir", Options["--outfileDir"])
525 MiscUtil.ValidateOptionsOutputDirOverwrite(
526 "-o, --outfileDir", Options["--outfileDir"], "--overwrite", Options["--overwrite"]
527 )
528
529 MiscUtil.ValidateOptionTextValue("--loggingLevel", Options["--loggingLevel"], "Info Warning Error")
530
531 MiscUtil.ValidateOptionTextValue("-m, --mode", Options["--mode"], "FirstMolecule AllMolecules MoleculeNames")
532 MiscUtil.ValidateOptionTextValue("--missingChargeMode", Options["--missingChargeMode"], "Calculate Stop")
533
534 if re.match("^MoleculeNames$", Options["--mode"], re.I):
535 if MiscUtil.IsEmpty(Options["--moleculeNames"]):
536 MiscUtil.PrintError(
537 'You must specify a value for "--moleculeNames" option during, MoleculeNames, value for "-m, --mode" option.'
538 )
539
540
541 # Setup a usage string for docopt...
542 _docoptUsage_ = """
543 OpenFECalculateAbsoluteHydrationFreeEnergy.py - Calculate absolute hydration free energy
544
545 Usage:
546 OpenFECalculateAbsoluteHydrationFreeEnergy.py [--ahfeParams <Name,Value,...>] [--executeDAGParams <Name,Value,..>]
547 [--infileParams <Name,Value,...>] [--loggingLevel <Info, Warning or Error>] [--mode <FirstMolecule, AllMolecules, or ...>]
548 [--missingChargeMode <Calculate or Stop>] [--moleculeNames <MolName1,MolName2,..>] [--outfilePrefix <text>]
549 [--resultFileParams <Name,Value,..>] [--solventParams <Name,Value,...>] [--overwrite]
550 [-w <dir>] -i <infile> -o <outifiledir>
551 OpenFECalculateAbsoluteHydrationFreeEnergy.py -l | --list
552 OpenFECalculateAbsoluteHydrationFreeEnergy.py -h | --help | -e | --examples
553
554 Description:
555 Calculate Absolute Hydration Free Energy (AHFE) for molecules in a small
556 molecule input file. You may calculate AHFEs for specific molecules or all
557 molecules in the input file.
558
559 The small molecule input file must contain molecules already prepared for
560 simulation. It must contain appropriate 3D coordinates along with no missing
561 hydrogens.
562
563 The MD simulation workflow, employed for the calculation of AHFEs, involves
564 the following steps: initial minimization; NVT equilibration; NPT equilibration;
565 production NPT. The MD simulation protocol is repeated 3 times for solvent
566 transformation from MolSolventToSolventOnly and vacumm simulation, and
567 he results are analyzed to estimate AHFEs. The default time and step size
568 settings for the MD protocol are shown below:
569
570 Protocol repeats, 3
571
572 Time step size: 4.0 femtosecond
573
574 Solvent equilibration phase:
575
576 Max minimization steps: 5,000
577 NVT equilibration length: 0.1 nanosecond
578 NPT equilibration length: 0.2 nanosecond
579 NPT length: 0.5 nanosecond
580
581 Solvent production phase:
582
583 Max minimization steps: 5,000
584 NPT equilibration length: 1.0 nanosecond
585 NPT length: 10.0 nanosecond
586
587 Vacuum equilibration phase:
588
589 Max minimization steps: 5,000
590 NVT equilibration length: None
591 NPT equilibration length: 0.2 nanosecond
592 NPT length: 0.5 nanosecond
593
594 Vacuum production phase:
595
596 Max minimization steps: 5,000
597 NVT equilibration length: None
598 NPT equilibration length: 0.5 nanosecond
599 NPT length: 2.0 nanosecond
600
601 Each solvent and vacuum simulation, by default, may run for 11.8 and 3.2
602 nanosecond respectively, for a total of 15 nanoseconds. The total MD
603 simulation time for correspond to 45 nanosecond to repeat the protocol
604 3 times for the solvent and vacuum simulations.
605
606 Possible outfile prefix:
607
608 <OutfilePrefix> or <InfileRoot>
609
610 Possible output directories:
611
612 <OutfileDir>
613
614 <OutfileDir>/Transformations
615 <OutfileDir>/Results
616
617 Possible output files and directories under <OutfileDir>:
618
619 <OutfilePrefix>_AHFE_Results.<csv or tsv>
620
621 Transformations/<MolName>_Solvent_To_Solvent_Only.json
622 ... ... ...
623
624 Results/<MolName>_AbsoluteSolvation_Results.json
625
626 Results/shared_AbsoluteSolvationSolventUnit-*/
627 Results/scratch_AbsoluteSolvationVacuumUnit-*/
628 ... ... ...
629
630 Options:
631 -a, --ahfeParams <Name,Value,...> [default: auto]
632 A comma delimited list of parameter name and value pairs for AHFE protocol
633 settings employed during the calculation of AHFEs.
634
635 The default values are automatically updated to match settings provided by
636 OpenFE module AbsoluteSolvationProtocol.
637
638 You must specify valid OpenFE values for these parameters. An extensive
639 validation is not performed.
640
641 The supported parameter names along with their default values are
642 are shown below:
643
644 protocolRepeats, 3
645
646 Integrator settings:
647
648 integratorBarostatFrequency, 25.0 * timestep [ The specified value
649 is a multiple of integratorTimestep. ]
650 integratorConstraintTolerance, 1e-06
651 integratorLangevinCollisionRate, 1.0 [ Units: 1 / picosecond ]
652 integratorNRestartAttempts, 20
653 integratorReassignVelocities, no [ Possible values: yes or no ]
654 integratorRemoveCom, no [ Possible values: yes or no ]
655 integratorTimestep, 4.0 [ Units: femtosecond ]
656
657 Lambda settings:
658
659 lambdaElec, 0.0 0.25 0.5 0.75 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
660 1.0 [ Possible values: A space delimited list of values
661 between 0.0 and 1.0 ]
662 lambdaRestraints, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
663 0.0 0.0 [ Possible values: A space delimited list of values
664 between 0.0 and 1.0 ]
665 lambdaVdw, [0.0 0.0 0.0 0.0 0.0 0.12 0.24 0.36 0.48 0.6 0.7 0.77
666 0.85 1.0 [ Possible values: A space delimited list of values
667 between 0.0 and 1.0 ]
668
669 Partial charge settings:
670
671 partialChargeNaglModel, None [ Default: Production AM1BCC model for
672 NAGL; Possible value: Any valid name. ]
673 partialChargeNumberOfConformers, None [ Possible value: > 0 ]
674 partialChargeOffToolkitBackend, AmberTools [ Possible values:
675 AmberTools or RDKit ]
676 partialChargeMethod, AM1BCC [ Possble values: AM1BCC, Espaloma,
677 or NAGL ]
678
679 Solvation settings:
680
681 solvationBoxShape, dodecahedron [ Possible values: cube,
682 dodecahedron, or octahedron ]
683 solvationBoxSize, None [ Possible value: A triplet of space
684 X Y Z values; Units: nanometer ]
685 solvationSolventModel, tip3p [ Possible values: tip3p, spce, tip4pew,
686 or tip5p ]
687 solvationSolventPadding, 1.5 [ Units: nanometer ]
688
689 Solvent engine settings:
690
691 solventEngineComputePlatform, CPU [ Possible values: CPU, CUDA,
692 OpenCL, or Reference ]
693 solventEngineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
694
695 Solvent equil output settings:
696
697 solventEquilOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
698 solventEquilOutputCheckpointStorageFilename, checkpoint.chk
699 solventEquilOutputNPTStructure, equil_npt_structure.pdb
700 solventEquilOutputNVTStructure, equil_nvt_structure.pdb
701 solventEquilOutputForcefieldCache, db.json
702 solventEquilOutputLogOutput, equil_simulation.log
703 solventEquilOutputMinimizedStructure, minimized.pdb
704 solventEquilOutputIndices, not water [ Possible value: Any valid
705 selection. ]
706 solventEquilOutputPreminimizedStructure, system.pdb
707 solventEquilOutputProductionTrajectoryFilename, production_equil.xtc
708 solventEquilOutputTrajectoryWriteInterval, 20.0 [ Units: picosecond ]
709
710 Solvent equil simulation settings:
711
712 solventEquilSimulationEquilLength, 0.2 [ Units: nanosecond ]
713 solventEquilSimulationEquiLengthNVT, 0.1 [ Units: nanosecond ]
714 solventEquilSimulationMinimizationSteps,5000
715 solventEquilSimulationProductionLength,0.5 [ Units: nanosecond ]
716
717 Solvent forcefield settings:
718
719 solventForcefieldConstraints, HBonds [ Possible values: HBonds,
720 AllBonds, or HAngles ]
721 solventForcefields, amber/ff14SB.xml, amber/tip3p_standard.xml
722 amber/tip3p_HFE_multivalent.xml amber/phosaa10.xml
723 [ Possible values: A space delimited list of valid names. ]
724 solventForcefieldHydrogenMass, 3.0 [ Units: amu ]
725 solventForcefieldNonbondedCutoff,0.9 [ Units: nanometer ]
726 solventForcefieldNonbondedMethod, PME [ Possible values: PME or
727 NoCutoff ]
728 solventForcefieldRigidWater, yes, [ Possible values: yes or no ]
729 solventForcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible
730 value: A valid forcefield name. ]
731
732 Solvent output settings:
733
734 solventOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
735 solventOutputCheckpointStorageFilename, solvent_checkpoint.nc
736 solventOutputForcefieldCache, db.json
737 solventOutputFilename, solvent.nc
738 solventOutputIndices, not water [ Possible value: Any valid
739 selection. ]
740 solventOutputStructure, hybrid_system.pdb
741 solventOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
742 solventOutputVelocitiesWriteFrequency, None [ Possible
743 values: > 0; Units: picosecond ]
744
745 Solvent simulation settings:
746
747 solventSimulationEarlyTerminationTargetError, 0.0 [ Units:
748 kilocalorie_per_mole ]
749 solventSimulationEquilibrationLength, 1.0 [ Units: nanosecond ]
750 solventSimulationMinimizationSteps, 5000
751 solventSimulationNReplicas, 14
752 solventSimulationProductionLength, 10.0 [ Units: nanosecond ]
753 solventSimulationRealTimeAnalysisInterval, 250.0 [ Units:
754 picosecond ]
755 solventSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units:
756 picosecond
757 solventSimulationSamplerMethod, repex [ Possible values: repex,
758 sams, or independent ]
759 solventSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
760 values: logZ-flatness, minimum-visits or histogram-flatness ]
761 solventSimulationsamsGamma0, 1.0
762 solventSimulationTimePerIteration,2.5 [ Units: picosecond ]
763
764 Thermo settings:
765
766 thermoPh, None [ Possible values: > 0 ]
767 thermoPressure, 1.0 [ Units: bar ]
768 thermoRedoxPotential, None [ Possible values: A valid float.
769 Units: millivolts (mV) ]
770 thermoTemperature, 298.15 [ Units: kelvin ]
771
772 Vacuum engine settings:
773
774 vacuumEngineComputePlatform, CPU [ Possible values: CPU, CUDA,
775 OpenCL, or Reference ]
776 vacummEngineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
777
778 Vacuum equil output settings:
779
780 vacuumEquilOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
781 vacuumEquilOutputCheckpointStorageFilename, checkpoint.chk
782 vacuumEquilOutputNPTStructure, equil_structure.pdb
783 vacuumEquilOutputNVTStructure,None
784 vacuumEquilOutputForcefieldCache, db.json
785 vacuumEquilOutputLogOutput, equil_simulation.log
786 vacuumEquilOutputMinimizedStructure, minimized.pdb
787 vacuumEquilOutputIndices, not water [ Possible value: Any valid
788 selection. ]
789 vacuumEquilOutputPreminimizedStructure, system.pdb
790 vacuumEquilOutputProductionTrajectoryFilename, production_equil.xtc
791 vacuumEquilOutputTrajectoryWriteInterval, 20.0 [ Units: picosecond ]
792
793 Vacuum equil simulation settings:
794
795 vacuumEquilSimulationEquilLength, 0.2 [ Units: nanosecond ]
796 vacuumEquilSimulationEquilLengthNVT, None [ Units: nanosecond ]
797 vacuumEquilSimulationMinimizationSteps, 5000
798 vacuumEquilSimulationProductionLength, 0.5 [ Units: nanosecond ]
799
800 Vacuum forcefield settings:
801
802 vacuumForcefieldConstraints, HBonds [ Possible values: HBonds,
803 AllBonds, or HAngles ]
804 vacuumForcefields, amber/ff14SB.xml, amber/tip3p_standard.xml
805 amber/tip3p_HFE_multivalent.xml amber/phosaa10.xml
806 [ Possible values: A space delimited list of valid names. ]
807 vacuumForcefieldHydrogenMass, 3.0 [ Units: amu ]
808 vacuumForcefieldNonbondedCutoff, 0.9 [ Units: nanometer ]
809 vacuumForcefieldNonbondedMethod, nocutoff [ Possible values: PME
810 or NoCutoff ]
811 vacuumForcefieldRigidWater, yes, [ Possible values: yes or no ]
812 vacuumForcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible
813 value: A valid forcefield name. ]
814
815 Vacuum output settings:
816
817 vacuumOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
818 vacuumOutputCheckpointStorageFilename, vacuum_checkpoint.nc
819 vacuumOutputForcefieldCache, db.json
820 vacuumOutputFilename, vacuum.nc
821 vacuumOutputIndices, not water [ Possible value: Any valid
822 selection. ]
823 vacuumOutputStructure, hybrid_system.pdb
824 vacuumOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
825 vacuumOutputVelocitiesWriteFrequency, None [ Possible
826 values: > 0; Units: picosecond ]
827
828 Vacuum simulation settings:
829
830 vacuumSimulationEarlyTerminationTargetError, 0.0 [ Units:
831 0.0 kilocalorie_per_mole ]
832 vacuumSimulationEquilibrationLength, 0.5 [ Units: nanosecond ]
833 vacuumSimulationMinimizationSteps, 5000
834 vacuumSimulationNReplicas, 14
835 vacuumSimulationProductionLength, 2.0 [ Units: nanosecond ]
836 vacuumSimulationRealTimeAnalysisInterval, 250.0 [ Units: picosecond ]
837 vacuumSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units: picosecond]
838 vacuumSimulationSamplerMethod, repex [ Possible values: repex,
839 sams, or independent ]
840 vacuumSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
841 values: logZ-flatness, minimum-visits or histogram-flatness ]
842 vacuumSimulationSamsGamma0, 1.0
843 vacuumSimulationTimePerIteration,2.5 [ Units: picosecond ]
844
845 A brief description of parameters, taken from OpenFE documentation, is
846 provided below:
847
848 protocolRepeats: Number of completely independent repeats of the
849 entire sampling process.
850
851 Integrator settings:
852
853 Parameters controlling the LangevinSplittingDynamicsMove integrator
854 used for simulation.
855
856 integratorBarostatFrequency: Frequency at which volume scaling
857 changes should be attempted.
858 integratorConstraintTolerance: Tolerance for constraint solver.
859 integratorLangevinCollisionRate: Collision frequency.
860 integratorNRestartAttempts: Number of attempts to restart from
861 Context in case there are NaNs in the energies after
862 integration.
863 integratorReassignVelocities: Reassign velocities from the
864 Maxwell-Boltzmann distribution at the beginning of each
865 Monte Carlo move.
866 integratorRemoveCom: Remove the center of mass motion.
867 integratorTimestep: Size of the simulation timestep.
868
869 Lambda settings:
870
871 Lambda protocol parameters.
872
873 lambdaElec: List of lambda values for electrostatics. The values of
874 0 and 1 imply state A and state B respectively.
875 lambdaRestraints: List of lambda values for restraints. The values
876 of 0 and 1 imply state A and state B respectively.
877 lambdaVdw: List of lamda values for van der Waals. The values of
878 of 0 and 1 imply state A and state B respectively.
879
880 Partial charge settings:
881
882 Parameters for automatically assigning missing partial charges to
883 small molecules, including the partial charge method.
884
885 partialChargeNaglModel: Model to use for partial charge assignment.
886 A value of None implies the use of the latest available
887 production AM1BCC model.
888 partialChargeNumberOfConformers: Number of conformers to generate
889 as part of the partial charge assignment. A value of None
890 implies the use of the existing conformer.
891 partialChargeOffToolkitBackend: OpenFF toolkit registry backend to
892 use for calculating partial charges.
893 partialChargeMethod: Method to use for calculating partial charges.
894
895 Solvation settings:
896
897 Solvation parameters for the system, including the solvent model and
898 the solvent padding.
899
900 solvationBoxShape: Shape of the periodic solvent box to create.
901 solvationBoxSize: Lengths of the unit cell for a solvent box.
902 solvationSolventModel: Forcefield water model to use during
903 solvation and defining the model properties.
904 solvationSolventPadding: Minimum distance from any solute bounding
905 sphere to the edge of the box.
906
907 Solvent engine settings:
908
909 Parameters configuring the compute platform used by the OpenMM to
910 perform the simulation.
911
912 solventEngineComputePlatform: Platform to use for running OpenMM MD
913 calculations.
914 solventEngineGpuDeviceIndex: Space delimited list of device indices
915 to use for running OpenMM MD calculations.
916
917 Solvent equil output settings:
918
919 Parameters controlling simulation output during equilibration
920 phase of solvent transformation.
921
922 solventEquilOutputCheckpointInterval: Frequency to write the
923 checkpoint file.
924 solventEquilOutputCheckpointStorageFilename: Checkpoint filename.
925 solventEquilOutputNPTStructure: NPT structure filename.
926 solventEquilOutputNVTStructure: NVT strucure filename.
927 solventEquilOutputForcefieldCache: Filename for caching small
928 molecule residue templates.
929 solventEquilOutputLogOutput: Simulation log filename.
930 solventEquilOutputMinimizedStructure: Minimized structire filename.
931 solventEquilOutputIndices: Selection string for selecting
932 coordinates to write.
933 solventEquilOutputPreminimizedStructure: Initial structure filename.
934 solventEquilOutputProductionTrajectoryFilename: Trajectory filename.
935 solventEquilOutputTrajectoryWriteInterval: Frequency for writing
936 velocities to trajectory file.
937
938 Solvent equil simulation settings:
939
940 Parameters controlling simulation during equilibration phase of
941 solvent transformation.
942
943 solventEquilSimulationEquilLength: Length of the NPT equilibration
944 phase.
945 solventEquilSimulationEquiLengthNVT: Length of the NVT equilibration
946 phase.
947 solventEquilSimulationMinimizationSteps: Maximum number of
948 minimization steps to perform.
949 solventEquilSimulationProductionLength: Length of the NPT production
950 phase.
951
952 Solvent forcefield settings:
953
954 Parameters to set up the force field with OpenMM Force Fields
955 equilibration phase of solvent transformation.
956
957 solventForcefieldConstraints: Constraints to use.
958 solventForcefields: List of valid forcefield paths for all
959 components except small molecules.
960 solventForcefieldHydrogenMass: Mass to be repartitioned to
961 hydrogens from neighboring heavy atoms.
962 solventForcefieldNonbondedCutoff: Cutoff for short range nonbonded
963 interactions.
964 solventForcefieldNonbondedMethod: Method for treating nonbonded
965 interactions.
966 solventForcefieldRigidWater: Use a rigid water model.
967 solventForcefieldSmallMoleculeForcefield: A valid forcefield name
968 to use for small molecules.
969
970 Solvent output settings:
971
972 Parameters controlling simulation output during final phase of
973 solvent transformation.
974
975 solventOutputCheckpointInterval: Frequency to write the checkpoint
976 file.
977 solventOutputCheckpointStorageFilename: Checkpoint filename.
978 solventOutputForcefieldCache: Filename for caching small molecule
979 residue templates.
980 solventOutputFilename: Trajectory filename.
981 solventOutputIndices: Selection string for selecting coordinates to
982 write.
983 solventOutputStructure: Hybrid topology structure filename.
984 solventOutputPositionsWriteFrequency: Frequency for writing
985 positions to trajectory file.
986 solventOutputVelocitiesWriteFrequency: Frequency for writing
987 velocities to trajectory file.
988
989 Solvent simulation settings:
990
991 Parameters controlling simulation during final phase of solvent
992 transformation.
993
994 solventSimulationEarlyTerminationTargetError: Target error for the
995 real time analysis measured in kcal/mol. Once the MBAR error of
996 the free energy is at or below this value, the simulation will
997 be considered complete. The suggested value of 0.12 has shown to
998 be effective in both hydration and binding free energy
999 benchmarks.
1000 solventSimulationEquilibrationLength: Length of the equilibration
1001 phase. The specified value must be divisible by 'integratorTimestep'.
1002 solventSimulationMinimizationSteps: Maximum number of minimization
1003 steps to perform.
1004 solventSimulationNReplicas: Number of replicas to use.
1005 solventSimulationProductionLength: Length of the production phase.
1006 The specified value must be divisible by 'integratorTimestep'.
1007 solventSimulationRealTimeAnalysisMinimumTime: Time interval for
1008 performing analysis of the free energies. At each interval, real
1009 time analysis data will be written to a yaml file named
1010 <outputFileName>_real_time_analysis.yaml. The current error
1011 in the estimate will also be assessed and the simulation will
1012 be terminated when it drops below
1013 'solventSimulationEarlyTerminationTargetError'.
1014 solventSimulationSamplerMethod: Alchemical sampling method to use:
1015 REPEX (Hamiltonian REPlica EXchange), SAMS (Self-Adjusted
1016 Mixture Sampling), or Independent (Independently sampled lambda
1017 windows).
1018 solventSimulationSamsFlatnessCriteria:Method for assessing when to
1019 switch to asymptomatically optimal scheme for SAMS.
1020 solventSimulationsamsGamma0: Initial weight adaptation rate for
1021 SAMS.
1022 solventSimulationTimePerIteration: Simulation time between each
1023 MCMC move attempt
1024
1025 Vacuum engine settings:
1026
1027 Parameters configuring the compute platform used by the OpenMM to
1028 perform the simulation.
1029
1030 vacuumEngineComputePlatform: Platform to use for running OpenMM MD
1031 calculations.
1032 vacuumEngineGpuDeviceIndex: Space delimited list of device indices
1033 to use for running OpenMM MD calculations.
1034
1035 The rest of the vacuum settings are similar to the solvent settings
1036 already described under various sections for solvent. The prefix
1037 'vacuum' is used for the names of the pramaters instead of the
1038 prefix 'solvent.'
1039
1040 Thermo settings:
1041
1042 Thermodynamic parameters, including the temperature and the pressure
1043 of the system.
1044
1045 thermoPh: Simulation pH
1046 thermoPressure: Simulation pressure.
1047 thermoRedoxPotential:Simulation redox potential.
1048 thermoTemperature: Simulation temperature.
1049
1050 -e, --examples
1051 Print examples.
1052 --executeDAGParams <Name,Value,..> [default: auto]
1053 A comma delimited list of parameter name and value pairs for executing
1054 protocol DAGs (Directed Acyclic Graph) to run AHFE calculations.
1055
1056 The supported parameter names along with their default values are
1057 are shown below:
1058
1059 keepShared, yes [ Possible values: yes or no ]
1060 keepScratch, no [ Possible values: yes or no ]
1061 nRetries, 2 [ Possible values: >= 0. A value of 0 implies only
1062 1 try. ]
1063
1064 A brief description of parameters is provided below:
1065
1066 keepShared: Keep shared directories after the execution of DAG.
1067 keepScratch: Keep scratch directories after the execution of DAG.
1068 nRetries: Number of times to attempt the execution.
1069
1070 -h, --help
1071 Print this help message.
1072 -i, --infile <infile>
1073 Input file containing small molecules.
1074 --infileParams <Name,Value,...> [default: auto]
1075 A comma delimited list of parameter name and value pairs for reading
1076 molecules from files. The supported parameter names for different file
1077 formats, along with their default values, are shown below:
1078
1079 SD: removeHydrogens,no,sanitize,yes,strictParsing,yes
1080
1081 -l, --list
1082 List default AHFE protocol settings provided by OpenFE module
1083 AbsoluteSolvationProtocol.
1084 --loggingLevel <Info, Warning or Error> [default: Error]
1085 Logging level to configure the 'root logger' via logging.basicConfig()
1086 function. The default logging level is changed from 'logging.INFO' to
1087 'logging.ERROR'. Otherwise, OpenFE and its associated modules
1088 may generate a lot of informational messages.
1089 -m, --mode <FirstMolecule, AllMolecules, or ...> [default: FirstMolecule]
1090 Calculate AHFE for the first molecule, the specified molecule names,
1091 or all molecules in an input file. Possible values: FirstMolecule,
1092 AllMolecules, or MoleculeNames. You must specify a comma delimited list
1093 of molecule names using '--moleculeNames'option during 'MoleculeNames'
1094 value for '--mode' option.
1095 --missingChargeMode <Calculate or Stop> [default: Stop]
1096 Calculate missing partial charges for molecules before running AHFE
1097 calculations or terminate the execution of the script. The missing
1098 partial charges will be automatically calculated by OpenFE module
1099 AbsoluteSolvationProtocol during the calculation of AHFE. You
1100 may control the calculation of partial charges by specifying values for
1101 partialCharge* parameters using '--ahfeParams' option.
1102 --moleculeNames <MolName1,MolName2,..>
1103 A comma delimited list of molecule names for calculating AHFEs.
1104 This option is only used during 'MoleculeNames' value for
1105 '--mode' option.
1106 -o, --outfileDir <outfiledir>
1107 Output directory.
1108 --outfilePrefix <text> [default: auto]
1109 Prefix for generating output files under output directory.
1110 --overwrite
1111 Overwrite existing files.
1112 --resultFileParams <Name,Value,..> [default: auto]
1113 A comma delimited list of parameter name and value pairs for writing
1114 calculated RHFEs values to a results file.
1115
1116 The supported parameter names along with their default values are
1117 are shown below:
1118
1119 precision, 4 [ Possible values: > 0 ]
1120 delimiter, comma [ Possible values: comma or tab ]
1121
1122 --solventParams <Name,Value,...> [default: auto]
1123 A comma delimited list of parameter name and value pairs for solvent
1124 component. You must specify valid OpenFE values. No extensive validation
1125 is performed. These parameters are used in conjunction with solvation*
1126 parameters available through '--ahfeParams' to perform solvation.
1127
1128 The supported parameter names along with their default values are
1129 are shown below:
1130
1131 positiveIon, Na+ [ Possible value: Li+, Na+, K+, Rb+, or Cs+ ]
1132 negativeIon, Cl- [ Possible values: Cl-, Br-, F-, or I- ]
1133 neutralize, yes [ Possible values: yes or no ]
1134 ionConcentration, 0.15 [ Units: molar ]
1135
1136 A brief description of parameters is provided below:
1137
1138 positiveIon, negativeion: Pair of ions used to neutralize and bring
1139 the solvent to required ionic concentration.
1140 neutralize: Neutralize the net charge on the chemical state by the
1141 ions in the solvent component.
1142 ionConcentration: Ionic concentration.
1143
1144 -w, --workingdir <dir>
1145 Location of working directory which defaults to the current directory.
1146
1147 Examples:
1148 The sample protein and ligand files for tyrosine kinase 2 (Tyk2) are
1149 distributed with MayaChemTools and are available in data directory. These
1150 files have been taken from OpenFE distribution for example notebooks. The
1151 AM1BCC partial charges have been calculated for the ligands in SD file to
1152 facilitate calculations. You may review OpenFE tutorial notebooks for the
1153 expected results.
1154
1155 To calcuate AHFE for the first molecule in a SD file, performing 3 independent
1156 repeats of the entire MD sampling process to estimate AHFE for the molecule,
1157 each solvent and vacuum MD repeat consisting of equilibration phase ( Solvent:
1158 Minimization - 5,000; NVT - 0.1 ns; NPT - 0.2; NPT prod - 0.5 ns; Vacuum:
1159 Minimization - 5,000; NVT - None; NPT - 0.2 ns; NPT prod - 0.5 ns) and
1160 production phase ( Solvent: Minimization - 5,000; NPT equil - 1.0 ns; NPT prod:
1161 10.0 ns; Vacuum: Minimization - 5,000; NVT equil - None; NPT equil - 0.5 ns;
1162 NPT prod - 2 ns) using a step size of of 4 fs, writing out appropriate trajectory
1163 and PDB files for each MD repeat in Results subdirectory under output directory,
1164 type:
1165
1166 % OpenFECalculateAbsoluteHydrationFreeEnergy.py
1167 -i SampleTyk2Ligands.sdf -o SampleTyk2LigandsAHFE
1168
1169 To run the first example for calculating AHFE for specific molecules using CUDA
1170 platform on your machine to perform solvent and vacuum MD simulations and
1171 generate various output files, type:
1172
1173 % OpenFECalculateAbsoluteHydrationFreeEnergy.py
1174 -i SampleTyk2Ligands.sdf -o SampleTyk2LigandsAHFE -m MoleculeNames
1175 --moleculeNames "lig_ejm_31, lig_ejm_47"
1176 --ahfeParams "solventEngineComputePlatform,CUDA,
1177 vacuumEngineComputePlatform,CUDA"
1178
1179 To run the second example to see all warning messages produced by OpenFE
1180 modules and write various output files, type;
1181
1182 % OpenFECalculateAbsoluteHydrationFreeEnergy.py
1183 -i SampleTyk2Ligands.sdf -o SampleTyk2LigandsAHFE -m MoleculeNames
1184 --moleculeNames "lig_ejm_31, lig_ejm_47"
1185 --ahfeParams "solventEngineComputePlatform,CUDA,
1186 vacuumEngineComputePlatform,CUDA"
1187 --loggingLevel Warning
1188
1189 To run the first example for calculating AHFE for all molecules using CUDA
1190 platform on your machine to perform solvent and vacuum MD simulations,
1191 automatically calculate missing partial charges for molecules, and generate
1192 various output files, type:
1193
1194 % OpenFECalculateAbsoluteHydrationFreeEnergy.py
1195 -i SampleTyk2LigandsNoCharges.sdf -o SampleTyk2LigandsAHFE
1196 -m AllMolecules --ahfeParams "solventEngineComputePlatform,CUDA,
1197 vacuumEngineComputePlatform,CUDA"
1198 --missingChargeMode Calculate
1199
1200 To run the second example by specifying explict values for various parametres
1201 and generate various output files, type:
1202
1203 % OpenFECalculateAbsoluteHydrationFreeEnergy.py
1204 -i SampleTyk2Ligands.sdf -o SampleTyk2LigandsAHFE -m MoleculeNames
1205 --moleculeNames "lig_ejm_31, lig_ejm_47"
1206 --loggingLevel Error
1207 --executeDAGParams "keepShared, yes, nRetries, 2"
1208 --missingChargeMode Stop --ahfeParams "protocolRepeats,3,
1209 solventEngineComputePlatform,CUDA, vacuumEngineComputePlatform,CUDA,
1210 integratorTimestep, 4.0, solvationBoxShape, cube,
1211 solvationSolventModel, tip3p,
1212 solventEquilSimulationEquiLengthNVT, 0.1,
1213 solventEquilSimulationEquilLength, 0.2,
1214 solventEquilSimulationProductionLength,0.5,
1215 solventSimulationEquilibrationLength, 1.0,
1216 solventSimulationProductionLength, 10.0,
1217 vacuumEquilSimulationEquilLengthNVT, None,
1218 vacuumEquilSimulationEquilLength, 0.2,
1219 vacuumEquilSimulationProductionLength, 0.5,
1220 vacuumSimulationEquilibrationLength, 0.5,
1221 vacuumSimulationProductionLength, 2.0,
1222 thermoPressure, 0.98692327, thermoTemperature, 298.15"
1223
1224 Author:
1225 Manish Sud(msud@san.rr.com)
1226
1227 See also:
1228 OpenFECalculateAbsoluteBindingFreeEnergy.py,
1229 OpenFECalculatePartialCharges.py, OpenFECalculateRelativeBindingFreeEnergy.py,
1230 OpenFECalculateRelativeHydrationFreeEnergy.py, OpenFEGenerateLigandNetwork.py
1231
1232 Copyright:
1233 Copyright (C) 2026 Manish Sud. All rights reserved.
1234
1235 The functionality available in this script is implemented using OpenFE, an
1236 open source molecuar for alchemical free energy calculations.
1237
1238 This file is part of MayaChemTools.
1239
1240 MayaChemTools is free software; you can redistribute it and/or modify it under
1241 the terms of the GNU Lesser General Public License as published by the Free
1242 Software Foundation; either version 3 of the License, or (at your option) any
1243 later version.
1244
1245 """
1246
1247 if __name__ == "__main__":
1248 main()