Package MolKit :: Package pdb2pqr :: Package src :: Module inputgen
[hide private]
[frames] | no frames]

Source Code for Module MolKit.pdb2pqr.src.inputgen

  1  """ inputgen class 
  2   
  3      Create an APBS input file using psize data 
  4   
  5      Written by Todd Dolinsky based on original sed script by Nathan Baker 
  6   
  7          ---------------------------- 
  8      
  9      PDB2PQR -- An automated pipeline for the setup, execution, and analysis of 
 10      Poisson-Boltzmann electrostatics calculations 
 11   
 12      Nathan A. Baker (baker@biochem.wustl.edu) 
 13      Todd Dolinsky (todd@ccb.wustl.edu) 
 14      Dept. of Biochemistry and Molecular Biophysics 
 15      Center for Computational Biology 
 16      Washington University in St. Louis 
 17   
 18      Jens Nielsen (Jens.Nielsen@ucd.ie) 
 19      University College Dublin 
 20   
 21      Additional contributing authors listed in documentation and supporting 
 22      package licenses. 
 23   
 24      Copyright (c) 2003-2007.  Washington University in St. Louis.   
 25      All Rights Reserved. 
 26   
 27      This file is part of PDB2PQR. 
 28   
 29      PDB2PQR is free software; you can redistribute it and/or modify 
 30      it under the terms of the GNU General Public License as published by 
 31      the Free Software Foundation; either version 2 of the License, or 
 32      (at your option) any later version. 
 33    
 34      PDB2PQR is distributed in the hope that it will be useful, 
 35      but WITHOUT ANY WARRANTY; without even the implied warranty of 
 36      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 37      GNU General Public License for more details. 
 38      
 39      You should have received a copy of the GNU General Public License 
 40      along with PDB2PQR; if not, write to the Free Software 
 41      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
 42   
 43      ---------------------------- 
 44  """ 
 45   
 46  # User - Definable Variables: Default values 
 47   
 48  # CFAC = 1.7                  # Factor by which to expand mol dims to 
 49                                # get coarse grid dims 
 50  # FADD = 20                   # Amount to add to mol dims to get fine 
 51                                # grid dims 
 52  # SPACE = 0.50                # Desired fine mesh resolution 
 53  # GMEMFAC = 200               # Number of bytes per grid point required  
 54                                # for sequential MG calculation  
 55  # GMEMCEIL = 400              # Max MB allowed for sequential MG 
 56                                # calculation.  Adjust this to force the 
 57                                # script to perform faster calculations (which 
 58                                # require more parallelism). 
 59  # OFAC = 0.1                  # Overlap factor between mesh partitions 
 60  # REDFAC = 0.25               # The maximum factor by which a domain 
 61                                # dimension can be reduced during focusing 
 62   
 63  import string, sys 
 64  import psize 
 65   
66 -class Elec:
67 """ 68 An object for the ELEC section of an APBS input file 69 """
70 - def __init__(self, size, method, asyncflag):
71 """ 72 Initialize the variables that can be set in this object 73 Users can modify any of these variables (that's why 74 they're here!) 75 """ 76 77 # If this is an async or parallel calc, we want to use 78 # the per-grid dime rather than the global dime. 79 80 self.dime = size.getFineGridPoints() 81 gmem = 200.0 * self.dime[0] * self.dime[1] * self.dime[2] / 1024.0 / 1024.0 82 if method == "": # method not named - use ceiling 83 if gmem > size.getConstant("GMEMCEIL"): method = "mg-para" 84 else: method = "mg-auto" 85 86 if method == "mg-para": 87 self.dime = size.getSmallest() 88 89 self.method = method 90 self.glen = size.getCoarseGridDims() 91 self.cglen = size.getCoarseGridDims() 92 self.fglen = size.getFineGridDims() 93 self.pdime = size.getProcGrid() 94 95 self.label = "" 96 self.nlev = 4 97 self.ofrac = 0.1 98 self.async = 0 99 self.asyncflag = asyncflag 100 self.cgcent = "mol 1" 101 self.fgcent = "mol 1" 102 self.gcent = "mol 1" 103 self.mol = 1 104 self.lpbe = 1 105 self.npbe = 0 106 self.bcfl = "sdh" 107 self.ion = [] # Multiple ions possible 108 self.pdie = 2.0 109 self.sdie = 78.54 110 self.srfm = "smol" 111 self.chgm = "spl2" 112 self.sdens = 10.0 113 self.srad = 1.4 114 self.swin = 0.3 115 self.temp = 298.15 116 self.gamma = 0.105 117 self.calcenergy = "total" 118 self.calcforce = "no" 119 self.write = [] # Multiple write statements possible
120
121 - def __str__(self):
122 """ 123 Return the elec statement as a string. Check the method 124 to see which keywords to use. 125 """ 126 text = "elec %s\n" % self.label 127 text += " %s\n" % self.method 128 text += " dime %i %i %i\n" % (self.dime[0], self.dime[1], self.dime[2]) 129 if self.method == "mg-manual": 130 text += " nlev %i\n" % self.nlev 131 text += " glen %.3f %.3f %.3f\n" % (self.glen[0], self.glen[1], self.glen[2]) 132 text += " gcent %s\n" % self.gcent 133 elif self.method == "mg-auto": 134 text += " cglen %.4f %.4f %.4f\n" % (self.cglen[0], self.cglen[1], self.cglen[2]) 135 text += " fglen %.4f %.4f %.4f\n" % (self.fglen[0], self.fglen[1], self.fglen[2]) 136 text += " cgcent %s\n" % self.cgcent 137 text += " fgcent %s\n" % self.fgcent 138 elif self.method == "mg-para": 139 text += " pdime %i %i %i\n" % (self.pdime[0], self.pdime[1], self.pdime[2]) 140 text += " ofrac %.1f\n" % self.ofrac 141 text += " cglen %.4f %.4f %.4f\n" % (self.cglen[0], self.cglen[1], self.cglen[2]) 142 text += " fglen %.4f %.4f %.4f\n" % (self.fglen[0], self.fglen[1], self.fglen[2]) 143 text += " cgcent %s\n" % self.cgcent 144 text += " fgcent %s\n" % self.fgcent 145 if self.asyncflag == 1: 146 text += " async %i\n" % self.async 147 text += " mol %i\n" % self.mol 148 if self.lpbe: text += " lpbe\n" 149 else: text += " npbe\n" 150 text += " bcfl %s\n" % self.bcfl 151 for ion in self.ion: 152 text += " ion %.2f %.3f %.2f\n" % (ion[0], ion[1], ion[2]) 153 text += " pdie %.4f\n" % self.pdie 154 text += " sdie %.4f\n" % self.sdie 155 text += " srfm %s\n" % self.srfm 156 text += " chgm %s\n" % self.chgm 157 text += " sdens %.2f\n" % self.sdens 158 text += " srad %.2f\n" % self.srad 159 text += " swin %.2f\n" % self.swin 160 text += " temp %.2f\n" % self.temp 161 text += " gamma %.3f\n" % self.gamma 162 text += " calcenergy %s\n" % self.calcenergy 163 text += " calcforce %s\n" % self.calcforce 164 for write in self.write: 165 text += " write %s %s %s\n" % (write[0], write[1], write[2]) 166 text += "end\n" 167 return text
168
169 -class Input:
170 """ 171 The input class. Each input object is one APBS input file. 172 """ 173
174 - def __init__(self, pqrpath, size, method, asyncflag):
175 """ 176 Initialize the input file class. Each input file contains 177 a PQR name, a list of elec objects, and a list of strings 178 containing print statements. For starters assume two 179 ELEC statements are needed, one for the inhomgenous and 180 the other for the homogenous dielectric calculations. 181 182 Users can edit the elec statements and the print statements. 183 184 This assumes you have already run psize, either by 185 size.runPsize(/path/to/pqr) or 186 187 size.parseString(string) 188 size.setAll() 189 190 Parameters 191 pqrpath: The path to the PQR file (string) 192 size: The Psize object (psize) 193 method: The method (para, auto, manual, async) to use 194 asyncflag: 1 if async is desired, 0 otherwise 195 """ 196 197 self.pqrpath = pqrpath 198 self.asyncflag = asyncflag 199 200 # Initialize variables to default elec values 201 202 elec1 = Elec(size, method, asyncflag) 203 elec2 = Elec(size, method, asyncflag) 204 setattr(elec2, "sdie", 2.0) 205 self.elecs = [elec1, elec2] 206 207 i = string.rfind(pqrpath, "/") + 1 208 self.pqrname = pqrpath[i:] 209 210 self.prints = ["print energy 2 - 1 end"]
211
212 - def __str__(self):
213 """ 214 Return the text of the input file 215 """ 216 text = "read\n" 217 text += " mol pqr %s\n" % self.pqrname 218 text += "end\n" 219 for elec in self.elecs: 220 text += str(elec) 221 for prints in self.prints: 222 text += prints 223 text += "\nquit\n" 224 return text
225
226 - def printInputFiles(self):
227 """ 228 Make the input file(s) associated with this object 229 """ 230 period = string.find(self.pqrpath,".") 231 if self.asyncflag == 1: 232 outname = self.pqrpath[0:period] + "-para.in" 233 234 # Temporarily disable async flag 235 for elec in self.elecs: 236 elec.asyncflag = 0 237 file = open(outname, "w") 238 file.write(str(self)) 239 file.close() 240 241 # Now make the async files 242 elec = self.elecs[0] 243 244 nproc = elec.pdime[0] * elec.pdime[1] * elec.pdime[2] 245 for i in range(int(nproc)): 246 outname = self.pqrpath[0:period] + "-PE%i.in" % i 247 for elec in self.elecs: 248 elec.asyncflag = 1 249 elec.async = i 250 file = open(outname, "w") 251 file.write(str(self)) 252 file.close() 253 254 else: 255 if period > 0: 256 outname = self.pqrpath[0:period] + ".in" 257 else: 258 outname = self.pqrpath + ".in" 259 file = open(outname, "w") 260 file.write(str(self)) 261 file.close()
262
263 -def splitInput(filename):
264 """ 265 Split the parallel input file into multiple async file names 266 267 Parameters 268 filename: The path to the original parallel input 269 file (string) 270 """ 271 nproc = 0 272 file = open(filename) 273 text = "" 274 while 1: 275 line = file.readline() 276 if line == "": break 277 text += line 278 line = string.strip(line) 279 if line.startswith("pdime"): # Get # Procs 280 words = string.split(line) 281 nproc = int(words[1]) * int(words[2]) * int(words[3]) 282 283 if nproc == 0: 284 sys.stderr.write("%s is not a valid APBS parallel input file!\n" % filename) 285 sys.stderr.write("The inputgen script was unable to asynchronize this file!\n") 286 sys.exit(2) 287 288 period = string.find(filename,".") 289 for i in range(nproc): 290 outname = filename[0:period] + "-PE%i.in" % i 291 outtext = string.replace(text, "mg-para\n","mg-para\n async %i\n" % i) 292 outfile = open(outname, "w") 293 outfile.write(outtext) 294 outfile.close()
295
296 -def usage():
297 """ 298 Display the usage information for this script 299 """ 300 size = psize.Psize() 301 usage = "\n" 302 usage = usage + "Use this script to generate new APBS input files or split an existing\n" 303 usage = usage + "parallel input file into multiple async files.\n\n" 304 usage = usage + "Usage: inputgen.py [opts] <filename>\n" 305 usage = usage + "Optional Arguments:\n" 306 usage = usage + " --help : Display this text\n" 307 usage = usage + " --split : Split an existing parallel input file to multiple\n" 308 usage = usage + " async input files.\n" 309 usage = usage + " --METHOD=<value> : Force output file to write a specific APBS ELEC\n" 310 usage = usage + " method. Options are para (parallel), auto\n" 311 usage = usage + " (automatic), manual (manual), or async (asynchronous).\n" 312 usage = usage + " solve. async will result in multiple input files.\n" 313 usage = usage + " --CFAC=<value> : Factor by which to expand molecular dimensions to\n" 314 usage = usage + " get coarse grid dimensions.\n" 315 usage = usage + " [default = %g]\n" % size.getConstant("CFAC") 316 usage = usage + " --FADD=<value> : Amount to add to molecular dimensions to get fine\n" 317 usage = usage + " grid dimensions.\n" 318 usage = usage + " [default = %g]\n" % size.getConstant("FADD") 319 usage = usage + " --SPACE=<value> : Desired fine mesh resolution\n" 320 usage = usage + " [default = %g]\n" % size.getConstant("SPACE") 321 usage = usage + " --GMEMFAC=<value> : Number of bytes per grid point required\n" 322 usage = usage + " for sequential MG calculation\n" 323 usage = usage + " [default = %g]\n" % size.getConstant("GMEMFAC") 324 usage = usage + " --GMEMCEIL=<value> : Max MB allowed for sequential MG\n" 325 usage = usage + " calculation. Adjust this to force the\n" 326 usage = usage + " script to perform faster calculations (which\n" 327 usage = usage + " require more parallelism).\n" 328 usage = usage + " [default = %g]\n" % size.getConstant("GMEMCEIL") 329 usage = usage + " --OFAC=<value> : Overlap factor between mesh partitions\n" 330 usage = usage + " [default = %g]\n" % size.getConstant("OFAC") 331 usage = usage + " --REDFAC=<value> : The maximum factor by which a domain\n" 332 usage = usage + " dimension can be reduced during focusing\n" 333 usage = usage + " [default = %g]\n" % size.getConstant("REDFAC") 334 sys.stderr.write(usage) 335 sys.exit(2)
336
337 -def main():
338 339 import getopt 340 filename = "" 341 shortOptList = "" 342 longOptList = ["help","split","METHOD=","CFAC=","SPACE=","GMEMCEIL=","GMEMFAC=","OFAC=","REDFAC="] 343 344 try: 345 opts, args = getopt.getopt(sys.argv[1:], shortOptList, longOptList) 346 except getopt.GetoptError, details: 347 sys.stderr.write("Option error (%s)!\n" % details) 348 usage() 349 350 if len(args) != 1: 351 sys.stderr.write("Invalid argument list!\n") 352 usage() 353 else: 354 filename = args[0] 355 356 method = "" 357 size = psize.Psize() 358 async = 0 359 split = 0 360 361 for o, a in opts: 362 if o == "--help": 363 usage() 364 if o == "--split": split = 1 365 if o == "--METHOD": 366 if a == "para": 367 sys.stdout.write("Forcing a parallel calculation\n") 368 method = "mg-para" 369 elif a == "auto": 370 sys.stdout.write("Forcing a sequential calculation\n") 371 method = "mg-auto" 372 elif a == "async": 373 sys.stdout.write("Forcing an asynchronous calculation\n") 374 method = "mg-para" 375 async = 1 376 elif a == "manual": 377 sys.stdout.write("Forcing a manual calculation\n") 378 method = "mg-manual" 379 else: 380 sys.stdout.write("Incorrect method argument: %s\n" % a) 381 sys.stdout.write("Defaulting to memory dependent result\n") 382 if o == "--CFAC": 383 size.setConstant("CFAC", float(a)) 384 if o == "--SPACE": 385 size.setConstant("SPACE", float(a)) 386 if o == "--GMEMFAC": 387 size.setConstant("GMEMFAC", int(a)) 388 if o == "--GMEMCEIL": 389 size.setConstant("GMEMCEIL", int(a)) 390 if o == "--OFAC": 391 size.setConstant("OFAC", float(a)) 392 if o == "--REDFAC": 393 size.setConstant("REDFAC", float(a)) 394 395 if split == 1: 396 splitInput(filename) 397 else: 398 size.runPsize(filename) 399 input = Input(filename, size, method, async) 400 input.printInputFiles()
401 402 if __name__ == "__main__": main() 403