def __init__(self, assy, list): Jig.__init__(self, assy, list) self.cancelled = False # set default color of new gamess jig to magenta self.color = magenta # This is the "draw" color. When selected, this will become highlighted red. self.normcolor = magenta # This is the normal (unselected) color. #bruce 050913 thinks self.history is no longer needed: ## self.history = env.history #self.psets = [] # list of parms set objects [as of circa 050704, only the first of these is ever defined (thinks bruce)] self.pset = gamessParms('Parameter Set 1') self.gmsjob = GamessJob(Gamess.job_parms, jig=self) ## bruce 050701 removing this: self.gmsjob.edit() self.outputfile = '' # Name of jig's most recent output file. [this attr is intentionally not copied -- bruce 050704]
def __createJobs(self, jobInfoList): """ Create SimJob objects, return the list of job objects """ jobs = [] for j in jobInfoList: if j[0]['Engine'] in ['GAMESS', 'PC GAMESS']: #Create GamessJob, call GamessJob.readProp() jobs += [GamessJob(j[0], job_from_file =j[1:])] elif j[0]['Engine'] == 'nanoSIM-1': #Create nanoEngineer-1 MD simulator job pass return jobs
class Gamess(Jig): """ A Gamess jig has a list of atoms with one or more parameter sets used to run a GAMESS calcuation. """ sym = "GAMESS" icon_names = ["modeltree/gamess.png", "modeltree/gamess-hide.png"] featurename = "GAMESS Jig" #bruce 051203 #bruce 050704 added these attrs and related methods, to make copying of this jig work properly mutable_attrs = ('pset', ) copyable_attrs = Jig.copyable_attrs + () + mutable_attrs # Default job parameters for a GAMESS job. job_parms = { 'Engine': 'GAMESS', 'Calculation': '', 'Description': "No comments? How about today's weather?", 'Status': '', 'Server_id': '', 'Job_id': '', 'Time': '0.0' } # create a blank Gamess jig with the given list of atoms def __init__(self, assy, list): Jig.__init__(self, assy, list) self.cancelled = False # set default color of new gamess jig to magenta self.color = magenta # This is the "draw" color. When selected, this will become highlighted red. self.normcolor = magenta # This is the normal (unselected) color. #bruce 050913 thinks self.history is no longer needed: ## self.history = env.history #self.psets = [] # list of parms set objects [as of circa 050704, only the first of these is ever defined (thinks bruce)] self.pset = gamessParms('Parameter Set 1') self.gmsjob = GamessJob(Gamess.job_parms, jig=self) ## bruce 050701 removing this: self.gmsjob.edit() self.outputfile = '' # Name of jig's most recent output file. [this attr is intentionally not copied -- bruce 050704] def edit(self): self.gmsjob.edit() # it's drawn as a wire cube around each atom. def _draw(self, glpane, dispdef): for a in self.atoms: # Using dispdef of the atom's chunk instead of the glpane's dispdef fixes bug 373. mark 060122. chunk = a.molecule dispdef = chunk.get_dispdef(glpane) disp, rad = a.howdraw(dispdef) # wware 060203 selected bounding box bigger, bug 756 if self.picked: rad *= 1.01 drawwirecube(self.color, a.posn(), rad) # Write "gamess" record to POV-Ray file in the format: # gamess(<box-center>,box-radius,<r, g, b>) def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return if self.picked: c = self.normcolor else: c = self.color for a in self.atoms: disp, rad = a.howdraw(dispdef) grec = "gamess(" + povpoint( a.posn()) + "," + str(rad) + ",<" + str(c[0]) + "," + str( c[1]) + "," + str(c[2]) + ">)\n" file.write(grec) def _getinfo(self): return "[Object: Gamess Jig] [Name: " + str( self.name) + "] [Total Atoms: " + str(len( self.atoms)) + "] [Parameters: " + self.gms_parms_info() + "]" def _getToolTipInfo(self): #ninad060825 """ Return a string for display in Dynamic Tool tip """ attachedAtomCount = "<font color=\"#0000FF\">Total Atoms: </font>%d" % ( len(self.atoms)) return str(self.name) + "<br>" + "<font color=\"#0000FF\"> Jig Type:</font>Gamess Jig"\ + "<br>" + "<font color=\"#0000FF\"> Parameters:</font>" + self.gms_parms_info()\ + "<br>" + str(attachedAtomCount) def getstatistics(self, stats): stats.ngamess += 1 def gms_parms_info(self, delimeter='/'): """ Return a GAMESS parms shorthand string. """ # This is something Damian and I discussed to quickly display the parms set for # a Gamess jig. It is used in the header of the GAMESS INP file and in the naming of # the new chunk made from a GAMESS optimization. It is also used to display the # parameter info (along with the energy) when doing an energy calculation. # Mark 050625. d = delimeter pset = self.pset # SCFTYP (RHF, UHF, or ROHF) s1 = scftyp[pset.ui.scftyp] # Hartree-Fock (display nothing), DFT (display functional) or MP2 if ecm[pset.ui.ecm] == 'DFT': if sys.platform == 'win32': # Windows - PC GAMESS item = pcgms_dfttyp_items[pset.ui.dfttyp] else: # Linux or MacOS - GAMESS item = gms_dfttyp_items[pset.ui.dfttyp] s2, junk = item.split(' ', 1) s2 = d + s2 elif ecm[pset.ui.ecm] == 'MP2': s2 = d + 'MP2' else: s2 = '' # Basis Set s3 = d + pset.ui.gbasisname # Charge s4 = d + 'Ch' + str(pset.ui.icharg) # Multiplicity s5 = d + 'M' + str(pset.ui.mult + 1) return s1 + s2 + s3 + s4 + s5 def __CM_Calculate_Energy(self): """ Gamess Jig context menu "Calculate Energy" """ self.calculate_energy() def calculate_energy(self): """ Calculate energy. """ cmd = greenmsg("Calculate Energy: ") errmsgs = ["GAMESS job aborted.", "Error: GAMESS job failed."] pset = self.pset runtyp = pset.ui.runtyp # Save runtyp (Calculate) setting to restore it later. pset.ui.runtyp = 0 # Energy calculation origCalType = self.gmsjob.Calculation self.gmsjob.Calculation = 'Energy' self.update_gamess_parms() # Run GAMESS job. Return value r: # 0 = success # 1 = job aborted # 2 = job failed. r = self.gmsjob.launch() pset.ui.runtyp = runtyp # Restore to original value self.gmsjob.Calculation = origCalType if r: # Job was aborted or an error occurred. msg = redmsg(errmsgs[r - 1]) env.history.message(cmd + msg) return self.print_energy() def __CM_Optimize_Geometry(self): """ Gamess Jig context menu "Optimize Geometry" """ self.optimize_geometry() def optimize_geometry(self): """ Optimize geometry """ cmd = greenmsg("Optimize Geometry: ") errmsgs = ["GAMESS job aborted.", "Error: GAMESS job failed."] pset = self.pset runtyp = pset.ui.runtyp # Save runtyp (Calculate) setting to restore it later. pset.ui.runtyp = 1 # Optimize origCalType = self.gmsjob.Calculation self.gmsjob.Calculation = 'Optimize' self.update_gamess_parms() # Run GAMESS job. Return value r: # 0 = success # 1 = job aborted. # 2 = job failed. r = self.gmsjob.launch() pset.ui.runtyp = runtyp # Restore to original value self.gmsjob.Calculation = origCalType if r: # Job was aborted or an error occurred. msg = redmsg(errmsgs[r - 1]) env.history.message(cmd + msg) return try: r2 = self.move_optimized_atoms() except: print_compact_traceback( "GamessProp.run_job(): error reading GAMESS OUT file [%s]: " % \ self.outputfile ) env.history.message( redmsg(cmd + "Internal error while inserting GAMESS geometry: " + self.outputfile)) else: if r2: env.history.message(cmd + redmsg("Atoms not adjusted.")) else: self.assy.changed() # The file and the part are not the same. self.print_energy( ) # Print the final energy from the optimize OUT file, too. env.history.message(cmd + "Atoms adjusted.") def __CM_Optimize_Geometry__options(self): if Jig.is_disabled(self): return ['disabled'] else: return [] def __CM_Calculate_Energy__options(self): if Jig.is_disabled(self): return ['disabled'] else: return [] pass def print_energy(self): r, final_energy_str = get_energy_from_gms_outfile(self.outputfile) if r == 1: # GAMESS terminated abnormally. if final_energy_str: env.history.message( redmsg( final_energy_str + " Check if you have set the right Gamess executable file. Usually it's called gamess.??.x or ??gamess.exe." )) return msg = "Final energy value not found. The output file is located at: " + self.outputfile env.history.message(redmsg(msg)) elif r == 2: # The output file not exist msg = "The output file %s doesn't exist. The reason is either that Gamess didn't run or the output file has been deleted. " % self.outputfile env.history.message(redmsg(msg)) else: # Final energy was found. gmstr = self.gms_parms_info() msg = "GAMESS finished. The output file is located at: " + self.outputfile env.history.message(msg) msg = "Parameters: " + gmstr + ". The final energy is: " + final_energy_str + " Hartree." env.history.message(msg) mmp_record_name = "gamess" #bruce 050701 def move_optimized_atoms(self): newPositions = get_atompos_from_gms_outfile(self.assy, self.outputfile, self.atoms) # retval is either a list of atom posns or an error message string. assert type(newPositions) in [type([]), type("")] if type(newPositions) == type([]): self.move_atoms(newPositions) self.assy.changed() self.assy.o.gl_update() #self.assy.w.win_update() return 0 else: env.history.message(redmsg(newPositions)) return 1 def move_atoms(self, newPositions): # used when reading xyz files """ [Borrowed from movie.moveAtoms.] Move a list of atoms to newPosition. After all atoms moving, bond updated, update display once. <parameter>newPosition is a list of atom absolute position, the list order is the same as self.alist """ atomList = self.atoms if len(newPositions) != len(atomList): #bruce 050225 added some parameters to this error message #bruce 050406 comment: but it probably never comes out, since readxyz checks this, # so I won't bother to print it to history here. But leaving it in is good for safety. print "move_atoms: The number of atoms from GAMESS file (%d) is not matching with that of the current model (%d)" % \ (len(newPositions), len(atomList)) return move_alist_and_snuggle(atomList, newPositions) #bruce 051221 fix a bug analogous to bug 1239 by letting this new function (containing a loop) # replace a copy (which was right here) of the older buggy version of that loop self.assy.o.gl_update() return def writemmp(self, mapping): #bruce 050701 "[extends Jig method]" super = Jig super.writemmp( self, mapping ) # this writes the main gamess record, and some general info leaf records valid for all nodes pset = self.pset pset.writemmp(mapping, 0) # This writes the pset's info, as a series of "info gamess" records which modify the last gamess jig; # in case we ever want to extend this to permit more than one pset per jig in the mmp file, # each of those records has a "pset index" which we pass here as 0 (and which is written using "%s"). # So if we wanted to write more psets we could say self.psets[i].writemmp(mapping, i) for each one. return def readmmp_info_gamess_setitem(self, key, val, interp): #bruce 050701 """ This is called when reading an mmp file, for each "info gamess" record which occurs right after this node is read and no other (gamess jig) node has been read. Key is a list of words, val a string; the entire record format is presently [050701] "info gamess <key> = <val>", and there are exactly two words in <key>, the "parameter set index" (presently always 0) and the "param name". Interp is an object to help us translate references in <val> into other objects read from the same mmp file or referred to by it. See the calls of this or similar methods from files_mmp for the doc of interp methods. If key is recognized, this method should set the attribute or property it refers to to val; otherwise it must do nothing. (An unrecognized key, even if longer than any recognized key, is not an error. Someday it would be ok to warn about an mmp file containing unrecognized info records or keys, but not too verbosely (at most once per file per type of info).) """ if len(key) != 2 or not key[0].isdigit(): if debug_flags.atom_debug: print "atom_debug: fyi: info gamess with unrecognized key %r (not an error)" % ( key, ) return pset_index, name = key pset_index = int(pset_index) # pset_index is presently always 0, but this code should work provided self.psets has an element with this index; try: pset = self.pset except: # not an error -- future mmp formats might use non-existent indices and expect readers to create new psets. if debug_flags.atom_debug: print "atom_debug: fyi: info gamess with non-existent pset index in key %r (not an error)" % ( key, ) return # the rest of the work should be done by the pset. try: self.pset.info_gamess_setitem(name, val, interp) except: print_compact_traceback( "bug: exception (ignored) in pset.info_gamess_setitem( %r, %r, interp ): " % (name, val)) return pass def own_mutable_copyable_attrs(self): #bruce 050704 """ [overrides Node method] """ super = Jig super.own_mutable_copyable_attrs(self) for attr in self.mutable_attrs: if attr == 'pset': # special-case code for this attr, a list of gamessParms objects # (those objects, and the list itself, are mutable and need to be de-shared) val = getattr(self, attr) #assert type(val) == type([]) newval = val.deepcopy() #for item in val] setattr(self, attr, newval) else: print "bug: don't know how to copy attr %r in %r", attr, self pass return def cm_duplicate(self): #bruce 050704. """ Make a sibling node in the MT which has the same atoms, and a copy of the params, of this jig. """ #e Warning: The API (used by modelTree to decide whether to offer this command) is wrong, # and the implem should be generalized (to work on any Node or Group). Specifically, # this should become a Node method which always works (whether or not it's advisable to use it); # then the MT cmenu should dim it if some other method (which might depend on more than just the class) # says it's not advisable to use it. # I think it's advisable only on a Gamess jig, and on a chunk, # and maybe on a Group -- but what to do about contained jigs in a Group for which # some but not all atoms are being duplicated, or even other jigs in the Group, is a # design question, and it might turn out to be too ambiguous to safely offer it at all # for a Group with jigs in it. # Some code taken from Jig.copy_full_in_mapping and Jig._copy_fixup_at_end. copy = self.__class__(self.assy, self.atoms[:]) orig = self orig.copy_copyable_attrs_to(copy) # replaces .name set by __init__ copy.name = copy.name + "-copy" #e could improve copy.own_mutable_copyable_attrs( ) # eliminate unwanted sharing of mutable copyable_attrs if orig.picked: self.color = self.normcolor orig.addsibling(copy) if copy.part is None: #bruce 050707 see if this is enough to fix bug 755 self.assy.update_parts() env.history.message("Made duplicate Gamess jig on same atoms: [%s]" % copy.name) # note: the wire cubes from multiple jigs on the sme atoms get overdrawn, # which will mess up the selection coloring of those wirecubes # since the order of drawing them is unrelated to which one is selected # (and since the OpenGL behavior seems a bit unpredictable anyway). ##e Should fix this to only draw one wirecube, of the "maximal color", I guess... self.assy.w.win_update() # MT and glpane both might need update return #def set_disabled_by_user_choice(self, val): # """Called when users disable/enable the jig""" # self.gmsjob.edit_cntl.run_job_btn.setEnabled(not val) # Jig.set_disabled_by_user_choice(self, val) def is_disabled(self): """ Which is called when model tree is updated? """ val = Jig.is_disabled(self) self.gmsjob.edit_cntl.run_job_btn.setEnabled(not val) return val def update_gamess_parms(self): """ Update the GAMESS parameter set values using the settings in the UI object. """ # $CONTRL group ########################################### # Parms Values self.pset.contrl.runtyp = runtyp[self.pset.ui.runtyp] # RUNTYP self.pset.contrl.scftyp = scftyp[self.pset.ui.scftyp] # SCFTYP self.pset.contrl.icharg = str(self.pset.ui.icharg) # ICHARG self.pset.contrl.mult = str(self.pset.ui.mult + 1) # MULT self.pset.contrl.mplevl = mplevl[self.pset.ui.ecm] # MPLEVL self.pset.contrl.inttyp = inttyp[self.pset.ui.ecm] # INTTYP self.pset.contrl.maxit = self.pset.ui.iterations # Iterations # ICUT and QMTTOL #s = str(self.gbasis_combox.currentText()) m = self.pset.ui.gbasisname.count( '+' ) # If there is a plus sign in the basis set name, we have "diffuse orbitals" if m: # We have diffuse orbitals self.pset.contrl.icut = 11 if self.gmsjob.server.engine != 'PC GAMESS': # PC GAMESS does not support QMTTOL. Mark 052105 self.pset.contrl.qmttol = '3.0E-6' else: self.pset.contrl.qmttol = None else: # No diffuse orbitals self.pset.contrl.icut = 9 if self.gmsjob.server.engine == 'GAMESS': self.pset.contrl.qmttol = '1.0E-6' else: self.pset.contrl.qmttol = None # PC GAMESS does not support QMTTOL. Mark 052105 # DFTTYP (PC GAMESS only) # For PC GAMESS, the DFTTYP keyword is included in the CONTRL section, not the $DFT group. if self.gmsjob.server.engine == 'PC GAMESS': if ecm[self.pset.ui.ecm] == 'DFT': item = pcgms_dfttyp_items[ self.pset.ui. dfttyp] # Item's full text, including the '(xxx)' self.pset.contrl.dfttyp, junk = item.split( ' ', 1) # DFTTYPE, removing the '(xxx)'. self.pset.dft.nrad = pcgms_gridsize[ self.pset.ui.gridsize] # Grid Size parameters else: # None or MP2 self.pset.contrl.dfttyp = 0 self.pset.dft.nrad = 0 # $SCF group ########################################### self.pset.scf.extrap = tf[self.pset.ui.extrap] # EXTRAP self.pset.scf.dirscf = tf[self.pset.ui.dirscf] # DIRSCF self.pset.scf.damp = tf[self.pset.ui.damp] # DAMP self.pset.scf.diis = tf[self.pset.ui.diis] # DIIS self.pset.scf.shift = tf[self.pset.ui.shift] # SHIFT self.pset.scf.soscf = tf[self.pset.ui.soscf] # SOSCF self.pset.scf.rstrct = tf[self.pset.ui.rstrct] # RSTRCT # CONV (GAMESS) or # NCONV (PC GAMESS) if self.gmsjob.server.engine == 'GAMESS': self.pset.scf.conv = conv[self.pset.ui.conv] # CONV (GAMESS) self.pset.scf.nconv = 0 # Turn off NCONV else: # PC GAMESS self.pset.scf.nconv = conv[self.pset.ui.conv] # NCONV (PC GAMESS) self.pset.scf.conv = 0 # Turn off CONV # $SYSTEM group ########################################### self.pset.system.timlin = 1000 # Time limit in minutes self.pset.system.memory = self.pset.ui.memory * 1000000 # $MP2 group ########################################### self.pset.mp2.ncore = ncore[self.pset.ui.ncore] # $DFT group ########################################### # The DFT section record is supported in GAMESS only. if self.gmsjob.server.engine == 'GAMESS': if ecm[self.pset.ui.ecm] == 'DFT': item = gms_dfttyp_items[self.pset.ui.dfttyp] self.pset.dft.dfttyp, junk = item.split(' ', 1) # DFTTYP in $CONTRL self.pset.dft.nrad = gms_gridsize[ self.pset.ui.gridsize] # Grid Size parameters else: # None or MP2 self.pset.dft.dfttyp = 'NONE' self.pset.dft.nrad = 0 # $GUESS group ########################################### # $STATPT group ########################################### if runtyp[self.pset.ui.runtyp] == 'optimize': self.pset.statpt.opttol = float(opttol[self.pset.ui.rmsdconv]) else: self.pset.statpt.opttol = None # $BASIS group ########################################### if ecm[self.pset.ui.ecm] == 'None': self.pset.basis.gbasis = gbasis[self.pset.ui.gbasis] # GBASIS else: self.pset.basis.gbasis = gbasis[self.pset.ui.gbasis + 2] # GBASIS return pass # end of class Gamess
class Gamess(Jig): """ A Gamess jig has a list of atoms with one or more parameter sets used to run a GAMESS calcuation. """ sym = "GAMESS" icon_names = ["modeltree/gamess.png", "modeltree/gamess-hide.png"] featurename = "GAMESS Jig" #bruce 051203 #bruce 050704 added these attrs and related methods, to make copying of this jig work properly mutable_attrs = ('pset',) copyable_attrs = Jig.copyable_attrs + () + mutable_attrs # Default job parameters for a GAMESS job. job_parms = { 'Engine':'GAMESS', 'Calculation':'', 'Description':"No comments? How about today's weather?", 'Status':'', 'Server_id':'', 'Job_id':'', 'Time':'0.0'} # create a blank Gamess jig with the given list of atoms def __init__(self, assy, list): Jig.__init__(self, assy, list) self.cancelled = False # set default color of new gamess jig to magenta self.color = magenta # This is the "draw" color. When selected, this will become highlighted red. self.normcolor = magenta # This is the normal (unselected) color. #bruce 050913 thinks self.history is no longer needed: ## self.history = env.history #self.psets = [] # list of parms set objects [as of circa 050704, only the first of these is ever defined (thinks bruce)] self.pset = gamessParms('Parameter Set 1') self.gmsjob = GamessJob(Gamess.job_parms, jig=self) ## bruce 050701 removing this: self.gmsjob.edit() self.outputfile = '' # Name of jig's most recent output file. [this attr is intentionally not copied -- bruce 050704] def edit(self): self.gmsjob.edit() # it's drawn as a wire cube around each atom. def _draw(self, glpane, dispdef): for a in self.atoms: # Using dispdef of the atom's chunk instead of the glpane's dispdef fixes bug 373. mark 060122. chunk = a.molecule dispdef = chunk.get_dispdef(glpane) disp, rad = a.howdraw(dispdef) # wware 060203 selected bounding box bigger, bug 756 if self.picked: rad *= 1.01 drawwirecube(self.color, a.posn(), rad) # Write "gamess" record to POV-Ray file in the format: # gamess(<box-center>,box-radius,<r, g, b>) def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return if self.picked: c = self.normcolor else: c = self.color for a in self.atoms: disp, rad = a.howdraw(dispdef) grec = "gamess(" + povpoint(a.posn()) + "," + str(rad) + ",<" + str(c[0]) + "," + str(c[1]) + "," + str(c[2]) + ">)\n" file.write(grec) def _getinfo(self): return "[Object: Gamess Jig] [Name: " + str(self.name) + "] [Total Atoms: " + str(len(self.atoms)) + "] [Parameters: " + self.gms_parms_info() + "]" def _getToolTipInfo(self): #ninad060825 """ Return a string for display in Dynamic Tool tip """ attachedAtomCount = "<font color=\"#0000FF\">Total Atoms: </font>%d"%(len(self.atoms)) return str(self.name) + "<br>" + "<font color=\"#0000FF\"> Jig Type:</font>Gamess Jig"\ + "<br>" + "<font color=\"#0000FF\"> Parameters:</font>" + self.gms_parms_info()\ + "<br>" + str(attachedAtomCount) def getstatistics(self, stats): stats.ngamess += 1 def gms_parms_info(self, delimeter='/'): """ Return a GAMESS parms shorthand string. """ # This is something Damian and I discussed to quickly display the parms set for # a Gamess jig. It is used in the header of the GAMESS INP file and in the naming of # the new chunk made from a GAMESS optimization. It is also used to display the # parameter info (along with the energy) when doing an energy calculation. # Mark 050625. d = delimeter pset = self.pset # SCFTYP (RHF, UHF, or ROHF) s1 = scftyp[pset.ui.scftyp] # Hartree-Fock (display nothing), DFT (display functional) or MP2 if ecm[pset.ui.ecm] == 'DFT': if sys.platform == 'win32': # Windows - PC GAMESS item = pcgms_dfttyp_items[pset.ui.dfttyp] else: # Linux or MacOS - GAMESS item = gms_dfttyp_items[pset.ui.dfttyp] s2, junk = item.split(' ',1) s2 = d + s2 elif ecm[pset.ui.ecm] == 'MP2': s2 = d + 'MP2' else: s2 = '' # Basis Set s3 = d + pset.ui.gbasisname # Charge s4 = d + 'Ch' + str(pset.ui.icharg) # Multiplicity s5 = d + 'M' + str(pset.ui.mult + 1) return s1 + s2 + s3 + s4 + s5 def __CM_Calculate_Energy(self): """ Gamess Jig context menu "Calculate Energy" """ self.calculate_energy() def calculate_energy(self): """ Calculate energy. """ cmd = greenmsg("Calculate Energy: ") errmsgs = ["GAMESS job aborted.", "Error: GAMESS job failed."] pset = self.pset runtyp = pset.ui.runtyp # Save runtyp (Calculate) setting to restore it later. pset.ui.runtyp = 0 # Energy calculation origCalType = self.gmsjob.Calculation self.gmsjob.Calculation = 'Energy' self.update_gamess_parms() # Run GAMESS job. Return value r: # 0 = success # 1 = job aborted # 2 = job failed. r = self.gmsjob.launch() pset.ui.runtyp = runtyp # Restore to original value self.gmsjob.Calculation = origCalType if r: # Job was aborted or an error occurred. msg = redmsg(errmsgs[r-1]) env.history.message( cmd + msg ) return self.print_energy() def __CM_Optimize_Geometry(self): """ Gamess Jig context menu "Optimize Geometry" """ self.optimize_geometry() def optimize_geometry(self): """ Optimize geometry """ cmd = greenmsg("Optimize Geometry: ") errmsgs = ["GAMESS job aborted.", "Error: GAMESS job failed."] pset = self.pset runtyp = pset.ui.runtyp # Save runtyp (Calculate) setting to restore it later. pset.ui.runtyp = 1 # Optimize origCalType = self.gmsjob.Calculation self.gmsjob.Calculation = 'Optimize' self.update_gamess_parms() # Run GAMESS job. Return value r: # 0 = success # 1 = job aborted. # 2 = job failed. r = self.gmsjob.launch() pset.ui.runtyp = runtyp # Restore to original value self.gmsjob.Calculation = origCalType if r: # Job was aborted or an error occurred. msg = redmsg(errmsgs[r-1]) env.history.message( cmd + msg ) return try: r2 = self.move_optimized_atoms() except: print_compact_traceback( "GamessProp.run_job(): error reading GAMESS OUT file [%s]: " % \ self.outputfile ) env.history.message( redmsg( cmd + "Internal error while inserting GAMESS geometry: " + self.outputfile) ) else: if r2: env.history.message(cmd + redmsg( "Atoms not adjusted.")) else: self.assy.changed() # The file and the part are not the same. self.print_energy() # Print the final energy from the optimize OUT file, too. env.history.message( cmd + "Atoms adjusted.") def __CM_Optimize_Geometry__options(self): if Jig.is_disabled(self): return ['disabled'] else: return [] def __CM_Calculate_Energy__options(self): if Jig.is_disabled(self): return ['disabled'] else: return [] pass def print_energy(self): r, final_energy_str = get_energy_from_gms_outfile(self.outputfile) if r == 1: # GAMESS terminated abnormally. if final_energy_str: env.history.message(redmsg(final_energy_str + " Check if you have set the right Gamess executable file. Usually it's called gamess.??.x or ??gamess.exe.")) return msg = "Final energy value not found. The output file is located at: " + self.outputfile env.history.message(redmsg(msg)) elif r == 2: # The output file not exist msg = "The output file %s doesn't exist. The reason is either that Gamess didn't run or the output file has been deleted. " % self.outputfile env.history.message(redmsg(msg)) else: # Final energy was found. gmstr = self.gms_parms_info() msg = "GAMESS finished. The output file is located at: " + self.outputfile env.history.message(msg) msg = "Parameters: " + gmstr + ". The final energy is: " + final_energy_str + " Hartree." env.history.message(msg) mmp_record_name = "gamess" #bruce 050701 def move_optimized_atoms(self): newPositions = get_atompos_from_gms_outfile( self.assy, self.outputfile, self.atoms ) # retval is either a list of atom posns or an error message string. assert type(newPositions) in [type([]),type("")] if type(newPositions) == type([]): self.move_atoms(newPositions) self.assy.changed() self.assy.o.gl_update() #self.assy.w.win_update() return 0 else: env.history.message(redmsg( newPositions)) return 1 def move_atoms(self, newPositions): # used when reading xyz files """ [Borrowed from movie.moveAtoms.] Move a list of atoms to newPosition. After all atoms moving, bond updated, update display once. <parameter>newPosition is a list of atom absolute position, the list order is the same as self.alist """ atomList = self.atoms if len(newPositions) != len(atomList): #bruce 050225 added some parameters to this error message #bruce 050406 comment: but it probably never comes out, since readxyz checks this, # so I won't bother to print it to history here. But leaving it in is good for safety. print "move_atoms: The number of atoms from GAMESS file (%d) is not matching with that of the current model (%d)" % \ (len(newPositions), len(atomList)) return move_atoms_and_normalize_bondpoints(atomList, newPositions) #bruce 051221 fix a bug analogous to bug 1239 by letting this new function (containing a loop) # replace a copy (which was right here) of the older buggy version of that loop self.assy.o.gl_update() return def writemmp(self, mapping): #bruce 050701 "[extends Jig method]" super = Jig super.writemmp(self, mapping) # this writes the main gamess record, and some general info leaf records valid for all nodes pset = self.pset pset.writemmp(mapping, 0) # This writes the pset's info, as a series of "info gamess" records which modify the last gamess jig; # in case we ever want to extend this to permit more than one pset per jig in the mmp file, # each of those records has a "pset index" which we pass here as 0 (and which is written using "%s"). # So if we wanted to write more psets we could say self.psets[i].writemmp(mapping, i) for each one. return def readmmp_info_gamess_setitem( self, key, val, interp ): #bruce 050701 """ This is called when reading an mmp file, for each "info gamess" record which occurs right after this node is read and no other (gamess jig) node has been read. Key is a list of words, val a string; the entire record format is presently [050701] "info gamess <key> = <val>", and there are exactly two words in <key>, the "parameter set index" (presently always 0) and the "param name". Interp is an object to help us translate references in <val> into other objects read from the same mmp file or referred to by it. See the calls of this or similar methods from files_mmp for the doc of interp methods. If key is recognized, this method should set the attribute or property it refers to to val; otherwise it must do nothing. (An unrecognized key, even if longer than any recognized key, is not an error. Someday it would be ok to warn about an mmp file containing unrecognized info records or keys, but not too verbosely (at most once per file per type of info).) """ if len(key) != 2 or not key[0].isdigit(): if debug_flags.atom_debug: print "atom_debug: fyi: info gamess with unrecognized key %r (not an error)" % (key,) return pset_index, name = key pset_index = int(pset_index) # pset_index is presently always 0, but this code should work provided self.psets has an element with this index; try: pset = self.pset except: # not an error -- future mmp formats might use non-existent indices and expect readers to create new psets. if debug_flags.atom_debug: print "atom_debug: fyi: info gamess with non-existent pset index in key %r (not an error)" % (key,) return # the rest of the work should be done by the pset. try: self.pset.info_gamess_setitem( name, val, interp ) except: print_compact_traceback("bug: exception (ignored) in pset.info_gamess_setitem( %r, %r, interp ): " % (name,val) ) return pass def own_mutable_copyable_attrs(self): #bruce 050704 """ [overrides Node method] """ super = Jig super.own_mutable_copyable_attrs( self) for attr in self.mutable_attrs: if attr == 'pset': # special-case code for this attr, a list of gamessParms objects # (those objects, and the list itself, are mutable and need to be de-shared) val = getattr(self, attr) #assert type(val) == type([]) newval = val.deepcopy()#for item in val] setattr(self, attr, newval) else: print "bug: don't know how to copy attr %r in %r", attr, self pass return def cm_duplicate(self): #bruce 050704. """ Make a sibling node in the MT which has the same atoms, and a copy of the params, of this jig. """ #e Warning: The API (used by modelTree to decide whether to offer this command) is wrong, # and the implem should be generalized (to work on any Node or Group). Specifically, # this should become a Node method which always works (whether or not it's advisable to use it); # then the MT cmenu should dim it if some other method (which might depend on more than just the class) # says it's not advisable to use it. # I think it's advisable only on a Gamess jig, and on a chunk, # and maybe on a Group -- but what to do about contained jigs in a Group for which # some but not all atoms are being duplicated, or even other jigs in the Group, is a # design question, and it might turn out to be too ambiguous to safely offer it at all # for a Group with jigs in it. # Some code taken from Jig.copy_full_in_mapping and Jig._copy_fixup_at_end. copy = self.__class__( self.assy, self.atoms[:] ) orig = self orig.copy_copyable_attrs_to(copy) # replaces .name set by __init__ copy.name = copy.name + "-copy" #e could improve copy.own_mutable_copyable_attrs() # eliminate unwanted sharing of mutable copyable_attrs if orig.picked: self.color = self.normcolor orig.addsibling(copy) if copy.part is None: #bruce 050707 see if this is enough to fix bug 755 self.assy.update_parts() env.history.message( "Made duplicate Gamess jig on same atoms: [%s]" % copy.name ) # note: the wire cubes from multiple jigs on the sme atoms get overdrawn, # which will mess up the selection coloring of those wirecubes # since the order of drawing them is unrelated to which one is selected # (and since the OpenGL behavior seems a bit unpredictable anyway). ##e Should fix this to only draw one wirecube, of the "maximal color", I guess... self.assy.w.win_update() # MT and glpane both might need update return #def set_disabled_by_user_choice(self, val): # """Called when users disable/enable the jig""" # self.gmsjob.edit_cntl.run_job_btn.setEnabled(not val) # Jig.set_disabled_by_user_choice(self, val) def is_disabled(self): """ Which is called when model tree is updated? """ val = Jig.is_disabled(self) self.gmsjob.edit_cntl.run_job_btn.setEnabled(not val) return val def update_gamess_parms(self): """ Update the GAMESS parameter set values using the settings in the UI object. """ # $CONTRL group ########################################### # Parms Values self.pset.contrl.runtyp = runtyp[self.pset.ui.runtyp] # RUNTYP self.pset.contrl.scftyp = scftyp[self.pset.ui.scftyp] # SCFTYP self.pset.contrl.icharg = str(self.pset.ui.icharg) # ICHARG self.pset.contrl.mult = str(self.pset.ui.mult + 1) # MULT self.pset.contrl.mplevl = mplevl[self.pset.ui.ecm] # MPLEVL self.pset.contrl.inttyp = inttyp[self.pset.ui.ecm] # INTTYP self.pset.contrl.maxit = self.pset.ui.iterations # Iterations # ICUT and QMTTOL #s = str(self.gbasis_combox.currentText()) m = self.pset.ui.gbasisname.count('+') # If there is a plus sign in the basis set name, we have "diffuse orbitals" if m: # We have diffuse orbitals self.pset.contrl.icut = 11 if self.gmsjob.server.engine != 'PC GAMESS': # PC GAMESS does not support QMTTOL. Mark 052105 self.pset.contrl.qmttol = '3.0E-6' else: self.pset.contrl.qmttol = None else: # No diffuse orbitals self.pset.contrl.icut = 9 if self.gmsjob.server.engine == 'GAMESS': self.pset.contrl.qmttol = '1.0E-6' else: self.pset.contrl.qmttol = None # PC GAMESS does not support QMTTOL. Mark 052105 # DFTTYP (PC GAMESS only) # For PC GAMESS, the DFTTYP keyword is included in the CONTRL section, not the $DFT group. if self.gmsjob.server.engine == 'PC GAMESS': if ecm[self.pset.ui.ecm] == 'DFT': item = pcgms_dfttyp_items[self.pset.ui.dfttyp] # Item's full text, including the '(xxx)' self.pset.contrl.dfttyp, junk = item.split(' ',1) # DFTTYPE, removing the '(xxx)'. self.pset.dft.nrad = pcgms_gridsize[self.pset.ui.gridsize] # Grid Size parameters else: # None or MP2 self.pset.contrl.dfttyp = 0 self.pset.dft.nrad = 0 # $SCF group ########################################### self.pset.scf.extrap = tf[self.pset.ui.extrap] # EXTRAP self.pset.scf.dirscf = tf[self.pset.ui.dirscf] # DIRSCF self.pset.scf.damp = tf[self.pset.ui.damp] # DAMP self.pset.scf.diis = tf[self.pset.ui.diis] # DIIS self.pset.scf.shift = tf[self.pset.ui.shift] # SHIFT self.pset.scf.soscf = tf[self.pset.ui.soscf] # SOSCF self.pset.scf.rstrct = tf[self.pset.ui.rstrct] # RSTRCT # CONV (GAMESS) or # NCONV (PC GAMESS) if self.gmsjob.server.engine == 'GAMESS': self.pset.scf.conv = conv[self.pset.ui.conv] # CONV (GAMESS) self.pset.scf.nconv = 0 # Turn off NCONV else: # PC GAMESS self.pset.scf.nconv = conv[self.pset.ui.conv] # NCONV (PC GAMESS) self.pset.scf.conv = 0 # Turn off CONV # $SYSTEM group ########################################### self.pset.system.timlin = 1000 # Time limit in minutes self.pset.system.memory = self.pset.ui.memory * 1000000 # $MP2 group ########################################### self.pset.mp2.ncore = ncore[self.pset.ui.ncore] # $DFT group ########################################### # The DFT section record is supported in GAMESS only. if self.gmsjob.server.engine == 'GAMESS': if ecm[self.pset.ui.ecm] == 'DFT': item = gms_dfttyp_items[self.pset.ui.dfttyp] self.pset.dft.dfttyp, junk = item.split(' ',1) # DFTTYP in $CONTRL self.pset.dft.nrad = gms_gridsize[self.pset.ui.gridsize] # Grid Size parameters else: # None or MP2 self.pset.dft.dfttyp = 'NONE' self.pset.dft.nrad = 0 # $GUESS group ########################################### # $STATPT group ########################################### if runtyp[self.pset.ui.runtyp] == 'optimize': self.pset.statpt.opttol = float(opttol[self.pset.ui.rmsdconv]) else: self.pset.statpt.opttol = None # $BASIS group ########################################### if ecm[self.pset.ui.ecm] == 'None': self.pset.basis.gbasis = gbasis[self.pset.ui.gbasis] # GBASIS else: self.pset.basis.gbasis = gbasis[self.pset.ui.gbasis + 2] # GBASIS return pass # end of class Gamess