def addtobdb(smimol,sminame): globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print('To add to database, you need to set a custom path. Please enter a writeable file path:') new_path = input('path=') globs.add_custom_path(new_path) copy_to_custom_path() bpath = globs.custom_path + "/Bind/bind.dict" bindcores = readdict(bpath) bind_folder = globs.custom_path + "/Bind/" # check if binding species exists if sminame in bindcores.keys(): emsg = 'Molecule '+sminame+' already existing in binding species database.' return emsg else: # convert to unicode smimol = unicodedata.normalize('NFKD',smimol).encode('ascii','ignore') sminame = unicodedata.normalize('NFKD',sminame).encode('ascii','ignore') if '~' in smimol: smimol = smimol.replace('~',os.expanduser('~')) # convert ligand from smiles/file bind,bsmi,emsg = bind_load(smimol,bindcores) if emsg: return emsg bind.convert2mol3D() # convert to mol3D # new entry for dictionary # create shortname if len(sminame) > 5: shortname = sminame[0:3]+sminame[-2:] else: shortname = sminame if '.mol' in smimol: shutil.copy2(smimol,bind_folder+sminame+'.mol') snew = sminame+':'+sminame+'.mol,'+shortname+',' elif '.xyz' in smimol: shutil.copy2(smimol,bind_folder +sminame+'.xyz') snew = sminame+':'+sminame+'.xyz,'+shortname+',' elif bind.OBmol: # write smiles file in Bind species directory bind.OBmol.write('smi',bind_folder +sminame+'.smi') snew = sminame+':'+sminame+'.smi,'+shortname+',' else: # write xyz file in Bind species directory bind.writexyz(bind_folder +sminame+'.xyz') # write xyz file snew = sminame+':'+sminame+'.xyz,'+shortname+',' # update dictionary f = open(bpath,'r') ss = f.read().splitlines() f.close() f = open(bpath,'w') ss.append(snew) ssort = sorted(ss[1:]) f.write(ss[0]+'\n') for s in ssort: f.write(s+'\n') f.close() return emsg
def addtocdb(smimol,sminame,smicat): emsg = False globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print('To add to database, you need to set a custom path. Please enter a writeable file path:') new_path = input('path=') globs.add_custom_path(new_path) copy_to_custom_path() cpath = globs.custom_path + "/Cores/cores.dict" mcores = readdict(cpath) cores_folder = globs.custom_path + "/Cores/" # check if core exists if sminame in mcores.keys(): emsg = 'Core '+sminame+' already existing in core database.' return emsg else: # get connection atoms ccats = filter(None,re.split(' |,|\t',smicat)) cats = [int(a)-1 for a in ccats] if len(cats)==0: cats=[0] cs = [str(a) for a in cats] css = ' '.join(cs) # convert to unicode smimol = unicodedata.normalize('NFKD',smimol).encode('ascii','ignore') if '~' in smimol: smimol = smimol.replace('~',os.expanduser('~')) # convert ligand from smiles/file core,emsg = core_load(smimol,mcores) if emsg: return emsg core.convert2mol3D() # convert to mol3D # write xyz file in Cores directory # new entry for dictionary if '.mol' in smimol: shutil.copy2(smimol,cores_folder+sminame+'.mol') snew = sminame+':'+sminame+'.mol,'+css+','+'1' elif '.xyz' in smimol: shutil.copy2(smimol,cores_folder + sminame+'.xyz') snew = sminame+':'+sminame+'.xyz,'+css+','+'1' else: core.writexyz(cores_folder +sminame+'.xyz') # write xyz file # new entry for dictionary snew = sminame+':'+sminame+'.xyz,'+css+','+'1' # update dictionary f = open(cpath,'r') ss = f.read().splitlines() f.close() f = open(cpath,'w') ss.append(snew) ssort = sorted(ss[1:]) f.write(ss[0]+'\n') for s in ssort: f.write(s+'\n') f.close() return emsg
def getslicores(): globs = globalvars() if globs.custom_path: # test if a custom path is used: slicores = str( globs.custom_path).rstrip('/') + "/Ligands/simple_ligands.dict" else: slicores = resource_filename( Requirement.parse("molSimplify"), "molSimplify/Ligands/simple_ligands.dict") slicores = readdict(slicores) return slicores
def checkinput(args): globs = globalvars() emsg = False # check core if not args.core: print 'WARNING: No core specified. Defaulting to Fe. Available cores are: '+getcores() args.core = ['fe'] # check oxidation state if not args.oxstate: try: print 'WARNING: No oxidation state specified. Defaulting to '+globs.defaultoxstate[args.core[0].lower()] args.oxstate = globs.defaultoxstate[args.core[0].lower()] except: print 'WARNING: No oxidation state specified. Defaulting to II' args.oxstate = 'II' # check ligands if not args.lig and not args.rgen: if args.gui: from Classes.mWidgets import mQDialogWarn qqb = mQDialogWarn('Warning','You specified no ligands.\n') qqb.setParent(args.gui.wmain) else: print 'WARNING: No ligands specified. Defaulting to water.\n' args.lig = ['water'] # check coordination number and geometry if not args.coord and not args.geometry: if not args.gui: print 'WARNING: No geometry and coordination number specified. Defaulting to octahedral (6).\n' args.coord = 6 args.geometry = 'oct' coords,geomnames,geomshorts,geomgroups = getgeoms() if args.coord and (not args.geometry or (args.geometry not in geomnames and args.geometry not in geomshorts)): print 'WARNING: No or unknown coordination geometry specified. Defaulting to '+globs.defaultgeometry[int(args.coord)][1] args.geometry = globs.defaultgeometry[int(args.coord)][0] if args.geometry and not args.coord: if args.geometry not in geomnames and args.geometry not in geomshorts: print 'You have specified an invalid geometry. Available geometries are:' printgeoms() print 'Defaulting to octahedral (6)' args.geometry = 'oct' args.coord = 6 else: try: args.coord = coords[geomnames.index(args.geometry)] except: args.coord = coords[geomshorts.index(args.geometry)] print 'WARNING: No coordination number specified. Defaulting to '+str(args.coord) # check number of ligands if args.coord and not args.ligocc: print('WARNING: No ligand numbers specified. Defaulting to '+str(args.coord)+' of the first ligand and 0 of all others.\n') args.ligocc = [args.coord] for lig in args.lig[1:]: args.ligocc.append(0)
def getsimilar(smi, nmols, dbselect, finger, squery, args): ####################################### ## smi: pybel reference smiles ## ## nmols: number of similar ones ## ## dbselect: database to be searched ## ####################################### ## get database files [dbsdf, dbfs] = setupdb(dbselect) print('database set up :' + str(dbsdf) + ' || ' + str(dbfs)) globs = globalvars() print('Finding results similar, comparing to ' + smi) obab = 'babel' if dbfs and args.dbfs: com = obab + ' ' + dbfs + ' ' + 'simres.smi -d -xf' + finger + ' -s"' + smi + '" -al' + nmols else: mybash(obab + ' -isdf ' + dbsdf + ' -osdf -O tmp.sdf -d') com = obab + ' tmp.sdf simres.smi -xf' + finger + ' -s"' + smi + '"' ## perform search using bash commandline print('Performing substructure search:') print('running: ' + str(com)) res = mybash(com) print('res = ' + str(res)) print('number of SMILES returned : ' + str(mybash('cat simres.smi | wc -l'))) if os.path.isfile('tmp.sdf'): os.remove('tmp.sdf') shutil.copy('simres.smi', 'initial.smi') if args.dbmaxsmartsmatches: print('Applying filters: inside get similar') com = obab + " -ismi simres.smi -osmi -O simres.smi -h --filter " + squery print('running: ' + str(com)) mybash(com) print('number of lines in simres.smi: ' + str(mybash('cat simres.smi | wc -l'))) # com = obab+" -ismi simres.smi -osmi -O simres.smi -d --filter 'nsmartsmatches<="+args.dbmaxsmartsmatches+"'" # rint('running: '+ str(com)) # res = mybash(com) # print('number of lines in simres.smi after dxbsmartmatches: '+str(mybash('cat simres.smi | wc -l'))) # print res shutil.copy('simres.smi', 'afterfilteringsmarts.smi') ## check output and print error if nothing was found if ('errors' in res): ss = 'No matches were found in DB. Log info:\n' + res print ss return ss, True else: return 'simres.smi', False
def getmcores(): ## this form of the functionn ## is used extensively in the GUI ## so it got it's own call. This ## is basically the same as getcores() but ## returns the full dictionary globs = globalvars() if globs.custom_path: # test if a custom path is used: mcores = str(globs.custom_path).rstrip('/') + "/Cores/cores.dict" else: mcores = resource_filename(Requirement.parse("molSimplify"),"molSimplify/Cores/cores.dict") mcores = readdict(mcores) return mcores
def simple_slope_ann(slope_excitation): globs=globalvars() path_to_file = resource_filename(Requirement.parse("molSimplify"),"molSimplify/python_nn/" + "ms_slope") #print('path to ANN data: ',path_to_file) n = simple_network_builder([24,50,50],"ms_slope") ## no alpha value #print(slope_excitation) slope_excitation,sl_center,sl_shift = excitation_standardizer(slope_excitation,'slope') #print(slope_excitation) result = n.activate(slope_excitation) # print('result is ' + str(result)) # print('center is ' + str(sl_center) + ' shift '+ str(sl_shift)) result = (result*sl_shift) + sl_center #print('result is ' + str(result)) return result
def getlicores(): globs = globalvars() if globs.custom_path: # test if a custom path is used: licores = str(globs.custom_path).rstrip('/') + "/Ligands/ligands.dict" else: licores = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Ligands/ligands.dict") licores = readdict(licores) for ligand in licores.keys(): if len(licores[ligand][2]) == 2 and type(licores[ligand][2]) == list: licores[ligand + '_flipped'] = copy.deepcopy(licores[ligand]) licores[ligand + '_flipped'][2].reverse() return licores
def loadcoord(coord): globs = globalvars() # f = open(installdir+'Data/'+coord+'.dat') if globs.custom_path: f = globs.custom_path + "/Data/" +coord + ".dat" else: f = resource_filename(Requirement.parse("molSimplify"),"molSimplify/Data/" +coord + ".dat") f = open(f) txt = filter(None,f.read().splitlines()) f.close() b = [] for line in txt: l = filter(None,line.split(None)) b.append([float(l[0]),float(l[1]),float(l[2])]) return b
def simple_slope_ann(slope_excitation): globs = globalvars() path_to_file = resource_filename(Requirement.parse("molSimplify"), "molSimplify/python_nn/" + "ms_slope") #print('path to ANN data: ',path_to_file) n = simple_network_builder([24, 50, 50], "ms_slope") ## no alpha value #print(slope_excitation) slope_excitation, sl_center, sl_shift = excitation_standardizer( slope_excitation, 'slope') #print(slope_excitation) result = n.activate(slope_excitation) # print('result is ' + str(result)) # print('center is ' + str(sl_center) + ' shift '+ str(sl_shift)) result = (result * sl_shift) + sl_center #print('result is ' + str(result)) return result
def simple_splitting_ann(excitation): globs=globalvars() path_to_file = resource_filename(Requirement.parse("molSimplify"),"molSimplify/python_nn/" + "ms_split") #print('path to ANN data: ',path_to_file) n = simple_network_builder([25,50,50],"ms_split") excitation,sp_center,sp_shift = excitation_standardizer(excitation,'split') #print(excitation) #print('center is ' + str(sp_center)) #print('scale is '+ str(sp_shift)) #print(excitation) result = n.activate(excitation) #print('result is ' + str(result)) result = (result*sp_shift) + sp_center #print('result is ' + str(result)) return result,excitation
def getsimilar(smi, nmols, dbselect, finger, squery, args): ##get database files [dbsdf, dbfs] = setupdb(dbselect) print('database set up :' + str(dbsdf) + ' || ' + str(dbfs)) globs = globalvars() print('Finding results similar, comparing to ' + smi) obab = 'babel' if dbfs and args.dbfs: com = obab + ' ' + dbfs + ' ' + 'simres.smi -d -xf' + finger + ' -s"' + smi + '" -al' + nmols else: mybash(obab + ' -isdf ' + dbsdf + ' -osdf -O tmp.sdf -d') com = obab + ' tmp.sdf simres.smi -xf' + finger + ' -s"' + smi + '"' # perform search using bash commandline print('Performing substructure search:') print('running: ' + str(com)) res = mybash(com) print ('res = ' + str(res)) print('number of SMILES returned : ' + str(mybash('cat simres.smi | wc -l'))) if os.path.isfile('tmp.sdf'): os.remove('tmp.sdf') shutil.copy('simres.smi', 'initial.smi') if args.dbmaxsmartsmatches: print('Applying filters: inside get similar') com = obab + " -ismi simres.smi -osmi -O simres.smi -h --filter " + squery print('running: ' + str(com)) mybash(com) print('number of lines in simres.smi: ' + str(mybash('cat simres.smi | wc -l'))) # com = obab+" -ismi simres.smi -osmi -O simres.smi -d --filter 'nsmartsmatches<="+args.dbmaxsmartsmatches+"'" # rint('running: '+ str(com)) # res = mybash(com) # print('number of lines in simres.smi after dxbsmartmatches: '+str(mybash('cat simres.smi | wc -l'))) # print res shutil.copy('simres.smi', 'afterfilteringsmarts.smi') ## check output and print error if nothing was found if ('errors' in res): ss = 'No matches were found in DB. Log info:\n' + res print ss return ss, True else: return 'simres.smi', False
def simple_splitting_ann(excitation): globs = globalvars() path_to_file = resource_filename(Requirement.parse("molSimplify"), "molSimplify/python_nn/" + "ms_split") #print('path to ANN data: ',path_to_file) n = simple_network_builder([25, 50, 50], "ms_split") excitation, sp_center, sp_shift = excitation_standardizer( excitation, 'split') # print('center is ' + str(sp_center)) # print('scale is '+ str(sp_shift)) result = n.activate(excitation) #print(excitation) #print('result is ' + str(result)) result = (result * sp_shift) + sp_center #print('result is ' + str(result)) return result
def loaddata(path): globs = globalvars() # loads ML data from ML.dat file and # store to dictionary if globs.custom_path: # test if a custom path is used: fname = str(globs.custom_path).rstrip('/') + path else: fname = resource_filename(Requirement.parse("molSimplify"),"molSimplify"+path) d = dict() f = open(fname) txt = f.read() lines = filter(None,txt.splitlines()) for line in lines[1:]: if '#'!=line[0]: # skip comments l = filter(None,line.split(None)) d[(l[0],l[1],l[2],l[3],l[4])] = l[5] # read dictionary f.close() return d
def copy_to_custom_path(): globs = globalvars() if not globs.custom_path: print('Error, custom path not set!') raise ('') ## create folder if not os.path.exists(globs.custom_path): os.makedirs(globs.custom_path) ### copytree cannot overwrite, need to enusre directory does not exist already core_dir = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Cores") li_dir = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Ligands") bind_dir = (resource_filename(Requirement.parse("molSimplify"), "molSimplify/Bind")) data_dir = (resource_filename(Requirement.parse("molSimplify"), "molSimplify/Data")) subs_dir = (resource_filename(Requirement.parse("molSimplify"), "molSimplify/Substrates")) if os.path.exists(str(globs.custom_path).rstrip("/") + "/Cores"): print('Note: removing old molSimplify data') shutil.rmtree(str(globs.custom_path).rstrip("/") + "/Cores") if os.path.exists(str(globs.custom_path).rstrip("/") + "/Ligands"): print('Note: removing old molSimplify data') shutil.rmtree(str(globs.custom_path).rstrip("/") + "/Ligands") if os.path.exists(str(globs.custom_path).rstrip("/") + "/Bind"): print('Note: removing old molSimplify data') shutil.rmtree(str(globs.custom_path).rstrip("/") + "/Bind") if os.path.exists(str(globs.custom_path).rstrip("/") + "/Data"): print('Note: removing old molSimplify data') shutil.rmtree(str(globs.custom_path).rstrip("/") + "/Data") if os.path.exists(str(globs.custom_path).rstrip("/") + "/Substrates"): print('Note: removing old molSimplify data') shutil.rmtree(str(globs.custom_path).rstrip("/") + "/Substrates") shutil.copytree(core_dir, str(globs.custom_path).rstrip("/") + "/Cores") shutil.copytree(li_dir, str(globs.custom_path).rstrip("/") + "/Ligands") shutil.copytree(bind_dir, str(globs.custom_path).rstrip("/") + "/Bind") shutil.copytree(data_dir, str(globs.custom_path).rstrip("/") + "/Data") shutil.copytree(subs_dir, str(globs.custom_path).rstrip("/") + "/Substrates")
def setupdb(dbselect): globs = globalvars() dbdir = os.path.relpath(globs.chemdbdir) + '/' # get files in directory dbfiles = os.listdir(dbdir) # search for db files dbmatches = [dbf for dbf in dbfiles if dbselect.lower() in dbf.lower()] dbsdf = [dbm for dbm in dbmatches if '.sdf' in dbm] dbfs = [dbm for dbm in dbmatches if '.fs' in dbm] # print('thefile list' + str(dbfiles)) if len(dbsdf) == 0: print dbselect + ' sdf database file missing from ' + dbdir + '. Please make sure file ' + dbselect + '.sdf is there..' dbf1 = False else: dbf1 = dbdir + dbsdf[0] if len(dbfs) == 0: print dbselect + ' fastsearch database file missing from ' + dbdir + '. Please make sure file ' + dbselect + '.fs is there, it speeds up search significantly..' dbf2 = False else: dbf2 = dbdir + dbfs[0] return [dbf1, dbf2]
def setupdb(dbselect): globs = globalvars() dbdir = os.path.relpath(globs.chemdbdir) + '/' # get files in directory dbfiles = os.listdir(dbdir) # search for db files dbmatches = [dbf for dbf in dbfiles if dbselect.lower() in dbf.lower()] dbsdf = [dbm for dbm in dbmatches if '.sdf' in dbm] dbfs = [dbm for dbm in dbmatches if '.fs' in dbm] # print('thefile list' + str(dbfiles)) if len(dbsdf) == 0: print dbselect + ' sdf database file missing from ' + dbdir + '. Please make sure file ' + dbselect + '.sdf is there..' dbf1 = False else: dbf1 = dbdir + dbsdf[0] if len(dbfs) == 0: print dbselect + ' fastsearch database file missing from ' + dbdir + '. Please make sure file ' + dbselect + '.fs is there, it speeds up search significantly..' dbf2 = False else: dbf2 = dbdir + dbfs[0] return [dbf1, dbf2]
def parseall(parser): globs = globalvars() parser.add_argument("-i", help="input file") # hidden (non-user) arguments for GUI parser.add_argument("-rprompt", help=argparse.SUPPRESS,action="store_true") parser.add_argument("-gui", help=argparse.SUPPRESS,action="store_true") # gui placeholder parser.add_argument("-checkdirb", help="CLI only: automatically ignore warning to replace existing folder", action="store_true") parser.add_argument("-checkdirt", action="store_true") # directory removal check flag (what does this actually do?) args=parser.parse_args() parseinputs_basic(parser,args) parseinputs_advanced(parser,args) parseinputs_slabgen(parser,args) parseinputs_autocorr(parser,args) parseinputs_chainb(parser,args) parseinputs_db(parser,args) parseinputs_inputgen(parser,args) parseinputs_postproc(parser,args) parseinputs_random(parser,args) parseinputs_binding(parser,args) parseinputs_customcore(parser,args) parseinputs_naming(parser,args) return args
def bind_load(userbind, bindcores): globs = globalvars() if '~' in userbind: homedir = os.path.expanduser("~") userbind = userbind.replace('~', homedir) emsg = False bind = mol3D() # initialize binding molecule bsmi = False # flag for smiles ### check if binding molecule exists in dictionary if userbind in bindcores.keys(): # load bind mol file (with hydrogens) # fbind = installdir+'Bind/'+bindcores[userbind][0] if globs.custom_path: fbind = globs.custom_path + "/Bind/" + bindcores[userbind][0] else: fbind = resource_filename( Requirement.parse("molSimplify"), "molSimplify/Bind/" + bindcores[userbind][0]) # check if bind xyz/mol file exists if not glob.glob(fbind): emsg = "We can't find the binding species structure file %s right now! Something is amiss. Exiting..\n" % fbind print emsg return False, False, emsg if ('.xyz' in fbind): bind.OBMol = bind.getOBMol(fbind, 'xyzf') elif ('.mol' in fbind): bind.OBMol = bind.getOBMol(fbind, 'molf') elif ('.smi' in fbind): bind.OBMol = bind.getOBMol(fbind, 'smif') bind.charge = bind.OBMol.GetTotalCharge() ### load from file elif ('.mol' in userbind or '.xyz' in userbind or '.smi' in userbind): if glob.glob(userbind): ftype = userbind.split('.')[-1] # try and catch error if conversion doesn't work try: bind.OBMol = bind.getOBMol(userbind, ftype + 'f') # convert from file bind.charge = bind.OBMol.GetTotalCharge() except IOError: emsg = 'Failed converting file ' + userbind + ' to molecule..Check your file.\n' return False, emsg bind.ident = userbind.rsplit('/')[-1] bind.ident = bind.ident.split('.' + ftype)[0] else: emsg = 'Binding species file ' + userbind + ' does not exist. Exiting..\n' return False, emsg ### if not, try converting from SMILES else: # check for transition metals userbind = checkTMsmiles(userbind) # try and catch error if conversion doesn't work try: bind.OBMol = bind.getOBMol(userbind, 'smi') # convert from smiles bind.charge = bind.OBMol.GetTotalCharge() bsmi = True bind.ident = 'smi' except IOError: emsg = "We tried converting the string '%s' to a molecule but it wasn't a valid SMILES string.\n" % userbind emsg += "Furthermore, we couldn't find the binding species structure: '%s' in the binding species dictionary. Try again!\n" % userbind print emsg return False, False, emsg return bind, bsmi, emsg
def lig_load(userligand, licores=None): if licores == None: licores = getlicores() #@licores.pop("x", None) globs = globalvars() ### get groups ### groups = [] for entry in licores: groups += licores[entry][3] groups = sorted(list(set(groups))) # check if user requested group if userligand.lower() in groups: subligs = [ key for key in licores if userligand.lower() in licores[key][3] ] # randomly select ligand userligand = random.choice(subligs) if '~' in userligand: homedir = os.path.expanduser("~") userligand = userligand.replace('~', homedir) emsg = False lig = mol3D() # initialize ligand molecule lig.needsconformer = False ### check if ligand exists in dictionary if userligand in licores.keys(): print('loading ligand from dictionary: ' + str(userligand)) dbentry = licores[userligand] # load lig mol file (with hydrogens) if globs.custom_path: flig = globs.custom_path + "/Ligands/" + dbentry[0] else: flig = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Ligands/" + dbentry[0]) # check if ligand xyz/mol file exists #print('looking for '+flig) if not glob.glob(flig): emsg = "We can't find the ligand structure file %s right now! Something is amiss. Exiting..\n" % flig print emsg return False, emsg if ('.xyz' in flig): lig.OBMol = lig.getOBMol(flig, 'xyzf') elif ('.mol' in flig): lig.OBMol = lig.getOBMol(flig, 'molf') elif ('.smi' in flig): print('SMILES conversion') lig.OBMol = lig.getOBMol(flig, 'smif') lig.needsconformer = True ### modified the check for length, ### as it parsing string length instead of ### list length! if isinstance(dbentry[2], (str, unicode)): lig.denticity = 1 else: lig.denticity = len(dbentry[2]) lig.ident = dbentry[1] lig.charge = lig.OBMol.GetTotalCharge() if 'pi' in dbentry[2]: lig.cat = [int(l) for l in dbentry[2][:-1]] lig.cat.append('pi') else: if lig.denticity == 1: lig.cat = [int(dbentry[2])] else: lig.cat = [int(l) for l in dbentry[2]] if lig.denticity > 1: lig.grps = dbentry[3] else: lig.grps = [] if len(dbentry) > 3: lig.ffopt = dbentry[4][0] ### load from file elif ('.mol' in userligand or '.xyz' in userligand or '.smi' in userligand or '.sdf' in userligand): #flig = resource_filename(Requirement.parse("molSimplify"),"molSimplify/" +userligand) if glob.glob(userligand): ftype = userligand.split('.')[-1] # try and catch error if conversion doesn't work try: print('ligand is an ' + ftype + ' file') lig.OBMol = lig.getOBMol(userligand, ftype + 'f') # convert from file # generate coordinates if not existing lig.charge = lig.OBMol.GetTotalCharge() print('Ligand successfully converted to OBMol') except IOError: emsg = 'Failed converting file ' + userligand + ' to molecule..Check your file.\n' return False, emsg lig.ident = userligand.rsplit('/')[-1] lig.ident = lig.ident.split('.' + ftype)[0] else: emsg = 'Ligand file ' + userligand + ' does not exist. Exiting..\n' print emsg return False, emsg ### if not, try interpreting as SMILES string else: try: lig.getOBMol(userligand, 'smistring', True) # convert from smiles lig.convert2mol3D() assert lig.natoms lig.charge = lig.OBMol.GetTotalCharge() print('Ligand successfully interpreted as SMILES') except: emsg = "We tried converting the string '%s' to a molecule but it wasn't a valid SMILES string.\n" % userligand emsg += "Furthermore, we couldn't find the ligand structure: '%s' in the ligands dictionary. Try again!\n" % userligand emsg += "\nAvailable ligands are: %s\n" % getligs() emsg += "\nAnd available groups are: %s\n" % getligroups(licores) print emsg return False, emsg lig.ident = 'smi' lig.needsconformer = True lig.name = userligand return lig, emsg
def substr_load(usersubstrate, sub_i, subcatoms, subcores=None): if subcores == None: subcores = getsubcores() globs = globalvars() if '~' in usersubstrate: homedir = os.path.expanduser("~") usersubstrate = usersubstrate.replace('~', homedir) emsg = False sub = mol3D() # initialize core molecule ### check if substrate exists in dictionary if usersubstrate.lower() in [i.subname for i in subcores.keys()]: print('loading substrate from dictionary') # create a list for each item column in the dictionary var_list = [] for var in [ subcores[i][0:] for i in subcores.keys() if i.subname == usersubstrate.lower() ]: var_list.append(var) var_list = sorted(var_list) var_list_sub_i = var_list[sub_i] if globs.custom_path: fsubst = globs.custom_path + "/Substrates/" + var_list_sub_i[0] else: fsubst = resource_filename( Requirement.parse("molSimplify"), "molSimplify/Substrates/" + var_list_sub_i[0]) # check if substrate xyz/mol file exists if not glob.glob(fsubst): emsg = "We can't find the substrate structure file %s right now! Something is amiss. Exiting..\n" % fcore print emsg return False, emsg if ('.xyz' in fsubst): sub.OBMol = sub.getOBMol(fsubst, 'xyzf') elif ('.mol' in fsubst): sub.OBMol = sub.getOBMol(fsubst, 'molf') elif ('.smi' in fsubst): sub.OBMol = sub.getOBMol(fsubst, 'smif') # Parsing substrate denticity ### modified the check for length, ### as it parsing string length instead of ### list length! if isinstance(var_list_sub_i[2], (str, unicode)): sub.denticity = 1 else: sub.denticity = len(var_list_sub_i[2]) # Parsing substrate identity sub.ident = var_list_sub_i[1] # Parsing substrate charge sub.charge = sub.OBMol.GetTotalCharge() # Parsing substrate connection atoms if 'pi' in var_list_sub_i[2]: sub.denticity = 1 sub.cat = [int(l) for l in var_list_sub_i[2][:-1]] sub.cat.append('pi') else: if sub.denticity == 1: sub.cat = [int(var_list_sub_i[2])] else: sub.cat = [int(l) for l in var_list_sub_i[2]] if not subcatoms: subcatoms = sub.cat # Parsing substrate group sub.grps = var_list_sub_i[3] if len(var_list_sub_i[4]) > 0: sub.ffopt = var_list_sub_i[4] ### load from file elif ('.mol' in usersubstrate or '.xyz' in usersubstrate or '.smi' in usersubstrate): if glob.glob(usersubstrate): ftype = usersubstrate.split('.')[-1] print('Substrate is a ' + ftype + ' file') # try and catch error if conversion doesn't work try: sub.OBMol = sub.getOBMol(usersubstrate, ftype + 'f') # convert from file print('Substrate successfully converted to OBMol') except IOError: emsg = 'Failed converting file ' + usersubstrate + ' to molecule..Check your file.\n' print emsg return False, emsg sub.ident = usersubstrate.split('.')[0] sub.ident = sub.ident.rsplit('/')[-1] else: emsg = 'Substrate file ' + usersubstrate + ' does not exist. Exiting..\n' print emsg return False, emsg ### if not, try converting from SMILES else: # check for transition metals usersubstrate = checkTMsmiles(usersubstrate) # try and catch error if conversion doesn't work try: sub.OBMol = sub.getOBMol(usersubstrate, 'smistring', True) # convert from smiles print('Substrate successfully interpreted as smiles') except IOError: emsg = "We tried converting the string '%s' to a molecule but it wasn't a valid SMILES string.\n" % usercore emsg += "Furthermore, we couldn't find the substrate structure: '%s' in the substrates dictionary. Try again!\n" % usercore emsg += "\nAvailable substrates are: %s\n" % getsubstrates() print emsg return False, emsg sub.cat = [0] sub.denticity = 1 sub.ident = 'substrate' return sub, subcatoms, emsg
def core_load(usercore, mcores=None): if mcores == None: mcores = getmcores() globs = globalvars() if '~' in usercore: homedir = os.path.expanduser("~") usercore = usercore.replace('~', homedir) emsg = False core = mol3D() # initialize core molecule ### check if core exists in dictionary if usercore.lower() in mcores.keys(): #print('loading core from dictionary') dbentry = mcores[usercore.lower()] # load core mol file (with hydrogens if globs.custom_path: fcore = globs.custom_path + "/Cores/" + dbentry[0] else: fcore = resource_filename(Requirement.parse("molSimplify"), "molSimplify/Cores/" + dbentry[0]) # check if core xyz/mol file exists if not glob.glob(fcore): emsg = "We can't find the core structure file %s right now! Something is amiss. Exiting..\n" % fcore print emsg return False, emsg if ('.xyz' in fcore): core.OBMol = core.getOBMol(fcore, 'xyzf') elif ('.mol' in fcore): core.OBMol = core.getOBMol(fcore, 'molf') elif ('.smi' in fcore): core.OBMol = core.getOBMol(fcore, 'smif') core.cat = [int(l) for l in filter(None, dbentry[1])] core.denticity = dbentry[2] core.ident = usercore ### load from file elif ('.mol' in usercore or '.xyz' in usercore or '.smi' in usercore): if glob.glob(usercore): ftype = usercore.split('.')[-1] print('Core is a ' + ftype + ' file') # try and catch error if conversion doesn't work try: core.OBMol = core.getOBMol(usercore, ftype + 'f') # convert from file print('Core successfully converted to OBMol') except IOError: emsg = 'Failed converting file ' + usercore + ' to molecule..Check your file.\n' print emsg return False, emsg core.ident = usercore.split('.')[0] core.ident = core.ident.rsplit('/')[-1] else: emsg = 'Core file ' + usercore + ' does not exist. Exiting..\n' print emsg return False, emsg ### if not, try converting from SMILES else: # check for transition metals usercore = checkTMsmiles(usercore) # try and catch error if conversion doesn't work try: core.OBMol = core.getOBMol(usercore, 'smistring', True) # convert from smiles print('Core successfully interpreted as smiles') except IOError: emsg = "We tried converting the string '%s' to a molecule but it wasn't a valid SMILES string.\n" % usercore emsg += "Furthermore, we couldn't find the core structure: '%s' in the cores dictionary. Try again!\n" % usercore emsg += "\nAvailable cores are: %s\n" % getcores() print emsg return False, emsg core.cat = [0] core.denticity = 1 core.ident = 'core' return core, emsg
def checkTMsmiles(smi): g = globalvars() for m in g.metals(): if m in smi: smi = smi.replace(m, '[' + m + ']') return smi
def mlpgen(args, strfiles, rootdir): # get global variables globs = globalvars() jobdirs = [] coordfs = [] # Initialize the jobparams dictionary with mandatory/useful keywords. jobparams = ['EF', 'PM7', 'XYZ', 'HESSIAN'] spin_keywords = { 1: 'SINGLET', 2: 'DOUBLET', 3: 'TRIPLET', 4: 'QUARTET', 5: 'QUINTET', 6: 'SEXTET', 7: 'SEPTET' } # Overwrite plus add any new dictionary keys from commandline input. for xyzf in strfiles: rdir = xyzf.rsplit('/', 1)[0] xyzft = xyzf.rsplit('/', 1)[-1] xyzf += '.xyz' coordfs.append(xyzf.rsplit('/', 1)[-1]) coordname = xyzft # Setting jobname for files + truncated name for queue. nametrunc = coordname if not os.path.exists(rdir + '/' + nametrunc) and not args.jobdir: os.mkdir(rdir + '/' + nametrunc) if args.jobdir: mdir = args.jobdir else: mdir = rdir + '/' + nametrunc jobdirs.append(mdir) # shutil.copy2(xyzf,mdir) # shutil.copy2(xyzf.replace('.xyz','.molinp'),mdir.replace('.xyz','.molinp')) # Just carry over spin and charge keywords if they're set. Could do checks, none for now. if args.spin: jobparams.append(spin_keywords[int(args.spin)]) jobparams.append('UHF') else: jobparams.append("SINGLET") if args.charge: jobparams.append('CHARGE=' + str(args.charge)) # Now we're ready to start building the input file and the job script for i, jobd in enumerate(jobdirs): output = open(strfiles[i] + '.mop', 'w') f = open(strfiles[i] + '.xyz') s = f.readlines()[2:] # read coordinates f.close() # write rem block for terms in jobparams: output.write(' ' + terms) # write additional options if (args.remoption): if len(args.remoption) % 2 > 0: print('WARNING: wrong number of arguments in -remoption') else: for elem in range(0, int(0.5 * len(args.remoption))): key, val = args.remoption[2 * elem], args.remoption[2 * elem + 1] output.write(key + '\t\t' + val + '\n') output.write('\n' + nametrunc + '\n') output.write('\n') # write $molecule block for lines in s: ll = lines.split('\t') for i, items in enumerate(ll): output.write(' ' + items.strip('\n')) if i > 0: output.write(' 1') if i == 3: output.write('\n') output.close() return jobdirs
def qgen(args, strfiles, method): # get global variables globs = globalvars() jobdirs = [] coordfs = [] # Initialize the jobparams dictionary with mandatory/useful keywords. jobparams = { 'UNRESTRICTED': 'true', 'BASIS': 'lanl2dz', 'JOBTYPE': 'opt', 'EXCHANGE': 'b3lyp', 'CORRELATION': 'none', 'MAX_SCF_CYCLES': '500', 'GEOM_OPT_MAX_CYCLES': '1000', 'SYMMETRY': 'off', 'PRINT_ORBITALS': 'true', 'CHARGE': '1', 'SPIN': '1', } # Overwrite plus add any new dictionary keys from commandline input. for xyzf in strfiles: rdir = xyzf.rsplit('/', 1)[0] xyzft = xyzf.rsplit('/', 1)[-1] xyzf += '.xyz' coordfs.append(xyzf.rsplit('/', 1)[-1]) coordname = xyzft # Setting jobname for files + truncated name for queue. if len(coordname) > 10: nametrunc = coordname[0:6] + coordname[-4:] else: nametrunc = coordname if not os.path.exists(rdir + '/' + nametrunc) and not args.jobdir: os.mkdir(rdir + '/' + nametrunc) mdir = rdir + '/' + nametrunc if method: mmd = '/' + method mdir = rdir + '/' + nametrunc + mmd if not os.path.exists(mdir): os.mkdir(mdir) jobdirs.append(mdir) shutil.copy2(xyzf, mdir) shutil.copy2(xyzf.replace('.xyz', '.molinp'), mdir.replace('.xyz', '.molinp')) try: shutil.copy2(xyzf.replace('.xyz', '.report'), mdir.replace('.xyz', '.report')) except: pass # Check for existence of basis and sanitize name if args.basis and len(args.basis) > 1: jobparams['BASIS'] = args.basis if args.correlation and len(args.correlation) > 1: jobparams['CORRELATION'] = args.correlation if method and len(method) > 1: jobparams['EXCHANGE'] = method if not args.unrestricted: jobparams['UNRESTRICTED'] = 'false' if (args.runtyp and 'en' in args.runtyp.lower()): jobparams['run'] = 'SP' elif (args.runtyp and 'ts' in args.runtyp.lower()): jobparams['run'] = 'TS' # Just carry over spin and charge keywords if they're set. Could do checks, none for now. if args.spin: jobparams['SPIN'] = args.spin if args.charge: jobparams['CHARGE'] = args.charge # Now we're ready to start building the input file and the job script for i, jobd in enumerate(jobdirs): output = open(jobd + '/qch.inp', 'w') f = open(jobd + '/' + coordfs[i]) s0 = f.readlines()[2:] # read coordinates f.close() # if separate split to two molecules if args.bsep and '--' in ''.join(s0): idxsplit = [isdx for isdx, ss in enumerate(s0) if '--' in ss][0] s = '--\n' + jobparams['CHARGE'] + ' ' + jobparams['SPIN'] + '\n' s += ''.join(s0[:idxsplit]) s += '--\n0 1\n' s += ''.join(s0[idxsplit + 3:]) else: s = s0 # write rem block output.write('$rem\nUNRESTRICTED\t\t' + jobparams['UNRESTRICTED']) output.write('\nBASIS\t\t' + jobparams['BASIS'] + '\nJOBTYPE\t\t' + jobparams['JOBTYPE']) output.write('\nEXCHANGE\t\t' + jobparams['EXCHANGE'] + '\nCORRELATION\t\t') output.write(jobparams['CORRELATION'] + '\nMAX_SCF_CYCLES\t\t') output.write(jobparams['MAX_SCF_CYCLES'] + '\nGEOM_OPT_MAX_CYCLES\t\t') output.write(jobparams['GEOM_OPT_MAX_CYCLES'] + '\nSYMMETRY\t\t' + jobparams['SYMMETRY']) output.write('\nPRINT_ORBITALS\t\t' + jobparams['PRINT_ORBITALS'] + '\n') # write additional options if (args.remoption): if len(args.remoption) % 2 > 0: print('WARNING: wrong number of arguments in -remoption') else: for elem in range(0, int(0.5 * len(args.remoption))): key, val = args.remoption[2 * elem], args.remoption[2 * elem + 1] output.write(key + '\t\t' + val + '\n') output.write('$end\n\n') # write $molecule block output.write('$molecule\n' + jobparams['CHARGE'] + ' ' + jobparams['SPIN'] + '\n') output.write(''.join(s) + '$end') output.close() return jobdirs
def startgen(argv,flag,gui): emsg = False # check for configuration file homedir = os.path.expanduser("~") #configfile = False if not glob.glob(homedir+'/.molSimplify') else True #if not configfile: # print "It looks like the configuration file '~/.molSimplify' does not exist!Please follow the next steps to configure the file." # instdir = raw_input("Please select the full path of the top installation directory for the program: ") # cdbdir = raw_input("Please specify the full path of the directory containing chemical databases:") # mwfn = raw_input("Specify the full path to the Multiwfn executable (for post-processing):") # f = open(homedir+'/.molSimplify','w') # if len(instdir) > 1: # f.write("INSTALLDIR="+instdir+'\n') # if len(cdbdir) > 1: # f.write("CHEMDBDIR="+cdbdir+'\n') # if len(mwfn) > 1 : # f.write("MULTIWFN="+mwfn[0]+'\n') # f.close() ### end set-up configuration file ### ############ GLOBALS DEFINITION ############ globs = globalvars() #installdir = globs.installdir rundir = globs.rundir PROGRAM = globs.PROGRAM ###### END GLOBALS DEFINITION ############## # correct installdir #if installdir[-1]!='/': # installdir+='/' # print welcome message ss = "\n************************************************************" ss += "\n******** Welcome to "+PROGRAM+"! Let's get started. ********\n" ss += "************************************************************\n\n" if not flag: print ss sys.argv = argv parser = argparse.ArgumentParser() args = parseall(parser) # check if input file exists if not glob.glob(args.i): emsg = 'Input file '+args.i+' does not exist. Please specify a valid input file.\n' print emsg return emsg args.gui = gui # add gui flag # parse input file if args.i: parseinputfile(args) if args.cdxml: print 'converting cdxml file into xyz' cdxml = args.cdxml[0] fname, msg = loadcdxml(cdxml) print(msg) if 'two' in msg: core = fname + '_cat.xyz' sub = fname + '_sub.xyz' args.core = [core] args.substrate = [sub] args.tsgen = True # if not args.postp and not args.dbsearch and not args.dbfinger and not args.drawmode and not (args.slab_gen or args.place_on_slab) and not (args.chain) and not (args.correlate): # check input arguments if not args.postp and not args.dbsearch and not args.dbfinger and not (args.slab_gen or args.place_on_slab) and not (args.chain) and not (args.correlate): # check input arguments # check input arguments print 'Checking input...' if args.tsgen: emsg = checkinput(args,calctype="tsgen") elif args.ligadd: emsg = checkinput(args,calctype="dbadd") else: emsg = checkinput(args) # check before cleaning input arguments and clean only if checked cleaninput(args) args.gui = False # deepcopy will give error if emsg: del args return emsg # check for jobs directory rundir = args.rundir+'/' if (args.rundir) else rundir if not os.path.isdir(rundir): os.mkdir(rundir) ################### START MAIN #################### args0 = copy.deepcopy(args) # save initial arguments # add gui flag args.gui = gui # postprocessing run? if (args.postp): postproc(rundir,args,globs) # database search? elif (args.dbsearch or args.dbfinger): emsg = dbsearch(rundir,args,globs) if emsg: del args return emsg else: print 'Successful database search!\n' # random generation? elif (args.rgen): # check if random generation was requested if args.charge: args.charge = args.charge[0] if args.spin: args.spin = args.spin[0] corests=args.core for cc in corests: args = copy.deepcopy(args0) # add gui flag args.gui = gui args.core = cc if (args.lig or args.coord or args.lignum or args.ligocc): # constraints given? args, emsg = constrgen(rundir,args,globs) if emsg: del args return emsg else: emsg = 'For random generation specify at least a ligand, coordination or ligand types.\n' print emsg del args return emsg #elif args.drawmode: # emsg = draw_supervisor(args,rundir) # slab/place on slab? elif (args.slab_gen or args.place_on_slab): emsg = slab_module_supervisor(args,rundir) # chain builder elif (args.chain): print('chain on') emsg = chain_builder_supervisor(args,rundir) # correlation analysis elif (args.correlate): print('analysis is looking for correlations') analysis_supervisor(args,rundir) # add ligand to list elif (args.ligadd): print('adding ' +str(args.ligadd) + ' to ligand database with name ' + args.ligname + ' and connection atom(s) ' + str(args.ligcon)) addtoldb(smimol=args.ligadd.decode('utf-8'),sminame=args.ligname.decode('utf-8'),smident = len(args.ligcon),smicat=str(args.ligcon).strip('[]').decode('utf-8'),smigrps ="custom",smictg="custom",ffopt=args.ligffopt) # normal structure generation or transition state building else: args = copy.deepcopy(args0) # add gui flag args.gui = gui corests=args.core # if args.tsgen: # goes through multigenruns for maximum interoperability # print('building a transition state') if args.tsgen: # goes through multigenruns for maximum interoperability print('building a transition state') else: print('building an equilibrium complex') for cc in corests: args.core = cc emsg = multigenruns(rundir,args,globs) if emsg: print emsg del args return emsg ss = "\n**************************************************************" ss += "\n***** Thank you for using "+PROGRAM+". Have a nice day! ******\n" ss += "**************************************************************" ss += globs.about if not flag: print ss del args return emsg
''' # Written by the HJK Group # Dpt of Chemical Engineering, MIT ########################################################## ############ Main script that coordinates ############## ############# all parts of the program ################ ########################################################## import sys, argparse, os, platform, shutil from Scripts.inparse import * from Scripts.generator import * from molSimplify.Classes.globalvars import * globs = globalvars() DescString_basic = 'Welcome to molSimplify. Only basic usage is described here.\n' DescString_basic += 'For help on advanced modules, please refer to our documentation at WEBLINK or provide additional commands to -h, as below:\n' DescString_basic += '-h advanced: advanced structure generation help\n' DescString_basic += '-h slabgen: slab builder help\n' #DescString_basic += '-h chainb: chain builder help\n' DescString_basic += '-h autocorr: automated correlation analysis help\n' DescString_basic += '-h db: database search help\n' DescString_basic += '-h inputgen: quantum chemistry code input file generation help\n' DescString_basic += '-h postproc: post-processing help\n' DescString_basic += '-h random: random generation help\n' DescString_basic += '-h binding: binding species (second molecule) generation help\n' DescString_basic += '-h customcore: custom core functionalization help\n' DescString_basic += '-h naming: custom filename help\n' DescString_advanced = 'Printing advanced structure generation help.'
def removefromDB(sminame,ropt): emsg = False globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print('To database, you need to set a custom path. Please enter a writeable file path:') new_path = input('path=') globs.add_custom_path(new_path) copy_to_custom_path() li_path = globs.custom_path + "/Ligands/ligands.dict" li_folder = globs.custom_path + "/Ligands/" core_path = globs.custom_path + "/Cores/cores.dict" core_dir = globs.custom_path + "/Cores/" bind_path = globs.custom_path + "/Bind/bind.dict" bind_folder = globs.custom_path +"/Bind/" # convert to unicode sminame = unicodedata.normalize('NFKD',sminame).encode('ascii','ignore') if ropt==1: # update dictionary f = open(li_path,'r') ss = f.read().splitlines() f.close() f = open(li_path,'w') ssort = sorted(ss[1:]) f.write(ss[0]+'\n') for s in ssort: sss = s.split(':') if sminame!=sss[0]: f.write(s+'\n') else: os.remove(li_folder + sss[1].split(',')[0]) f.close() elif ropt==0: mcores = readdict(core_path) # update dictionary f = open(core_path,'r') ss = f.read().splitlines() f.close() f = open(core_path,'w') ssort = sorted(ss[1:]) f.write(ss[0]+'\n') for s in ssort: sss = s.split(':') if sminame!=sss[0]: f.write(s+'\n') else: os.remove(core_folder+sss[1].split(',')[0]) f.close() elif ropt==2: bindcores = readdict(bind_path) # update dictionary f = open(bind_path,'r') ss = f.read().splitlines() f.close() f = open(bind_path,'w') ssort = sorted(ss[1:]) f.write(ss[0]+'\n') for s in ssort: sss = s.split(':') if sminame!=sss[0]: f.write(s+'\n') else: os.remove(bind_folder+sss[1].split(',')[0]) f.close() return emsg
def removefromDB(sminame, ropt): emsg = False globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print( 'To database, you need to set a custom path. Please enter a writeable file path:' ) new_path = eval(input('path=')) globs.add_custom_path(new_path) copy_to_custom_path() li_path = globs.custom_path + "/Ligands/ligands.dict" li_folder = globs.custom_path + "/Ligands/" core_path = globs.custom_path + "/Cores/cores.dict" core_dir = globs.custom_path + "/Cores/" bind_path = globs.custom_path + "/Bind/bind.dict" bind_folder = globs.custom_path + "/Bind/" # convert to unicode sminame = unicodedata.normalize('NFKD', sminame).encode('ascii', 'ignore').decode() if ropt == 1: # update dictionary f = open(li_path, 'r') ss = f.read().splitlines() f.close() f = open(li_path, 'w') ssort = sorted(ss[1:]) f.write(ss[0] + '\n') for s in ssort: sss = s.split(':') if sminame != sss[0]: f.write(s + '\n') else: os.remove(li_folder + sss[1].split(',')[0]) f.close() elif ropt == 0: mcores = readdict(core_path) # update dictionary f = open(core_path, 'r') ss = f.read().splitlines() f.close() f = open(core_path, 'w') ssort = sorted(ss[1:]) f.write(ss[0] + '\n') for s in ssort: sss = s.split(':') if sminame != sss[0]: f.write(s + '\n') else: os.remove(core_folder + sss[1].split(',')[0]) f.close() elif ropt == 2: bindcores = readdict(bind_path) # update dictionary f = open(bind_path, 'r') ss = f.read().splitlines() f.close() f = open(bind_path, 'w') ssort = sorted(ss[1:]) f.write(ss[0] + '\n') for s in ssort: sss = s.split(':') if sminame != sss[0]: f.write(s + '\n') else: os.remove(bind_folder + sss[1].split(',')[0]) f.close() return emsg
def molcgen(args, strfiles, method): # global variables globs = globalvars() jobdirs = [] coordfs = [] # Initialize the jobparams dictionary with mandatory/useful keywords. TG: removed min_coordinates cartesian jobparams = { 'Group': 'Nosym', 'method': 'CASSCF', 'spin': '1', 'charge': '0', # 'nactel':'2', # 'frozen':'0', # 'ras2':'12', 'ciroot': '1 1 ;1', 'ITER': '1000,100', 'multistate': '1 1', 'imaginary': '0.1', 'ipeashift': '0.25', 'density': 'no', 'grid_it': 'no', 'gridtype': 'TOTAL', 'NPOINTS': '100 100 100', } # if multiple methods requested generate c directories # Overwrite plus add any new dictionary keys from commandline input. for xyzf in strfiles: rdir = xyzf.rsplit('/', 1)[0] xyzft = xyzf.rsplit('/', 1)[-1] xyzf += '.xyz' coordfs.append(xyzf.rsplit('/', 1)[-1]) coordname = xyzft # Setting jobname for files + truncated name for queue. if len(coordname) > 10: nametrunc = coordname else: nametrunc = coordname if not os.path.exists(rdir + '/' + nametrunc) and not args.jobdir: os.mkdir(rdir + '/' + nametrunc) mdir = rdir + '/' + nametrunc if method: if method[0] == 'U' or method[0] == 'u': mmd = '/' + method[1:] else: mmd = '/' + method mdir = rdir + '/' + nametrunc + mmd if not os.path.exists(mdir): try: os.mkdirs(mdir) except: pass if not args.jobdir: jobdirs.append(mdir) shutil.copy2(xyzf, mdir) shutil.copy2(xyzf.replace('.xyz', '.molinp'), mdir.replace('.xyz', '.molinp')) try: shutil.copy2(xyzf.replace('.xyz', '.report'), mdir.replace('.xyz', '.report')) except: pass elif args.jobdir: jobdirs.append(rdir) # parse extra arguments # Method parsing, does not check if a garbage method is used here: if method: jobparams['method'] = method else: jobparams['method'] = 'CASSCF' print((args.method, method, jobparams['method'])) # Check runtype if (args.runtyp and 'energy' in args.runtyp.lower()): jobparams['run'] = 'energy' else: print( '''Warning! Currently MOLCAS input file generation is only supported for single point energy. For other types of calculation requested, the input file is generated for single point energy instead''') # Just carry over spin and charge keywords if they're set. Could do checks, none for now. if args.spin: jobparams['spin'] = str(args.spin) if args.charge: if args.bcharge: args.charge = int(args.charge) + int(args.bcharge) jobparams['charge'] = str(args.charge) # Check for existence of basis and sanitize name # Automatically assign basis based on element if args.basis and args.basis != 'lacvps_ecp': jobparams['basis'] = args.basis elif (not args.basis) or args.basis == 'lacvps_ecp': temp = mol3D() jobparams['basis'] = molcbasis(strfiles, 'ANO-rcc') # Overwrite plus add any new dictionary keys from commandline input. if args.qoption: if len(args.qoption) % 2 != 0: print('WARNING: wrong number of arguments in -qoption') else: for elem in range(0, int(0.5 * len(args.qoption))): key, val = args.qoption[2 * elem], args.qoption[2 * elem + 1] jobparams[key] = val # Check which paramters are missing # Check and automatically assign number of active electrons if 'nactel' not in jobparams: oxnum = 0 # oxidation state number if args.oxstate in list(romans.keys()): oxnum = int(romans[args.oxstate]) else: oxnum = int(args.oxstate) jobparams['nactel'] = molcnactels(strfiles, oxnum) else: nactel = int(jobparams['nactel']) jobparams['nactel'] = [nactel for i in range(0, len(strfiles))] # Check and automatically assign number of frozen orbitals for CASSCF if 'frozen' not in jobparams: jobparams['frozen'] = molcfrozens(strfiles) else: frozen = int(jobparams['frozen']) jobparams['frozen'] = [frozen for i in range(0, len(strfiles))] # Check and automatically assign number of frozen orbitals for ras2 if 'ras2' not in jobparams: jobparams['ras2'] = molcras2s(strfiles) else: ras2 = int(jobparams['ras2']) jobparams['ras2'] = [ras2 for i in range(0, len(strfiles))] # Check key for grid_it. Overwrite the default in case # the command line input is in different case for key in list(jobparams.keys()): if 'grid_it' in key.lower() and key != 'grid_it': jobparams['grid_it'] = jobparams[key] break # Now we're ready to start building the input file if not args.jobdir: for i, jobd in enumerate(jobdirs): output = open(jobd + '/molcas.input', 'w') output.write('# file created with %s\n' % globs.PROGRAM) molcwrt(output, jobparams, coordfs[i], i) output.close() elif args.jobdir: for i, jobd in enumerate(jobdirs): print(('jobd is ' + jobd)) output = open(jobd + '/molcas.input', 'w') output.write('# file created with %s\n' % globs.PROGRAM) molcwrt(output, jobparams, coordfs[i], i) output.close() return jobdirs
def plugin_defs(): globs = globalvars() plugin_path = resource_filename(Requirement.parse("molSimplify"), "molSimplify/plugindefines_reference.txt") return plugin_path
def dissim(outf, n): globs = globalvars() obab = 'babel' # clone hitlist file hit_list_path = "hitlist.smi" with open(outf) as f: smiles_list = f.readlines() with open(hit_list_path, 'w') as f: f.writelines(smiles_list) # generate fs of original hit list mybash(obab + ' -ismi ' + hit_list_path + ' -osdf tmp.sdf') mybash(obab + ' tmp.sdf -ofs') # number of hits numcpds = mybash('obabel tmp.sdf -onul') numcpds = int(numcpds.split(None)[0]) # pick first element of list mybash('obabel tmp.sdf -O 1.smi -f 1 -l 1') del smiles_list[0] with open(hit_list_path, 'w') as f: f.writelines(smiles_list) # recompute the fs and number of hits parameters numcpds += -1 # decrease number of hits mybash(obab + ' -ismi ' + hit_list_path + ' -osdf tmp.sdf') mybash(obab + ' tmp.sdf -ofs') print 'Performing dissimilarity search:' mostdissim = [] if n > 1: # find most dissimilar structure for i in range(n - 1): # initialize list of total similarities simsum = [0] * numcpds # compute total similarity of each dissimilar structure with hit list for j in range(i + 1): a = mybash('obabel ' + str(j + 1) + '.smi tmp.sdf -ofpt') a = a.splitlines() a = [s.split('= ') for s in a] a = [item for sublist in a for item in sublist] aa = [] for k in a: try: aa.append(float(k)) except: pass a = aa simsum = [x + y for x, y in zip(simsum, a)] # pick most dissimilar structure by greedily minimizing total similarity mostdissim = simsum.index(min(simsum)) mybash('obabel tmp.sdf -O ' + str(i + 2) + '.smi -f ' + str(mostdissim + 1) + ' -l' + str(mostdissim + 1)) # remove most dissimilar from the list and re-write the smi file del smiles_list[mostdissim] with open(hit_list_path, 'w') as f: f.writelines(smiles_list) # recompute the fs and number of hits parameters numcpds += -1 # decrease number of hits mybash(obab + ' -ismi ' + hit_list_path + ' -osdf tmp.sdf') mybash(obab + ' tmp.sdf -ofs') # combine results into one file f = open('dissimres.smi', 'w') for i in range(n): ff = open(str(i + 1) + '.smi', 'r') s = ff.read().splitlines() ff.close() f.write(s[0] + '\n') os.remove(str(i + 1) + '.smi') f.close() return 0
def gamgen(args, strfiles, method): # get global variables globs = globalvars() jobdirs = [] coordfs = [] # Initialize the jobparams dictionary with mandatory/useful keywords. jobparams = { 'RUNTYP': 'OPTIMIZE', 'GBASIS': 'N21', 'MAXIT': '500', 'DFTTYP': 'B3LYP', 'SCFTYP': 'UHF', 'ICHARG': '0', 'MULT': '1', } # Overwrite plus add any new dictionary keys from commandline input. for xyzf in strfiles: # convert to "gamess format" xyzf = xyz2gxyz(xyzf + '.xyz') rdir = xyzf.rsplit('/', 1)[0] xyzft = xyzf.rsplit('/', 1)[-1] xyzf += '.gxyz' coordfs.append(xyzf) coordname = xyzft # Setting jobname for files + truncated name for queue. if len(coordname) > 10: nametrunc = coordname[0:6] + coordname[-4:] else: nametrunc = coordname if not os.path.exists(rdir + '/' + nametrunc): os.mkdir(rdir + '/' + nametrunc) mdir = rdir + '/' + nametrunc if method: if method[0] == 'U' or method[0] == 'u': mmd = '/' + method[1:] else: mmd = '/' + method jobparams['SCFTYP'] = 'RHF' mdir = rdir + '/' + nametrunc + mmd if not os.path.exists(mdir): os.mkdir(mdir) jobdirs.append(mdir) shutil.copy2(xyzf, mdir) shutil.copy2(xyzf.replace('.gxyz', '.molinp'), mdir.replace('.gxyz', '.molinp')) try: shutil.copy2(xyzf.replace('.xyz', '.report'), mdir.replace('.xyz', '.report')) except: pass if method: if method[0] == 'U' or method[0] == 'u': method = method[1:] # Just carry over spin and charge keywords if they're set. Could do checks, none for now. if args.spin: jobparams['MULT'] = str(args.spin) if args.charge: jobparams['ICHARG'] = str(args.charge) # Check for existence of basis and sanitize name if args.gbasis: jobparams['GBASIS'] = args.gbasis.upper() if args.ngauss: jobparams['NGAUSS'] = args.ngauss.upper() if method: jobparams['DFTTYP'] = method.upper() if (args.runtyp and 'en' in args.runtyp.lower()): jobparams['run'] = 'ENERGY' elif (args.runtyp and 'ts' in args.runtyp.lower()): jobparams['run'] = 'SADPOINT' # Now we're ready to start building the input file and the job script for i, jobd in enumerate(jobdirs): output = open(jobd + '/gam.inp', 'w') f = open(coordfs[i]) s = f.read() # read coordinates f.close() jobparams['coordinates'] = s output.write('! File created using %s\n' % globs.PROGRAM) # write $BASIS block output.write(' $BASIS ') if args.ngauss: output.write(' GBASIS=' + jobparams['GBASIS']) output.write(' NGAUSS=' + jobparams['NGAUSS']) else: output.write(' GBASIS=' + jobparams['GBASIS']) if args.ndfunc: output.write(' NDFUNC=' + args.ndfunc) if args.npfunc: output.write(' NPFUNC=' + args.npfunc) output.write(' $END\n') # write $SYSTEM block output.write(' $SYSTEM ') # check if MWORDS specified by the user if not args.sysoption or not ('MWORDS' in args.sysoption): output.write(' MWORDS=16') # write additional options if (args.sysoption): if len(args.sysoption) % 2 > 0: print('WARNING: wrong number of arguments in -sysoption') else: for elem in range(0, int(0.5 * len(args.sysoption))): key, val = args.sysoption[2 * elem], args.sysoption[2 * elem + 1] output.write(' ' + key + '=' + val + ' ') output.write(' $END\n') # write CONTRL block output.write(' $CONTRL SCFTYP=' + jobparams['SCFTYP'] + ' DFTTYP=') output.write(jobparams['DFTTYP'] + ' RUNTYP=' + jobparams['RUNTYP']) output.write('\n ICHARG=' + jobparams['ICHARG'] + ' MULT=') # check if CC basis set specified and add spherical if 'CC' in jobparams['GBASIS']: output.write(jobparams['MULT'] + ' ISPHER=1\n') else: output.write(jobparams['MULT'] + '\n') # write additional options if (args.ctrloption): if len(args.ctrloption) % 2 > 0: print('WARNING: wrong number of arguments in -ctrloption') else: for elem in range(0, int(0.5 * len(args.ctrloption))): key, val = args.ctrloption[2 * elem], args.ctrloption[2 * elem + 1] output.write(' ' + key + '=' + val + ' ') output.write(' $END\n') # write $SCF block output.write(' $SCF ') # check if options specified by the user if not args.scfoption or not ('DIRSCF' in args.scfoption): output.write(' DIRSCF=.TRUE.') if not args.scfoption or not ('DIIS' in args.scfoption): output.write(' DIIS=.TRUE.') if not args.scfoption or not ('SHIFT' in args.scfoption): output.write(' SHIFT=.TRUE.') # write additional options if (args.scfoption): if len(args.scfoption) % 2 != 0: print('WARNING: wrong number of arguments in -scfoption') else: for elem in range(0, int(0.5 * len(args.scfoption))): key, val = args.scfoption[2 * elem], args.scfoption[2 * elem + 1] output.write(' ' + key + '=' + val + ' ') output.write(' $END\n') # write $STATPT block output.write(' $STATPT ') # check if NSTEP specified by the user if not args.statoption or not ('NSTEP' in args.statoption): output.write(' NSTEP=100') # write additional options if (args.statoption): if len(args.statoption) % 2 > 0: print('WARNING: wrong number of arguments in -statoption') else: for elem in range(0, int(0.5 * len(args.statoption))): key, val = args.statoption[2 * elem], args.statoption[2 * elem + 1] output.write(' ' + key + '=' + val + ' ') output.write(' $END\n') # write $DATA block output.write(' $DATA\n') output.write(jobparams['coordinates'] + ' $END\n') output.close() return jobdirs
def startgen(argv, flag, gui): emsg = False ### check for configuration file ## homedir = os.path.expanduser("~") #configfile = False if not glob.glob(homedir+'/.molSimplify') else True #if not configfile: # print "It looks like the configuration file '~/.molSimplify' does not exist!Please follow the next steps to configure the file." # instdir = raw_input("Please select the full path of the top installation directory for the program: ") # cdbdir = raw_input("Please specify the full path of the directory containing chemical databases:") # mwfn = raw_input("Specify the full path to the Multiwfn executable (for post-processing):") # f = open(homedir+'/.molSimplify','w') # if len(instdir) > 1: # f.write("INSTALLDIR="+instdir+'\n') # if len(cdbdir) > 1: # f.write("CHEMDBDIR="+cdbdir+'\n') # if len(mwfn) > 1 : # f.write("MULTIWFN="+mwfn[0]+'\n') # f.close() ### end set-up configuration file ### ############ GLOBALS DEFINITION ############ globs = globalvars() #installdir = globs.installdir rundir = globs.rundir PROGRAM = globs.PROGRAM ###### END GLOBALS DEFINITION ############## # correct installdir #if installdir[-1]!='/': # installdir+='/' # print welcome message ss = "\n************************************************************" ss += "\n******** Welcome to " + PROGRAM + "! Let's get started. ********\n" ss += "************************************************************\n\n" if not flag: print ss sys.argv = argv parser = argparse.ArgumentParser() args = parseall(parser) # check if input file exists if not glob.glob(args.i): emsg = 'Input file ' + args.i + ' does not exist. Please specify a valid input file.\n' print emsg return emsg args.gui = gui # add gui flag # parse input file if args.i: parseinputfile(args) if not args.postp and not args.dbsearch and not args.dbfinger and not ( args.slab_gen or args.place_on_slab) and not (args.chain) and not ( args.correlate): # check input arguments # check input arguments print 'Checking input...' emsg = checkinput(args) # check before cleaning input arguments and clean only if checked cleaninput(args) args.gui = False # deepcopy will give error if emsg: del args return emsg # check for jobs directory rundir = args.rundir + '/' if (args.rundir) else rundir if not os.path.isdir(rundir): os.mkdir(rundir) ################### START MAIN #################### args0 = copy.deepcopy(args) # save initial arguments # add gui flag args.gui = gui # postprocessing run? if (args.postp): postproc(rundir, args, globs) # database search? elif (args.dbsearch or args.dbfinger): emsg = dbsearch(rundir, args, globs) if emsg: del args return emsg else: print 'Successful database search!\n' # random generation? elif (args.rgen): # check if random generation was requested if args.charge: args.charge = args.charge[0] if args.spin: args.spin = args.spin[0] corests = args.core for cc in corests: args = copy.deepcopy(args0) # add gui flag args.gui = gui args.core = cc if (args.lig or args.coord or args.lignum or args.ligocc): # constraints given? args, emsg = constrgen(rundir, args, globs) if emsg: del args return emsg else: emsg = 'For random generation specify at least a ligand, coordination or ligand types.\n' print emsg del args return emsg # slab/place on slab? elif (args.slab_gen or args.place_on_slab): emsg = slab_module_supervisor(args, rundir) # chain builder elif (args.chain): print('chain on') emsg = chain_builder_supervisor(args, rundir) # correlation analysis elif (args.correlate): print('analysis is looking for correlations') analysis_supervisor(args, rundir) # normal structure generation else: args = copy.deepcopy(args0) # add gui flag args.gui = gui corests = args.core for cc in corests: args.core = cc emsg = multigenruns(rundir, args, globs) if emsg: print emsg del args return emsg ss = "\n**************************************************************" ss += "\n***** Thank you for using " + PROGRAM + ". Have a nice day! ******\n" ss += "**************************************************************" ss += globs.about if not flag: print ss del args return emsg
def tcgen(args, strfiles, method): # global variables # print('----- args provided to tc gen --------') # print(args) globs = globalvars() jobdirs = [] coordfs = [] # Initialize the jobparams dictionary with mandatory/useful keywords. TG: removed min_coordinates cartesian jobparams = { 'run': 'minimize', 'timings': 'yes', 'maxit': '500', 'scrdir': './scr', 'method': 'b3lyp', 'basis': 'lacvps_ecp', 'spinmult': '1', 'charge': '0', 'gpus': '1', } # if multiple methods requested generate c directories # Overwrite plus add any new dictionary keys from commandline input. for xyzf in strfiles: rdir = xyzf.rsplit('/', 1)[0] xyzft = xyzf.rsplit('/', 1)[-1] xyzf += '.xyz' coordfs.append(xyzf.rsplit('/', 1)[-1]) coordname = xyzft # Setting jobname for files + truncated name for queue. if len(coordname) > 10: nametrunc = coordname else: nametrunc = coordname if not os.path.exists(rdir + '/' + nametrunc) and not args.jobdir: os.mkdir(rdir + '/' + nametrunc) mdir = rdir + '/' + nametrunc if method: if method[0] == 'U' or method[0] == 'u': mmd = '/' + method[1:] else: mmd = '/' + method mdir = rdir + '/' + nametrunc + mmd if not os.path.exists(mdir): os.mkdir(mdir) if not args.jobdir: jobdirs.append(mdir) if not args.reportonly: shutil.copy2(xyzf, mdir) shutil.copy2(xyzf.replace('.xyz', '.molinp'), mdir.replace('.xyz', '.molinp')) try: shutil.copy2(xyzf.replace('.xyz', '.report'), mdir.replace('.xyz', '.report')) except: pass elif args.jobdir: jobdirs.append(rdir) # if report only specified, end here if args.reportonly: return jobdirs # parse extra arguments # Method parsing, does not check if a garbage method is used here: unrestricted = False if method: jobparams['method'] = method if ('u' or 'U') in method[0]: # Unrestricted calculation unrestricted = True else: # Restricted calculation unrestricted = False if args.spin and int(args.spin) > 1: jobparams['method'] = 'u' + method unrestricted = True else: if args.spin and int(args.spin) >= 1: jobparams['method'] = 'ub3lyp' unrestricted = True else: jobparams['method'] = 'b3lyp' if (args.runtyp and 'energy' in args.runtyp.lower()): jobparams['run'] = 'energy' elif (args.runtyp and 'ts' in args.runtyp.lower()): jobparams['run'] = 'ts' elif (args.runtyp and 'gradient' in args.runtyp.lower()): jobparams['run'] = 'gradient' if (args.gpus): jobparams['gpus'] = args.gpus if (args.dispersion): jobparams['dispersion'] = args.dispersion # Just carry over spin and charge keywords if they're set. Could do checks, none for now. if args.spin: jobparams['spinmult'] = args.spin if args.charge: if args.bcharge: args.charge = int(args.charge) + int(args.bcharge) jobparams['charge'] = args.charge # Check for existence of basis and sanitize name if args.basis: ecp = False # Flag not currently used, for deciding gpus_ecp code or not later. Can always specify with 'extra' command if '*' in args.basis: jobparams['basis'] = args.basis.replace('*', 's') else: jobparams['basis'] = args.basis # Overwrite plus add any new dictionary keys from commandline input. if args.qoption: if len(args.qoption) % 2 != 0: print('WARNING: wrong number of arguments in -qoption') else: for elem in range(0, int(0.5 * len(args.qoption))): key, val = args.qoption[2 * elem], args.qoption[2 * elem + 1] jobparams[key] = val # Extra keywords for unrestricted. if unrestricted: # If running unrestricted, assume convergence will be more difficult for now. jobparams['scf'] = 'diis+a' if 'levelshift' not in jobparams: jobparams['levelshift'] = 'yes' elif jobparams['levelshift'] != 'yes': print(( "Warning! You're doing an unrestricted calculation but have set levelshift = %s" % (jobparams['levelshift']))) if 'levelshiftvala' not in jobparams: jobparams['levelshiftvala'] = '0.25' if 'levelshiftvalb' not in jobparams: jobparams['levelshiftvalb'] = '0.25' # Now we're ready to start building the input file if not args.jobdir: for i, jobd in enumerate(jobdirs): output = open(jobd + '/terachem_input', 'w') output.write('# file created with %s\n' % globs.PROGRAM) jobparams['coordinates'] = coordfs[i] for keys in list(jobparams.keys()): output.write('%s %s\n' % (keys, jobparams[keys])) if jobparams['run'] == 'minimize': output.write('new_minimizer yes\n') #output.write('min_coordinates cartesian\n') if args.tc_fix_dihedral: temp = mol3D() temp.readfromxyz(strfiles[i]) metal_ind = temp.findMetal() fixed_atoms = list() fixed_atoms = temp.getBondedAtoms(metal_ind) fixed_atoms = [str(int(i) + 1) for i in fixed_atoms] # 1-based indices string_to_write = 'dihedral 0 ' + '_'.join(fixed_atoms) # print(string_to_write) output.write('$constraint_set \n') output.write(string_to_write + '\n') output.write('end\n') output.close() elif args.jobdir: for i, jobd in enumerate(jobdirs): print(('jobd is ' + jobd)) if args.name: output = open(jobd + '/' + args.name + '.in', 'w') else: output = open(jobd + '/terachem_input', 'w') output.write('# file created with %s\n' % globs.PROGRAM) jobparams['coordinates'] = coordfs[i] for keys in list(jobparams.keys()): output.write('%s %s\n' % (keys, jobparams[keys])) if jobparams['run'] == 'minimize': output.write('new_minimizer yes\n') #output.write('min_coordinates cartesian\n') if args.tc_fix_dihedral: temp = mol3D() temp.readfromxyz(strfiles[i]) metal_ind = temp.findMetal() fixed_atoms = list() fixed_atoms = temp.getBondedAtoms(metal_ind) fixed_atoms = [str(int(i) + 1) for i in fixed_atoms] # 1-based indices string_to_write = 'dihedral 0 ' + '_'.join(fixed_atoms) # print(string_to_write) output.write('$constraint_set \n') output.write(string_to_write + '\n') output.write('end\n') output.close() return jobdirs
def addtoldb(smimol,sminame,smident,smicat,smigrps,smictg,ffopt): emsg = False globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print('To add to database, you need to set a custom path. Please enter a writeable file path:') new_path = input('path=') globs.add_custom_path(new_path) copy_to_custom_path() lipath = globs.custom_path + "/Ligands/ligands.dict" licores = readdict(lipath) ligands_folder = globs.custom_path + "/Ligands/" print("ligands_folder is : " + str(ligands_folder)) # check if ligand exists if sminame in licores.keys(): emsg = 'Ligand '+sminame+' already existing in ligands database.' emsg += ' To replace, delete the existing entry first.' return emsg else: # get connection atoms ccats = filter(None,re.split(' |,|\t',smicat)) # get groups groups = filter(None,re.split(' |,|\t',smigrps)) grp = 'all '+' '.join(groups) grp += ' '+smictg if smicat=='': cats = range(0,int(smident)) else: cats = [int(a)-1 for a in ccats] cs = [str(a) for a in cats] css = ' '.join(cs) # convert to unicode smimol = unicodedata.normalize('NFKD',smimol).encode('ascii','ignore') sminame = unicodedata.normalize('NFKD',sminame).encode('ascii','ignore') if '~' in smimol: smimol = smimol.replace('~',os.expanduser('~')) # convert ligand from smiles/file lig,emsg = lig_load(smimol,licores) if emsg: return emsg lig.convert2mol3D() # convert to mol3D shortname = sminame print("smimol is "+str(smimol)) print("sminame is "+str(sminame)) # sanitize ff options: if not ffopt in ["A","B","BA"]: print('warning: incompatible ffopt choice. Options are ' + str(["A","B","BA","N"])) sys.exit(1) # new entry for dictionary if '.mol' in smimol: shutil.copy2(smimol,ligands_folder + sminame+'.mol') snew = sminame+':'+sminame+'.mol,'+shortname+','+css+','+grp+','+ffopt elif '.xyz' in smimol: shutil.copy2(smimol,ligands_folder + sminame+'.xyz') snew = sminame+':'+sminame+'.xyz,'+shortname+','+css+','+grp+','+ffopt elif lig.OBMol: # write smiles file in Ligands directory obConversion = openbabel.OBConversion() obConversion.SetOutFormat("smi") red = obConversion.Read(lig.OBMol) obConversion.WriteFile(lig.OBMol,ligands_folder + sminame+'.smi') #lig.OBMol.write('smi',ligands_folder + sminame+'.smi') snew = sminame+':'+sminame+'.smi,'+shortname+','+css+','+grp+','+ffopt else: # write xyz file in Ligands directory lig.writexyz(ligands_folder+sminame+'.xyz') # write xyz file snew = sminame+':'+sminame+'.xyz,'+shortname+','+css+','+grp+','+ffopt # update dictionary f = open(lipath,'r') ss = f.read().splitlines() f.close() f = open(lipath,'w') ss.append(snew) ssort = sorted(ss[1:]) f.write(ss[0]+'\n') for s in ssort: f.write(s+'\n') f.close() return emsg
def ogen(args, strfiles, method): # global variables globs = globalvars() jobdirs = [] coordfs = [] # Initialize the jobparams dictionary with mandatory/useful keywords. TG: removed min_coordinates cartesian jobparams = { 'run': 'Sp', 'basis': 'def2-TZVP', 'MaxIter': '500', 'method': 'B3LYP', 'spinmult': '1', 'charge': '0', 'ERI': 'NORI', 'REL': '', 'UNO': '', 'mdci_maxit': '200', 'mdci_shift': '0.2', 'HFX': False, } # if multiple methods requested generate c directories # Overwrite plus add any new dictionary keys from commandline input. for xyzf in strfiles: rdir = xyzf.rsplit('/', 1)[0] xyzft = xyzf.rsplit('/', 1)[-1] xyzf += '.xyz' coordfs.append(xyzf.rsplit('/', 1)[-1]) coordname = xyzft # Setting jobname for files + truncated name for queue. if len(coordname) > 10: nametrunc = coordname else: nametrunc = coordname if not os.path.exists(rdir + '/' + nametrunc) and not args.jobdir: os.mkdir(rdir + '/' + nametrunc) mdir = rdir + '/' + nametrunc if method: if method[0] == 'U' or method[0] == 'u': mmd = '/' + method[1:] else: mmd = '/' + method mdir = rdir + '/' + nametrunc + mmd if not os.path.exists(mdir): try: os.mkdirs(mdir) except: pass if not args.jobdir: jobdirs.append(mdir) shutil.copy2(xyzf, mdir) shutil.copy2(xyzf.replace('.xyz', '.molinp'), mdir.replace('.xyz', '.molinp')) try: shutil.copy2(xyzf.replace('.xyz', '.report'), mdir.replace('.xyz', '.report')) except: pass elif args.jobdir: jobdirs.append(rdir) # parse extra arguments # Method parsing, does not check if a garbage method is used here: unrestricted = False if method: jobparams['method'] = method if args.spin and int(args.spin) > 1: unrestricted = True # For ORCA, "ro" or "u" is not needed if ('u' or 'U') in method[0]: jobparams['method'] = method[1:] # Unrestricted calculation elif ('ro' or 'RO') in method[0]: # Restricted calculation unrestricted = False jobparams['method'] = method[2:] else: if args.spin and int(args.spin) >= 1: jobparams['method'] = 'B3LYP' unrestricted = True else: jobparams['method'] = 'B3LYP' print((args.method, method, jobparams['method'])) # Check runtype and we accept both ORCA and terachem naming convention if (args.runtyp and 'energy' in args.runtyp.lower()): jobparams['run'] = 'Sp' elif (args.runtyp and 'sp' in args.runtyp.lower()): jobparams['run'] = 'Sp' elif (args.runtyp and 'opt' in args.runtyp.lower()): jobparams['run'] = 'Opt' elif (args.runtyp and 'minimize' in args.runtyp.lower()): jobparams['run'] = 'Opt' elif (args.runtyp and 'gradient' in args.runtyp.lower()): jobparams['run'] = 'EnGrad' elif (args.runtyp and 'engrad' in args.runtyp.lower()): jobparams['run'] = 'EnGrad' # Special sanity check for CCSD(T) if jobparams['run'] == 'Opt' and 'CC' in jobparams['method']: print( '''Warning! You requested geometry optimization with Coupled-Cluster methods, which is NOT supported. Instead, we will geometry optimize the structure with B3LYP and then conduct CCSD(T) energy calculation on the optimized structure''' ) # TODO: check ORCA dispersion if (args.dispersion): jobparams['dispersion'] = args.dispersion # Just carry over spin and charge keywords if they're set. Could do checks, none for now. if args.spin: jobparams['spinmult'] = args.spin if args.charge: if args.bcharge: args.charge = int(args.charge) + int(args.bcharge) jobparams['charge'] = args.charge # Check for existence of basis and sanitize name # Read in basis name from args only if it's not the default for terachem if args.basis and args.basis != 'lacvps_ecp': jobparams['basis'] = args.basis if 'DIISMaxEq' not in jobparams: jobparams['DIISMaxEq'] = 15 # Overwrite plus add any new dictionary keys from commandline input. if args.qoption: if len(args.qoption) % 2 != 0: print('WARNING: wrong number of arguments in -qoption') else: for elem in range(0, int(0.5 * len(args.qoption))): key, val = args.qoption[2 * elem], args.qoption[2 * elem + 1] jobparams[key] = val # Extra keywords for unrestricted. if unrestricted: # If running unrestricted, assume convergence will be more difficult for now. jobparams['scf'] = 'SlowConv' jobparams['UNO'] = 'UNO' if 'levelshift' not in jobparams: jobparams['levelshift'] = 'yes' elif jobparams['levelshift'] != 'yes': print(( "Warning! You're doing an unrestricted calculation but have set levelshift = %s" % (jobparams['levelshift']))) if 'levelshiftval' not in jobparams: if 'levelshiftvala' in jobparams: jobparams['levelshiftval'] = jobparams['levelshiftvala'] elif 'levelshiftvalb' in jobparams: jobparams['levelshiftval'] = jobparams['levelshiftvalb'] else: jobparams['levelshiftval'] = 0.25 if 'ErrOff' not in jobparams: jobparams['ErrOff'] = 0.00001 # Now we're ready to start building the input file if not args.jobdir: for i, jobd in enumerate(jobdirs): output = open(jobd + '/orca.in', 'w') output.write('# file created with %s\n' % globs.PROGRAM) if 'CC' in jobparams['method'] and jobparams['run'] == 'Opt': params0 = jobparams.copy() params0['method'] = 'B3LYP' ogenwrt(output, params0, coordfs[i]) output.write('\n$new_job\n') jobparams['run'] = 'Sp' ogenwrt(output, jobparams, '') else: ogenwrt(output, jobparams, coordfs[i]) output.close() elif args.jobdir: for i, jobd in enumerate(jobdirs): print(('jobd is ' + jobd)) output = open(jobd + '/orca.in', 'w') output.write('# file created with %s\n' % globs.PROGRAM) if 'CC' in jobparams['method'] and jobparams['run'] == 'Opt': params0 = jobparams.copy() params0['method'] = 'B3LYP' ogenwrt(output, params0, coordfs[i]) output.write('\n$new_job\n') jobparams['run'] = 'Sp' ogenwrt(output, jobparams, '') else: ogenwrt(output, jobparams, coordfs[i]) output.close() return jobdirs
molSimplify 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. You should have received a copy of the GNU General Public License along with molSimplify. If not, see http://www.gnu.org/licenses/. ''' import sys, argparse, os, platform, shutil from Scripts.inparse import * from Scripts.generator import * from molSimplify.Classes.globalvars import * globs = globalvars() ## Basic help description string DescString_basic = 'Welcome to molSimplify. Only basic usage is described here.\n' DescString_basic += 'For help on advanced modules, please refer to our documentation at molsimplify.mit.edu or provide additional commands to -h, as below:\n' DescString_basic += '-h advanced: advanced structure generation help\n' DescString_basic += '-h slabgen: slab builder help\n' #DescString_basic += '-h chainb: chain builder help\n' DescString_basic += '-h autocorr: automated correlation analysis help\n' DescString_basic += '-h db: database search help\n' DescString_basic += '-h inputgen: quantum chemistry code input file generation help\n' DescString_basic += '-h postproc: post-processing help\n' DescString_basic += '-h random: random generation help\n' DescString_basic += '-h binding: binding species (second molecule) generation help\n' DescString_basic += '-h customcore: custom core functionalization help\n' DescString_basic += '-h tsgen: transition state generation help\n' DescString_basic += '-h naming: custom filename help\n'
def addtobdb(smimol, sminame): globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print( 'To add to database, you need to set a custom path. Please enter a writeable file path:' ) new_path = eval(input('path=')) globs.add_custom_path(new_path) copy_to_custom_path() bpath = globs.custom_path + "/Bind/bind.dict" bindcores = readdict(bpath) bind_folder = globs.custom_path + "/Bind/" # check if binding species exists if sminame in list(bindcores.keys()): emsg = 'Molecule ' + sminame + ' already existing in binding species database.' return emsg else: # convert to unicode smimol = unicodedata.normalize('NFKD', smimol).encode('ascii', 'ignore').decode() sminame = unicodedata.normalize('NFKD', sminame).encode('ascii', 'ignore').decode() if '~' in smimol: smimol = smimol.replace('~', os.expanduser('~')) # convert ligand from smiles/file bind, bsmi, emsg = bind_load(smimol, bindcores) if emsg: return emsg bind.convert2mol3D() # convert to mol3D # new entry for dictionary # create shortname if len(sminame) > 5: shortname = sminame[0:3] + sminame[-2:] else: shortname = sminame if '.mol' in smimol: shutil.copy2(smimol, bind_folder + sminame + '.mol') snew = sminame + ':' + sminame + '.mol,' + shortname + ',' elif '.xyz' in smimol: shutil.copy2(smimol, bind_folder + sminame + '.xyz') snew = sminame + ':' + sminame + '.xyz,' + shortname + ',' elif bind.OBmol: # write smiles file in Bind species directory bind.OBmol.write('smi', bind_folder + sminame + '.smi') snew = sminame + ':' + sminame + '.smi,' + shortname + ',' else: # write xyz file in Bind species directory bind.writexyz(bind_folder + sminame + '.xyz') # write xyz file snew = sminame + ':' + sminame + '.xyz,' + shortname + ',' # update dictionary f = open(bpath, 'r') ss = f.read().splitlines() f.close() f = open(bpath, 'w') ss.append(snew) ssort = sorted(ss[1:]) f.write(ss[0] + '\n') for s in ssort: f.write(s + '\n') f.close() return emsg
def postproc(rundir,args,globs): globs = globalvars() if args.gui: from Classes.mWidgets import mQDialogErr from Classes.mWidgets import mQDialogInf choice = mQDialogInf('Post processing','Parsing the results will take a while..Please be patient. Start?') choice.setParent(args.gui.pWindow) # locate output files pdir = args.postdir if args.postdir else globs.rundir cmd = "find '"+pdir+"' -name *out" t = mybash(cmd) resf = t.splitlines() logfile = pdir+"/post.log" if not os.path.isdir(pdir): print '\nSpecified directory '+pdir+' does not exist..\n\n' if args.gui: args.gui.iWtxt.setText('\nSpecified directory '+pdir+' does not exist.\n\n'+args.gui.iWtxt.toPlainText()) return flog = open(logfile,'a') flog.write('\n\n\n##### Date: '+time.strftime('%m/%d/%Y %H:%M')+'#####\n\n') # run summary report if args.pres: print '\nGetting runs summary..\n\n' flog.write('\nGetting runs summary..\n\n') if args.gui: args.gui.iWtxt.setText('\nGetting runs summary..\n\n'+args.gui.iWtxt.toPlainText()) terapost(resf,pdir,args.gui,flog) gampost(resf,pdir,args.gui,flog) # run nbo analysis if args.pnbo: print '\nGetting NBO summary..\n\n' flog.write('\nGetting NBO summary..\n\n') if args.gui: args.gui.iWtxt.setText('\nGetting NBO summary..\n\n'+args.gui.iWtxt.toPlainText()) nbopost(resf,pdir,args.gui,flog) # locate molden files cmd = "find "+"'"+pdir+"'"+" -name *molden" t = mybash(cmd) molf = t.splitlines() # parse molecular orbitals if args.porbinfo: print '\nGetting MO information..\n\n' flog.write('\nGetting MO information..\n\n') if args.gui: args.gui.iWtxt.setText('\nGetting MO information..\n\n'+args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir+'/MO_files'): os.mkdir(pdir+'/MO_files') moldpost(molf,pdir,args.gui,flog) # calculate delocalization indices if args.pdeloc: print '\nCalculating delocalization indices..\n\n' flog.write('\nCalculating delocalization indices..\n\n') if args.gui: args.gui.iWtxt.setText('\nCalculating delocalization indices..\n\n'+args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir+'/Deloc_files'): os.mkdir(pdir+'/Deloc_files') deloc(molf,pdir,args.gui,flog) # calculate charges if args.pcharge: print '\nCalculating charges..\n\n' flog.write('\nCalculating charges..\n\n') if args.gui: args.gui.iWtxt.setText('\nCalculating charges..\n\n'+args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir+'/Charge_files'): os.mkdir(pdir+'/Charge_files') getcharges(molf,pdir,args.gui,flog) # parse wavefunction if args.pwfninfo: print '\nCalculating wavefunction properties..\n\n' flog.write('\nCalculating wavefunction properties..\n\n') if args.gui: args.gui.iWtxt.setText('\nCalculating wavefunction properties..\n\n'+args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir+'/Wfn_files'): os.mkdir(pdir+'/Wfn_files') if not os.path.isdir(pdir+'/Cube_files'): os.mkdir(pdir+'/Cube_files') getcubes(molf,pdir,args.gui,flog) getwfnprops(molf,pdir,args.gui,flog) if not args.pgencubes and os.path.isdir(pdir+'/Cube_files'): shutil.rmtree(pdir+'/Cube_files') # generate cube files if args.pgencubes: print '\nGenerating cube files..\n\n' flog.write('\nGenerating cube files..\n\n') if args.gui: args.gui.iWtxt.setText('\nGenerating cube files..\n\n'+args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir+'/Cube_files'): os.mkdir(pdir+'/Cube_files') getcubes(molf,pdir,args.gui,flog) flog.close()
def addtoldb(smimol, sminame, smident, smicat, smigrps, smictg, ffopt): emsg = False globs = globalvars() if not globs.custom_path or not os.path.exists(str(globs.custom_path)): print( 'To add to database, you need to set a custom path. Please enter a writeable file path:' ) new_path = eval(input('path=')) globs.add_custom_path(new_path) copy_to_custom_path() lipath = globs.custom_path + "/Ligands/ligands.dict" licores = readdict(lipath) ligands_folder = globs.custom_path + "/Ligands/" print(("ligands_folder is : " + str(ligands_folder))) # check if ligand exists if sminame in list(licores.keys()): emsg = 'Ligand ' + sminame + ' already existing in ligands database.' emsg += ' To replace, delete the existing entry first.' return emsg else: # get connection atoms ccats = [_f for _f in re.split(' |,|\t', smicat) if _f] # get groups groups = [_f for _f in re.split(' |,|\t', smigrps) if _f] grp = 'build ' + ' '.join(groups) grp += ' ' + smictg if smicat == '': cats = list(range(0, int(smident))) else: cats = [int(a) - 1 for a in ccats] cs = [str(a) for a in cats] css = ' '.join(cs) # convert to unicode smimol = unicodedata.normalize('NFKD', str(smimol)).encode('ascii', 'ignore').decode() sminame = unicodedata.normalize('NFKD', str(sminame)).encode( 'ascii', 'ignore').decode() if '~' in smimol: smimol = smimol.replace('~', os.expanduser('~')) # convert ligand from smiles/file lig, emsg = lig_load(smimol, licores) if emsg: return emsg lig.convert2mol3D() # convert to mol3D shortname = sminame print(("smimol is " + str(smimol))) print(("sminame is " + str(sminame))) # sanitize ff options: if not ffopt in ["A", "B", "BA"]: print(('warning: incompatible ffopt choice. Options are ' + str(["A", "B", "BA", "N"]))) sys.exit(1) # new entry for dictionary if '.mol' in smimol: shutil.copy2(smimol, ligands_folder + sminame + '.mol') snew = str(sminame) + ':' + str(sminame) + '.mol,' + str( shortname) + ',' + str(css) + ',' + str(grp) + ',' + str( ffopt) + ',' + str(lig.charge) elif '.xyz' in smimol: shutil.copy2(smimol, ligands_folder + sminame + '.xyz') snew = str(sminame) + ':' + str(sminame) + '.xyz,' + str( shortname) + ',' + str(css) + ',' + str(grp) + ',' + str( ffopt) + ',' + str(lig.charge) elif lig.OBMol: # write smiles file in Ligands directory obConversion = openbabel.OBConversion() obConversion.SetOutFormat("smi") red = obConversion.Read(lig.OBMol) obConversion.WriteFile(lig.OBMol, ligands_folder + sminame + '.smi') #lig.OBMol.write('smi',ligands_folder + sminame+'.smi') snew = str(sminame) + ':' + str(sminame) + '.smi,' + str( shortname) + ',' + str(css) + ',' + str(grp) + ',' + str( ffopt) + ',' + str(lig.charge) else: # write xyz file in Ligands directory lig.writexyz(ligands_folder + sminame + '.xyz') # write xyz file snew = str(sminame) + ':' + str(sminame) + '.xyz,' + str( shortname) + ',' + str(css) + ',' + str(grp) + ',' + str( ffopt) + ',' + str(lig.charge) # update dictionary f = open(lipath, 'r') ss = f.read().splitlines() f.close() f = open(lipath, 'w') ss.append(snew) ssort = sorted(ss[1:]) f.write(ss[0] + '\n') for s in ssort: f.write(s + '\n') f.close() return emsg
def postproc(rundir, args, globs): globs = globalvars() if args.gui: from Classes.mWidgets import mQDialogErr from Classes.mWidgets import mQDialogInf choice = mQDialogInf( 'Post processing', 'Parsing the results will take a while..Please be patient. Start?') choice.setParent(args.gui.pWindow) # locate output files pdir = args.postdir if args.postdir else globs.rundir cmd = "find '" + pdir + "' -name *out" t = mybash(cmd) resf = t.splitlines() logfile = pdir + "/post.log" if not os.path.isdir(pdir): print '\nSpecified directory ' + pdir + ' does not exist..\n\n' if args.gui: args.gui.iWtxt.setText('\nSpecified directory ' + pdir + ' does not exist.\n\n' + args.gui.iWtxt.toPlainText()) return flog = open(logfile, 'a') flog.write('\n\n\n##### Date: ' + time.strftime('%m/%d/%Y %H:%M') + '#####\n\n') # run summary report if args.pres: print '\nGetting runs summary..\n\n' flog.write('\nGetting runs summary..\n\n') if args.gui: args.gui.iWtxt.setText('\nGetting runs summary..\n\n' + args.gui.iWtxt.toPlainText()) terapost(resf, pdir, args.gui, flog) gampost(resf, pdir, args.gui, flog) # run nbo analysis if args.pnbo: print '\nGetting NBO summary..\n\n' flog.write('\nGetting NBO summary..\n\n') if args.gui: args.gui.iWtxt.setText('\nGetting NBO summary..\n\n' + args.gui.iWtxt.toPlainText()) nbopost(resf, pdir, args.gui, flog) # locate molden files cmd = "find " + "'" + pdir + "'" + " -name *molden" t = mybash(cmd) molf = t.splitlines() # parse molecular orbitals if args.porbinfo: print '\nGetting MO information..\n\n' flog.write('\nGetting MO information..\n\n') if args.gui: args.gui.iWtxt.setText('\nGetting MO information..\n\n' + args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir + '/MO_files'): os.mkdir(pdir + '/MO_files') moldpost(molf, pdir, args.gui, flog) # calculate delocalization indices if args.pdeloc: print '\nCalculating delocalization indices..\n\n' flog.write('\nCalculating delocalization indices..\n\n') if args.gui: args.gui.iWtxt.setText( '\nCalculating delocalization indices..\n\n' + args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir + '/Deloc_files'): os.mkdir(pdir + '/Deloc_files') deloc(molf, pdir, args.gui, flog) # calculate charges if args.pcharge: print '\nCalculating charges..\n\n' flog.write('\nCalculating charges..\n\n') if args.gui: args.gui.iWtxt.setText('\nCalculating charges..\n\n' + args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir + '/Charge_files'): os.mkdir(pdir + '/Charge_files') getcharges(molf, pdir, args.gui, flog) # parse wavefunction if args.pwfninfo: print '\nCalculating wavefunction properties..\n\n' flog.write('\nCalculating wavefunction properties..\n\n') if args.gui: args.gui.iWtxt.setText( '\nCalculating wavefunction properties..\n\n' + args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir + '/Wfn_files'): os.mkdir(pdir + '/Wfn_files') if not os.path.isdir(pdir + '/Cube_files'): os.mkdir(pdir + '/Cube_files') getcubes(molf, pdir, args.gui, flog) getwfnprops(molf, pdir, args.gui, flog) if not args.pgencubes and os.path.isdir(pdir + '/Cube_files'): shutil.rmtree(pdir + '/Cube_files') # generate cube files if args.pgencubes: print '\nGenerating cube files..\n\n' flog.write('\nGenerating cube files..\n\n') if args.gui: args.gui.iWtxt.setText('\nGenerating cube files..\n\n' + args.gui.iWtxt.toPlainText()) if not os.path.isdir(pdir + '/Cube_files'): os.mkdir(pdir + '/Cube_files') getcubes(molf, pdir, args.gui, flog) flog.close()