From: <bao...@us...> - 2006-05-18 10:30:49
|
Revision: 125 Author: baoilleach Date: 2006-05-18 03:30:34 -0700 (Thu, 18 May 2006) ViewCVS: http://svn.sourceforge.net/cclib/?rev=125&view=rev Log Message: ----------- Created a function to guess the filetype of a logfile and return an instance or None. Unfortunately, I ran into several non-trivial problems which required me (as far as I could figure out) to reorganise the import statements in cclib. At first I put guesstype() as a method of Logfile. Then I realised it was better as a function in logfileparser.py. Then I realised that due to some restrictions in circular import statements (or something) I needed to stop using 'from x import y' type imports and change to 'import x; use x.y' type statements. In the end the tests are back working and I've moved parser helper utilities into utils.py. What a drag though! I still don't know what exactly was the problem. Unfortunately, I've had to remove the magic from __init__.py so that 'from cclib.parser import ADF' no longer works. We should consider removing the suffix 'parser' from the filenames in the cclib.parser directory, as it does not add anything. Modified Paths: -------------- trunk/src/cclib/parser/__init__.py trunk/src/cclib/parser/adfparser.py trunk/src/cclib/parser/gamessparser.py trunk/src/cclib/parser/gaussianparser.py trunk/src/cclib/parser/jaguarparser.py trunk/src/cclib/parser/logfileparser.py trunk/test/testGeoOpt.py trunk/test/testSP.py trunk/test/testSPun.py trunk/test/testall.py Added Paths: ----------- trunk/src/cclib/parser/utils.py Modified: trunk/src/cclib/parser/__init__.py =================================================================== --- trunk/src/cclib/parser/__init__.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/src/cclib/parser/__init__.py 2006-05-18 10:30:34 UTC (rev 125) @@ -1,4 +0,0 @@ -from gaussianparser import Gaussian -from gamessparser import GAMESS -from adfparser import ADF -from jaguarparser import Jaguar Modified: trunk/src/cclib/parser/adfparser.py =================================================================== --- trunk/src/cclib/parser/adfparser.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/src/cclib/parser/adfparser.py 2006-05-18 10:30:34 UTC (rev 125) @@ -20,9 +20,10 @@ import re,time import Numeric import random # For sometimes running the progress updater -from logfileparser import Logfile,convertor +import utils +import logfileparser -class ADF(Logfile): +class ADF(logfileparser.Logfile): """An ADF log file""" SCFCNV,SCFCNV2 = range(2) #used to index self.scftargets[] maxelem,norm = range(2) # used to index scf.values @@ -220,7 +221,7 @@ blank = inputfile.next() line = inputfile.next() temp = inputfile.next().strip().split() - self.scfenergies.append(convertor(float(temp[-1]),"hartree","eV")) + self.scfenergies.append(utils.convertor(float(temp[-1]),"hartree","eV")) for i in range(6): line = inputfile.next() values = [] @@ -251,7 +252,7 @@ info=line.split() if len(info)==5: #this is restricted self.mosyms[0].append(self.normalisesym(info[0])) - self.moenergies[0].append(convertor(float(info[3]),'hartree','eV')) + self.moenergies[0].append(utils.convertor(float(info[3]),'hartree','eV')) if info[2]=='0.00' and not hasattr(self,'homos'): self.logger.info("Creating attribute homos[]") self.homos=[len(self.moenergies[0])-2] @@ -262,13 +263,13 @@ self.mosyms.append([]) if info[2]=='A': self.mosyms[0].append(self.normalisesym(info[0])) - self.moenergies[0].append(convertor(float(info[4]),'hartree','eV')) + self.moenergies[0].append(utils.convertor(float(info[4]),'hartree','eV')) if info[3]=='0.00' and homoa==None: homoa=len(self.moenergies[0])-2 if info[2]=='B': self.mosyms[1].append(self.normalisesym(info[0])) - self.moenergies[1].append(convertor(float(info[4]),'hartree','eV')) + self.moenergies[1].append(utils.convertor(float(info[4]),'hartree','eV')) if info[3]=='0.00' and homob==None: homob=len(self.moenergies[1])-2 Modified: trunk/src/cclib/parser/gamessparser.py =================================================================== --- trunk/src/cclib/parser/gamessparser.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/src/cclib/parser/gamessparser.py 2006-05-18 10:30:34 UTC (rev 125) @@ -20,9 +20,10 @@ import re,time import Numeric import random # For sometimes running the progress updater -from logfileparser import Logfile,convertor,PeriodicTable +import utils +import logfileparser -class GAMESS(Logfile): +class GAMESS(logfileparser.Logfile): """A GAMESS log file.""" SCFRMS,SCFMAX,SCFENERGY = range(3) # Used to index self.scftargets[] def __init__(self,*args): @@ -30,8 +31,6 @@ # Call the __init__ method of the superclass super(GAMESS, self).__init__(logname="GAMESS",*args) - self.pt = PeriodicTable() - def __str__(self): """Return a string representation of the object.""" return "GAMESS log file %s" % (self.filename) @@ -136,8 +135,8 @@ line = inputfile.next() while line.strip(): temp = line.strip().split() - atomcoords.append([convertor(float(x),"au","Ang") for x in temp[2:4]]) - atomnos.append(self.pt.number[temp[0]]) # Use the element name + atomcoords.append([utils.convertor(float(x),"au","Ang") for x in temp[2:4]]) + atomnos.append(self.table.number[temp[0]]) # Use the element name line = inputfile.next() self.atomnos = Numeric.array(atomnos,"i") self.atomcoords.append(atomcoords) @@ -287,7 +286,7 @@ blank = inputfile.next() line = inputfile.next() # Eigenvector no line = inputfile.next() - self.moenergies[0].extend([convertor(float(x),"hartree","eV") for x in line.split()]) + self.moenergies[0].extend([utils.convertor(float(x),"hartree","eV") for x in line.split()]) line = inputfile.next() self.mosyms[0].extend(map(self.normalisesym,line.split())) for i in range(self.nbasis): @@ -324,7 +323,7 @@ blank = inputfile.next() line = inputfile.next() # Eigenvector no line = inputfile.next() - self.moenergies[1].extend([convertor(float(x),"hartree","eV") for x in line.split()]) + self.moenergies[1].extend([utils.convertor(float(x),"hartree","eV") for x in line.split()]) line = inputfile.next() self.mosyms[1].extend(map(self.normalisesym,line.split())) for i in range(self.nbasis): Modified: trunk/src/cclib/parser/gaussianparser.py =================================================================== --- trunk/src/cclib/parser/gaussianparser.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/src/cclib/parser/gaussianparser.py 2006-05-18 10:30:34 UTC (rev 125) @@ -20,9 +20,10 @@ import re,time import Numeric import random # For sometimes running the progress updater -from logfileparser import Logfile,convertor +import utils +import logfileparser -class Gaussian(Logfile): +class Gaussian(logfileparser.Logfile): """A Gaussian 98/03 log file""" SCFRMS,SCFMAX,SCFENERGY = range(3) # Used to index self.scftargets[] def __init__(self,*args): @@ -287,7 +288,7 @@ i = 0 while i*10+4<len(part): x = part[i*10:(i+1)*10] - self.moenergies[0].append(convertor(self.float(x),"hartree","eV")) + self.moenergies[0].append(utils.convertor(self.float(x),"hartree","eV")) i += 1 line = inputfile.next() if line.find('Beta')==2: @@ -309,7 +310,7 @@ i = 0 while i*10+4<len(part): x = part[i*10:(i+1)*10] - self.moenergies[1].append(convertor(self.float(x),"hartree","eV")) + self.moenergies[1].append(utils.convertor(self.float(x),"hartree","eV")) i += 1 line = inputfile.next() self.moenergies = Numeric.array(self.moenergies,"f") @@ -370,7 +371,7 @@ # (unrestricted calc) (first excited state is 2!) # Excited State 2: ?Spin -A 0.1222 eV 10148.75 nm f=0.0000 parts = line[36:].split() - self.etenergies.append(convertor(self.float(parts[0]),"eV","cm-1")) + self.etenergies.append(utils.convertor(self.float(parts[0]),"eV","cm-1")) self.etoscs.append(self.float(parts[4].split("=")[1])) self.etsyms.append(line[21:36].split()) Modified: trunk/src/cclib/parser/jaguarparser.py =================================================================== --- trunk/src/cclib/parser/jaguarparser.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/src/cclib/parser/jaguarparser.py 2006-05-18 10:30:34 UTC (rev 125) @@ -20,9 +20,10 @@ import re,time import Numeric import random # For sometimes running the progress updater -from logfileparser import Logfile,convertor +import utils +import logfileparser -class Jaguar(Logfile): +class Jaguar(logfileparser.Logfile): """A Jaguar output file""" def __init__(self,*args): @@ -115,7 +116,7 @@ while line.strip(): temp = line.strip().split() for i in range(0,len(temp),2): - self.moenergies[0].append(convertor(float(temp[i]),"hartree","eV")) + self.moenergies[0].append(utils.convertor(float(temp[i]),"hartree","eV")) self.mosyms[0].append(temp[i+1]) line = inputfile.next() self.moenergies = Numeric.array(self.moenergies,"f") Modified: trunk/src/cclib/parser/logfileparser.py =================================================================== --- trunk/src/cclib/parser/logfileparser.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/src/cclib/parser/logfileparser.py 2006-05-18 10:30:34 UTC (rev 125) @@ -19,37 +19,8 @@ """ import logging, sys import Numeric +import utils -def convertor(value,fromunits,tounits): - """Convert from one set of units to another. - - >>> print "%.1f" % convertor(8,"eV","cm-1") - 64524.8 - """ - _convertor = {"eV_to_cm-1": lambda x: x*8065.6, - "hartree_to_eV": lambda x: x*27.2114, - "nm_to_cm-1": lambda x: 1e7/x, - "cm-1_to_nm": lambda x: 1e7/x, - "au_to_Ang": lambda x: x*0.529177} - - return _convertor["%s_to_%s" % (fromunits,tounits)] (value) - -class PeriodicTable(object): - """Allows conversion between element name and atomic no. - - >>> t = PeriodicTable() - >>> t.element[6] - 'C' - >>> t.number['C'] - 6 - """ - def __init__(self): - self.element = [None,"H","He","Li","Be","B","C","N","O","F","Ne","Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca","Sc","Ti","V","Cr","Mn","Fe" - "Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr","Rb","Sr","Y","Zr","Nb","Mo"] - self.number = {} - for i in range(1,len(self.element)): - self.number[self.element[i]] = i - class Logfile(object): """Abstract class for logfile objects. @@ -97,7 +68,7 @@ self.parsed = False self.loglevel = loglevel self.logname = logname - self.table = PeriodicTable() + self.table = utils.PeriodicTable() # Set up the logger self.logger = logging.getLogger('%s %s' % (self.logname,self.filename)) Added: trunk/src/cclib/parser/utils.py =================================================================== --- trunk/src/cclib/parser/utils.py (rev 0) +++ trunk/src/cclib/parser/utils.py 2006-05-18 10:30:34 UTC (rev 125) @@ -0,0 +1,81 @@ +""" +cclib is a parser for computational chemistry log files. + +See http://cclib.sf.net for more information. + +Copyright (C) 2006 Noel O'Boyle and Adam Tenderholt + + This program is free software; you can redistribute and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +Contributions (monetary as well as code :-) are encouraged. +""" +import adfparser +import gamessparser +import gaussianparser +import jaguarparser + +def guesstype(filename): + """Guess the identity of a particular log file and return an instance of that. + + Notes: uses the first 20 lines of a log file to guess its identity + + Returns: one of ADF, GAMESS, Gaussian, Jaguar, or None (if it cannot figure it out). + """ + filetype = None + inputfile = open(filename,"r") + for i,line in enumerate(inputfile): + if i>20: break # not elegant, but less buggy than a while loop testing for EOF + if line.find("Amsterdam Density Functional")>=0: + filetype = adfparser.ADF + elif line.find("GAMESS")>=0: + filetype = gamessparser.GAMESS + elif line.find("Gaussian")>=0: + filetype = gaussianparser.Gaussian + elif line.find("Jaguar")>=0: + filetype = jaguarparser.Jaguar + inputfile.close() # Need to close before creating an instance + if filetype: + filetype = apply(filetype,[filename]) # Create an instance of the chosen class + return filetype + +def convertor(value,fromunits,tounits): + """Convert from one set of units to another. + + >>> print "%.1f" % convertor(8,"eV","cm-1") + 64524.8 + """ + _convertor = {"eV_to_cm-1": lambda x: x*8065.6, + "hartree_to_eV": lambda x: x*27.2114, + "nm_to_cm-1": lambda x: 1e7/x, + "cm-1_to_nm": lambda x: 1e7/x, + "au_to_Ang": lambda x: x*0.529177} + + return _convertor["%s_to_%s" % (fromunits,tounits)] (value) + +class PeriodicTable(object): + """Allows conversion between element name and atomic no. + + >>> t = PeriodicTable() + >>> t.element[6] + 'C' + >>> t.number['C'] + 6 + """ + def __init__(self): + self.element = [None,"H","He","Li","Be","B","C","N","O","F","Ne","Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca","Sc","Ti","V","Cr","Mn","Fe" + "Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr","Rb","Sr","Y","Zr","Nb","Mo"] + self.number = {} + for i in range(1,len(self.element)): + self.number[self.element[i]] = i + +if __name__=="__main__": + import doctest,utils + doctest.testmod(utils,verbose=False) Property changes on: trunk/src/cclib/parser/utils.py ___________________________________________________________________ Name: svn:executable + * Modified: trunk/test/testGeoOpt.py =================================================================== --- trunk/test/testGeoOpt.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/test/testGeoOpt.py 2006-05-18 10:30:34 UTC (rev 125) @@ -1,8 +1,12 @@ import os, unittest -from cclib.parser import GAMESS,Gaussian,ADF,Jaguar from Numeric import array from testall import getfile +from cclib.parser.adfparser import ADF +from cclib.parser.gamessparser import GAMESS +from cclib.parser.gaussianparser import Gaussian +from cclib.parser.jaguarparser import Jaguar + class GenericGeoOptTest(unittest.TestCase): def testhomos(self): """Is the index of the homo equal to 34?""" Modified: trunk/test/testSP.py =================================================================== --- trunk/test/testSP.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/test/testSP.py 2006-05-18 10:30:34 UTC (rev 125) @@ -1,7 +1,10 @@ import os, unittest -from cclib.parser import GAMESS,Gaussian,ADF,Jaguar from Numeric import array from testall import getfile +from cclib.parser.adfparser import ADF +from cclib.parser.gamessparser import GAMESS +from cclib.parser.gaussianparser import Gaussian +from cclib.parser.jaguarparser import Jaguar class GenericSPTest(unittest.TestCase): """Restricted single point calculations with MO coeffs and overlap info.""" Modified: trunk/test/testSPun.py =================================================================== --- trunk/test/testSPun.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/test/testSPun.py 2006-05-18 10:30:34 UTC (rev 125) @@ -1,7 +1,10 @@ import os, unittest -from cclib.parser import GAMESS,Gaussian,ADF,Jaguar from Numeric import array from testall import getfile +from cclib.parser.adfparser import ADF +from cclib.parser.gamessparser import GAMESS +from cclib.parser.gaussianparser import Gaussian +from cclib.parser.jaguarparser import Jaguar class GenericSPunTest(unittest.TestCase): """Restricted single point calculations with MO coeffs and overlap info.""" Modified: trunk/test/testall.py =================================================================== --- trunk/test/testall.py 2006-05-18 08:38:50 UTC (rev 124) +++ trunk/test/testall.py 2006-05-18 10:30:34 UTC (rev 125) @@ -1,6 +1,9 @@ import unittest import os -from cclib.parser import Gaussian,GAMESS,ADF,Jaguar +from cclib.parser.adfparser import ADF +from cclib.parser.gamessparser import GAMESS +from cclib.parser.gaussianparser import Gaussian +from cclib.parser.jaguarparser import Jaguar def getfile(parser,*location): """Returns a parsed logfile.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |