Parse the logfile, using the assumed extract method of the child.
: """Parse the logfile, using the assumed extract method of the child.""" # Check that the sub-class has an extract attribute, # that is callable with the proper number of arguemnts. if not hasattr(self, "extract"): raise AttributeError, "Class %s has no extract() method." %self.__class__.__name__ return -1 if not callable(self.extract): raise AttributeError, "Method %s._extract not callable." %self.__class__.__name__ return -1 if len(inspect.getargspec(self.extract)) != 3: raise AttributeError, "Method %s._extract takes wrong number of arguments." %self.__class__.__name__ return -1 # Save the current list of attributes to keep after parsing. # The dict of self should be the same after parsing. _nodelete = list(set(self.__dict__.keys())) # Initiate the FileInput object for the input files. # Remember that self.filename can be a list of files. if not self.isstream: inputfile = openlogfile(self.filename) else: inputfile = self.stream # Intialize self.progress. if self.progress: inputfile.seek(0,2) nstep = inputfile.tell() inputfile.seek(0) self.progress.initialize(nstep) self.progress.step = 0 if fupdate: self.fupdate = fupdate if cupdate: self.cupdate = cupdate # Initialize the ccData object that will be returned. # This is normally ccData, but can be changed by passing # the datatype argument to __init__(). data = self.datatype() # Copy the attribute list, so that the parser knows what to expect, # specifically in __setattr__(). # The class self.datatype (normally ccData) must have this attribute. self._attrlist = data._attrlist # Maybe the sub-class has something to do before parsing. if hasattr(self, "before_parsing"): self.before_parsing() # Loop over lines in the file object and call extract(). # This is where the actual parsing is done. for line in inputfile: self.updateprogress(inputfile, "Unsupported information", cupdate) # This call should check if the line begins a section of extracted data. # If it does, it parses some lines and sets the relevant attributes (to self). # Any attributes can be freely set and used across calls, however only those # in data._attrlist will be moved to final data object that is returned. self.extract(inputfile, line) # Close input file object. if not self.isstream: inputfile.close() # Maybe the sub-class has something to do after parsing. if hasattr(self, "after_parsing"): self.after_parsing() # If atomcoords were not parsed, but some input coordinates were ("inputcoords"). # This is originally from the Gaussian parser, a regression fix. if not hasattr(self, "atomcoords") and hasattr(self, "inputcoords"): self.atomcoords = numpy.array(self.inputcoords, 'd') # Set nmo if not set already - to nbasis. if not hasattr(self, "nmo") and hasattr(self, "nbasis"): self.nmo = self.nbasis # Creating deafult coreelectrons array. if not hasattr(self, "coreelectrons") and hasattr(self, "natom"): self.coreelectrons = numpy.zeros(self.natom, "i") # Move all cclib attributes to the ccData object. # To be moved, an attribute must be in data._attrlist. for attr in data._attrlist: if hasattr(self, attr): setattr(data, attr, getattr(self, attr)) # Now make sure that the cclib attributes in the data object # are all the correct type (including arrays and lists of arrays). data.arrayify() # Delete all temporary attributes (including cclib attributes). # All attributes should have been moved to a data object, # which will be returned. for attr in self.__dict__.keys(): if not attr in _nodelete: self.__delattr__(attr) # Update self.progress as done. if self.progress: self.progress.update(nstep, "Done") # Return the ccData object that was generated. return data