• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

tools/python/main.py

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     # Initialize the MALOC library
00171     startVio()
00172 
00173     # Initialize variables, arrays
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     # Start the main timer
00189     main_timer_start = time.clock()
00190 
00191     # Check invocation
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     # Parse the input file
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     # Load the molecules using loadMolecules routine
00207     # loadMolecule passing NULL as second arg instead of Vparam
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     # Setup the calculations
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     # Load the necessary maps
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     # Do the calculations
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         # Routine initMG
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         # Print problem parameters if desired (comment out if you want
00273         # to minimize output to stdout)
00274            
00275         printMGPARM(mgparm, realCenter)
00276         printPBEPARM(pbeparm)
00277       
00278         # Solve the problem : Routine solveMG
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         # Set partition information : Routine setPartMG
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         # Get the energies - the energy for this calculation
00293         # (calculation number icalc) will be stored in the totEnergy array
00294 
00295         ret, totEnergy[icalc] = energyMG(nosh, icalc, thispmg, 0, \
00296                                          totEnergy[icalc], 0.0, 0.0, 0.0)
00297         
00298         # Calculate forces
00299         
00300         aforce = get_AtomForce(atomforce, icalc)
00301         wrap_forceMG(mem, nosh, pbeparm, mgparm, thispmg, aforce, alist, nforce, icalc)
00302           
00303         # Write out data from MG calculations : Routine writedataMG          
00304         writedataMG(rank, nosh, pbeparm, thispmg)
00305            
00306         # Write out matrix from MG calculations        
00307         writematMG(rank, nosh, pbeparm, thispmg)
00308     
00309     # Handle print statements - comment out if limiting output to stdout
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     # Clean up APBS structures
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     # Clean up Python structures
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     # Clean up MALOC structures
00362     delete_Com(com)
00363     delete_Mem(mem)
00364     stdout.write("\n")
00365     stdout.write("Thanks for using APBS!\n\n")
00366 
00367     # Stop the main timer
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()

Generated on Wed Oct 20 2010 11:12:21 for APBS by  doxygen 1.7.2