1 #!/bin/env python 2 # File: OpenMMUtil.py 3 # Author: Manish Sud <msud@san.rr.com> 4 # 5 # Copyright (C) 2025 Manish Sud. All rights reserved. 6 # 7 # The functionality available in this script is implemented using OpenMM, an 8 # open source molecuar simulation package. 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 sys 32 import re 33 import glob 34 import multiprocessing as mp 35 import numpy as np 36 37 import openmm as mm 38 import openmm.app 39 40 import openmmforcefields as mmff 41 import openmmforcefields.generators 42 import openff as ff 43 import openff.toolkit 44 45 import pdbfixer 46 import mdtraj 47 48 import MiscUtil 49 50 __all__ = ["AddWaterBox", "DoAtomListsOverlap", "DoesAtomListOverlapWithSystemConstraints", "DoesSystemContainWater", "FreezeAtoms", "GetAtoms", "GetFormattedTotalSimulationTime", "InitializeBarostat", "InitializeIntegrator", "InitializeReporters", "InitializeSimulation", "InitializeSystem", "InitializeSystemGenerator", "MergeSmallMoleculeWithMacromolecule", "PerformAnnealing", "ProcessOptionOpenMMRestartParameters", "ProcessOptionOpenMMAtomsSelectionParameters", "ProcessOptionOpenMMAnnealingParameters", "ProcessOptionOpenMMForcefieldParameters", "ProcessOptionOpenMMIntegratorParameters", "ProcessOptionOpenMMPlatformParameters", "ProcessOptionOpenMMOutputParameters", "ProcessOptionOpenMMSimulationParameters", "ProcessOptionOpenMMSystemParameters", "ProcessOptionOpenMMWaterBoxParameters", "ReadPDBFile", "ReadSmallMoleculeFile", "RestraintAtoms", "SetupAnnealingParameters", "SetupIntegratorParameters", "SetupSimulationParameters", "SetupSystemGeneratorForcefieldsParameters", "WritePDBFile", "WriteSimulationStatePDBFile"] 51 52 def InitializeSystem(PDBFile, ForcefieldParamsInfo, SystemParamsInfo, WaterBoxAdd = False, WaterBoxParamsInfo = None, SmallMolFile = None, SmallMolID = "LIG"): 53 """Initialize OpenMM system using specified forcefields, system and water box 54 parameters along with a small molecule file and ID. 55 56 The ForcefieldParamsInfo parameter is a dictionary of name and value pairs for 57 system parameters and may be generated by calling the function named 58 ProcessOptionOpenMMForcefieldParameters(). 59 60 The SystemParamsInfo parameter is a dictionary of name and value pairs for 61 system parameters and may be generated by calling the function named 62 ProcessOptionOpenMMSystemParameters(). 63 64 The WaterBoxParamsInfo parameter is a dictionary of name and value pairs for 65 system parameters and may be generated by calling the function named 66 ProcessOptionOpenMMWaterBoxParameters(). 67 68 Arguments: 69 PDBFile (str): PDB file name.. 70 ForcefieldParamsInfo (dict): Parameter name and value pairs. 71 SystemParamsInfo (dict): Parameter name and value pairs. 72 WaterBoxAdd (bool): Add water box. 73 WaterBoxParamsInfo (dict): Parameter name and value pairs. 74 SmallMolFile (str): Small molecule file name.. 75 SmallMolID (str): Three letter small molecule ID 76 77 Returns: 78 Object: OpenMM system object. 79 Object: OpenMM topology object. 80 Object: OpenMM positions object. 81 82 Examples: 83 84 ... ... ... 85 OptionsInfo["ForcefieldParams"] = 86 OpenMMUtil.ProcessOptionOpenMMForcefieldParameters( 87 "--forcefieldParams", Options["--forcefieldParams"]) 88 ... ... ... 89 OptionsInfo["SystemParams"] = 90 OpenMMUtil.ProcessOptionOpenMMSystemParameters("--systemParams", 91 Options["--systemParams"]) 92 ... ... ... 93 OptionsInfo["WaterBoxParams"] = 94 OpenMMUtil.ProcessOptionOpenMMWaterBoxParameters( 95 "--waterBoxParams", Options["--waterBoxParams"]) 96 ... ... ... 97 System, Topology, Positions = OpenMMUtil.InitializeSystem( 98 OptionsInfo["Infile"], OptionsInfo["ForcefieldParams"], 99 OptionsInfo["SystemParams"], OptionsInfo["WaterBox"], 100 OptionsInfo["WaterBoxParams"], OptionsInfo["SmallMolFile"], 101 OptionsInfo["SmallMolID"]) 102 103 """ 104 105 # Read PDB file file... 106 MiscUtil.PrintInfo("\nReading PDB file %s..." % PDBFile) 107 PDBHandle = ReadPDBFile(PDBFile) 108 109 ModellerHandle = mm.app.Modeller(PDBHandle.topology, PDBHandle.positions) 110 MiscUtil.PrintInfo("Number of residues: %s; Number of atoms: %s" % (ModellerHandle.topology.getNumResidues(), ModellerHandle.topology.getNumAtoms())) 111 112 # Read small molecule file... 113 SmallMols = None 114 if SmallMolFile is not None: 115 MiscUtil.PrintInfo("\nReading small molecule file %s..." % SmallMolFile) 116 SmallMol = ReadSmallMoleculeFile(SmallMolFile) 117 if SmallMol is None: 118 MiscUtil.PrintError("Failed to read small molecule file: %s" % SmallMolFile) 119 SmallMols = [SmallMol] 120 121 MiscUtil.PrintInfo("\nGenerating macromolecule and small molecule complex...") 122 MergeSmallMoleculeWithMacromolecule(ModellerHandle, SmallMol, SmallMolID) 123 MiscUtil.PrintInfo("Number of residues: %s; Number of atoms: %s" % (ModellerHandle.topology.getNumResidues(), ModellerHandle.topology.getNumAtoms())) 124 125 # Initialize system generator... 126 BiopolymerForcefield = ForcefieldParamsInfo["Biopolymer"] 127 SmallMoleculeForcefield = ForcefieldParamsInfo["SmallMolecule"] 128 WaterForcefield = ForcefieldParamsInfo["Water"] 129 AdditionalForcefiedsList = ForcefieldParamsInfo["AdditionalList"] 130 SystemGeneratorHandle = InitializeSystemGenerator(BiopolymerForcefield, SmallMoleculeForcefield, WaterForcefield, SystemParamsInfo, SmallMols, AdditionalForcefiedsList) 131 132 if WaterBoxAdd: 133 AddWaterBox(ModellerHandle, SystemGeneratorHandle, WaterBoxParamsInfo) 134 MiscUtil.PrintInfo("Number of residues: %s; Number of atoms: %s" % (ModellerHandle.topology.getNumResidues(), ModellerHandle.topology.getNumAtoms())) 135 else: 136 MiscUtil.PrintInfo("\nSkipping addition of a water box...") 137 if DoesSystemContainWater(ModellerHandle.topology): 138 if ForcefieldParamsInfo["ImplicitWater"]: 139 MiscUtil.PrintInfo("Your system contains water molecules during the use of implicit water forcefield. The combination of biopolymer and water forcefields, %s and %s, specified using \"--forcefieldParams\" option may not be valid. You may consider removing water molecules from your system or specify a valid combination of biopolymer and water forcefields for explicit water." % (ForcefieldParamsInfo["Biopolymer"], ForcefieldParamsInfo["Water"])) 140 141 MiscUtil.PrintInfo("\nBuilding system...") 142 SystemHandle = SystemGeneratorHandle.create_system(ModellerHandle.topology, molecules = SmallMols) 143 144 MiscUtil.PrintInfo("Periodic boundary conditions: %s" % ("Yes" if DoesSystemUsesPeriodicBoundaryConditions(SystemHandle) else "No")) 145 146 return (SystemHandle, ModellerHandle.topology, ModellerHandle.positions) 147 148 def InitializeSystemGenerator(BiopolymerForcefield, SmallMoleculeForcefield, WaterForcefield, SystemParamsInfo, SmallMols, AdditionalForcefieldsList = None): 149 """Initialize MMFF system generator using specified forcefields and system parameters 150 along with a list of molecules. 151 152 The SystemParamsInfo parameter is a dictionary of name and value pairs for 153 system parameters and may be generated by calling the function named 154 ProcessOptionOpenMMSystemParameters(). 155 156 Arguments: 157 BiopolymerForcefield (str): Biopolymer force field name. 158 SmallMoleculeForcefield (str): Small molecule force field name. 159 WaterForcefield (str): Water force field name. 160 SystemParamsInfo (dict): Parameter name and value pairs. 161 SmallMols (list): List of OpenFF toolkit molecule objects. 162 AdditionalForcefieldsList (list): List of any additional forcefield 163 names 164 165 Returns: 166 Object: MMFF system generator object. 167 168 Examples: 169 170 OptionsInfo["SystemParams"] = 171 OpenMMUtil.ProcessOptionOpenMMSystemParameters("--systemParams", 172 Options["--systemParams"]) 173 ... ... ... 174 SystemGeneratorHandle = OpenMMUtil.InitializeSystemGenerator( 175 BiopolymerForcefield, SmallMoleculeForcefield, WaterForcefield, 176 OptionsInfo["SystemParams"], SmallMols, AdditionalForcefiedsList) 177 178 """ 179 180 (ForcefieldParams, PeriodicForcefieldParams, NonPeriodicForcefieldParams) = SetupSystemGeneratorForcefieldsParameters(SystemParamsInfo) 181 182 AdditionalForcefieldMsg = "" 183 if AdditionalForcefieldsList is not None: 184 AdditionalForcefieldMsg = "; Additional forcefield(s): %s" % ", ".join(AdditionalForcefieldsList) 185 186 MiscUtil.PrintInfo("\nInitializing system generator (Biopolymer forcefield: %s; Small molecule forcefield: %s; Water forcefield: %s%s)..." % (BiopolymerForcefield, SmallMoleculeForcefield,WaterForcefield, AdditionalForcefieldMsg)) 187 188 ForcefieldsList = [BiopolymerForcefield, WaterForcefield] 189 if AdditionalForcefieldsList is not None: 190 ForcefieldsList.extend(AdditionalForcefieldsList) 191 192 SystemGeneratorHandle = mmff.generators.SystemGenerator(forcefields = ForcefieldsList, small_molecule_forcefield = SmallMoleculeForcefield, molecules = SmallMols, forcefield_kwargs = ForcefieldParams, periodic_forcefield_kwargs = PeriodicForcefieldParams, nonperiodic_forcefield_kwargs = NonPeriodicForcefieldParams) 193 194 return SystemGeneratorHandle 195 196 def InitializeIntegrator(ParamsInfo, ConstraintErrorTolerance): 197 """Initialize integrator. 198 199 The ParamsInfo parameter is a dictionary of name and value pairs for 200 integrator parameters and may be generated by calling the function named 201 ProcessOptionOpenMMIntegratorParameters(). 202 203 Arguments: 204 ParamsInfo (dict): Parameter name and value pairs. 205 ConstraintErrorTolerance (float): Distance tolerance for 206 constraints as a fraction of the constrained distance. 207 208 Returns: 209 Object: OpenMM integrator object. 210 211 Examples: 212 213 OptionsInfo["IntegratorParams"] = 214 OpenMMUtil.ProcessOptionOpenMMIntegratorParameters( 215 "--integratorParams", Options["--integratorParams"], 216 HydrogenMassRepartioningStatus = 217 OptionsInfo["SystemParams"]["HydrogenMassRepartioning"]) 218 ... ... ... 219 Integrator = OpenMMUtil.InitializeIntegrator( 220 OptionsInfo["IntegratorParams"], 221 OptionsInfo["SystemParams"]["ConstraintErrorTolerance"]) 222 223 """ 224 225 IntegratorParamsInfo = SetupIntegratorParameters(ParamsInfo) 226 227 IntegratorName = IntegratorParamsInfo["Integrator"] 228 RandomSeed = IntegratorParamsInfo["RandomSeed"] 229 StepSize = IntegratorParamsInfo["StepSize"] 230 Temperature = IntegratorParamsInfo["Temperature"] 231 FrictionCoefficient = IntegratorParamsInfo["FrictionCoefficient"] 232 233 MiscUtil.PrintInfo("\nIntializing integrator (Name: %s; StepSize: %s; Temperature: %s)..." % (IntegratorName, StepSize, Temperature)) 234 235 if re.match("^LangevinMiddle$", IntegratorName, re.I): 236 Integrator = mm.LangevinMiddleIntegrator(Temperature, FrictionCoefficient, StepSize) 237 elif re.match("^Langevin$", IntegratorName, re.I): 238 Integrator = mm.LangevinIntegrator(Temperature, FrictionCoefficient, StepSize) 239 elif re.match("^NoseHoover$", IntegratorName, re.I): 240 Integrator = mm.NoseHooverIntegrator(Temperature, FrictionCoefficient, StepSize) 241 elif re.match("^Brownian$", IntegratorName, re.I): 242 Integrator = mm.BrownianIntegrator(Temperature, FrictionCoefficient, StepSize) 243 else: 244 MiscUtil.PrintError("The parameter value specified, %s, for parameter name, integrator, for option \"--integratorParams\" is not a valid value. Supported values: LangevinMiddle, Langevin, NoseHoover, or Brownian" % IntegratorName) 245 246 Integrator.setConstraintTolerance(ConstraintErrorTolerance) 247 248 if RandomSeed is not None: 249 if re.match("^(LangevinMiddle|Langevin|Brownian)$", IntegratorName, re.I): 250 MiscUtil.PrintInfo("Setting random number seed for integrator to %s..." % RandomSeed) 251 Integrator.setRandomNumberSeed(RandomSeed) 252 else: 253 MiscUtil.PrintInfo("Skipping setting of random number seed. Not supported for integrator %s..." % IntegratorName) 254 255 return Integrator 256 257 def InitializeBarostat(ParamsInfo): 258 """Initialize barostat. 259 260 The ParamsInfo parameter is a dictionary of name and value pairs for 261 integrator parameters and may be generated by calling the function named 262 ProcessOptionOpenMMIntegratorParameters(). 263 264 Arguments: 265 ParamsInfo (dict): Parameter name and value pairs. 266 267 Returns: 268 Object: OpenMM barostat object. 269 270 Examples: 271 272 OptionsInfo["IntegratorParams"] = 273 OpenMMUtil.ProcessOptionOpenMMIntegratorParameters( 274 "--integratorParams", Options["--integratorParams"], 275 HydrogenMassRepartioningStatus = 276 OptionsInfo["SystemParams"]["HydrogenMassRepartioning"]) 277 ... ... ... 278 Barostat = OpenMMUtil.InitializeBarostat( 279 OptionsInfo["IntegratorParams"]) 280 281 """ 282 IntegratorParamsInfo = SetupIntegratorParameters(ParamsInfo) 283 284 BarostatName = IntegratorParamsInfo["Barostat"] 285 if re.match("^MonteCarlo$", BarostatName, re.I): 286 MiscUtil.PrintInfo("\nInitializing Monte Carlo barostat (Pressure: %s)... " % (IntegratorParamsInfo["Pressure"])) 287 Barostat = mm.MonteCarloBarostat(IntegratorParamsInfo["Pressure"], IntegratorParamsInfo["Temperature"], IntegratorParamsInfo["BarostatInterval"]) 288 elif re.match("^MonteCarloMembrane$", BarostatName, re.I): 289 MiscUtil.PrintInfo("\nInitializing Monte Carlo membrane barostat (Pressure: %s; SurfaceTension: %s; XYMode: %s; ZMode: %s)... " % (IntegratorParamsInfo["Pressure"], IntegratorParamsInfo["SurfaceTension"], IntegratorParamsInfo["XYModeSpecified"], IntegratorParamsInfo["ZModeSpecified"])) 290 Barostat = mm.MonteCarloMembraneBarostat(IntegratorParamsInfo["Pressure"], IntegratorParamsInfo["SurfaceTension"], IntegratorParamsInfo["Temperature"], IntegratorParamsInfo["XYMode"], IntegratorParamsInfo["ZMode"], IntegratorParamsInfo["BarostatInterval"]) 291 else: 292 MiscUtil.PrintError("The parameter value specified, %s, for parameter name, barostat, for option \"--integratorParams\" is not a valid value. Supported values: MonteCarlo or MonteCarloMembrane" % BarostatName) 293 294 if IntegratorParamsInfo["RandomSeed"] is not None: 295 RandomSeed = IntegratorParamsInfo["RandomSeed"] 296 MiscUtil.PrintInfo("Setting random number seed for barostat to %s..." % RandomSeed) 297 Barostat.setRandomNumberSeed(RandomSeed) 298 299 return Barostat 300 301 def InitializeSimulation(System, Integrator, Topology, Positions, PlatformParamsInfo): 302 """Initialize simulation. 303 304 The PlatformParamsInfo parameter is a dictionary of name and value pairs for 305 platform parameters and may be generated by calling the function named 306 ProcessOptionOpenMMPlatformParameters(). 307 308 Arguments: 309 System (object): OpenMM system object. 310 Integrator (object): OpenMM integrator object. 311 Topology (object): OpenMM topology object. 312 Positons (object): OpenMM Positions object. 313 PlatformParamsInfo (dict): Parameter name and value pairs. 314 315 Returns: 316 Object: OpenMM simulation object. 317 318 Examples: 319 320 ParamsDefaultInfoOverride = {"Name": Options["--platform"], 321 "Threads": 1} 322 OptionsInfo["PlatformParams"] = 323 OpenMMUtil.ProcessOptionOpenMMPlatformParameters("--platformParams", 324 Options["--platformParams"], ParamsDefaultInfoOverride) 325 ... ... ... 326 Simulation = OpenMMUtil.InitializeSimulation(System, Integrator, Topology, 327 Positions, OptionsInfo["PlatformParams"]) 328 329 """ 330 331 PlatformName, PlatformProperties, PlatformMsg = SetupPlatformParameters(PlatformParamsInfo) 332 MiscUtil.PrintInfo("\nInitializing simulation (%s)..." % PlatformMsg) 333 334 try: 335 PlatformHandle = mm.Platform.getPlatformByName(PlatformName) 336 except Exception as ErrMsg: 337 MiscUtil.PrintInfo("") 338 MiscUtil.PrintError("Failed to get platform %s:\n%s\n" % (PlatformName, ErrMsg)) 339 340 try: 341 SimulationHandle = mm.app.Simulation(Topology, System, Integrator, PlatformHandle, PlatformProperties) 342 except Exception as ErrMsg: 343 MiscUtil.PrintInfo("") 344 MiscUtil.PrintError("Failed to initialize simulation: %s\n" % (ErrMsg)) 345 346 SimulationHandle.context.setPositions(Positions) 347 348 return (SimulationHandle) 349 350 def InitializeReporters(OutputParamsInfo, TotalSteps, DataOutAppendStatus): 351 """Initialize reporters for writing data to trajectory, log, and checkpoint 352 files along with reporting to the stdout. 353 354 The OutputParamsInfo parameter is a dictionary of name and value pairs for 355 output parameters and may be generated by calling the function named 356 ProcessOptionOpenMMOutputParameters(). 357 358 Arguments: 359 OutputParamsInfo (dict): Parameter name and value pairs. 360 TotalSteps (int): Total number of simulation steps. 361 DataOutAppendStatus (bool): Append data to trajectory and log file. 362 363 Returns: 364 Object: OpenMM trajectory reporter object. 365 Object: OpenMM data log file reporter object. 366 Object: OpenMM stodut reporter object. 367 Object: OpenMM checkpoint reporter object. 368 369 Examples: 370 371 if OptionsInfo["NVTMode"]: 372 ParamsDefaultInfoOverride = {"DataOutType": "Step Speed Progress 373 PotentialEnergy Temperature Time Volume"} 374 else: 375 ParamsDefaultInfoOverride = {"DataOutType": "Step Speed Progress 376 PotentialEnergy Temperature Time Density"} 377 OptionsInfo["OutputParams"] = 378 OpenMMUtil.ProcessOptionOpenMMOutputParameters("--outputParams", 379 Options["--outputParams"], OptionsInfo["OutfilePrefix"], 380 ParamsDefaultInfoOverride) 381 ProcessOutfileNames() 382 ... ... ... 383 (TrajReporter, DataLogReporter, DataStdoutReporter, CheckpointReporter) 384 = OpenMMUtil.InitializeReporters(OptionsInfo["OutputParams"], 385 OptionsInfo["SimulationParams"]["Steps"], OptionsInfo["DataOutAppendMode"]) 386 387 """ 388 389 (TrajReporter, DataLogReporter, DataStdoutReporter, CheckpointReporter) = [None] * 4 390 if OutputParamsInfo["Traj"]: 391 if re.match("^DCD$", OutputParamsInfo["TrajFormat"], re.I): 392 TrajReporter = mm.app.DCDReporter(OutputParamsInfo["TrajFile"], OutputParamsInfo["TrajSteps"], append = DataOutAppendStatus) 393 elif re.match("^XTC$", OutputParamsInfo["TrajFormat"], re.I): 394 if not DataOutAppendStatus: 395 # Remove existing traj file; otherwise, XTCReporter fails... 396 if os.path.isfile(OutputParamsInfo["TrajFile"]): 397 os.remove(OutputParamsInfo["TrajFile"]) 398 TrajReporter = mm.app.XTCReporter(OutputParamsInfo["TrajFile"], OutputParamsInfo["TrajSteps"], append = DataOutAppendStatus) 399 else: 400 MiscUtil.PrintError("The parameter value specified, %s, for parameter name, trajFormat, for option \"--outputParams\" is not a valid value. Supported format: DCD or XTC") 401 402 if OutputParamsInfo["Checkpoint"]: 403 CheckpointReporter = mm.app.CheckpointReporter(OutputParamsInfo["CheckpointFile"], OutputParamsInfo["CheckpointSteps"]) 404 405 DataOutTypeStatusMap = OutputParamsInfo["DataOutTypeStatusMap"] 406 if OutputParamsInfo["DataLog"]: 407 DataLogReporter = mm.app.StateDataReporter(OutputParamsInfo["DataLogFile"], OutputParamsInfo["DataLogSteps"], totalSteps = TotalSteps, step = DataOutTypeStatusMap["Step"], time = DataOutTypeStatusMap["Time"], speed = DataOutTypeStatusMap["Speed"], progress = DataOutTypeStatusMap["Progress"], elapsedTime = DataOutTypeStatusMap["ElapsedTime"], remainingTime = DataOutTypeStatusMap["RemainingTime"], potentialEnergy = DataOutTypeStatusMap["PotentialEnergy"], kineticEnergy = DataOutTypeStatusMap["KineticEnergy"], totalEnergy = DataOutTypeStatusMap["TotalEnergy"], temperature = DataOutTypeStatusMap["Temperature"], volume = DataOutTypeStatusMap["Volume"], density = DataOutTypeStatusMap["Density"], separator = OutputParamsInfo["DataOutDelimiter"], append = DataOutAppendStatus) 408 409 if OutputParamsInfo["DataStdout"]: 410 DataStdoutReporter = mm.app.StateDataReporter(sys.stdout, OutputParamsInfo["DataStdoutSteps"], totalSteps = TotalSteps, step = DataOutTypeStatusMap["Step"], time = DataOutTypeStatusMap["Time"], speed = DataOutTypeStatusMap["Speed"], progress = DataOutTypeStatusMap["Progress"], elapsedTime = DataOutTypeStatusMap["ElapsedTime"], remainingTime = DataOutTypeStatusMap["RemainingTime"], potentialEnergy = DataOutTypeStatusMap["PotentialEnergy"], kineticEnergy = DataOutTypeStatusMap["KineticEnergy"], totalEnergy = DataOutTypeStatusMap["TotalEnergy"], temperature = DataOutTypeStatusMap["Temperature"], volume = DataOutTypeStatusMap["Volume"], density = DataOutTypeStatusMap["Density"], separator = OutputParamsInfo["DataOutDelimiter"]) 411 412 return (TrajReporter, DataLogReporter, DataStdoutReporter, CheckpointReporter) 413 414 def PerformAnnealing(Simulation, Integrator, Barostat, TemperatureStart, TemperatureEnd, TemperatureChange, SimulationSteps): 415 """Perform annealing by heating or cooling the system from start to end 416 temperature. 417 418 The temperature is increased or decreased from start to end temperature by 419 temperature to perform annealing following by performing simulations for a 420 specified number of steps after each temperature step. 421 422 Arguments: 423 System (object): OpenMM system object. 424 Integrator (object): OpenMM integrator object. 425 Barostat (object): OpenMM integrator object. 426 TemperatureStart (float): Start temperature. 427 TemperatureEnd (float): End temperature. 428 TemperatureChange (int): Temperature step size to heat or cool the 429 system from start to end temperature. 430 SimulationSteps (fint): Number of simulations steps to perform after 431 each temperature step. 432 433 Returns: 434 int: Total number of simulation steps. 435 436 Examples: 437 438 ... ... ... 439 TotalInitialSimulationSteps = OpenMMUtil.PerformAnnealing(Simulation, 440 Integrator, Barostat, InitialStart, InitialEnd, InitialChange, InitialSteps) 441 442 """ 443 444 if TemperatureStart < TemperatureEnd: 445 TemperatureRange = np.arange(TemperatureStart, TemperatureEnd, TemperatureChange) 446 else: 447 TemperatureRange = np.arange(TemperatureStart, TemperatureEnd, -TemperatureChange) 448 449 TemperatureRange = TemperatureRange.tolist() 450 TemperatureRange.append(TemperatureEnd) 451 452 TotalSimulationSteps = 0 453 for Temperature in TemperatureRange: 454 Temperature = Temperature * mm.unit.kelvin 455 456 Integrator.setTemperature(Temperature) 457 if Barostat is not None: 458 Barostat.setDefaultTemperature(Temperature) 459 460 Simulation.step(SimulationSteps) 461 TotalSimulationSteps += SimulationSteps 462 463 return TotalSimulationSteps 464 465 def AddWaterBox(ModellerHandle, SystemGeneratorHandle, WaterBoxParamsInfo): 466 """Add a water box. 467 468 The WaterBoxParamsInfo parameter is a dictionary of name and value pairs for 469 waterbox parameters and may be generated by calling the function named 470 ProcessOptionOpenMMWaterBoxParameters(). 471 472 Arguments: 473 ModellerHandle (object): OpenMM modeller object. 474 SystemGeneratorHandle (object): OpenMM system generator object. 475 WaterBoxParamsInfo (dict): Parameter name and value pairs. 476 477 Returns: 478 None. 479 480 Examples: 481 482 OptionsInfo["WaterBoxParams"] = 483 OpenMMUtil.ProcessOptionOpenMMWaterBoxParameters("--waterBoxParams", 484 Options["--waterBoxParams"]) 485 ... ... ... 486 OpenMMUtil.AddWaterBox(ModellerHandle, SystemGeneratorHandle, 487 OptionsInfo["WaterBoxParams"]) 488 489 """ 490 491 MiscUtil.PrintInfo("\nRemoving any existing waters...") 492 ModellerHandle.deleteWater() 493 494 MiscUtil.PrintInfo("\nAdding a water box...") 495 496 Size, Padding, Shape = [None] * 3 497 if WaterBoxParamsInfo["ModeSize"]: 498 SizeList = WaterBoxParamsInfo["SizeList"] 499 Size = mm.Vec3(SizeList[0], SizeList[1], SizeList[2]) * mm.unit.nanometer 500 elif WaterBoxParamsInfo["ModePadding"]: 501 Padding = WaterBoxParamsInfo["Padding"] * mm.unit.nanometer 502 Shape = WaterBoxParamsInfo["Shape"] 503 else: 504 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, mode, using \"--waterBoxParams\" option is not a valid value. Supported values: Size Padding \n" % (WaterBoxParamsInfo["Mode"])) 505 506 IonicStrength = WaterBoxParamsInfo["IonicStrength"] * mm.unit.molar 507 508 ModellerHandle.addSolvent(SystemGeneratorHandle.forcefield, model = WaterBoxParamsInfo["Model"], boxSize = Size, boxVectors = None, padding = Padding, numAdded = None, boxShape = Shape, positiveIon = WaterBoxParamsInfo["IonPositive"], negativeIon = WaterBoxParamsInfo["IonNegative"], ionicStrength = IonicStrength, neutralize = True) 509 510 def SetupSystemGeneratorForcefieldsParameters(SystemParamsInfo): 511 """Setup forcefied parameters for OpenMM API calls. 512 513 The SystemParamsInfo parameter is a dictionary of name and value pairs for 514 system parameters and may be generated by calling the function named 515 ProcessOptionOpenMMSystemParameters(). 516 517 Arguments: 518 SystemParamsInfo (dict): Parameter name and value pairs. 519 520 Returns: 521 dict: Forcefield parameter name and value pairs. 522 dictionary2: Periodic forcefield parameter name and value pairs. 523 dictionary3: Non-periodic parameter name and value pairs. 524 525 Examples: 526 527 OptionsInfo["SystemParams"] = 528 OpenMMUtil.ProcessOptionOpenMMSystemParameters("--systemParams", 529 Options["--systemParams"]) 530 ... ... ... 531 (ForcefieldParams, PeriodicForcefieldParams, NonPeriodicForcefieldParams) 532 = SetupSystemGeneratorForcefieldsParameters(OptionsInfo["SystemParams"]) 533 534 """ 535 536 ForcefieldParams = {"constraints": SystemParamsInfo["Constraints"], "rigidWater": SystemParamsInfo["RigidWater"], "removeCMMotion": SystemParamsInfo["RemoveCMMotion"]} 537 if SystemParamsInfo["HydrogenMassRepartioning"]: 538 ForcefieldParams["hydrogenMass"] = SystemParamsInfo["HydrogenMass"] * mm.unit.amu 539 540 NonbondedCutoff = SystemParamsInfo["NonbondedCutoff"] * mm.unit.nanometers 541 PeriodicForcefieldParams = {"nonbondedMethod": SystemParamsInfo["NonbondedMethodPeriodic"], "nonbondedCutoff": NonbondedCutoff, "ewaldErrorTolerance": SystemParamsInfo["EwaldErrorTolerance"]} 542 NonPeriodicForcefieldParams = {"nonbondedMethod": SystemParamsInfo["NonbondedMethodNonPeriodic"], "nonbondedCutoff" : NonbondedCutoff} 543 544 return (ForcefieldParams, PeriodicForcefieldParams, NonPeriodicForcefieldParams) 545 546 def SetupPlatformParameters(ParamsInfo): 547 """Setup platform parameters for OpenMM calls. 548 549 The ParamsInfo parameter is a dictionary of name and value pairs for 550 platform parameters and may be generated by calling the function named 551 ProcessOptionOpenMMPlatformParameters(). 552 553 Arguments: 554 ParamsInfo (dict): Parameter name and value pairs. 555 556 Returns: 557 str: PlatformName. 558 dict: Platform properities parameter name and values pairs. 559 str: Text message describing platform. 560 561 Examples: 562 563 ParamsDefaultInfoOverride = {"Name": Options["--platform"], 564 "Threads": 1} 565 OptionsInfo["PlatformParams"] = 566 OpenMMUtil.ProcessOptionOpenMMPlatformParameters("--platformParams", 567 Options["--platformParams"], ParamsDefaultInfoOverride) 568 ... ... ... 569 PlatformName, PlatformProperties, PlatformMsg = 570 SetupPlatformParameters(PlatformParamsInfo) 571 572 """ 573 574 PlatformName = ParamsInfo["Name"] 575 ParamNames = None 576 577 if re.match("^CPU$", PlatformName, re.I): 578 ParamNames = ["Threads"] 579 elif re.match("^CUDA$", PlatformName, re.I): 580 ParamNames = ["DeviceIndex", "DeterministicForces", "Precision", "TempDirectory", "UseBlockingSync", "UseCpuPme"] 581 elif re.match("^OpenCL$", PlatformName, re.I): 582 ParamNames = ["DeviceIndex", "OpenCLPlatformIndex", "Precision", "UseCpuPme"] 583 elif re.match("^Reference$", PlatformName, re.I): 584 ParamNames = None 585 else: 586 MiscUtil.PrintError("The parameter value specified, %s, for parameter name, name, for option \"--platformParams\" is not a valid value. Supported values: CPU, CUDA, OpenCL, or Reference") 587 588 PlatformProperties = None 589 if ParamNames is not None: 590 FirstValue = True 591 for ParamName in ParamNames: 592 ParamValue = ParamsInfo[ParamName] 593 if ParamValue is not None: 594 if FirstValue: 595 FirstValue = False 596 PlatformProperties = {} 597 PlatformProperties[ParamName] = ParamValue 598 599 PlatformMsg = "Platform: %s" % PlatformName 600 if re.match("^CPU$", PlatformName, re.I): 601 Threads = ParamsInfo["Threads"] 602 if Threads is None or Threads == "0": 603 Threads = "auto" 604 PlatformMsg = "Platform: %s; Threads: %s" % (PlatformName, Threads) 605 elif re.match("^(CUDA|OpenCL)$", PlatformName, re.I): 606 DeviceIndex = "auto" if ParamsInfo["DeviceIndex"] is None else ParamsInfo["DeviceIndex"] 607 Precision = "auto" if ParamsInfo["Precision"] is None else ParamsInfo["Precision"] 608 PlatformMsg = "Platform: %s; DeviceIndex: %s; Precision: %s" % (PlatformName, DeviceIndex, Precision) 609 610 return (PlatformName, PlatformProperties, PlatformMsg) 611 612 def SetupAnnealingParameters(ParamsInfo): 613 """Setup annealing parameters for OpenMM API calls. 614 615 The ParamsInfo parameter is a dictionary of name and value pairs for 616 annealing parameters and may be generated by calling the function named 617 ProcessOptionOpenMMAnnealingParameters(). 618 619 Arguments: 620 ParamsInfo (dict): Parameter name and value pairs. 621 622 Returns: 623 dict: Integrator parameter name and values pairs. 624 625 Examples: 626 627 OptionsInfo["AnnealingParams"] = 628 OpenMMUtil.ProcessOptionOpenMMAnnealingParameters( 629 "--annealingParams", Options["--annealingParams"], 630 ... ... ... 631 IntegratorParams = SetupIntegratorParameters( 632 OptionsInfo["IntegratorParams"]) 633 634 """ 635 636 ParamsInfoWithUnits = {} 637 638 ParamsInfoWithUnits["InitialStart"] = ParamsInfo["InitialStart"] * mm.unit.kelvin 639 ParamsInfoWithUnits["InitialEnd"] = ParamsInfo["InitialEnd"] * mm.unit.kelvin 640 ParamsInfoWithUnits["InitialChange"] = ParamsInfo["InitialChange"] * mm.unit.kelvin 641 ParamsInfoWithUnits["InitialSteps"] = ParamsInfo["InitialSteps"] 642 643 ParamsInfoWithUnits["InitialEquilibrationSteps"] = ParamsInfo["InitialEquilibrationSteps"] 644 645 ParamsInfoWithUnits["Cycles"] = ParamsInfo["Cycles"] 646 ParamsInfoWithUnits["CycleStart"] = ParamsInfo["CycleStart"] * mm.unit.kelvin 647 ParamsInfoWithUnits["CycleEnd"] = ParamsInfo["CycleEnd"] * mm.unit.kelvin 648 ParamsInfoWithUnits["CycleChange"] = ParamsInfo["CycleChange"] * mm.unit.kelvin 649 ParamsInfoWithUnits["CycleSteps"] = ParamsInfo["CycleSteps"] 650 651 ParamsInfoWithUnits["CycleEquilibrationSteps"] = ParamsInfo["CycleEquilibrationSteps"] 652 653 ParamsInfoWithUnits["FinalEquilibrationSteps"] = ParamsInfo["FinalEquilibrationSteps"] 654 655 return ParamsInfoWithUnits 656 657 def SetupIntegratorParameters(ParamsInfo): 658 """Setup integrator parameters for OpenMM API calls. 659 660 The ParamsInfo parameter is a dictionary of name and value pairs for 661 integrator parameters and may be generated by calling the function named 662 ProcessOptionOpenMMIntegratorParameters(). 663 664 Arguments: 665 ParamsInfo (dict): Parameter name and value pairs. 666 667 Returns: 668 dict: Integrator parameter name and values pairs. 669 670 Examples: 671 672 OptionsInfo["IntegratorParams"] = 673 OpenMMUtil.ProcessOptionOpenMMIntegratorParameters( 674 "--integratorParams", Options["--integratorParams"], 675 HydrogenMassRepartioningStatus = 676 OptionsInfo["SystemParams"]["HydrogenMassRepartioning"]) 677 ... ... ... 678 IntegratorParams = SetupIntegratorParameters( 679 OptionsInfo["IntegratorParams"]) 680 681 """ 682 683 ParamsInfoWithUnits = {} 684 685 ParamsInfoWithUnits["Integrator"] = ParamsInfo["Integrator"] 686 687 ParamsInfoWithUnits["RandomSeed"] = ParamsInfo["RandomSeed"] 688 689 ParamsInfoWithUnits["FrictionCoefficient"] = ParamsInfo["FrictionCoefficient"]/mm.unit.picosecond 690 ParamsInfoWithUnits["StepSize"] = ParamsInfo["StepSize"] * mm.unit.femtoseconds 691 ParamsInfoWithUnits["Temperature"] = ParamsInfo["Temperature"] * mm.unit.kelvin 692 693 ParamsInfoWithUnits["Barostat"] = ParamsInfo["Barostat"] 694 695 ParamsInfoWithUnits["Pressure"] = ParamsInfo["Pressure"] * mm.unit.atmospheres 696 ParamsInfoWithUnits["BarostatInterval"] = ParamsInfo["BarostatInterval"] 697 698 SurfaceTensionInAngstroms = ParamsInfo["SurfaceTension"] 699 SurfaceTension = SurfaceTensionInAngstroms * mm.unit.atmospheres * mm.unit.angstroms 700 701 SurfaceTensionInNanometers = SurfaceTension.value_in_unit(mm.unit.atmospheres * mm.unit.nanometer) 702 ParamsInfoWithUnits["SurfaceTension"] = SurfaceTensionInNanometers * mm.unit.atmospheres * mm.unit.nanometers 703 704 XYMode = ParamsInfo["XYMode"] 705 XYModeSpecified = "" 706 if re.match("^Anisotropic$", XYMode, re.I): 707 XYMode = mm.MonteCarloMembraneBarostat.XYAnisotropic 708 XYModeSpecified = "Anisotropic" 709 elif re.match("^Isotropic$", XYMode, re.I): 710 XYMode = mm.MonteCarloMembraneBarostat.XYIsotropic 711 XYModeSpecified = "Isotropic" 712 else: 713 MiscUtil.PrintError("The parameter value specified, %s, for parameter name, xymode, for option \"--integratorParams\" is not a valid value. Supported values: Anisotropic or Isotropic" % XYMode) 714 ParamsInfoWithUnits["XYMode"] = XYMode 715 ParamsInfoWithUnits["XYModeSpecified"] = XYModeSpecified 716 717 ZMode = ParamsInfo["ZMode"] 718 ZModeSpecified = "" 719 if re.match("^Fixed$", ZMode, re.I): 720 ZMode = mm.MonteCarloMembraneBarostat.ZFixed 721 ZModeSpecified = "Fixed" 722 elif re.match("^Free$", ZMode, re.I): 723 ZMode = mm.MonteCarloMembraneBarostat.ZFree 724 ZModeSpecified = "Free" 725 else: 726 MiscUtil.PrintError("The parameter value specified, %s, for parameter name, zmode, for option \"--integratorParams\" is not a valid value. Supported values: Fixed or Free" % ZMode) 727 ParamsInfoWithUnits["ZMode"] = ZMode 728 ParamsInfoWithUnits["ZModeSpecified"] = ZModeSpecified 729 730 return ParamsInfoWithUnits 731 732 def SetupSimulationParameters(ParamsInfo): 733 """Setup simulation parameters for OpenMM API calls. 734 735 The ParamsInfo parameter is a dictionary of name and value pairs for 736 integrator parameters and may be generated by calling the function named 737 ProcessOptionOpenMSimulationParameters(). 738 739 Arguments: 740 ParamsInfo (dict): Parameter name and value pairs. 741 742 Returns: 743 dict: Integrator parameter name and values pairs. 744 745 Examples: 746 747 OptionsInfo["SimulationParams"] = 748 OpenMMUtil.ProcessOptionOpenMMSimulationParameters( 749 "--simulationParams", Options["--simulationParams"]) 750 ... ... ... 751 SimulationParams = SetupSimulationParameters( 752 OptionsInfo["SimulationParams"]) 753 754 """ 755 756 ParamsInfoWithUnits = {} 757 758 ParamsInfoWithUnits["Steps"] = ParamsInfo["Steps"] 759 760 ParamsInfoWithUnits["Minimization"] = ParamsInfo["Minimization"] 761 ParamsInfoWithUnits["MinimizationMaxSteps"] = ParamsInfo["MinimizationMaxSteps"] 762 763 MinimizationToleranceInKcal = ParamsInfo["MinimizationTolerance"] 764 MinimizationTolerance = MinimizationToleranceInKcal * mm.unit.kilocalories_per_mole/mm.unit.angstroms 765 766 MinimizationToleranceInJoules = MinimizationTolerance.value_in_unit(mm.unit.kilojoules_per_mole/mm.unit.nanometer) 767 MinimizationTolerance = MinimizationToleranceInJoules*mm.unit.kilojoules_per_mole/mm.unit.nanometer 768 769 ParamsInfoWithUnits["MinimizationToleranceInKcal"] = MinimizationToleranceInKcal 770 ParamsInfoWithUnits["MinimizationToleranceInJoules"] = MinimizationToleranceInJoules 771 ParamsInfoWithUnits["MinimizationTolerance"] = MinimizationTolerance 772 773 ParamsInfoWithUnits["Equilibration"] = ParamsInfo["Equilibration"] 774 ParamsInfoWithUnits["EquilibrationSteps"] = ParamsInfo["EquilibrationSteps"] 775 776 return ParamsInfoWithUnits 777 778 def ReimageRealignTrajectory(Topology, TrajFile, ReimageFrames = True, RealignFrames = True, Selection = "protein and backbone and name CA"): 779 """Reimage and realign a trajectory file using MDTraj. The trajectory frames 780 are reimaged before realigning to the first frame using the specified atom 781 selection. 782 783 The trajectory file format must a valid format supported by MDTraj. No 784 validation is performed. 785 786 Arguments: 787 Topology (str or object): PDB file name or OpenMM topology object. 788 TrajFile (str): Trajectory file name. 789 ReimageFrames (bool): Reimage trajectory frames. 790 RealignFrames (bool): Realign trajectory frames. 791 Selection (str): MDTraj atom selection for realigning frames. 792 793 Returns: 794 None or object: MDTraj trajectory object. 795 bool: Reimaged status. 796 bool: Realigned status. 797 798 """ 799 800 if isinstance(Topology, str): 801 MiscUtil.PrintInfo("Reading trajectory file %s (TopologyFile: %s)..." % (TrajFile, Topology)) 802 else: 803 MiscUtil.PrintInfo("Reading trajectory file %s..." % (TrajFile)) 804 Topology = mdtraj.Topology.from_openmm(Topology) 805 806 try: 807 Traj = mdtraj.load(TrajFile, top = Topology) 808 except Exception as ErrMsg: 809 MiscUtil.PrintInfo("") 810 MiscUtil.PrintWarning("Failed to read trajectory file: %s" % ErrMsg) 811 MiscUtil.PrintInfo("") 812 return (None, False, False) 813 814 ReimagedStatus, RealignedStatus = [False] * 2 815 816 if ReimageFrames: 817 MiscUtil.PrintInfo("Reimaging frames...") 818 try: 819 Traj.image_molecules(inplace = True) 820 ReimagedStatus = True 821 except Exception as ErrMsg: 822 MiscUtil.PrintInfo("") 823 MiscUtil.PrintWarning("Failed to reimage frames: %s" % ErrMsg) 824 MiscUtil.PrintInfo("") 825 else: 826 MiscUtil.PrintInfo("Skipping reimaging of frames...") 827 828 if RealignFrames: 829 MiscUtil.PrintInfo("Realigning frames to the first frame using selection \"%s\"..." % Selection) 830 try: 831 SelectionAtomIndices = Traj.top.select(Selection) 832 except Exception as ErrMsg: 833 MiscUtil.PrintInfo("") 834 MiscUtil.PrintWarning("Failed to align frames using selection \"%s\": %s" % (Selection, ErrMsg)) 835 MiscUtil.PrintInfo("") 836 return (Traj, ReimagedStatus, RealignedStatus) 837 838 if SelectionAtomIndices.size == 0: 839 MiscUtil.PrintInfo("") 840 MiscUtil.PrintWarning("Failed to align frames using selection \"%s\": No matched atoms found" % (Selection)) 841 MiscUtil.PrintInfo("") 842 return (Traj, ReimagedStatus, RealignedStatus) 843 844 RealignedStatus = True 845 Traj.superpose(Traj, frame = 0, atom_indices = SelectionAtomIndices) 846 else: 847 MiscUtil.PrintInfo("Skipping realignment of frames to the first frame...") 848 849 return (Traj, ReimagedStatus, RealignedStatus) 850 851 def FreezeAtoms(System, AtomList): 852 """Freeze atoms during a simulation. The specified atoms are kept completely 853 fixed by setting their masses to zero. Their positions do not change during 854 local energy minimization and MD simulation, and they do not contribute 855 to the kinetic energy of the system. 856 857 Arguments: 858 System (object): OpenMM system object. 859 AtomList (list): List of OpenMM atom objects. 860 861 Returns: 862 None 863 864 """ 865 866 if AtomList is None: 867 return 868 869 for Atom in AtomList: 870 System.setParticleMass(Atom.index, 0*mm.unit.amu) 871 872 def RestraintAtoms(System, Positions, AtomList, SpringConstantInKcal): 873 """Restraint atoms during a simulation. The motion of specified atoms is 874 restricted by adding a harmonic force that binds them to their starting 875 positions. The atoms are not completely fixed unlike freezing of atoms. 876 Their motion, however, is restricted and they are not able to move far away 877 from their starting positions during local energy minimization and MD 878 simulation. 879 880 The SpringConstantInKcal value must be specified in the units of 881 kcal/mol/A*82. It is automatically converted into the units of 882 kjoules/mol/nm**2 for OpenMM API call. 883 884 Arguments: 885 System (object): OpenMM system object. 886 Positions (object): OpenMM positons object object. 887 AtomList (list): List of OpenMM atom object. 888 SpringConstantInKcal (float): Spring constant value. 889 890 Returns: 891 None 892 893 """ 894 895 if AtomList is None: 896 return 897 898 SpringConstant = SpringConstantInKcal * mm.unit.kilocalories_per_mole/mm.unit.angstroms**2 899 SpringConstantInKjoules = SpringConstant.value_in_unit(mm.unit.kilojoules_per_mole/mm.unit.nanometer**2) 900 901 MiscUtil.PrintInfo("Restraint spring constant: %.2f kcal/mol/A**2 (%.2f kjoules/mol/nm**2)" % (SpringConstantInKcal, SpringConstantInKjoules)) 902 903 if DoesSystemUsesPeriodicBoundaryConditions(System): 904 # For periodic systems... 905 RestraintForce = mm.CustomExternalForce('k*periodicdistance(x, y, z, x0, y0, z0)^2') 906 else: 907 # For non-periodic systems... 908 RestraintForce = mm.CustomExternalForce('k*((x-x0)^2+(y-y0)^2+(z-z0)^2)') 909 910 SpringConstant = SpringConstantInKjoules * mm.unit.kilojoules_per_mole/mm.unit.nanometer**2 911 RestraintForce.addGlobalParameter('k', SpringConstant) 912 913 RestraintForce.addPerParticleParameter('x0') 914 RestraintForce.addPerParticleParameter('y0') 915 RestraintForce.addPerParticleParameter('z0') 916 917 for Atom in AtomList: 918 RestraintForce.addParticle(Atom.index, Positions[Atom.index]) 919 920 def GetAtoms(Topology, CAlphaProteinStatus, ResidueNames, Negate): 921 """Get a list of atoms in the specified residue names. You may set 922 CAlphaProteinStatus flag to True to only retrieve CAlpha atoms from 923 the residues. In addition, you may negate residue name match using 924 Negate flag. 925 926 Arguments: 927 Topology (object): OpenMM topology object. 928 CAlphaProteinStatus (bool): Get CAlpha atoms only. 929 ResidueNames (list): List of residue names. 930 Negate (bool): Negate residue name match. 931 932 Returns: 933 None or List of OpenMM atom objects. 934 935 """ 936 AtomList = [] 937 for Chain in Topology.chains(): 938 for Residue in Chain.residues(): 939 if CAlphaProteinStatus: 940 if Residue.name in ResidueNames: 941 for Atom in Residue.atoms(): 942 if _MatchName(Atom.name, ["CA"], Negate): 943 AtomList.append(Atom) 944 else: 945 if _MatchName(Residue.name, ResidueNames, Negate): 946 AtomList.extend(Residue.atoms()) 947 948 if len(AtomList) == 0: 949 AtomList = None 950 951 return AtomList 952 953 def _MatchName(Name, NamesList, Negate = False): 954 """Match name to the names in a list.""" 955 956 Status = True if Name in NamesList else False 957 if Negate: 958 Status = not Status 959 960 return Status 961 962 def DoesSystemUsesPeriodicBoundaryConditions(System): 963 """Check for the use of periodic boundary conditions in a system. 964 965 Arguments: 966 System (object): OpenMM system object. 967 968 Returns: 969 bool : True - Uses periodic boundary conditions; Otherwise, false. 970 971 """ 972 973 try: 974 Status = True if System.usesPeriodicBoundaryConditions() else False 975 except Exception: 976 Status = False 977 978 return Status 979 980 def DoesAtomListOverlapWithSystemConstraints(System, AtomList): 981 """Check for the overlap of specified atoms with the atoms involved 982 in system constraints. 983 984 Arguments: 985 System (object): OpenMM system object. 986 AtomList (list): List of OpenMM atom objects. 987 988 Returns: 989 bool : True - Overlap with system constraints; Otherwise, false. 990 991 """ 992 993 NumConstraints = System.getNumConstraints() 994 if NumConstraints == 0: 995 return False 996 997 if AtomList is None: 998 return False 999 1000 AtomListIndices = [Atom.index for Atom in AtomList] 1001 1002 for Index in range(NumConstraints): 1003 Particle1Index, Particle2Index, Distance = System.getConstraintParameters(Index) 1004 if Particle1Index in AtomListIndices or Particle2Index in AtomListIndices: 1005 return True 1006 1007 return False 1008 1009 def DoAtomListsOverlap(AtomList1, AtomList2): 1010 """Check for the overlap of atoms in the specified atom lists. 1011 1012 Arguments: 1013 AtomList1 (list): List of OpenMM atom objects. 1014 AtomList2 (list): List of OpenMM atom objects. 1015 1016 Returns: 1017 bool : True - Overlap between atoms lists; Otherwise, false. 1018 1019 """ 1020 1021 if AtomList1 is None or AtomList2 is None: 1022 return False 1023 1024 AtomList1Indices = [Atom.index for Atom in AtomList1] 1025 1026 for Atom in AtomList2: 1027 if Atom.index in AtomList1Indices: 1028 return True 1029 1030 return False 1031 1032 def DoesSystemContainWater(Topology, WaterResidueNames = ['HOH']): 1033 """Check for the presence of water residues in a system. 1034 1035 Arguments: 1036 Topology (object): OpenMM modeller topology object. 1037 WaterResidueNames (list): List of water residue names. 1038 1039 Returns: 1040 bool : True - Contains water; Otherwise, false. 1041 1042 """ 1043 1044 Status = False 1045 for Residue in Topology.residues(): 1046 if Residue.name in WaterResidueNames: 1047 Status = True 1048 break 1049 1050 return Status 1051 1052 def ReadPDBFile(PDBFile): 1053 """Read molecule from a PDB file. 1054 1055 The supported PDB file formats are pdb and cif. 1056 1057 Arguments: 1058 PDBFile (str): Name of PDB file. 1059 1060 Returns: 1061 object: OpenMM PDBFile or PDBFilex object. 1062 1063 """ 1064 1065 FileDir, FileName, FileExt = MiscUtil.ParseFileName(PDBFile) 1066 if re.match("^pdb$", FileExt, re.I): 1067 PDBHandle = mm.app.PDBFile(PDBFile) 1068 elif re.match("^cif$", FileExt, re.I): 1069 PDBHandle = mm.app.PDBxFile(PDBFile) 1070 else: 1071 MiscUti.PrintError("Failed to read PDB file. Invalid PDB file format %s...\n" % PDBFile) 1072 1073 return PDBHandle 1074 1075 def WritePDBFile(PDBFile, Topology, Positions, KeepIDs = True): 1076 """Write a PDB file. 1077 1078 The supported PDB file formats are pdb and cif. 1079 1080 Arguments: 1081 PDBFile (str): Name of PDB file. 1082 Topology (object): Topology OpenMM object. 1083 Positions (object): Positions OpenMM object. 1084 KeepIDs (bool): Keep existing residue and chain IDs. 1085 1086 Returns: 1087 None 1088 1089 """ 1090 1091 FileDir, FileName, FileExt = MiscUtil.ParseFileName(PDBFile) 1092 if re.match("^pdb$", FileExt, re.I): 1093 mm.app.PDBFile.writeFile(Topology, Positions, PDBFile, KeepIDs) 1094 elif re.match("^cif$", FileExt, re.I): 1095 mm.app.PDBxFile.writeFile(Topology, Positions, PDBFile, KeepIDs) 1096 else: 1097 MiscUti.PrintError("Failed to write PDB file. Invalid PDB file format %s...\n" % PDBFile) 1098 1099 def WriteSimulationStatePDBFile(Simulation, PDBFile, KeepIDs = True): 1100 """Write a PDB file for current simulation state. 1101 1102 The supported PDB file formats are pdb and cif. 1103 1104 Arguments: 1105 Simulation (object): OpenMM simulation object. 1106 PDBFile (str): Name of PDB fil. 1107 KeepIDs (bool): Keep existing residue and chain IDs. 1108 1109 Returns: 1110 None 1111 1112 """ 1113 1114 CurrentPositions = Simulation.context.getState(getPositions = True).getPositions() 1115 WritePDBFile(PDBFile, Simulation.topology, CurrentPositions, KeepIDs) 1116 1117 def ReadSmallMoleculeFile(FileName): 1118 """Read small molecule file using OpenFF toolkit. 1119 1120 Arguments: 1121 FileName (str): Small molecule file name. 1122 1123 Returns: 1124 None or OpenFF tookit molecule object. 1125 1126 """ 1127 1128 try: 1129 SmallMol = ff.toolkit.Molecule.from_file(FileName) 1130 except Exception as ErrMsg: 1131 SmallMol = None 1132 MiscUtil.PrintInfo("") 1133 MiscUtil.PrintWarning("OpenFF.toolkit.Molecule.from_file() failed: %s" % ErrMsg) 1134 MiscUtil.PrintInfo("") 1135 1136 return SmallMol 1137 1138 def MergeSmallMoleculeWithMacromolecule(ModellerHandle, SmallMol, SmallMolID = "LIG"): 1139 """Merge small molecule with macromolecule data contained in a modeller object and 1140 assign a three letter small molecule residue name to the merged small molecule. 1141 1142 Arguments: 1143 ModellerHandle (object): OpenMM modeller object. 1144 SmallMol (object): OpenFF tookit molecule object. 1145 SmallMolID (str): Three letter residue name for small molecule. 1146 1147 Returns: 1148 None 1149 1150 """ 1151 1152 SmallMolToplogy = SmallMol.to_topology() 1153 SmallMolOpenMMTopology = SmallMolToplogy.to_openmm() 1154 SmallMolOpenMMPositions = SmallMolToplogy.get_positions().to_openmm() 1155 1156 # Set small molecule residue name to LIG... 1157 for Chain in SmallMolOpenMMTopology.chains(): 1158 for Residue in Chain.residues(): 1159 Residue.name = SmallMolID 1160 1161 ModellerHandle.add(SmallMolOpenMMTopology, SmallMolOpenMMPositions) 1162 1163 def GetFormattedTotalSimulationTime(StepSize, Steps): 1164 """Get formatted total simulation time with appropriate time units. 1165 parameter names and values. 1166 1167 Arguments: 1168 StepSize (object): OpenMM quantity object. 1169 Steps (int): Number of steps. 1170 1171 Returns: 1172 str: Total time. 1173 1174 """ 1175 1176 TotalTime = StepSize * Steps 1177 TotalTimeValue = TotalTime.value_in_unit(mm.unit.femtoseconds) 1178 1179 if TotalTimeValue < 1e3: 1180 TotalTimeUnits = "fs" 1181 TotalTime = TotalTime.value_in_unit(mm.unit.femtoseconds) 1182 elif TotalTimeValue < 1e6: 1183 TotalTimeUnits = "ps" 1184 TotalTime = TotalTime.value_in_unit(mm.unit.picoseconds) 1185 elif TotalTimeValue < 1e9: 1186 TotalTimeUnits = "ns" 1187 TotalTime = TotalTime.value_in_unit(mm.unit.nanoseconds) 1188 elif TotalTimeValue < 1e12: 1189 TotalTimeUnits = "us" 1190 TotalTime = TotalTime.value_in_unit(mm.unit.microseconds) 1191 else: 1192 TotalTimeUnits = "ms" 1193 TotalTime = TotalTime.value_in_unit(mm.unit.milliseconds) 1194 1195 TotalTime = "%.2f %s" % (TotalTime, TotalTimeUnits) 1196 1197 return TotalTime 1198 1199 def ProcessOptionOpenMMRestartParameters(ParamsOptionName, ParamsOptionValue, OutfilePrefix, ParamsDefaultInfo = None): 1200 """Process parameters for restart option and return a map containing processed 1201 parameter names and values. 1202 1203 ParamsOptionValue is a comma delimited list of parameter name and value pairs 1204 to setup platform. 1205 1206 The supported parameter names along with their default and possible 1207 values are shown below: 1208 1209 finalStateFile, <OutfilePrefix>_FinalState.<chk> [ Possible values: 1210 Valid final state checkpoint or XML filename ] 1211 dataAppend, yes [ Possible values: yes or no] 1212 1213 A brief description of parameters is provided below: 1214 1215 finalStateFile: Final state checkpoint or XML file 1216 1217 dataAppend: Append data to existing trajectory and data log files during the 1218 restart of a simulation using a previously saved final state checkpoint or 1219 XML file. 1220 1221 Arguments: 1222 ParamsOptionName (str): Command line OpenMM restart option name. 1223 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 1224 OutfilePrefix (str): Prefix for output files. 1225 ParamsDefaultInfo (dict): Default values to override for selected parameters. 1226 1227 Returns: 1228 dictionary: Processed parameter name and value pairs. 1229 1230 """ 1231 1232 ParamsInfo = {"FinalStateFile": "auto", "DataAppend": True} 1233 1234 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 1235 1236 if re.match("^auto$", ParamsOptionValue, re.I): 1237 _ProcessOptionOpenMMRestartParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1238 return ParamsInfo 1239 1240 for Index in range(0, len(ParamsOptionValueWords), 2): 1241 Name = ParamsOptionValueWords[Index].strip() 1242 Value = ParamsOptionValueWords[Index + 1].strip() 1243 1244 ParamName = CanonicalParamNamesMap[Name.lower()] 1245 ParamValue = Value 1246 1247 if re.match("^FinalStateFile$", ParamName, re.I): 1248 if not re.match("^auto$", Value, re.I): 1249 if not os.path.exists(Value): 1250 MiscUtil.PrintError("The file name specified, %s, for parameter name, %s, using option \"%s\" doesn't exist.\n." % (Value, Name, ParamsOptionName)) 1251 if not MiscUtil.CheckFileExt(Value, "chk xml"): 1252 MiscUtil.PrintError("The file name specified, %s, for parameter name, %s, using option \"%s\" is not valid file. Supported file formats: chk or xml\n." % (Value, Name, ParamsOptionName)) 1253 ParamValue = Value 1254 elif re.match("^DataAppend$", ParamName, re.I): 1255 if not re.match("^(yes|no|true|false)$", Value, re.I): 1256 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 1257 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False 1258 else: 1259 ParamValue = Value 1260 1261 # Set value... 1262 ParamsInfo[ParamName] = ParamValue 1263 1264 # Handle parameters with possible auto values... 1265 _ProcessOptionOpenMMRestartParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1266 1267 return ParamsInfo 1268 1269 def _ProcessOptionOpenMMRestartParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix): 1270 """Process parameters with possible auto values and perform validation. 1271 """ 1272 1273 FinalStateFileCheckpointMode = False 1274 FinalStateFileXMLMode = False 1275 1276 ParamName = "FinalStateFile" 1277 FinalStateFile = ParamsInfo[ParamName] 1278 if re.match("^auto$", FinalStateFile, re.I): 1279 FinalStateFile = "%s_FinalState.chk" % OutfilePrefix 1280 FinalStateFileCheckpointMode = True 1281 else: 1282 if MiscUtil.CheckFileExt(FinalStateFile, "chk"): 1283 FinalStateFileCheckpointMode = True 1284 elif MiscUtil.CheckFileExt(FinalStateFile, "xml"): 1285 FinalStateFileXMLMode = True 1286 else: 1287 MiscUtil.PrintError("The file name specified, %s, for parameter name, %s, using option \"%s\ is not valid. Supported file formats: chk or xml\n." % (FinalStateFile, ParamName, ParamsOptionName)) 1288 1289 ParamsInfo["FinalStateFile"] = FinalStateFile 1290 ParamsInfo["FinalStateFileCheckpointMode"] = FinalStateFileCheckpointMode 1291 ParamsInfo["FinalStateFileXMLMode"] = FinalStateFileXMLMode 1292 1293 def ProcessOptionOpenMMSystemParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 1294 """Process parameters for system option and return a map containing processed 1295 parameter names and values. 1296 1297 ParamsOptionValue is a comma delimited list of parameter name and value pairs 1298 to setup platform. 1299 1300 The supported parameter names along with their default and possible 1301 values are shown below: 1302 1303 constraints, BondsInvolvingHydrogens [ Possible values: None, 1304 WaterOnly, BondsInvolvingHydrogens, AllBonds, or 1305 AnglesInvolvingHydrogens ] 1306 constraintErrorTolerance, 0.000001 1307 ewaldErrorTolerance, 0.0005 1308 1309 nonbondedMethodPeriodic, PME [ Possible values: NoCutoff, 1310 CutoffNonPeriodic, or PME ] 1311 nonbondedMethodNonPeriodic, NoCutoff [ Possible values: 1312 NoCutoff or CutoffNonPeriodic] 1313 nonbondedCutoff, 1.0 [ Units: nm ] 1314 1315 hydrogenMassRepartioning, yes [ Possible values: yes or no ] 1316 hydrogenMass, 1.5 [ Units: amu] 1317 1318 removeCMMotion, yes [ Possible values: yes or no ] 1319 rigidWater, auto [ Possible values: yes or no. Default: 'No' for 1320 'None' value of constraints; Otherwise, yes ] 1321 1322 A brief description of parameters is provided below: 1323 1324 constraints: Type of system constraints to use for simulation. These constraints 1325 are different from freezing and restraining of any atoms in the system. 1326 1327 constraintErrorTolerance: Distance tolerance for constraints as a fraction 1328 of the constrained distance. 1329 1330 ewaldErrorTolerance: Ewald error tolerance for a periodic system. 1331 1332 nonbondedMethodPeriodic: Nonbonded method to use during the calculation of 1333 long range interactions for a periodic system. 1334 1335 nonbondedMethodNonPeriodic: Nonbonded method to use during the calculation 1336 of long range interactions for a non-periodic system. 1337 1338 nonbondedCutoff: Cutoff distance to use for long range interactions in both 1339 perioidic non-periodic systems. 1340 1341 hydrogenMassRepartioning: Use hydrogen mass repartioning. It increases the 1342 mass of the hydrogen atoms attached to the heavy atoms and decreasing the 1343 mass of the bonded heavy atom to maintain constant system mass. This allows 1344 the use of larger integration step size (4 fs) during a simulation. 1345 1346 hydrogenMass: Hydrogen mass to use during repartioning. 1347 1348 removeCMMotion: Remove all center of mass motion at every time step. 1349 1350 rigidWater: Keep water rigid during a simulation. This is determined 1351 automatically based on the value of 'constraints' parameter. 1352 1353 Arguments: 1354 ParamsOptionName (str): Command line OpenMM system option name. 1355 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 1356 ParamsDefaultInfo (dict): Default values to override for selected parameters. 1357 1358 Returns: 1359 dictionary: Processed parameter name and value pairs. 1360 1361 """ 1362 1363 ParamsInfo = {"Constraints": "BondsInvolvingHydrogens", "ConstraintErrorTolerance": 0.000001, "EwaldErrorTolerance": 0.0005, "NonbondedMethodPeriodic": "PME", "NonbondedMethodNonPeriodic": "NoCutoff", "NonbondedCutoff": 1.0, "HydrogenMassRepartioning": True, "HydrogenMass": 1.5, "RemoveCMMotion": True, "RigidWater": "auto"} 1364 1365 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 1366 1367 if re.match("^auto$", ParamsOptionValue, re.I): 1368 _ProcessOptionOpenMMSystemParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 1369 return ParamsInfo 1370 1371 for Index in range(0, len(ParamsOptionValueWords), 2): 1372 Name = ParamsOptionValueWords[Index].strip() 1373 Value = ParamsOptionValueWords[Index + 1].strip() 1374 1375 ParamName = CanonicalParamNamesMap[Name.lower()] 1376 ParamValue = Value 1377 1378 if re.match("^Constraints$", ParamName, re.I): 1379 if not re.match("^auto$", Value, re.I): 1380 if not re.match("^(None|WaterOnly|BondsInvolvingHydrogens|AllBonds|AnglesInvolvingHydrogens)$", Value, re.I): 1381 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: None, WaterOnly, BondsInvolvingHydrogens, AllBonds, or AnglesInvolvingHydrogens." % (Value, Name, ParamsOptionName)) 1382 ParamValue = Value 1383 elif re.match("^(ConstraintErrorTolerance|EwaldErrorTolerance|NonbondedCutoff|HydrogenMass)$", ParamName, re.I): 1384 if not MiscUtil.IsFloat(Value): 1385 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 1386 Value = float(Value) 1387 if Value <= 0: 1388 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1389 ParamValue = Value 1390 elif re.match("^NonbondedMethodPeriodic$", ParamName, re.I): 1391 if not re.match("^(NoCutoff|CutoffPeriodic|PME)$", Value, re.I): 1392 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: NoCutoff, CutoffPeriodic, or PME" % (Value, Name, ParamsOptionName)) 1393 ParamValue = Value 1394 elif re.match("^NonbondedMethodNonPeriodic$", ParamName, re.I): 1395 if not re.match("^(NoCutoff|CutoffNonPeriodic)$", Value, re.I): 1396 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: NoCutoff or CutoffNonPeriodic" % (Value, Name, ParamsOptionName)) 1397 ParamValue = Value 1398 elif re.match("^(HydrogenMassRepartioning|removeCMMotion)$", ParamName, re.I): 1399 if not re.match("^(yes|no|true|false)$", Value, re.I): 1400 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 1401 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False 1402 elif re.match("^RigidWater$", ParamName, re.I): 1403 if not re.match("^auto$", Value, re.I): 1404 if not re.match("^(yes|no|true|false)$", Value, re.I): 1405 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 1406 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False 1407 else: 1408 ParamValue = Value 1409 1410 # Set value... 1411 ParamsInfo[ParamName] = ParamValue 1412 1413 # Handle parameters with possible auto values... 1414 _ProcessOptionOpenMMSystemParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 1415 1416 return ParamsInfo 1417 1418 def _ProcessOptionOpenMMSystemParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 1419 """Process parameters with possible auto values and perform validation. 1420 """ 1421 1422 for ParamName in ["NonbondedMethodPeriodic", "NonbondedMethodNonPeriodic"]: 1423 ParamValue = ParamsInfo[ParamName] 1424 if re.match("^NoCutoff$", ParamValue, re.I): 1425 ParamValue = mm.app.NoCutoff 1426 elif re.match("^CutoffNonPeriodic$", ParamValue, re.I): 1427 ParamValue = mm.app.CutoffNonPeriodic 1428 elif re.match("^CutoffPeriodic$", ParamValue, re.I): 1429 ParamValue = mm.app.CutoffPeriodic 1430 elif re.match("^PME$", ParamValue, re.I): 1431 ParamValue = mm.app.PME 1432 else: 1433 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: NoCutoff, CutoffNonPeriodic, CutoffPeriodic, or PME" % (ParamValue, ParamName, ParamsOptionName)) 1434 ParamsInfo[ParamName] = ParamValue 1435 1436 ParamName = "Constraints" 1437 ParamValue = ParamsInfo[ParamName] 1438 ConstraintsValue = None 1439 RigidWaterValue = False 1440 if re.match("^None$", ParamValue, re.I): 1441 ConstraintsValue = None 1442 RigidWaterValue = False 1443 elif re.match("^WaterOnly$", ParamValue, re.I): 1444 ConstraintsValue = None 1445 RigidWaterValue = True 1446 elif re.match("^BondsInvolvingHydrogens$", ParamValue, re.I): 1447 ConstraintsValue = mm.app.HBonds 1448 RigidWaterValue = True 1449 elif re.match("^AllBonds$", ParamValue, re.I): 1450 ConstraintsValue = mm.app.AllBonds 1451 RigidWaterValue = True 1452 elif re.match("^AnglesInvolvingHydrogens$", ParamValue, re.I): 1453 ConstraintsValue = mm.app.HAngles 1454 RigidWaterValue = True 1455 else: 1456 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: None, WaterOnly, BondsInvolvingHydrogens, AllBonds, or AnglesInvolvingHydrogens." % (ParamValue, ParamName, ParamsOptionName)) 1457 1458 ParamsInfo[ParamName] = ConstraintsValue 1459 1460 ParamName = "RigidWater" 1461 ParamValue = "%s" % ParamsInfo[ParamName] 1462 if re.match("^auto$", ParamValue, re.I): 1463 ParamsInfo[ParamName] = RigidWaterValue 1464 1465 def ProcessOptionOpenMMIntegratorParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None, HydrogenMassRepartioningStatus = False): 1466 """Process parameters for integrator option and return a map containing processed 1467 parameter names and values. 1468 1469 ParamsOptionValue is a comma delimited list of parameter name and value pairs 1470 to setup platform. 1471 1472 The supported parameter names along with their default and possible 1473 values are shown below: 1474 1475 integrator, LangevinMiddle [ Possible values: LangevinMiddle, 1476 Langevin, NoseHoover, Brownian ] 1477 1478 randomSeed, auto [ Possible values: > 0 ] 1479 1480 frictionCoefficient, 1.0 [ Units: 1/ps ] 1481 stepSize, auto [ Units: fs; Default value: 4 fs during yes value of 1482 hydrogen mass repartioning with no freezing/restraining of atoms; 1483 otherwsie, 2 fs ] 1484 temperature, 300.0 [ Units: kelvin ] 1485 1486 barostat, MonteCarlo [ Possible values: MonteCarlo or 1487 MonteCarloMembrane ] 1488 barostatInterval, 25 1489 pressure, 1.0 [ Units: atm ] 1490 1491 Parameters used only for MonteCarloMembraneBarostat with default 1492 values corresponding to Amber forcefields: 1493 1494 surfaceTension, 0.0 [ Units: atm*A. It is automatically converted 1495 into OpenMM default units of atm*nm before its usage. ] 1496 xymode, Isotropic [ Possible values: Anisotropic or Isotropic ] 1497 zmode, Free [ Possible values: Free or Fixed ] 1498 1499 A brief description of parameters is provided below: 1500 1501 integrator: Type of integrator 1502 1503 randomSeed: Random number seed for barostat and integrator. Not supported 1504 NoseHoover integrator. 1505 1506 frictionCoefficient: Friction coefficient for coupling the system to the heat 1507 bath. 1508 1509 stepSize: Simulation time step size. 1510 1511 temperature: Simulation temperature. 1512 1513 barostat: Barostat type. 1514 1515 barostatInterval: Barostat interval step size during NPT simulation for 1516 applying Monte Carlo pressure changes. 1517 1518 pressure: Pressure during NPT simulation. 1519 1520 surfaceTension: Surface tension acting on the system. 1521 1522 xymode: Behavior along X and Y axes. You may allow the X and Y axes 1523 to vary independently of each other or always scale them by the same 1524 amount to keep the ratio of their lengths constant. 1525 1526 zmode: Beahvior along Z axis. You may allow the Z axis to vary 1527 independently of the other axes or keep it fixed. 1528 1529 Arguments: 1530 ParamsOptionName (str): Command line OpenMM integrator option name. 1531 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 1532 ParamsDefaultInfo (dict): Default values to override for selected parameters. 1533 1534 Returns: 1535 dictionary: Processed parameter name and value pairs. 1536 1537 """ 1538 1539 ParamsInfo = {"Integrator": "LangevinMiddle", "RandomSeed": "auto", "FrictionCoefficient": 1.0, "StepSize": "auto", "Temperature": 300.0, "Barostat": "MonteCarlo", "BarostatInterval": 25, "Pressure": 1.0, "SurfaceTension": 0.0, "XYMode": "Isotropic", "ZMode": "Free"} 1540 1541 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 1542 1543 if re.match("^auto$", ParamsOptionValue, re.I): 1544 _ProcessOptionOpenMMIntegratorParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, HydrogenMassRepartioningStatus) 1545 return ParamsInfo 1546 1547 for Index in range(0, len(ParamsOptionValueWords), 2): 1548 Name = ParamsOptionValueWords[Index].strip() 1549 Value = ParamsOptionValueWords[Index + 1].strip() 1550 1551 ParamName = CanonicalParamNamesMap[Name.lower()] 1552 ParamValue = Value 1553 1554 if re.match("^Integrator$", ParamName, re.I): 1555 if not re.match("^(LangevinMiddle|Langevin|NoseHoover|Brownian)$", Value, re.I): 1556 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: LangevinMiddle,Langevin, NoseHoover, or Brownian." % (Value, Name, ParamsOptionName)) 1557 ParamValue = Value 1558 elif re.match("^(FrictionCoefficient|Pressure)$", ParamName, re.I): 1559 if not MiscUtil.IsFloat(Value): 1560 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 1561 Value = float(Value) 1562 if Value <= 0: 1563 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1564 ParamValue = Value 1565 elif re.match("^StepSize$", ParamName, re.I): 1566 if not re.match("^auto$", Value, re.I): 1567 if not MiscUtil.IsFloat(Value): 1568 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 1569 Value = float(Value) 1570 if Value <= 0: 1571 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1572 ParamValue = Value 1573 elif re.match("^(Temperature|SurfaceTension)$", ParamName, re.I): 1574 if not MiscUtil.IsFloat(Value): 1575 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 1576 Value = float(Value) 1577 if Value < 0: 1578 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: >= 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1579 ParamValue = Value 1580 elif re.match("^BarostatInterval$", ParamName, re.I): 1581 if not MiscUtil.IsInteger(Value): 1582 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (Value, ParamName, ParamsOptionName)) 1583 Value = int(Value) 1584 if Value <= 0: 1585 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1586 ParamValue = Value 1587 elif re.match("^Barostat$", ParamName, re.I): 1588 if not re.match("^(MonteCarlo|MonteCarloMembrane)$", Value, re.I): 1589 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: MonteCarlo or MonteCarloMembrane" % (Value, Name, ParamsOptionName)) 1590 ParamValue = Value 1591 elif re.match("^XYMode$", ParamName, re.I): 1592 if not re.match("^(Anisotropic|Isotropic)$", Value, re.I): 1593 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: Anisotropic or Isotropic" % (Value, Name, ParamsOptionName)) 1594 ParamValue = Value 1595 elif re.match("^ZMode$", ParamName, re.I): 1596 if not re.match("^(Free|Fixed)$", Value, re.I): 1597 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: Fixed or Free" % (Value, Name, ParamsOptionName)) 1598 ParamValue = Value 1599 elif re.match("^RandomSeed$", ParamName, re.I): 1600 if not re.match("^auto$", Value, re.I): 1601 if not MiscUtil.IsInteger(Value): 1602 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (Value, ParamName, ParamsOptionName)) 1603 Value = int(Value) 1604 if Value <= 0: 1605 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1606 ParamValue = Value 1607 else: 1608 ParamValue = Value 1609 1610 # Set value... 1611 ParamsInfo[ParamName] = ParamValue 1612 1613 # Handle parameters with possible auto values... 1614 _ProcessOptionOpenMMIntegratorParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, HydrogenMassRepartioningStatus) 1615 1616 return ParamsInfo 1617 1618 def _ProcessOptionOpenMMIntegratorParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, HydrogenMassRepartioningStatus): 1619 """Process parameters with possible auto values and perform validation. 1620 """ 1621 1622 ParamName = "StepSize" 1623 ParamValue = "%s" % ParamsInfo[ParamName] 1624 ParamsInfo["StepSizeSpecified"] = ParamValue 1625 if re.match("^auto$", ParamValue, re.I): 1626 ParamValue = 4.0 if HydrogenMassRepartioningStatus else 2.0 1627 ParamsInfo[ParamName] = ParamValue 1628 1629 ParamName = "RandomSeed" 1630 ParamValue = "%s" % ParamsInfo[ParamName] 1631 ParamsInfo["RandomSeedSpecified"] = ParamValue 1632 if re.match("^auto$", ParamValue, re.I): 1633 ParamsInfo[ParamName] = None 1634 1635 def ProcessOptionOpenMMSimulationParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 1636 """Process parameters for simulation option and return a map containing processed 1637 parameter names and values. 1638 1639 ParamsOptionValue is a comma delimited list of parameter name and value pairs 1640 to setup platform. 1641 1642 The supported parameter names along with their default and possible 1643 values are shown below: 1644 1645 steps, 1000000 [ Possible values: > 0 ] 1646 1647 minimization, yes [ Possible values: yes or no ] 1648 minimizationMaxSteps, auto [ Possible values: >= 0. The value of 1649 zero implies until the minimization is converged. ] 1650 minimizationTolerance, 0.25 [ Units: kcal/mol/A. The default value 1651 0.25, corresponds to OpenMM default of value of 10.04 1652 kjoules/mol/nm. It is automatically converted into OpenMM 1653 default units before its usage. ] 1654 1655 equilibration, yes [ Possible values: yes or no ] 1656 equilibrationSteps, 1000 [ Possible values: > 0 ] 1657 1658 A brief description of parameters is provided below: 1659 1660 steps: Number of steps for production run. 1661 1662 equilibration: Perform equilibration before the production run. 1663 1664 equilibrationSteps: Number of steps for equilibration. 1665 1666 minimizationMaxSteps: Maximum number of minimization steps. The value 1667 of zero implies until the minimization is converged. 1668 1669 minimizationTolerance: Energy convergence tolerance during minimization. 1670 1671 minimization: Perform minimization before equilibration and production run. 1672 1673 Arguments: 1674 ParamsOptionName (str): Command line OpenMM simulation option name. 1675 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 1676 ParamsDefaultInfo (dict): Default values to override for selected parameters. 1677 1678 Returns: 1679 dictionary: Processed parameter name and value pairs. 1680 1681 """ 1682 1683 ParamsInfo = {"Steps": 1000000, "Minimization": True, "MinimizationMaxSteps": "auto", "MinimizationTolerance": 0.24, "Equilibration": True, "EquilibrationSteps": 1000} 1684 1685 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 1686 1687 if re.match("^auto$", ParamsOptionValue, re.I): 1688 _ProcessOptionOpenMMSimulationParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 1689 return ParamsInfo 1690 1691 for Index in range(0, len(ParamsOptionValueWords), 2): 1692 Name = ParamsOptionValueWords[Index].strip() 1693 Value = ParamsOptionValueWords[Index + 1].strip() 1694 1695 ParamName = CanonicalParamNamesMap[Name.lower()] 1696 ParamValue = Value 1697 1698 if re.match("^(Steps|EquilibrationSteps)$", ParamName, re.I): 1699 if not MiscUtil.IsInteger(Value): 1700 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (Value, ParamName, ParamsOptionName)) 1701 Value = int(Value) 1702 if Value <= 0: 1703 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1704 ParamValue = Value 1705 elif re.match("^(Minimization|Equilibration)$", ParamName, re.I): 1706 if not re.match("^(yes|no|true|false)$", Value, re.I): 1707 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 1708 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False 1709 elif re.match("^MinimizationMaxSteps$", ParamName, re.I): 1710 if not re.match("^auto$", Value, re.I): 1711 if not MiscUtil.IsInteger(Value): 1712 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (Value, ParamName, ParamsOptionName)) 1713 Value = int(Value) 1714 if Value < 0: 1715 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: >= 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1716 ParamValue = Value 1717 elif re.match("^MinimizationTolerance$", ParamName, re.I): 1718 if not MiscUtil.IsFloat(Value): 1719 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 1720 Value = float(Value) 1721 if Value <= 0: 1722 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1723 ParamValue = Value 1724 else: 1725 ParamValue = Value 1726 1727 # Set value... 1728 ParamsInfo[ParamName] = ParamValue 1729 1730 # Handle parameters with possible auto values... 1731 _ProcessOptionOpenMMSimulationParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 1732 1733 return ParamsInfo 1734 1735 def _ProcessOptionOpenMMSimulationParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 1736 """Process parameters with possible auto values and perform validation. 1737 """ 1738 1739 ParamName = "MinimizationMaxSteps" 1740 ParamValue = "%s" % ParamsInfo[ParamName] 1741 if re.match("^auto$", ParamValue, re.I): 1742 ParamsInfo[ParamName] = 0 1743 1744 def ProcessOptionOpenMMOutputParameters(ParamsOptionName, ParamsOptionValue, OutfilePrefix, ParamsDefaultInfo = None): 1745 """Process parameters for output option and return a map containing processed 1746 parameter names and values. 1747 1748 ParamsOptionValue is a comma delimited list of parameter name and value pairs 1749 to setup platform. 1750 1751 The supported parameter names along with their default and possible 1752 values are shown below: 1753 1754 checkpoint, no [ Possible values: yes or no ] 1755 checkpointFile, auto [ Default: <OutfilePrefix>.chk ] 1756 checkpointSteps, 10000 1757 1758 dataOutType, auto [ Possible values: A space delimited list of valid 1759 parameter names. 1760 NPT simulation default: Density Step Speed Progress 1761 PotentialEnergy Temperature Time. 1762 NVT simulation default: Step Speed Progress PotentialEnergy 1763 Temperature Time Volumne 1764 Other valid names: ElapsedTime RemainingTime KineticEnergy 1765 TotalEnergy ] 1766 1767 dataLog, yes [ Possible values: yes or no ] 1768 dataLogFile, auto [ Default: <OutfilePrefix>.csv ] 1769 dataLogSteps, 1000 1770 1771 dataStdout, no [ Possible values: yes or no ] 1772 dataStdoutSteps, 1000 1773 1774 minimizationDataSteps, 100 1775 minimizationDataStdout, no [ Possible values: yes or no ] 1776 minimizationDataLog, no [ Possible values: yes or no ] 1777 minimizationDataLogFile, auto [ Default: 1778 <OutfilePrefix>_MinimizationOut.csv ] 1779 minimizationDataOutType, auto [ Possible values: A space delimited 1780 list of valid parameter names. Default: SystemEnergy 1781 RestraintEnergy MaxConstraintError. 1782 Other valid names: RestraintStrength ] 1783 1784 pdbOutFormat, PDB [ Possible values: PDB or CIF ] 1785 pdbOutKeepIDs, yes [ Possible values: yes or no ] 1786 1787 pdbOutMinimized, no [ Possible values: yes or no ] 1788 pdbOutEquilibrated, no [ Possible values: yes or no ] 1789 pdbOutFinal, no [ Possible values: yes or no ] 1790 1791 saveFinalStateCheckpoint, yes [ Possible values: yes or no ] 1792 saveFinalStateCheckpointFile, auto [ Default: 1793 <OutfilePrefix>_FinalState.chk ] 1794 saveFinalStateXML, no [ Possible values: yes or no ] 1795 saveFinalStateXMLFile, auto [ Default: 1796 <OutfilePrefix>_FinalState.xml] 1797 1798 traj, yes [ Possible values: yes or no ] 1799 trajFile, auto [ Default: <OutfilePrefix>.<TrajFormat> ] 1800 trajFormat, DCD [ Possible values: DCD or XTC ] 1801 trajSteps, 10000 1802 1803 xmlSystemOut, no [ Possible values: yes or no ] 1804 xmlSystemFile, auto [ Default: <OutfilePrefix>_System.xml ] 1805 xmlIntegratorOut, no [ Possible values: yes or no ] 1806 xmlIntegratorFile, auto [ Default: <OutfilePrefix>_Integrator.xml ] 1807 1808 A brief description of parameters is provided below: 1809 1810 checkpoint: Write intermediate checkpoint file. 1811 checkpointFile: Intermediate checkpoint file name. 1812 checkpointSteps: Frequency of writing intermediate checkpoint file. 1813 1814 dataOutType: Type of data to write to stdout and log file. 1815 1816 dataLog: Write data to log file. 1817 dataLogFile: Data log file name. 1818 dataLogSteps: Frequency of writing data to log file. 1819 1820 dataStdout: Write data to stdout. 1821 dataStdoutSteps: Frequency of writing data to stdout. 1822 1823 minimizationDataSteps: Frequency of writing data to stdout and log file. 1824 minimizationDataStdout: Write data to stdout. 1825 minimizationDataLog: Write data to log file. 1826 minimizationDataLogFile: Data log fie name. 1827 minimizationDataOutType: Type of data to write to stdout and log file. 1828 1829 pdbOutFormat: Format of output PDB files. 1830 pdbOutKeepIDs: Keep existing chain and residue IDs. 1831 1832 pdbOutMinimized: Write PDB file after minimization. 1833 pdbOutEquilibrated: Write PDB file after equilibration. 1834 pdbOutFinal: Write final PDB file after production run. 1835 1836 saveFinalStateCheckpoint: Save final state checkpoint file. 1837 saveFinalStateCheckpointFile: Name of final state checkpoint file. 1838 saveFinalStateXML: Save final state XML file. 1839 saveFinalStateXMLFile: Name of final state XML file. 1840 1841 traj: Write out trajectory file. 1842 trajFile: Trajectory file name. 1843 trajFormat: Trajectory file format. 1844 trajSteps: Frequency of writing trajectory file. 1845 1846 xmlSystemOut: Write system XML file. 1847 xmlSystemFile: System XML file name. 1848 xmlIntegratorOut: Write integrator XML file. 1849 xmlIntegratorFile: Integrator XML file name. 1850 1851 Arguments: 1852 ParamsOptionName (str): Command line OpenMM system option name. 1853 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 1854 ParamsDefaultInfo (dict): Default values to override for selected parameters. 1855 1856 Returns: 1857 dictionary: Processed parameter name and value pairs. 1858 1859 """ 1860 1861 ParamsInfo = {"Checkpoint": False, "CheckpointFile": "auto", "CheckpointSteps": 10000, 1862 "DataOutType": "auto", 1863 "DataLog": True, "DataLogFile": "auto", "DataLogSteps": 1000, 1864 "DataStdout": False, "DataStdoutSteps": 1000, 1865 "MinimizationDataSteps": 100, "MinimizationDataStdout": False, "MinimizationDataLog": False, "MinimizationDataLogFile": "auto", "MinimizationDataOutType": "auto", 1866 "PDBOutFormat": "PDB", "PDBOutKeepIDs": True, "PDBOutMinimized": False, "PDBOutEquilibrated": False, "PDBOutFinal": False, 1867 "SaveFinalStateCheckpoint": True, "SaveFinalStateCheckpointFile": "auto", "SaveFinalStateXML": False, "SaveFinalStateXMLFile": "auto", 1868 "Traj": True, "TrajFile": "auto", "TrajFormat": "DCD", "TrajSteps": 10000, 1869 "XmlSystemOut": False, "XmlSystemFile": "auto", "XmlIntegratorOut": False, "XmlIntegratorFile": "auto"} 1870 1871 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 1872 1873 if re.match("^auto$", ParamsOptionValue, re.I): 1874 _ProcessOptionOpenMMOutputParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1875 return ParamsInfo 1876 1877 for Index in range(0, len(ParamsOptionValueWords), 2): 1878 Name = ParamsOptionValueWords[Index].strip() 1879 Value = ParamsOptionValueWords[Index + 1].strip() 1880 1881 ParamName = CanonicalParamNamesMap[Name.lower()] 1882 ParamValue = Value 1883 1884 if re.match("^(Checkpoint|DataLog|DataStdout|MinimizationDataStdout|MinimizationDataLog|PDBOutKeepIDs|SaveFinalStateCheckpoint|SaveFinalStateXML|Traj|XmlSystemOut|XmlIntegratorOut|PDBOutMinimized|PDBOutEquilibrated|PDBOutFinal)$", ParamName, re.I): 1885 if not re.match("^(yes|no|true|false)$", Value, re.I): 1886 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 1887 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False 1888 elif re.match("^(CheckpointFile|SaveFinalStateCheckpointFile)$", ParamName, re.I): 1889 if not re.match("^auto$", Value, re.I): 1890 if not MiscUtil.CheckFileExt(Value, "chk"): 1891 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported file format: chk" % (Value, Name, ParamsOptionName)) 1892 ParamValue = Value 1893 elif re.match("^(DataLogFile|MinimizationDataLogFile)$", ParamName, re.I): 1894 if not re.match("^auto$", Value, re.I): 1895 if not MiscUtil.CheckFileExt(Value, "csv"): 1896 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported file formats: csv" % (Value, Name, ParamsOptionName)) 1897 ParamValue = Value 1898 elif re.match("^(SaveFinalStateXMLFile|XmlSystemFile|XmlIntegratorFile)$", ParamName, re.I): 1899 if not re.match("^auto$", Value, re.I): 1900 if not MiscUtil.CheckFileExt(Value, "xml"): 1901 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported file format: xml" % (Value, Name, ParamsOptionName)) 1902 ParamValue = Value 1903 elif re.match("^TrajFile$", ParamName, re.I): 1904 if not re.match("^auto$", Value, re.I): 1905 if not MiscUtil.CheckFileExt(Value, "dcd xtc"): 1906 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported file formats: dcd xtc" % (Value, Name, ParamsOptionName)) 1907 ParamValue = Value 1908 elif re.match("^(CheckpointSteps|DataLogSteps|DataStdoutSteps|MinimizationDataSteps|TrajSteps)$", ParamName, re.I): 1909 if not MiscUtil.IsInteger(Value): 1910 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (Value, ParamName, ParamsOptionName)) 1911 Value = int(Value) 1912 if Value <= 0: 1913 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 1914 ParamValue = Value 1915 elif re.match("^DataOutType$", ParamName, re.I): 1916 if not re.match("^auto$", Value, re.I): 1917 ValueTypes = Value.split() 1918 if len(ValueTypes) == 0: 1919 MiscUtil.PrintError("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 valid values.\n" % (Value, ParamName, ParamsOptionName)) 1920 ValueTypesSpecified = [] 1921 for ValueType in ValueTypes: 1922 if not re.match("^(Step|Speed|Progress|PotentialEnergy|Temperature|ElapsedTime|RemainingTime|Time|KineticEnergy|TotalEnergy|Volume|Density)$", ValueType, re.I): 1923 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: Step, Speed, Progress, PotentialEnergy, Temperature, ElapsedTime, RemainingTime, Time, KineticEnergy, TotalEnergy, Volume, or Density" % (ValueType, Name, ParamsOptionName)) 1924 if ValueType in ValueTypesSpecified: 1925 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. It has already been specified." % (ValueType, Name, ParamsOptionName)) 1926 ValueTypesSpecified.append(ValueType) 1927 ParamsInfo["DataOutTypeList"] = ValueTypes 1928 elif re.match("^MinimizationDataOutType$", ParamName, re.I): 1929 if not re.match("^auto$", Value, re.I): 1930 ValueTypes = Value.split() 1931 if len(ValueTypes) == 0: 1932 MiscUtil.PrintError("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 valid values.\n" % (Value, ParamName, ParamsOptionName)) 1933 ValueTypesSpecified = [] 1934 for ValueType in ValueTypes: 1935 if not re.match("^(SystemEnergy|RestraintEnergy|RestraintStrength|MaxConstraintError)$", ValueType, re.I): 1936 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: SystemEnergy, RestraintEnergy, RestraintStrength, or MaxConstraintError" % (ValueType, Name, ParamsOptionName)) 1937 if ValueType in ValueTypesSpecified: 1938 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. It has already been specified." % (ValueType, Name, ParamsOptionName)) 1939 ValueTypesSpecified.append(ValueType) 1940 ParamsInfo["MinimizationDataOutTypeList"] = ValueTypes 1941 elif re.match("^PDBOutFormat$", ParamName, re.I): 1942 if not re.match("^(PDB|CIF)$", Value, re.I): 1943 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: PDB or CIF" % (Value, Name, ParamsOptionName)) 1944 ParamValue = Value 1945 elif re.match("^TrajFormat$", ParamName, re.I): 1946 if not re.match("^(DCD|XTC)$", Value, re.I): 1947 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: DCD or XTC" % (Value, Name, ParamsOptionName)) 1948 ParamValue = Value 1949 else: 1950 ParamValue = Value 1951 1952 # Set value... 1953 ParamsInfo[ParamName] = ParamValue 1954 1955 # Handle parameters with possible auto values... 1956 _ProcessOptionOpenMMOutputParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1957 1958 return ParamsInfo 1959 1960 def _ProcessOptionOpenMMOutputParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix): 1961 """Process parameters with possible auto values and perform validation. 1962 """ 1963 1964 # Use comma as a delimiter... 1965 ParamsInfo["DataOutDelimiter"] = "," 1966 ParamsInfo["DataOutfileExt"] = "csv" 1967 1968 ParamName = "TrajFormat" 1969 ParamValue = ParamsInfo[ParamName] 1970 if re.match("^DCD$", ParamValue, re.I): 1971 TrajFileExt = "dcd" 1972 elif re.match("^XTC$", ParamValue, re.I): 1973 TrajFileExt = "xtc" 1974 else: 1975 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: DCD or XTC" % (ParamValue, ParamName, ParamsOptionName)) 1976 ParamsInfo["TrajFileExt"] = TrajFileExt 1977 1978 ParamName = "PDBOutFormat" 1979 ParamValue = ParamsInfo[ParamName] 1980 if re.match("^PDB$", ParamValue, re.I): 1981 PDBOutfileExt = "pdb" 1982 elif re.match("^CIF$", ParamValue, re.I): 1983 PDBOutfileExt = "cif" 1984 else: 1985 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: PDB or CIF" % (ParamValue, ParamName, ParamsOptionName)) 1986 ParamsInfo["PDBOutfileExt"] = PDBOutfileExt 1987 1988 _ProcessFileNamesOutputPatramaters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1989 _ProcessDataOutTypeOutputParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1990 _ProcessMinimizationDataOutTypeOutputParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix) 1991 1992 def _ProcessFileNamesOutputPatramaters(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix): 1993 """Process output parameters corresponding to file names.""" 1994 1995 OutfileExt = ParamsInfo["DataOutfileExt"] 1996 TrajFileExt = ParamsInfo["TrajFileExt"] 1997 OutfilesSuffixAndExtMap = {"CheckpointFile": ["", "chk"], "DataLogFile": ["", OutfileExt], "MinimizationDataLogFile": ["Minimization", OutfileExt], "SaveFinalStateCheckpointFile": ["FinalState", "chk"], "SaveFinalStateXMLFile": ["FinalState", "xml"], "TrajFile": ["", TrajFileExt], "XmlSystemFile": ["System", "xml"], "XmlIntegratorFile": ["Integrator", "xml"]} 1998 OutfileNames = [] 1999 for ParamName in OutfilesSuffixAndExtMap: 2000 ParamValue = ParamsInfo[ParamName] 2001 if re.match("^auto$", ParamValue, re.I): 2002 DataOutfileSuffix, DataOutfileExt = OutfilesSuffixAndExtMap[ParamName] 2003 if len(DataOutfileSuffix): 2004 DataOutfileSuffix = "_%s" % DataOutfileSuffix 2005 ParamValue = "%s%s.%s" % (OutfilePrefix, DataOutfileSuffix, DataOutfileExt) 2006 ParamsInfo[ParamName] = ParamValue 2007 else: 2008 # Check for duplicate output file names... 2009 if ParamValue not in OutfileNames: 2010 OutfileNames.append(ParamValue) 2011 else: 2012 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. It's a duplicate file name." % (ParamValue, ParamName, ParamsOptionName)) 2013 2014 # Validate specified traj file extension... 2015 if re.match("^TrajFile$", ParamName, re.I): 2016 TrajFormat = ParamsInfo["TrajFormat"] 2017 if not MiscUtil.CheckFileExt(ParamValue, TrajFileExt): 2018 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. The file extension must match must match the extenstion, %s, corresponding to trajectory format, %s, speecified using \"--trajFormat\" option." % (ParamValue, ParamName, ParamsOptionName, TrajFileExt, TrajFormat)) 2019 2020 def _ProcessDataOutTypeOutputParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix): 2021 """Process output parameter corresponding to data out type.""" 2022 2023 # Setup data out types... 2024 DataOutTypeStatusMap = {"Step": False, "Speed": False, "Progress": False, "PotentialEnergy": False, "Temperature": False, "ElapsedTime": False, "RemainingTime": False, "Time": False, "KineticEnergy": False, "TotalEnergy": False, "Volume": False, "Density": False} 2025 CanonicalDataOutTypeMap = {} 2026 ValidDataOutTypes = [] 2027 for DataOutType in DataOutTypeStatusMap: 2028 ValidDataOutTypes.append(DataOutType) 2029 CanonicalDataOutTypeMap[DataOutType.lower()] = DataOutType 2030 2031 # Process data out types... 2032 ParamName = "DataOutType" 2033 ParamValue = ParamsInfo[ParamName] 2034 DataOutTypeList = [] 2035 if re.match("^auto$", ParamValue, re.I): 2036 DataOutTypeList = ["Step", "Speed", "Progress", "PotentialEnergy", "Temperature"] 2037 else: 2038 if "DataOutTypeList" in ParamsInfo: 2039 DataOutTypeList = ParamsInfo["DataOutTypeList"] 2040 else: 2041 DataOutTypeList = ParamsInfo["DataOutType"].split() 2042 ParamsInfo["DataOutTypeList"] = DataOutTypeList 2043 2044 for DataOutType in DataOutTypeList: 2045 CanonicalDataOutType = DataOutType.lower() 2046 if CanonicalDataOutType not in CanonicalDataOutTypeMap: 2047 MiscUtil.PrintError("The parameter value, %s specified for paramaer name, %s, specified using \"%s\" is not a valid name. Supported parameter names: %s" % (DataOutType, ParamName, ParamsOptionName, " ".join(ValidDataOutTypes))) 2048 2049 DataOutType = CanonicalDataOutTypeMap[CanonicalDataOutType] 2050 DataOutTypeStatusMap[DataOutType] = True 2051 2052 ParamsInfo["DataOutTypeList"] = DataOutTypeList 2053 ParamsInfo["DataOutTypeStatusMap"] = DataOutTypeStatusMap 2054 2055 def _ProcessMinimizationDataOutTypeOutputParameter(ParamsInfo, ParamsOptionName, ParamsOptionValue, OutfilePrefix): 2056 """Process output parameter corresponding to minimization data out type.""" 2057 2058 # Setup mimimization data out types... 2059 DataOutTypeOpenMMNameMap = {"SystemEnergy": "system energy", "RestraintEnergy": "restraint energy", "RestraintStrength": "restraint strength", "MaxConstraintError": "max constraint error"} 2060 2061 CanonicalDataOutTypeMap = {} 2062 ValidDataOutTypes = [] 2063 for DataOutType in DataOutTypeOpenMMNameMap: 2064 ValidDataOutTypes.append(DataOutType) 2065 CanonicalDataOutTypeMap[DataOutType.lower()] = DataOutType 2066 2067 # Process minimization data out types... 2068 ParamName = "MinimizationDataOutType" 2069 ParamValue = ParamsInfo[ParamName] 2070 DataOutTypeList = [] 2071 if re.match("^auto$", ParamValue, re.I): 2072 DataOutTypeList = ["SystemEnergy", "RestraintEnergy", "MaxConstraintError"] 2073 else: 2074 if "MinimizationDataOutTypeList" in ParamsInfo: 2075 DataOutTypeList = ParamsInfo["MinimizationDataOutTypeList"] 2076 else: 2077 DataOutTypeList = ParamsInfo["MinimizationDataOutType"].split() 2078 ParamsInfo["MinimizationDataOutTypeList"] = DataOutTypeList 2079 2080 # Set up a list containing OpenMM names for minimization reporter... 2081 DataOutTypeOpenMMNameList = [] 2082 for DataOutType in DataOutTypeList: 2083 CanonicalDataOutType = DataOutType.lower() 2084 if CanonicalDataOutType not in CanonicalDataOutTypeMap: 2085 MiscUtil.PrintError("The parameter value, %s specified for paramaer name, %s, specified using \"%s\" is not a valid name. Supported parameter names: %s" % (DataOutType, ParamName, ParamsOptionName, " ".join(ValidDataOutTypes))) 2086 2087 DataOutType = CanonicalDataOutTypeMap[CanonicalDataOutType] 2088 2089 DataOutTypeOpenMMName = DataOutTypeOpenMMNameMap[DataOutType] 2090 DataOutTypeOpenMMNameList.append(DataOutTypeOpenMMName) 2091 2092 ParamsInfo["MinimizationDataOutTypeList"] = DataOutTypeList 2093 ParamsInfo["MinimizationDataOutTypeOpenMMNameList"] = DataOutTypeOpenMMNameList 2094 2095 def ProcessOptionOpenMMAtomsSelectionParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 2096 """Process parameters for selecting atoms and return a map containing 2097 processed parameter names and values. 2098 2099 ParamsOptionValue is a comma delimited list of parameter name and value pairs 2100 to select atoms. 2101 2102 The supported parameter names along with their default and possible 2103 values are shown below: 2104 2105 selection, none [ Possible values: CAlphaProtein, Ions, Ligand, 2106 Protein, Residues, or Water ] 2107 selectionSpec, auto [ Possible values: A space delimited list of 2108 residue names ] 2109 negate, no [ Possible values: yes or no ] 2110 2111 A brief description of parameters is provided below: 2112 2113 selection: Atom selection to freeze. 2114 2115 selectionSpec: A space delimited list of residue names for selecting atoms. 2116 You must specify its value during 'Ligand' and 'Protein' value for 'selection'. 2117 The default values are automatically set for 'CAlphaProtein', 'Ions', 'Protein', 2118 and 'Water' values of 'selection' as shown below: 2119 2120 CAlphaProtein: List of stadard protein residues from pdbfixer 2121 for selecting CAlpha atoms. 2122 Ions: Li Na K Rb Cs Cl Br F I 2123 Water: HOH 2124 Protein: List of standard protein residues from pdbfixer. 2125 2126 negate: Negate atom selection match to select atoms for freezing. 2127 2128 In addition, you may specify an explicit space delimited list of residue 2129 names using 'selectionSpec' for any 'selection". The specified residue 2130 names are appended to the appropriate default values during the 2131 selection of atoms for freezing. 2132 2133 Arguments: 2134 ParamsOptionName (str): Command line OpenMM selection option name. 2135 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 2136 ParamsDefaultInfo (dict): Default values to override for selected parameters. 2137 2138 Returns: 2139 dictionary: Processed parameter name and value pairs. 2140 2141 """ 2142 2143 ParamsInfo = {"Selection": None, "SelectionSpec": "auto", "Negate": False} 2144 2145 if ParamsOptionValue is None: 2146 return ParamsInfo 2147 2148 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 2149 2150 if re.match("^auto$", ParamsOptionValue, re.I): 2151 _ProcessOptionOpenMMAtomsSelectionParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2152 return ParamsInfo 2153 2154 for Index in range(0, len(ParamsOptionValueWords), 2): 2155 Name = ParamsOptionValueWords[Index].strip() 2156 Value = ParamsOptionValueWords[Index + 1].strip() 2157 2158 ParamName = CanonicalParamNamesMap[Name.lower()] 2159 ParamValue = Value 2160 2161 # Set value... 2162 ParamsInfo[ParamName] = ParamValue 2163 if re.match("^Selection$", ParamName, re.I): 2164 if not re.match("^(CAlphaProtein|Ions|Ligand|Protein|Residues|Water)$", Value, re.I): 2165 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: CAlphaProtein, Ions, Ligand, Protein, Residues, or Water" % (Value, Name, ParamsOptionName)) 2166 ParamValue = Value 2167 elif re.match("^SelectionSpec$", ParamName, re.I): 2168 if not re.match("^(auto|none)$", Value, re.I): 2169 Values = Value.split() 2170 if len(Values) == 0: 2171 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. It must contain space delimited list of residue names.\n" % (Value, ParamName, ParamsOptionName)) 2172 # Set residues list... 2173 ParamsInfo["SelectionSpecList"] = Values 2174 elif re.match("^Negate$", ParamName, re.I): 2175 if not re.match("^(yes|no|true|false)$", Value, re.I): 2176 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 2177 ParamValue = True if re.match("^(yes|true)$", Value, re.I) else False 2178 else: 2179 ParamValue = Value 2180 2181 # Set value... 2182 ParamsInfo[ParamName] = ParamValue 2183 2184 # Handle parameters with possible auto values... 2185 _ProcessOptionOpenMMAtomsSelectionParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2186 2187 return ParamsInfo 2188 2189 def _ProcessOptionOpenMMAtomsSelectionParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 2190 """Process parameters with possible auto values and perform validation. 2191 """ 2192 2193 SelectionParamName = "Selection" 2194 SelectionParamValue = ParamsInfo[SelectionParamName] 2195 2196 SelectionSpecParamName = "SelectionSpec" 2197 SelectionSpecParamValue = ParamsInfo[SelectionSpecParamName] 2198 2199 SelectionSpecList = None if re.match("^(auto|none)$", SelectionSpecParamValue, re.I) else ParamsInfo["SelectionSpecList"] 2200 2201 ResidueNames = None 2202 if re.match("^(CAlphaProtein|Protein)$", SelectionParamValue, re.I): 2203 ResidueNames = pdbfixer.pdbfixer.proteinResidues 2204 if SelectionSpecList is not None: 2205 ResidueNames.extend(SelectionSpecList) 2206 elif re.match("^Ions$", SelectionParamValue, re.I): 2207 ResidueNames = ["Li", "Na", "K", "Rb", "Cs", "Cl", "Br", "F", "I"] 2208 if SelectionSpecList is not None: 2209 ResidueNames.extend(SelectionSpecList) 2210 elif re.match("^Ligand$", SelectionParamValue, re.I): 2211 if SelectionSpecList is None: 2212 MiscUtil.PrintError("No value specified for parameter name, %s, using \"%s\" option is not a valid value. It must contain a ligand residue name.\n" % (SelectionSpecParamName, ParamsOptionName)) 2213 elif len(SelectionSpecList) != 1: 2214 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. It must contain a single ligand residue name.\n" % (SelectionSpecParamValue, SelectionSpecParamName, ParamsOptionName)) 2215 ResidueNames = SelectionSpecList 2216 elif re.match("^Residues$", SelectionParamValue, re.I): 2217 if SelectionSpecList is None: 2218 MiscUtil.PrintError("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 residue names.\n" % (SelectionSpecParamValue, SelectionSpecParamName, ParamsOptionName)) 2219 ResidueNames = SelectionSpecList 2220 elif re.match("^Water$", SelectionParamValue, re.I): 2221 ResidueNames = ["HOH"] 2222 if SelectionSpecList is not None: 2223 ResidueNames.extend(SelectionSpecList) 2224 2225 ParamsInfo["ResidueNames"] = [ResidueName.upper() for ResidueName in ResidueNames] 2226 ParamsInfo["CAlphaProteinStatus"] = True if re.match("^CAlphaProtein$", SelectionParamValue, re.I) else False 2227 2228 def ProcessOptionOpenMMForcefieldParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 2229 """Process parameters for biopolymer, small molecule, and water forcefields and 2230 return a map containing processed parameter names and values. 2231 2232 ParamsOptionValue is a comma delimited list of parameter name and value pairs 2233 for forcefields. 2234 2235 The supported parameter names along with their default and possible 2236 values are shown below: 2237 2238 biopolymer, amber14-all.xml [ Possible values: Any Valid value ] 2239 smallMolecule, OpenFF_2.2.0 [ Possible values: Any Valid value ] 2240 water, auto [ Possible values: Any Valid value ] 2241 2242 Possible biopolymer forcefield values: 2243 2244 amber14-all.xml, amber99sb.xml, amber99sbildn.xml, amber03.xml, 2245 amber10.xml 2246 charmm36.xml, charmm_polar_2019.xml 2247 amoeba2018.xml 2248 2249 Possible small molecule forcefield values: 2250 2251 openff_2.2.0, openff_2.0.0, openff_1.3.1, openff_1.2.1, openff_1.1.1, 2252 smirnoff99frosst 2253 gaff-2.11, gaff-2.1, gaff-1.81, gaff-1.8, gaff-1.4 2254 2255 The default water forcefield valus is dependent on the type of the 2256 biopolymer forcefield as shown below: 2257 2258 Amber: amber14/tip3pfb.xml 2259 CHARMM: charmm36/water.xml or None for charmm_polar_2019.xml 2260 Amoeba: None (Explicit) 2261 2262 Possible water forcefield values: 2263 2264 amber14/tip3p.xml, amber14/tip3pfb.xml, amber14/spce.xml, 2265 amber14/tip4pew.xml, amber14/tip4pfb.xml, 2266 implicit/obc2.xml, implicit/GBn.xml, implicit/GBn2.xml 2267 charmm36/water.xml, charmm36/tip3p-pme-b.xml, 2268 charmm36/tip3p-pme-f.xml, charmm36/spce.xml, 2269 charmm36/tip4pew.xml, charmm36/tip4p2005.xml, 2270 charmm36/tip5p.xml, charmm36/tip5pew.xml, 2271 implicit/obc2.xml, implicit/GBn.xml, implicit/GBn2.xml 2272 amoeba2018_gk.xml (Implict water), None (Explicit water for amoeba) 2273 2274 You may specify any valid forcefield name supported by OpenMM. No 2275 explicit validation is performed. 2276 2277 Arguments: 2278 ParamsOptionName (str): Command line OpenMM forcefield option name. 2279 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 2280 ParamsDefaultInfo (dict): Default values to override for selected parameters. 2281 2282 Returns: 2283 dictionary: Processed parameter name and value pairs. 2284 2285 """ 2286 2287 ParamsInfo = {"Biopolymer": "amber14-all.xml", "SmallMolecule": "openff-2.2.1", "Water": "auto", "Additional" : "None"} 2288 2289 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 2290 2291 if re.match("^auto$", ParamsOptionValue, re.I): 2292 _ProcessOptionOpenMMForcefieldParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2293 return ParamsInfo 2294 2295 for Index in range(0, len(ParamsOptionValueWords), 2): 2296 Name = ParamsOptionValueWords[Index].strip() 2297 Value = ParamsOptionValueWords[Index + 1].strip() 2298 2299 ParamName = CanonicalParamNamesMap[Name.lower()] 2300 ParamValue = Value 2301 2302 # Set value... 2303 ParamsInfo[ParamName] = ParamValue 2304 2305 # Handle parameters with possible auto values... 2306 _ProcessOptionOpenMMForcefieldParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2307 2308 return ParamsInfo 2309 2310 def _ProcessOptionOpenMMForcefieldParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 2311 """Process parameters with possible auto values and perform validation. 2312 """ 2313 WaterForcefield = ParamsInfo["Water"] 2314 if re.match("^None$", WaterForcefield, re.I): 2315 WaterForcefield = None 2316 ParamsInfo["Water"] = WaterForcefield 2317 elif re.match("^auto$", WaterForcefield, re.I): 2318 BiopolymerForcefield = ParamsInfo["Biopolymer"] 2319 if re.search("amber", BiopolymerForcefield, re.I): 2320 WaterForcefield = "amber14/tip3pfb.xml" 2321 elif re.search("charmm", BiopolymerForcefield, re.I): 2322 if re.search("charmm_polar_2019", BiopolymerForcefield, re.I): 2323 WaterForcefield = None 2324 else: 2325 WaterForcefield = "charmm36/water.xml" 2326 elif re.search("amoeba", BiopolymerForcefield, re.I): 2327 # Explicit water... 2328 WaterForcefield = None 2329 else: 2330 WaterForcefield = None 2331 ParamsInfo["Water"] = WaterForcefield 2332 2333 # Set status of implicit water forcefield... 2334 BiopolymerForcefield = ParamsInfo["Biopolymer"] 2335 ParamsInfo["ImplicitWater"] = True if _IsImplicitWaterForcefield(BiopolymerForcefield, WaterForcefield) else False 2336 2337 # Process additional forcefields... 2338 ParamName = "Additional" 2339 ParamValue = ParamsInfo[ParamName] 2340 ParamValuesList = None 2341 if not re.match("^None$", ParamValue, re.I): 2342 ParamValuesList = ParamValue.split() 2343 if len(ParamValuesList) == 0: 2344 MiscUtil.PrintError("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 valid values.\n" % (ParamValue, ParamName, ParamsOptionName)) 2345 ParamsInfo["AdditionalList"] = ParamValuesList 2346 2347 def _IsImplicitWaterForcefield(BiopolymerForcefield, WaterForcefield): 2348 """Check the nature of the water forcefield.""" 2349 2350 Status = False 2351 if WaterForcefield is None: 2352 if re.search("charmm_polar_2019", BiopolymerForcefield, re.I): 2353 Status = True 2354 else: 2355 Status = False 2356 else: 2357 if re.search("amber", BiopolymerForcefield, re.I): 2358 if re.search("implicit", WaterForcefield, re.I): 2359 Status = True 2360 elif re.search("charmm", BiopolymerForcefield, re.I): 2361 if re.search("implicit", WaterForcefield, re.I): 2362 Status = True 2363 elif re.search("amoeba", BiopolymerForcefield, re.I): 2364 Status = True 2365 2366 return Status 2367 2368 def ProcessOptionOpenMMAnnealingParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 2369 """Process parameters for annealing option and return a map containing processed 2370 parameter names and values. 2371 2372 ParamsOptionValue is a comma delimited list of parameter name and value pairs 2373 to setup platform. 2374 2375 The supported parameter names along with their default values for 2376 different platforms are shown below: 2377 2378 threads, 1 [ Possible value: >= 0 or auto. The value of 'auto' 2379 Initial heating parameters: 2380 2381 initialStart, 0.0 [ Units: kelvin ] 2382 initialEnd, 300.0 [ Units: kelvin ] 2383 initialChange, 5.0 [ Units: kelvin ] 2384 initialSteps, 5000 2385 2386 initialEquilibrationSteps, 100000 2387 2388 Heating and cooling cycle parameters: 2389 2390 cycles, 1 2391 2392 cycleStart, auto [ Units: kelvin. The default value is set to 2393 initialEnd ] 2394 cycleEnd, 315.0 [ Units: kelvin ] 2395 cycleChange, 1.0 [ Units: kelvin ] 2396 cycleSteps, 1000 2397 2398 cycleEquilibrationSteps, 100000 2399 2400 Final equilibration parameters: 2401 2402 finalEquilibrationSteps, 200000 2403 2404 A brief description of parameters is provided below: 2405 2406 Initial heating parameters: 2407 2408 initialStart: Start temperature for initial heating. 2409 initialEnd: End temperature for initial heating. 2410 initialChange: Temperature change for increasing temperature 2411 during initial heating. 2412 initialSteps: Number of simulation steps after each 2413 heating step during initial heating 2414 2415 initialEquilibrationSteps: Number of equilibration steps 2416 after the completion of initial heating. 2417 2418 Heating and cooling cycles parameters: 2419 2420 cycles: Number of annealing cycles to perform. Each cycle 2421 consists of a heating and a cooling phase. The heating phase 2422 consists of the following steps: Heat system from start to 2423 end temperature using change size and perform simulation for a 2424 number of steps after each increase in temperature; Perform 2425 equilibration after the completion of heating. The cooling 2426 phase is reverse of the heating phase and cools the system 2427 from end to start temperature. 2428 2429 cycleStart: Start temperature for annealing cycle. 2430 cycleEnd: End temperature for annealing cycle. 2431 cycleChange: Temperature change for increasing or decreasing 2432 temperature during annealing cycle. 2433 cycleSteps: Number of simulation steps after each heating and 2434 cooling step during annealing cycle. 2435 2436 cycleEquilibrationSteps: Number of equilibration steps 2437 after the completion of heating and cooling phase during a 2438 annealing cycle. 2439 2440 Final equilibration parameters: 2441 2442 finalEquilibrationSteps: Number of final equilibration 2443 steps after the completion of annealing cycles. 2444 2445 Arguments: 2446 ParamsOptionName (str): Command line OpenMM annealing option name. 2447 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 2448 ParamsDefaultInfo (dict): Default values to override for selected parameters. 2449 2450 Returns: 2451 dictionary: Processed parameter name and value pairs. 2452 2453 """ 2454 2455 ParamsInfo = {"InitialStart": 0.0, "InitialEnd": 300.0, "InitialChange": 5.0, "InitialSteps": 5000, "InitialEquilibrationSteps": 100000, "Cycles": 1, "CycleStart": "auto", "CycleEnd": 315.0, "CycleChange": 1.0, "CycleSteps": 1000, "CycleEquilibrationSteps": 100000, "FinalEquilibrationSteps": 200000 } 2456 2457 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 2458 2459 if re.match("^auto$", ParamsOptionValue, re.I): 2460 _ProcessOptionOpenMMAnnealingParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2461 return ParamsInfo 2462 2463 for Index in range(0, len(ParamsOptionValueWords), 2): 2464 Name = ParamsOptionValueWords[Index].strip() 2465 Value = ParamsOptionValueWords[Index + 1].strip() 2466 2467 ParamName = CanonicalParamNamesMap[Name.lower()] 2468 ParamValue = Value 2469 2470 if re.match("^(InitialStart|InitialEnd|CycleEnd)$", ParamName, re.I): 2471 if not MiscUtil.IsFloat(Value): 2472 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 2473 Value = float(Value) 2474 if Value < 0: 2475 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 2476 ParamValue = Value 2477 elif re.match("^(InitialChange|CycleChange)$", ParamName, re.I): 2478 if not MiscUtil.IsFloat(Value): 2479 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 2480 Value = float(Value) 2481 if Value <= 0: 2482 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 2483 ParamValue = Value 2484 elif re.match("^CycleStart$", ParamName, re.I): 2485 if not re.match("^auto$", Value, re.I): 2486 if not MiscUtil.IsFloat(Value): 2487 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 2488 Value = float(Value) 2489 if Value < 0: 2490 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 2491 ParamValue = Value 2492 elif re.match("^(InitialSteps|InitialEquilibrationSteps|Cycles|CycleSteps|CycleEquilibrationSteps|FinalEquilibrationSteps)$", ParamName, re.I): 2493 if not MiscUtil.IsInteger(Value): 2494 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a integer.\n" % (Value, ParamName, ParamsOptionName)) 2495 Value = int(Value) 2496 if Value <= 0: 2497 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 2498 ParamValue = Value 2499 else: 2500 ParamValue = Value 2501 2502 # Set value... 2503 ParamsInfo[ParamName] = ParamValue 2504 2505 # Handle parameters with possible auto values... 2506 _ProcessOptionOpenMMAnnealingParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2507 2508 return ParamsInfo 2509 2510 def _ProcessOptionOpenMMAnnealingParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 2511 """Process parameters with possible auto values and perform validation. 2512 """ 2513 2514 ParamName = "CycleStart" 2515 ParamValue = "%s" % ParamsInfo[ParamName] 2516 if re.match("^auto$", ParamValue, re.I): 2517 ParamsInfo[ParamName] = ParamsInfo["InitialEnd"] 2518 2519 if ParamsInfo["InitialStart"] >= ParamsInfo["InitialEnd"]: 2520 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, initialStart, must be less than value, %s, specified for parameter name, initialEnd, using \"%s\" option.\n" % (ParamsInfo["InitialStart"], ParamsInfo["InitialEnd"], ParamsOptionName)) 2521 2522 if ParamsInfo["CycleStart"] >= ParamsInfo["CycleEnd"]: 2523 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, cycleStart, must be less than value, %s, specified for parameter name, cycleEnd, using \"%s\" option.\n" % (ParamsInfo["CycleStart"], ParamsInfo["CycleEnd"], ParamsOptionName)) 2524 2525 if ParamsInfo["CycleStart"] != ParamsInfo["InitialEnd"]: 2526 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, cycleStart, must be equal to value, %s, specified for parameter name, initialEndEnd, using \"%s\" option.\n" % (ParamsInfo["CycleStart"], ParamsInfo["InitialEnd"], ParamsOptionName)) 2527 2528 if ParamsInfo["InitialChange"] >= (ParamsInfo["InitialEnd"] - ParamsInfo["InitialStart"]): 2529 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, initialChange, must be less than value, %s, corresponding to the difference between values specified for parameter names, initialStart and initialEnd, using \"%s\" option.\n" % (ParamsInfo["InitialChange"], (ParamsInfo["InitialEnd"] - ParamsInfo["InitialStart"]), ParamsOptionName)) 2530 2531 if ParamsInfo["CycleChange"] >= (ParamsInfo["CycleEnd"] - ParamsInfo["CycleStart"]): 2532 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, cycleChange, must be less than value, %s, corresponding to the difference between values specified for parameter names, cycleStart and cycleEnd, using \"%s\" option.\n" % (ParamsInfo["CycleChange"], (ParamsInfo["CycleEnd"] - ParamsInfo["CycleStart"]), ParamsOptionName)) 2533 2534 2535 def ProcessOptionOpenMMPlatformParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 2536 """Process parameters for platform option and return a map containing processed 2537 parameter names and values. 2538 2539 ParamsOptionValue is a comma delimited list of parameter name and value pairs 2540 to setup platform. 2541 2542 The supported parameter names along with their default values for 2543 different platforms are shown below: 2544 2545 CPU: 2546 2547 threads, 1 [ Possible value: >= 0 or auto. The value of 'auto' 2548 or zero implies the use of all available CPUs for threading. ] 2549 2550 CUDA: 2551 2552 deviceIndex, auto [ Possible values: 0, '0 1' etc. ] 2553 deterministicForces, auto [ Possible values: yes or no ] 2554 precision, single [ Possible values: single, double, or mix ] 2555 tempDirectory, auto [ Possible value: DirName ] 2556 useBlockingSync, auto [ Possible values: yes or no ] 2557 useCpuPme, auto [ Possible values: yes or no ] 2558 2559 OpenCL: 2560 2561 deviceIndex, auto [ Possible values: 0, '0 1' etc. ] 2562 openCLPlatformIndex, auto [ Possible value: Number] 2563 precision, single [ Possible values: single, double, or mix ] 2564 useCpuPme, auto [ Possible values: yes or no ] 2565 2566 A brief description of parameters is provided below: 2567 2568 CPU: 2569 2570 threads: Number of threads to use for simulation. 2571 2572 CUDA: 2573 2574 deviceIndex: Space delimited list of device indices to use for 2575 calculations. 2576 deterministicForces: Generate reproducible results at the cost of a 2577 small decrease in performance. 2578 precision: Number precision to use for calculations. 2579 tempDirectory: Directory name for storing temporary files. 2580 useBlockingSync: Control run-time synchronization between CPU and 2581 GPU. 2582 useCpuPme: Use CPU-based PME implementation. 2583 2584 OpenCL: 2585 2586 deviceIndex: Space delimited list of device indices to use for 2587 simulation. 2588 openCLPlatformIndex: Platform index to use for calculations. 2589 precision: Number precision to use for calculations. 2590 useCpuPme: Use CPU-based PME implementation. 2591 2592 Arguments: 2593 ParamsOptionName (str): Command line OpenMM platform option name. 2594 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 2595 ParamsDefaultInfo (dict): Default values to override for selected parameters. 2596 2597 Returns: 2598 dictionary: Processed parameter name and value pairs. 2599 2600 """ 2601 2602 ParamsInfo = {"Name": "CPU", "Threads": "auto", "DeviceIndex": "auto", "DeterministicForces": "auto", "Precision": "single", "TempDirectory": "auto", "UseBlockingSync": "auto", "UseCpuPme": "auto", "OpenCLPlatformIndex": "auto"} 2603 2604 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 2605 2606 if re.match("^auto$", ParamsOptionValue, re.I): 2607 _ProcessOptionOpenMMPlatformParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2608 return ParamsInfo 2609 2610 for Index in range(0, len(ParamsOptionValueWords), 2): 2611 Name = ParamsOptionValueWords[Index].strip() 2612 Value = ParamsOptionValueWords[Index + 1].strip() 2613 2614 ParamName = CanonicalParamNamesMap[Name.lower()] 2615 ParamValue = Value 2616 2617 if re.match("^Name$", ParamName, re.I): 2618 if not re.match("^(CPU|CUDA|OpenCL|Reference)$", Value, re.I): 2619 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: CPU, GPU, OpenCL, or Reference" % (Value, Name, ParamsOptionName)) 2620 ParamValue = Value 2621 elif re.match("^Threads$", ParamName, re.I): 2622 if not re.match("^auto$", Value, re.I): 2623 if not MiscUtil.IsInteger(Value): 2624 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (Value, ParamName, ParamsOptionName)) 2625 Value = int(Value) 2626 if Value < 0: 2627 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: >=0 \n" % (ParamValue, ParamName, ParamsOptionName)) 2628 if Value > mp.cpu_count(): 2629 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is greater than number of CPUs, %s, returned by mp.cpu_count().\n" % (ParamValue, ParamName, ParamsOptionName, mp.cpu_count())) 2630 ParamValue = "%s" % Value 2631 elif re.match("^Precision$", ParamName, re.I): 2632 if not re.match("^(Single|Double|Mix)$", Value, re.I): 2633 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: single, double or mix" % (Value, Name, ParamsOptionName)) 2634 ParamValue = Value.lower() 2635 elif re.match("^(DeterministicForces|UseBlockingSync|UseCpuPme)$", ParamName, re.I): 2636 if not re.match("^auto$", Value, re.I): 2637 if not re.match("^(yes|no|true|false)$", Value, re.I): 2638 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: yes or no" % (Value, Name, ParamsOptionName)) 2639 ParamValue = "true" if re.match("^(yes|true)$", Value, re.I) else "false" 2640 elif re.match("^(DeviceIndex|openCLPlatformIndex)$", ParamName, re.I): 2641 if not re.match("^auto$", Value, re.I): 2642 DeviceIndices = Value.split() 2643 if len(DeviceIndices) == 0: 2644 MiscUtil.PrintError("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" % (Value, ParamName, ParamsOptionName)) 2645 for DeviceIndex in DeviceIndices: 2646 if not MiscUtil.IsInteger(DeviceIndex): 2647 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be an integer.\n" % (DeviceIndex, ParamName, ParamsOptionName)) 2648 ParamValue = ",".join(DeviceIndices) 2649 elif re.match("^TempDirectory$", ParamName, re.I): 2650 if not re.match("^auto$", Value, re.I): 2651 if not os.path.isdir(Value): 2652 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. The specified directory doesn't exists." % (Value, Name, ParamsOptionName)) 2653 ParamValue = Value 2654 else: 2655 ParamValue = Value 2656 2657 # Set value... 2658 ParamsInfo[ParamName] = ParamValue 2659 2660 # Handle parameters with possible auto values... 2661 _ProcessOptionOpenMMPlatformParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2662 2663 return ParamsInfo 2664 2665 def _ProcessOptionOpenMMPlatformParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 2666 """Process parameters with possible auto values and perform validation. 2667 """ 2668 2669 ParamValueMap = {"cpu": "CPU", "cuda": "CUDA", "opencl": "OpenCL", "reference": "Reference"} 2670 ParamName = "Name" 2671 ParamValue = ParamsInfo[ParamName].lower() 2672 if ParamValue in ParamValueMap: 2673 ParamsInfo[ParamName] = ParamValueMap[ParamValue] 2674 2675 ParamsInfo["Precision"] = ParamsInfo["Precision"].lower() 2676 2677 # Set "auto" values to None and treat all other values as strings... 2678 for ParamName in ParamsInfo: 2679 ParamValue = "%s" % ParamsInfo[ParamName] 2680 if re.match("^auto$", ParamValue, re.I): 2681 ParamsInfo[ParamName] = None 2682 else: 2683 ParamsInfo[ParamName] = ParamValue 2684 2685 def ProcessOptionOpenMMWaterBoxParameters(ParamsOptionName, ParamsOptionValue, ParamsDefaultInfo = None): 2686 """Process parameters for adding a water box option and return a map containing 2687 processed parameter names and values. 2688 2689 ParamsOptionValue is a comma delimited list of parameter name and value pairs 2690 for adding a water box. 2691 2692 The supported parameter names along with their default and possible 2693 values are shown below: 2694 2695 model, tip3p [ Possible values: tip3p, spce, tip4pew, tip5p or swm4ndp ] 2696 mode, Padding [ Possible values: Size or Padding ] 2697 size, None [ Possible values: xsize ysize zsize ] 2698 padding, 1.0 2699 shape, cube [ Possible values: cube, dodecahedron, or octahedron ] 2700 ionPositive, Na+ [ Possible values: Li+, Na+, K+, Rb+, or Cs+ ] 2701 ionNegative, Cl- [ Possible values: Cl-, Br-, F-, or I- ] 2702 ionicStrength, 0.0 2703 2704 A brief description of parameters is provided below: 2705 2706 model: Water model to use for adding water box. 2707 2708 mode: Specify the size of the waterbox explicitly or calculate it automatically 2709 for a macromolecule along with adding padding around macromolecule. 2710 Possible values: Size or Padding. 2711 2712 size: A space delimited triplet of values corresponding to water size in 2713 nanometers. It must be specified during 'Size' value of 'mode' parameter. 2714 2715 padding: Padding around macromolecule in nanometers for filling box with 2716 water. It must be specified during 'Padding' value of 'mode' parameter. 2717 2718 ionPositive: Type of positive ion to add during the addition of a water box. 2719 2720 ionNegative: Type of negative ion to add during the addition of a water box. 2721 2722 ionicStrength: Total concentration (molar) of both positive and negative ions 2723 to add excluding he ions added to neutralize the system during the addition 2724 of a water box. 2725 2726 Arguments: 2727 ParamsOptionName (str): Command line OpenMM water box option name. 2728 ParamsOptionValues (str): Space delimited list of parameter name and value pairs. 2729 ParamsDefaultInfo (dict): Default values to override for selected parameters. 2730 2731 Returns: 2732 dictionary: Processed parameter name and value pairs. 2733 2734 """ 2735 2736 ParamsInfo = {"Model": "tip3p", "Mode": "Padding", "Size": None, "Padding": 1.0, "Shape": "cube", "IonPositive": "Na+", "IonNegative": "Cl-", "IonicStrength": 0.0} 2737 2738 (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords) = _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo) 2739 2740 if re.match("^auto$", ParamsOptionValue, re.I): 2741 _ProcessOptionOpenMMWaterBoxParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2742 return ParamsInfo 2743 2744 for Index in range(0, len(ParamsOptionValueWords), 2): 2745 Name = ParamsOptionValueWords[Index].strip() 2746 Value = ParamsOptionValueWords[Index + 1].strip() 2747 2748 ParamName = CanonicalParamNamesMap[Name.lower()] 2749 ParamValue = Value 2750 2751 if re.match("^Model$", ParamName, re.I): 2752 if not re.match("^(tip3p|spce|tip4pew|tip5p|swm4ndp)$", Value, re.I): 2753 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: tip3p, spce, tip4pew, tip5p, or swm4ndp" % (Value, Name, ParamsOptionName)) 2754 ParamValue = Value.lower() 2755 elif re.match("^Mode$", ParamName, re.I): 2756 if not re.match("^(Padding|Size)$", Value, re.I): 2757 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: Padding or Size" % (Value, Name, ParamsOptionName)) 2758 ParamValue = Value 2759 elif re.match("^Size$", ParamName, re.I): 2760 if Value is not None and not re.match("^None$", Value, re.I): 2761 SizeValues = Value.split() 2762 if len(SizeValues) != 3: 2763 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. It must contain 3 float values separated by spaces.\n" % (Value, ParamName, ParamsOptionName)) 2764 2765 SizeValueList = [] 2766 for SizeValue in SizeValues: 2767 if not MiscUtil.IsFloat(SizeValue): 2768 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (SizeValue, ParamName, ParamsOptionName)) 2769 SizeValue = float(SizeValue) 2770 if SizeValue <= 0: 2771 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (SizeValue, ParamName, ParamsOptionName)) 2772 SizeValueList.append(SizeValue) 2773 2774 # Set size values... 2775 ParamsInfo["SizeList"] = SizeValueList 2776 2777 ParamValue = Value 2778 elif re.match("^Padding$", ParamName, re.I): 2779 if not MiscUtil.IsFloat(Value): 2780 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 2781 Value = float(Value) 2782 if Value <= 0: 2783 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: > 0\n" % (ParamValue, ParamName, ParamsOptionName)) 2784 ParamValue = Value 2785 elif re.match("^Shape$", ParamName, re.I): 2786 if not re.match("^(cube|dodecahedron|octahedron)$", Value, re.I): 2787 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: cube, dodecahedron, or octahedron" % (Value, Name, ParamsOptionName)) 2788 ParamValue = Value.lower() 2789 elif re.match("^IonPositive$", ParamName, re.I): 2790 ValidValues = "Li+ Na+ K+ Rb+ Cs+" 2791 EscapedValidValuesPattern = "Li\+|Na\+|K\+|Rb\+|Cs\+" 2792 if not re.match("^(%s)$" % EscapedValidValuesPattern, Value): 2793 MiscUtil.PrintError("The value specified, %s, for parameter name, %s, using \"%s\" option is not a valid. Supported value(s): %s" % (ParamValue, ParamName, ParamsOptionName, ValidValues)) 2794 ParamValue = Value 2795 elif re.match("^IonNegative$", ParamName, re.I): 2796 ValidValues = "F- Cl- Br- I-" 2797 ValidValuesPattern = "F-|Cl-|Br-|I-" 2798 if not re.match("^(%s)$" % ValidValuesPattern, Value): 2799 MiscUtil.PrintError("The value specified, %s, for parameter name, %s, using \"%s\" option is not a valid. Supported value(s): %s" % (ParamValue, ParamName, ParamsOptionName, ValidValues)) 2800 ParamValue = Value 2801 elif re.match("^IonicStrength$", ParamName, re.I): 2802 if not MiscUtil.IsFloat(Value): 2803 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option must be a float.\n" % (Value, ParamName, ParamsOptionName)) 2804 Value = float(Value) 2805 if Value < 0: 2806 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: >= 0\n" % (ParamValue, ParamName, ParamsOptionName)) 2807 ParamValue = Value 2808 else: 2809 ParamValue = Value 2810 2811 # Set value... 2812 ParamsInfo[ParamName] = ParamValue 2813 2814 # Handle parameters with possible auto values... 2815 _ProcessOptionOpenMMWaterBoxParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue) 2816 2817 return ParamsInfo 2818 2819 def _ProcessOptionOpenMMWaterBoxParameters(ParamsInfo, ParamsOptionName, ParamsOptionValue): 2820 """Process parameters with possible auto values and perform validation. 2821 """ 2822 2823 ParamsInfo["ModeSize"] = True if re.match("^Size$", ParamsInfo["Mode"], re.I) else False 2824 ParamsInfo["ModePadding"] = True if re.match("^Padding$", ParamsInfo["Mode"], re.I) else False 2825 2826 if ParamsInfo["ModeSize"]: 2827 ParamName = "Size" 2828 ParamValue = ParamsInfo[ParamName] 2829 if ParamValue is None: 2830 MiscUtil.PrintError("The parameter value, %s, specified for parameter name, %s, using \"%s\" option is not a valid value. Supported values: x y z\n" % (ParamValue, ParamName, ParamsOptionName)) 2831 else: 2832 ParamsInfo["SizeList"] = None 2833 2834 def _ValidateAndCanonicalizeParameterNames(ParamsOptionName, ParamsOptionValue, ParamsInfo, ParamsDefaultInfo): 2835 """Validate and canonicalize parameter names.""" 2836 2837 # Setup a canonical paramater names... 2838 ValidParamNames = [] 2839 CanonicalParamNamesMap = {} 2840 for ParamName in sorted(ParamsInfo): 2841 ValidParamNames.append(ParamName) 2842 CanonicalParamNamesMap[ParamName.lower()] = ParamName 2843 2844 # Update default values... 2845 if ParamsDefaultInfo is not None: 2846 for ParamName in ParamsDefaultInfo: 2847 if ParamName not in ParamsInfo: 2848 MiscUtil.PrintError("The default parameter name, %s, specified using \"%s\" option is not a valid name. Supported parameter names: %s" % (ParamName, ParamsDefaultInfo, " ".join(ValidParamNames))) 2849 ParamsInfo[ParamName] = ParamsDefaultInfo[ParamName] 2850 2851 ParamsOptionValue = ParamsOptionValue.strip() 2852 if not ParamsOptionValue: 2853 MiscUtil.PrintError("No valid parameter name and value pairs specified using \"%s\" option" % ParamsOptionName) 2854 2855 ParamsOptionValueWords = None 2856 if not re.match("^auto$", ParamsOptionValue, re.I): 2857 ParamsOptionValueWords = ParamsOptionValue.split(",") 2858 if len(ParamsOptionValueWords) % 2: 2859 MiscUtil.PrintError("The number of comma delimited paramater names and values, %d, specified using \"%s\" option must be an even number." % (len(ParamsOptionValueWords), ParamsOptionName)) 2860 2861 if ParamsOptionValueWords is not None: 2862 for Index in range(0, len(ParamsOptionValueWords), 2): 2863 Name = ParamsOptionValueWords[Index].strip() 2864 CanonicalName = Name.lower() 2865 if not CanonicalName in CanonicalParamNamesMap: 2866 MiscUtil.PrintError("The parameter name, %s, specified using \"%s\" is not a valid name. Supported parameter names: %s" % (Name, ParamsOptionName, " ".join(ValidParamNames))) 2867 2868 return (ValidParamNames, CanonicalParamNamesMap, ParamsOptionValue, ParamsOptionValueWords)