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