modules/chempy/gamess1.py (557 lines of code) (raw):

#A* ------------------------------------------------------------------- #B* This file contains source code for the PyMOL computer program #C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific. #D* ------------------------------------------------------------------- #E* It is unlawful to modify or remove this copyright notice. #F* ------------------------------------------------------------------- #G* Please see the accompanying LICENSE file for further information. #H* ------------------------------------------------------------------- #I* Additional authors of this source file include: #-* #-* #-* #Z* ------------------------------------------------------------------- # this is quick and dirty irst crack at a gamess interface, written by someone who # knows very little about the program (WLD) - hence the version 1 identifier... # by the way, most of the below is untested... from __future__ import print_function import os import shutil import glob import re import sys import time from chempy import feedback from chempy.brick import Brick atNum = { 'H' : 1, 'C' : 6, 'N' : 7, 'O' : 8, 'F' : 9, 'P' : 15, 'S' : 16, 'Cl' : 17, 'Br' : 35, 'I' : 53, } def do(input,run_prefix=None,echo=None, punch=None,output=None,skip=None): if not run_prefix: run_prefix = 'gamess_run' if not skip: if feedback['gamess']: print(" "+str(__name__)+': creating temporary files "%s.*"' % (run_prefix)) print(" "+str(__name__)+': launching gamess...') try: for a in glob.glob(run_prefix+".*"): os.unlink(a) except: pass f = open(run_prefix+".inp",'w') for a in input: f.write(a) f.close() if echo: os.system(rungms_path+' '+run_prefix+" 2>&1 | tee "+run_prefix+".out") else: os.system(rungms_path+' '+run_prefix+" > "+run_prefix+".out 2>&1") # NFS workaround (flushes the directory cache so that glob will work) try: os.unlink(".sync") except: pass f = open(".sync",'w') f.close() # if feedback['gamess']: print(" "+str(__name__)+': job complete. ') if punch: for src in glob.glob(run_prefix+".dat"): f = open(src) punch = f.readlines() f.close() if output: for src in glob.glob(run_prefix+".out"): f = open(src) output = f.readlines() f.close() return (output,punch) if 'GAMESS' in os.environ: base = os.environ['GAMESS'] bin_path = base + '/bin/' rungms_path = bin_path + 'rungms' else: base = '' bin_path = '' params_path = '' class State: def __init__(self): self.model = None self.data = None self.vec = None def load_model(self,model): self.model = model def get_zmat_ordering(self): lst = [] for z in self.model.get_internal_tuples(): lst.append(z[0]) return lst def get_data_group(self,basis = None,zmat = 1): model = self.model gmsList = [] # write header records gmsList.append(" $DATA\n") gmsList.append(model.molecule.title+" from "+str(__name__)+"\n") gmsList.append("C1\n") # write atom records in an ordering compatible with internal # coordinate generation c = 1 for z in self.get_zmat_ordering(): a = model.atom[z] if not len(a.name): name = a.symbol + "%02d"%c else: name = a.name gmsList.append("%10s %5.1f %18.10f %18.10f %18.10f\n" % (name,atNum[a.symbol],a.coord[0], a.coord[1],a.coord[2])) c = c + 1 gmsList.append(" $END\n") return gmsList def get_ordered_data_group(self): gmsList = self.data[0:3] flag = 1 c = 3 for a in self.data[3:]: if flag: flag = 0 gmsList.append(a) if not a.strip(): flag = 1 c = c + 1 return gmsList def get_contrl_group(self, scftyp='RHF', runtyp='ENERGY', exetyp='RUN', coord='UNIQUE', nzvar = -1): gmsList = [] model = self.model if nzvar: if nzvar<0: nzvar = (self.model.nAtom*3)-6 gmsList.append(" $CONTRL SCFTYP=%s RUNTYP=%s EXETYP=%s\n" % (scftyp,runtyp,exetyp) ) if coord: gmsList.append("COORD=%s\n"%coord) if nzvar: gmsList.append("NZVAR=%d\n"%nzvar) chg = 0 for a in model.atom: chg = chg + a.formal_charge chg = int(chg) if chg==0: icharg=None else: icharg='ICHARG=%d' % chg if icharg: gmsList.append("%s\n" % (icharg)) gmsList.append(" $END\n") return gmsList def read_output_list(self,list): ll = len(list) c = 0 crd_list = [] chg_list = [] nrg_list = [] for a in list: if a[0:36] == ' COORDINATES OF ALL ATOMS ARE (ANGS)': crd_list.append(c+3) if a[0:13] == ' NET CHARGES:': chg_list.append(c+4) if a[0:37] == ' TOTAL ENERGY =': nrg_list.append(c) c = c + 1 atom = self.model.atom idx = {} c = 0 for a in atom: idx[a.name.upper()]=c # games converts to uppercase c = c + 1 if len(crd_list): a = crd_list.pop() cc = 0 while a<ll: l = list[a] name = l[1:11].strip() if name=='': break atom[idx[name]].coord = [float(l[16:31]), float(l[31:46]), float(l[46:61])] cc = cc + 1 a = a + 1 if cc and feedback['gamess']: print(" "+str(__name__)+': coordinates modified for %d atoms.' % (cc)) if len(chg_list): a = chg_list.pop() cc = 0 while a<ll: l = list[a] name = l[1:11].strip() if name[0]=='-': break atom[idx[name]].partial_charge = float(l[19:27]) a = a + 1 cc = cc + 1 if cc and feedback['gamess']: print(" "+str(__name__)+': charges modified for %d atoms.' % (cc)) if len(nrg_list): a = nrg_list.pop() l = list[a] # get energy, and convert to kcal/mole self.model.molecule.energy = float(l[38:58].strip())*627.5095 if feedback['gamess']: print(" "+str(__name__)+': energy updated %12.6f.' % self.model.molecule.energy) def read_punch_list(self,list): ll = len(list) c = 0 data_list = [] vec_list = [] for a in list: if a[0:6] == ' $DATA': data_list.append(c) elif a[0:5] == ' $VEC': vec_list.append(c) c = c + 1 if len(data_list): a = data_list.pop() self.data = [] data = self.data while a<ll: la = list[a] data.append(la) if la[0:5] == ' $END': break a = a + 1 if feedback['gamess']: print(" "+str(__name__)+': read $DATA group.') if len(vec_list): a = vec_list.pop() self.vec = [] vec = self.data while a<ll: la = list[a] vec.append(la) if la[0:5] == ' $END': break a = a + 1 if feedback['gamess']: print(" "+str(__name__)+': read new $VEC group.') def update_data_coords(self): # update coordinates of ordered atoms in $DATA idx = {} c = 0 for a in self.model.atom: idx[a.name.upper()]=c c = c + 1 if self.data: flag = 1 c = 3 for a in self.data[3:]: if flag: flag = 0 kee = a[0:3] if kee not in idx: break i = idx[kee] at = self.model.atom[i] self.data[c]="%-10s%5.1f%18.10f%18.10f%18.10f\n" % ( at.name,atNum[at.symbol],at.coord[0], at.coord[1],at.coord[2]) if not a.strip(): flag = 1 c = c + 1 def read_density_list(self,list,brick,z_step): ll = len(list) c = 0 den_list = [] for a in list: if a[0:37] == ' ELECTRON DENSITY, IPOINT,X,Y,Z,EDENS': den_list.append(c+1) c = c + 1 if len(den_list): lst = 0 a = den_list.pop() for x in range(brick.dim[0]): for y in range(brick.dim[1]): brick.lvl[x][y][z_step] = float(list[a][36:51]) a = a + 1 if feedback['gamess']: print(" "+str(__name__)+': read density slice %d of %d.' %( z_step+1,brick.dim[2])) def read_potential_list(self,list,brick,z_step): ll = len(list) c = 0 pot_list = [] for a in list: if a[0:51] == 'THE ROWS OF THE ELECTROSTATIC POTENTIAL GRID (A.U.)': pot_list.append(c+1) c = c + 1 if len(pot_list): lst = 0 a = pot_list.pop() for x in range(brick.dim[0]): aa = a mat = list[aa][0:3] col = [] while 1: if list[aa][0:3]==mat: col.append(list[aa][5:]) aa = aa + 1 else: break a = aa vst = ' '.join(col).split() for y in range(brick.dim[1]): brick.lvl[x][y][z_step] = float(vst[y]) if feedback['gamess']: print(" "+str(__name__)+': read potential slice %d of %d.' %( z_step+1,brick.dim[2])) def get_basis_group(self,gbasis='N31',ngauss=6,ndfunc=1): gmsList = [] gmsList.append(" $BASIS GBASIS=%s NGAUSS=%d NDFUNC=%d\n" % (gbasis,ngauss,ndfunc)) model = self.model chg = 0 for a in model.atom: chg = chg + a.formal_charge chg = int(chg) if chg<0: diffsp=' DIFFSP=.TRUE.' else: diffsp=None if diffsp: gmsList.append("%s\n" % (diffsp)) gmsList.append(" $END\n") return gmsList def get_zmat_ext_freeze_torsion(self,flag=3): # requires PYMOL to read dihedrals from structure # requires list of dihedrals from tinker.amber # from pymol import cmd from .tinker.amber import Topology cmd.load_model(self.model,'_gamess1') model = self.model # get mapping of model ordering to zmat ordering m2z = {} z2m = {} c = 1 # GAMESS is one-based for a in self.get_zmat_ordering(): m2z[a] = c z2m[c] = a c = c + 1 # get all torsions in the molecule topo = Topology(self.model) # find those where flag is set in all atoms mask = 2 ** flag frozen_list = [] for a in list(topo.torsion.keys()): if (model.atom[a[0]].flags& model.atom[a[1]].flags& model.atom[a[2]].flags& model.atom[a[3]].flags)&mask: frozen_list.append(a) print(" freeze-torsion: %d torsions will be frozen."%len(frozen_list)) irzmat = [] ifzmat = [] fvalue = [] if len(frozen_list): for frozen in frozen_list: # find additional torsions which need to be removed remove = [] for a in list(topo.torsion.keys()): if (((a[1]==frozen[1])and(a[2]==frozen[2])) or ((a[2]==frozen[1])and(a[1]==frozen[2]))): if a!=frozen: remove.append(a) # convert to internal coordinate ordering frozen_z = (m2z[frozen[0]],m2z[frozen[1]], m2z[frozen[2]],m2z[frozen[3]]) remove_z = [] for a in remove: remove_z.append(m2z[a[0]],m2z[a[1]],m2z[a[2]],m2z[a[3]]) # now reorder atoms in torsions to reflect z_matrix ordering # (not sure this is necessary) if frozen_z[0]>frozen_z[3]: frozen_z = (frozen_z[3],frozen_z[2],frozen_z[1],frozen_z[0]) tmp_z = [] for a in remove_z: if a[0]>a[3]: tmp_z.append((a[3],a[2],a[1],a[0])) else: tmp_z.append(a) remove_z = tmp_z # get value of the fixed torsion fixed = (z2m[frozen_z[0]],z2m[frozen_z[1]], z2m[frozen_z[2]],z2m[frozen_z[3]]) dihe = cmd.get_dihedral("(_gamess1 and id %d)"%fixed[0], "(_gamess1 and id %d)"%fixed[1], "(_gamess1 and id %d)"%fixed[2], "(_gamess1 and id %d)"%fixed[3]) # write out report for user edification print(" freeze-torsion: fixing freeze-torsion:") print(" freeze-torsion: %d-%d-%d-%d (pymol), %d-%d-%d-%d (gamess)"%( fixed[0],fixed[1],fixed[2],fixed[3], frozen_z[0],frozen_z[1],frozen_z[2],frozen_z[3])) print(" freeze-torsion: at %5.3f"%dihe) print(" freeze-torsion: removing redundant torsions:") for a in remove_z[1:]: print(" freeze-torsion: %d-%d-%d-%d (pymol), %d-%d-%d-%d (gamess)"%( z2m[a[0]],z2m[a[1]],z2m[a[2]],z2m[a[3]], a[0],a[1],a[2],a[3])) # add parameters for this torsion into the list ifzmat.append((3,frozen_z[0],frozen_z[1],frozen_z[2],frozen_z[3])) fvalue.append(dihe) if len(remove_z): for a in remove_z[1:]: irzmat.append((3,a[0],a[1],a[2],a[3])) # generate restrained dihedral information zmat_ext = [] if len(ifzmat): zmat_ext.append(" IFZMAT(1)=\n") comma = "" for a in ifzmat: zmat_ext.append(comma+"%d,%d,%d,%d,%d\n"%a) comma = "," if len(fvalue): zmat_ext.append(" FVALUE(1)=\n") comma = "" for a in fvalue: zmat_ext.append(comma+"%1.7f\n"%a) comma = "," if len(irzmat): zmat_ext.append(" IRZMAT(1)=\n") comma = "" for a in irzmat: zmat_ext.append(comma+"%d,%d,%d,%d,%d\n"%a) comma = "," cmd.delete("_gamess1") # important if len(zmat_ext): return zmat_ext else: return None def get_zmat_group(self,auto=1,dlc=1,zmat_extend=None): gmsList = [] if auto and dlc: if zmat_extend == None: gmsList.append(" $ZMAT DLC=.TRUE. AUTO=.TRUE. $END\n") else: gmsList.append(" $ZMAT DLC=.TRUE. AUTO=.TRUE.\n") gmsList.extend(zmat_extend) gmsList.append(" $END\n") else: raise RuntimeError return gmsList def get_eldens_group(self,morb=0): gmsList = [] gmsList.append(" $ELDENS IEDEN=1 MORB=%i \n" % morb) gmsList.append("WHERE=GRID OUTPUT=PUNCH\n $END\n") return gmsList def get_elpot_group(self,morb=0): gmsList = [] gmsList.append(" $ELPOT IEPOT=1 \n") gmsList.append("WHERE=GRID OUTPUT=PUNCH\n $END\n") return gmsList def get_guess_group(self,guess='HUCKEL'): return [" $GUESS GUESS=%s $END\n"%guess] def get_grid_group(self,brick,z_step): origin = ( brick.origin[0], brick.origin[1], brick.origin[2]+brick.grid[2]*z_step) x_coord = ( brick.origin[0]+brick.range[0]+brick.grid[0]/100.0, brick.origin[1], brick.origin[2]+brick.grid[2]*z_step) y_coord = ( brick.origin[0], brick.origin[1]+brick.range[1]+brick.grid[1]/100.0, brick.origin[2]+brick.grid[2]*z_step) gmsList = [ " $GRID ORIGIN(1)=%12.5f,%12.5f,%12.5f\n" % origin, "XVEC(1) = %12.5f,%12.5f,%12.5f\n" % x_coord, "YVEC(1) = %12.5f,%12.5f,%12.5f\n" % y_coord, "SIZE = %12.5f\n" % brick.grid[0], " $END\n" ] return gmsList def get_scf(self,dirscf=1): gmsList = [] if dirscf: gmsList.append(" $SCF DIRSCF=.TRUE. $END\n") return gmsList def get_optimize_job(self,dirscf=1,zmat_extend=None): gmsList = [] gmsList.extend(self.get_contrl_group(runtyp='OPTIMIZE')) gmsList.extend(self.get_basis_group()) gmsList.extend(self.get_scf(dirscf=dirscf)) gmsList.extend(self.get_data_group()) gmsList.extend(self.get_zmat_group(zmat_extend=zmat_extend)) gmsList.append(" $STATPT NSTEP=50 $END\n") return gmsList def get_optimize_charge_job(self): gmsList = self.get_optimize_job() gmsList.append(" $ELPOT IEPOT=1 WHERE=PDC $END\n") gmsList.append(" $PDC PTSEL=GEODESIC CONSTR=CHARGE $END\n") return gmsList def get_energy_charge_job(self): gmsList = self.get_energy_job() gmsList.append(" $ELPOT IEPOT=1 WHERE=PDC $END\n") gmsList.append(" $PDC PTSEL=GEODESIC CONSTR=CHARGE $END\n") return gmsList def get_prop_job(self): gmsList = [] gmsList.extend(self.get_contrl_group(runtyp = 'PROP', nzvar=0)) gmsList.extend(self.get_guess_group(guess='MOREAD')) self.update_data_coords() gmsList.extend(self.data) gmsList.extend(self.vec) return gmsList def get_energy_job(self): gmsList=[] gmsList.extend(self.get_contrl_group( runtyp = 'ENERGY' )) gmsList.extend(self.get_basis_group()) gmsList.extend(self.get_scf()) gmsList.extend(self.get_data_group()) gmsList.extend(self.get_zmat_group()) return gmsList def get_density_job(self,brick,z_step,morb=0): gmsList = self.get_prop_job() gmsList.extend(self.get_eldens_group(morb=morb)) gmsList.extend(self.get_grid_group(brick,z_step)) return gmsList def get_potential_job(self,brick,z_step): gmsList = self.get_prop_job() gmsList.extend(self.get_elpot_group()) gmsList.extend(self.get_grid_group(brick,z_step)) return gmsList def get_prop_charge_job(self): gmsList = self.get_prop_job() gmsList.append(" $ELPOT IEPOT=1 WHERE=PDC $END\n") gmsList.append(" $PDC PTSEL=GEODESIC CONSTR=CHARGE $END\n") return gmsList def get_density(self,brick,morb=0,run_prefix=None): for a in range(brick.dim[2]): gmsList = self.get_density_job(brick,a,morb=morb) result = do(gmsList,punch=1, run_prefix=run_prefix) self.read_density_list(result[1],brick,a) def get_potential(self,brick,run_prefix=None): for a in range(brick.dim[2]): gmsList = self.get_potential_job(brick,a) result = do(gmsList,punch=1, run_prefix=run_prefix) self.read_potential_list(result[1],brick,a) def get_charges(self,run_prefix=None): gmsList = self.get_energy_job() result = do(gmsList,output=1,punch=1, run_prefix=run_prefix) self.read_output_list(result[0]) self.read_punch_list(result[1]) def get_energy(self,run_prefix=None): gmsList = self.get_energy_job() result = do(gmsList,output=1,punch=1, run_prefix=run_prefix) self.read_output_list(result[0]) self.read_punch_list(result[1]) def get_optimized_energy(self,run_prefix=None,zmat_extend=None): gmsList = self.get_optimize_job(zmat_extend=zmat_extend) result = do(gmsList,output=1,punch=1, run_prefix=run_prefix) self.read_output_list(result[0]) self.read_punch_list(result[1]) def get_optimized_charges(self,run_prefix=None,skip=None): gmsList = self.get_optimize_charge_job() result = do(gmsList,output=1,punch=1, run_prefix=run_prefix,skip=skip) self.read_output_list(result[0]) self.read_punch_list(result[1]) def get_prop_charges(self,run_prefix=None): gmsList = self.get_prop_charge_job() result = do(gmsList,output=1,punch=1, run_prefix=run_prefix) self.read_output_list(result[0]) self.read_punch_list(result[1]) if 'GAMESS' in os.environ: base = os.environ['GAMESS'] rungms_path = base + '/bin/rungms' else: base = '' rungms_path = ''