00001 """ Python APBS Driver File
00002
00003 This module allows a user to run APBS through Python. Use this module if
00004 you wish to include APBS in a Python-based application.
00005
00006 The module mimics the main.c driver that is used in the C version of APBS.
00007 The functions which are called are located in apbslib.py, which is
00008 automatically generated by SWIG to wrap each APBS function. See the APBS
00009 documentation for more information about each function.
00010
00011 Todd Dolinsky (todd@ccb.wustl.edu)
00012 Nathan Baker (baker@biochem.wustl.edu)
00013 Washington University in St. Louis
00014
00015 APBS -- Adaptive Poisson-Boltzmann Solver
00016
00017 Nathan A. Baker (baker@biochem.wustl.edu)
00018 Dept. Biochemistry and Molecular Biophysics
00019 Center for Computational Biology
00020 Washington University in St. Louis
00021
00022 Additional contributing authors listed in the code documentation.
00023
00024 Copyright (c) 2002-2010, Washington University in St. Louis.
00025 Portions Copyright (c) 2002-2010. Nathan A. Baker
00026 Portions Copyright (c) 1999-2002. The Regents of the University of California.
00027 Portions Copyright (c) 1995. Michael Holst
00028
00029 All rights reserved.
00030
00031 Redistribution and use in source and binary forms, with or without
00032 modification, are permitted provided that the following conditions are met:
00033
00034 * Redistributions of source code must retain the above copyright notice, this
00035 list of conditions and the following disclaimer.
00036
00037 * Redistributions in binary form must reproduce the above copyright notice,
00038 this list of conditions and the following disclaimer in the documentation
00039 and/or other materials provided with the distribution.
00040
00041 * Neither the name of Washington University in St. Louis nor the names of its
00042 contributors may be used to endorse or promote products derived from this
00043 software without specific prior written permission.
00044
00045 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00046 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00047 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00048 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00049 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00050 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00051 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00052 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00053 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00054 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00055 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00056 """
00057
00058 from apbslib import *
00059 import sys, time
00060 import string
00061 from sys import stdout, stderr
00062
00063 __author__ = "Todd Dolinsky, Nathan Baker, Yong Huang"
00064 __date__ = "September 2009"
00065 __version__ = "1.3"
00066
00067 Python_kb = 1.3806581e-23
00068 Python_Na = 6.0221367e+23
00069 NOSH_MAXMOL = 20
00070 NOSH_MAXCALC = 20
00071
00072 class APBSError(Exception):
00073 """ APBSError class
00074
00075 The APBSError class inherits off the Exception module and returns
00076 a string defining the nature of the error.
00077 """
00078
00079 def __init__(self, value):
00080 """
00081 Initialize with error message
00082
00083 Parameters
00084 value: Error Message (string)
00085 """
00086 self.value = value
00087
00088 def __str__(self):
00089 """
00090 Return the error message
00091 """
00092 return `self.value`
00093
00094 def getHeader():
00095 """ Get header information about APBS
00096 Returns (header)
00097 header: Information about APBS
00098 """
00099
00100 header = "\n\n\
00101 ----------------------------------------------------------------------\n\
00102 Adaptive Poisson-Boltzmann Solver (APBS)\n\
00103 Version 1.3\n\
00104 \n\
00105 APBS -- Adaptive Poisson-Boltzmann Solver\n\
00106 \n\
00107 Nathan A. Baker (baker@biochem.wustl.edu)\n\
00108 Dept. Biochemistry and Molecular Biophysics\n\
00109 Center for Computational Biology\n\
00110 Washington University in St. Louis\n\
00111 \n\
00112 Additional contributing authors listed in the code documentation.\n\
00113 \n\
00114 Copyright (c) 2002-2010, Washington University in St. Louis.\n\
00115 Portions Copyright (c) 2002-2010. Nathan A. Baker\n\
00116 Portions Copyright (c) 1999-2002. The Regents of the University of California.\n\
00117 Portions Copyright (c) 1995. Michael Holst\n\
00118 \n\
00119 All rights reserved.\n\
00120 \n\
00121 Redistribution and use in source and binary forms, with or without\n\
00122 modification, are permitted provided that the following conditions are met:\n\
00123 \n\
00124 * Redistributions of source code must retain the above copyright notice, this\n\
00125 list of conditions and the following disclaimer.\n\
00126 \n\
00127 * Redistributions in binary form must reproduce the above copyright notice,\n\
00128 this list of conditions and the following disclaimer in the documentation\n\
00129 and/or other materials provided with the distribution.\n\
00130 \n\
00131 * Neither the name of Washington University in St. Louis nor the names of its\n\
00132 contributors may be used to endorse or promote products derived from this\n\
00133 software without specific prior written permission.\n\
00134 \n\
00135 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\
00136 \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\
00137 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\
00138 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n\
00139 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
00140 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
00141 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
00142 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n\
00143 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n\
00144 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n\
00145 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\
00146 ----------------------------------------------------------------------\n\
00147 \n\n"
00148
00149 return header
00150
00151 def getUsage():
00152 """ Get usage information about running APBS via Python
00153 Returns (usage)
00154 usage: Text about running APBS via Python
00155 """
00156
00157 usage = "\n\n\
00158 ----------------------------------------------------------------------\n\
00159 This driver program calculates electrostatic potentials, energies,\n\
00160 and forces using both multigrid methods.\n\
00161 It is invoked as:\n\n\
00162 python main.py apbs.in\n\
00163 ----------------------------------------------------------------------\n\n"
00164
00165 return usage
00166
00167 def main():
00168 """ Main driver for testing. Runs APBS on given input file """
00169
00170
00171 startVio()
00172
00173
00174 com = Vcom_ctor(1)
00175 rank = Vcom_rank(com)
00176 size = Vcom_size(com)
00177 mgparm = MGparm()
00178 pbeparm = PBEparm()
00179 mem = Vmem_ctor("Main")
00180 pbe = new_pbelist(NOSH_MAXMOL)
00181 pmg = new_pmglist(NOSH_MAXMOL)
00182 pmgp = new_pmgplist(NOSH_MAXMOL)
00183 realCenter = double_array(3)
00184 totEnergy = []
00185 nforce = int_array(NOSH_MAXCALC)
00186 atomforce = new_atomforcelist(NOSH_MAXCALC)
00187
00188
00189 main_timer_start = time.clock()
00190
00191
00192 stdout.write(getHeader())
00193 if len(sys.argv) != 2:
00194 stderr.write("main: Called with %d arguments!\n" % len(sys.argv))
00195 stderr.write(getUsage())
00196 raise APBSError, "Incorrect Usage!"
00197
00198
00199 nosh = NOsh_ctor(rank, size)
00200 input_file = sys.argv[1]
00201 stdout.write("Parsing input file %s...\n" % input_file)
00202 if NOsh_parseInputFile(nosh, input_file) != 1:
00203 stderr.write("main: Error while parsing input file.\n")
00204 raise APBSError, "Error while parsing input file!"
00205
00206
00207
00208 alist = new_valist(NOSH_MAXMOL)
00209 if loadMolecules(nosh,None,alist) != 1:
00210 stderr.write("main: Error while loading molecules. \n")
00211 raise APBSError, "Error while loading molecules!"
00212
00213
00214
00215 if NOsh_setupElecCalc(nosh, alist) != 1:
00216 stderr.write("main: Error while setting up calculations. \n")
00217 raise APBSError, "Error while setting up calculations!"
00218
00219
00220
00221 dielXMap = new_gridlist(NOSH_MAXMOL)
00222 dielYMap = new_gridlist(NOSH_MAXMOL)
00223 dielZMap = new_gridlist(NOSH_MAXMOL)
00224 if loadDielMaps(nosh, dielXMap, dielYMap, dielZMap) != 1:
00225 stderr.write("Error reading dielectric maps!\n")
00226 raise APBSError, "Error reading dielectric maps!"
00227
00228 kappaMap = new_gridlist(NOSH_MAXMOL)
00229 if loadKappaMaps(nosh, kappaMap) != 1:
00230 stderr.write("Error reading kappa maps!\n")
00231 raise APBSError, "Error reading kappa maps!"
00232
00233 chargeMap = new_gridlist(NOSH_MAXMOL)
00234 if loadChargeMaps(nosh, chargeMap) != 1:
00235 stderr.write("Error reading charge maps!\n")
00236 raise APBSError, "Error reading charge maps!"
00237
00238
00239
00240 stdout.write("Preparing to run %d PBE calculations. \n" % nosh.ncalc)
00241
00242 for icalc in xrange(nosh.ncalc): totEnergy.append(0.0)
00243
00244 for icalc in xrange(nosh.ncalc):
00245 stdout.write("---------------------------------------------\n")
00246 calc = NOsh_getCalc(nosh, icalc)
00247 mgparm = calc.mgparm
00248 pbeparm = calc.pbeparm
00249 if calc.calctype != 0:
00250 stderr.write("main: Only multigrid calculations supported!\n")
00251 raise APBSError, "Only multigrid calculations supported!"
00252
00253 for k in range(0, nosh.nelec):
00254 if NOsh_elec2calc(nosh,k) >= icalc:
00255 break
00256
00257 name = NOsh_elecname(nosh, k)
00258 if name == "":
00259 stdout.write("CALCULATION #%d: MULTIGRID\n" % (icalc+1))
00260 else:
00261 stdout.write("CALCULATION #%d (%s): MULTIGRID\n" % ((icalc+1),name))
00262 stdout.write("Setting up problem...\n")
00263
00264
00265
00266 if initMG(icalc, nosh, mgparm, pbeparm, realCenter, pbe,
00267 alist, dielXMap, dielYMap, dielZMap, kappaMap, chargeMap,
00268 pmgp, pmg) != 1:
00269 stderr.write("Error setting up MG calculation!\n")
00270 raise APBSError, "Error setting up MG calculation!"
00271
00272
00273
00274
00275 printMGPARM(mgparm, realCenter)
00276 printPBEPARM(pbeparm)
00277
00278
00279
00280 thispmg = get_Vpmg(pmg,icalc)
00281
00282 if solveMG(nosh, thispmg, mgparm.type) != 1:
00283 stderr.write("Error solving PDE! \n")
00284 raise APBSError, "Error Solving PDE!"
00285
00286
00287
00288 if setPartMG(nosh, mgparm, thispmg) != 1:
00289 stderr.write("Error setting partition info!\n")
00290 raise APBSError, "Error setting partition info!"
00291
00292
00293
00294
00295 ret, totEnergy[icalc] = energyMG(nosh, icalc, thispmg, 0, \
00296 totEnergy[icalc], 0.0, 0.0, 0.0)
00297
00298
00299
00300 aforce = get_AtomForce(atomforce, icalc)
00301 wrap_forceMG(mem, nosh, pbeparm, mgparm, thispmg, aforce, alist, nforce, icalc)
00302
00303
00304 writedataMG(rank, nosh, pbeparm, thispmg)
00305
00306
00307 writematMG(rank, nosh, pbeparm, thispmg)
00308
00309
00310
00311 if nosh.nprint > 0:
00312 stdout.write("---------------------------------------------\n")
00313 stdout.write("PRINT STATEMENTS\n")
00314 for iprint in xrange(nosh.nprint):
00315 if NOsh_printWhat(nosh, iprint) == NPT_ENERGY:
00316 printEnergy(com, nosh, totEnergy, iprint)
00317 elif NOsh_printWhat(nosh, iprint) == NPT_FORCE:
00318 printForce(com, nosh, nforce, atomforce, iprint)
00319 elif NOsh_printWhat(nosh, iprint) == NPT_ELECENERGY:
00320 printElecEnergy(com, nosh, totEnergy, iprint)
00321 elif NOsh_printWhat(nosh, iprint) == NPT_ELECFORCE:
00322 printElecForce(com, nosh, nforce, atomForce, iprint)
00323 elif NOsh_printWhat(nosh, iprint) == NPT_APOLENERGY:
00324 printApolEnergy(nosh, iprint)
00325 elif NOsh_printWhat(nosh, iprint) == NPT_APOLFORCE:
00326 printApolForce(com, nosh, nforce, atomForce, iprint)
00327 else:
00328 stdout.write("Undefined PRINT keyword!\n")
00329 break
00330
00331 stdout.write("----------------------------------------\n")
00332 stdout.write("CLEANING UP AND SHUTTING DOWN...\n")
00333
00334
00335 killForce(mem, nosh, nforce, atomforce)
00336 killEnergy()
00337 killMG(nosh, pbe, pmgp, pmg)
00338 killChargeMaps(nosh, chargeMap)
00339 killKappaMaps(nosh, kappaMap)
00340 killDielMaps(nosh, dielXMap, dielYMap, dielZMap)
00341 killMolecules(nosh, alist)
00342
00343 delete_Nosh(nosh)
00344
00345
00346
00347 delete_double_array(realCenter)
00348 delete_int_array(nforce)
00349 delete_atomforcelist(atomforce)
00350 delete_valist(alist)
00351 delete_gridlist(dielXMap)
00352 delete_gridlist(dielYMap)
00353 delete_gridlist(dielZMap)
00354 delete_gridlist(kappaMap)
00355 delete_gridlist(chargeMap)
00356 delete_pmglist(pmg)
00357 delete_pmgplist(pmgp)
00358 delete_pbelist(pbe)
00359
00360
00361
00362 delete_Com(com)
00363 delete_Mem(mem)
00364 stdout.write("\n")
00365 stdout.write("Thanks for using APBS!\n\n")
00366
00367
00368 main_timer_stop = time.clock()
00369 stdout.write("Total execution time: %1.6e sec\n" % (main_timer_stop - main_timer_start))
00370
00371
00372 if __name__ == "__main__": main()