1 #
2 # File: OpenFEUtil.py
3 # Author: Manish Sud <msud@san.rr.com>
4 #
5 # Copyright (C) 2026 Manish Sud. All rights reserved.
6 #
7 # The functionality available in this script is implemented using OpenFE, an
8 # open source package for alchemical free energy calculations.
9 #
10 # This file is part of MayaChemTools.
11 #
12 # MayaChemTools is free software; you can redistribute it and/or modify it under
13 # the terms of the GNU Lesser General Public License as published by the Free
14 # Software Foundation; either version 3 of the License, or (at your option) any
15 # later version.
16 #
17 # MayaChemTools is distributed in the hope that it will be useful, but without
18 # any warranty; without even the implied warranty of merchantability of fitness
19 # for a particular purpose. See the GNU Lesser General Public License for more
20 # details.
21 #
22 # You should have received a copy of the GNU Lesser General Public License
23 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
24 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
25 # Boston, MA, 02111-1307, USA.
26 #
27
28 from __future__ import print_function
29
30 import os
31 import re
32 import importlib
33 import matplotlib.pyplot as plt
34 import json
35 import pathlib
36
37 import openfe
38
39 import kartograf
40 import openff
41 import gufe
42
43 from openfe.utils.atommapping_network_plotting import plot_atommapping_network
44 from openfe.protocols.openmm_afe import AbsoluteSolvationProtocol
45
46 import MiscUtil
47 import RDKitUtil
48
49 __all__ = [
50 "CalculatePartialCharges",
51 "ExecuteProtocolDAG",
52 "ExecuteProtocolDAGsAndGatherResults",
53 "GenerateLigandNetwork",
54 "GetMolFromName",
55 "GetMolNamePresentCount",
56 "GetMissingPartialChargesMolCount",
57 "GetPartialChargePropName",
58 "InitializeAbsoluteBindingFreeEngeryProtocol",
59 "InitializeAbsoluteSolvationFreeEngeryProtocol",
60 "InitializeAtomMapper",
61 "InitializeAtomMappers",
62 "InitializeAtomMapperScorer",
63 "InitializeChemicalSystem",
64 "InitializeProtocolDAG",
65 "InitializeRelativeFreeEngeryHybridTopologyProtocol",
66 "InitializeRelativeFreeEngerySeparatedTopologyProtocol",
67 "InitializeSolventComponent",
68 "InitializeTransformation",
69 "IsMolNamePresent",
70 "IsMolNamePresentMultipleTimes",
71 "ListOpenFESettings",
72 "ListOpenFESettingsByGroupName",
73 "ProcessMoleculePairs",
74 "ProcessMoleculeNames",
75 "ProcessOptionOpenFEChargeParameters",
76 "ProcessOptionOpenFEAbsoluteFreeEnergyMode",
77 "ProcessOptionOpenFEAbsoluteBindingFreeEnergyParameters",
78 "ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters",
79 "ProcessOptionOpenFEMapper",
80 "ProcessOptionOpenFEExecuteDAGParameters",
81 "ProcessOptionOpenFEMapperParameters",
82 "ProcessOptionOpenFEMissingChargeMode",
83 "ProcessOptionOpenFEMoleculePairs",
84 "ProcessOptionOpenFENetwork",
85 "ProcessOptionOpenFENetworkParameters",
86 "ProcessOptionOpenFERelativeFreeEnergyMode",
87 "ProcessOptionOpenFERelativeFreeEnergyChargeCorrectionParameters",
88 "ProcessOptionOpenFERelativeFreeEnergyParameters",
89 "ProcessOptionOpenFERelativeFreeEnergySeparatedTopologyParameters",
90 "ProcessOptionOpenFERelativeFreeEnergyVacuumParameters",
91 "ProcessOptionOpenFEResultFileParameters",
92 "ProcessOptionOpenFESolventParameters",
93 "ProcessRadialCentralLigandName",
94 "ReadAndValidateMolecules",
95 "ReadPDBFile",
96 "SetupAbsoluteBindingFreeEnergySettings",
97 "SetupAbsoluteHydrationFreeEnergySettings",
98 "SetupRelativeFreeEnergySettings",
99 "SetupRelativeFreeEnergySeparatedTopologySettings",
100 "SuggestAtomMappingsForMoleculePairs",
101 "UpdateRelativeFreeEnergySettingsForChargeCorrection",
102 "UpdateRelativeFreeEnergySettingsForVacuum",
103 "WriteLigandNetworkGraphMLFile",
104 "WriteLigandNetworkImageFile",
105 "WriteMappingImageFile",
106 "WriteProtocolDAGResultFile",
107 ]
108
109
110 def InitializeRelativeFreeEngeryHybridTopologyProtocol(RBFESettings):
111 """Initialize relative free energy hybrid topology protocol.
112
113 Arguments:
114 RBFESettings (object): OpenFE RelativeHybridTopologyProtocol settings
115 object.
116
117 Returns:
118 object: OpenFE RelativeHybridTopologyProtocol object.
119
120 """
121
122 try:
123 RBFEProtocol = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol(settings=RBFESettings)
124 except Exception as ErrMsg:
125 MiscUtil.PrintInfo("")
126 MiscUtil.PrintError("Failed to initialize relative hybrid topology procotol :\n%s" % ErrMsg)
127
128 return RBFEProtocol
129
130
131 def InitializeRelativeFreeEngerySeparatedTopologyProtocol(RBFESettings):
132 """Initialize relative free energy separated topologies protocol.
133
134 Arguments:
135 RBFESettings (object): OpenFE SeparatedTopologyProtocol settings
136 object.
137
138 Returns:
139 object: OpenFE SeparatedTopologyProtocol object.
140
141 """
142
143 try:
144 from openfe.protocols.openmm_septop import SepTopProtocol
145 RBFEProtocol = SepTopProtocol(RBFESettings)
146 except Exception as ErrMsg:
147 MiscUtil.PrintInfo("")
148 MiscUtil.PrintError("Failed to initialize separated topologies procotol :\n%s" % ErrMsg)
149
150 return RBFEProtocol
151
152
153 def InitializeAbsoluteBindingFreeEngeryProtocol(ABFESettings):
154 """Initialize absolute binding free energy protocol.
155
156 Arguments:
157 ABFESettings (object): OpenFE AbsoluteBindindProtocol settings
158 object.
159
160 Returns:
161 object: OpenFE AbsoluteBindingProtocol object.
162
163 """
164
165 try:
166 from openfe.protocols.openmm_afe import AbsoluteBindingProtocol
167
168 ABFEProtocol = AbsoluteBindingProtocol(settings=ABFESettings)
169 except Exception as ErrMsg:
170 MiscUtil.PrintInfo("")
171 MiscUtil.PrintError("Failed to initialize absolute binding procotol :\n%s" % ErrMsg)
172
173 return ABFEProtocol
174
175
176 def InitializeAbsoluteSolvationFreeEngeryProtocol(AHFESettings):
177 """Initialize absolute solvation free energy protocol.
178
179 Arguments:
180 AHFESettings (object): OpenFE AbsoluteSolvationProtocol settings
181 object.
182
183 Returns:
184 object: OpenFE AbsoluteSolvationProtocol object.
185
186 """
187
188 try:
189 AHFEProtocol = AbsoluteSolvationProtocol(settings=AHFESettings)
190 except Exception as ErrMsg:
191 MiscUtil.PrintInfo("")
192 MiscUtil.PrintError("Failed to initialize absolute solvation procotol :\n%s" % ErrMsg)
193
194 return AHFEProtocol
195
196
197 def InitializeSolventComponent(SolventParamsInfo):
198 """Initialize a solvent component.
199
200 The SolventParamsInfo parameter is a dictionary of name and value pairs for
201 network parameters and may be generated by calling the function named
202 ProcessOptionOpenFESolventParameters().
203
204 Arguments:
205 SolventParamsInfo (dict): Parameter name and value pairs.
206
207 Returns:
208 object: OpenFE SolventComponent object.
209
210 """
211
212 try:
213 SolventComponent = openfe.SolventComponent(
214 positive_ion=SolventParamsInfo["PositiveIon"],
215 negative_ion=SolventParamsInfo["NegativeIon"],
216 neutralize=SolventParamsInfo["Neutralize"],
217 ion_concentration=SolventParamsInfo["IonConcentration"],
218 )
219 except Exception as ErrMsg:
220 MiscUtil.PrintInfo("")
221 MiscUtil.PrintError("Failed to initialize solvent component :\n%s" % ErrMsg)
222
223 return SolventComponent
224
225
226 def InitializeChemicalSystem(SmallMol=None, MacroMol=None, Solvent=None, Name=""):
227 """Initialize a chemical system.
228
229 A valid value must be specified for at least one part of the system.
230
231 Arguments:
232 SmallMol (object): OpenFE SMC object.
233 MacroMol (object): OpenFE PDB object.
234 Solvent (object): OpenFE solvent component object.
235 Name (str): Chemical system name.
236
237 Returns:
238 object: OpenFE ChemicalSystem object.
239
240 """
241
242 SystemComponents = {}
243 if SmallMol is not None:
244 SystemComponents["ligand"] = SmallMol
245 if MacroMol is not None:
246 SystemComponents["protein"] = MacroMol
247 if Solvent is not None:
248 SystemComponents["solvent"] = Solvent
249
250 if len(SystemComponents.keys()) == 0:
251 MiscUtil.PrintInfo("")
252 MiscUtil.PrintError(
253 "Failed to initialize chemical system. You must specify one of the following chemical components: small molecule, macro molecule, or solvent."
254 )
255
256 try:
257 System = openfe.ChemicalSystem(components=SystemComponents, name=Name)
258 except Exception as ErrMsg:
259 MiscUtil.PrintInfo("")
260 MiscUtil.PrintError("Failed to initialize chemical system:\n%s" % ErrMsg)
261
262 return System
263
264
265 def InitializeTransformation(StateA, StateB, Mapping, Protocol, Name="", Validate=False):
266 """Initialize a transformation between two chemical systems represented by
267 StateA and StateB.
268
269 Arguments:
270 StateA (object): OpenFE ChemicalSystem object.
271 StateB (object): OpenFE ChemicalSystem object.
272 Mapping (object): OpenFE mapping object.
273 Protocol (object): OpenFE protocol object.
274 Name (str): Transformation name.
275 Validate (bool): Validate inputs for transformation..
276
277 Returns:
278 object: OpenFE Transformation object.
279
280 """
281
282 try:
283 Transformation = openfe.Transformation(
284 stateA=StateA, stateB=StateB, mapping=Mapping, protocol=Protocol, name=Name, validate=Validate
285 )
286 except Exception as ErrMsg:
287 MiscUtil.PrintInfo("")
288 MiscUtil.PrintError("Failed to initialize transformation:\n%s" % ErrMsg)
289
290 return Transformation
291
292
293 def InitializeProtocolDAG(Transformation, Name=""):
294 """Create a protocol DAG (Directed Acyclic Graph) for a transformation
295 to perform calculation.
296
297 Arguments:
298 Transformation (object): OpenFE Transformation object.
299 Name (str): DAG name.
300
301 Returns:
302 object: OpenFE DAG object.
303
304 """
305
306 try:
307 ProtocolDAG = Transformation.create(name=Name)
308 except Exception as ErrMsg:
309 MiscUtil.PrintInfo("")
310 MiscUtil.PrintError("Failed to initialize protocol DAG:\n%s" % ErrMsg)
311
312 return ProtocolDAG
313
314
315 def ExecuteProtocolDAGsAndGatherResults(
316 MolTransformations,
317 MolProtocolDAGs,
318 SharedOutDirPath,
319 ScratchOutDirPath,
320 KeepShared=True,
321 KeepScratch=False,
322 NRetries=0,
323 WriteResults=True,
324 ):
325 """Execute protocol DAG and gather results.
326
327 Arguments:
328 MolTransformations (List): List of OpenFE transformation objects.
329 MolProtocolDAGs (List): List of OpenFE DAG objects.
330 SharedOutDirPath (str): Shared results directory path.
331 ScratchOutDirPath (str): Scratch results directory path.
332 KeepShared (bool): Keep shared directory.
333 KeepScratch (bool): Keep scratch directory.
334 NRetries (int): Number of times to attempt the execution. A value
335 0 implies only 1 try.
336 WriteResults (bool): Write results to a JSON file.
337
338 Returns:
339 list: List of OpenFE DAG result objects.
340
341 """
342
343 MiscUtil.PrintInfo("\nExecuting protocol DAGs...")
344
345 MolProtocolResults = []
346
347 DAGCount = len(MolProtocolDAGs)
348 DAGFailedCount = 0
349 for Index in range(0, len(MolProtocolDAGs)):
350 DAGNum = Index + 1
351 ProtocolResult = _ExecuteProtocolDAGAndGatherResult(
352 MolTransformations[Index],
353 MolProtocolDAGs[Index],
354 DAGNum,
355 DAGCount,
356 SharedOutDirPath,
357 ScratchOutDirPath,
358 KeepShared=KeepShared,
359 KeepScratch=KeepScratch,
360 NRetries=NRetries,
361 WriteResults=WriteResults,
362 )
363
364 MolProtocolResults.append(ProtocolResult)
365
366 if ProtocolResult is None:
367 DAGFailedCount += 1
368
369 MiscUtil.PrintInfo("\nTotal number of protocol DAGs: %s" % DAGCount)
370 MiscUtil.PrintInfo("Number of protocol DAGs successfully executed: %s" % (DAGCount - DAGFailedCount))
371 MiscUtil.PrintInfo("Number of protocol DAGs failed during execution %s" % DAGFailedCount)
372
373 return MolProtocolResults
374
375
376 def _ExecuteProtocolDAGAndGatherResult(
377 Transformation,
378 ProtocolDAG,
379 DAGNum,
380 DAGCount,
381 ResultSharedOutDirPath,
382 ResultScratchOutDirPath,
383 KeepShared=True,
384 KeepScratch=False,
385 NRetries=0,
386 WriteResults=True,
387 ):
388 """Execute DAG and gather result."""
389
390 SharedOutDirPath = pathlib.Path(ResultSharedOutDirPath)
391 ScratchOutDirPath = pathlib.Path(ResultScratchOutDirPath)
392
393 (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime()
394 MiscUtil.PrintInfo("\nExecuting protocol DAG %s (%s of %s)..." % (ProtocolDAG.name, DAGNum, DAGCount))
395
396 ProtocolDAGResult = ExecuteProtocolDAG(
397 ProtocolDAG,
398 SharedOutDirPath,
399 ScratchOutDirPath,
400 KeepShared=KeepShared,
401 KeepScratch=KeepScratch,
402 NRetries=NRetries,
403 )
404
405 ProtocolResult = None
406 if ProtocolDAGResult is not None:
407 # Gather results...
408 MiscUtil.PrintInfo("\nGathering results...")
409 ProtocolResult = Transformation.protocol.gather([ProtocolDAGResult])
410
411 if WriteResults:
412 MiscUtil.PrintInfo("Writing result file...")
413 ResultsFilePath = os.path.join(ResultSharedOutDirPath, "%s_Results.json" % ProtocolDAG.name)
414 WriteProtocolDAGResultFile(ProtocolDAGResult, ProtocolResult, ResultsFilePath)
415
416 MiscUtil.PrintInfo("Completion time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime))
417
418 return ProtocolResult
419
420
421 def ExecuteProtocolDAG(
422 ProtocolDAG, SharedOutDirPath, ScratchOutDirPath, KeepShared=True, KeepScratch=False, NRetries=0
423 ):
424 """Execute protocol DAG to perform simulations for calculating FE.
425
426 Arguments:
427 ProtocolDAG (object): OpenFE protocol DAG object.
428 SharedOutDirPath (object): Pathlib path object.
429 ScratchOutDirPath (object): Pathlib path object.
430 KeepShared (bool): Keep shared directory.
431 KeepScratch (bool): Keep scratch directory.
432 NRetries (int): Number of times to attempt the execution. A value
433 0 implies only 1 try.
434
435 Returns:
436 object: OpenFE DAG result object.
437
438 """
439
440 ProtocolDAGResult = None
441 try:
442 ProtocolDAGResult = openfe.execute_DAG(
443 ProtocolDAG,
444 shared_basedir=SharedOutDirPath,
445 scratch_basedir=ScratchOutDirPath,
446 keep_shared=KeepShared,
447 keep_scratch=KeepScratch,
448 raise_error=True,
449 n_retries=NRetries,
450 )
451 except Exception as ErrMsg:
452 ProtocolDAGResult = None
453 MiscUtil.PrintInfo("")
454 MiscUtil.PrintInfo("Failed to execute DAG:\n%s\n" % (ErrMsg))
455
456 if ProtocolDAGResult is not None:
457 if not ProtocolDAGResult.ok():
458 ProtocolDAGResult = None
459 MiscUtil.PrintInfo("")
460 MiscUtil.PrintInfo("Failed to execute DAG: Result not ok...\n")
461
462 return ProtocolDAGResult
463
464
465 def WriteProtocolDAGResultFile(ProtocolDAGResult, ProtocolResult, ResultsFilePath):
466 """Write DAG results to a JSON file.
467
468 The file format and contents are based on the OpenFECLI code in quickrun.py.
469
470 Arguments:
471 ProtocolDAGResult (object): OpenFE DAG result object.
472 ProtocolResult (object): OpenFE protocol result object.
473 ResultsFilePath (str): File path.
474
475 Returns:
476 None
477
478 """
479
480 # Setup results...
481 if ProtocolDAGResult is None or ProtocolResult is None:
482 ResultsMap = {"estimate": "NA", "uncertainty": "NA", "protocol_result": "NA", "unit_results": "NA"}
483 else:
484 Estimate = ProtocolResult.get_estimate()
485 Uncertainty = ProtocolResult.get_uncertainty()
486 ResultsMap = {
487 "estimate": Estimate,
488 "uncertainty": Uncertainty,
489 "protocol_result": ProtocolResult.to_dict(),
490 "unit_results": {Unit.key: Unit.to_keyed_dict() for Unit in ProtocolDAGResult.protocol_unit_results},
491 }
492
493 # Write out results file...
494 with open(ResultsFilePath, mode="w") as OutFH:
495 json.dump(ResultsMap, OutFH, cls=gufe.tokenization.JSON_HANDLER.encoder)
496
497
498 def GenerateLigandNetwork(Mols, NetworkName, NetworkParamsInfo, Mappers, MapperScorer):
499 """Generate a ligand network for molecules using the specified atom mappers
500 and scorer. You may specify multiple atom mappers for generating mapping
501 between two molecules. All specified mappers are employed to identify the
502 highest scoring edges for generating a ligand network.
503
504 Possible values for network name are: LOMAP, MinimalSpanning, or Radial.
505
506 The NetworkParamsInfo parameter is a dictionary of name and value pairs for
507 network parameters and may be generated by calling the function named
508 ProcessOptionOpenFENetworkParameters().
509
510 Arguments:
511 Mols (list): List of OpenFE molecule objects.
512 NetworkName (str): Network name.
513 NetworkParamsInfo (dict): Parameter name and value pairs.
514 Mapper (list): List of OpenFE atom mapper objects.
515 MapperScorer (Callable): OpenFE atom mapper scorer.
516
517 Returns:
518 object: OpenFE ligand network object.
519
520 """
521
522 try:
523 if re.match("^LOMAP$", NetworkName, re.I):
524 LigandNetwork = openfe.ligand_network_planning.generate_lomap_network(
525 ligands=Mols,
526 mappers=Mappers,
527 scorer=MapperScorer,
528 distance_cutoff=NetworkParamsInfo["LomapDistanceCutoff"],
529 max_path_length=NetworkParamsInfo["LomapMaxPathLength"],
530 actives=None,
531 max_dist_from_active=2,
532 require_cycle_covering=NetworkParamsInfo["LomapRequireCycleCovering"],
533 radial=False,
534 fast=False,
535 )
536 elif re.match("^MinimalSpanning$", NetworkName, re.I):
537 LigandNetwork = openfe.ligand_network_planning.generate_minimal_spanning_network(
538 ligands=Mols,
539 mappers=Mappers,
540 scorer=MapperScorer,
541 progress=NetworkParamsInfo["MinimalSpanningProgress"],
542 )
543 elif re.match("^Radial$", NetworkName, re.I):
544 CentralMolName = NetworkParamsInfo["RadialCentralLigand"]
545 if not IsMolNamePresent(Mols, CentralMolName):
546 MiscUtil.PrintInfo("")
547 MiscUtil.PrintError(
548 "Failed to generate ligand network: Couldn't find molecule corresponding to central ligand %s"
549 % CentralMolName
550 )
551
552 if IsMolNamePresentMultipleTimes(Mols, CentralMolName):
553 MiscUtil.PrintInfo("")
554 MiscUtil.PrintError(
555 "Failed to generate ligand network: Found mulpliple occurrences molecule corresponding to central ligand %s"
556 % CentralMolName
557 )
558
559 CentralMol = GetMolFromName(Mols, CentralMolName)
560 OtherMols = [Mol for Mol in Mols if Mol.name != CentralMolName]
561
562 LigandNetwork = openfe.ligand_network_planning.generate_radial_network(
563 ligands=OtherMols, central_ligand=CentralMol, mappers=Mappers, scorer=MapperScorer
564 )
565 else:
566 MiscUtil.PrintInfo("")
567 MiscUtil.PrintError("Invalid network name: %s" % NetworkName)
568 except Exception as ErrMsg:
569 MiscUtil.PrintInfo("")
570 MiscUtil.PrintError("Failed to generate ligand network:\n%s" % ErrMsg)
571
572 return LigandNetwork
573
574
575 def InitializeAtomMappers(MapperNameList, MapperParamsInfo):
576 """Initialize atom mappers.
577
578 Possible values for atom mapper names: LOMAP or Kartograf.
579
580 The MapperParamsInfo parameter is a dictionary of name and value pairs for
581 network parameters and may be generated by calling the function named
582 ProcessOptionOpenFEMapperParameters().
583
584 Arguments:
585 MapperNameList (list):List of atom mapper names.
586 MapperParamsInfo (dict): Parameter name and value pairs.
587
588 Returns:
589 list: List of OpenFE atom mapper objects.
590
591 """
592
593 Mappers = []
594 for MapperName in MapperNameList:
595 Mapper = InitializeAtomMapper(MapperName, MapperParamsInfo)
596 Mappers.append(Mapper)
597
598 return Mappers
599
600
601 def InitializeAtomMapper(MapperName, MapperParamsInfo):
602 """Initialize an atom mapper.
603
604 Possible values for atom mapper names are: LOMAP or Kartograf.
605
606 The MapperParamsInfo parameter is a dictionary of name and value pairs for
607 network parameters and may be generated by calling the function named
608 ProcessOptionOpenFEMapperParameters().
609
610 Arguments:
611 MapperName (str): Atom mapper name.
612 MapperParamsInfo (dict): Parameter name and value pairs.
613
614 Returns:
615 object: OpenFE Atom mapper object.
616
617 """
618
619 Mapper = None
620 try:
621 if re.match("^LOMAP$", MapperName, re.I):
622 Mapper = openfe.setup.LomapAtomMapper(
623 time=MapperParamsInfo["LomapTime"],
624 threed=MapperParamsInfo["LomapThreeD"],
625 max3d=MapperParamsInfo["LomapMax3D"],
626 element_change=MapperParamsInfo["LomapElementChange"],
627 seed=MapperParamsInfo["LomapSeed"],
628 shift=MapperParamsInfo["LomapShift"],
629 )
630 elif re.match("^Kartograf$", MapperName, re.I):
631 Mapper = kartograf.KartografAtomMapper(
632 atom_max_distance=MapperParamsInfo["KartografAtomMaxDistance"],
633 atom_map_hydrogens=MapperParamsInfo["KartografAtomMapHydrogens"],
634 map_hydrogens_on_hydrogens_only=MapperParamsInfo["KartografMapHydrogensOnHydrogensOnly"],
635 map_exact_ring_matches_only=MapperParamsInfo["KartografMapExactRingMatchesOnly"],
636 allow_partial_fused_rings=MapperParamsInfo["KartografAllowPartialFusedRings"],
637 )
638 else:
639 MiscUtil.PrintInfo("")
640 MiscUtil.PrinError("Invalid mapper name: %s" % MapperName)
641 except Exception as ErrMsg:
642 MiscUtil.PrintInfo("")
643 MiscUtil.PrintError("Failed to initialize atom mapper:\n%s" % ErrMsg)
644
645 return Mapper
646
647
648 def InitializeAtomMapperScorer(ScorerName):
649 """Initialize an atom mapper scorer.
650
651 Possible value for scorer name is LOMAP.
652
653 Arguments:
654 ScorerName (str): Atom mapper scorer name.
655
656 Returns:
657 object: Atom mapper scorer object.
658
659 """
660
661 Scorer = None
662 if re.match("^LOMAP$", ScorerName, re.I):
663 try:
664 Scorer = openfe.lomap_scorers.default_lomap_score
665 except Exception as ErrMsg:
666 MiscUtil.PrintInfo("")
667 MiscUtil.PrintError("Failed to initialize atom mapper scorer:\n%s" % ErrMsg)
668 else:
669 MiscUtil.PrintInfo("")
670 MiscUtil.PrinError("Invalid atom mapper scorer name: %s" % ScorerName)
671
672 return Scorer
673
674
675 def CalculatePartialCharges(Mols, ChargeMethod, ChargeParamsInfo):
676 """Calculate partial atomic charges for molecules and return a set of
677 OpenFE charges molecule objects. The calculated charges are stored as
678 value of the molecule property named 'atom.dprop.PartialCharge'.
679
680 The following methods are supported to calculate partial atomic charges:
681 AM1BCC, M1-Mulliken, Espaloma, Gasteiger, MMFF94, or NAGL.
682
683 The ChargeParamsInfo parameter is a dictionary of name and value pairs for
684 charge parameters and may be generated by calling the function named
685 ProcessOptionOpenFEChargeParameters().
686
687 Arguments:
688 Mols (list): List of OpenFE molecule objects.
689 ChargeMethod (str): Charge method.
690 ChargeParamsInfo (dict): Parameter name and value pairs.
691
692 Returns:
693 list: List of OpenFE charged molecule objects.
694 bool: True or False.
695
696 """
697
698 if re.match("^(AM1BCC|Espaloma|NAGL)$", ChargeMethod, re.I):
699 (ChargedMols, Status) = _BulkAssignPartialCharges(Mols, ChargeMethod, ChargeParamsInfo)
700 elif re.match("(AM1-Mulliken|Gasteiger|MMFF94)", ChargeMethod, re.I):
701 (ChargedMols, Status) = _AssignPartialCharges(Mols, ChargeMethod, ChargeParamsInfo)
702 else:
703 MiscUtil.PrintInfo("")
704 MiscUtil.PrintError("Failed to calculate partial charges: Invalid charge method %s" % ChargeMethod)
705
706 return (ChargedMols, Status)
707
708
709 def _BulkAssignPartialCharges(Mols, ChargeMethod, ChargeParamsInfo):
710 """Assign partial charges using OpenFE wrapper for assigning bulk charges."""
711
712 SortChargedMols = True if ChargeParamsInfo["NumProcessors"] > 1 else False
713 if SortChargedMols:
714 # Multiprocessing may scramble the list of molecules. Add TmpMolNum
715 # property for sorting molecules...
716 Mols = _AddTmpMolNumPropertyForSorting(Mols)
717
718 Status = True
719 try:
720 # Set generate_n_conformers to None to use existing conformer...
721 ChargedMols = openfe.protocols.openmm_utils.charge_generation.bulk_assign_partial_charges(
722 molecules=Mols,
723 overwrite=True,
724 method=ChargeMethod,
725 toolkit_backend=ChargeParamsInfo["Toolkit"],
726 generate_n_conformers=None,
727 nagl_model=ChargeParamsInfo["NaglModel"],
728 processors=ChargeParamsInfo["NumProcessors"],
729 )
730 except Exception as ErrMsg:
731 Status = False
732 ChargedMols = None
733 MiscUtil.PrintInfo("")
734 MiscUtil.PrintWarning("Failed to bulk assign partial charges:\n%s\n" % (ErrMsg))
735
736 if Status:
737 if SortChargedMols:
738 ChargedMols = _SortMolsAndRemoveMolNumProperty(ChargedMols)
739
740 return (ChargedMols, Status)
741
742
743 def _AddTmpMolNumPropertyForSorting(Mols):
744 """Add TmpMolNum property for sorting molecules."""
745
746 RDKitMols = []
747 MolNum = 0
748 for Mol in Mols:
749 MolNum += 1
750 RDKitMol = openfe.SmallMoleculeComponent.to_rdkit(Mol)
751 RDKitMol.SetProp("TmpMolNum", "%s" % MolNum)
752
753 RDKitMols.append(RDKitMol)
754
755 Mols = [openfe.SmallMoleculeComponent.from_rdkit(Mol) for Mol in RDKitMols]
756
757 return Mols
758
759
760 def _SortMolsAndRemoveMolNumProperty(Mols):
761 """Sort molecules using TmpMolNum property along with clearing the property."""
762
763 RDKitMols = [openfe.SmallMoleculeComponent.to_rdkit(Mol) for Mol in Mols]
764
765 # Setup a TmpMolNum to RDKitMol map...
766 TmpMolNumMap = {}
767 for RDKitMol in RDKitMols:
768 TmpMolNum = int(RDKitMol.GetProp("TmpMolNum"))
769 TmpMolNumMap[TmpMolNum] = RDKitMol
770 RDKitMol.ClearProp("TmpMolNum")
771
772 # Setup a sorted RDKitMols list using TmpMolNums...
773 SortedRDKitMols = []
774 for TmpMolNum in sorted(TmpMolNumMap.keys()):
775 SortedRDKitMols.append(TmpMolNumMap[TmpMolNum])
776
777 # Setup sorted OpenFE mols...
778 SortedMols = [openfe.SmallMoleculeComponent.from_rdkit(RDKitMol) for RDKitMol in SortedRDKitMols]
779
780 return SortedMols
781
782
783 def _AssignPartialCharges(Mols, ChargeMethod, ChargeParamsInfo):
784 """Assign partial charges using OpenFF method."""
785
786 import tqdm
787
788 ToolkitRegistry = None
789 Toolkit = ChargeParamsInfo["Toolkit"]
790 if re.match("^RDKit$", Toolkit, re.I):
791 ToolkitRegistry = openff.toolkit.ToolkitRegistry([openff.toolkit.RDKitToolkitWrapper])
792 elif re.match("^AmberTools$", Toolkit, re.I):
793 ToolkitRegistry = openff.toolkit.ToolkitRegistry([openff.toolkit.AmberToolsToolkitWrapper])
794
795 PartialChargeMethod = ChargeMethod.lower()
796 StrictNCconformers = False
797 NormalizePartialCharges = True
798
799 UseConformerStatus = ChargeParamsInfo["UseConformer"]
800
801 # Transform OpenFE molecule to OpenFF molecule...
802 OpenFFMols = [openfe.SmallMoleculeComponent.to_openff(Mol) for Mol in Mols]
803
804 Status = True
805 ChargedMols = []
806 (MolCount, CalcFailedCount) = [0] * 2
807 for Mol in tqdm.tqdm(OpenFFMols, desc="Calculating charges", ncols=80, total=len(OpenFFMols)):
808 MolCount += 1
809
810 Conformers = None
811 if UseConformerStatus and Mol.n_conformers > 0:
812 Conformers = Mol.conformers
813
814 Status = True
815 try:
816 if ToolkitRegistry is None:
817 Mol.assign_partial_charges(
818 partial_charge_method=PartialChargeMethod,
819 strict_n_conformers=StrictNCconformers,
820 use_conformers=Conformers,
821 normalize_partial_charges=NormalizePartialCharges,
822 )
823 else:
824 Mol.assign_partial_charges(
825 partial_charge_method=PartialChargeMethod,
826 strict_n_conformers=StrictNCconformers,
827 use_conformers=Conformers,
828 normalize_partial_charges=NormalizePartialCharges,
829 toolkit_registry=ToolkitRegistry,
830 )
831 except Exception as ErrMsg:
832 Status = False
833 CalcFailedCount += 1
834 MiscUtil.PrintInfo("")
835 MiscUtil.PrintWarning("Failed to calculate partial charges for molecule %s:\n%s\n" % (Mol.name, ErrMsg))
836 continue
837
838 # Track charges molecules...
839 ChargedMols.append(openfe.SmallMoleculeComponent.from_openff(Mol))
840
841 if len(ChargedMols) == 0:
842 ChargedMols = None
843
844 MiscUtil.PrintInfo("\nNumber of valid molecules: %d" % MolCount)
845 MiscUtil.PrintInfo("Number of molecules failed during the the calculation of partial charges: %d" % CalcFailedCount)
846
847 return (ChargedMols, Status)
848
849
850 def ListOpenFESettings(Settings):
851 """List setting retrieved from a protocol settings object.
852
853 Arguments:
854 Settings (object): OpenFE protocol settings object.
855
856 Returns:
857 None
858
859 """
860
861 try:
862 if hasattr(Settings, "model_dump"):
863 SettingDict = Settings.model_dump()
864 else:
865 SettingDict = Settings.dict()
866 except Exception as ErrMsg:
867 MiscUtil.PrintInfo("")
868 MiscUtil.PrintError("Failed to list settings\n%s" % ErrMsg)
869
870 for SettingName in sorted(SettingDict.keys()):
871 SettingValue = SettingDict[SettingName]
872 if isinstance(SettingValue, dict):
873 MiscUtil.PrintInfo("\n%s:" % (SettingName))
874 for Name in sorted(SettingValue):
875 Value = SettingValue[Name]
876 MiscUtil.PrintInfo(" %s:%s" % (Name, Value))
877 else:
878 MiscUtil.PrintInfo("\n%s:%s" % (SettingName, SettingValue))
879 continue
880
881
882 def ListOpenFESettingsByGroupName(Settings, SettingName):
883 """List setting retrieved from a protocol settings object for a specified
884 settings group name.
885
886 Arguments:
887 Settings (object): OpenFE protocol settings object.
888
889 Returns:
890 None
891
892 """
893
894 try:
895 if hasattr(Settings, "model_dump"):
896 SettingDict = Settings.model_dump()
897 else:
898 SettingDict = Settings.dict()
899 except Exception as ErrMsg:
900 MiscUtil.PrintInfo("")
901 MiscUtil.PrintError("Failed to list settings\n%s" % ErrMsg)
902
903 if SettingName in SettingDict:
904 SettingValue = SettingDict[SettingName]
905 else:
906 MiscUtil.PrintWarning("No settings available for group name: %s" % SettingName)
907 return
908
909 if isinstance(SettingValue, dict):
910 MiscUtil.PrintInfo("\n%s:" % (SettingName))
911 for Name in sorted(SettingValue):
912 Value = SettingValue[Name]
913 MiscUtil.PrintInfo(" %s:%s" % (Name, Value))
914 else:
915 MiscUtil.PrintInfo("\n%s:%s" % (SettingName, SettingValue))
916
917
918 def GetMolFromName(Mols, MolName):
919 """Get the first molecule whose name matches the specified molecule name
920 from a list of molecules.
921
922 Arguments:
923 Mols (list): List of OpenFE molecule objects.
924 MolName (str): Molecule name
925
926 Returns:
927 object or None: Open FE molecule object.
928
929 """
930
931 MatchedMol = None
932 for Mol in Mols:
933 if Mol.name == MolName:
934 MatchedMol = Mol
935 break
936
937 return MatchedMol
938
939
940 def IsMolNamePresent(Mols, MolName):
941 """Check for the presence of a molecule name in a list of molecules.
942
943 Arguments:
944 Mols (list): List OpenFE molecule objects.
945 MolName (str): Molecule name
946
947 Returns:
948 bool: True or False.
949
950 """
951
952 Status = False
953 for Mol in Mols:
954 if Mol.name == MolName:
955 Status = True
956 break
957
958 return Status
959
960
961 def IsMolNamePresentMultipleTimes(Mols, MolName):
962 """Check for the presence of a molecule name in a list of molecules.
963
964 Arguments:
965 Mols (list): List OpenFE molecule objects.
966 MolName (str): Molecule name
967
968 Returns:
969 bool: True or False.
970
971 """
972
973 MatchedMolCount = GetMolNamePresentCount(Mols, MolName)
974
975 return True if MatchedMolCount > 1 else False
976
977
978 def GetMolNamePresentCount(Mols, MolName):
979 """Get count of molecule name present in a list of molecules.
980
981 Arguments:
982 Mols (list): List OpenFE molecule objects.
983 MolName (str): Molecule name
984
985 Returns:
986 int: Molecule name present count.
987
988 """
989
990 MatchedMolCount = 0
991 for Mol in Mols:
992 if Mol.name == MolName:
993 MatchedMolCount += 1
994
995 return MatchedMolCount
996
997
998 def GetMissingPartialChargesMolCount(Mols):
999 """Get count of molecules with missing partial atomic charges.
1000
1001 The absence of molecule property name, atom.dprop.PartialCharge,
1002 implies missing charges for the molecule.
1003
1004 Arguments:
1005 Mols (list): List OpenFE molecule objects.
1006
1007 Returns:
1008 int: Molecule count with missing partial charges.
1009
1010 """
1011
1012 PropName = GetPartialChargePropName()
1013 MolCount = 0
1014 for Mol in Mols:
1015 RDKitMol = Mol.to_rdkit()
1016 if not RDKitMol.HasProp(PropName):
1017 MolCount += 1
1018
1019 return MolCount
1020
1021
1022 def GetPartialChargePropName():
1023 """Get partial atomic charge property name used for associating partial
1024 charges to a molecule.
1025
1026 Arguments:
1027 None
1028
1029 Returns:
1030 str: Propery name 'atom.dprop.PartialCharge'
1031
1032 """
1033
1034 PropName = "atom.dprop.PartialCharge"
1035
1036 return PropName
1037
1038
1039 def WriteLigandNetworkGraphMLFile(LigandNetwork, GraphMLOutfile):
1040 """Write ligand network to a GraphML file.
1041
1042 Arguments:
1043 LigandNetwork (object): OpenFE ligand network object.
1044 GraphMLOutfile (str): GraphML file path.
1045
1046 Returns:
1047 None
1048
1049 """
1050
1051 with open(GraphMLOutfile, "w") as Writer:
1052 Writer.write(LigandNetwork.to_graphml())
1053
1054
1055 def WriteLigandNetworkImageFile(LigandNetwork, ImageOutfile):
1056 """Write ligand network to an image file.
1057
1058 You must specify a valid format supported by Python module Matplotlib.
1059 For example: PNG (.png), SVG (.svg), PDF (.pdf), etc.
1060
1061 Arguments:
1062 LigandNetwork (object): OpenFE ligand network object.
1063 ImageOutfile (str): Image file path.
1064
1065 Returns:
1066 None
1067
1068 """
1069
1070 plt.figure()
1071
1072 plot_atommapping_network(LigandNetwork)
1073 plt.savefig(ImageOutfile)
1074
1075 plt.close()
1076
1077
1078 def WriteMappingImageFile(Mapping, ImageOutfile):
1079 """Write mapping to an image file.
1080
1081 You must specify PNG (.png) format for the image file.
1082
1083 Arguments:
1084 Mapping (object): OpenFE mapping object.
1085 ImageOutfile (str): Image file path.
1086
1087 Returns:
1088 None
1089
1090 """
1091
1092 Mapping.draw_to_file(ImageOutfile)
1093
1094
1095 def ReadPDBFile(PDBFile, Name=""):
1096 """Read molecule from a PDB file.
1097
1098 The supported PDB file formats are: PDB(.pdb) and CIF (.cif)
1099
1100 Arguments:
1101 PDBFile (str): PDB file path.
1102 Name (str): Name of macromolecule.
1103
1104 Returns:
1105 object: OpenFE PDB object.
1106
1107 """
1108
1109 FileDir, FileName, FileExt = MiscUtil.ParseFileName(PDBFile)
1110 if re.match("^pdb$", FileExt, re.I):
1111 PDBHandle = openfe.ProteinComponent.from_pdb_file(PDBFile, name=Name)
1112 elif re.match("^cif$", FileExt, re.I):
1113 PDBHandle = openfe.ProteinComponent.from_pdbx_file(PDBFile, name=Name)
1114 else:
1115 MiscUtil.PrintError("Failed to read PDB file. Invalid PDB file format %s...\n" % PDBFile)
1116
1117 return PDBHandle
1118
1119
1120 def ReadAndValidateMolecules(FileName, **KeyWordArgs):
1121 """Read molecules from an input file, validate all molecule objects, and return
1122 a list of valid OpenFE SmallMoleculeComponent objects along with the count of
1123 valid and non-valid molecule objects.
1124
1125 Arguments:
1126 FileName (str): Name of a file with complete path.
1127 **KeyWordArgs (dict) : Parameter name and value pairs for reading
1128 and processing molecules.
1129
1130 Returns:
1131 list or None: List of valid OpenFE molecule objects.
1132 int : Number of total molecules in input file.
1133 int : Number of valid molecules in input file.
1134
1135 Notes:
1136 The file extension is used to determine type of the file and set up an appropriate
1137 file reader.
1138
1139 """
1140
1141 # Setup a molecule reader...
1142 RDKitMols = RDKitUtil.ReadMolecules(FileName, **KeyWordArgs)
1143
1144 OpenFEMols = []
1145 (MolCount, ValidMolCount) = [0] * 2
1146 for RDKitMol in RDKitMols:
1147 MolCount += 1
1148
1149 if not _CheckAndValidateMolecule(RDKitMol, MolCount):
1150 continue
1151
1152 ValidMolCount += 1
1153
1154 # Setup OpenFE molecule...
1155 OpenFEMols.append(openfe.SmallMoleculeComponent.from_rdkit(RDKitMol))
1156
1157 return (OpenFEMols, MolCount, ValidMolCount)
1158
1159
1160 def _CheckAndValidateMolecule(Mol, MolCount=None):
1161 """Check and validate RDKit molecule for OpenFE calculations."""
1162
1163 if Mol is None:
1164 return False
1165
1166 # Update empty molname...
1167 MolName = Mol.GetProp("_Name")
1168 if MiscUtil.IsEmpty(MolName):
1169 MolName = RDKitUtil.GetMolName(Mol, MolCount)
1170 Mol.SetProp("_Name", MolName)
1171
1172 # Check for empty molecule...
1173 if RDKitUtil.IsMolEmpty(Mol):
1174 MiscUtil.PrintWarning("Ignoring empty molecule: %s\n" % MolName)
1175 return False
1176
1177 # Check for invalid element symbol....
1178 if not RDKitUtil.ValidateElementSymbols(RDKitUtil.GetAtomSymbols(Mol)):
1179 MiscUtil.PrintWarning("Ignoring molecule containing invalid element symbols: %s\n" % MolName)
1180 return False
1181
1182 # Check for 3D flag...
1183 if not Mol.GetConformer().Is3D():
1184 MiscUtil.PrintWarning("3D tag is not set for molecule: %s\n" % MolName)
1185
1186 # Check for missing hydrogens...
1187 if RDKitUtil.AreHydrogensMissingInMolecule(Mol):
1188 MiscUtil.PrintWarning("Missing hydrogens in molecule: %s\n" % MolName)
1189
1190 return True
1191
1192
1193 def ProcessRadialCentralLigandName(Mols, RadialCentralMolName):
1194 """Check for the presence of the central ligand name, used for generating
1195 a radial ligand network, in a list of molecules and make sure it occurs only
1196 once in the list.
1197
1198 Arguments:
1199 Mols (list): List of OpenFE molecule objects.
1200 CentralMoleculeName (str): Molecule name.
1201
1202 Returns:
1203 Object or none: OpenFE molecule object or None.
1204
1205 """
1206
1207 if RadialCentralMolName is None:
1208 return None
1209
1210 MiscUtil.PrintInfo("\nProcessing central ligand name for radial network (%s)..." % RadialCentralMolName)
1211
1212 MolCount = GetMolNamePresentCount(Mols, RadialCentralMolName)
1213 if MolCount == 0:
1214 MiscUtil.PrintError(
1215 'The value specified, %s, for parameter name, radialCentralLigand, using option "-n, --networkParams" is not valid. The specified molecule name is not present in the small molecule input file.'
1216 % (RadialCentralMolName)
1217 )
1218 if MolCount > 1:
1219 MiscUtil.PrintError(
1220 'The value specified, %s, for parameter name, radialCentralLigand, using option "-n, --networkParams" is not valid. The specified molecule name is present multiple times in the small molecule input file.'
1221 % (RadialCentralMolName)
1222 )
1223
1224 Mol = GetMolFromName(Mols, RadialCentralMolName)
1225
1226 return Mol
1227
1228
1229 def SuggestAtomMappingsForMoleculePairs(MoleculePairs, Mappers, MapperScorer):
1230 """Suggest atom mapping between a pair of molecules using specified mappers
1231 and a scorer.
1232
1233 You may specify multiple mappers for generating mapping between pair of
1234 molecules. All specified mappers are employed to identify the highest scoring
1235 mapping between a pair of molecules.
1236
1237 Arguments:
1238 Mols (list): List pf OpenFE molecule objects.
1239 Mappers (list): List of OpenFE mapper objects.
1240 MapperScorer (object): OpenFE scorer object.
1241
1242 Returns:
1243 list: List of OpenFE mapping objects.
1244
1245 """
1246
1247 MolAToMolBMappings = []
1248 for Index in range(0, len(MoleculePairs), 2):
1249 MolA = MoleculePairs[Index]
1250 MolB = MoleculePairs[Index + 1]
1251
1252 # Setup all atom mappings...
1253 Mappings = []
1254 for Mapper in Mappers:
1255 Mapping = next(Mapper.suggest_mappings(MolA, MolB))
1256 Mappings.append(Mapping)
1257
1258 # Select the mapping with the highest score...
1259 BestScore = 0.0
1260 BestMapping = None
1261 for Mapping in Mappings:
1262 Score = MapperScorer(Mapping)
1263 if Score > BestScore:
1264 BestScore = Score
1265 BestMapping = Mapping
1266
1267 # Track the best mapping...
1268 if BestMapping is not None:
1269 BestMapping = BestMapping.with_annotations({"score": BestScore})
1270 MolAToMolBMappings.append(BestMapping)
1271
1272 return MolAToMolBMappings
1273
1274
1275 def ProcessMoleculePairs(Mols, MoleculePairsList=None):
1276 """Process molecule names, corresponding to pairs of molecules, to generate
1277 a list of molecule objects for these names. The molecule name must be a valid
1278 name and occur only once in the list of molecules.
1279
1280 The first and the second molecule in the list of molecules is returned for an
1281 unspecified list of molecule names.
1282
1283 Arguments:
1284 Mols (list): List of OpenFE molecule objects.
1285 MoleculePairsList (list): List of molecule names corresponding to pairs
1286 of molecules.
1287
1288 Returns:
1289 list: List of OpenFE molecule objects corresponding to pairs of molecule
1290 names.
1291
1292 """
1293
1294 MoleculePairsMolList = None
1295
1296 if MoleculePairsList is None:
1297 # Use first two molecules...
1298 Mol1 = Mols[0]
1299 Mol2 = Mols[1]
1300 MoleculePairsMolList = [Mol1, Mol2]
1301 else:
1302 MiscUtil.PrintInfo("\nProcessing specified molecule pairs...")
1303
1304 MoleculePairsMolList = []
1305 for MolName in MoleculePairsList:
1306 MolCount = GetMolNamePresentCount(Mols, MolName)
1307 if MolCount == 0:
1308 MiscUtil.PrintError(
1309 'The value specified, %s, for "--moleculePairs" is not valid. The specified molecule name is not present in the small molecule input file.'
1310 % (MolName)
1311 )
1312 if MolCount > 1:
1313 MiscUtil.PrintError(
1314 'The value specified, %s, for option "--moleculePairs" is not valid. The specified molecule name is present multiple times in the small molecule input file.'
1315 % (MolName)
1316 )
1317 Mol = GetMolFromName(Mols, MolName)
1318 MoleculePairsMolList.append(Mol)
1319
1320 return MoleculePairsMolList
1321
1322
1323 def ProcessOptionOpenFEMoleculePairs(OptionName, OptionValue):
1324 """Process molecule pairs command line option and return a list
1325 of molecule names.
1326
1327 Arguments:
1328 OptionName (str): Command line molecule pairs option name.
1329 OptionValue (str): Command line molecule pairs option value.
1330
1331 Returns:
1332 list or none: List of molecule names.
1333
1334 """
1335
1336 MoleculePairs = OptionValue.strip()
1337 if re.match("^auto$", MoleculePairs, re.I):
1338 return None
1339
1340 MoleculePairsWords = MoleculePairs.split(",")
1341 if len(MoleculePairsWords) % 2:
1342 MiscUtil.PrintError(
1343 'The number of comma delimited values, %d, specified using "%s" option must be an even number.'
1344 % (len(MoleculePairsWords), OptionName)
1345 )
1346
1347 MoleculePairsList = []
1348 for Index in range(0, len(MoleculePairsWords), 2):
1349 MoleculeName1 = MoleculePairsWords[Index].strip()
1350 MoleculeName2 = MoleculePairsWords[Index + 1].strip()
1351
1352 if MoleculeName1 == MoleculeName2:
1353 MiscUtil.PrintError(
1354 'The molecule name pairs, %s and %s, specified using using "%s" option is not valid. You must specify distinct molecule names.'
1355 % (MoleculeName1, MoleculeName2, OptionName)
1356 )
1357
1358 MoleculePairsList.append(MoleculeName1)
1359 MoleculePairsList.append(MoleculeName2)
1360
1361 return MoleculePairsList
1362
1363
1364 def ProcessMoleculeNames(Mols, MoleculeNamesList=None):
1365 """Process molecule names to generate a list of molecule objects for
1366 specified names. The molecule name must be a valid name and occur
1367 only once in the list of molecules.
1368
1369 The first molecule in the list of molecules is returned for an unspecified
1370 list of molecule names.
1371
1372 Arguments:
1373 Mols (list): List of OpenFE molecule objects.
1374 MoleculeNamesList (list): List of molecule names.
1375
1376 Returns:
1377 list: List of OpenFE molecule objects corresponding to molecule names.
1378
1379 """
1380
1381 MoleculeNamesMolList = None
1382
1383 if MoleculeNamesList is None:
1384 # Use first molecule...
1385 MoleculeNamesMolList = Mols[0]
1386 else:
1387 MiscUtil.PrintInfo("\nProcessing molecule names...")
1388
1389 MoleculeNamesMolList = []
1390 for MolName in MoleculeNamesList:
1391 MolCount = GetMolNamePresentCount(Mols, MolName)
1392 if MolCount == 0:
1393 MiscUtil.PrintError(
1394 'The value specified, %s, for "--moleculeNames" is not valid. The specified molecule name is not present in the small molecule input file.'
1395 % (MolName)
1396 )
1397 if MolCount > 1:
1398 MiscUtil.PrintError(
1399 'The value specified, %s, for option "--moleculeNames" is not valid. The specified molecule name is present multiple times in the small molecule input file.'
1400 % (MolName)
1401 )
1402 Mol = GetMolFromName(Mols, MolName)
1403 MoleculeNamesMolList.append(Mol)
1404
1405 return MoleculeNamesMolList
1406
1407
1408 def ProcessOptionOpenFEMissingChargeMode(OptionName, OptionValue):
1409 """Process missing charge mode command line option and return a valid
1410 canonical value.
1411
1412 Valid values are: Calculate or Stop.
1413
1414 Arguments:
1415 OptionName (str): Command line missing charge mode option name.
1416 OptionValue (str): Command line missing charge mode option value.
1417
1418 Returns:
1419 str: Canonical value for missing charge mode.
1420
1421 """
1422
1423 Value = OptionValue.strip()
1424 if re.match("^Calculate$", Value, re.I):
1425 Value = "Calculate"
1426 elif re.match("^Stop$", Value, re.I):
1427 Value = "Stop"
1428 else:
1429 MiscUtil.PrintError(
1430 'The value specified, %s, for option "%s" is not valid. Supported values: Calculate or Stop'
1431 % (OptionValue, OptionName)
1432 )
1433
1434 return Value
1435
1436
1437 def ProcessOptionOpenFERelativeFreeEnergyMode(OptionName, OptionValue):
1438 """Process relative FE mode command line option and return a valid
1439 canonical value.
1440
1441 Valid values names are: MoleculePairs or MoleculeNetwork.
1442
1443 Arguments:
1444 OptionName (str): Command line missing charge mode option name.
1445 OptionValue (str): Command line missing charge mode option value.
1446
1447 Returns:
1448 str: Canonical value for missing charge mode.
1449
1450 """
1451
1452 Value = OptionValue.strip()
1453 if re.match("^MoleculePairs$", Value, re.I):
1454 Value = "MoleculePairs"
1455 elif re.match("^MoleculeNetwork$", Value, re.I):
1456 Value = "MoleculeNetwork"
1457 else:
1458 MiscUtil.PrintError(
1459 'The value specified, %s, for option "%s" is not valid. Supported values: MoleculePairs or MoleculeNetwork'
1460 % (OptionValue, OptionName)
1461 )
1462
1463 return Value
1464
1465
1466 def ProcessOptionOpenFEAbsoluteFreeEnergyMode(OptionName, OptionValue):
1467 """Process absolute FE mode command line option and return a valid
1468 canonical value.
1469
1470 Valid values names are: FirstMolecule, AllMolecules, or MoleculeNames.
1471
1472 Arguments:
1473 OptionName (str): Command line missing charge mode option name.
1474 OptionValue (str): Command line missing charge mode option value.
1475
1476 Returns:
1477 str: Canonical value for missing charge mode.
1478
1479 """
1480
1481 Value = OptionValue.strip()
1482 if re.match("^FirstMolecule$", Value, re.I):
1483 Value = "FirstMolecule"
1484 elif re.match("^AllMolecules$", Value, re.I):
1485 Value = "AllMolecules"
1486 elif re.match("^MoleculeNames$", Value, re.I):
1487 Value = "MoleculeNames"
1488 else:
1489 MiscUtil.PrintError(
1490 'The value specified, %s, for option "%s" is not valid. Supported values: FirstMolecule, AllMolecules, or MoleculeNames'
1491 % (OptionValue, OptionName)
1492 )
1493
1494 return Value
1495
1496
1497 def ProcessOptionOpenFEExecuteDAGParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
1498 """Process parameters for protocol DAG execution and return a map
1499 containing processed parameter names and values.
1500
1501 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
1502 to setup execution of protocol DAG.
1503
1504 The supported parameter names along with their default and possible
1505 values are shown below:
1506
1507 keepShared, yes [ Possible values: yes or no ]
1508 keepScratch, no [ Possible values: yes or no ]
1509 nRetries, 2 [ Possible values: >= 0. A value of 0 implies only 1 try. ]
1510
1511 A brief description of parameters is provided below:
1512
1513 keepShared: Keep shared directories after the execution of DAG.
1514 keepScratch: Keep scratch directories after the execution of DAG.
1515 nRetries: Number of times to attempt the execution.
1516
1517 Arguments:
1518 ParamsOptionName (str): Command line execute DAG parameters option name.
1519 ParamsOptionValues (str): Comma delimited list of parameter name and value pairs.
1520 ParamsDefaultInfo (dict): Default values to override for selected parameters.
1521
1522 Returns:
1523 dictionary: Processed parameter name and value pairs.
1524
1525 """
1526
1527 ParamsInfo = {"KeepShared": True, "KeepScratch": False, "NRetries": 2}
1528
1529 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
1530 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
1531 )
1532
1533 if re.match("^auto$", ParamsOptionValue, re.I):
1534 _ProcessOptionOpenFEExecuteDAGParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1535 return ParamsInfo
1536
1537 for Index in range(0, len(ParamsOptionValueWords), 2):
1538 Name = ParamsOptionValueWords[Index].strip()
1539 Value = ParamsOptionValueWords[Index + 1].strip()
1540
1541 ParamName = CanonicalParamNamesMap[Name.lower()]
1542 ParamValue = Value
1543
1544 if re.match("^NRetries$", ParamName, re.I):
1545 if not MiscUtil.IsInteger(Value):
1546 MiscUtil.PrintError(
1547 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
1548 % (Value, ParamName, ParamsOptionName)
1549 )
1550 Value = int(Value)
1551 if Value < 0:
1552 MiscUtil.PrintError(
1553 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: >= 0\n'
1554 % (ParamValue, ParamName, ParamsOptionName)
1555 )
1556 ParamValue = Value
1557 elif re.match("^(KeepShared|KeepScratch)$", ParamName, re.I):
1558 if not re.match("^(yes|no|true|false)$", Value, re.I):
1559 MiscUtil.PrintError(
1560 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
1561 % (Value, Name, ParamsOptionName)
1562 )
1563 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
1564 else:
1565 ParamValue = Value
1566
1567 # Set value...
1568 ParamsInfo[ParamName] = ParamValue
1569
1570 # Handle parameters with possible auto values...
1571 _ProcessOptionOpenFEExecuteDAGParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1572
1573 return ParamsInfo
1574
1575
1576 def _ProcessOptionOpenFEExecuteDAGParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
1577 """Process parameters with possible auto values and perform validation."""
1578
1579 # Nothing to do...
1580 return
1581
1582
1583 def ProcessOptionOpenFEResultFileParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
1584 """Process parameters for result file and return a map containing processed
1585 parameter names and values.
1586
1587 The supported parameter names along with their default and possible
1588 values are shown below:
1589
1590 precision, 4 [ Possible values: > 0 ]
1591 delimiter, comma [ Possible values: comma or tab ]
1592
1593 Arguments:
1594 ParamsOptionName (str): Command line result file parameters option name.
1595 ParamsOptionValues (str): Comma delimited list of parameter name and value pairs.
1596 ParamsDefaultInfo (dict): Default values to override for selected parameters.
1597
1598 Returns:
1599 dictionary: Processed parameter name and value pairs.
1600
1601 """
1602
1603 ParamsInfo = {"Precision": 4, "Delimiter": "Comma"}
1604
1605 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
1606 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
1607 )
1608
1609 if re.match("^auto$", ParamsOptionValue, re.I):
1610 _ProcessOptionOpenFEResultFileParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1611 return ParamsInfo
1612
1613 for Index in range(0, len(ParamsOptionValueWords), 2):
1614 Name = ParamsOptionValueWords[Index].strip()
1615 Value = ParamsOptionValueWords[Index + 1].strip()
1616
1617 ParamName = CanonicalParamNamesMap[Name.lower()]
1618 ParamValue = Value
1619
1620 if re.match("^Precision$", ParamName, re.I):
1621 if not MiscUtil.IsInteger(Value):
1622 MiscUtil.PrintError(
1623 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
1624 % (Value, ParamName, ParamsOptionName)
1625 )
1626 Value = int(Value)
1627 if Value <= 0:
1628 MiscUtil.PrintError(
1629 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
1630 % (ParamValue, ParamName, ParamsOptionName)
1631 )
1632 ParamValue = Value
1633 elif re.match("^Delimiter$", ParamName, re.I):
1634 if not re.match("^(comma|tab)$", Value, re.I):
1635 MiscUtil.PrintError(
1636 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: comma or tab'
1637 % (Value, Name, ParamsOptionName)
1638 )
1639 ParamValue = Value
1640 else:
1641 ParamValue = Value
1642
1643 # Set value...
1644 ParamsInfo[ParamName] = ParamValue
1645
1646 # Handle parameters with possible auto values...
1647 _ProcessOptionOpenFEResultFileParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1648
1649 return ParamsInfo
1650
1651
1652 def _ProcessOptionOpenFEResultFileParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
1653 """Process parameters with possible auto values and perform validation."""
1654
1655 ParamName = "Delimiter"
1656 ParamValue = ParamsInfo[ParamName]
1657
1658 if re.match("^Tab$", ParamValue, re.I):
1659 FileExt = "tsv"
1660 FileDelimiter = "\t"
1661 elif re.match("^Comma$", ParamValue, re.I):
1662 FileExt = "csv"
1663 FileDelimiter = ","
1664 else:
1665 MiscUtil.PrintError(
1666 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: comma or tab'
1667 % (ParamValue, ParamName, ParamsOptionName)
1668 )
1669
1670 ParamsInfo["Ext"] = FileExt
1671 ParamsInfo["Delim"] = FileDelimiter
1672
1673 return
1674
1675
1676 def ProcessOptionOpenFERelativeFreeEnergyChargeCorrectionParameters(
1677 ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None
1678 ):
1679 """Process parameters for RBFE charge correction option and return a map
1680 containing processed parameter names and values.
1681
1682 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
1683 to setup charge correction for RBFE calculations.
1684
1685 The supported parameter names along with their default and possible
1686 values are shown below:
1687
1688 alchemicalExplicitChargeCorrection, yes
1689 simulationProductionLength = 20 * unit.nanosecond
1690 simulationNReplicas, 22
1691 lambdaWindows, 22
1692
1693 Arguments:
1694 ParamsOptionName (str): Command line OpenFE RBFE charge correction
1695 parameters option name.
1696 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
1697 ParamsDefaultInfo (dict): Default values to override for selected parameters.
1698
1699 Returns:
1700 dictionary: Processed parameter name and value pairs.
1701
1702 """
1703
1704 ParamsInfo = {
1705 "AlchemicalExplicitChargeCorrection": True,
1706 "SimulationProductionLength": 20,
1707 "SimulationNReplicas": 22,
1708 "LambdaWindows": 22,
1709 }
1710
1711 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
1712 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
1713 )
1714
1715 if re.match("^auto$", ParamsOptionValue, re.I):
1716 _ProcessOptionOpenFERelativeFreeEnergyChargeCorrectionParameters(
1717 ParamsInfo, ParamsOptionName, ParamsOptionValue
1718 )
1719 return ParamsInfo
1720
1721 for Index in range(0, len(ParamsOptionValueWords), 2):
1722 Name = ParamsOptionValueWords[Index].strip()
1723 Value = ParamsOptionValueWords[Index + 1].strip()
1724
1725 ParamName = CanonicalParamNamesMap[Name.lower()]
1726 ParamValue = Value
1727
1728 if re.match("^(SimulationProductionLength|SimulationNReplicas|LambdaWindows)$", ParamName, re.I):
1729 if not MiscUtil.IsInteger(Value):
1730 MiscUtil.PrintError(
1731 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
1732 % (Value, ParamName, ParamsOptionName)
1733 )
1734 Value = int(Value)
1735 if Value <= 0:
1736 MiscUtil.PrintError(
1737 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
1738 % (ParamValue, ParamName, ParamsOptionName)
1739 )
1740 ParamValue = Value
1741 elif re.match("^AlchemicalExplicitChargeCorrection$", ParamName, re.I):
1742 if not re.match("^(yes|no|true|false)$", Value, re.I):
1743 MiscUtil.PrintError(
1744 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
1745 % (Value, Name, ParamsOptionName)
1746 )
1747 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
1748 else:
1749 ParamValue = Value
1750
1751 # Set value...
1752 ParamsInfo[ParamName] = ParamValue
1753
1754 # Handle parameters with possible auto values...
1755 _ProcessOptionOpenFERelativeFreeEnergyChargeCorrectionParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1756
1757 return ParamsInfo
1758
1759
1760 def _ProcessOptionOpenFERelativeFreeEnergyChargeCorrectionParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
1761 """Process parameters with possible auto values and perform validation."""
1762
1763 # Setup units for SimulationProductionLength...
1764 ParamName = "SimulationProductionLength"
1765 ParamValue = ParamsInfo[ParamName]
1766 if MiscUtil.IsNumber(ParamValue):
1767 ParamsInfo[ParamName] = ParamValue * openff.units.unit.nanosecond
1768
1769
1770 def ProcessOptionOpenFERelativeFreeEnergyVacuumParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
1771 """Process parameters for RBFE vacuum option and return a map containing
1772 processed parameter names and values.
1773
1774 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
1775 to setup charge correction for RBFE calculations.
1776
1777 The supported parameter names along with their default and possible
1778 values are shown below:
1779
1780 forcefieldNonbondedMethod, NoCutoff [ Possible values: PME or NoCutoff ]
1781
1782 Arguments:
1783 ParamsOptionName (str): Command line OpenFE RBFE vacuum parameters
1784 option name.
1785 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
1786 ParamsDefaultInfo (dict): Default values to override for selected parameters.
1787
1788 Returns:
1789 dictionary: Processed parameter name and value pairs.
1790
1791 """
1792
1793 ParamsInfo = {"ForcefieldNonbondedMethod": "nocutoff"}
1794
1795 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
1796 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
1797 )
1798
1799 if re.match("^auto$", ParamsOptionValue, re.I):
1800 _ProcessOptionOpenFERelativeFreeEnergyVacuumParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1801 return ParamsInfo
1802
1803 for Index in range(0, len(ParamsOptionValueWords), 2):
1804 Name = ParamsOptionValueWords[Index].strip()
1805 Value = ParamsOptionValueWords[Index + 1].strip()
1806
1807 ParamName = CanonicalParamNamesMap[Name.lower()]
1808 ParamValue = Value
1809
1810 if re.match("^ForcefieldNonbondedMethod$", ParamName, re.I):
1811 if not re.match("^(PME|NoCutoff)$", Value, re.I):
1812 MiscUtil.PrintError(
1813 'The parameter value, %s, specified for parameter name, %s, using "%s" option is may be a valid OpenFE value. Supported values: PME or NoCutoff'
1814 % (Value, Name, ParamsOptionName)
1815 )
1816 ParamValue = Value.lower()
1817 else:
1818 ParamValue = Value
1819
1820 # Set value...
1821 ParamsInfo[ParamName] = ParamValue
1822
1823 # Handle parameters with possible auto values...
1824 _ProcessOptionOpenFERelativeFreeEnergyVacuumParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
1825
1826 return ParamsInfo
1827
1828
1829 def _ProcessOptionOpenFERelativeFreeEnergyVacuumParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
1830 """Process parameters with possible auto values and perform validation."""
1831
1832 # Nothing to do...
1833 return
1834
1835
1836 def ProcessOptionOpenFERelativeFreeEnergyParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
1837 """Process parameters for RFE parameters option and return a map
1838 containing processed parameter names and values.
1839
1840 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
1841 to setup RFE calculations.
1842
1843 The default values are automatically updated to match settings provided by
1844 OpenFE module RelativeHybridTopologyProtocol.
1845
1846 You must specify valid OpenFE values for these parameters. An extensive
1847 validation is not performed.
1848
1849 The supported parameter names along with their default and possible
1850 values are shown below:
1851
1852 protocolRepeats, 3
1853
1854 Alchemical settings:
1855
1856 alchemicalEndstateDispersionCorrection, no [ Possible values:
1857 yes or no ]
1858 alchemicalExplicitChargeCorrection, no [ Possible values:
1859 yes or no ]
1860 alchemicalExplicitChargeCorrectionCutoff, 0.8 [ Units: nanometer ]
1861 alchemicalSoftcoreLJ, Gapsys [ Possible values: Gapsys or Beutler ]
1862 alchemicalSoftcoreAlpha, 0.85
1863 alchemicalTurnOffCoreUniqueExceptions, no [ Possible values:
1864 yes or no ]
1865 alchemicalUseDispersionCorrection, no [ Possible values: yes or no ]
1866
1867 Engine settings:
1868
1869 engineComputePlatform, CPU [ Possible values: CPU, CUDA, OpenCL,
1870 or Reference ]
1871 engineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
1872
1873 Forcefield settings:
1874
1875 forcefieldConstraints, HBonds [ Possible values: HBonds, ALLBonds or
1876 HAngles ]
1877 forcefields, ['amber/ff14SB.xml', 'amber/tip3p_standard.xml',
1878 'amber/tip3p_HFE_multivalent.xml', 'amber/phosaa10.xml']
1879 [ Possible values: A space delimited list of valid names. ]
1880 forcefieldHydrogenMass, 3.0 [ Units: amu ]
1881 forcefieldNonbondedCutoff, 0.9 [ Units: nanometer ]
1882 forcefieldNonbondedMethod, PME [ Possible values: PME or NoCutoff ]
1883 forcefieldRigidWater, yes [ Possible values: yes or no ]
1884 forcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible value:
1885 A valid forcefield name. ]
1886
1887 Integrator settings:
1888
1889 integratorBarostatFrequency, 25.0 * timestep [ The specified value
1890 is a multiple of integratorTimestep. ]
1891 integratorConstraintTolerance, 1e-06
1892 integratorLangevinCollisionRate, 1.0 [ Units: 1 / picosecond ]
1893 integratorNRestartAttempts, 20
1894 integratorReassignVelocities, no [ Possible values: yes or no ]
1895 integratorRemoveCom, no [ Possible values: yes or no ]
1896 integratorTimestep, 4.0 [ Units: femtosecond ]
1897
1898 Lambda settings:
1899
1900 lambdaFunctions, default [ Possible values: Default, namd, or
1901 quarters ]
1902 lambdaWindows, 11
1903
1904 Output settings:
1905
1906 outputCheckpointInterval, 1.0 [ Units: nanosecond ]
1907 outputCheckpointStorageFilename, checkpoint.chk
1908 outputForcefieldCache, db.json
1909 outputFilename, simulation.nc
1910 outputIndices, not water [ Possible value: Any valid selection. ]
1911 outputStructure, hybrid_system.pdb
1912 outputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
1913 outputVelocitiesWriteFrequency, None [ Possible values: > 0;
1914 Units: picosecond ]
1915
1916 Partial charge settings:
1917
1918 partialChargeNaglModel, None [ Default: Production AM1BCC model for
1919 NAGL; Possible value: Any valid name. ]
1920 partialChargeNumberOfConformers, None [ Possible value: > 0 ]
1921 partialChargeOffToolkitBackend, AmberTools [ Possible values:
1922 AmberTools or RDKit ]
1923 partialChargeMethod, AM1BCC [ Possble values: AM1BCC, Espaloma,
1924 or NAGL ]
1925
1926 Simulation settings:
1927
1928 simulationEarlyTerminationTargetError, 0.0 [ Units:
1929 kilocalorie_per_mole ]
1930 simulationEquilibrationLength, 1.0 [ Units: nanosecond ]
1931 simulationMinimizationSteps, 5000
1932 simulationNReplicas, 11
1933 simulationProductionLength, 5.0 [ Units: nanosecond ]
1934 simulationRealTimeAnalysisInterval, 250.0 [ Units: picosecond ]
1935 simulationRealTimeAnalysisMinimumTime, 500.0 [ Units: picosecond ]
1936 simulationSamplerMethod, repex [ Possible values: repex, sams,
1937 or independent ]
1938 simulationSamsFlatnessCriteria, logZ-flatness [ Possible values:
1939 logZ-flatness, minimum-visits or histogram-flatness ]
1940 simulationSamsGamma0, 1.0
1941 simulationTimePerIteration, 2.5 [ Units: picosecond ]
1942
1943 Solvation settings:
1944
1945 solvationBoxShape, dodecahedron [ Possible values: cube,
1946 dodecahedron, or octahedron ]
1947 solvationBoxSize, None [ Possible value: A triplet of space
1948 X Y Z values; Units: nanometer ]
1949 solvationSolventModel, tip3p [ Possible values: tip3p, spce, tip4pew,
1950 or tip5p ]
1951 solvationSolventPadding, 1.5 [ Units: nanometer ]
1952
1953 Thermo settings:
1954
1955 thermoPh, None [ Possible values: > 0 ]
1956 thermoPressure, 1.0 [ Units: bar ]
1957 thermoRedoxPotential, None [ Possible values: A valid float.
1958 Units: millivolts (mV) ]
1959 thermoTemperature, 298.15 [ Units: kelvin ]
1960
1961 A brief description of parameters, taken from OpenFE documentation, is
1962 provided below:
1963
1964 protocolRepeats: Number of completely independent repeats of the
1965 entire sampling process.
1966
1967 Alchemical settings:
1968
1969 Parameters controlling the creation of the hybrid topology system,
1970 including various parameters ranging from softcore parameters to
1971 whether or not to apply an explicit charge correction for systems
1972 with net charge changes.
1973
1974 alchemicalEndstateDispersionCorrection: Employ extra unsampled
1975 endstate windows for long range correction.
1976 alchemicalExplicitChargeCorrection: Explicitly account for a charge
1977 difference during the alchemical transformation by transforming
1978 a water to a counterion of the opposite charge of the formal
1979 charge difference.
1980 alchemicalExplicitChargeCorrectionCutoff: Minimum distance from the
1981 system solutes from which an alchemical water can be chosen.
1982 alchemicalSoftcoreLJ: Use LJ softcore function as defined by Gapsys
1983 [ Ref 181 ] or Buetler [ Ref 182 ].
1984 alchemicalSoftcoreAlpha: Softcore alpha parameter.
1985 alchemicalTurnOffCoreUniqueExceptions: Turn off interactions for
1986 new exceptions (not just 1,4s) at lambda 0 and old exceptions at
1987 lambda 1 between unique atoms and core atoms.
1988 alchemicalUseDispersionCorrection: Use dispersion correction in the
1989 hybrid topology state.
1990
1991 Engine settings:
1992
1993 Parameters configuring the compute platform used by the OpenMM to
1994 perform the simulation.
1995
1996 engineComputePlatform: Platform to use for running OpenMM MD
1997 calculations.
1998 engineGpuDeviceIndex: Space delimited list of device indices to use
1999 for running OpenMM MD calculations.
2000
2001 Forcefield settings:
2002
2003 Parameters to set up the force field with OpenMM Force Fields,
2004 including the general force fields, the small molecule force field,
2005 the nonbonded method, and the nonbonded cutoff.
2006
2007 forcefieldConstraints: Constraints to use.
2008 forcefields: List of valid forcefield paths for all components
2009 except small molecules.
2010 forcefieldHydrogenMass: Mass to be repartitioned to hydrogens from
2011 neighboring heavy atoms.
2012 forcefieldNonbondedCutoff: Cutoff for short range nonbonded
2013 interactions.
2014 forcefieldNonbondedMethod: Method for treating nonbonded
2015 interactions.
2016 forcefieldRigidWater: Use a rigid water model.
2017 forcefieldSmallMoleculeForcefield: A valid forcefield name to use
2018 for small molecules.
2019
2020 Integrator settings
2021
2022 Parameters controlling the LangevinSplittingDynamicsMove integrator
2023 used for simulation.
2024
2025 integratorBarostatFrequency: Frequency at which volume scaling
2026 changes should be attempted.
2027 integratorConstraintTolerance: Tolerance for constraint solver.
2028 integratorLangevinCollisionRate: Collision frequency.
2029 integratorNRestartAttempts: Number of attempts to restart from
2030 Context in case there are NaNs in the energies after
2031 integration.
2032 integratorReassignVelocities: Reassign velocities from the
2033 Maxwell-Boltzmann distribution at the beginning of each
2034 Monte Carlo move.
2035 integratorRemoveCom: Remove the center of mass motion.
2036 integratorTimestep: Size of the simulation timestep.
2037
2038 Lambda settings:
2039
2040 Lambda protocol parameters, including number of lambda windows and
2041 lambda functions.
2042
2043 lambdaFunctions: Function name to use for alchemical mutation.
2044 lambdaWindows: Number of lambda windows to calculate.
2045
2046 Output settings:
2047
2048 Parameter controlling simulation output, including the frequency to
2049 write a checkpoint file, the selection string for writing selected
2050 coordinates, and the paths to the trajectory and output structure
2051 files.
2052
2053 outputCheckpointInterval: Frequency to write the checkpoint file.
2054 outputCheckpointStorageFilename: Checkpoint filename.
2055 outputForcefieldCache: Filename for caching small molecule residue
2056 templates.
2057 outputFilename: Trajectory filename.
2058 outputIndices: Selection string for selecting coordinates to write.
2059 outputStructure: Hybrid topology structure filename.
2060 outputPositionsWriteFrequency: Frequency for writing positions to
2061 trajectory file.
2062 outputVelocitiesWriteFrequency: Frequency for writing velocities to
2063 trajectory file.
2064
2065 Partial charge settings:
2066
2067 Parameters for automatically assigning missing partial charges to
2068 small molecules, including the partial charge method.
2069
2070 partialChargeNaglModel: Model to use for partial charge assignment.
2071 A value of None implies the use of the latest available
2072 production AM1BCC model.
2073 partialChargeNumberOfConformers: Number of conformers to generate
2074 as part of the partial charge assignment. A value of None
2075 implies the use of the existing conformer.
2076 partialChargeOffToolkitBackend: OpenFF toolkit registry backend to
2077 use for calculating partial charges.
2078 partialChargeMethod: Method to use for calculating partial charges.
2079
2080 Simulation settings:
2081
2082 Parameters controlling the simulation plan and the alchemical
2083 sampler, including the number of minimization steps, lengths of
2084 equilibration and production runs, the sampler method (e.g.
2085 Hamiltonian REPlica EXchange (repex), and the time interval at
2086 which to perform an analysis of the free energies.
2087
2088 simulationEarlyTerminationTargetError: Target error for the real
2089 time analysis measured in kcal/mol. Once the MBAR error of the
2090 free energy is at or below this value, the simulation will be
2091 considered complete. The suggested value of 0.12 has shown to
2092 be effective in both hydration and binding free energy
2093 benchmarks.
2094 simulationEquilibrationLength: Length of the equilibration phase.
2095 The specified value must be divisible by 'integratorTimestep'.
2096 simulationMinimizationSteps: Number of minimization steps to
2097 perform.
2098 simulationNReplicas: Number of replicas to use.
2099 simulationProductionLength: Length of the production phase.
2100 The specified value must be divisible by 'integratorTimestep'.
2101 simulationRealTimeAnalysisInterval: Time interval for performing
2102 analysis of the free energies. At each interval, real time
2103 analysis data will be written to a yaml file named
2104 <outputFileName>_real_time_analysis.yaml. The current error
2105 in the estimate will also be assessed and the simulation will
2106 be terminated when it drops below
2107 'simulationEarlyTerminationTargetError'.
2108 simulationRealTimeAnalysisMinimumTime: Minimum simulation time
2109 after which the real time analysis is performed.
2110 simulationSamplerMethod: Alchemical sampling method to use:
2111 REPEX (Hamiltonian REPlica EXchange), SAMS (Self-Adjusted
2112 Mixture Sampling), or Independent (Independently sampled lambda
2113 windows).
2114 simulationSamsFlatnessCriteria:Method for assessing when to switch
2115 to asymptomatically optimal scheme for SAMS.
2116 simulationSamsGamma0: Initial weight adaptation rate for SAMS.
2117 simulationTimePerIteration: Simulation time between each MCMC move
2118 attempt
2119
2120 Solvation settings:
2121
2122 Solvation parameters for the system, including the solvent model and
2123 the solvent padding.
2124
2125 solvationBoxShape: Shape of the periodic solvent box to create.
2126 solvationBoxSize: Lengths of the unit cell for a solvent box.
2127 solvationSolventModel: Forcefield water model to use during
2128 solvation and defining the model properties.
2129 solvationSolventPadding: Minimum distance from any solute bounding
2130 sphere to the edge of the box.
2131
2132 Thermo settings:
2133
2134 Thermodynamic parameters, including the temperature and the pressure
2135 of the system.
2136
2137 thermoPh: Simulation pH.
2138 thermoPressure: Simulation pressure.
2139 thermoRedoxPotential:Simulation redox potential.
2140 thermoTemperature: Simulation temperature.
2141
2142 Arguments:
2143 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
2144 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
2145 ParamsDefaultInfo (dict): Default values to override selected parameters.
2146
2147 Returns:
2148 dictionary: Processed parameter name and value pairs.
2149
2150 """
2151 ParamsInfo = _SetupRelativeFreeEnergyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue)
2152
2153 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
2154 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
2155 )
2156
2157 if re.match("^auto$", ParamsOptionValue, re.I):
2158 _ProcessOptionOpenFERelativeFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
2159 return ParamsInfo
2160
2161 for Index in range(0, len(ParamsOptionValueWords), 2):
2162 Name = ParamsOptionValueWords[Index].strip()
2163 Value = ParamsOptionValueWords[Index + 1].strip()
2164
2165 ParamName = CanonicalParamNamesMap[Name.lower()]
2166 ParamValue = Value
2167
2168 if re.match(
2169 "^(ProtocolRepeats|IntegratorNRestartAttempts|LambdaWindows|PartialChargeNumberOfConformers|SimulationMinimizationSteps|SimulationNReplicas|solvationNumbeOfSolventMolecules)$",
2170 ParamName,
2171 re.I,
2172 ):
2173 # Int > 0
2174 if not MiscUtil.IsInteger(Value):
2175 MiscUtil.PrintError(
2176 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
2177 % (Value, ParamName, ParamsOptionName)
2178 )
2179 Value = int(Value)
2180 if Value <= 0:
2181 MiscUtil.PrintError(
2182 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2183 % (ParamValue, ParamName, ParamsOptionName)
2184 )
2185 ParamValue = Value
2186 elif re.match(
2187 "^(AlchemicalSoftcoreAlpha|ForcefieldHydrogenMass|IntegratorConstraintTolerance|SimulationSamsGamma0)$",
2188 ParamName,
2189 re.I,
2190 ):
2191 # float > 0
2192 if not MiscUtil.IsFloat(Value):
2193 MiscUtil.PrintError(
2194 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2195 % (Value, ParamName, ParamsOptionName)
2196 )
2197 Value = float(Value)
2198 if Value <= 0:
2199 MiscUtil.PrintError(
2200 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2201 % (ParamValue, ParamName, ParamsOptionName)
2202 )
2203 ParamValue = Value
2204 elif re.match("^ThermoPh$", ParamName, re.I):
2205 # float > 0 or None
2206 if re.match("^None$", Value, re.I):
2207 ParamValue = None
2208 else:
2209 if not MiscUtil.IsFloat(Value):
2210 MiscUtil.PrintError(
2211 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2212 % (Value, ParamName, ParamsOptionName)
2213 )
2214 Value = float(Value)
2215 if Value <= 0:
2216 MiscUtil.PrintError(
2217 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2218 % (ParamValue, ParamName, ParamsOptionName)
2219 )
2220 ParamValue = Value
2221 elif re.match("^ThermoRedoxPotential$", ParamName, re.I):
2222 if re.match("^None$", Value, re.I):
2223 ParamValue = None
2224 else:
2225 if not MiscUtil.IsFloat(Value):
2226 MiscUtil.PrintError(
2227 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2228 % (Value, ParamName, ParamsOptionName)
2229 )
2230 Value = float(Value)
2231 ParamValue = Value * openff.units.unit.millivolts
2232 elif re.match(
2233 "^(AlchemicalEndstateDispersionCorrection|AlchemicalExplicitChargeCorrection|AlchemicalTurnOffCoreUniqueExceptions|AlchemicalUseDispersionCorrection|ForcefieldRigidWater|IntegratorReassignVelocities|IntegratorRemoveCom)$",
2234 ParamName,
2235 re.I,
2236 ):
2237 # bool
2238 if not re.match("^(yes|no|true|false)$", Value, re.I):
2239 MiscUtil.PrintError(
2240 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
2241 % (Value, Name, ParamsOptionName)
2242 )
2243 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
2244 elif re.match("^(AlchemicalExplicitChargeCorrectionCutoff|ForcefieldNonbondedCutoff)$", ParamName, re.I):
2245 # float > 0 and units nanometer
2246 if not MiscUtil.IsFloat(Value):
2247 MiscUtil.PrintError(
2248 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2249 % (Value, ParamName, ParamsOptionName)
2250 )
2251 Value = float(Value)
2252 if Value <= 0:
2253 MiscUtil.PrintError(
2254 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2255 % (ParamValue, ParamName, ParamsOptionName)
2256 )
2257 ParamValue = Value * openff.units.unit.nanometer
2258 elif re.match("^SolvationSolventPadding$", ParamName, re.I):
2259 # float > 0 and units nanometer or none
2260 if re.match("^None$", Value, re.I):
2261 ParamValue = None
2262 else:
2263 if not MiscUtil.IsFloat(Value):
2264 MiscUtil.PrintError(
2265 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2266 % (Value, ParamName, ParamsOptionName)
2267 )
2268 Value = float(Value)
2269 if Value <= 0:
2270 MiscUtil.PrintError(
2271 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2272 % (ParamValue, ParamName, ParamsOptionName)
2273 )
2274 ParamValue = Value * openff.units.unit.nanometer
2275 elif re.match("^AlchemicalSoftcoreLJ$", ParamName, re.I):
2276 if not re.match("^(Gapsys|Beutler)$", Value, re.I):
2277 MiscUtil.PrintError(
2278 'The parameter value, %s, specified for parameter name, %s, using "%s" option is may be a valid OpenFE value. Supported values: Gapsys or Beutler'
2279 % (Value, Name, ParamsOptionName)
2280 )
2281 ParamValue = Value.lower()
2282 elif re.match("^EngineComputePlatform$", ParamName, re.I):
2283 if not re.match("^(CPU|CUDA|OpenCL|Reference)$", Value, re.I):
2284 MiscUtil.PrintError(
2285 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: CPU, CUDA, OpenCL, or Reference'
2286 % (Value, Name, ParamsOptionName)
2287 )
2288 ParamValue = Value
2289 elif re.match("^EngineGpuDeviceIndex$", ParamName, re.I):
2290 # Comma delimited string values...
2291 DeviceIndices = Value.split()
2292 if len(DeviceIndices) == 0:
2293 MiscUtil.PrintError(
2294 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain space delimited list of device indices.\n'
2295 % (Value, ParamName, ParamsOptionName)
2296 )
2297 for DeviceIndex in DeviceIndices:
2298 if not MiscUtil.IsInteger(DeviceIndex):
2299 MiscUtil.PrintError(
2300 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
2301 % (DeviceIndex, ParamName, ParamsOptionName)
2302 )
2303 DeviceIndices = [int(DeviceIndex) for DeviceIndex in DeviceIndices]
2304 ParamValue = DeviceIndices
2305 elif re.match("^Forcefields$", ParamName, re.I):
2306 # List of string values.....
2307 Values = Value.split()
2308 if len(Values) == 0:
2309 MiscUtil.PrintError(
2310 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a space delimited list of values..\n'
2311 % (Value, ParamName, ParamsOptionName)
2312 )
2313 ParamValue = Values
2314 elif re.match("^ForcefieldConstraints$", ParamName, re.I):
2315 if not re.match("^(HBonds|AllBonds|HAngles|None)$", Value, re.I):
2316 MiscUtil.PrintError(
2317 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: HBonds, AllBonds, HAngles, or None'
2318 % (Value, Name, ParamsOptionName)
2319 )
2320 ParamValue = None if re.match("^None$", Value, re.I) else Value.lower()
2321 elif re.match("^ForcefieldNonbondedMethod$", ParamName, re.I):
2322 if not re.match("^(PME|NoCutoff)$", Value, re.I):
2323 MiscUtil.PrintError(
2324 'The parameter value, %s, specified for parameter name, %s, using "%s" option is may be a valid OpenFE value. Supported values: PME or NoCutoff'
2325 % (Value, Name, ParamsOptionName)
2326 )
2327 ParamValue = Value.lower()
2328 elif re.match("^PartialChargeOffToolkitBackend$", ParamName, re.I):
2329 if not re.match("^(AmberTools|OpenEye|RDKit)$", Value, re.I):
2330 MiscUtil.PrintError(
2331 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AmberTools, OpenEye, or RDKit'
2332 % (Value, Name, ParamsOptionName)
2333 )
2334 ParamValue = Value.lower()
2335 elif re.match("^PartialChargeMethod$", ParamName, re.I):
2336 if not re.match("^(AM1BCC|AM1BCCELF10|Espaloma|NAGL)$", Value, re.I):
2337 MiscUtil.PrintError(
2338 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AM1BCC, AM1BCCELF10, Espaloma, or NAGL'
2339 % (Value, Name, ParamsOptionName)
2340 )
2341 ParamValue = Value.lower()
2342 elif re.match("^IntegratorBarostatFrequency$", ParamName, re.I):
2343 if not MiscUtil.IsFloat(Value):
2344 MiscUtil.PrintError(
2345 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2346 % (Value, ParamName, ParamsOptionName)
2347 )
2348 Value = float(Value)
2349 if Value <= 0:
2350 MiscUtil.PrintError(
2351 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2352 % (ParamValue, ParamName, ParamsOptionName)
2353 )
2354 ParamValue = Value * openff.units.unit.timestep
2355 elif re.match("^IntegratorLangevinCollisionRate$", ParamName, re.I):
2356 if not MiscUtil.IsFloat(Value):
2357 MiscUtil.PrintError(
2358 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2359 % (Value, ParamName, ParamsOptionName)
2360 )
2361 Value = float(Value)
2362 if Value <= 0:
2363 MiscUtil.PrintError(
2364 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2365 % (ParamValue, ParamName, ParamsOptionName)
2366 )
2367 ParamValue = Value / openff.units.unit.picosecond
2368 elif re.match("^IntegratorTimestep$", ParamName, re.I):
2369 # float > 0 femtosecond
2370 if not MiscUtil.IsFloat(Value):
2371 MiscUtil.PrintError(
2372 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2373 % (Value, ParamName, ParamsOptionName)
2374 )
2375 Value = float(Value)
2376 if Value <= 0:
2377 MiscUtil.PrintError(
2378 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2379 % (ParamValue, ParamName, ParamsOptionName)
2380 )
2381 ParamValue = Value * openff.units.unit.femtosecond
2382 elif re.match(
2383 "^(OutputPositionsWriteFrequency|SimulationRealTimeAnalysisMinimumTime|SimulationTimePerIteration)$",
2384 ParamName,
2385 re.I,
2386 ):
2387 # float > 0 picosecond
2388 if not MiscUtil.IsFloat(Value):
2389 MiscUtil.PrintError(
2390 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2391 % (Value, ParamName, ParamsOptionName)
2392 )
2393 Value = float(Value)
2394 if Value <= 0:
2395 MiscUtil.PrintError(
2396 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2397 % (ParamValue, ParamName, ParamsOptionName)
2398 )
2399 ParamValue = Value * openff.units.unit.picosecond
2400 elif re.match("^(OutputCheckpointInterval|SimulationEquilibrationLength|SimulationProductionLength)$", ParamName, re.I):
2401 # float > 0 nanosecond
2402 if not MiscUtil.IsFloat(Value):
2403 MiscUtil.PrintError(
2404 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2405 % (Value, ParamName, ParamsOptionName)
2406 )
2407 Value = float(Value)
2408 if Value <= 0:
2409 MiscUtil.PrintError(
2410 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2411 % (ParamValue, ParamName, ParamsOptionName)
2412 )
2413 ParamValue = Value * openff.units.unit.nanosecond
2414 elif re.match("^(OutputVelocitiesWriteFrequency|SimulationRealTimeAnalysisInterval)$", ParamName, re.I):
2415 # float > 0 picosecond or none
2416 if re.match("^None$", Value, re.I):
2417 ParamValue = None
2418 else:
2419 if not MiscUtil.IsFloat(Value):
2420 MiscUtil.PrintError(
2421 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2422 % (Value, ParamName, ParamsOptionName)
2423 )
2424 Value = float(Value)
2425 if Value <= 0:
2426 MiscUtil.PrintError(
2427 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2428 % (ParamValue, ParamName, ParamsOptionName)
2429 )
2430 ParamValue = Value * openff.units.unit.picosecond
2431 elif re.match("^LambdaFunctions$", ParamName, re.I):
2432 if not re.match("^(default|namd|quarters)$", Value, re.I):
2433 MiscUtil.PrintError(
2434 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: default, namd, or quarters'
2435 % (Value, Name, ParamsOptionName)
2436 )
2437 ParamValue = Value.lower()
2438 elif re.match("^SimulationSamplerMethod$", ParamName, re.I):
2439 if not re.match("^(repex|sams|independent)$", Value, re.I):
2440 MiscUtil.PrintError(
2441 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: repex, sams, or independent'
2442 % (Value, Name, ParamsOptionName)
2443 )
2444 ParamValue = Value.lower()
2445 elif re.match("^SimulationSamsFlatnessCriteria$", ParamName, re.I):
2446 if not re.match("^(logz-flatness|minimum-visits|histogram-flatness)$", Value, re.I):
2447 MiscUtil.PrintError(
2448 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: logz-flatness, minimum-visits, or histogram-flatness'
2449 % (Value, Name, ParamsOptionName)
2450 )
2451 ParamValue = Value.lower()
2452 elif re.match("^SolvationBoxShape$", ParamName, re.I):
2453 if not re.match("^(cube|dodecahedron|octahedron)$", Value, re.I):
2454 MiscUtil.PrintError(
2455 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: cube, dodecahedron, or octahedron'
2456 % (Value, Name, ParamsOptionName)
2457 )
2458 ParamValue = Value.lower()
2459 elif re.match("^SolvationSolventModel$", ParamName, re.I):
2460 if not re.match("^(tip3p|spce|tip4pew|tip5p)$", Value, re.I):
2461 MiscUtil.PrintError(
2462 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: tip3p, spce, tip4pew, or tip5p'
2463 % (Value, Name, ParamsOptionName)
2464 )
2465 ParamValue = Value.lower()
2466 elif re.match("^SimulationEarlyTerminationTargetError$", ParamName, re.I):
2467 # float >= 0 units kilocalorie_per_mole
2468 if not MiscUtil.IsFloat(Value):
2469 MiscUtil.PrintError(
2470 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2471 % (Value, ParamName, ParamsOptionName)
2472 )
2473 Value = float(Value)
2474 if Value < 0:
2475 MiscUtil.PrintError(
2476 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2477 % (ParamValue, ParamName, ParamsOptionName)
2478 )
2479 ParamValue = Value * openff.units.unit.kilocalorie_per_mole
2480 elif re.match("^SolvationBoxSize$", ParamName, re.I):
2481 # List of X, Y, Z values...
2482 if re.match("^None$", Value, re.I):
2483 ParamValue = None
2484 else:
2485 Values = Value.split()
2486 if len(Values) != 3:
2487 MiscUtil.PrintError(
2488 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of three space delimited values.\n'
2489 % (Value, ParamName, ParamsOptionName)
2490 )
2491 for Value in Values:
2492 if not MiscUtil.IsFloat(Value):
2493 MiscUtil.PrintError(
2494 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2495 % (Value, ParamName, ParamsOptionName)
2496 )
2497 Values = [float(Value) for Value in Values]
2498 ParamValue = Values * openff.units.unit.nanometer
2499 elif re.match("^ThermoPressure$", ParamName, re.I):
2500 # float > 0 and units bar
2501 if not MiscUtil.IsFloat(Value):
2502 MiscUtil.PrintError(
2503 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2504 % (Value, ParamName, ParamsOptionName)
2505 )
2506 Value = float(Value)
2507 if Value <= 0:
2508 MiscUtil.PrintError(
2509 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
2510 % (ParamValue, ParamName, ParamsOptionName)
2511 )
2512 ParamValue = Value * openff.units.unit.bar
2513 elif re.match("^ThermoTemperature$", ParamName, re.I):
2514 # float >= 0 and units kelvin
2515 if not MiscUtil.IsFloat(Value):
2516 MiscUtil.PrintError(
2517 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
2518 % (Value, ParamName, ParamsOptionName)
2519 )
2520 Value = float(Value)
2521 if Value < 0:
2522 MiscUtil.PrintError(
2523 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: >= 0\n'
2524 % (ParamValue, ParamName, ParamsOptionName)
2525 )
2526 ParamValue = Value * openff.units.unit.kelvin
2527 else:
2528 # Str or None...
2529 ParamValue = None if re.match("^None$", Value, re.I) else Value
2530
2531 # Set value...
2532 ParamsInfo[ParamName] = ParamValue
2533
2534 # Handle parameters with possible auto values...
2535 _ProcessOptionOpenFERelativeFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
2536
2537 return ParamsInfo
2538
2539
2540 def _ProcessOptionOpenFERelativeFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
2541 """Process parameters with possible auto values and perform validation."""
2542
2543 # Validate solvation parameter values...
2544 ParamName1 = "SolvationBoxSize"
2545 ParamValue1 = ParamsInfo[ParamName1]
2546 ParamName2 = "SolvationSolventPadding"
2547 ParamValue2 = ParamsInfo[ParamName2]
2548 if ParamsInfo[ParamName1] is not None and ParamsInfo[ParamName2] is not None:
2549 MiscUtil.PrintError(
2550 'The parameter values, %s and %s, specified for parameter names, %s and %s, using "%s" option is not a valid value. You must specify only one of these values.\n'
2551 % (ParamValue1, ParamValue2, ParamName1, ParamName2, ParamsOptionName)
2552 )
2553
2554 _ProcessPartialChargeMethodRelativeFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
2555 _ProcessPartialChargeNaglRelativeFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
2556
2557
2558 def _ProcessPartialChargeMethodRelativeFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
2559 """Process PartialChargeMethod RFE paramater."""
2560
2561 _ProcessPartialChargeMethodFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
2562
2563
2564 def _ProcessPartialChargeNaglRelativeFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
2565 """Process PartialChargeNaglModel RFE paramater."""
2566
2567 _ProcessPartialChargeNaglFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
2568
2569
2570 def _SetupMapForRelativeFreeEnergyParameters():
2571 """Map relative free energy option paramater names to OpenFE relative
2572 free energy settings.
2573 """
2574
2575 RFEParametersMap = {
2576 "ProtocolRepeats": [None, "protocol_repeats"],
2577 "AlchemicalEndstateDispersionCorrection": ["alchemical_settings", "endstate_dispersion_correction"],
2578 "AlchemicalExplicitChargeCorrection": ["alchemical_settings", "explicit_charge_correction"],
2579 "AlchemicalExplicitChargeCorrectionCutoff": ["alchemical_settings", "explicit_charge_correction_cutoff"],
2580 "AlchemicalSoftcoreLJ": ["alchemical_settings", "softcore_LJ"],
2581 "AlchemicalSoftcoreAlpha": ["alchemical_settings", "softcore_alpha"],
2582 "AlchemicalTurnOffCoreUniqueExceptions": ["alchemical_settings", "turn_off_core_unique_exceptions"],
2583 "AlchemicalUseDispersionCorrection": ["alchemical_settings", "use_dispersion_correction"],
2584 "EngineComputePlatform": ["engine_settings", "compute_platform"],
2585 "EngineGpuDeviceIndex": ["engine_settings", "gpu_device_index"],
2586 "ForcefieldConstraints": ["forcefield_settings", "constraints"],
2587 "Forcefields": ["forcefield_settings", "forcefields"],
2588 "ForcefieldHydrogenMass": ["forcefield_settings", "hydrogen_mass"],
2589 "ForcefieldNonbondedCutoff": ["forcefield_settings", "nonbonded_cutoff"],
2590 "ForcefieldNonbondedMethod": ["forcefield_settings", "nonbonded_method"],
2591 "ForcefieldRigidWater": ["forcefield_settings", "rigid_water"],
2592 "ForcefieldSmallMoleculeForcefield": ["forcefield_settings", "small_molecule_forcefield"],
2593 "IntegratorBarostatFrequency": ["integrator_settings", "barostat_frequency"],
2594 "IntegratorConstraintTolerance": ["integrator_settings", "constraint_tolerance"],
2595 "IntegratorLangevinCollisionRate": ["integrator_settings", "langevin_collision_rate"],
2596 "IntegratorNRestartAttempts": ["integrator_settings", "n_restart_attempts"],
2597 "IntegratorReassignVelocities": ["integrator_settings", "reassign_velocities"],
2598 "IntegratorRemoveCom": ["integrator_settings", "remove_com"],
2599 "IntegratorTimestep": ["integrator_settings", "timestep"],
2600 "LambdaFunctions": ["lambda_settings", "lambda_functions"],
2601 "LambdaWindows": ["lambda_settings", "lambda_windows"],
2602 "OutputCheckpointInterval": ["output_settings", "checkpoint_interval"],
2603 "OutputCheckpointStorageFilename": ["output_settings", "checkpoint_storage_filename"],
2604 "OutputForcefieldCache": ["output_settings", "forcefield_cache"],
2605 "OutputFilename": ["output_settings", "output_filename"],
2606 "OutputIndices": ["output_settings", "output_indices"],
2607 "OutputStructure": ["output_settings", "output_structure"],
2608 "OutputPositionsWriteFrequency": ["output_settings", "positions_write_frequency"],
2609 "OutputVelocitiesWriteFrequency": ["output_settings", "velocities_write_frequency"],
2610 "PartialChargeNaglModel": ["partial_charge_settings", "nagl_model"],
2611 "PartialChargeNumberOfConformers": ["partial_charge_settings", "number_of_conformers"],
2612 "PartialChargeOffToolkitBackend": ["partial_charge_settings", "off_toolkit_backend"],
2613 "PartialChargeMethod": ["partial_charge_settings", "partial_charge_method"],
2614 "SimulationEarlyTerminationTargetError": ["simulation_settings", "early_termination_target_error"],
2615 "SimulationEquilibrationLength": ["simulation_settings", "equilibration_length"],
2616 "SimulationMinimizationSteps": ["simulation_settings", "minimization_steps"],
2617 "SimulationNReplicas": ["simulation_settings", "n_replicas"],
2618 "SimulationProductionLength": ["simulation_settings", "production_length"],
2619 "SimulationRealTimeAnalysisInterval": ["simulation_settings", "real_time_analysis_interval"],
2620 "SimulationRealTimeAnalysisMinimumTime": ["simulation_settings", "real_time_analysis_minimum_time"],
2621 "SimulationSamplerMethod": ["simulation_settings", "sampler_method"],
2622 "SimulationSamsFlatnessCriteria": ["simulation_settings", "sams_flatness_criteria"],
2623 "SimulationSamsGamma0": ["simulation_settings", "sams_gamma0"],
2624 "SimulationTimePerIteration": ["simulation_settings", "time_per_iteration"],
2625 "SolvationBoxShape": ["solvation_settings", "box_shape"],
2626 "SolvationBoxSize": ["solvation_settings", "box_size"],
2627 "SolvationSolventModel": ["solvation_settings", "solvent_model"],
2628 "SolvationSolventPadding": ["solvation_settings", "solvent_padding"],
2629 "ThermoPh": ["thermo_settings", "ph"],
2630 "ThermoPressure": ["thermo_settings", "pressure"],
2631 "ThermoRedoxPotential": ["thermo_settings", "redox_potential"],
2632 "ThermoTemperature": ["thermo_settings", "temperature"],
2633 }
2634
2635 return RFEParametersMap
2636
2637
2638 def _SetupRelativeFreeEnergyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue):
2639 """Setup RFE default parameters information using the current RFE settings."""
2640
2641 ParamsInfo = {}
2642
2643 RBFESettings = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol.default_settings()
2644 RFEParametersMap = _SetupMapForRelativeFreeEnergyParameters()
2645
2646 for ParamName in RFEParametersMap.keys():
2647 RFEParamGroupName, RFEParamName = RFEParametersMap[ParamName]
2648 if RFEParamGroupName is None:
2649 if hasattr(RBFESettings, RFEParamName):
2650 ParamsInfo[ParamName] = getattr(RBFESettings, RFEParamName)
2651 else:
2652 MiscUtil.PrintInfo(
2653 'The OpenFE RFE settings name, %s, corresponding to RFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
2654 % (RFEParamName, ParamName, ParamsOptionName)
2655 )
2656 else:
2657 RFEParamGroupSettings = (
2658 getattr(RBFESettings, RFEParamGroupName) if hasattr(RBFESettings, RFEParamGroupName) else None
2659 )
2660 if RFEParamGroupSettings is not None and hasattr(RFEParamGroupSettings, RFEParamName):
2661 ParamsInfo[ParamName] = getattr(RFEParamGroupSettings, RFEParamName)
2662 else:
2663 MiscUtil.PrintInfo(
2664 'The OpenFE RFE parameter name, %s, for settings, %s, corresponding to RFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
2665 % (RFEParamName, RFEParamGroupName, ParamName, ParamsOptionName)
2666 )
2667
2668 return ParamsInfo
2669
2670
2671 def SetupRelativeFreeEnergySettings(ParamsOptionName, ParamsInfo):
2672 """Setup relative free energy protocol settings to calculate RBFE.
2673
2674 The ParamsInfo is a comma delimited list of parameter name and value pairs
2675 returned by ProcessOptionOpenFERelativeFreeEnergyParameters().
2676
2677 Arguments:
2678 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
2679 ParamsInfo (dict): Parameter name and value pairs.
2680
2681 Returns:
2682 object: OpenFE RelativeHybridTopologyProtocol settings object.
2683
2684 """
2685
2686 RBFESettings = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol.default_settings()
2687 RFEParametersMap = _SetupMapForRelativeFreeEnergyParameters()
2688
2689 _UpdateOpenFESettings("RBFE", ParamsOptionName, ParamsInfo, RBFESettings, RFEParametersMap)
2690
2691 return RBFESettings
2692
2693
2694 def UpdateRelativeFreeEnergySettingsForChargeCorrection(ParamsOptionName, ParamsInfo, RBFESettings):
2695 """Update relative free energy protocol settings for charge correction.
2696
2697 The ParamsInfo is a comma delimited list of parameter name and value pairs
2698 returned by ProcessOptionOpenFERelativeFreeEnergyChargeCorrectionParameters().
2699
2700 Arguments:
2701 ParamsOptionName (str): Command line OpenFE RBFE charge correction
2702 parameters option name.
2703 ParamsInfo (dict): Parameter name and value pairs.
2704 RBFESettings (dict): OpenFE RelativeHybridTopologyProtocol settings object.
2705
2706 Returns:
2707 None
2708
2709 """
2710
2711 RFEParametersMap = _SetupMapForRelativeFreeEnergyParameters()
2712
2713 for ParamName in ParamsInfo.keys():
2714 if ParamName in RFEParametersMap:
2715 RFEParamGroupName, RFEParamName = RFEParametersMap[ParamName]
2716 if RFEParamGroupName is None:
2717 if hasattr(RBFESettings, RFEParamName):
2718 setattr(RBFESettings, RFEParamName, ParamsInfo[ParamName])
2719 else:
2720 MiscUtil.PrintInfo(
2721 'The charge correction RFE parameter name, %s, specified using option "%s" is not valud. Ignoring parameter...'
2722 % (ParamName, ParamsOptionName)
2723 )
2724 else:
2725 RFEParamGroupSettings = (
2726 getattr(RBFESettings, RFEParamGroupName) if hasattr(RBFESettings, RFEParamGroupName) else None
2727 )
2728 if RFEParamGroupSettings is not None and hasattr(RFEParamGroupSettings, RFEParamName):
2729 setattr(RFEParamGroupSettings, RFEParamName, ParamsInfo[ParamName])
2730 else:
2731 MiscUtil.PrintInfo(
2732 'The charge correction RFE parameter name, %s, specified using option "%s" is not valud. Ignoring parameter...'
2733 % (ParamName, ParamsOptionName)
2734 )
2735 else:
2736 MiscUtil.PrintInfo(
2737 'The charge correction RFE parameter name, %s, specified using option "%s" is not valud. Ignoring parameter...'
2738 % (ParamName, ParamsOptionName)
2739 )
2740
2741
2742 def UpdateRelativeFreeEnergySettingsForVacuum(ParamsOptionName, ParamsInfo, RBFESettings):
2743 """Update relative free energy protocol settings for vacuum.
2744
2745 The ParamsInfo is a comma delimited list of parameter name and value pairs
2746 returned by ProcessOptionOpenFERelativeFreeEnergyVacuumParameters().
2747
2748 Arguments:
2749 ParamsOptionName (str): Command line OpenFE RBFE vacuum parameters
2750 option name.
2751 ParamsInfo (dict): Parameter name and value pairs.
2752 RBFESettings (dict): OpenFE RelativeHybridTopologyProtocol settings object.
2753
2754 Returns:
2755 None
2756
2757 """
2758
2759 RFEParametersMap = _SetupMapForRelativeFreeEnergyParameters()
2760
2761 for ParamName in ParamsInfo.keys():
2762 if ParamName in RFEParametersMap:
2763 RFEParamGroupName, RFEParamName = RFEParametersMap[ParamName]
2764 if RFEParamGroupName is None:
2765 if hasattr(RBFESettings, RFEParamName):
2766 setattr(RBFESettings, RFEParamName, ParamsInfo[ParamName])
2767 else:
2768 MiscUtil.PrintInfo(
2769 'The vacuum RFE parameter name, %s, specified using option "%s" is not valud. Ignoring parameter...'
2770 % (ParamName, ParamsOptionName)
2771 )
2772 else:
2773 RFEParamGroupSettings = (
2774 getattr(RBFESettings, RFEParamGroupName) if hasattr(RBFESettings, RFEParamGroupName) else None
2775 )
2776 if RFEParamGroupSettings is not None and hasattr(RFEParamGroupSettings, RFEParamName):
2777 setattr(RFEParamGroupSettings, RFEParamName, ParamsInfo[ParamName])
2778 else:
2779 MiscUtil.PrintInfo(
2780 'The vacuum RFE parameter name, %s, specified using option "%s" is not valud. Ignoring parameter...'
2781 % (ParamName, ParamsOptionName)
2782 )
2783 else:
2784 MiscUtil.PrintInfo(
2785 'The vacuum RFE parameter name, %s, specified using option "%s" is not valud. Ignoring parameter...'
2786 % (ParamName, ParamsOptionName)
2787 )
2788
2789
2790 def ProcessOptionOpenFERelativeFreeEnergySeparatedTopologyParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
2791 """Process parameters for RBFE parameters option and return a map
2792 containing processed parameter names and values.
2793
2794 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
2795 to setup RBFE calculations using a separated topologies approach.
2796
2797 The default values are automatically updated to match settings provided by
2798 OpenFE module SepTopProtocol.
2799
2800 You must specify valid OpenFE values for these parameters. An extensive
2801 validation is not performed.
2802
2803 The supported parameter names along with their default and possible
2804 values are shown below:
2805
2806 protocolRepeats, 3
2807
2808 Complex equil output settings:
2809
2810 complexEquilOutputCheckpointInterval, 1 [ Units: nanosecond ]
2811 complexEquilOutputCheckpointStorageFilename, checkpoint.chk
2812 complexEquilOutputEquilNPTStructure, equil_npt.pdb
2813 complexEquilOutputEquilNVTstructure, None
2814 complexEquilOutputForcefieldCache, db.json
2815 complexEquilOutputLogOutput, equil_simulation.log
2816 complexEquilOutputMinimizedStructure, minimized.pdb
2817 complexEquilOutputIndices, all [ Possible value: Any valid
2818 selection. ]
2819 complexEquilOutputPreminimizedStructure, system.pdb
2820 complexEquilOutputProductionTrajectoryFilename, production_equil.xtc
2821 complexEquilOutputTrajectoryWriteInterval, 20.0 [ Units:
2822 picosecond ]
2823
2824 Complex equil simulation settings:
2825
2826 complexEquilSimulationEquilibrationLength, 0.1 [ Units: nanosecond ]
2827 complexEquilSimulationEquilibrationLengthNVT, 0.1 [ Units:
2828 nanosecond ]
2829 complexEquilSimulationMinimizationSteps, 5000
2830 complexEquilSimulationProductionLength, 2.0 [ Units: nanosecond ]
2831
2832 Complex lambda settings:
2833
2834 complexLambdaElecA, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.25 0.5 0.75
2835 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 [ Possible values: A space
2836 delimited list of values between 0.0 and 1.0 ]
2837 complexLambdaElecB, 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.75 0.5 0.25
2838 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 [ Possible values: A space
2839 delimited list of values between 0.0 and 1.0 ]
2840 complexLambdaRestraintsA, 0.0 0.05 0.1 0.3 0.5 0.75 1.0 1.0 1.0
2841 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 [ Possible values: A
2842 space delimited list of values between 0.0 and 1.0 ]
2843 complexLambdaRestraintsB, 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
2844 1.0 1.0 1.0 0.75 0.5 0.3 0.1 0.05 0.0 [ Possible values: A space
2845 delimited list of values between 0.0 and 1.0 ]
2846 complexLambdaVdwA, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2847 0.143 0.286 0.429 0.572 0.715 0.857 1.0 [ Possible values: A
2848 delimited list of values between 0.0 and 1.0 ]
2849 complexLambdaVdwB, 1.0 0.857 0.715 0.572 0.429 0.286 0.143 0.0
2850 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 [ Possible values: A
2851 delimited list of values between 0.0 and 1.0 ]
2852
2853 Complex output settings:
2854
2855 complexOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
2856 complexOutputCheckpointStorageFilename, complex_checkpoint.nc
2857 complexOutputForcefieldCache, db.json
2858 complexOutputFilename, complex.nc
2859 complexOutputIndices, not water [ Possible value: Any valid
2860 selection. ]
2861 complexOutputStructure, alchemical_system.pdb
2862 complexOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
2863 complexOutputVelocitiesWriteFrequency, None [ Possible
2864 values: > 0; Units: picosecond ]
2865
2866 Complex restraint settings:
2867
2868 complexRestraintKPhiA, 334.72 [ Units: kilojoule_per_mole/radian**2
2869 The default value is equivalent to 80 kcal/mol/radian**2 ]
2870 complexRestraintKPhiB, 334.72 [ Units: kilojoule_per_mole/radian**2
2871 The default value is equivalent to 80 kcal/mol/radian**2 ]
2872 complexRestraintKPhiC, 334.72 [ Units: kilojoule_per_mole/radian**2
2873 The default value is equivalent to 80 kcal/mol/radian**2 ]
2874 complexRestraintKR, 4184.0 [ Units: kilojoule_per_mole/nanometer**2
2875 The default value is equivalent to 10 kcal/mol/angstrom**2
2876 complexRestraintKThetaA, 334.72 [ Units:kilojoule_per_mole/radian**2
2877 The default value is equivalent to 80 kcal/mol/radian**2 ]
2878 complexRestraintKThetaB, 334.72 [ Units:kilojoule_per_mole/radian**2
2879 The default value is equivalent to 80 kcal/mol/radian**2 ]
2880 complexRestraintAnchorFindingStrategy, bonded [ Possible values:
2881 multi-residue or bonded ]
2882 complexRestraintDsspFilter, yes [ Possible values: yes or no ]
2883 complexRestraintHostMaxDistance, 1.5 [ Units: nanometer ]
2884 complexRestraintHostMinDistance, 0.5 [ Units: nanometer ]
2885 complexRestraintHostSelection, backbone [ Possible value: Any valid
2886 selection. ]
2887 complexRestraintRmsfCutoff, 0.1 [ Units: nanometer ]
2888
2889 Complex simulation settings:
2890
2891 complexSimulationEarlyTerminationTargetError, 0.0 [ Units:
2892 kilocalorie_per_mole ]
2893 complexSimulationEquilibrationLength, 1.0 [ Units: nanosecond ]
2894 complexSimulationMinimizationSteps, 5000
2895 complexSimulationNReplicas, 19
2896 complexSimulationProductionLength, 10.0 [ Units: nanosecond ]
2897 complexSimulationRealTimeAnalysisInterval, 250.0 [ Units:
2898 picosecond ]
2899 complexSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units:
2900 picosecond ]
2901 complexSimulationSamplerMethod, repex [ Possible values: repex,
2902 sams, or independent ]
2903 complexSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
2904 values: logZ-flatness, minimum-visits or histogram-flatness ]
2905 complexSimulationSamsGamma0, 1.0
2906 complexSimulationTimePerIteration, 2.5 [ Units: picosecond ]
2907
2908 Complex solvation settings:
2909
2910 complexSolvationBoxShape, dodecahedron [ Possible values: cube,
2911 dodecahedron, or octahedron ]
2912 complexSolvationBoxSize, None [ Possible value: A triplet of space
2913 X Y Z values; Units: nanometer ]
2914 complexSolvationSolventModel, tip3p [ Possible values: tip3p, spce,
2915 tip4pew, or tip5p ]
2916 complexSolvationSolventPadding, 1.0 [ Units: nanometer ]
2917
2918 Engine settings:
2919
2920 engineComputePlatform, CPU [ Possible values: CPU, CUDA,
2921 OpenCL, or Reference ]
2922 engineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
2923
2924 Forcefield settings:
2925
2926 forcefieldConstraints, HBonds [ Possible values: HBonds,
2927 AllBonds, or HAngles ]
2928 forcefields, amber/ff14SB.xml amber/tip3p_standard.xml
2929 amber/tip3p_HFE_multivalent.xml amber/phosaa10.xml
2930 [ Possible values: A space delimited list of valid names. ]
2931 forcefieldHydrogenMass, 3.0 [ Units: amu ]
2932 forcefieldNonbondedCutoff, 0.9 [ Units: nanometer ]
2933 forcefieldNonbondedMethod, PME [ Possible values: PME or
2934 NoCutoff ]
2935 forcefieldRigidWater, yes [ Possible values: yes or no ]
2936 forcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible
2937 value: A valid forcefield name. ]
2938
2939 Integrator settings:
2940
2941 integratorBarostatFrequency, 25.0 * timestep [ The specified value
2942 is a multiple of integratorTimestep. ]
2943 integratorConstraintTolerance, 1e-06
2944 integratorLangevinCollisionRate, 1.0 [ Units: 1 / picosecond ]
2945 integratorNRestartAttempts, 20
2946 integratorReassignVelocities, no [ Possible values: yes or no ]
2947 integratorRemoveCom, no [ Possible values: yes or no ]
2948 integratorTimestep, 4.0 [ Units: femtosecond ]
2949
2950 Partial charge settings:
2951
2952 partialChargeNaglModel, None [ Default: Production AM1BCC model for
2953 NAGL; Possible value: Any valid name. ]
2954 partialChargeNumberOfConformers, None [ Possible value: > 0 ]
2955 partialChargeOffToolkitBackend, AmberTools [ Possible values:
2956 AmberTools or RDKit ]
2957 partialChargeMethod, AM1BCC [ Possble values: AM1BCC, Espaloma,
2958 or NAGL ]
2959
2960 Solvent equil output settings:
2961
2962 solventEquilOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
2963 solventEquilOutputCheckpointStorageFilename, checkpoint.chk
2964 solventEquilOutputEquilNPTStructure, equil_npt.pdb
2965 solventEquilOutputEquilNVTstructure, None
2966 solventEquilOutputForcefieldCache, db.json
2967 solventEquilOutputLogOutput, equil_simulation.log
2968 solventEquilOutputMinimizedStructure, minimized.pdb
2969 solventEquilOutputIndices, all [ Possible value: Any valid
2970 selection. ]
2971 solventEquilOutputPreminimizedStructure, system.pdb
2972 solventEquilOutputProductionTrajectoryFilename, equil_npt.xtc
2973 solventEquilOutputTrajectoryWriteInterval, 20.0 [ Units:
2974 picosecond ]
2975
2976 Solvent_equil_simulation_settings:
2977
2978 solventEquilSimulationEquilibrationLength, 0.1 [ Units: nanosecond ]
2979 solventEquilSimulationEquilibrationLengthNVT, 0.1 [ Units:
2980 nanosecond ]
2981 solventEquilSimulationMinimizationSteps, 5000
2982 solventEquilSimulationProductionLength, 2.0 [ Units: nanosecond ]
2983
2984 Solvent lambda settings:
2985
2986 solventLambdaElecA, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.125
2987 0.25 0.375 0.5 0.625 0.75 0.875 1.0 1.0 1.0 1.0 1.0 1.0 1.0
2988 1.0 1.0 1.0 [ Possible values: A space delimited list of values
2989 between 0.0 and 1.0 ]
2990 solventLambdaElecB, 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.875
2991 0.75 0.625 0.5 0.375 0.25 0.125 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2992 0.0 0.0 0.0 [ Possible values: A space delimited list of values
2993 between 0.0 and 1.0 ]
2994 solventLambdaRestraintsA, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2995 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2996 0.0 [ Possible values: A space delimited list of values between
2997 0.0 and 1.0 ]
2998 solventLambdaRestraintsB, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2999 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3000 0.0 [ Possible values: A space delimited list of values between
3001 0.0 and 1.0 ]
3002 solventLambdaVdwA, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3003 0.0 0.0 0.0 0.0 0.0 0.0 0.15 0.23 0.3 0.4 0.52 0.64 0.76 0.88
3004 1.0 [ Possible values: A space delimited list of values between
3005 0.0 and 1.0 ]
3006 solventLambdaVdwB, 1.0 0.85 0.77 0.7 0.6 0.48 0.36 0.24 0.12 0.0
3007 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3008 0.0 [ Possible values: A space delimited list of values between
3009 0.0 and 1.0 ]
3010
3011 Solvent output settings:
3012
3013 solventOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
3014 solventOutputCheckpointStorageFilename, solvent_checkpoint.nc
3015 solventOutputForcefieldCache, db.json
3016 solventOutputFilename, solvent.nc
3017 solventOutputIndices, not water [ Possible value: Any valid
3018 selection. ]
3019 solventOutputStructure, alchemical_system.pdb
3020 solventOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
3021 solventOutputVelocitiesWriteFrequency, None [ Possible
3022 values: > 0; Units: picosecond ]
3023
3024 Solvent restraint settings:
3025
3026 solventRestraintCentralAtomsOnly, No [ Possible values: yes or no ]
3027 solventRestraintSpringConstant, 1000.0 [ Units: kilojoule_per_mole /
3028 nanometer ** 2. The default value is equivalent to 2.40
3029 kilocalorie_per_mole / angstromg ** 2 ]
3030
3031 Solvent simulation settings:
3032
3033 solventSimulationEarlyTerminationTargetError, 0.0 [ Units:
3034 kilocalorie_per_mole ]
3035 solventSimulationEquilibrationLength, 1.0 [ Units: nanosecond ]
3036 solventSimulationMinimizationSteps, 5000
3037 solventSimulationNReplicas, 27
3038 solventSimulationProductionLength, 10.0 [ Units: nanosecond ]
3039 solventSimulationRealTimeAnalysisInterval, 250.0 [ Unit: picosecond ]
3040 solventSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units:
3041 picosecond ]
3042 solventSimulationSamplerMethod, repex [ Possible values: repex,
3043 sams, or independent ]
3044 solventSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
3045 values: logZ-flatness, minimum-visits or histogram-flatness ]
3046 solventSimulationSamsGamma0, 1.0
3047 solventSimulationTimePerIteration, 2.5 [ Units: picosecond ]
3048
3049 Solvent solvation settings:
3050
3051 solventSolvationBoxShape, dodecahedron [ Possible values: cube,
3052 dodecahedron, or octahedron ]
3053 solventSolvationBoxSize, None [ Possible value: A triplet of space
3054 X Y Z values; Units: nanometer ]
3055 solventSolvationSolventModel, tip3p [ Possible values: tip3p, spce,
3056 tip4pew, or tip5p ]
3057 solventSolvationSolventPadding, 1.5 [ Units: nanometer ]
3058
3059 Thermo settings:
3060
3061 thermoPh, None [ Possible values: > 0 ]
3062 thermoPressure, 1.0 [ Units: bar ]
3063 thermoRedoxPotential, None [ Possible values: A valid float.
3064 Units: millivolts (mV) ]
3065 thermoTemperature, 298.15 [ Units: kelvin ]
3066
3067 A brief description of parameters, taken from OpenFE documentation, is
3068 provided below:
3069
3070 protocolRepeats: Number of completely independent repeats of the
3071 entire sampling process.
3072
3073 Complex settings:
3074
3075 Complex parameters for the system, including the solvent model and
3076 the solvent padding.
3077
3078 Complex equil output settings:
3079
3080 Parameters controlling simulation output during equilibration
3081 phase of complex transformation.
3082
3083 complexEquilOutputCheckpointInterval: Frequency to write the
3084 checkpoint file.
3085 complexEquilOutputCheckpointStorageFilename: Checkpoint filename.
3086 complexEquilOutputEquilNPTStructure: NPT structure filename.
3087 complexEquilOutputEquilNVTstructure: NVT strucure filename.
3088 complexEquilOutputForcefieldCache: Filename for caching small
3089 molecule residue templates.
3090 complexEquilOutputLogOutput: Simulation log filename.
3091 complexEquilOutputMinimizedStructure: Minimized structure filename.
3092 complexEquilOutputIndices: Selection string for selecting
3093 coordinates to write.
3094 complexEquilOutputPremnimizedStructure: Initial structure filename.
3095 complexEquilOutputProductionTrajectoryFilename: Trajectory filename.
3096 complexEquilOutputTrajectoryWriteInterval: Frequency for writing
3097 velocities to trajectory file.
3098
3099 Complex equil simulation settings:
3100
3101 Parameters controlling simulation during equilibration phase of
3102 complex transformation.
3103
3104 complexEquilSimulationEquilibrationLength: Length of the NPT
3105 equilibration phase.
3106 complexEquilSimulationEquilibrationLengthNVT: Length of the NVT
3107 equilibration phase.
3108 complexEquilSimulationMinimizationSteps: Maximum number of
3109 minimization steps to perform.
3110 complexEquilSimulationProductionLength: Length of the NPT
3111 production phase.
3112
3113 Complex lambda settings:
3114
3115 Lambda protocol parameters for complex transformation.
3116
3117 complexLambdaElecA: List of lambda values for electrostatics. The
3118 values of 0 and 1 imply state A and state B respectively.
3119 complexLambdaElecB: List of lambda values for electrostatics. The
3120 values of 0 and 1 imply state A and state B respectively.
3121 complexLambdaRestraintsA: List of lambda values for restraints. The
3122 values of 0 and 1 imply state A and state B respectively.
3123 complexLambdaRestraintsB: List of lambda values for restraints. The
3124 values of 0 and 1 imply state A and state B respectively.
3125 complexLambdaVdwA: List of lamda values for van der Waals. The
3126 values of of 0 and 1 imply state A and state B respectively.
3127 complexLambdaVdwB: List of lamda values for van der Waals. The
3128 values of of 0 and 1 imply state A and state B respectively.
3129
3130 Complex output settings:
3131
3132 Parameters controlling simulation output during final phase of
3133 complex transformation.
3134
3135 complexOutputCheckpointInterval: Frequency to write the checkpoint
3136 file.
3137 complexOutputCheckpointStorageFilename: Checkpoint filename.
3138 complexOutputForcefieldCache: Filename for caching small molecule
3139 residue templates.
3140 complexOutputFilename: Trajectory filename.
3141 complexOutputIndices: Selection string for selecting coordinates to
3142 write.
3143 complexOutputStructure: Topology structure filename.
3144 complexOutputPositionsWriteFrequency: Frequency for writing
3145 positions to trajectory file.
3146 complexOutputVelocitiesWriteFrequency: Frequency for writing
3147 velocities to trajectory file.
3148
3149 Complex restraint settings:
3150
3151 Parameters to configure Boresch-style restraint between two groups
3152 of atoms named host (Hx) and guest (Gx).
3153
3154 complexRestraintKPhiA: Equilibrium force constant for the dihedral
3155 formed by H2-H1-H0-G0.
3156 complexRestraintKPhiB: Equilibrium force constant for the dihedral
3157 formed by H1-H0-G0-G1.
3158 complexRestraintKPhiC: Equilibrium force constant for the dihedral
3159 formed by H0-G0-G1-G2.
3160 complexRestraintKR: Bond spring constant between H0 and G0.
3161 restraintKThetaA: Spring constant for the angle formed by H1-H0-G0.
3162 complexRestraintKThetaA: Spring constant for the angle formed by
3163 H1-H0-G0.
3164 complexRestraintKThetaB: Spring constant for the angle formed by
3165 H0-G0-G1.
3166 complexRestraintAnchorFindingStrategy: Boresch atom picking strategy
3167 to use. bonded: pick host atoms that are bonded to each other.
3168 multi-residue: pick host atoms which can span multiple residues.
3169 complexRestraintDsspFilter: Apply DSSP filter to the host atoms.
3170 complexRestraintHostMaxDistance: Maximum distance between any
3171 host atom and the guest G0 atom.
3172 complexRestraintHostMinDistance: Minimum distance between any
3173 host atom and the guest G0 atom
3174 complexRestraintHostSelection: A valid selection string to
3175 sub-select the host atoms which will be involved in the
3176 restraint.
3177 complexRestraintRmsfCutoff: Cutoff value for filtering atoms by their
3178 root mean square fluctuation. Atoms with values above this
3179 cutoff are ignored.
3180
3181 Complex simulation settings:
3182
3183 Parameters controlling simulation during final phase of complex
3184 transformation.
3185
3186 complexSimulationEarlyTerminationTargetError: Target error for the
3187 real time analysis measured in kcal/mol. Once the MBAR error of
3188 the free energy is at or below this value, the simulation will
3189 be considered complete. The suggested value of 0.12 has shown to
3190 be effective in both hydration and binding free energy
3191 benchmarks.
3192 complexSimulationEquilibrationLength: Length of the equilibration
3193 phase. The specified value must be divisible by
3194 'integratorTimestep'.
3195 complexSimulationMinimizationSteps: Maximum number of minimization
3196 steps to perform.
3197 complexSimulationNReplicas: Number of replicas to use.
3198 complexSimulationProductionLength: Length of the production phase.
3199 The specified value must be divisible by 'integratorTimestep'.
3200 complexSimulationRealTimeAnalysisMinimumTime: Time interval for
3201 performing analysis of the free energies. At each interval, real
3202 time analysis data will be written to a yaml file named
3203 <outputFileName>_real_time_analysis.yaml. The current error
3204 in the estimate will also be assessed and the simulation will
3205 be terminated when it drops below
3206 'complexSimulationEarlyTerminationTargetError'.
3207 complexSimulationSamplerMethod: Alchemical sampling method to use:
3208 REPEX (Hamiltonian REPlica EXchange), SAMS (Self-Adjusted
3209 Mixture Sampling), or Independent (Independently sampled lambda
3210 windows).
3211 complexSimulationSamsFlatnessCriteria:Method for assessing when to
3212 switch to asymptomatically optimal scheme for SAMS.
3213 complexSimulationsamsGamma0: Initial weight adaptation rate for
3214 SAMS.
3215 complexSimulationTimePerIteration: Simulation time between each
3216 MCMC move attempt
3217
3218 Complex solvation settings:
3219
3220 Solvation parameters for the system, including the solvent model and
3221 the solvent padding.
3222
3223 complexSolvationBoxShape: Shape of the periodic solvent box.
3224 complexSolvationBoxSize: Lengths of the unit cell for a solvent box.
3225 complexSolvationSolventModel: Forcefield water model to use during
3226 solvation and defining the model properties.
3227 complexSolvationSolventPadding: Minimum distance from any solute
3228 bounding sphere to the edge of the box.
3229
3230 Engine settings:
3231
3232 Parameters configuring the compute platform used by the OpenMM to
3233 perform the simulation.
3234
3235 engineComputePlatform: Platform to use for running OpenMM MD
3236 calculations.
3237 engineGpuDeviceIndex: Space delimited list of device indices
3238 to use for running OpenMM MD calculations.
3239
3240 Forcefield settings:
3241
3242 forcefieldConstraints:Constraints to use.
3243 forcefields: List of valid forcefield paths for all components
3244 except small molecules.
3245 forcefieldHydrogenMass: Mass to be repartitioned to hydrogens
3246 from neighboring heavy atoms.
3247 forcefieldNonbondedCutoff: Cutoff for short range nonbonded
3248 interactions.
3249 forcefieldNonbondedMethod: Method for treating nonbonded
3250 interactions.
3251 forcefieldRigidWater: Use a rigid water model.
3252 forcefieldSmallMoleculeForcefield: A valid forcefield name to use
3253 for small molecules.
3254
3255 Integrator settings:
3256
3257 Parameters controlling the LangevinSplittingDynamicsMove integrator
3258 used for simulation.
3259
3260 integratorBarostatFrequency: Frequency at which volume scaling
3261 changes should be attempted.
3262 integratorConstraintTolerance: Tolerance for constraint solver.
3263 integratorLangevinCollisionRate: Collision frequency.
3264 integratorNRestartAttempts: Number of attempts to restart from
3265 Context in case there are NaNs in the energies after
3266 integration.
3267 integratorReassignVelocities: Reassign velocities from the
3268 Maxwell-Boltzmann distribution at the beginning of each
3269 Monte Carlo move.
3270 integratorRemoveCom: Remove the center of mass motion.
3271 integratorTimestep: Size of the simulation timestep.
3272
3273 Partial charge settings:
3274
3275 Parameters for automatically assigning missing partial charges to
3276 small molecules, including the partial charge method.
3277
3278 partialChargeNaglModel: Model to use for partial charge assignment.
3279 A value of None implies the use of the latest available
3280 production AM1BCC model.
3281 partialChargeNumberOfConformers: Number of conformers to generate
3282 as part of the partial charge assignment. A value of None
3283 implies the use of the existing conformer.
3284 partialChargeOffToolkitBackend: OpenFF toolkit registry backend to
3285 use for calculating partial charges.
3286 partialChargeMethod: Method to use for calculating partial charges.
3287
3288 Solvent equil output settings:
3289 Solvent equil simulation settings:
3290 Solvent lambda settings:
3291 Solvent output settings:
3292 Solvent restraint settings:
3293 Solvent simulation settings:
3294 Solvent solvation settings:
3295
3296 The solvent settings are similar to the complex settings already
3297 described under various sections for complex. The prefix 'solvent'
3298 is used for the names of the pramaters instead of the prefix
3299 'complex.'
3300
3301 Thermo settings:
3302
3303 Thermodynamic parameters, including the temperature and the pressure
3304 of the system.
3305
3306 thermoPh: Simulation pH
3307 thermoPressure: Simulation pressure.
3308 thermoRedoxPotential:Simulation redox potential.
3309 thermoTemperature: Simulation temperature.
3310
3311 Arguments:
3312 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
3313 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
3314 ParamsDefaultInfo (dict): Default values to override selected parameters.
3315
3316 Returns:
3317 dictionary: Processed parameter name and value pairs.
3318
3319 """
3320
3321 ParamsInfo = _SetupRelativeBindingFreeEnergySeparatedTopologyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue)
3322
3323 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
3324 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
3325 )
3326
3327 if re.match("^auto$", ParamsOptionValue, re.I):
3328 _ProcessOptionOpenFERelativeBindingFreeEnergySeparatedTopologyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
3329 return ParamsInfo
3330
3331 for Index in range(0, len(ParamsOptionValueWords), 2):
3332 Name = ParamsOptionValueWords[Index].strip()
3333 Value = ParamsOptionValueWords[Index + 1].strip()
3334
3335 ParamName = CanonicalParamNamesMap[Name.lower()]
3336 ParamValue = Value
3337
3338 if re.match(
3339 "^(ProtocolRepeats|IntegratorNRestartAttempts|ComplexEquilSimulationMinimizationSteps|ComplexSimulationMinimizationSteps|ComplexSimulationNReplicas|IntegratorNRestartAttempts|PartialChargeNumberOfConformers|SolventEquilSimulationMinimizationSteps|SolventSimulationMinimizationSteps|SolventSimulationNReplicas)$",
3340 ParamName,
3341 re.I,
3342 ):
3343 # Int > 0
3344 if not MiscUtil.IsInteger(Value):
3345 MiscUtil.PrintError(
3346 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
3347 % (Value, ParamName, ParamsOptionName)
3348 )
3349 Value = int(Value)
3350 if Value <= 0:
3351 MiscUtil.PrintError(
3352 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3353 % (ParamValue, ParamName, ParamsOptionName)
3354 )
3355 ParamValue = Value
3356 elif re.match(
3357 "^(IntegratorConstraintTolerance|ComplexSimulationSamsGamma0|ForcefieldHydrogenMass|SolventSimulationSamsGamma0)$",
3358 ParamName,
3359 re.I,
3360 ):
3361 # float > 0
3362 if not MiscUtil.IsFloat(Value):
3363 MiscUtil.PrintError(
3364 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3365 % (Value, ParamName, ParamsOptionName)
3366 )
3367 Value = float(Value)
3368 if Value <= 0:
3369 MiscUtil.PrintError(
3370 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3371 % (ParamValue, ParamName, ParamsOptionName)
3372 )
3373 ParamValue = Value
3374 elif re.match(
3375 "^(ForcefieldRigidWater|IntegratorReassignVelocities|IntegratorRemoveCom|ComplexRestraintDsspFilter|SolventRestraintCentralAtomsOnly)$",
3376 ParamName,
3377 re.I,
3378 ):
3379 # bool
3380 if not re.match("^(yes|no|true|false)$", Value, re.I):
3381 MiscUtil.PrintError(
3382 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
3383 % (Value, Name, ParamsOptionName)
3384 )
3385 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
3386 elif re.match("^ThermoPh$", ParamName, re.I):
3387 # float > 0 or None
3388 if re.match("^None$", Value, re.I):
3389 ParamValue = None
3390 else:
3391 if not MiscUtil.IsFloat(Value):
3392 MiscUtil.PrintError(
3393 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3394 % (Value, ParamName, ParamsOptionName)
3395 )
3396 Value = float(Value)
3397 if Value <= 0:
3398 MiscUtil.PrintError(
3399 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3400 % (ParamValue, ParamName, ParamsOptionName)
3401 )
3402 ParamValue = Value
3403 elif re.match("^ThermoRedoxPotential$", ParamName, re.I):
3404 if re.match("^None$", Value, re.I):
3405 ParamValue = None
3406 else:
3407 if not MiscUtil.IsFloat(Value):
3408 MiscUtil.PrintError(
3409 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3410 % (Value, ParamName, ParamsOptionName)
3411 )
3412 Value = float(Value)
3413 ParamValue = Value * openff.units.unit.millivolts
3414 elif re.match("^IntegratorLangevinCollisionRate$", ParamName, re.I):
3415 if not MiscUtil.IsFloat(Value):
3416 MiscUtil.PrintError(
3417 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3418 % (Value, ParamName, ParamsOptionName)
3419 )
3420 Value = float(Value)
3421 if Value <= 0:
3422 MiscUtil.PrintError(
3423 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3424 % (ParamValue, ParamName, ParamsOptionName)
3425 )
3426 ParamValue = Value / openff.units.unit.picosecond
3427 elif re.match(
3428 "^(ComplexLambdaElecA|ComplexLambdaElecB|ComplexLambdaRestraintsA|ComplexLambdaRestraintsB|ComplexLambdaVdwA|ComplexLambdaVdwB|SolventLambdaElecA|SolventLambdaElecB|SolventLambdaRestraintsA|SolventLambdaRestraintsB|SolventLambdaVdwA|SolventLambdaVdwB)$",
3429 ParamName,
3430 re.I,
3431 ):
3432 # List of float values between 0 and 1...
3433 Values = Value.split()
3434 if len(Values) == 0:
3435 MiscUtil.PrintError(
3436 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of space delimited values\n'
3437 % (Value, ParamName, ParamsOptionName)
3438 )
3439 for Value in Values:
3440 if not MiscUtil.IsFloat(Value):
3441 MiscUtil.PrintError(
3442 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3443 % (Value, ParamName, ParamsOptionName)
3444 )
3445 Value = float(Value)
3446 if Value < 0.0 or Value > 1.0:
3447 MiscUtil.PrintError(
3448 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not valid value. Supported values: 0.0 to 1.0\n'
3449 % (Value, ParamName, ParamsOptionName)
3450 )
3451 Values = [float(Value) for Value in Values]
3452 ParamValue = Values
3453 elif re.match("^IntegratorBarostatFrequency$", ParamName, re.I):
3454 if not MiscUtil.IsFloat(Value):
3455 MiscUtil.PrintError(
3456 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3457 % (Value, ParamName, ParamsOptionName)
3458 )
3459 Value = float(Value)
3460 if Value <= 0:
3461 MiscUtil.PrintError(
3462 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3463 % (ParamValue, ParamName, ParamsOptionName)
3464 )
3465 ParamValue = Value * openff.units.unit.timestep
3466 elif re.match("^IntegratorLangevinCollisionRate$", ParamName, re.I):
3467 if not MiscUtil.IsFloat(Value):
3468 MiscUtil.PrintError(
3469 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3470 % (Value, ParamName, ParamsOptionName)
3471 )
3472 Value = float(Value)
3473 if Value <= 0:
3474 MiscUtil.PrintError(
3475 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3476 % (ParamValue, ParamName, ParamsOptionName)
3477 )
3478 ParamValue = Value / openff.units.unit.picosecond
3479 elif re.match("^IntegratorTimestep$", ParamName, re.I):
3480 # float > 0 femtosecond
3481 if not MiscUtil.IsFloat(Value):
3482 MiscUtil.PrintError(
3483 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3484 % (Value, ParamName, ParamsOptionName)
3485 )
3486 Value = float(Value)
3487 if Value <= 0:
3488 MiscUtil.PrintError(
3489 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3490 % (ParamValue, ParamName, ParamsOptionName)
3491 )
3492 ParamValue = Value * openff.units.unit.femtosecond
3493 elif re.match(
3494 "^(ComplexEquilOutputTrajectoryWriteInterval|ComplexOutputPositionsWriteFrequency|ComplexSimulationRealTimeAnalysisInterval|ComplexSimulationRealTimeAnalysisMinimumTime|ComplexSimulationTimePerIteration|SolventEquilOutputTrajectoryWriteInterval|SolventOutputPositionsWriteFrequency|SolventSimulationRealTimeAnalysisInterval|SolventSimulationRealTimeAnalysisMinimumTime|SolventSimulationTimePerIteration)$",
3495 ParamName,
3496 re.I,
3497 ):
3498 # float > 0 picosecond
3499 if not MiscUtil.IsFloat(Value):
3500 MiscUtil.PrintError(
3501 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3502 % (Value, ParamName, ParamsOptionName)
3503 )
3504 Value = float(Value)
3505 if Value <= 0:
3506 MiscUtil.PrintError(
3507 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3508 % (ParamValue, ParamName, ParamsOptionName)
3509 )
3510 ParamValue = Value * openff.units.unit.picosecond
3511 elif re.match(
3512 "^(ComplexEquilOutputCheckpointInterval|ComplexEquilSimulationEquilibrationLength|ComplexEquilSimulationEquilibrationLengthNVT|ComplexEquilSimulationProductionLength|ComplexOutputCheckpointInterval|ComplexSimulationEquilibrationLength|ComplexSimulationProductionLength|SolventEquilOutputCheckpointInterval|SolventEquilSimulationEquilibrationLength|SolventEquilSimulationEquilibrationLengthNVT|SolventEquilSimulationProductionLength|SolventOutputCheckpointInterval|SolventSimulationEquilibrationLength|SolventSimulationProductionLength)$",
3513 ParamName,
3514 re.I,
3515 ):
3516 # float > 0 nanosecond
3517 if not MiscUtil.IsFloat(Value):
3518 MiscUtil.PrintError(
3519 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3520 % (Value, ParamName, ParamsOptionName)
3521 )
3522 Value = float(Value)
3523 if Value <= 0:
3524 MiscUtil.PrintError(
3525 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3526 % (ParamValue, ParamName, ParamsOptionName)
3527 )
3528 ParamValue = Value * openff.units.unit.nanosecond
3529 elif re.match(
3530 "^(ComplexOutputVelocitiesWriteFrequency|SolventOutputVelocitiesWriteFrequency)$", ParamName, re.I
3531 ):
3532 # float > 0 picosecond or none
3533 if re.match("^None$", Value, re.I):
3534 ParamValue = None
3535 else:
3536 if not MiscUtil.IsFloat(Value):
3537 MiscUtil.PrintError(
3538 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3539 % (Value, ParamName, ParamsOptionName)
3540 )
3541 Value = float(Value)
3542 if Value <= 0:
3543 MiscUtil.PrintError(
3544 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3545 % (ParamValue, ParamName, ParamsOptionName)
3546 )
3547 ParamValue = Value * openff.units.unit.picosecond
3548 elif re.match("^PartialChargeMethod$", ParamName, re.I):
3549 if not re.match("^(AM1BCC|AM1BCCELF10|Espaloma|NAGL)$", Value, re.I):
3550 MiscUtil.PrintError(
3551 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AM1BCC, AM1BCCELF10, Espaloma, or NAGL'
3552 % (Value, Name, ParamsOptionName)
3553 )
3554 ParamValue = Value.lower()
3555 elif re.match("^PartialChargeOffToolkitBackend$", ParamName, re.I):
3556 if not re.match("^(AmberTools|OpenEye|RDKit)$", Value, re.I):
3557 MiscUtil.PrintError(
3558 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AmberTools, OpenEye, or RDKit'
3559 % (Value, Name, ParamsOptionName)
3560 )
3561 ParamValue = Value.lower()
3562 elif re.match("^(ComplexSolvationBoxShape|SolventSolvationBoxShape)$", ParamName, re.I):
3563 if not re.match("^(cube|dodecahedron|octahedron)$", Value, re.I):
3564 MiscUtil.PrintError(
3565 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: cube, dodecahedron, or octahedron'
3566 % (Value, Name, ParamsOptionName)
3567 )
3568 ParamValue = Value.lower()
3569 elif re.match("^(ComplexSolvationBoxSize|SolventSolvationBoxSize)$", ParamName, re.I):
3570 # List of X, Y, Z values...
3571 if re.match("^None$", Value, re.I):
3572 ParamValue = None
3573 else:
3574 Values = Value.split()
3575 if len(Values) != 3:
3576 MiscUtil.PrintError(
3577 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of three space delimited values.\n'
3578 % (Value, ParamName, ParamsOptionName)
3579 )
3580 for Value in Values:
3581 if not MiscUtil.IsFloat(Value):
3582 MiscUtil.PrintError(
3583 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3584 % (Value, ParamName, ParamsOptionName)
3585 )
3586 Values = [float(Value) for Value in Values]
3587 ParamValue = Values * openff.units.unit.nanometer
3588 elif re.match("^(ComplexSolvationSolventModel|SolventSolvationSolventModel)$", ParamName, re.I):
3589 if not re.match("^(tip3p|spce|tip4pew|tip5p)$", Value, re.I):
3590 MiscUtil.PrintError(
3591 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: tip3p, spce, tip4pew, or tip5p'
3592 % (Value, Name, ParamsOptionName)
3593 )
3594 ParamValue = Value.lower()
3595 elif re.match("^EngineComputePlatform$", ParamName, re.I):
3596 if not re.match("^(CPU|CUDA|OpenCL|Reference)$", Value, re.I):
3597 MiscUtil.PrintError(
3598 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: CPU, CUDA, OpenCL, or Reference'
3599 % (Value, Name, ParamsOptionName)
3600 )
3601 ParamValue = Value
3602 elif re.match(
3603 "^(ForcefieldNonbondedCutoff|ComplexRestraintHostMaxDistance|ComplexRestraintHostMinDistance|ComplexRestraintRmsfCutoff)$",
3604 ParamName,
3605 re.I,
3606 ):
3607 # float > 0 and units nanometer
3608 if not MiscUtil.IsFloat(Value):
3609 MiscUtil.PrintError(
3610 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3611 % (Value, ParamName, ParamsOptionName)
3612 )
3613 Value = float(Value)
3614 if Value <= 0:
3615 MiscUtil.PrintError(
3616 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3617 % (ParamValue, ParamName, ParamsOptionName)
3618 )
3619 ParamValue = Value * openff.units.unit.nanometer
3620 elif re.match("^(ComplexSolvationSolventPadding|SolventSolvationSolventPadding)$", ParamName, re.I):
3621 # float > 0 and units nanometer or none
3622 if re.match("^None$", Value, re.I):
3623 ParamValue = None
3624 else:
3625 if not MiscUtil.IsFloat(Value):
3626 MiscUtil.PrintError(
3627 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3628 % (Value, ParamName, ParamsOptionName)
3629 )
3630 Value = float(Value)
3631 if Value <= 0:
3632 MiscUtil.PrintError(
3633 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3634 % (ParamValue, ParamName, ParamsOptionName)
3635 )
3636 ParamValue = Value * openff.units.unit.nanometer
3637 elif re.match("^EngineGpuDeviceIndex$", ParamName, re.I):
3638 # Comma delimited string values...
3639 DeviceIndices = Value.split()
3640 if len(DeviceIndices) == 0:
3641 MiscUtil.PrintError(
3642 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain space delimited list of device indices.\n'
3643 % (Value, ParamName, ParamsOptionName)
3644 )
3645 for DeviceIndex in DeviceIndices:
3646 if not MiscUtil.IsInteger(DeviceIndex):
3647 MiscUtil.PrintError(
3648 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
3649 % (DeviceIndex, ParamName, ParamsOptionName)
3650 )
3651 DeviceIndices = [int(DeviceIndex) for DeviceIndex in DeviceIndices]
3652 ParamValue = DeviceIndices
3653 elif re.match("^(ForcefieldConstraints)$", ParamName, re.I):
3654 if not re.match("^(HBonds|AllBonds|HAngles|None)$", Value, re.I):
3655 MiscUtil.PrintError(
3656 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: HBonds, AllBonds, HAngles, or None'
3657 % (Value, Name, ParamsOptionName)
3658 )
3659 ParamValue = None if re.match("^None$", Value, re.I) else Value.lower()
3660 elif re.match("^(Forcefields)$", ParamName, re.I):
3661 # List of string values.....
3662 Values = Value.split()
3663 if len(Values) == 0:
3664 MiscUtil.PrintError(
3665 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a space delimited list of values..\n'
3666 % (Value, ParamName, ParamsOptionName)
3667 )
3668 ParamValue = Values
3669 elif re.match("^(ForcefieldNonbondedMethod)$", ParamName, re.I):
3670 if not re.match("^(PME|NoCutoff)$", Value, re.I):
3671 MiscUtil.PrintError(
3672 'The parameter value, %s, specified for parameter name, %s, using "%s" option is may be a valid OpenFE value. Supported values: PME or NoCutoff'
3673 % (Value, Name, ParamsOptionName)
3674 )
3675 ParamValue = Value.lower()
3676 elif re.match(
3677 "^(ComplexSimulationEarlyTerminationTargetError|SolventSimulationEarlyTerminationTargetError)$",
3678 ParamName,
3679 re.I,
3680 ):
3681 # float >= 0 units: kilocalorie_per_mole
3682 if not MiscUtil.IsFloat(Value):
3683 MiscUtil.PrintError(
3684 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3685 % (Value, ParamName, ParamsOptionName)
3686 )
3687 Value = float(Value)
3688 if Value < 0:
3689 MiscUtil.PrintError(
3690 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3691 % (ParamValue, ParamName, ParamsOptionName)
3692 )
3693 ParamValue = Value * openff.units.unit.kilocalorie_per_mole
3694 elif re.match(
3695 "^(ComplexRestraintKPhiA|ComplexRestraintKPhiB|ComplexRestraintKPhiC|ComplexRestraintKThetaA|ComplexRestraintKThetaB)$", ParamName, re.I
3696 ):
3697 # float > 0 units: kilojoule_per_mole / radian ** 2
3698 if not MiscUtil.IsFloat(Value):
3699 MiscUtil.PrintError(
3700 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3701 % (Value, ParamName, ParamsOptionName)
3702 )
3703 Value = float(Value)
3704 if Value <= 0:
3705 MiscUtil.PrintError(
3706 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3707 % (ParamValue, ParamName, ParamsOptionName)
3708 )
3709 ParamValue = Value * openff.units.unit.kilojoule_per_mole / openff.units.unit.radian**2
3710 elif re.match("^(ComplexRestraintKR)$", ParamName, re.I):
3711 # float > 0 units: kilojoule_per_mole / nanometer ** 2
3712 if not MiscUtil.IsFloat(Value):
3713 MiscUtil.PrintError(
3714 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3715 % (Value, ParamName, ParamsOptionName)
3716 )
3717 Value = float(Value)
3718 if Value <= 0:
3719 MiscUtil.PrintError(
3720 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3721 % (ParamValue, ParamName, ParamsOptionName)
3722 )
3723 ParamValue = Value * openff.units.unit.kilojoule_per_mole / openff.units.unit.nanometer**2
3724 elif re.match("^ComplexRestraintAnchorFindingStrategy$", ParamName, re.I):
3725 if not re.match("^(multi-residue|bonded)$", Value, re.I):
3726 MiscUtil.PrintError(
3727 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: multi-residue or bonded'
3728 % (Value, Name, ParamsOptionName)
3729 )
3730 ParamValue = Value
3731 elif re.match("^(solventRestraintSpringConstant)$", ParamName, re.I):
3732 # float > 0 units: kilojoule_per_mole / nanometer ** 2
3733 if not MiscUtil.IsFloat(Value):
3734 MiscUtil.PrintError(
3735 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3736 % (Value, ParamName, ParamsOptionName)
3737 )
3738 Value = float(Value)
3739 if Value <= 0:
3740 MiscUtil.PrintError(
3741 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3742 % (ParamValue, ParamName, ParamsOptionName)
3743 )
3744 ParamValue = Value * openff.units.unit.kilojoule_per_mole / openff.units.unit.nanometer**2
3745 elif re.match("^(ComplexSimulationSamplerMethod|SolventSimulationSamplerMethod)$", ParamName, re.I):
3746 if not re.match("^(repex|sams|independent)$", Value, re.I):
3747 MiscUtil.PrintError(
3748 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: repex, sams, or independent'
3749 % (Value, Name, ParamsOptionName)
3750 )
3751 ParamValue = Value.lower()
3752 elif re.match(
3753 "^(ComplexSimulationSamsFlatnessCriteria|SolventSimulationSamsFlatnessCriteria)$", ParamName, re.I
3754 ):
3755 if not re.match("^(logz-flatness|minimum-visits|histogram-flatness)$", Value, re.I):
3756 MiscUtil.PrintError(
3757 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: logz-flatness, minimum-visits, or histogram-flatness'
3758 % (Value, Name, ParamsOptionName)
3759 )
3760 ParamValue = Value.lower()
3761 elif re.match("^ThermoPressure$", ParamName, re.I):
3762 # float > 0 and units standard_atmosphere
3763 if not MiscUtil.IsFloat(Value):
3764 MiscUtil.PrintError(
3765 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3766 % (Value, ParamName, ParamsOptionName)
3767 )
3768 Value = float(Value)
3769 if Value <= 0:
3770 MiscUtil.PrintError(
3771 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
3772 % (ParamValue, ParamName, ParamsOptionName)
3773 )
3774 ParamValue = Value * openff.units.unit.bar
3775 elif re.match("^ThermoTemperature$", ParamName, re.I):
3776 # float >= 0 and units kelvin
3777 if not MiscUtil.IsFloat(Value):
3778 MiscUtil.PrintError(
3779 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
3780 % (Value, ParamName, ParamsOptionName)
3781 )
3782 Value = float(Value)
3783 if Value < 0:
3784 MiscUtil.PrintError(
3785 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: >= 0\n'
3786 % (ParamValue, ParamName, ParamsOptionName)
3787 )
3788 ParamValue = Value * openff.units.unit.kelvin
3789 else:
3790 # Str or None...
3791 ParamValue = None if re.match("^None$", Value, re.I) else Value
3792
3793 # Set value...
3794 ParamsInfo[ParamName] = ParamValue
3795
3796 # Handle parameters with possible auto values...
3797 _ProcessOptionOpenFERelativeBindingFreeEnergySeparatedTopologyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
3798
3799 return ParamsInfo
3800
3801 def _ProcessOptionOpenFERelativeBindingFreeEnergySeparatedTopologyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
3802 """Process parameters with possible auto values and perform validation."""
3803
3804 for NamePrefix in ["Complex", "Solvent"]:
3805 ParamName1 = "%sSolvationBoxSize" % NamePrefix
3806 ParamValue1 = ParamsInfo[ParamName1]
3807 ParamName2 = "%sSolvationSolventPadding" % NamePrefix
3808 ParamValue2 = ParamsInfo[ParamName2]
3809 if ParamsInfo[ParamName1] is not None and ParamsInfo[ParamName2] is not None:
3810 MiscUtil.PrintError(
3811 'The parameter values, %s and %s, specified for parameter names, %s and %s, using "%s" option is not a valid value. You must specify only one of these values.\n'
3812 % (ParamValue1, ParamValue2, ParamName1, ParamName2, ParamsOptionName)
3813 )
3814
3815 for NamePrefix in ["Complex", "Solvent"]:
3816 ParamNames = []
3817 ParamValuesCount = []
3818 for ParamType in ["LambdaElecA", "LambdaElecB", "LambdaRestraintsA", "LambdaRestraintsA", "LambdaVdwA", "LambdaVdwB"]:
3819 ParamName = "%s%s" % (NamePrefix, ParamType)
3820 ParamValueCount = len(ParamsInfo[ParamName])
3821 ParamNames.append(ParamName)
3822 ParamValuesCount.append(ParamValueCount)
3823
3824 for Index in range(1, len(ParamNames)):
3825 if ParamValuesCount[Index] != ParamValuesCount[0]:
3826 ParamValuesCount = ["%s" % Value for Value in ParamValuesCount]
3827 MiscUtil.PrintError("The number of values - %s - specified for parameter names - %s - using \"%s\" option are not valid. You must specify same number of values for these parameters." % (",".join(ParamValuesCount), ",".join(ParamNames), ParamsOptionName))
3828
3829 _ProcessPartialChargeMethodRelativeBindingFreeEnergySeparatedTopologyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
3830 _ProcessPartialChargeNaglRelativeBindingFreeEnergySeparatedTopologyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
3831
3832 def _ProcessPartialChargeMethodRelativeBindingFreeEnergySeparatedTopologyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
3833 """Process PartialChargeMethod RBFE paramater."""
3834
3835 _ProcessPartialChargeMethodFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
3836
3837
3838 def _ProcessPartialChargeNaglRelativeBindingFreeEnergySeparatedTopologyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
3839 """Process PartialChargeNaglModel RBFE paramater."""
3840
3841 _ProcessPartialChargeNaglFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
3842
3843 def _SetupRelativeBindingFreeEnergySeparatedTopologyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue):
3844 """Setup RBFE default parameters information using the current RBFE settings."""
3845
3846 ParamsInfo = {}
3847
3848 from openfe.protocols.openmm_septop import SepTopProtocol
3849
3850 RBFESettings = SepTopProtocol.default_settings()
3851 RBFEParametersMap = _SetupMapForRelativeBindingFreeEnergySeparatedTopologyParameters()
3852
3853 for ParamName in RBFEParametersMap.keys():
3854 RBFEParamGroupName, RBFEParamName = RBFEParametersMap[ParamName]
3855 if RBFEParamGroupName is None:
3856 if hasattr(RBFESettings, RBFEParamName):
3857 ParamsInfo[ParamName] = getattr(RBFESettings, RBFEParamName)
3858 else:
3859 MiscUtil.PrintInfo(
3860 'The OpenFE RBFE settings name, %s, corresponding to RBFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
3861 % (RBFEParamName, ParamName, ParamsOptionName)
3862 )
3863 else:
3864 RBFEParamGroupSettings = (
3865 getattr(RBFESettings, RBFEParamGroupName) if hasattr(RBFESettings, RBFEParamGroupName) else None
3866 )
3867 if RBFEParamGroupSettings is not None and hasattr(RBFEParamGroupSettings, RBFEParamName):
3868 ParamsInfo[ParamName] = getattr(RBFEParamGroupSettings, RBFEParamName)
3869 else:
3870 MiscUtil.PrintInfo(
3871 'The OpenFE RBFE parameter name, %s, for settings, %s, corresponding to RBFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
3872 % (RBFEParamName, RBFEParamGroupName, ParamName, ParamsOptionName)
3873 )
3874
3875 return ParamsInfo
3876
3877
3878 def _SetupMapForRelativeBindingFreeEnergySeparatedTopologyParameters():
3879 """Map relative free energy option paramater names to OpenFE relative
3880 binding free energy separated topologies settings.
3881 """
3882
3883 RBFEParametersMap = {
3884 "ProtocolRepeats": [None, "protocol_repeats"],
3885
3886 "ComplexEquilOutputCheckpointInterval": ["complex_equil_output_settings", "checkpoint_interval"],
3887 "ComplexEquilOutputCheckpointStorageFilename": ["complex_equil_output_settings", "checkpoint_storage_filename"],
3888 "ComplexEquilOutputEquilNPTStructure": ["complex_equil_output_settings", "equil_npt_structure"],
3889 "ComplexEquilOutputEquilNVTstructure": ["complex_equil_output_settings", "equil_nvt_structure"],
3890 "ComplexEquilOutputForcefieldCache": ["complex_equil_output_settings", "forcefield_cache"],
3891 "ComplexEquilOutputLogOutput": ["complex_equil_output_settings", "log_output"],
3892 "ComplexEquilOutputMinimizedStructure": ["complex_equil_output_settings", "minimized_structure"],
3893 "ComplexEquilOutputIndices": ["complex_equil_output_settings", "output_indices"],
3894 "ComplexEquilOutputPreminimizedStructure": ["complex_equil_output_settings", "preminimized_structure"],
3895 "ComplexEquilOutputProductionTrajectoryFilename": ["complex_equil_output_settings", "production_trajectory_filename",],
3896 "ComplexEquilOutputTrajectoryWriteInterval": ["complex_equil_output_settings", "trajectory_write_interval"],
3897
3898 "ComplexEquilSimulationEquilibrationLength": ["complex_equil_simulation_settings", "equilibration_length"],
3899 "ComplexEquilSimulationEquilibrationLengthNVT": ["complex_equil_simulation_settings", "equilibration_length_nvt",
3900 ],
3901 "ComplexEquilSimulationMinimizationSteps": ["complex_equil_simulation_settings", "minimization_steps"],
3902 "ComplexEquilSimulationProductionLength": ["complex_equil_simulation_settings", "production_length"],
3903
3904 "ComplexLambdaElecA": ["complex_lambda_settings", "lambda_elec_A"],
3905 "ComplexLambdaElecB": ["complex_lambda_settings", "lambda_elec_B"],
3906 "ComplexLambdaRestraintsA": ["complex_lambda_settings", "lambda_restraints_A"],
3907 "ComplexLambdaRestraintsB": ["complex_lambda_settings", "lambda_restraints_B"],
3908 "ComplexLambdaVdwA": ["complex_lambda_settings", "lambda_vdw_A"],
3909 "ComplexLambdaVdwB": ["complex_lambda_settings", "lambda_vdw_B"],
3910
3911 "ComplexOutputCheckpointInterval": ["complex_output_settings", "checkpoint_interval"],
3912 "ComplexOutputCheckpointStorageFilename": ["complex_output_settings", "checkpoint_storage_filename"],
3913 "ComplexOutputForcefieldCache": ["complex_output_settings", "forcefield_cache"],
3914 "ComplexOutputFilename": ["complex_output_settings", "output_filename"],
3915 "ComplexOutputIndices": ["complex_output_settings", "output_indices"],
3916 "ComplexOutputStructure": ["complex_output_settings", "output_structure"],
3917 "ComplexOutputPositionsWriteFrequency": ["complex_output_settings", "positions_write_frequency"],
3918 "ComplexOutputVelocitiesWriteFrequency": ["complex_output_settings", "velocities_write_frequency"],
3919
3920 "ComplexRestraintKPhiA": ["complex_restraint_settings", "K_phiA"],
3921 "ComplexRestraintKPhiB": ["complex_restraint_settings", "K_phiB"],
3922 "ComplexRestraintKPhiC": ["complex_restraint_settings", "K_phiC"],
3923 "complexRestraintKR": ["complex_restraint_settings", "K_r"],
3924 "ComplexRestraintKThetaA": ["complex_restraint_settings", "K_thetaA"],
3925 "ComplexRestraintKThetaB": ["complex_restraint_settings", "K_thetaB"],
3926 "ComplexRestraintAnchorFindingStrategy": ["complex_restraint_settings", "anchor_finding_strategy"],
3927 "ComplexRestraintDsspFilter": ["complex_restraint_settings", "dssp_filter"],
3928 "ComplexRestraintHostMaxDistance": ["complex_restraint_settings", "host_max_distance"],
3929 "ComplexRestraintHostMinDistance": ["complex_restraint_settings", "host_min_distance"],
3930 "ComplexRestraintHostSelection": ["complex_restraint_settings", "host_selection"],
3931 "ComplexRestraintRmsfCutoff": ["complex_restraint_settings", "rmsf_cutoff"],
3932
3933 "ComplexSimulationEarlyTerminationTargetError": ["complex_simulation_settings", "early_termination_target_error",],
3934 "ComplexSimulationEquilibrationLength": ["complex_simulation_settings", "equilibration_length"],
3935 "ComplexSimulationMinimizationSteps": ["complex_simulation_settings", "minimization_steps"],
3936 "ComplexSimulationNReplicas": ["complex_simulation_settings", "n_replicas"],
3937 "ComplexSimulationProductionLength": ["complex_simulation_settings", "production_length"],
3938 "ComplexSimulationRealTimeAnalysisInterval": ["complex_simulation_settings", "real_time_analysis_interval"],
3939 "ComplexSimulationRealTimeAnalysisMinimumTime": ["complex_simulation_settings", "real_time_analysis_minimum_time",],
3940 "ComplexSimulationSamplerMethod": ["complex_simulation_settings", "sampler_method"],
3941 "ComplexSimulationSamsFlatnessCriteria": ["complex_simulation_settings", "sams_flatness_criteria"],
3942 "ComplexSimulationSamsGamma0": ["complex_simulation_settings", "sams_gamma0"],
3943 "ComplexSimulationTimePerIteration": ["complex_simulation_settings", "time_per_iteration"],
3944
3945 "ComplexSolvationBoxShape": ["complex_solvation_settings", "box_shape"],
3946 "ComplexSolvationBoxSize": ["complex_solvation_settings", "box_size"],
3947 "ComplexSolvationSolventModel": ["complex_solvation_settings", "solvent_model"],
3948 "ComplexSolvationSolventPadding": ["complex_solvation_settings", "solvent_padding"],
3949
3950 "EngineComputePlatform": ["engine_settings", "compute_platform"],
3951 "EngineGpuDeviceIndex": ["engine_settings", "gpu_device_index"],
3952
3953 "ForcefieldConstraints": ["forcefield_settings", "constraints"],
3954 "Forcefields": ["forcefield_settings", "forcefields"],
3955 "ForcefieldHydrogenMass": ["forcefield_settings", "hydrogen_mass"],
3956 "ForcefieldNonbondedCutoff": ["forcefield_settings", "nonbonded_cutoff"],
3957 "ForcefieldNonbondedMethod": ["forcefield_settings", "nonbonded_method"],
3958 "ForcefieldRigidWater": ["forcefield_settings", "rigid_water"],
3959 "ForcefieldSmallMoleculeForcefield": ["forcefield_settings", "small_molecule_forcefield"],
3960
3961 "IntegratorBarostatFrequency": ["integrator_settings", "barostat_frequency"],
3962 "IntegratorConstraintTolerance": ["integrator_settings", "constraint_tolerance"],
3963 "IntegratorLangevinCollisionRate": ["integrator_settings", "langevin_collision_rate"],
3964 "IntegratorNRestartAttempts": ["integrator_settings", "n_restart_attempts"],
3965 "IntegratorReassignVelocities": ["integrator_settings", "reassign_velocities"],
3966 "IntegratorRemoveCom": ["integrator_settings", "remove_com"],
3967 "IntegratorTimestep": ["integrator_settings", "timestep"],
3968
3969 "PartialChargeNaglModel": ["partial_charge_settings", "nagl_model"],
3970 "PartialChargeNumberOfConformers": ["partial_charge_settings", "number_of_conformers"],
3971 "PartialChargeOffToolkitBackend": ["partial_charge_settings", "off_toolkit_backend"],
3972 "PartialChargeMethod": ["partial_charge_settings", "partial_charge_method"],
3973
3974 "SolventEquilOutputCheckpointInterval": ["solvent_equil_output_settings", "checkpoint_interval"],
3975 "SolventEquilOutputCheckpointStorageFilename": ["solvent_equil_output_settings", "checkpoint_storage_filename"],
3976 "SolventEquilOutputEquilNPTStructure": ["solvent_equil_output_settings", "equil_npt_structure"],
3977 "SolventEquilOutputEquilNVTstructure": ["solvent_equil_output_settings", "equil_nvt_structure"],
3978 "SolventEquilOutputForcefieldCache": ["solvent_equil_output_settings", "forcefield_cache"],
3979 "SolventEquilOutputLogOutput": ["solvent_equil_output_settings", "log_output"],
3980 "SolventEquilOutputMinimizedStructure": ["solvent_equil_output_settings", "minimized_structure"],
3981 "SolventEquilOutputIndices": ["solvent_equil_output_settings", "output_indices"],
3982 "SolventEquilOutputPreminimizedStructure": ["solvent_equil_output_settings", "preminimized_structure"],
3983 "SolventEquilOutputProductionTrajectoryFilename": ["solvent_equil_output_settings", "production_trajectory_filename",],
3984 "SolventEquilOutputTrajectoryWriteInterval": ["solvent_equil_output_settings", "trajectory_write_interval"],
3985
3986 "SolventEquilSimulationEquilibrationLength": ["solvent_equil_simulation_settings", "equilibration_length"],
3987 "SolventEquilSimulationEquilibrationLengthNVT": ["solvent_equil_simulation_settings", "equilibration_length_nvt",],
3988 "SolventEquilSimulationMinimizationSteps": ["solvent_equil_simulation_settings", "minimization_steps"],
3989 "SolventEquilSimulationProductionLength": ["solvent_equil_simulation_settings", "production_length"],
3990
3991 "SolventLambdaElecA": ["solvent_lambda_settings", "lambda_elec_A"],
3992 "SolventLambdaElecB": ["solvent_lambda_settings", "lambda_elec_B"],
3993 "SolventLambdaRestraintsA": ["solvent_lambda_settings", "lambda_restraints_A"],
3994 "SolventLambdaRestraintsB": ["solvent_lambda_settings", "lambda_restraints_B"],
3995 "SolventLambdaVdwA": ["solvent_lambda_settings", "lambda_vdw_A"],
3996 "SolventLambdaVdwB": ["solvent_lambda_settings", "lambda_vdw_B"],
3997
3998 "SolventOutputCheckpointInterval": ["solvent_output_settings", "checkpoint_interval"],
3999 "SolventOutputCheckpointStorageFilename": ["solvent_output_settings", "checkpoint_storage_filename"],
4000 "SolventOutputForcefieldCache": ["solvent_output_settings", "forcefield_cache"],
4001 "SolventOutputFilename": ["solvent_output_settings", "output_filename"],
4002 "SolventOutputIndices": ["solvent_output_settings", "output_indices"],
4003 "SolventOutputStructure": ["solvent_output_settings", "output_structure"],
4004 "SolventOutputPositionsWriteFrequency": ["solvent_output_settings", "positions_write_frequency"],
4005 "SolventOutputVelocitiesWriteFrequency": ["solvent_output_settings", "velocities_write_frequency"],
4006
4007 "SolventRestraintCentralAtomsOnly": ["solvent_restraint_settings", "central_atoms_only"],
4008 "SolventRestraintSpringConstant": ["solvent_restraint_settings", "spring_constant"],
4009
4010 "SolventSimulationEarlyTerminationTargetError": ["solvent_simulation_settings", "early_termination_target_error",],
4011 "SolventSimulationEquilibrationLength": ["solvent_simulation_settings", "equilibration_length"],
4012 "SolventSimulationMinimizationSteps": ["solvent_simulation_settings", "minimization_steps"],
4013 "SolventSimulationNReplicas": ["solvent_simulation_settings", "n_replicas"],
4014 "SolventSimulationProductionLength": ["solvent_simulation_settings", "production_length"],
4015 "SolventSimulationRealTimeAnalysisInterval": ["solvent_simulation_settings", "real_time_analysis_interval"],
4016 "SolventSimulationRealTimeAnalysisMinimumTime": ["solvent_simulation_settings", "real_time_analysis_minimum_time",],
4017 "SolventSimulationSamplerMethod": ["solvent_simulation_settings", "sampler_method"],
4018 "SolventSimulationSamsFlatnessCriteria": ["solvent_simulation_settings", "sams_flatness_criteria"],
4019 "SolventSimulationSamsGamma0": ["solvent_simulation_settings", "sams_gamma0"],
4020 "SolventSimulationTimePerIteration": ["solvent_simulation_settings", "time_per_iteration"],
4021
4022 "SolventSolvationBoxShape": ["solvent_solvation_settings", "box_shape"],
4023 "SolventSolvationBoxSize": ["solvent_solvation_settings", "box_size"],
4024 "SolventSolvationSolventModel": ["solvent_solvation_settings", "solvent_model"],
4025 "SolventSolvationSolventPadding": ["solvent_solvation_settings", "solvent_padding"],
4026
4027 "ThermoPh": ["thermo_settings", "ph"],
4028 "ThermoPressure": ["thermo_settings", "pressure"],
4029 "ThermoRedoxPotential": ["thermo_settings", "redox_potential"],
4030 "ThermoTemperature": ["thermo_settings", "temperature"],
4031 }
4032
4033 return RBFEParametersMap
4034
4035
4036 def SetupRelativeFreeEnergySeparatedTopologySettings(ParamsOptionName, ParamsInfo):
4037 """Setup relative binding free energy protocol settings to calculate RBFE using separated
4038 topology.
4039
4040 The ParamsInfo is a comma delimited list of parameter name and value pairs
4041 returned by ProcessOptionOpenFERelatibveBindingFreeEnergySeparatedTopologyParameters().
4042
4043 Arguments:
4044 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
4045 ParamsInfo (dict): Parameter name and value pairs.
4046
4047 Returns:
4048 object: OpenFE SepTopProtocol settings object.
4049
4050 """
4051
4052 from openfe.protocols.openmm_septop import SepTopProtocol
4053
4054 RBFESettings = SepTopProtocol.default_settings()
4055 RBFEParametersMap = _SetupMapForRelativeBindingFreeEnergySeparatedTopologyParameters()
4056
4057 _UpdateOpenFESettings("RBFESepTop", ParamsOptionName, ParamsInfo, RBFESettings, RBFEParametersMap)
4058
4059 return RBFESettings
4060
4061
4062 def SetupAbsoluteHydrationFreeEnergySettings(ParamsOptionName, ParamsInfo):
4063 """Setup absolute hydration free energy protocol settings to calculate AHFE.
4064
4065 The ParamsInfo is a comma delimited list of parameter name and value pairs
4066 returned by ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters().
4067
4068 Arguments:
4069 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
4070 ParamsInfo (dict): Parameter name and value pairs.
4071
4072 Returns:
4073 object: OpenFE AbsoluteSolvationProtocol settings object.
4074
4075 """
4076
4077 AHFESettings = AbsoluteSolvationProtocol.default_settings()
4078 AHFEParametersMap = _SetupMapForAbsoluteHydrationFreeEnergyParameters()
4079
4080 _UpdateOpenFESettings("AHFE", ParamsOptionName, ParamsInfo, AHFESettings, AHFEParametersMap)
4081
4082 return AHFESettings
4083
4084
4085 def ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters(
4086 ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None
4087 ):
4088 """Process parameters for AHFE parameters option and return a map
4089 containing processed parameter names and values.
4090
4091 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
4092 to setup AHFE calculations.
4093
4094 The default values are automatically updated to match settings provided by
4095 OpenFE module AbsoluteSolvationProtocol.
4096
4097 You must specify valid OpenFE values for these parameters. An extensive
4098 validation is not performed.
4099
4100 The supported parameter names along with their default and possible
4101 values are shown below:
4102
4103 protocolRepeats, 3
4104
4105 Integrator settings:
4106
4107 integratorBarostatFrequency, 25.0 * timestep [ The specified value
4108 is a multiple of integratorTimestep. ]
4109 integratorConstraintTolerance, 1e-06
4110 integratorLangevinCollisionRate, 1.0 [ Units: 1 / picosecond ]
4111 integratorNRestartAttempts, 20
4112 integratorReassignVelocities, no [ Possible values: yes or no ]
4113 integratorRemoveCom, no [ Possible values: yes or no ]
4114 integratorTimestep, 4.0 [ Units: femtosecond ]
4115
4116 Lambda settings:
4117
4118 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
4119 1.0 [ Possible values: A space delimited list of values
4120 between 0.0 and 1.0 ]
4121 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
4122 0.0 0.0 [ Possible values: A space delimited list of values
4123 between 0.0 and 1.0 ]
4124 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
4125 0.85 1.0 [ Possible values: A space delimited list of values
4126 between 0.0 and 1.0 ]
4127
4128 Partial charge settings:
4129
4130 partialChargeNaglModel, None [ Default: Production AM1BCC model for
4131 NAGL; Possible value: Any valid name. ]
4132 partialChargeNumberOfConformers, None [ Possible value: > 0 ]
4133 partialChargeOffToolkitBackend, AmberTools [ Possible values:
4134 AmberTools or RDKit ]
4135 partialChargeMethod, AM1BCC [ Possble values: AM1BCC, Espaloma,
4136 or NAGL ]
4137
4138 Solvation settings:
4139
4140 solvationBoxShape, dodecahedron [ Possible values: cube,,
4141 dodecahedron, or octahedron ]
4142 solvationBoxSize, None [ Possible value: A triplet of space
4143 X Y Z values; Units: nanometer ]
4144 solvationSolventModel, tip3p [ Possible values: tip3p, spce, tip4pew,
4145 or tip5p ]
4146 solvationSolventPadding, 1.5 [ Units: nanometer ]
4147
4148 Solvent engine settings:
4149
4150 solventEngineComputePlatform, CPU [ Possible values: CPU, CUDA,
4151 OpenCL, or Reference ]
4152 solventEngineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
4153
4154 Solvent equil output settings:
4155
4156 solventEquilOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
4157 solventEquilOutputCheckpointStorageFilename, checkpoint.chk
4158 solventEquilOutputNPTStructure, equil_npt_structure.pdb
4159 solventEquilOutputNVTStructure, equil_nvt_structure.pdb
4160 solventEquilOutputForcefieldCache, db.json
4161 solventEquilOutputLogOutput, equil_simulation.log
4162 solventEquilOutputMinimizedStructure, minimized.pdb
4163 solventEquilOutputIndices, not water [ Possible value: Any valid
4164 selection. ]
4165 solventEquilOutputPreminimizedStructure, system.pdb
4166 solventEquilOutputProductionTrajectoryFilename, production_equil.xtc
4167 solventEquilOutputTrajectoryWriteInterval, 20.0 [ Units: picosecond ]
4168
4169 Solvent equil simulation settings:
4170
4171 solventEquilSimulationEquilLength, 0.2 [ Units: nanosecond ]
4172 solventEquilSimulationEquiLengthNVT, 0.1 [ Units: nanosecond ]
4173 solventEquilSimulationMinimizationSteps,5000
4174 solventEquilSimulationProductionLength,0.5 [ Units: nanosecond ]
4175
4176 Solvent forcefield settings:
4177
4178 solventForcefieldConstraints, HBonds [ Possible values: HBonds,
4179 AllBonds, or HAngles ]
4180 solventForcefields, amber/ff14SB.xml, amber/tip3p_standard.xml
4181 amber/tip3p_HFE_multivalent.xml amber/phosaa10.xml
4182 [ Possible values: A space delimited list of valid names. ]
4183 solventForcefieldHydrogenMass, 3.0 [ Units: amu ]
4184 solventForcefieldNonbondedCutoff, 0.9 [ Units: nanometer ]
4185 solventForcefieldNonbondedMethod, PME [ Possible values: PME or
4186 NoCutoff ]
4187 solventForcefieldRigidWater, yes, [ Possible values: yes or no ]
4188 solventForcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible
4189 value: A valid forcefield name. ]
4190
4191 Solvent output settings:
4192
4193 solventOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
4194 solventOutputCheckpointStorageFilename, solvent_checkpoint.nc
4195 solventOutputForcefieldCache, db.json
4196 solventOutputFilename, solvent.nc
4197 solventOutputIndices, not water [ Possible value: Any valid
4198 selection. ]
4199 solventOutputStructure, hybrid_system.pdb
4200 solventOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
4201 solventOutputVelocitiesWriteFrequency, None [ Possible
4202 values: > 0; Units: picosecond ]
4203
4204 Solvent simulation settings:
4205
4206 solventSimulationEarlyTerminationTargetError, 0.0 [ Units:
4207 kilocalorie_per_mole ]
4208 solventSimulationEquilibrationLength, 1.0 [ Units: nanosecond ]
4209 solventSimulationMinimizationSteps, 5000
4210 solventSimulationNReplicas, 14
4211 solventSimulationProductionLength, 10.0 [ Units: nanosecond ]
4212 solventSimulationRealTimeAnalysisInterval, 250.0 [ Units:
4213 picosecond ]
4214 solventSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units:
4215 picosecond
4216 solventSimulationSamplerMethod, repex [ Possible values: repex,
4217 sams, or independent ]
4218 solventSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
4219 values: logZ-flatness, minimum-visits or histogram-flatness ]
4220 solventSimulationsamsGamma0, 1.0
4221 solventSimulationTimePerIteration,2.5 [ Units: picosecond ]
4222
4223 Thermo settings:
4224
4225 thermoPh, None [ Possible values: > 0 ]
4226 thermoPressure, 1.0 [ Units: bar ]
4227 thermoRedoxPotential, None [ Possible values: A valid float.
4228 Units: millivolts (mV) ]
4229 thermoTemperature, 298.15 [ Units: kelvin ]
4230
4231 Vacuum engine settings:
4232
4233 vacuumEngineComputePlatform, CPU [ Possible values: CPU, CUDA,
4234 OpenCL, or Reference ]
4235 vacummEngineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
4236
4237 Vacuum equil output settings:
4238
4239 vacuumEquilOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
4240 vacuumEquilOutputCheckpointStorageFilename, checkpoint.chk
4241 vacuumEquilOutputNPTStructure, equil_structure.pdb
4242 vacuumEquilOutputNVTStructure,None
4243 vacuumEquilOutputForcefieldCache, db.json
4244 vacuumEquilOutputLogOutput, equil_simulation.log
4245 vacuumEquilOutputMinimizedStructure, minimized.pdb
4246 vacuumEquilOutputIndices, not water [ Possible value: Any valid
4247 selection. ]
4248 vacuumEquilOutputPreminimizedStructure, system.pdb
4249 vacuumEquilOutputProductionTrajectoryFilename, production_equil.xtc
4250 vacuumEquilOutputTrajectoryWriteInterval, 20.0 [ Units: picosecond ]
4251
4252 Vacuum equil simulation settings:
4253
4254 vacuumEquilSimulationEquilLength, 0.2 [ Units: nanosecond ]
4255 vacuumEquilSimulationEquilLengthNVT, None [ Units: nanosecond ]
4256 vacuumEquilSimulationMinimizationSteps, 5000
4257 vacuumEquilSimulationProductionLength, 0.5 [ Units: nanosecond ]
4258
4259 Vacuum forcefield settings:
4260
4261 vacuumForcefieldConstraints, HBonds [ Possible values: HBonds,
4262 AllBonds, or HAngles ]
4263 vacuumForcefields, amber/ff14SB.xml, amber/tip3p_standard.xml
4264 amber/tip3p_HFE_multivalent.xml amber/phosaa10.xml
4265 [ Possible values: A space delimited list of valid names. ]
4266 vacuumForcefieldHydrogenMass, 3.0 [ Units: amu ]
4267 vacuumForcefieldNonbondedCutoff, 0.9 [ Units: nanometer ]
4268 vacuumForcefieldNonbondedMethod, nocutoff [ Possible values: PME
4269 or NoCutoff ]
4270 vacuumForcefieldRigidWater, yes, [ Possible values: yes or no ]
4271 vacuumForcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible
4272 value: A valid forcefield name. ]
4273
4274 Vacuum output settings:
4275
4276 vacuumOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
4277 vacuumOutputCheckpointStorageFilename, vacuum_checkpoint.nc
4278 vacuumOutputForcefieldCache, db.json
4279 vacuumOutputFilename, vacuum.nc
4280 vacuumOutputIndices, not water [ Possible value: Any valid
4281 selection. ]
4282 vacuumOutputStructure, hybrid_system.pdb
4283 vacuumOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
4284 vacuumOutputVelocitiesWriteFrequency, None [ Possible
4285 values: > 0; Units: picosecond ]
4286
4287 Vacuum simulation settings:
4288
4289 vacuumSimulationEarlyTerminationTargetError, 0.0 [ Units:
4290 0.0 kilocalorie_per_mole ]
4291 vacuumSimulationEquilibrationLength, 0.5 [ Units: nanosecond ]
4292 vacuumSimulationMinimizationSteps, 5000
4293 vacuumSimulationNReplicas, 14
4294 vacuumSimulationProductionLength, 2.0 [ Units: nanosecond ]
4295 vacuumSimulationRealTimeAnalysisInterval, 250.0 [ Units: picosecond ]
4296 vacuumSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units: picosecond]
4297 vacuumSimulationSamplerMethod, repex [ Possible values: repex,
4298 sams, or independent ]
4299 vacuumSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
4300 values: logZ-flatness, minimum-visits or histogram-flatness ]
4301 vacuumSimulationSamsGamma0, 1.0
4302 vacuumSimulationTimePerIteration,2.5 [ Units: picosecond ]
4303
4304 Thermo settings:
4305
4306 thermoPh, None [ Possible values: > 0 ]
4307 thermoPressure, 0.98692327 [ Units: standard_atmosphere ]
4308 thermoRedoxPotential, None [ Possible values: A valid float.
4309 Units: millivolts (mV) ]
4310 thermoTemperature, 298.15 [ Units: kelvin ]
4311
4312 A brief description of parameters, taken from OpenFE documentation, is
4313 provided below:
4314
4315 protocolRepeats: Number of completely independent repeats of the
4316 entire sampling process.
4317
4318 Integrator settings:
4319
4320 Parameters controlling the LangevinSplittingDynamicsMove integrator
4321 used for simulation.
4322
4323 integratorBarostatFrequency: Frequency at which volume scaling
4324 changes should be attempted.
4325 integratorConstraintTolerance: Tolerance for constraint solver.
4326 integratorLangevinCollisionRate: Collision frequency.
4327 integratorNRestartAttempts: Number of attempts to restart from
4328 Context in case there are NaNs in the energies after
4329 integration.
4330 integratorReassignVelocities: Reassign velocities from the
4331 Maxwell-Boltzmann distribution at the beginning of each
4332 Monte Carlo move.
4333 integratorRemoveCom: Remove the center of mass motion.
4334 integratorTimestep: Size of the simulation timestep.
4335
4336 Lambda settings:
4337
4338 Lambda protocol parameters, including number of lambda windows and
4339
4340 lambdaElec: List of lambda values for electrostatics. The values of
4341 0 and 1 imply state A and state B respectively.
4342 lambdaRestraints: List of lambda values for restraints. The values
4343 of 0 and 1 imply state A and state B respectively.
4344 lambdaVdw: List of lamda values for van der Waals. The values of
4345 of 0 and 1 imply state A and state B respectively.
4346
4347 Partial charge settings:
4348
4349 Parameters for automatically assigning missing partial charges to
4350 small molecules, including the partial charge method.
4351
4352 partialChargeNaglModel: Model to use for partial charge assignment.
4353 A value of None implies the use of the latest available
4354 production AM1BCC model.
4355 partialChargeNumberOfConformers: Number of conformers to generate
4356 as part of the partial charge assignment. A value of None
4357 implies the use of the existing conformer.
4358 partialChargeOffToolkitBackend: OpenFF toolkit registry backend to
4359 use for calculating partial charges.
4360 partialChargeMethod: Method to use for calculating partial charges.
4361
4362 Solvation settings:
4363
4364 Solvation parameters for the system, including the solvent model and
4365 the solvent padding.
4366
4367 solvationBoxShape: Shape of the periodic solvent box to create.
4368 solvationBoxSize: Lengths of the unit cell for a solvent box.
4369 solvationSolventModel: Forcefield water model to use during
4370 solvation and defining the model properties.
4371 solvationSolventPadding: Minimum distance from any solute bounding
4372 sphere to the edge of the box.
4373
4374 Solvent engine settings:
4375
4376 Parameters configuring the compute platform used by the OpenMM to
4377 perform the simulation.
4378
4379 solventEngineComputePlatform: Platform to use for running OpenMM MD
4380 calculations.
4381 solventEngineGpuDeviceIndex: Space delimited list of device indices
4382 to use for running OpenMM MD calculations.
4383
4384 Solvent equil output settings:
4385
4386 Parameters controlling simulation output during equilibration
4387 phase of solvent transformation.
4388
4389 solventEquilOutputCheckpointInterval: Frequency to write the
4390 checkpoint file.
4391 solventEquilOutputCheckpointStorageFilename: Checkpoint filename.
4392 solventEquilOutputNPTStructure: NPT structure filename.
4393 solventEquilOutputNVTStructure: NVT strucure filename.
4394 solventEquilOutputForcefieldCache: Filename for caching small
4395 molecule residue templates.
4396 solventEquilOutputLogOutput: Simulation log filename.
4397 solventEquilOutputMinimizedStructure: Minimized structire filename.
4398 solventEquilOutputIndices: Selection string for selecting
4399 coordinates to write.
4400 solventEquilOutputPreminimizedStructure: Initial structure filename.
4401 solventEquilOutputProductionTrajectoryFilename: Trajectory filename.
4402 solventEquilOutputTrajectoryWriteInterval: Frequency for writing
4403 velocities to trajectory file.
4404
4405 Solvent equil simulation settings:
4406
4407 Parameters controlling simulation during equilibration phase of
4408 solvent transformation.
4409
4410 solventEquilSimulationEquilLength: Length of the NPT equilibration
4411 phase.
4412 solventEquilSimulationEquiLengthNVT: Length of the NVT equilibration
4413 phase.
4414 solventEquilSimulationMinimizationSteps: Maximum number of
4415 minimization steps to perform.
4416 solventEquilSimulationProductionLength: Length of the NPT production
4417 phase.
4418
4419 Solvent forcefield settings:
4420
4421 Parameters to set up the force field with OpenMM Force Fields
4422 equilibration phase of solvent transformation.
4423
4424 solventForcefieldConstraints: Constraints to use.
4425 solventForcefields: List of valid forcefield paths for all
4426 components except small molecules.
4427 solventForcefieldHydrogenMass: Mass to be repartitioned to
4428 hydrogens from neighboring heavy atoms.
4429 solventForcefieldNonbondedCutoff: Cutoff for short range nonbonded
4430 interactions.
4431 solventForcefieldNonbondedMethod: Method for treating nonbonded
4432 interactions.
4433 solventForcefieldRigidWater: Use a rigid water model.
4434 solventForcefieldSmallMoleculeForcefield: A valid forcefield name
4435 to use small molecules.
4436
4437 Solvent output settings:
4438
4439 Parameters controlling simulation output during final phase of
4440 solvent transformation.
4441
4442 solventOutputCheckpointInterval: Frequency to write the checkpoint
4443 file.
4444 solventOutputCheckpointStorageFilename: Checkpoint filename.
4445 solventOutputForcefieldCache: Filename for caching small molecule
4446 residue templates.
4447 solventOutputFilename: Trajectory filename.
4448 solventOutputIndices: Selection string for selecting coordinates to
4449 write.
4450 solventOutputStructure: Hybrid topology structure filename.
4451 solventOutputPositionsWriteFrequency: Frequency for writing
4452 positions to trajectory file.
4453 solventOutputVelocitiesWriteFrequency: Frequency for writing
4454 velocities to trajectory file.
4455
4456 Solvent simulation settings:
4457
4458 Parameters controlling simulation during final phase of solvent
4459 transformation.
4460
4461 solventSimulationEarlyTerminationTargetError: Target error for the
4462 real time analysis measured in kcal/mol. Once the MBAR error of
4463 the free energy is at or below this value, the simulation will
4464 be considered complete. The suggested value of 0.12 has shown to
4465 be effective in both hydration and binding free energy
4466 benchmarks.
4467 solventSimulationEquilibrationLength: Length of the equilibration
4468 phase. The specified value must be divisible by 'integratorTimestep'.
4469 solventSimulationMinimizationSteps: Maximum number of minimization
4470 steps to perform.
4471 solventSimulationNReplicas: Number of replicas to use.
4472 solventSimulationProductionLength: Length of the production phase.
4473 The specified value must be divisible by 'integratorTimestep'.
4474 solventSimulationRealTimeAnalysisMinimumTime: Time interval for
4475 performing analysis of the free energies. At each interval, real
4476 time analysis data will be written to a yaml file named
4477 <outputFileName>_real_time_analysis.yaml. The current error
4478 in the estimate will also be assessed and the simulation will
4479 be terminated when it drops below
4480 'simulationEarlyTerminationTargetError'.
4481 solventSimulationSamplerMethod: Minimum simulation time after
4482 which the real time analysis is performed.
4483 solventSimulationSamplerMethod: Alchemical sampling method to use:
4484 REPEX (Hamiltonian REPlica EXchange), SAMS (Self-Adjusted
4485 Mixture Sampling), or Independent (Independently sampled lambda
4486 windows).
4487 solventSimulationSamsFlatnessCriteria:Method for assessing when to
4488 switch to asymptomatically optimal scheme for SAMS.
4489 solventSimulationsamsGamma0: Initial weight adaptation rate for
4490 SAMS.
4491 solventSimulationTimePerIteration: Simulation time between each
4492 MCMC move attempt
4493
4494 Vacuum engine settings:
4495
4496 Parameters configuring the compute platform used by the OpenMM to
4497 perform the simulation.
4498
4499 vacuumEngineComputePlatform: Platform to use for running OpenMM MD
4500 calculations.
4501 vacuumEngineGpuDeviceIndex: Space delimited list of device indices
4502 to use for running OpenMM MD calculations.
4503
4504 The rest of the vacuum settings are similar to the solvent settings already
4505 described under various sections for solvent. The prefix 'vacuum' is used
4506 for the names of the pramaters instead of the prefix 'solvent.'
4507
4508 Thermo settings:
4509
4510 Thermodynamic parameters, including the temperature and the pressure
4511 of the system.
4512
4513 thermoPh: Simulation pH
4514 thermoPressure: Simulation pressure.
4515 thermoRedoxPotential:Simulation redox potential.
4516 thermoTemperature: Simulation temperature.
4517
4518 Arguments:
4519 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
4520 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
4521 ParamsDefaultInfo (dict): Default values to override selected parameters.
4522
4523 Returns:
4524 dictionary: Processed parameter name and value pairs.
4525
4526 """
4527 ParamsInfo = _SetupAbsoluteHydrationFreeEnergyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue)
4528
4529 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
4530 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
4531 )
4532
4533 if re.match("^auto$", ParamsOptionValue, re.I):
4534 _ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
4535 return ParamsInfo
4536
4537 for Index in range(0, len(ParamsOptionValueWords), 2):
4538 Name = ParamsOptionValueWords[Index].strip()
4539 Value = ParamsOptionValueWords[Index + 1].strip()
4540
4541 ParamName = CanonicalParamNamesMap[Name.lower()]
4542 ParamValue = Value
4543
4544 if re.match(
4545 "^(ProtocolRepeats|IntegratorNRestartAttempts|PartialChargeNumberOfConformers|SolventEquilSimulationMinimizationSteps|SolventSimulationMinimizationSteps|SolventSimulationNReplicas|VacuumEquilSimulationMinimizationSteps|VacuumSimulationMinimizationSteps|VacuumSimulationNReplicas)$",
4546 ParamName,
4547 re.I,
4548 ):
4549 # Int > 0
4550 if not MiscUtil.IsInteger(Value):
4551 MiscUtil.PrintError(
4552 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
4553 % (Value, ParamName, ParamsOptionName)
4554 )
4555 Value = int(Value)
4556 if Value <= 0:
4557 MiscUtil.PrintError(
4558 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4559 % (ParamValue, ParamName, ParamsOptionName)
4560 )
4561 ParamValue = Value
4562 elif re.match(
4563 "^(IntegratorConstraintTolerance|SolventForcefieldHydrogenMass|SolventSimulationsamsGamma0|VacuumForcefieldHydrogenMass)$",
4564 ParamName,
4565 re.I,
4566 ):
4567 # float > 0
4568 if not MiscUtil.IsFloat(Value):
4569 MiscUtil.PrintError(
4570 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4571 % (Value, ParamName, ParamsOptionName)
4572 )
4573 Value = float(Value)
4574 if Value <= 0:
4575 MiscUtil.PrintError(
4576 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4577 % (ParamValue, ParamName, ParamsOptionName)
4578 )
4579 ParamValue = Value
4580 elif re.match("^ThermoPh$", ParamName, re.I):
4581 # float > 0 or None
4582 if re.match("^None$", Value, re.I):
4583 ParamValue = None
4584 else:
4585 if not MiscUtil.IsFloat(Value):
4586 MiscUtil.PrintError(
4587 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4588 % (Value, ParamName, ParamsOptionName)
4589 )
4590 Value = float(Value)
4591 if Value <= 0:
4592 MiscUtil.PrintError(
4593 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4594 % (ParamValue, ParamName, ParamsOptionName)
4595 )
4596 ParamValue = Value
4597 elif re.match("^ThermoRedoxPotential$", ParamName, re.I):
4598 if re.match("^None$", Value, re.I):
4599 ParamValue = None
4600 else:
4601 if not MiscUtil.IsFloat(Value):
4602 MiscUtil.PrintError(
4603 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4604 % (Value, ParamName, ParamsOptionName)
4605 )
4606 Value = float(Value)
4607 ParamValue = Value * openff.units.unit.millivolts
4608 elif re.match("^(SolventForcefieldNonbondedCutoff|VacuumForcefieldNonbondedCutoff)$", ParamName, re.I):
4609 # float > 0 and units nanometer
4610 if not MiscUtil.IsFloat(Value):
4611 MiscUtil.PrintError(
4612 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4613 % (Value, ParamName, ParamsOptionName)
4614 )
4615 Value = float(Value)
4616 if Value <= 0:
4617 MiscUtil.PrintError(
4618 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4619 % (ParamValue, ParamName, ParamsOptionName)
4620 )
4621 ParamValue = Value * openff.units.unit.nanometer
4622 elif re.match("^SolvationSolventPadding$", ParamName, re.I):
4623 # float > 0 and units nanometer or none
4624 if re.match("^None$", Value, re.I):
4625 ParamValue = None
4626 else:
4627 if not MiscUtil.IsFloat(Value):
4628 MiscUtil.PrintError(
4629 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4630 % (Value, ParamName, ParamsOptionName)
4631 )
4632 Value = float(Value)
4633 if Value <= 0:
4634 MiscUtil.PrintError(
4635 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4636 % (ParamValue, ParamName, ParamsOptionName)
4637 )
4638 ParamValue = Value * openff.units.unit.nanometer
4639 elif re.match(
4640 "^(IntegratorReassignVelocities|IntegratorRemoveCom|SolventForcefieldRigidWater|VacuumForcefieldRigidWater)$",
4641 ParamName,
4642 re.I,
4643 ):
4644 # bool
4645 if not re.match("^(yes|no|true|false)$", Value, re.I):
4646 MiscUtil.PrintError(
4647 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
4648 % (Value, Name, ParamsOptionName)
4649 )
4650 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
4651 elif re.match("^(LambdaElec|LambdaRestraints|LambdaVdw)$", ParamName, re.I):
4652 # List of float values between 0 and 1...
4653 Values = Value.split()
4654 if len(Values) == 0:
4655 MiscUtil.PrintError(
4656 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of space delimited values\n'
4657 % (Value, ParamName, ParamsOptionName)
4658 )
4659 for Value in Values:
4660 if not MiscUtil.IsFloat(Value):
4661 MiscUtil.PrintError(
4662 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4663 % (Value, ParamName, ParamsOptionName)
4664 )
4665 Value = float(Value)
4666 if Value < 0.0 or Value > 1.0:
4667 MiscUtil.PrintError(
4668 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not valid value. Supported values: 0.0 to 1.0\n'
4669 % (Value, ParamName, ParamsOptionName)
4670 )
4671 Values = [float(Value) for Value in Values]
4672 ParamValue = Values
4673 elif re.match("^IntegratorBarostatFrequency$", ParamName, re.I):
4674 if not MiscUtil.IsFloat(Value):
4675 MiscUtil.PrintError(
4676 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4677 % (Value, ParamName, ParamsOptionName)
4678 )
4679 Value = float(Value)
4680 if Value <= 0:
4681 MiscUtil.PrintError(
4682 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4683 % (ParamValue, ParamName, ParamsOptionName)
4684 )
4685 ParamValue = Value * openff.units.unit.timestep
4686 elif re.match("^IntegratorLangevinCollisionRate$", ParamName, re.I):
4687 if not MiscUtil.IsFloat(Value):
4688 MiscUtil.PrintError(
4689 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4690 % (Value, ParamName, ParamsOptionName)
4691 )
4692 Value = float(Value)
4693 if Value <= 0:
4694 MiscUtil.PrintError(
4695 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4696 % (ParamValue, ParamName, ParamsOptionName)
4697 )
4698 ParamValue = Value / openff.units.unit.picosecond
4699 elif re.match("^IntegratorTimestep$", ParamName, re.I):
4700 # float > 0 femtosecond
4701 if not MiscUtil.IsFloat(Value):
4702 MiscUtil.PrintError(
4703 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4704 % (Value, ParamName, ParamsOptionName)
4705 )
4706 Value = float(Value)
4707 if Value <= 0:
4708 MiscUtil.PrintError(
4709 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4710 % (ParamValue, ParamName, ParamsOptionName)
4711 )
4712 ParamValue = Value * openff.units.unit.femtosecond
4713 elif re.match(
4714 "^(SolventEquilOutputTrajectoryWriteInterval|SolventOutputPositionsWriteFrequency|SolventSimulationRealTimeAnalysisInterval|SolventSimulationRealTimeAnalysisMinimumTime|SolventSimulationTimePerIteration|VacuumEquilOutputTrajectoryWriteInterval|VacuumOutputPositionsWriteFrequency|VacuumSimulationRealTimeAnalysisInterval|VacuumSimulationRealTimeAnalysisMinimumTime|VacuumSimulationTimePerIteration)$",
4715 ParamName,
4716 re.I,
4717 ):
4718 # float > 0 picosecond
4719 if not MiscUtil.IsFloat(Value):
4720 MiscUtil.PrintError(
4721 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4722 % (Value, ParamName, ParamsOptionName)
4723 )
4724 Value = float(Value)
4725 if Value <= 0:
4726 MiscUtil.PrintError(
4727 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4728 % (ParamValue, ParamName, ParamsOptionName)
4729 )
4730 ParamValue = Value * openff.units.unit.picosecond
4731 elif re.match(
4732 "^(SolventEquilOutputCheckpointInterval|SolventEquilSimulationEquilLength|SolventEquilSimulationEquiLengthNVT|SolventEquilSimulationProductionLength|SolventOutputCheckpointInterval|SolventSimulationEquilibrationLength|SolventSimulationProductionLength|VacuumEquilOutputCheckpointInterval|VacuumEquilSimulationEquilLength|VacuumEquilSimulationProductionLength|VacuumOutputCheckpointInterval|VacuumSimulationEquilibrationLength|VacuumSimulationProductionLength)$",
4733 ParamName,
4734 re.I,
4735 ):
4736 # float > 0 nanosecond
4737 if not MiscUtil.IsFloat(Value):
4738 MiscUtil.PrintError(
4739 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4740 % (Value, ParamName, ParamsOptionName)
4741 )
4742 Value = float(Value)
4743 if Value <= 0:
4744 MiscUtil.PrintError(
4745 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4746 % (ParamValue, ParamName, ParamsOptionName)
4747 )
4748 ParamValue = Value * openff.units.unit.nanosecond
4749 elif re.match(
4750 "^(SolventOutputVelocitiesWriteFrequency|VacuumOutputVelocitiesWriteFrequency)$", ParamName, re.I
4751 ):
4752 # float > 0 picosecond or none
4753 if re.match("^None$", Value, re.I):
4754 ParamValue = None
4755 else:
4756 if not MiscUtil.IsFloat(Value):
4757 MiscUtil.PrintError(
4758 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4759 % (Value, ParamName, ParamsOptionName)
4760 )
4761 Value = float(Value)
4762 if Value <= 0:
4763 MiscUtil.PrintError(
4764 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4765 % (ParamValue, ParamName, ParamsOptionName)
4766 )
4767 ParamValue = Value * openff.units.unit.picosecond
4768 elif re.match("^(VacuumEquilSimulationEquilLengthNVT)$", ParamName, re.I):
4769 # float > 0 nanosecond or none
4770 if re.match("^None$", Value, re.I):
4771 ParamValue = None
4772 else:
4773 if not MiscUtil.IsFloat(Value):
4774 MiscUtil.PrintError(
4775 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4776 % (Value, ParamName, ParamsOptionName)
4777 )
4778 Value = float(Value)
4779 if Value <= 0:
4780 MiscUtil.PrintError(
4781 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4782 % (ParamValue, ParamName, ParamsOptionName)
4783 )
4784 ParamValue = Value * openff.units.unit.nanosecond
4785 elif re.match("^PartialChargeMethod$", ParamName, re.I):
4786 if not re.match("^(AM1BCC|AM1BCCELF10|Espaloma|NAGL)$", Value, re.I):
4787 MiscUtil.PrintError(
4788 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AM1BCC, AM1BCCELF10, Espaloma, or NAGL'
4789 % (Value, Name, ParamsOptionName)
4790 )
4791 ParamValue = Value.lower()
4792 elif re.match("^PartialChargeOffToolkitBackend$", ParamName, re.I):
4793 if not re.match("^(AmberTools|OpenEye|RDKit)$", Value, re.I):
4794 MiscUtil.PrintError(
4795 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AmberTools, OpenEye, or RDKit'
4796 % (Value, Name, ParamsOptionName)
4797 )
4798 ParamValue = Value.lower()
4799 elif re.match("^SolvationBoxShape$", ParamName, re.I):
4800 if not re.match("^(cube|dodecahedron|octahedron)$", Value, re.I):
4801 MiscUtil.PrintError(
4802 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: cube, dodecahedron, or octahedron'
4803 % (Value, Name, ParamsOptionName)
4804 )
4805 ParamValue = Value.lower()
4806 elif re.match("^SolvationBoxSize$", ParamName, re.I):
4807 # List of X, Y, Z values...
4808 if re.match("^None$", Value, re.I):
4809 ParamValue = None
4810 else:
4811 Values = Value.split()
4812 if len(Values) != 3:
4813 MiscUtil.PrintError(
4814 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of three space delimited values.\n'
4815 % (Value, ParamName, ParamsOptionName)
4816 )
4817 for Value in Values:
4818 if not MiscUtil.IsFloat(Value):
4819 MiscUtil.PrintError(
4820 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4821 % (Value, ParamName, ParamsOptionName)
4822 )
4823 Values = [float(Value) for Value in Values]
4824 ParamValue = Values * openff.units.unit.nanometer
4825 elif re.match("^SolvationSolventModel$", ParamName, re.I):
4826 if not re.match("^(tip3p|spce|tip4pew|tip5p)$", Value, re.I):
4827 MiscUtil.PrintError(
4828 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: tip3p, spce, tip4pew, or tip5p'
4829 % (Value, Name, ParamsOptionName)
4830 )
4831 ParamValue = Value.lower()
4832 elif re.match("^(SolventEngineComputePlatform|VacuumEngineComputePlatform)$", ParamName, re.I):
4833 if not re.match("^(CPU|CUDA|OpenCL|Reference)$", Value, re.I):
4834 MiscUtil.PrintError(
4835 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: CPU, CUDA, OpenCL, or Reference'
4836 % (Value, Name, ParamsOptionName)
4837 )
4838 ParamValue = Value
4839 elif re.match("^(SolventEngineGpuDeviceIndex|VacuumEngineGpuDeviceIndex)$", ParamName, re.I):
4840 # Comma delimited string values...
4841 DeviceIndices = Value.split()
4842 if len(DeviceIndices) == 0:
4843 MiscUtil.PrintError(
4844 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain space delimited list of device indices.\n'
4845 % (Value, ParamName, ParamsOptionName)
4846 )
4847 for DeviceIndex in DeviceIndices:
4848 if not MiscUtil.IsInteger(DeviceIndex):
4849 MiscUtil.PrintError(
4850 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
4851 % (DeviceIndex, ParamName, ParamsOptionName)
4852 )
4853 DeviceIndices = [int(DeviceIndex) for DeviceIndex in DeviceIndices]
4854 ParamValue = DeviceIndices
4855 elif re.match("^(SolventForcefieldConstraints|VacuumForcefieldConstraints)$", ParamName, re.I):
4856 if not re.match("^(HBonds|AllBonds|HAngles|None)$", Value, re.I):
4857 MiscUtil.PrintError(
4858 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: HBonds, AllBonds, HAngles, or None'
4859 % (Value, Name, ParamsOptionName)
4860 )
4861 ParamValue = None if re.match("^None$", Value, re.I) else Value.lower()
4862 elif re.match("^(SolventForcefields|VacuumForcefields)$", ParamName, re.I):
4863 # List of string values.....
4864 Values = Value.split()
4865 if len(Values) == 0:
4866 MiscUtil.PrintError(
4867 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a space delimited list of values..\n'
4868 % (Value, ParamName, ParamsOptionName)
4869 )
4870 ParamValue = Values
4871 elif re.match("^(SolventForcefieldNonbondedMethod|VacuumForcefieldNonbondedMethod)$", ParamName, re.I):
4872 if not re.match("^(PME|NoCutoff)$", Value, re.I):
4873 MiscUtil.PrintError(
4874 'The parameter value, %s, specified for parameter name, %s, using "%s" option is may be a valid OpenFE value. Supported values: PME or NoCutoff'
4875 % (Value, Name, ParamsOptionName)
4876 )
4877 ParamValue = Value.lower()
4878 elif re.match(
4879 "^(SolventSimulationEarlyTerminationTargetError|VacuumSimulationEarlyTerminationTargetError)$",
4880 ParamName,
4881 re.I,
4882 ):
4883 # float >= 0 units kilocalorie_per_mole
4884 if not MiscUtil.IsFloat(Value):
4885 MiscUtil.PrintError(
4886 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4887 % (Value, ParamName, ParamsOptionName)
4888 )
4889 Value = float(Value)
4890 if Value < 0:
4891 MiscUtil.PrintError(
4892 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4893 % (ParamValue, ParamName, ParamsOptionName)
4894 )
4895 ParamValue = Value * openff.units.unit.kilocalorie_per_mole
4896 elif re.match("^(SolventSimulationSamplerMethod|VacuumSimulationSamplerMethod)$", ParamName, re.I):
4897 if not re.match("^(repex|sams|independent)$", Value, re.I):
4898 MiscUtil.PrintError(
4899 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: repex, sams, or independent'
4900 % (Value, Name, ParamsOptionName)
4901 )
4902 ParamValue = Value.lower()
4903 elif re.match(
4904 "^(SolventSimulationSamsFlatnessCriteria|VacuumSimulationSamsFlatnessCriteria)$", ParamName, re.I
4905 ):
4906 if not re.match("^(logz-flatness|minimum-visits|histogram-flatness)$", Value, re.I):
4907 MiscUtil.PrintError(
4908 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: logz-flatness, minimum-visits, or histogram-flatness'
4909 % (Value, Name, ParamsOptionName)
4910 )
4911 ParamValue = Value.lower()
4912 elif re.match("^ThermoPressure$", ParamName, re.I):
4913 # float > 0 and units bar
4914 if not MiscUtil.IsFloat(Value):
4915 MiscUtil.PrintError(
4916 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4917 % (Value, ParamName, ParamsOptionName)
4918 )
4919 Value = float(Value)
4920 if Value <= 0:
4921 MiscUtil.PrintError(
4922 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
4923 % (ParamValue, ParamName, ParamsOptionName)
4924 )
4925 ParamValue = Value * openff.units.unit.bar
4926 elif re.match("^ThermoTemperature$", ParamName, re.I):
4927 # float >= 0 and units kelvin
4928 if not MiscUtil.IsFloat(Value):
4929 MiscUtil.PrintError(
4930 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
4931 % (Value, ParamName, ParamsOptionName)
4932 )
4933 Value = float(Value)
4934 if Value < 0:
4935 MiscUtil.PrintError(
4936 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: >= 0\n'
4937 % (ParamValue, ParamName, ParamsOptionName)
4938 )
4939 ParamValue = Value * openff.units.unit.kelvin
4940 else:
4941 # Str or None...
4942 ParamValue = None if re.match("^None$", Value, re.I) else Value
4943
4944 # Set value...
4945 ParamsInfo[ParamName] = ParamValue
4946
4947 # Handle parameters with possible auto values...
4948 _ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
4949
4950 return ParamsInfo
4951
4952
4953 def _ProcessOptionOpenFEAbsoluteHydrationFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
4954 """Process parameters with possible auto values and perform validation."""
4955
4956 # Validate solvation parameter values...
4957 ParamName1 = "SolvationBoxSize"
4958 ParamValue1 = ParamsInfo[ParamName1]
4959 ParamName2 = "SolvationSolventPadding"
4960 ParamValue2 = ParamsInfo[ParamName2]
4961 if ParamsInfo[ParamName1] is not None and ParamsInfo[ParamName2] is not None:
4962 MiscUtil.PrintError(
4963 'The parameter values, %s and %s, specified for parameter names, %s and %s, using "%s" option is not a valid value. You must specify only one of these values.\n'
4964 % (ParamValue1, ParamValue2, ParamName1, ParamName2, ParamsOptionName)
4965 )
4966
4967 ParamName1 = "LambdaElec"
4968 ParamValue1Count = len(ParamsInfo[ParamName1])
4969 ParamName2 = "LambdaRestraints"
4970 ParamValue2Count = len(ParamsInfo[ParamName2])
4971 ParamName3 = "LambdaVdw"
4972 ParamValue3Count = len(ParamsInfo[ParamName3])
4973 if ParamValue1Count != ParamValue2Count or ParamValue1Count != ParamValue3Count:
4974 MiscUtil.PrintError(
4975 'The number of values - %s, %s, and %s - specified for parameter names - %s, %s, and %s, using "%s" option are not valid. You must specify same number of values for these parameters.'
4976 % (
4977 ParamValue1Count,
4978 ParamValue2Count,
4979 ParamValue3Count,
4980 ParamName1,
4981 ParamName2,
4982 ParamName3,
4983 ParamsOptionName,
4984 )
4985 )
4986
4987 _ProcessPartialChargeMethodAbsoluteHydrationFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
4988 _ProcessPartialChargeNaglAbsoluteHydrationFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
4989
4990
4991 def _ProcessPartialChargeMethodAbsoluteHydrationFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
4992 """Process PartialChargeMethod AHFE paramater."""
4993
4994 _ProcessPartialChargeMethodFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
4995
4996
4997 def _ProcessPartialChargeNaglAbsoluteHydrationFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
4998 """Process PartialChargeNaglModel AHFE paramater."""
4999
5000 _ProcessPartialChargeNaglFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
5001
5002
5003 def _SetupAbsoluteHydrationFreeEnergyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue):
5004 """Setup AHFE default parameters information using the current AHFE settings."""
5005
5006 ParamsInfo = {}
5007
5008 AHFESettings = AbsoluteSolvationProtocol.default_settings()
5009 AHFEParametersMap = _SetupMapForAbsoluteHydrationFreeEnergyParameters()
5010
5011 for ParamName in AHFEParametersMap.keys():
5012 AHFEParamGroupName, AHFEParamName = AHFEParametersMap[ParamName]
5013 if AHFEParamGroupName is None:
5014 if hasattr(AHFESettings, AHFEParamName):
5015 ParamsInfo[ParamName] = getattr(AHFESettings, AHFEParamName)
5016 else:
5017 MiscUtil.PrintInfo(
5018 'The OpenFE AHFE settings name, %s, corresponding to AHFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
5019 % (AHFEParamName, ParamName, ParamsOptionName)
5020 )
5021 else:
5022 AHFEParamGroupSettings = (
5023 getattr(AHFESettings, AHFEParamGroupName) if hasattr(AHFESettings, AHFEParamGroupName) else None
5024 )
5025 if AHFEParamGroupSettings is not None and hasattr(AHFEParamGroupSettings, AHFEParamName):
5026 ParamsInfo[ParamName] = getattr(AHFEParamGroupSettings, AHFEParamName)
5027 else:
5028 MiscUtil.PrintInfo(
5029 'The OpenFE AHFE parameter name, %s, for settings, %s, corresponding to AHFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
5030 % (AHFEParamName, AHFEParamGroupName, ParamName, ParamsOptionName)
5031 )
5032
5033 return ParamsInfo
5034
5035
5036 def _SetupMapForAbsoluteHydrationFreeEnergyParameters():
5037 """Map relative free energy option paramater names to OpenFE absolute
5038 hydration free energy settings.
5039 """
5040
5041 AHFEParametersMap = {
5042 "ProtocolRepeats": [None, "protocol_repeats"],
5043 "IntegratorBarostatFrequency": ["integrator_settings", "barostat_frequency"],
5044 "IntegratorConstraintTolerance": ["integrator_settings", "constraint_tolerance"],
5045 "IntegratorLangevinCollisionRate": ["integrator_settings", "langevin_collision_rate"],
5046 "IntegratorNRestartAttempts": ["integrator_settings", "n_restart_attempts"],
5047 "IntegratorReassignVelocities": ["integrator_settings", "reassign_velocities"],
5048 "IntegratorRemoveCom": ["integrator_settings", "remove_com"],
5049 "IntegratorTimestep": ["integrator_settings", "timestep"],
5050 "LambdaElec": ["lambda_settings", "lambda_elec"],
5051 "LambdaRestraints": ["lambda_settings", "lambda_restraints"],
5052 "LambdaVdw": ["lambda_settings", "lambda_vdw"],
5053 "PartialChargeNaglModel": ["partial_charge_settings", "nagl_model"],
5054 "PartialChargeNumberOfConformers": ["partial_charge_settings", "number_of_conformers"],
5055 "PartialChargeOffToolkitBackend": ["partial_charge_settings", "off_toolkit_backend"],
5056 "PartialChargeMethod": ["partial_charge_settings", "partial_charge_method"],
5057 "SolvationBoxShape": ["solvation_settings", "box_shape"],
5058 "SolvationBoxSize": ["solvation_settings", "box_size"],
5059 "SolvationSolventModel": ["solvation_settings", "solvent_model"],
5060 "SolvationSolventPadding": ["solvation_settings", "solvent_padding"],
5061 "SolventEngineComputePlatform": ["solvent_engine_settings", "compute_platform"],
5062 "SolventEngineGpuDeviceIndex": ["solvent_engine_settings", "gpu_device_index"],
5063 "SolventEquilOutputCheckpointInterval": ["solvent_equil_output_settings", "checkpoint_interval"],
5064 "SolventEquilOutputCheckpointStorageFilename": ["solvent_equil_output_settings", "checkpoint_storage_filename"],
5065 "SolventEquilOutputNPTStructure": ["solvent_equil_output_settings", "equil_npt_structure"],
5066 "SolventEquilOutputNVTStructure": ["solvent_equil_output_settings", "equil_nvt_structure"],
5067 "SolventEquilOutputForcefieldCache": ["solvent_equil_output_settings", "forcefield_cache"],
5068 "SolventEquilOutputLogOutput": ["solvent_equil_output_settings", "log_output"],
5069 "SolventEquilOutputMinimizedStructure": ["solvent_equil_output_settings", "minimized_structure"],
5070 "SolventEquilOutputIndices": ["solvent_equil_output_settings", "output_indices"],
5071 "SolventEquilOutputPreminimizedStructure": ["solvent_equil_output_settings", "preminimized_structure"],
5072 "SolventEquilOutputProductionTrajectoryFilename": [
5073 "solvent_equil_output_settings",
5074 "production_trajectory_filename",
5075 ],
5076 "SolventEquilOutputTrajectoryWriteInterval": ["solvent_equil_output_settings", "trajectory_write_interval"],
5077 "SolventEquilSimulationEquilLength": ["solvent_equil_simulation_settings", "equilibration_length"],
5078 "SolventEquilSimulationEquiLengthNVT": ["solvent_equil_simulation_settings", "equilibration_length_nvt"],
5079 "SolventEquilSimulationMinimizationSteps": ["solvent_equil_simulation_settings", "minimization_steps"],
5080 "SolventEquilSimulationProductionLength": ["solvent_equil_simulation_settings", "production_length"],
5081 "SolventForcefieldConstraints": ["solvent_forcefield_settings", "constraints"],
5082 "SolventForcefields": ["solvent_forcefield_settings", "forcefields"],
5083 "SolventForcefieldHydrogenMass": ["solvent_forcefield_settings", "hydrogen_mass"],
5084 "SolventForcefieldNonbondedCutoff": ["solvent_forcefield_settings", "nonbonded_cutoff"],
5085 "SolventForcefieldNonbondedMethod": ["solvent_forcefield_settings", "nonbonded_method"],
5086 "SolventForcefieldRigidWater": ["solvent_forcefield_settings", "rigid_water"],
5087 "SolventForcefieldSmallMoleculeForcefield": ["solvent_forcefield_settings", "small_molecule_forcefield"],
5088 "SolventOutputCheckpointInterval": ["solvent_output_settings", "checkpoint_interval"],
5089 "SolventOutputCheckpointStorageFilename": ["solvent_output_settings", "checkpoint_storage_filename"],
5090 "SolventOutputForcefieldCache": ["solvent_output_settings", "forcefield_cache"],
5091 "SolventOutputFilename": ["solvent_output_settings", "output_filename"],
5092 "SolventOutputIndices": ["solvent_output_settings", "output_indices"],
5093 "SolventOutputStructure": ["solvent_output_settings", "output_structure"],
5094 "SolventOutputPositionsWriteFrequency": ["solvent_output_settings", "positions_write_frequency"],
5095 "SolventOutputVelocitiesWriteFrequency": ["solvent_output_settings", "velocities_write_frequency"],
5096 "SolventSimulationEarlyTerminationTargetError": [
5097 "solvent_simulation_settings",
5098 "early_termination_target_error",
5099 ],
5100 "SolventSimulationEquilibrationLength": ["solvent_simulation_settings", "equilibration_length"],
5101 "SolventSimulationMinimizationSteps": ["solvent_simulation_settings", "minimization_steps"],
5102 "SolventSimulationNReplicas": ["solvent_simulation_settings", "n_replicas"],
5103 "SolventSimulationProductionLength": ["solvent_simulation_settings", "production_length"],
5104 "SolventSimulationRealTimeAnalysisInterval": ["solvent_simulation_settings", "real_time_analysis_interval"],
5105 "SolventSimulationRealTimeAnalysisMinimumTime": [
5106 "solvent_simulation_settings",
5107 "real_time_analysis_minimum_time",
5108 ],
5109 "SolventSimulationSamplerMethod": ["solvent_simulation_settings", "sampler_method"],
5110 "SolventSimulationSamsFlatnessCriteria": ["solvent_simulation_settings", "sams_flatness_criteria"],
5111 "SolventSimulationsamsGamma0": ["solvent_simulation_settings", "sams_gamma0"],
5112 "SolventSimulationTimePerIteration": ["solvent_simulation_settings", "time_per_iteration"],
5113 "ThermoPh": ["thermo_settings", "ph"],
5114 "ThermoPressure": ["thermo_settings", "pressure"],
5115 "ThermoRedoxPotential": ["thermo_settings", "redox_potential"],
5116 "ThermoTemperature": ["thermo_settings", "temperature"],
5117 "VacuumEngineComputePlatform": ["vacuum_engine_settings", "compute_platform"],
5118 "VacuumEngineGpuDeviceIndex": ["vacuum_engine_settings", "gpu_device_index"],
5119 "VacuumEquilOutputCheckpointInterval": ["vacuum_equil_output_settings", "checkpoint_interval"],
5120 "VacuumEquilOutputCheckpointStorageFilename": ["vacuum_equil_output_settings", "checkpoint_storage_filename"],
5121 "VacuumEquilOutputNPTStructure": ["vacuum_equil_output_settings", "equil_npt_structure"],
5122 "VacuumEquilOutputNVTStructure": ["vacuum_equil_output_settings", "equil_nvt_structure"],
5123 "VacuumEquilOutputForcefieldCache": ["vacuum_equil_output_settings", "forcefield_cache"],
5124 "VacuumEquilOutputLogOutput": ["vacuum_equil_output_settings", "log_output"],
5125 "VacuumEquilOutputMinimizedStructure": ["vacuum_equil_output_settings", "minimized_structure"],
5126 "VacuumEquilOutputIndices": ["vacuum_equil_output_settings", "output_indices"],
5127 "VacuumEquilOutputPreminimizedStructure": ["vacuum_equil_output_settings", "preminimized_structure"],
5128 "VacuumEquilOutputProductionTrajectoryFilename": [
5129 "vacuum_equil_output_settings",
5130 "production_trajectory_filename",
5131 ],
5132 "VacuumEquilOutputTrajectoryWriteInterval": ["vacuum_equil_output_settings", "trajectory_write_interval"],
5133 "VacuumEquilSimulationEquilLength": ["vacuum_equil_simulation_settings", "equilibration_length"],
5134 "VacuumEquilSimulationEquilLengthNVT": ["vacuum_equil_simulation_settings", "equilibration_length_nvt"],
5135 "VacuumEquilSimulationMinimizationSteps": ["vacuum_equil_simulation_settings", "minimization_steps"],
5136 "VacuumEquilSimulationProductionLength": ["vacuum_equil_simulation_settings", "production_length"],
5137 "VacuumForcefieldConstraints": ["vacuum_forcefield_settings", "constraints"],
5138 "VacuumForcefields": ["vacuum_forcefield_settings", "forcefields"],
5139 "VacuumForcefieldHydrogenMass": ["vacuum_forcefield_settings", "hydrogen_mass"],
5140 "VacuumForcefieldNonbondedCutoff": ["vacuum_forcefield_settings", "nonbonded_cutoff"],
5141 "VacuumForcefieldNonbondedMethod": ["vacuum_forcefield_settings", "nonbonded_method"],
5142 "VacuumForcefieldRigidWater": ["vacuum_forcefield_settings", "rigid_water"],
5143 "VacuumForcefieldSmallMoleculeForcefield": ["vacuum_forcefield_settings", "small_molecule_forcefield"],
5144 "VacuumOutputCheckpointInterval": ["vacuum_output_settings", "checkpoint_interval"],
5145 "VacuumOutputCheckpointStorageFilename": ["vacuum_output_settings", "checkpoint_storage_filename"],
5146 "VacuumOutputForcefieldCache": ["vacuum_output_settings", "forcefield_cache"],
5147 "VacuumOutputFilename": ["vacuum_output_settings", "output_filename"],
5148 "VacuumOutputIndices": ["vacuum_output_settings", "output_indices"],
5149 "VacuumOutputStructure": ["vacuum_output_settings", "output_structure"],
5150 "VacuumOutputPositionsWriteFrequency": ["vacuum_output_settings", "positions_write_frequency"],
5151 "VacuumOutputVelocitiesWriteFrequency": ["vacuum_output_settings", "velocities_write_frequency"],
5152 "VacuumSimulationEarlyTerminationTargetError": ["vacuum_simulation_settings", "early_termination_target_error"],
5153 "VacuumSimulationEquilibrationLength": ["vacuum_simulation_settings", "equilibration_length"],
5154 "VacuumSimulationMinimizationSteps": ["vacuum_simulation_settings", "minimization_steps"],
5155 "VacuumSimulationNReplicas": ["vacuum_simulation_settings", "n_replicas"],
5156 "VacuumSimulationProductionLength": ["vacuum_simulation_settings", "production_length"],
5157 "VacuumSimulationRealTimeAnalysisInterval": ["vacuum_simulation_settings", "real_time_analysis_interval"],
5158 "VacuumSimulationRealTimeAnalysisMinimumTime": [
5159 "vacuum_simulation_settings",
5160 "real_time_analysis_minimum_time",
5161 ],
5162 "VacuumSimulationSamplerMethod": ["vacuum_simulation_settings", "sampler_method"],
5163 "VacuumSimulationSamsFlatnessCriteria": ["vacuum_simulation_settings", "sams_flatness_criteria"],
5164 "VacuumSimulationSamsGamma0": ["vacuum_simulation_settings", "sams_gamma0"],
5165 "VacuumSimulationTimePerIteration": ["vacuum_simulation_settings", "time_per_iteration"],
5166 }
5167
5168 return AHFEParametersMap
5169
5170
5171 def SetupAbsoluteBindingFreeEnergySettings(ParamsOptionName, ParamsInfo):
5172 """Setup absolute binding free energy protocol settings to calculate ABFE.
5173
5174 The ParamsInfo is a comma delimited list of parameter name and value pairs
5175 returned by ProcessOptionOpenFEAbsoluteBindingFreeEnergyParameters().
5176
5177 Arguments:
5178 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
5179 ParamsInfo (dict): Parameter name and value pairs.
5180
5181 Returns:
5182 object: OpenFE AbsoluteBindingProtocol settings object.
5183
5184 """
5185
5186 from openfe.protocols.openmm_afe import AbsoluteBindingProtocol
5187
5188 ABFESettings = AbsoluteBindingProtocol.default_settings()
5189 ABFEParametersMap = _SetupMapForAbsoluteBindingFreeEnergyParameters()
5190
5191 _UpdateOpenFESettings("ABFE", ParamsOptionName, ParamsInfo, ABFESettings, ABFEParametersMap)
5192
5193 return ABFESettings
5194
5195
5196 def ProcessOptionOpenFEAbsoluteBindingFreeEnergyParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
5197 """Process parameters for ABFE parameters option and return a map
5198 containing processed parameter names and values.
5199
5200 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
5201 to setup ABFE calculations.
5202
5203 The default values are automatically updated to match settings provided by
5204 OpenFE module AbsoluteBindingProtocol.
5205
5206 You must specify valid OpenFE values for these parameters. An extensive
5207 validation is not performed.
5208
5209 The supported parameter names along with their default and possible
5210 values are shown below:
5211
5212 protocolRepeats, 3
5213
5214 Complex equil output settings:
5215
5216 complexEquilOutputCheckpointInterval, 1 [ Units: nanosecond ]
5217 complexEquilOutputCheckpointStorageFilename, checkpoint.chk
5218 complexEquilOutputEquilNPTStructure, equil_npt_structure.pdb
5219 complexEquilOutputEquilNVTstructure, equil_nvt_structure.pdb
5220 complexEquilOutputForcefieldCache, db.json
5221 complexEquilOutputLogOutput, production_equil_simulation.log
5222 complexEquilOutputMinimizedStructure, minimized.pdb
5223 complexEquilOutputIndices, all [ Possible value: Any valid
5224 selection. ]
5225 complexEquilOutputPremnimizedStructure, system.pdb
5226 complexEquilOutputProductionTrajectoryFilename, production_equil.xtc
5227 complexEquilOutputTrajectoryWriteInterval, 20.0 [ Units:
5228 picosecond ]
5229
5230 Complex equil simulation settings:
5231
5232 complexEquilSimulationEquilibrationLength, 0.5 [ Units: nanosecond ]
5233 complexEquilSimulationEquilibrationLengthNVT, 0.25 [ Units:
5234 nanosecond ]
5235 complexEquilSimulationMinimizationSteps, 5000
5236 complexEquilSimulationProductionLength, 5.0 [ Units: nanosecond ]
5237
5238 Complex lambda settings:
5239
5240 complexLambdaElec, 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6
5241 0.7 0.8 0.9 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
5242 1.0 1.0 [ Possible values: A space delimited list of values
5243 between 0.0 and 1.0 ]
5244 complexLambdaRestraints, 0.0 0.2 0.4 0.6 0.8 1.0 1.0 1.0 1.0 1.0
5245 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
5246 1.0 1.0 1.0 1.0 [ Possible values: A space delimited list of
5247 values between 0.0 and 1.0 ]
5248 complexLambdaVdw, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
5249 0.0 0.0 0.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.65 0.7 0.75 0.8 0.85
5250 0.9 0.95 1.0 [ Possible values: A space delimited list of values
5251 between 0.0 and 1.0 ]
5252
5253 Complex output settings:
5254
5255 complexOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
5256 complexOutputCheckpointStorageFilename, complex_checkpoint.nc
5257 complexOutputForcefieldCache, db.json
5258 complexOutputFilename, complex.nc
5259 complexOutputIndices, not water [ Possible value: Any valid
5260 selection. ]
5261 complexOutputStructure, alchemical_system.pdb
5262 complexOutputPositionsWriteFrequency, 100 [ Units: picosecond ]
5263 complexOutputVelocitiesWriteFrequency, None [ Possible
5264 values: > 0; Units: picosecond ]
5265
5266 Complex simulation settings:
5267
5268 complexSimulationEarlyTerminationTargetError, 0.0 [ Units:
5269 kilocalorie_per_mole ]
5270 complexSimulationEquilibrationLength, 1.0 [ Units: nanosecond ]
5271 complexSimulationMinimizationSteps, 5000
5272 complexSimulationNReplicas, 30
5273 complexSimulationProductionLength, 10.0 [ Units: nanosecond ]
5274 complexSimulationRealTimeAnalysisInterval, 250.0 [ Units:
5275 picosecond ]
5276 complexSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units:
5277 picosecond ]
5278 complexSimulationSamplerMethod, repex [ Possible values: repex,
5279 sams, or independent ]
5280 complexSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
5281 values: logZ-flatness, minimum-visits or histogram-flatness ]
5282 complexSimulationSamsGamma0, 1.0
5283 complexSimulationTimePerIteration, 2.5 [ Units: picosecond ]
5284
5285 Complex solvation settings:
5286
5287 complexSolvationBoxShape, dodecahedron [ Possible values: cube,
5288 dodecahedron, or octahedron ]
5289 complexSolvationBoxSize, None [ Possible value: A triplet of space
5290 X Y Z values; Units: nanometer ]
5291 complexSolvationSolventModel, tip3p [ Possible values: tip3p, spce,
5292 tip4pew, or tip5p ]
5293 complexSolvationSolventPadding, 1.0 [ Units: nanometer ]
5294
5295 Engine settings:
5296
5297 engineComputePlatform, CPU [ Possible values: CPU, CUDA,
5298 OpenCL, or Reference ]
5299 engineGpuDeviceIndex, None [ Possible values: 0, 0 1, etc. ]
5300
5301 Forcefield settings:
5302
5303 forcefieldConstraints, HBonds [ Possible values: HBonds,
5304 AllBonds, or HAngles ]
5305 forcefields, amber/ff14SB.xml amber/tip3p_standard.xml
5306 amber/tip3p_HFE_multivalent.xml amber/phosaa10.xml
5307 [ Possible values: A space delimited list of valid names. ]
5308 forcefieldHydrogenMass, 3.0 [ Units: amu ]
5309 forcefieldNonbondedCutoff, 0.9 [ Units: nanometer ]
5310 forcefieldNonbondedMethod, PME [ Possible values: PME or
5311 NoCutoff ]
5312 forcefieldRigidWater, yes, [ Possible values: yes or no ]
5313 forcefieldSmallMoleculeForcefield, openff-2.1.1 [ Possible
5314 value: A valid forcefield name. ]
5315
5316 Integrator settings:
5317
5318 integratorBarostatFrequency, 25.0 * timestep [ The specified value
5319 is a multiple of integratorTimestep. ]
5320 integratorConstraintTolerance, 1e-06
5321 integratorLangevinCollisionRate, 1.0 [ Units: 1 / picosecond ]
5322 integratorNRestartAttempts, 20
5323 integratorReassignVelocities, no [ Possible values: yes or no ]
5324 integratorRemoveCom, no [ Possible values: yes or no ]
5325 integratorTimestep, 4.0 [ Units: femtosecond ]
5326
5327 Partial charge settings:
5328
5329 partialChargeNaglModel, None [ Default: Production AM1BCC model for
5330 NAGL; Possible value: Any valid name. ]
5331 partialChargeNumberOfConformers, None [ Possible value: > 0 ]
5332 partialChargeOffToolkitBackend, AmberTools [ Possible values:
5333 AmberTools or RDKit ]
5334 partialChargeMethod, AM1BCC [ Possble values: AM1BCC, Espaloma,
5335 or NAGL ]
5336
5337 Restraint settings:
5338
5339 restraintKPhiA, 334.72 [ Units: kilojoule_per_mole / radian**2
5340 The default value is equivalent to 80 kcal/mol/radian**2 ]
5341 restraintKPhiB, 334.72 [ Units: kilojoule_per_mole / radian**2 ]
5342 The default value is equivalent to 80 kcal/mol/radian**2 ]
5343 restraintKPhiC, 334.72 [ Units: kilojoule_per_mole / radian**2 ]
5344 The default value is equivalent to 80 kcal/mo/radian**2 ]
5345 restraintKR, 4184.0 [ Units: kilojoule_per_molel / nanometer**2
5346 The default value is equivalent to 10 kcal/mol/angstrom**2
5347 restraintKThetaA, 334.72 [ Units: kilojoule_per_mole / radian**2 ]
5348 The default value is equivalent to 80 kcal/mol/radian**2 ]
5349 restraintKThetaB, 334.72 [ Units: kilojoule_per_mole / radian**2
5350 The default value is equivalent to 80 kcal/mol/radian**2 ]
5351 restraintAnchorFindingStrategy, bonded [ Possible values:
5352 multi-residue or bonded ]
5353 restraintDsspFilter, yes [ Possible values: yes or no ]
5354 restraintHostMaxDistance, 1.5 [ Units: nanometer ]
5355 restraintHostMinDistance, 0.5 [ Units: nanometer ]
5356 restraintHostSelection, backbone [ Possible value: Any valid
5357 selection. ]
5358 restraintRmsfCutoff, 0.1 [ Units: nanometer ]
5359
5360 Solvent equil output settings:
5361
5362 solventEquilOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
5363 solventEquilOutputCheckpointStorageFilename, checkpoint.chk
5364 solventEquilEquilOutputNPTStructure, equil_npt_structure.pdb
5365 solventEquilEquilNVTOutputStructure, equil_nvt_structure.pdb
5366 solventEquilOutputForcefieldCache, db.json
5367 solventEquilOutputLogOutput, production_equil_simulation.log
5368 solventEquilOutputMinimizedStructure, minimized.pdb
5369 solventEquilOutputIndices, all [ Possible value: Any valid
5370 selection. ]
5371 solventEquilOutputPreminimizedStructure, system.pdb
5372 solventEquilOutputProductionTrajectoryFilename, production_equil.xtc
5373 solventEquilOutputTrajectoryWriteInterval, 20.0 [ Units:
5374 picosecond ]
5375
5376 Solvent_equil_simulation_settings:
5377
5378 solventEquilSimulationEquilibrationLength, 0.2 [ Units: nanosecond ]
5379 solventEquilSimulationEquilibrationLengthNVT, 0.1 [ Units:
5380 nanosecond ]
5381 solventEquilSimulationMinimizationSteps, 5000
5382 solventEquilSimulationProductionLength, 0.5 [ Units: nanosecond ]
5383
5384 Solvent lambda settings:
5385
5386 solventLambdaElec, 0.0 0.25 0.5 0.75 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
5387 1.0 1.0 [ Possible values: A space delimited list of values
5388 between 0.0 and 1.0 ]
5389 solventLambdaRestraints, 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
5390 0.0 0.0 0.0 [ Possible values: A space delimited list of values
5391 between 0.0 and 1.0 ]
5392 solventLambdaVdw, 0.0 0.0 0.0 0.0 0.0 0.12 0.24 0.36 0.48 0.6 0.7
5393 0.77 0.85 1.0 [ Possible values: A space delimited list of values
5394 between 0.0 and 1.0 ]
5395
5396 Solvent output settings:
5397
5398 solventOutputCheckpointInterval, 1.0 [ Units: nanosecond ]
5399 solventOutputCheckpointStorageFilename, solvent_checkpoint.nc
5400 solventOutputForcefieldCache, db.json
5401 solventOutputFilename, solvent.nc
5402 solventOutputIndices, not water [ Possible value: Any valid
5403 selection. ]
5404 solventOutputStructure, alchemical_system.pdb
5405 solventOutputPositionsWriteFrequency, 100.0 [ Units: picosecond ]
5406 solventOutputVelocitiesWriteFrequency, None [ Possible
5407 values: > 0; Units: picosecond ]
5408
5409 Solvent simulation settings:
5410
5411 solventSimulationEarlyTerminationTargetError, 0.0 [ Units:
5412 kilocalorie_per_mole ]
5413 solventSimulationEquilibrationLength, 1.0 [ Units: nanosecond ]
5414 solventSimulationMinimizationSteps, 5000
5415 solventSimulationNReplicas, 14
5416 solventSimulationProductionLength, 10.0 [ Units: nanosecond ]
5417 solventSimulationRealTimeAnalysisInterval, 250.0 [ Unit: picosecond ]
5418 solventSimulationRealTimeAnalysisMinimumTime, 500.0 [ Units:
5419 picosecond ]
5420 solventSimulationSamplerMethod, repex [ Possible values: repex,
5421 sams, or independent ]
5422 solventSimulationSamsFlatnessCriteria, logZ-flatness [ Possible
5423 values: logZ-flatness, minimum-visits or histogram-flatness ]
5424 solventSimulationSamsGamma0, 1.0
5425 solventSimulationTimePerIteration, 2.5 [ Units: picosecond ]
5426
5427 Solvent solvation settings:
5428
5429 solventSolvationBoxShape, dodecahedron [ Possible values: cube,
5430 dodecahedron, or octahedron ]
5431 solventSolvationBoxSize, None [ Possible value: A triplet of space
5432 X Y Z values; Units: nanometer ]
5433 solventSolvationSolventModel, tip3p [ Possible values: tip3p, spce,
5434 tip4pew, or tip5p ]
5435 solventSolvationSolventPadding, 1.5 [ Units: nanometer ]
5436
5437 Thermo settings:
5438
5439 thermoPh, None [ Possible values: > 0 ]
5440 thermoPressure, 1.0 [ Units: bar ]
5441 thermoRedoxPotential, None [ Possible values: A valid float.
5442 Units: millivolts (mV) ]
5443 thermoTemperature, 298.15 [ Units: kelvin ]
5444
5445 A brief description of parameters, taken from OpenFE documentation, is
5446 provided below:
5447
5448 protocolRepeats: Number of completely independent repeats of the
5449 entire sampling process.
5450
5451 Complex settings:
5452
5453 Complex parameters for the system, including the solvent model and
5454 the solvent padding.
5455
5456 Complex equil output settings:
5457
5458 Parameters controlling simulation output during equilibration
5459 phase of complex transformation.
5460
5461 complexEquilOutputCheckpointInterval: Frequency to write the
5462 checkpoint file.
5463 complexEquilOutputCheckpointStorageFilename: Checkpoint filename.
5464 complexEquilOutputEquilNPTStructure: NPT structure filename.
5465 complexEquilOutputEquilNVTstructure: NVT strucure filename.
5466 complexEquilOutputForcefieldCache: Filename for caching small
5467 molecule residue templates.
5468 complexEquilOutputLogOutput: Simulation log filename.
5469 complexEquilOutputMinimizedStructure: Minimized structire filename.
5470 complexEquilOutputIndices: Selection string for selecting
5471 coordinates to write.
5472 complexEquilOutputPremnimizedStructure: Initial structure filename.
5473 complexEquilOutputProductionTrajectoryFilename: Trajectory filename.
5474 complexEquilOutputTrajectoryWriteInterval: Frequency for writing
5475 velocities to trajectory file.
5476
5477 Complex equil simulation settings:
5478
5479 Parameters controlling simulation during equilibration phase of
5480 complex transformation.
5481
5482 complexEquilSimulationEquilibrationLength: Length of the NPT
5483 equilibration phase.
5484 complexEquilSimulationEquilibrationLengthNVT: Length of the NVT
5485 equilibration phase.
5486 complexEquilSimulationMinimizationSteps: Maximum number of
5487 minimization steps to perform.
5488 complexEquilSimulationProductionLength: Length of the NPT
5489 production phase.
5490
5491 Complex lambda settings:
5492
5493 Lambda protocol parameters for complex transformation.
5494
5495 complexLambdaElec: List of lambda values for electrostatics. The
5496 values of 0 and 1 imply state A and state B respectively.
5497 complexLambdaRestraints: List of lambda values for restraints. The
5498 values of 0 and 1 imply state A and state B respectively.
5499 complexLambdaVdw: List of lamda values for van der Waals. The
5500 values of of 0 and 1 imply state A and state B respectively.
5501
5502 Complex output settings:
5503
5504 Parameters controlling simulation output during final phase of
5505 complex transformation.
5506
5507 complexOutputCheckpointInterval: Frequency to write the checkpoint
5508 file.
5509 complexOutputCheckpointStorageFilename: Checkpoint filename.
5510 complexOutputForcefieldCache: Filename for caching small molecule
5511 residue templates.
5512 complexOutputFilename: Trajectory filename.
5513 complexOutputIndices: Selection string for selecting coordinates to
5514 write.
5515 complexOutputStructure: Topology structure filename.
5516 complexOutputPositionsWriteFrequency: Frequency for writing
5517 positions to trajectory file.
5518 complexOutputVelocitiesWriteFrequency: Frequency for writing
5519 velocities to trajectory file.
5520
5521 Complex simulation settings:
5522
5523 Parameters controlling simulation during final phase of complex
5524 transformation.
5525
5526 complexSimulationEarlyTerminationTargetError: Target error for the
5527 real time analysis measured in kcal/mol. Once the MBAR error of
5528 the free energy is at or below this value, the simulation will
5529 be considered complete. The suggested value of 0.12 has shown to
5530 be effective in both hydration and binding free energy
5531 benchmarks.
5532 complexSimulationEquilibrationLength: Length of the equilibration
5533 phase. The specified value must be divisible by
5534 'integratorTimestep'.
5535 complexSimulationMinimizationSteps: Maximum number of minimization
5536 steps to perform.
5537 complexSimulationNReplicas: Number of replicas to use.
5538 complexSimulationProductionLength: Length of the production phase.
5539 The specified value must be divisible by 'integratorTimestep'.
5540 complexSimulationRealTimeAnalysisMinimumTime: Time interval for
5541 performing analysis of the free energies. At each interval, real
5542 time analysis data will be written to a yaml file named
5543 <outputFileName>_real_time_analysis.yaml. The current error
5544 in the estimate will also be assessed and the simulation will
5545 be terminated when it drops below
5546 'complexSimulationEarlyTerminationTargetError'.
5547 complexSimulationSamplerMethod: Alchemical sampling method to use:
5548 REPEX (Hamiltonian REPlica EXchange), SAMS (Self-Adjusted
5549 Mixture Sampling), or Independent (Independently sampled lambda
5550 windows).
5551 complexSimulationSamsFlatnessCriteria:Method for assessing when to
5552 switch to asymptomatically optimal scheme for SAMS.
5553 complexSimulationsamsGamma0: Initial weight adaptation rate for
5554 SAMS.
5555 complexSimulationTimePerIteration: Simulation time between each
5556 MCMC move attempt
5557
5558 Complex solvation settings:
5559
5560 Solvation parameters for the system, including the solvent model and
5561 the solvent padding.
5562
5563 complexSolvationBoxShape: Shape of the periodic solvent box.
5564 complexSolvationBoxSize: Lengths of the unit cell for a solvent box.
5565 complexSolvationSolventModel: Forcefield water model to use during
5566 solvation and defining the model properties.
5567 complexSolvationSolventPadding: Minimum distance from any solute
5568 bounding sphere to the edge of the box.
5569
5570 Engine settings:
5571
5572 Parameters configuring the compute platform used by the OpenMM to
5573 perform the simulation.
5574
5575 engineComputePlatform: Platform to use for running OpenMM MD
5576 calculations.
5577 engineGpuDeviceIndex: Space delimited list of device indices
5578 to use for running OpenMM MD calculations.
5579
5580 Forcefield settings:
5581
5582 forcefieldConstraints:Constraints to use.
5583 forcefields: List of valid forcefield paths for all components
5584 except small molecules.
5585 forcefieldHydrogenMass: Mass to be repartitioned to hydrogens
5586 from neighboring heavy atoms.
5587 forcefieldNonbondedCutoff: Cutoff for short range nonbonded
5588 interactions.
5589 forcefieldNonbondedMethod: Method for treating nonbonded
5590 interactions.
5591 forcefieldRigidWater: Use a rigid water model.
5592 forcefieldSmallMoleculeForcefield: A valid forcefield name to use
5593 for small molecules.
5594
5595 Integrator settings:
5596
5597 Parameters controlling the LangevinSplittingDynamicsMove integrator
5598 used for simulation.
5599
5600 integratorBarostatFrequency: Frequency at which volume scaling
5601 changes should be attempted.
5602 integratorConstraintTolerance: Tolerance for constraint solver.
5603 integratorLangevinCollisionRate: Collision frequency.
5604 integratorNRestartAttempts: Number of attempts to restart from
5605 Context in case there are NaNs in the energies after
5606 integration.
5607 integratorReassignVelocities: Reassign velocities from the
5608 Maxwell-Boltzmann distribution at the beginning of each
5609 Monte Carlo move.
5610 integratorRemoveCom: Remove the center of mass motion.
5611 integratorTimestep: Size of the simulation timestep.
5612
5613 Partial charge settings:
5614
5615 Parameters for automatically assigning missing partial charges to
5616 small molecules, including the partial charge method.
5617
5618 partialChargeNaglModel: Model to use for partial charge assignment.
5619 A value of None implies the use of the latest available
5620 production AM1BCC model.
5621 partialChargeNumberOfConformers: Number of conformers to generate
5622 as part of the partial charge assignment. A value of None
5623 implies the use of the existing conformer.
5624 partialChargeOffToolkitBackend: OpenFF toolkit registry backend to
5625 use for calculating partial charges.
5626 partialChargeMethod: Method to use for calculating partial charges.
5627
5628 Restraint settings:
5629
5630 Parameters to configure Boresch-style restraint between two groups
5631 of atoms named host (Hx) and guest (Gx).
5632
5633 restraintKPhiA: Equilibrium force constant for the dihedral formed
5634 by H2-H1-H0-G0.
5635 restraintKPhiB: Equilibrium force constant for the dihedral formed
5636 by H1-H0-G0-G1.
5637 restraintKPhiC: Equilibrium force constant for the dihedral formed
5638 by H0-G0-G1-G2.
5639 restraintKR: Bond spring constant between H0 and G0.
5640 restraintKThetaA: Spring constant for the angle formed by H1-H0-G0.
5641 restraintKThetaB: Spring constant for the angle formed by H0-G0-G1
5642 restraintAnchorFindingStrategy: Boresch atom picking strategy to
5643 use. bonded: pick host atoms that are bonded to each other.
5644 multi-residue: pick host atoms which can span multiple
5645 residues.
5646 restraintDsspFilter: Apply DSSP filter to the host atoms.
5647 restraintHostMaxDistance: Minimum distance between any host atom
5648 and the guest G0 atom.
5649 restraintHostMinDistance: Xaximum distance between any host atom
5650 and the guest G0 atom
5651 restraintHostSelection: A valid selection string to sub-select the
5652 host atoms which will be involved in the restraint.
5653 restraintRmsfCutoff: Cutoff value for filtering atoms by their root
5654 mean square fluctuation. Atoms with values above this cutoff
5655 are ignored.
5656
5657 Solvent equil output settings:
5658 Solvent equil simulation settings:
5659 Solvent lambda settings:
5660 Solvent output settings:
5661 Solvent simulation settings:
5662 Solvent solvation settings:
5663
5664 The solvent settings are similar to the complex settings already
5665 described under various sections for complex. The prefix 'solvent'
5666 is used for the names of the pramaters instead of the prefix
5667 'complex.'
5668
5669 Thermo settings:
5670
5671 Thermodynamic parameters, including the temperature and the pressure
5672 of the system.
5673
5674 thermoPh: Simulation pH
5675 thermoPressure: Simulation pressure.
5676 thermoRedoxPotential:Simulation redox potential.
5677 thermoTemperature: Simulation temperature.
5678
5679 Arguments:
5680 ParamsOptionName (str): Command line OpenFE RFE parameters option name.
5681 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
5682 ParamsDefaultInfo (dict): Default values to override selected parameters.
5683
5684 Returns:
5685 dictionary: Processed parameter name and value pairs.
5686
5687 """
5688
5689 ParamsInfo = _SetupAbsoluteBindingFreeEnergyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue)
5690
5691 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
5692 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
5693 )
5694
5695 if re.match("^auto$", ParamsOptionValue, re.I):
5696 _ProcessOptionOpenFEAbsoluteBindingFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
5697 return ParamsInfo
5698
5699 for Index in range(0, len(ParamsOptionValueWords), 2):
5700 Name = ParamsOptionValueWords[Index].strip()
5701 Value = ParamsOptionValueWords[Index + 1].strip()
5702
5703 ParamName = CanonicalParamNamesMap[Name.lower()]
5704 ParamValue = Value
5705
5706 if re.match(
5707 "^(ProtocolRepeats|IntegratorNRestartAttempts|ComplexEquilSimulationMinimizationSteps|ComplexSimulationMinimizationSteps|ComplexSimulationNReplicas|IntegratorNRestartAttempts|PartialChargeNumberOfConformers|SolventEquilSimulationMinimizationSteps|SolventSimulationMinimizationSteps|SolventSimulationNReplicas)$",
5708 ParamName,
5709 re.I,
5710 ):
5711 # Int > 0
5712 if not MiscUtil.IsInteger(Value):
5713 MiscUtil.PrintError(
5714 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
5715 % (Value, ParamName, ParamsOptionName)
5716 )
5717 Value = int(Value)
5718 if Value <= 0:
5719 MiscUtil.PrintError(
5720 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5721 % (ParamValue, ParamName, ParamsOptionName)
5722 )
5723 ParamValue = Value
5724 elif re.match(
5725 "^(IntegratorConstraintTolerance|ComplexSimulationSamsGamma0|ForcefieldHydrogenMass|SolventSimulationSamsGamma0)$",
5726 ParamName,
5727 re.I,
5728 ):
5729 # float > 0
5730 if not MiscUtil.IsFloat(Value):
5731 MiscUtil.PrintError(
5732 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5733 % (Value, ParamName, ParamsOptionName)
5734 )
5735 Value = float(Value)
5736 if Value <= 0:
5737 MiscUtil.PrintError(
5738 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5739 % (ParamValue, ParamName, ParamsOptionName)
5740 )
5741 ParamValue = Value
5742 elif re.match(
5743 "^(ForcefieldRigidWater|IntegratorReassignVelocities|IntegratorRemoveCom|RestraintDsspFilter)$",
5744 ParamName,
5745 re.I,
5746 ):
5747 # bool
5748 if not re.match("^(yes|no|true|false)$", Value, re.I):
5749 MiscUtil.PrintError(
5750 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
5751 % (Value, Name, ParamsOptionName)
5752 )
5753 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
5754 elif re.match("^ThermoPh$", ParamName, re.I):
5755 # float > 0 or None
5756 if re.match("^None$", Value, re.I):
5757 ParamValue = None
5758 else:
5759 if not MiscUtil.IsFloat(Value):
5760 MiscUtil.PrintError(
5761 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5762 % (Value, ParamName, ParamsOptionName)
5763 )
5764 Value = float(Value)
5765 if Value <= 0:
5766 MiscUtil.PrintError(
5767 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5768 % (ParamValue, ParamName, ParamsOptionName)
5769 )
5770 ParamValue = Value
5771 elif re.match("^ThermoRedoxPotential$", ParamName, re.I):
5772 if re.match("^None$", Value, re.I):
5773 ParamValue = None
5774 else:
5775 if not MiscUtil.IsFloat(Value):
5776 MiscUtil.PrintError(
5777 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5778 % (Value, ParamName, ParamsOptionName)
5779 )
5780 Value = float(Value)
5781 ParamValue = Value * openff.units.unit.millivolts
5782 elif re.match("^IntegratorLangevinCollisionRate$", ParamName, re.I):
5783 if not MiscUtil.IsFloat(Value):
5784 MiscUtil.PrintError(
5785 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5786 % (Value, ParamName, ParamsOptionName)
5787 )
5788 Value = float(Value)
5789 if Value <= 0:
5790 MiscUtil.PrintError(
5791 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5792 % (ParamValue, ParamName, ParamsOptionName)
5793 )
5794 ParamValue = Value / openff.units.unit.picosecond
5795 elif re.match(
5796 "^(ComplexLambdaElec|ComplexLambdaRestraints|ComplexLambdaVdw|SolventLambdaElec|SolventLambdaRestraints|SolventLambdaVdw)$",
5797 ParamName,
5798 re.I,
5799 ):
5800 # List of float values between 0 and 1...
5801 Values = Value.split()
5802 if len(Values) == 0:
5803 MiscUtil.PrintError(
5804 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of space delimited values\n'
5805 % (Value, ParamName, ParamsOptionName)
5806 )
5807 for Value in Values:
5808 if not MiscUtil.IsFloat(Value):
5809 MiscUtil.PrintError(
5810 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5811 % (Value, ParamName, ParamsOptionName)
5812 )
5813 Value = float(Value)
5814 if Value < 0.0 or Value > 1.0:
5815 MiscUtil.PrintError(
5816 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not valid value. Supported values: 0.0 to 1.0\n'
5817 % (Value, ParamName, ParamsOptionName)
5818 )
5819 Values = [float(Value) for Value in Values]
5820 ParamValue = Values
5821 elif re.match("^IntegratorBarostatFrequency$", ParamName, re.I):
5822 if not MiscUtil.IsFloat(Value):
5823 MiscUtil.PrintError(
5824 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5825 % (Value, ParamName, ParamsOptionName)
5826 )
5827 Value = float(Value)
5828 if Value <= 0:
5829 MiscUtil.PrintError(
5830 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5831 % (ParamValue, ParamName, ParamsOptionName)
5832 )
5833 ParamValue = Value * openff.units.unit.timestep
5834 elif re.match("^IntegratorLangevinCollisionRate$", ParamName, re.I):
5835 if not MiscUtil.IsFloat(Value):
5836 MiscUtil.PrintError(
5837 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5838 % (Value, ParamName, ParamsOptionName)
5839 )
5840 Value = float(Value)
5841 if Value <= 0:
5842 MiscUtil.PrintError(
5843 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5844 % (ParamValue, ParamName, ParamsOptionName)
5845 )
5846 ParamValue = Value / openff.units.unit.picosecond
5847 elif re.match("^IntegratorTimestep$", ParamName, re.I):
5848 # float > 0 femtosecond
5849 if not MiscUtil.IsFloat(Value):
5850 MiscUtil.PrintError(
5851 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5852 % (Value, ParamName, ParamsOptionName)
5853 )
5854 Value = float(Value)
5855 if Value <= 0:
5856 MiscUtil.PrintError(
5857 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5858 % (ParamValue, ParamName, ParamsOptionName)
5859 )
5860 ParamValue = Value * openff.units.unit.femtosecond
5861 elif re.match(
5862 "^(ComplexEquilOutputTrajectoryWriteInterval|ComplexOutputPositionsWriteFrequency|ComplexSimulationRealTimeAnalysisInterval|ComplexSimulationRealTimeAnalysisMinimumTime|ComplexSimulationTimePerIteration|SolventEquilOutputTrajectoryWriteInterval|SolventOutputPositionsWriteFrequency|SolventSimulationRealTimeAnalysisInterval|SolventSimulationRealTimeAnalysisMinimumTime|SolventSimulationTimePerIteration)$",
5863 ParamName,
5864 re.I,
5865 ):
5866 # float > 0 picosecond
5867 if not MiscUtil.IsFloat(Value):
5868 MiscUtil.PrintError(
5869 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5870 % (Value, ParamName, ParamsOptionName)
5871 )
5872 Value = float(Value)
5873 if Value <= 0:
5874 MiscUtil.PrintError(
5875 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5876 % (ParamValue, ParamName, ParamsOptionName)
5877 )
5878 ParamValue = Value * openff.units.unit.picosecond
5879 elif re.match(
5880 "^(ComplexEquilOutputCheckpointInterval|ComplexEquilSimulationEquilibrationLength|ComplexEquilSimulationEquilibrationLengthNVT|ComplexEquilSimulationProductionLength|ComplexOutputCheckpointInterval|ComplexSimulationEquilibrationLength|ComplexSimulationProductionLength|SolventEquilOutputCheckpointInterval|SolventEquilSimulationEquilibrationLength|SolventEquilSimulationEquilibrationLengthNVT|SolventEquilSimulationProductionLength|SolventOutputCheckpointInterval|SolventSimulationEquilibrationLength|SolventSimulationProductionLength)$",
5881 ParamName,
5882 re.I,
5883 ):
5884 # float > 0 nanosecond
5885 if not MiscUtil.IsFloat(Value):
5886 MiscUtil.PrintError(
5887 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5888 % (Value, ParamName, ParamsOptionName)
5889 )
5890 Value = float(Value)
5891 if Value <= 0:
5892 MiscUtil.PrintError(
5893 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5894 % (ParamValue, ParamName, ParamsOptionName)
5895 )
5896 ParamValue = Value * openff.units.unit.nanosecond
5897 elif re.match(
5898 "^(ComplexOutputVelocitiesWriteFrequency|SolventOutputVelocitiesWriteFrequency)$", ParamName, re.I
5899 ):
5900 # float > 0 picosecond or none
5901 if re.match("^None$", Value, re.I):
5902 ParamValue = None
5903 else:
5904 if not MiscUtil.IsFloat(Value):
5905 MiscUtil.PrintError(
5906 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5907 % (Value, ParamName, ParamsOptionName)
5908 )
5909 Value = float(Value)
5910 if Value <= 0:
5911 MiscUtil.PrintError(
5912 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5913 % (ParamValue, ParamName, ParamsOptionName)
5914 )
5915 ParamValue = Value * openff.units.unit.picosecond
5916 elif re.match("^PartialChargeMethod$", ParamName, re.I):
5917 if not re.match("^(AM1BCC|AM1BCCELF10|Espaloma|NAGL)$", Value, re.I):
5918 MiscUtil.PrintError(
5919 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AM1BCC, AM1BCCELF10, Espaloma, or NAGL'
5920 % (Value, Name, ParamsOptionName)
5921 )
5922 ParamValue = Value.lower()
5923 elif re.match("^PartialChargeOffToolkitBackend$", ParamName, re.I):
5924 if not re.match("^(AmberTools|OpenEye|RDKit)$", Value, re.I):
5925 MiscUtil.PrintError(
5926 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AmberTools, OpenEye, or RDKit'
5927 % (Value, Name, ParamsOptionName)
5928 )
5929 ParamValue = Value.lower()
5930 elif re.match("^(ComplexSolvationBoxShape|SolventSolvationBoxShape)$", ParamName, re.I):
5931 if not re.match("^(cube|dodecahedron|octahedron)$", Value, re.I):
5932 MiscUtil.PrintError(
5933 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: cube, dodecahedron, or octahedron'
5934 % (Value, Name, ParamsOptionName)
5935 )
5936 ParamValue = Value.lower()
5937 elif re.match("^(ComplexSolvationBoxSize|SolventSolvationBoxSize)$", ParamName, re.I):
5938 # List of X, Y, Z values...
5939 if re.match("^None$", Value, re.I):
5940 ParamValue = None
5941 else:
5942 Values = Value.split()
5943 if len(Values) != 3:
5944 MiscUtil.PrintError(
5945 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a set of three space delimited values.\n'
5946 % (Value, ParamName, ParamsOptionName)
5947 )
5948 for Value in Values:
5949 if not MiscUtil.IsFloat(Value):
5950 MiscUtil.PrintError(
5951 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5952 % (Value, ParamName, ParamsOptionName)
5953 )
5954 Values = [float(Value) for Value in Values]
5955 ParamValue = Values * openff.units.unit.nanometer
5956 elif re.match("^(ComplexSolvationSolventModel|SolventSolvationSolventModel)$", ParamName, re.I):
5957 if not re.match("^(tip3p|spce|tip4pew|tip5p)$", Value, re.I):
5958 MiscUtil.PrintError(
5959 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: tip3p, spce, tip4pew, or tip5p'
5960 % (Value, Name, ParamsOptionName)
5961 )
5962 ParamValue = Value.lower()
5963 elif re.match("^EngineComputePlatform$", ParamName, re.I):
5964 if not re.match("^(CPU|CUDA|OpenCL|Reference)$", Value, re.I):
5965 MiscUtil.PrintError(
5966 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: CPU, CUDA, OpenCL, or Reference'
5967 % (Value, Name, ParamsOptionName)
5968 )
5969 ParamValue = Value
5970 elif re.match(
5971 "^(ForcefieldNonbondedCutoff|RestraintHostMaxDistance|RestraintHostMinDistance|RestraintRmsfCutoff)$",
5972 ParamName,
5973 re.I,
5974 ):
5975 # float > 0 and units nanometer
5976 if not MiscUtil.IsFloat(Value):
5977 MiscUtil.PrintError(
5978 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5979 % (Value, ParamName, ParamsOptionName)
5980 )
5981 Value = float(Value)
5982 if Value <= 0:
5983 MiscUtil.PrintError(
5984 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
5985 % (ParamValue, ParamName, ParamsOptionName)
5986 )
5987 ParamValue = Value * openff.units.unit.nanometer
5988 elif re.match("^(ComplexSolvationSolventPadding|SolventSolvationSolventPadding)$", ParamName, re.I):
5989 # float > 0 and units nanometer or none
5990 if re.match("^None$", Value, re.I):
5991 ParamValue = None
5992 else:
5993 if not MiscUtil.IsFloat(Value):
5994 MiscUtil.PrintError(
5995 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
5996 % (Value, ParamName, ParamsOptionName)
5997 )
5998 Value = float(Value)
5999 if Value <= 0:
6000 MiscUtil.PrintError(
6001 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6002 % (ParamValue, ParamName, ParamsOptionName)
6003 )
6004 ParamValue = Value * openff.units.unit.nanometer
6005 elif re.match("^EngineGpuDeviceIndex$", ParamName, re.I):
6006 # Comma delimited string values...
6007 DeviceIndices = Value.split()
6008 if len(DeviceIndices) == 0:
6009 MiscUtil.PrintError(
6010 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain space delimited list of device indices.\n'
6011 % (Value, ParamName, ParamsOptionName)
6012 )
6013 for DeviceIndex in DeviceIndices:
6014 if not MiscUtil.IsInteger(DeviceIndex):
6015 MiscUtil.PrintError(
6016 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
6017 % (DeviceIndex, ParamName, ParamsOptionName)
6018 )
6019 DeviceIndices = [int(DeviceIndex) for DeviceIndex in DeviceIndices]
6020 ParamValue = DeviceIndices
6021 elif re.match("^(ForcefieldConstraints)$", ParamName, re.I):
6022 if not re.match("^(HBonds|AllBonds|HAngles|None)$", Value, re.I):
6023 MiscUtil.PrintError(
6024 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: HBonds, AllBonds, HAngles, or None'
6025 % (Value, Name, ParamsOptionName)
6026 )
6027 ParamValue = None if re.match("^None$", Value, re.I) else Value.lower()
6028 elif re.match("^(Forcefields)$", ParamName, re.I):
6029 # List of string values.....
6030 Values = Value.split()
6031 if len(Values) == 0:
6032 MiscUtil.PrintError(
6033 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. It must contain a space delimited list of values..\n'
6034 % (Value, ParamName, ParamsOptionName)
6035 )
6036 ParamValue = Values
6037 elif re.match("^(ForcefieldNonbondedMethod)$", ParamName, re.I):
6038 if not re.match("^(PME|NoCutoff)$", Value, re.I):
6039 MiscUtil.PrintError(
6040 'The parameter value, %s, specified for parameter name, %s, using "%s" option is may be a valid OpenFE value. Supported values: PME or NoCutoff'
6041 % (Value, Name, ParamsOptionName)
6042 )
6043 ParamValue = Value.lower()
6044 elif re.match(
6045 "^(ComplexSimulationEarlyTerminationTargetError|SolventSimulationEarlyTerminationTargetError)$",
6046 ParamName,
6047 re.I,
6048 ):
6049 # float >= 0 units: kilocalorie_per_mole
6050 if not MiscUtil.IsFloat(Value):
6051 MiscUtil.PrintError(
6052 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6053 % (Value, ParamName, ParamsOptionName)
6054 )
6055 Value = float(Value)
6056 if Value < 0:
6057 MiscUtil.PrintError(
6058 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6059 % (ParamValue, ParamName, ParamsOptionName)
6060 )
6061 ParamValue = Value * openff.units.unit.kilocalorie_per_mole
6062 elif re.match(
6063 "^(RestraintKPhiA|RestraintKPhiB|RestraintKPhiC|RestraintKThetaA|RestraintKThetaB)$", ParamName, re.I
6064 ):
6065 # float > 0 units: kilojoule_per_mole / radian ** 2
6066 if not MiscUtil.IsFloat(Value):
6067 MiscUtil.PrintError(
6068 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6069 % (Value, ParamName, ParamsOptionName)
6070 )
6071 Value = float(Value)
6072 if Value <= 0:
6073 MiscUtil.PrintError(
6074 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6075 % (ParamValue, ParamName, ParamsOptionName)
6076 )
6077 ParamValue = Value * openff.units.unit.kilojoule_per_mole / openff.units.unit.radian**2
6078 elif re.match("^(RestraintKR)$", ParamName, re.I):
6079 # float > 0 units: kilojoule_per_mole / nanometer ** 2
6080 if not MiscUtil.IsFloat(Value):
6081 MiscUtil.PrintError(
6082 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6083 % (Value, ParamName, ParamsOptionName)
6084 )
6085 Value = float(Value)
6086 if Value <= 0:
6087 MiscUtil.PrintError(
6088 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6089 % (ParamValue, ParamName, ParamsOptionName)
6090 )
6091 ParamValue = Value * openff.units.unit.kilojoule_per_mole / openff.units.unit.nanometer**2
6092 elif re.match("^RestraintAnchorFindingStrategy$", ParamName, re.I):
6093 if not re.match("^(multi-residue|bonded)$", Value, re.I):
6094 MiscUtil.PrintError(
6095 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: multi-residue or bonded'
6096 % (Value, Name, ParamsOptionName)
6097 )
6098 ParamValue = Value
6099 elif re.match("^(ComplexSimulationSamplerMethod|SolventSimulationSamplerMethod)$", ParamName, re.I):
6100 if not re.match("^(repex|sams|independent)$", Value, re.I):
6101 MiscUtil.PrintError(
6102 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: repex, sams, or independent'
6103 % (Value, Name, ParamsOptionName)
6104 )
6105 ParamValue = Value.lower()
6106 elif re.match(
6107 "^(ComplexSimulationSamsFlatnessCriteria|SolventSimulationSamsFlatnessCriteria)$", ParamName, re.I
6108 ):
6109 if not re.match("^(logz-flatness|minimum-visits|histogram-flatness)$", Value, re.I):
6110 MiscUtil.PrintError(
6111 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: logz-flatness, minimum-visits, or histogram-flatness'
6112 % (Value, Name, ParamsOptionName)
6113 )
6114 ParamValue = Value.lower()
6115 elif re.match("^ThermoPressure$", ParamName, re.I):
6116 # float > 0 and units standard_atmosphere
6117 if not MiscUtil.IsFloat(Value):
6118 MiscUtil.PrintError(
6119 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6120 % (Value, ParamName, ParamsOptionName)
6121 )
6122 Value = float(Value)
6123 if Value <= 0:
6124 MiscUtil.PrintError(
6125 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6126 % (ParamValue, ParamName, ParamsOptionName)
6127 )
6128 ParamValue = Value * openff.units.unit.bar
6129 elif re.match("^ThermoTemperature$", ParamName, re.I):
6130 # float >= 0 and units kelvin
6131 if not MiscUtil.IsFloat(Value):
6132 MiscUtil.PrintError(
6133 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6134 % (Value, ParamName, ParamsOptionName)
6135 )
6136 Value = float(Value)
6137 if Value < 0:
6138 MiscUtil.PrintError(
6139 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: >= 0\n'
6140 % (ParamValue, ParamName, ParamsOptionName)
6141 )
6142 ParamValue = Value * openff.units.unit.kelvin
6143 else:
6144 # Str or None...
6145 ParamValue = None if re.match("^None$", Value, re.I) else Value
6146
6147 # Set value...
6148 ParamsInfo[ParamName] = ParamValue
6149
6150 # Handle parameters with possible auto values...
6151 _ProcessOptionOpenFEAbsoluteBindingFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6152
6153 return ParamsInfo
6154
6155
6156 def _ProcessOptionOpenFEAbsoluteBindingFreeEnergyParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6157 """Process parameters with possible auto values and perform validation."""
6158
6159 for NamePrefix in ["Complex", "Solvent"]:
6160 ParamName1 = "%sSolvationBoxSize" % NamePrefix
6161 ParamValue1 = ParamsInfo[ParamName1]
6162 ParamName2 = "%sSolvationSolventPadding" % NamePrefix
6163 ParamValue2 = ParamsInfo[ParamName2]
6164 if ParamsInfo[ParamName1] is not None and ParamsInfo[ParamName2] is not None:
6165 MiscUtil.PrintError(
6166 'The parameter values, %s and %s, specified for parameter names, %s and %s, using "%s" option is not a valid value. You must specify only one of these values.\n'
6167 % (ParamValue1, ParamValue2, ParamName1, ParamName2, ParamsOptionName)
6168 )
6169
6170 for NamePrefix in ["Complex", "Solvent"]:
6171 ParamName1 = "%sLambdaElec" % NamePrefix
6172 ParamValue1Count = len(ParamsInfo[ParamName1])
6173 ParamName2 = "%sLambdaRestraints" % NamePrefix
6174 ParamValue2Count = len(ParamsInfo[ParamName2])
6175 ParamName3 = "%sLambdaVdw" % NamePrefix
6176 ParamValue3Count = len(ParamsInfo[ParamName3])
6177 if ParamValue1Count != ParamValue2Count or ParamValue1Count != ParamValue3Count:
6178 MiscUtil.PrintError(
6179 'The number of values - %s, %s, and %s - specified for parameter names - %s, %s, and %s, using "%s" option are not valid. You must specify same number of values for these parameters.'
6180 % (
6181 ParamValue1Count,
6182 ParamValue2Count,
6183 ParamValue3Count,
6184 ParamName1,
6185 ParamName2,
6186 ParamName3,
6187 ParamsOptionName,
6188 )
6189 )
6190
6191 _ProcessPartialChargeMethodAbsoluteBindingFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6192 _ProcessPartialChargeNaglAbsoluteBindingFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6193
6194
6195 def _ProcessPartialChargeMethodAbsoluteBindingFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6196 """Process PartialChargeMethod ABFE paramater."""
6197
6198 _ProcessPartialChargeMethodFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6199
6200
6201 def _ProcessPartialChargeNaglAbsoluteBindingFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6202 """Process PartialChargeNaglModel ABFE paramater."""
6203
6204 _ProcessPartialChargeNaglFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6205
6206
6207 def _SetupAbsoluteBindingFreeEnergyDefaultParametersInfo(ParamsOptionName, ParamsOptionValue):
6208 """Setup ABFE default parameters information using the current ABFE settings."""
6209
6210 ParamsInfo = {}
6211
6212 from openfe.protocols.openmm_afe import AbsoluteBindingProtocol
6213
6214 ABFESettings = AbsoluteBindingProtocol.default_settings()
6215 ABFEParametersMap = _SetupMapForAbsoluteBindingFreeEnergyParameters()
6216
6217 for ParamName in ABFEParametersMap.keys():
6218 ABFEParamGroupName, ABFEParamName = ABFEParametersMap[ParamName]
6219 if ABFEParamGroupName is None:
6220 if hasattr(ABFESettings, ABFEParamName):
6221 ParamsInfo[ParamName] = getattr(ABFESettings, ABFEParamName)
6222 else:
6223 MiscUtil.PrintInfo(
6224 'The OpenFE ABFE settings name, %s, corresponding to ABFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
6225 % (ABFEParamName, ParamName, ParamsOptionName)
6226 )
6227 else:
6228 ABFEParamGroupSettings = (
6229 getattr(ABFESettings, ABFEParamGroupName) if hasattr(ABFESettings, ABFEParamGroupName) else None
6230 )
6231 if ABFEParamGroupSettings is not None and hasattr(ABFEParamGroupSettings, ABFEParamName):
6232 ParamsInfo[ParamName] = getattr(ABFEParamGroupSettings, ABFEParamName)
6233 else:
6234 MiscUtil.PrintInfo(
6235 'The OpenFE ABFE parameter name, %s, for settings, %s, corresponding to ABFE parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
6236 % (ABFEParamName, ABFEParamGroupName, ParamName, ParamsOptionName)
6237 )
6238
6239 return ParamsInfo
6240
6241
6242 def _SetupMapForAbsoluteBindingFreeEnergyParameters():
6243 """Map relative free energy option paramater names to OpenFE absolute
6244 binding free energy settings.
6245 """
6246
6247 ABFEParametersMap = {
6248 "ProtocolRepeats": [None, "protocol_repeats"],
6249 "ComplexEquilOutputCheckpointInterval": ["complex_equil_output_settings", "checkpoint_interval"],
6250 "ComplexEquilOutputCheckpointStorageFilename": ["complex_equil_output_settings", "checkpoint_storage_filename"],
6251 "ComplexEquilOutputEquilNPTStructure": ["complex_equil_output_settings", "equil_npt_structure"],
6252 "ComplexEquilOutputEquilNVTstructure": ["complex_equil_output_settings", "equil_nvt_structure"],
6253 "ComplexEquilOutputForcefieldCache": ["complex_equil_output_settings", "forcefield_cache"],
6254 "ComplexEquilOutputLogOutput": ["complex_equil_output_settings", "log_output"],
6255 "ComplexEquilOutputMinimizedStructure": ["complex_equil_output_settings", "minimized_structure"],
6256 "ComplexEquilOutputIndices": ["complex_equil_output_settings", "output_indices"],
6257 "ComplexEquilOutputPreminimizedStructure": ["complex_equil_output_settings", "preminimized_structure"],
6258 "ComplexEquilOutputProductionTrajectoryFilename": [
6259 "complex_equil_output_settings",
6260 "production_trajectory_filename",
6261 ],
6262 "ComplexEquilOutputTrajectoryWriteInterval": ["complex_equil_output_settings", "trajectory_write_interval"],
6263 "ComplexEquilSimulationEquilibrationLength": ["complex_equil_simulation_settings", "equilibration_length"],
6264 "ComplexEquilSimulationEquilibrationLengthNVT": [
6265 "complex_equil_simulation_settings",
6266 "equilibration_length_nvt",
6267 ],
6268 "ComplexEquilSimulationMinimizationSteps": ["complex_equil_simulation_settings", "minimization_steps"],
6269 "ComplexEquilSimulationProductionLength": ["complex_equil_simulation_settings", "production_length"],
6270 "ComplexLambdaElec": ["complex_lambda_settings", "lambda_elec"],
6271 "ComplexLambdaRestraints": ["complex_lambda_settings", "lambda_restraints"],
6272 "ComplexLambdaVdw": ["complex_lambda_settings", "lambda_vdw"],
6273 "ComplexOutputCheckpointInterval": ["complex_output_settings", "checkpoint_interval"],
6274 "ComplexOutputCheckpointStorageFilename": ["complex_output_settings", "checkpoint_storage_filename"],
6275 "ComplexOutputForcefieldCache": ["complex_output_settings", "forcefield_cache"],
6276 "ComplexOutputFilename": ["complex_output_settings", "output_filename"],
6277 "ComplexOutputIndices": ["complex_output_settings", "output_indices"],
6278 "ComplexOutputStructure": ["complex_output_settings", "output_structure"],
6279 "ComplexOutputPositionsWriteFrequency": ["complex_output_settings", "positions_write_frequency"],
6280 "ComplexOutputVelocitiesWriteFrequency": ["complex_output_settings", "velocities_write_frequency"],
6281 "ComplexSimulationEarlyTerminationTargetError": [
6282 "complex_simulation_settings",
6283 "early_termination_target_error",
6284 ],
6285 "ComplexSimulationEquilibrationLength": ["complex_simulation_settings", "equilibration_length"],
6286 "ComplexSimulationMinimizationSteps": ["complex_simulation_settings", "minimization_steps"],
6287 "ComplexSimulationNReplicas": ["complex_simulation_settings", "n_replicas"],
6288 "ComplexSimulationProductionLength": ["complex_simulation_settings", "production_length"],
6289 "ComplexSimulationRealTimeAnalysisInterval": ["complex_simulation_settings", "real_time_analysis_interval"],
6290 "ComplexSimulationRealTimeAnalysisMinimumTime": [
6291 "complex_simulation_settings",
6292 "real_time_analysis_minimum_time",
6293 ],
6294 "ComplexSimulationSamplerMethod": ["complex_simulation_settings", "sampler_method"],
6295 "ComplexSimulationSamsFlatnessCriteria": ["complex_simulation_settings", "sams_flatness_criteria"],
6296 "ComplexSimulationSamsGamma0": ["complex_simulation_settings", "sams_gamma0"],
6297 "ComplexSimulationTimePerIteration": ["complex_simulation_settings", "time_per_iteration"],
6298 "ComplexSolvationBoxShape": ["complex_solvation_settings", "box_shape"],
6299 "ComplexSolvationBoxSize": ["complex_solvation_settings", "box_size"],
6300 "ComplexSolvationSolventModel": ["complex_solvation_settings", "solvent_model"],
6301 "ComplexSolvationSolventPadding": ["complex_solvation_settings", "solvent_padding"],
6302 "EngineComputePlatform": ["engine_settings", "compute_platform"],
6303 "EngineGpuDeviceIndex": ["engine_settings", "gpu_device_index"],
6304 "ForcefieldConstraints": ["forcefield_settings", "constraints"],
6305 "Forcefields": ["forcefield_settings", "forcefields"],
6306 "ForcefieldHydrogenMass": ["forcefield_settings", "hydrogen_mass"],
6307 "ForcefieldNonbondedCutoff": ["forcefield_settings", "nonbonded_cutoff"],
6308 "ForcefieldNonbondedMethod": ["forcefield_settings", "nonbonded_method"],
6309 "ForcefieldRigidWater": ["forcefield_settings", "rigid_water"],
6310 "ForcefieldSmallMoleculeForcefield": ["forcefield_settings", "small_molecule_forcefield"],
6311 "IntegratorBarostatFrequency": ["integrator_settings", "barostat_frequency"],
6312 "IntegratorConstraintTolerance": ["integrator_settings", "constraint_tolerance"],
6313 "IntegratorLangevinCollisionRate": ["integrator_settings", "langevin_collision_rate"],
6314 "IntegratorNRestartAttempts": ["integrator_settings", "n_restart_attempts"],
6315 "IntegratorReassignVelocities": ["integrator_settings", "reassign_velocities"],
6316 "IntegratorRemoveCom": ["integrator_settings", "remove_com"],
6317 "IntegratorTimestep": ["integrator_settings", "timestep"],
6318 "PartialChargeNaglModel": ["partial_charge_settings", "nagl_model"],
6319 "PartialChargeNumberOfConformers": ["partial_charge_settings", "number_of_conformers"],
6320 "PartialChargeOffToolkitBackend": ["partial_charge_settings", "off_toolkit_backend"],
6321 "PartialChargeMethod": ["partial_charge_settings", "partial_charge_method"],
6322 "RestraintKPhiA": ["restraint_settings", "K_phiA"],
6323 "RestraintKPhiB": ["restraint_settings", "K_phiB"],
6324 "RestraintKPhiC": ["restraint_settings", "K_phiC"],
6325 "RestraintKR": ["restraint_settings", "K_r"],
6326 "RestraintKThetaA": ["restraint_settings", "K_thetaA"],
6327 "RestraintKThetaB": ["restraint_settings", "K_thetaB"],
6328 "RestraintAnchorFindingStrategy": ["restraint_settings", "anchor_finding_strategy"],
6329 "RestraintDsspFilter": ["restraint_settings", "dssp_filter"],
6330 "RestraintHostMaxDistance": ["restraint_settings", "host_max_distance"],
6331 "RestraintHostMinDistance": ["restraint_settings", "host_min_distance"],
6332 "RestraintHostSelection": ["restraint_settings", "host_selection"],
6333 "RestraintRmsfCutoff": ["restraint_settings", "rmsf_cutoff"],
6334 "SolventEquilOutputCheckpointInterval": ["solvent_equil_output_settings", "checkpoint_interval"],
6335 "SolventEquilOutputCheckpointStorageFilename": ["solvent_equil_output_settings", "checkpoint_storage_filename"],
6336 "SolventEquilOutputEquilNPTStructure": ["solvent_equil_output_settings", "equil_npt_structure"],
6337 "SolventEquilOutputEquilNVTstructure": ["solvent_equil_output_settings", "equil_nvt_structure"],
6338 "SolventEquilOutputForcefieldCache": ["solvent_equil_output_settings", "forcefield_cache"],
6339 "SolventEquilOutputLogOutput": ["solvent_equil_output_settings", "log_output"],
6340 "SolventEquilOutputMinimizedStructure": ["solvent_equil_output_settings", "minimized_structure"],
6341 "SolventEquilOutputIndices": ["solvent_equil_output_settings", "output_indices"],
6342 "SolventEquilOutputPreminimizedStructure": ["solvent_equil_output_settings", "preminimized_structure"],
6343 "SolventEquilOutputProductionTrajectoryFilename": [
6344 "solvent_equil_output_settings",
6345 "production_trajectory_filename",
6346 ],
6347 "SolventEquilOutputTrajectoryWriteInterval": ["solvent_equil_output_settings", "trajectory_write_interval"],
6348 "SolventEquilSimulationEquilibrationLength": ["solvent_equil_simulation_settings", "equilibration_length"],
6349 "SolventEquilSimulationEquilibrationLengthNVT": [
6350 "solvent_equil_simulation_settings",
6351 "equilibration_length_nvt",
6352 ],
6353 "SolventEquilSimulationMinimizationSteps": ["solvent_equil_simulation_settings", "minimization_steps"],
6354 "SolventEquilSimulationProductionLength": ["solvent_equil_simulation_settings", "production_length"],
6355 "SolventLambdaElec": ["solvent_lambda_settings", "lambda_elec"],
6356 "SolventLambdaRestraints": ["solvent_lambda_settings", "lambda_restraints"],
6357 "SolventLambdaVdw": ["solvent_lambda_settings", "lambda_vdw"],
6358 "SolventOutputCheckpointInterval": ["solvent_output_settings", "checkpoint_interval"],
6359 "SolventOutputCheckpointStorageFilename": ["solvent_output_settings", "checkpoint_storage_filename"],
6360 "SolventOutputForcefieldCache": ["solvent_output_settings", "forcefield_cache"],
6361 "SolventOutputFilename": ["solvent_output_settings", "output_filename"],
6362 "SolventOutputIndices": ["solvent_output_settings", "output_indices"],
6363 "SolventOutputStructure": ["solvent_output_settings", "output_structure"],
6364 "SolventOutputPositionsWriteFrequency": ["solvent_output_settings", "positions_write_frequency"],
6365 "SolventOutputVelocitiesWriteFrequency": ["solvent_output_settings", "velocities_write_frequency"],
6366 "SolventSimulationEarlyTerminationTargetError": [
6367 "solvent_simulation_settings",
6368 "early_termination_target_error",
6369 ],
6370 "SolventSimulationEquilibrationLength": ["solvent_simulation_settings", "equilibration_length"],
6371 "SolventSimulationMinimizationSteps": ["solvent_simulation_settings", "minimization_steps"],
6372 "SolventSimulationNReplicas": ["solvent_simulation_settings", "n_replicas"],
6373 "SolventSimulationProductionLength": ["solvent_simulation_settings", "production_length"],
6374 "SolventSimulationRealTimeAnalysisInterval": ["solvent_simulation_settings", "real_time_analysis_interval"],
6375 "SolventSimulationRealTimeAnalysisMinimumTime": [
6376 "solvent_simulation_settings",
6377 "real_time_analysis_minimum_time",
6378 ],
6379 "SolventSimulationSamplerMethod": ["solvent_simulation_settings", "sampler_method"],
6380 "SolventSimulationSamsFlatnessCriteria": ["solvent_simulation_settings", "sams_flatness_criteria"],
6381 "SolventSimulationSamsGamma0": ["solvent_simulation_settings", "sams_gamma0"],
6382 "SolventSimulationTimePerIteration": ["solvent_simulation_settings", "time_per_iteration"],
6383 "SolventSolvationBoxShape": ["solvent_solvation_settings", "box_shape"],
6384 "SolventSolvationBoxSize": ["solvent_solvation_settings", "box_size"],
6385 "SolventSolvationSolventModel": ["solvent_solvation_settings", "solvent_model"],
6386 "SolventSolvationSolventPadding": ["solvent_solvation_settings", "solvent_padding"],
6387 "ThermoPh": ["thermo_settings", "ph"],
6388 "ThermoPressure": ["thermo_settings", "pressure"],
6389 "ThermoRedoxPotential": ["thermo_settings", "redox_potential"],
6390 "ThermoTemperature": ["thermo_settings", "temperature"],
6391 }
6392
6393 return ABFEParametersMap
6394
6395
6396 def _UpdateOpenFESettings(FECalcType, ParamsOptionName, ParamsInfo, FESettings, FEParametersMap):
6397 """Update OpenFE settings using values corresponding to parameter names."""
6398
6399 for ParamName in FEParametersMap.keys():
6400 FEParamGroupName, FEParamName = FEParametersMap[ParamName]
6401 if FEParamGroupName is None:
6402 if hasattr(FESettings, FEParamName):
6403 try:
6404 setattr(FESettings, FEParamName, ParamsInfo[ParamName])
6405 except Exception as ErrMsg:
6406 MiscUtil.PrintInfo(
6407 '\nThe OpenFE %s settings name, %s, corresponding to %s parameter name, %s, specified using option "%s" is not settable:\n\n%s\n'
6408 % (FECalcType, FEParamName, FECalcType, ParamName, ParamsOptionName, ErrMsg)
6409 )
6410 else:
6411 MiscUtil.PrintInfo(
6412 '\nThe OpenFE %s settings name, %s, corresponding to %s parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
6413 % (FECalcType, FEParamName, FECalcType, ParamName, ParamsOptionName)
6414 )
6415 else:
6416 FEaramGroupSettings = (
6417 getattr(FESettings, FEParamGroupName) if hasattr(FESettings, FEParamGroupName) else None
6418 )
6419 if FEaramGroupSettings is not None and hasattr(FEaramGroupSettings, FEParamName):
6420 try:
6421 setattr(FEaramGroupSettings, FEParamName, ParamsInfo[ParamName])
6422 except Exception as ErrMsg:
6423 MiscUtil.PrintInfo(
6424 '\nThe OpenFE %s settings name, %s, corresponding to %s parameter name, %s, specified using option "%s" is not settable:\n\n%s\n'
6425 % (FECalcType, FEParamName, FECalcType, ParamName, ParamsOptionName, ErrMsg)
6426 )
6427 else:
6428 MiscUtil.PrintInfo(
6429 '\nThe OpenFE %s parameter name, %s, for settings, %s, corresponding to %s parameter name, %s, specified using option "%s" is not available. Ignoring parameter...'
6430 % (FECalcType, FEParamName, FECalcType, FEParamGroupName, ParamName, ParamsOptionName)
6431 )
6432
6433
6434 def _ProcessPartialChargeMethodFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6435 """Process PartialChargeMethod paramater."""
6436
6437 ParamName = "PartialChargeMethod"
6438 ParamValue = ParamsInfo[ParamName]
6439 if re.match("^Espaloma$", ParamValue, re.I):
6440 if not _IsEspalomaChargeModuleAvailable():
6441 MiscUtil.PrintError(
6442 'The parameter value, %s specified for parameter name, %s, using "%s" option is not a valid value. Espaloma module is not available in your environment.\n'
6443 % (ParamValue, ParamName, ParamsOptionName)
6444 )
6445 elif re.match("^NAGL$", ParamValue, re.I):
6446 if not _IsNAGLChargeModuleAvailable():
6447 MiscUtil.PrintError(
6448 'The parameter value, %s specified for parameter name, %s, using "%s" option is not a valid value. NAGL module is not available in your environment.\n'
6449 % (ParamValue, ParamName, ParamsOptionName)
6450 )
6451
6452
6453 def _ProcessPartialChargeNaglFreeEnergyParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6454 """Process PartialChargeNaglModel paramater."""
6455
6456 ParamName = "PartialChargeMethod"
6457 ParamValue = ParamsInfo[ParamName]
6458 if not re.match("^NAGL$", ParamValue, re.I):
6459 return
6460
6461 if not _IsNAGLChargeModuleAvailable():
6462 MiscUtil.PrintError(
6463 'The parameter value, %s specified for parameter name, %s, using "%s" option is not a valid value. NAGL module is not available in your environment.\n'
6464 % (ParamValue, ParamName, ParamsOptionName)
6465 )
6466
6467 ParamName = "PartialChargeNaglModel"
6468 ParamValue = ParamsInfo[ParamName]
6469 _CheckAvailabilityOfNAGLModels(ParamName, ParamValue, ParamsOptionName)
6470
6471
6472 def ProcessOptionOpenFESolventParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
6473 """Process parameters for solvation option and return a map containing
6474 processed parameter names and values.
6475
6476 The ParamsOptionValue is a comma delimited list of parameter name and value
6477 pairs to setup solvation parameters for creating OpenFE SolventComponent.
6478
6479 The supported parameter names along with their default and possible
6480 values are shown below:
6481
6482 positiveIon, Na+ [ Possible value: Li+, Na+, K+, Rb+, or Cs+ ]
6483 negativeIon, Cl- [ Possible values: Cl-, Br-, F-, or I- ]
6484 neutralize, yes [ Possible values: yes or no ]
6485 ionConcentration, 0.15 [ Units: molar ]
6486
6487 A brief description of parameters is provided below:
6488
6489 positiveIon, negativeion: Pair of ions used to neutralize and bring
6490 the solvent to required ionic concentration.
6491 neutralize: Neutralize the net charge on the chemical state by the
6492 ions in the solvent component.
6493 ionConcentration: Ionic concentration.
6494
6495 Arguments:
6496 ParamsOptionName (str): Command line solvation parameters option name.
6497 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
6498 ParamsDefaultInfo (dict): Default values to override for selected parameters.
6499
6500 Returns:
6501 dictionary: Processed parameter name and value pairs.
6502
6503 """
6504
6505 ParamsInfo = {"PositiveIon": "Na+", "NegativeIon": "Cl-", "Neutralize": True, "IonConcentration": 0.15}
6506
6507 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
6508 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
6509 )
6510
6511 if re.match("^auto$", ParamsOptionValue, re.I):
6512 _ProcessOptionOpenFESolventParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6513 return ParamsInfo
6514
6515 for Index in range(0, len(ParamsOptionValueWords), 2):
6516 Name = ParamsOptionValueWords[Index].strip()
6517 Value = ParamsOptionValueWords[Index + 1].strip()
6518
6519 ParamName = CanonicalParamNamesMap[Name.lower()]
6520 ParamValue = Value
6521
6522 if re.match("^PositiveIon$", ParamName, re.I):
6523 ValidValues = "Li+ Na+ K+ Rb+ Cs+"
6524 EscapedValidValuesPattern = r"Li\+|Na\+|K\+|Rb\+|Cs\+"
6525 if not re.match("^(%s)$" % EscapedValidValuesPattern, Value):
6526 MiscUtil.PrintError(
6527 'The value specified, %s, for parameter name, %s, using "%s" option is not a valid. Supported value(s): %s'
6528 % (ParamValue, ParamName, ParamsOptionName, ValidValues)
6529 )
6530 ParamValue = Value
6531 elif re.match("^NegativeIon$", ParamName, re.I):
6532 ValidValues = "F- Cl- Br- I-"
6533 ValidValuesPattern = "F-|Cl-|Br-|I-"
6534 if not re.match("^(%s)$" % ValidValuesPattern, Value):
6535 MiscUtil.PrintError(
6536 'The value specified, %s, for parameter name, %s, using "%s" option is not a valid. Supported value(s): %s'
6537 % (ParamValue, ParamName, ParamsOptionName, ValidValues)
6538 )
6539 ParamValue = Value
6540 elif re.match("^IonConcentration$", ParamName, re.I):
6541 if not MiscUtil.IsFloat(Value):
6542 MiscUtil.PrintError(
6543 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6544 % (Value, ParamName, ParamsOptionName)
6545 )
6546 Value = float(Value)
6547 if Value < 0:
6548 MiscUtil.PrintError(
6549 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6550 % (ParamValue, ParamName, ParamsOptionName)
6551 )
6552 ParamValue = Value
6553 elif re.match("^Neutralize$", ParamName, re.I):
6554 if not re.match("^(yes|no|true|false)$", Value, re.I):
6555 MiscUtil.PrintError(
6556 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
6557 % (Value, Name, ParamsOptionName)
6558 )
6559 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
6560 else:
6561 ParamValue = Value
6562
6563 # Set value...
6564 ParamsInfo[ParamName] = ParamValue
6565
6566 # Handle parameters with possible auto values...
6567 _ProcessOptionOpenFESolventParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6568
6569 return ParamsInfo
6570
6571
6572 def _ProcessOptionOpenFESolventParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6573 """Process parameters with possible auto values and perform validation."""
6574
6575 # Setup units for IonConcentration...
6576 ParamName = "IonConcentration"
6577 ParamValue = ParamsInfo[ParamName]
6578 if MiscUtil.IsNumber(ParamValue):
6579 ParamsInfo[ParamName] = ParamValue * openff.units.unit.molar
6580
6581
6582 def ProcessOptionOpenFEMapper(OptionName, OptionValue):
6583 """Process mapper command line option and return a list of valid mapper
6584 names.
6585
6586 Valid atom mapper names are: LOMAP or Kartograf
6587
6588 Arguments:
6589 OptionName (str): Command line mapper option name.
6590 OptionValue (str): Comma delimited lis of mapper option values.
6591
6592 Returns:
6593 list: List of valid canonical mapper names.
6594
6595 """
6596
6597 MapperList = []
6598 Mappers = OptionValue.strip()
6599 for MapperName in Mappers.split(","):
6600 MapperName = MapperName.strip()
6601 if re.match("^LOMAP$", MapperName, re.I):
6602 MapperList.append("LOMAP")
6603 elif re.match("^Kartograf$", MapperName, re.I):
6604 MapperList.append("Kartograf")
6605 else:
6606 MiscUtil.PrintError(
6607 'The value specified, %s, for option "%s" is not valid. Supported values: LOMAP or Kartograf'
6608 % (MapperName, OptionName)
6609 )
6610
6611 return MapperList
6612
6613
6614 def ProcessOptionOpenFEMapperParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None):
6615 """Process parameters for mapper option and return a map containing processed
6616 parameter names and values.
6617
6618 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
6619 to setup platform.
6620
6621 The supported parameter names along with their default and possible
6622 values are shown below:
6623
6624 lomapTime, 20, [ Units: seconds ]
6625 lomapThreeD, yes [ Possible values: yes or no ]
6626 lomapMax3D, 1.0 [ Units: Angstrom ]
6627 lomapElementChange, yes [ Possible values: yes or no]
6628 lomapSeed, None [ Possible value: A string. An empty string causes
6629 MCS search to start from scratch ]
6630 lomapShift, no [ Possible values: yes or no]
6631
6632 kartografAtomMaxDistance, 0.95 [ Units: Angstrom ]
6633 kartografAtomMapHydrogens, yes [ Possible values: yes or no ]
6634 kartografMapHydrogensOnHydrogensOnly, No [ Possible values: yes or
6635 no ]
6636 kartografMapExactRingMatchesOnly, yes [ Possible values: yes or no ]
6637 kartografAllowPartialFusedRings, yes [ Possible values: yes or no ]
6638
6639 A brief description of parameters is provided below:
6640
6641 lomapTime: Time out for MCS algorithm.
6642 lomapThreeD: Use atom positions to prune symmetric mappings.
6643 lomapMax3D: Forbid mapping between atoms with distance more than
6644 specified value.
6645 lomapElementChange: Allow mappings that change an atom element.
6646 lomapSeed: An Empty SMARTS string causes MCS search to start from
6647 scratch.
6648 lomapShift: Keep pre-aligned atom positions for 3D position checks.
6649
6650 kartografAtomMaxDistance: Geometric criteria for two atoms
6651 corresponding to maximum distance between them.
6652 kartografAtomMapHydrogens: Map hydrogens.
6653 kartografMapHydrogensOnHydrogensOnly: Map hydrogens only on
6654 hydrogens.
6655 kartografMapExactRingMatchesOnly: Map rings with only matching ring
6656 size and bond orders. In addition, ring breaking is not permitted.
6657 kartografAllowPartialFusedRings: Allow mapping of partially fused
6658 rings.
6659
6660 Arguments:
6661 ParamsOptionName (str): Command line OpenFE mapper parameters option name.
6662 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
6663 ParamsDefaultInfo (dict): Default values to override for selected parameters.
6664
6665 Returns:
6666 dictionary: Processed parameter name and value pairs.
6667
6668 """
6669
6670 ParamsInfo = {
6671 "LomapTime": 20,
6672 "LomapThreeD": True,
6673 "LomapMax3D": 1.0,
6674 "LomapElementChange": True,
6675 "LomapSeed": None,
6676 "LomapShift": False,
6677 "KartografAtomMaxDistance": 0.95,
6678 "KartografAtomMapHydrogens": True,
6679 "KartografMapHydrogensOnHydrogensOnly": False,
6680 "KartografMapExactRingMatchesOnly": True,
6681 "KartografAllowPartialFusedRings": True,
6682 }
6683
6684 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
6685 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
6686 )
6687
6688 if re.match("^auto$", ParamsOptionValue, re.I):
6689 _ProcessOptionOpenFEMapperParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6690 return ParamsInfo
6691
6692 for Index in range(0, len(ParamsOptionValueWords), 2):
6693 Name = ParamsOptionValueWords[Index].strip()
6694 Value = ParamsOptionValueWords[Index + 1].strip()
6695
6696 ParamName = CanonicalParamNamesMap[Name.lower()]
6697 ParamValue = Value
6698
6699 if re.match("^(LomapMax3D|KartografAtomMaxDistance)$", ParamName, re.I):
6700 if not MiscUtil.IsFloat(Value):
6701 MiscUtil.PrintError(
6702 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
6703 % (Value, ParamName, ParamsOptionName)
6704 )
6705 Value = float(Value)
6706 if Value <= 0:
6707 MiscUtil.PrintError(
6708 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6709 % (ParamValue, ParamName, ParamsOptionName)
6710 )
6711 ParamValue = Value
6712 elif re.match("^(LomapTime)$", ParamName, re.I):
6713 if not MiscUtil.IsInteger(Value):
6714 MiscUtil.PrintError(
6715 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
6716 % (Value, ParamName, ParamsOptionName)
6717 )
6718 Value = int(Value)
6719 if Value <= 0:
6720 MiscUtil.PrintError(
6721 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6722 % (ParamValue, ParamName, ParamsOptionName)
6723 )
6724 ParamValue = Value
6725 elif re.match(
6726 "^(LomapThreeD|LomapElementChange|LomapShift|KartografAtomMapHydrogens|KartografMapHydrogensOnHydrogensOnly|KartografMapExactRingMatchesOnly|KartografAllowPartialFusedRings)$",
6727 ParamName,
6728 re.I,
6729 ):
6730 if not re.match("^(yes|no|true|false)$", Value, re.I):
6731 MiscUtil.PrintError(
6732 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
6733 % (Value, Name, ParamsOptionName)
6734 )
6735 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
6736 else:
6737 ParamValue = Value
6738
6739 # Set value...
6740 ParamsInfo[ParamName] = ParamValue
6741
6742 # Handle parameters with possible auto values...
6743 _ProcessOptionOpenFEMapperParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue)
6744
6745 return ParamsInfo
6746
6747
6748 def _ProcessOptionOpenFEMapperParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue):
6749 """Process parameters with possible auto values and perform validation."""
6750
6751 ParamName = "LomapSeed"
6752 ParamValue = ParamsInfo[ParamName]
6753 if ParamValue is None or re.match("^None$", ParamValue, re.I):
6754 ParamsInfo[ParamName] = ""
6755
6756
6757 def ProcessOptionOpenFECharge(OptionName, OptionValue):
6758 """Process charge command line option and return a valid canonical
6759 charge method name.
6760
6761 Valid network names are: AM1BCC, AM1-Mulliken, Espaloma, Gasteiger, MMFF94
6762 or NAGL
6763
6764 Arguments:
6765 OptionName (str): Command line charge option name.
6766 OptionValue (str): Command line charge option value.
6767
6768 Returns:
6769 str: Canonical charge method name.
6770
6771 """
6772
6773 Value = OptionValue.strip()
6774 if re.match("^AM1BCC$", Value, re.I):
6775 Value = "AM1BCC"
6776 elif re.match("^AM1-Mulliken$", Value, re.I):
6777 Value = "AM1-Mulliken"
6778 elif re.match("^Espaloma$", Value, re.I):
6779 Value = "Espaloma"
6780 if not _IsEspalomaChargeModuleAvailable():
6781 MiscUtil.PrintError(
6782 'The value specified, %s, for option "%s" is not valid. Espaloma module is not available in your environment.'
6783 % (OptionValue, OptionName)
6784 )
6785 elif re.match("^Gasteiger$", Value, re.I):
6786 Value = "Gasteiger"
6787 elif re.match("^MMFF94$", Value, re.I):
6788 Value = "MMFF94"
6789 elif re.match("^NAGL$", Value, re.I):
6790 Value = "NAGL"
6791 if not _IsNAGLChargeModuleAvailable():
6792 MiscUtil.PrintError(
6793 'The value specified, %s, for option "%s" is not valid. NAGL module is not available in your environment.'
6794 % (OptionValue, OptionName)
6795 )
6796 else:
6797 MiscUtil.PrintError(
6798 'The value specified, %s, for option "%s" is not valid. Supported values: AM1BCC, AM1-Mulliken, Espaloma, Gasteiger, MMFF94 or NAGL'
6799 % (OptionValue, OptionName)
6800 )
6801
6802 return Value
6803
6804
6805 def _IsEspalomaChargeModuleAvailable():
6806 """Check for the availability of Espaloma charge module."""
6807
6808 Status = False if importlib.util.find_spec("espaloma_charge") is None else True
6809
6810 return Status
6811
6812
6813 def _IsNAGLChargeModuleAvailable():
6814 """Check for the availability of NAGL charge module."""
6815
6816 Status = False if importlib.util.find_spec("openff.nagl_models") is None else True
6817
6818 return Status
6819
6820
6821 def ProcessOptionOpenFEChargeParameters(ParamsOptionName, ParamsOptionValue, ChargeMethod, ParamsDefaultInfo=None):
6822 """Process parameters for charge option and return a map containing processed
6823 parameter names and values.
6824
6825 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
6826 to setup platform.
6827
6828 The supported parameter names along with their default and possible
6829 values are shown below:
6830
6831 naglModel, auto [ Possible value: A valid NAGL model name. By
6832 default, it corresponds to the latest AM1BCC production model ]
6833 toolkit, auto [ Possible values: RDKit or AmberTools. Default value:
6834 RDKit for Gasteiger and MMFF94; AmberTools for AM1BCC and
6835 AM1-Mulliken; Not used for Espaloma and NAGL. ]
6836
6837 numProcessors, 1 [ Only used for AM1BCC, AM1-Mulliken, Espaloma,
6838 and NAGL ]
6839
6840 precision, 4
6841 lineSize, 90
6842
6843 useConformer, auto [ Use current conformer. Possible values: yes or
6844 no. Default value: no for Gasteiger using AmberToolkit;
6845 otherwise, yes. ]
6846
6847 A brief description of parameters is provided below:
6848
6849 naglModel: NAGL model name. The latest AM1BCC NAGL production
6850 model is used by default. You must specify it explicitly in case no
6851 production model is available.
6852 toolkit: Toolkit name. RDKit for Gasteiger and MMFF94; AmberTools
6853 for AM1BCC, AM1-Mulliken, and Gasteiger.
6854
6855 numProcessors: Number of processors. This is only used during the
6856 calculation of AM1BCC, AM1-Mulliken, Espaloma, and NAGL
6857 employing OpenFE method bulk_assign_partial_charges().
6858
6859 precision: Floating point precision for writing the calculated
6860 partial atomic charges.
6861 lineSize: Line size for writing the calculated partial aromic
6862 charges to SD file as a string value for data field label
6863 'atom.dprop.PartialCharge'.
6864
6865 useConformer: Use current conformer. The current conformer is
6866 always used to calculate AM1BCC, Espaloma abd NAGL charges
6867 using OpenFE method bulk_assign_partial_charges() and this
6868 option is ignored. In addition, the option value is passed to
6869 OpenFF method assign_partial_charges() during the calculation
6870 of AM1-Mulliken, Gasteiger and MMFF94 charges employing
6871 AmberTools or RDKit. The RDKit functions, however, ignore the
6872 conformer during the calculation of Gasteiger and MMFF94
6873 charges. The current conformer appears not used to calculate
6874 Gasteiger charges employing AmberTools.
6875
6876 Arguments:
6877 ParamsOptionName (str): Command line OpenFE network parameters option name.
6878 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
6879 ChargeMethod (str): Charge method name.
6880 ParamsDefaultInfo (dict): Default values to override for selected parameters.
6881
6882 Returns:
6883 dictionary: Processed parameter name and value pairs.
6884
6885 """
6886
6887 ParamsInfo = {
6888 "NaglModel": "auto",
6889 "Toolkit": "auto",
6890 "UseConformer": "auto",
6891 "NumProcessors": 1,
6892 "Precision": 4,
6893 "LineSize": 90,
6894 }
6895
6896 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
6897 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
6898 )
6899
6900 if re.match("^auto$", ParamsOptionValue, re.I):
6901 _ProcessOptionOpenFEChargeParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod)
6902 return ParamsInfo
6903
6904 for Index in range(0, len(ParamsOptionValueWords), 2):
6905 Name = ParamsOptionValueWords[Index].strip()
6906 Value = ParamsOptionValueWords[Index + 1].strip()
6907
6908 ParamName = CanonicalParamNamesMap[Name.lower()]
6909 ParamValue = Value
6910
6911 if re.match("^(NumProcessors|Precision|LineSize)$", ParamName, re.I):
6912 if not MiscUtil.IsInteger(Value):
6913 MiscUtil.PrintError(
6914 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
6915 % (Value, ParamName, ParamsOptionName)
6916 )
6917 Value = int(Value)
6918 if Value <= 0:
6919 MiscUtil.PrintError(
6920 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
6921 % (ParamValue, ParamName, ParamsOptionName)
6922 )
6923 ParamValue = Value
6924 elif re.match("^Toolkit$", ParamName, re.I):
6925 if not re.match("^auto$", Value, re.I):
6926 if not re.match("^(AmberTools|RDKit)$", Value, re.I):
6927 MiscUtil.PrintError(
6928 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: AmberTools or RDKit'
6929 % (Value, Name, ParamsOptionName)
6930 )
6931 ParamValue = Value
6932 elif re.match("^UseConformer$", ParamName, re.I):
6933 if not re.match("^auto$", Value, re.I):
6934 if not re.match("^(yes|no|true|false)$", Value, re.I):
6935 MiscUtil.PrintError(
6936 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
6937 % (Value, Name, ParamsOptionName)
6938 )
6939 ParamValue = Value
6940 else:
6941 ParamValue = Value
6942
6943 # Set value...
6944 ParamsInfo[ParamName] = ParamValue
6945
6946 # Handle parameters with possible auto values...
6947 _ProcessOptionOpenFEChargeParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod)
6948
6949 return ParamsInfo
6950
6951
6952 def _ProcessOptionOpenFEChargeParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod):
6953 """Process parameters with possible auto values and perform validation."""
6954
6955 _ProcessToolkitChargeParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod)
6956 _ProcessNaglModelChargeParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod)
6957 _ProcessUseConformerChargeParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod)
6958
6959
6960 def _ProcessToolkitChargeParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod):
6961 """Process Toolkit Charge parameter."""
6962
6963 ParamName = "Toolkit"
6964 ParamValue = ParamsInfo[ParamName]
6965 if re.match("^auto$", ParamValue, re.I):
6966 ParamValue = "RDKit" if re.match("^(Gasteiger|MMFF94)$", ChargeMethod, re.I) else "AmberTools"
6967 ParamsInfo[ParamName] = ParamValue
6968
6969 if re.match("^MMFF94$", ChargeMethod, re.I):
6970 if not re.match("^RDKit$", ParamValue, re.I):
6971 MiscUtil.PrintError(
6972 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values for charge method %s: RDKit\n'
6973 % (ParamValue, ParamName, ParamsOptionName, ChargeMethod)
6974 )
6975
6976 if re.match("^(AM1BCC|AM1-Mulliken)$", ChargeMethod, re.I):
6977 if not re.match("^AmberTools$", ParamValue, re.I):
6978 MiscUtil.PrintError(
6979 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values for charge method %s: AmberTools\n'
6980 % (ParamValue, ParamName, ParamsOptionName, ChargeMethod)
6981 )
6982
6983
6984 def _ProcessUseConformerChargeParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod):
6985 """Process UseConformer charge parameter."""
6986
6987 ParamName = "UseConformer"
6988 ParamValue = "%s" % ParamsInfo[ParamName]
6989
6990 if re.match("^auto$", ParamValue, re.I):
6991 ParamValue = None
6992 if re.match("^(AM1BCC|AM1-Mulliken|Espaloma|NAGL)$", ChargeMethod, re.I):
6993 ParamValue = True
6994 elif re.match("Gasteiger", ChargeMethod, re.I):
6995 if re.match("^AmberTools$", ParamsInfo["Toolkit"], re.I):
6996 ParamValue = False
6997 elif re.match("^RDKit$", ParamsInfo["Toolkit"], re.I):
6998 ParamValue = True
6999 elif re.match("MMFF94", ChargeMethod, re.I):
7000 if re.match("^RDKit$", ParamsInfo["Toolkit"], re.I):
7001 ParamValue = True
7002 ParamsInfo[ParamName] = ParamValue
7003
7004
7005 def _ProcessNaglModelChargeParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, ChargeMethod):
7006 """Process NaglModel charge parameter."""
7007
7008 if not re.match("^NAGL$", ChargeMethod, re.I):
7009 return
7010
7011 if not _IsNAGLChargeModuleAvailable():
7012 MiscUtil.PrintError(
7013 'The value specified, , for option "-c, --charge" is not valid. NAGL module is not available in your environment.'
7014 % (ChargeMethod)
7015 )
7016
7017 ParamName = "NaglModel"
7018 ParamValue = ParamsInfo[ParamName]
7019 if re.match("^auto$", ParamValue, re.I):
7020 ParamValue = None
7021 ParamsInfo[ParamName] = None
7022
7023 _CheckAvailabilityOfNAGLModels(ParamName, ParamValue, ParamsOptionName)
7024
7025
7026 def _CheckAvailabilityOfNAGLModels(ParamName, ParamValue, ParamsOptionName):
7027 """Check availability of NAGL models."""
7028
7029 # Check for the availability of production models...
7030 ModelType = "am1bcc"
7031 ProductionOnly = True
7032 AvailableModels = openff.nagl_models.get_models_by_type(model_type=ModelType, production_only=ProductionOnly)
7033 if len(AvailableModels) >= 1:
7034 if ParamValue is None:
7035 # It would be automatically picked up by OpenFE NAGL charge calculation....
7036 return
7037
7038 # Check for the availability of all models...
7039 ProductionOnly = False
7040 AvailableModels = openff.nagl_models.get_models_by_type(model_type=ModelType, production_only=ProductionOnly)
7041 AvailableModelNames = []
7042 for ModelPath in AvailableModels:
7043 DirName, ModelName = os.path.split(ModelPath)
7044 AvailableModelNames.append(ModelName)
7045
7046 if ParamValue is None:
7047 MiscUtil.PrintWarning(
7048 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. No AM1BCC production models available for charge method NAGL. You must explicitly specify a NAGL model name. Possible values: %s\n'
7049 % (ParamValue, ParamName, ParamsOptionName, " ".join(AvailableModelNames))
7050 )
7051 else:
7052 if ParamValue not in AvailableModelNames:
7053 MiscUtil.PrintWarning(
7054 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Available models for charge method NAGL: %s\n'
7055 % (ParamValue, ParamName, ParamsOptionName, " ".join(AvailableModelNames))
7056 )
7057
7058
7059 def ProcessOptionOpenFENetwork(OptionName, OptionValue):
7060 """Process network command line option and return a valid canonical
7061 network name.
7062
7063 Valid network names are: LOMAP, MinimalSpanning, or Radial.
7064
7065 Arguments:
7066 OptionName (str): Command line network option name.
7067 OptionValue (str): Command line network option value.
7068
7069 Returns:
7070 str: Canonical network name.
7071
7072 """
7073
7074 Value = OptionValue.strip()
7075 if re.match("^LOMAP$", Value, re.I):
7076 Value = "LOMAP"
7077 elif re.match("^MinimalSpanning$", Value, re.I):
7078 Value = "MinimalSpanning"
7079 elif re.match("^Radial$", Value, re.I):
7080 Value = "Radial"
7081 else:
7082 MiscUtil.PrintError(
7083 'The value specified, %s, for option "%s" is not valid. Supported values: LOMAP, MinimalSpanning or Radial'
7084 % (OptionValue, OptionName)
7085 )
7086
7087 return Value
7088
7089
7090 def ProcessOptionOpenFENetworkParameters(
7091 ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo=None, RadialNetworkStatus=False
7092 ):
7093 """Process parameters for network option and return a map containing processed
7094 parameter names and values.
7095
7096 The ParamsOptionValue is a comma delimited list of parameter name and value pairs
7097 to setup platform.
7098
7099 The supported parameter names along with their default and possible
7100 values are shown below:
7101
7102 lomapDistanceCutoff, 0.4
7103 lomapMaxPathLength, 6
7104 lomapRequireCycleCovering, yes [ Possible values: yes or no ]
7105
7106 minimalSpanningProgress, no [ Possible values: yes or no ]
7107
7108 radialCentralLigand, None [ Possible values: Valid ligand name ]
7109
7110 outputEdges, no [ Possible values: yes or no ]
7111 outputNetworkFormat, svg [ Possible values: Any valid format. ]
7112
7113 A brief description of parameters is provided below:
7114
7115 lomapDistanceCutoff: Maximum distance/dissimilarity between two
7116 molecules for an edge to be accepted.
7117 lomapMaxPathLength: Maximum distance between any two molecules in
7118 the resulting network
7119 lomapRequireCycleCovering: Add cycles into the network
7120
7121 minimalSpanningProgress: Show progress using tqdm.
7122
7123 radialCentralLigand: Name of central ligand. A valid ligand name
7124 must be specified to generate a radial ligand network.
7125
7126 outputEdges: Generate PNG image files for all edges in a ligand
7127 network.
7128 outputNetworkFormat: Valid image file format for ligand network.
7129 You must specify a valid format supported by Python module
7130 Matplotlib. For example: PNG (.png), SVG (.svg), PDF (.pdf),
7131 etc. In addition, the graphml file is always generated.
7132
7133 Arguments:
7134 ParamsOptionName (str): Command line OpenFE network parameters option name.
7135 ParamsOptionValue (str): Comma delimited list of parameter name and value pairs.
7136 ParamsDefaultInfo (dict): Default values to override for selected parameters.
7137 RadialNetworkStatus (bool): Radial network status.
7138
7139 Returns:
7140 dictionary: Processed parameter name and value pairs.
7141
7142 """
7143
7144 ParamsInfo = {
7145 "LomapDistanceCutoff": 0.4,
7146 "LomapMaxPathLength": 6,
7147 "LomapRequireCycleCovering": True,
7148 "MinimalSpanningProgress": False,
7149 "RadialCentralLigand": None,
7150 "OutputEdges": False,
7151 "OutputNetworkFormat": "svg",
7152 }
7153
7154 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = (
7155 _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo)
7156 )
7157
7158 if re.match("^auto$", ParamsOptionValue, re.I):
7159 _ProcessOptionOpenFENetworkParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, RadialNetworkStatus)
7160 return ParamsInfo
7161
7162 for Index in range(0, len(ParamsOptionValueWords), 2):
7163 Name = ParamsOptionValueWords[Index].strip()
7164 Value = ParamsOptionValueWords[Index + 1].strip()
7165
7166 ParamName = CanonicalParamNamesMap[Name.lower()]
7167 ParamValue = Value
7168
7169 if re.match("^(LomapDistanceCutoff)$", ParamName, re.I):
7170 if not MiscUtil.IsFloat(Value):
7171 MiscUtil.PrintError(
7172 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be a float.\n'
7173 % (Value, ParamName, ParamsOptionName)
7174 )
7175 Value = float(Value)
7176 if Value <= 0:
7177 MiscUtil.PrintError(
7178 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
7179 % (ParamValue, ParamName, ParamsOptionName)
7180 )
7181 ParamValue = Value
7182 elif re.match("^(LomapMaxPathLength)$", ParamName, re.I):
7183 if not MiscUtil.IsInteger(Value):
7184 MiscUtil.PrintError(
7185 'The parameter value, %s, specified for parameter name, %s, using "%s" option must be an integer.\n'
7186 % (Value, ParamName, ParamsOptionName)
7187 )
7188 Value = int(Value)
7189 if Value <= 0:
7190 MiscUtil.PrintError(
7191 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: > 0\n'
7192 % (ParamValue, ParamName, ParamsOptionName)
7193 )
7194 ParamValue = Value
7195 elif re.match("^(LomapRequireCycleCovering|MinimalSpanningProgress|OutputEdges)$", ParamName, re.I):
7196 if not re.match("^(yes|no|true|false)$", Value, re.I):
7197 MiscUtil.PrintError(
7198 'The parameter value, %s, specified for parameter name, %s, using "%s" option is not a valid value. Supported values: yes or no'
7199 % (Value, Name, ParamsOptionName)
7200 )
7201 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False
7202 else:
7203 ParamValue = Value
7204
7205 # Set value...
7206 ParamsInfo[ParamName] = ParamValue
7207
7208 # Handle parameters with possible auto values...
7209 _ProcessOptionOpenFENetworkParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, RadialNetworkStatus)
7210
7211 return ParamsInfo
7212
7213
7214 def _ProcessOptionOpenFENetworkParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, RadialNetworkStatus):
7215 """Process parameters with possible auto values and perform validation."""
7216
7217 if RadialNetworkStatus:
7218 ParamName = "RadialCentralLigand"
7219 ParamValue = ParamsInfo[ParamName]
7220 if ParamValue is None or MiscUtil.IsEmpty(ParamValue):
7221 MiscUtil.PrintError(
7222 'The value specified, %s, for parameter name, %s, using option "%s" is not valid. You must specify a valid ligand name to generate a radial network.'
7223 % (ParamValue, ParamName, ParamsOptionName)
7224 )
7225
7226
7227 def _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo):
7228 """Validate and canonicalize parameter names."""
7229
7230 # Setup a canonical paramater names...
7231 ValidParamNames = []
7232 CanonicalParamNamesMap = {}
7233 for ParamName in sorted(ParamsInfo):
7234 ValidParamNames.append(ParamName)
7235 CanonicalParamNamesMap[ParamName.lower()] = ParamName
7236
7237 # Update default values...
7238 if ParamsDefaultInfo is not None:
7239 for ParamName in ParamsDefaultInfo:
7240 if ParamName not in ParamsInfo:
7241 MiscUtil.PrintError(
7242 'The default parameter name, %s, specified using "%s" option is not a valid name. Supported parameter names: %s'
7243 % (ParamName, ParamsDefaultInfo, " ".join(ValidParamNames))
7244 )
7245 ParamsInfo[ParamName] = ParamsDefaultInfo[ParamName]
7246
7247 ParamsOptionValue = ParamsOptionValue.strip()
7248 if not ParamsOptionValue:
7249 MiscUtil.PrintError('No valid parameter name and value pairs specified using "%s" option' % ParamsOptionName)
7250
7251 ParamsOptionValueWords = None
7252 if not re.match("^auto$", ParamsOptionValue, re.I):
7253 ParamsOptionValueWords = ParamsOptionValue.split(",")
7254 if len(ParamsOptionValueWords) % 2:
7255 MiscUtil.PrintError(
7256 'The number of comma delimited paramater names and values, %d, specified using "%s" option must be an even number.'
7257 % (len(ParamsOptionValueWords), ParamsOptionName)
7258 )
7259
7260 if ParamsOptionValueWords is not None:
7261 for Index in range(0, len(ParamsOptionValueWords), 2):
7262 Name = ParamsOptionValueWords[Index].strip()
7263 CanonicalName = Name.lower()
7264 if CanonicalName not in CanonicalParamNamesMap:
7265 MiscUtil.PrintError(
7266 'The parameter name, %s, specified using "%s" is not a valid name. Supported parameter names: %s'
7267 % (Name, ParamsOptionName, " ".join(ValidParamNames))
7268 )
7269
7270 return (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords)