def submit_job(job, script=None): """Submit the specified job to queue for calculation""" logging.debug("Submitting job to queue") if not script: try: script = turbogo_helpers.read_clean_file("submitscript.sge") except turbogo_helpers.FileAccessError: raise turbogo_helpers.FileAccessError # submit job in Popen pipe and get job number back. p = Popen("qsub", stdin=PIPE, stdout=PIPE) poutput, perr = p.communicate(input=script) if "has been submitted" in poutput: jobid = poutput.split("\n")[0].split(" ")[2] if turbogo_helpers.is_int(jobid): job.jobid = jobid logging.info("Job {} with job id {} submitted".format(job.name, jobid)) turbogo_helpers.write_file("jobid", ["{}: {}".format(job.jobtype, jobid)]) else: job.jobid = None logging.warning("Job id unknown.") else: job.jobid = None logging.warning("Error starting job. qsub output: \n{}".format(poutput)) return job.jobid
def ensure_ts(job): """ This runs to read out the vibrational modes. If there are more than one negative, run screwer to adjust the geometry along the imaginary coordinate, and resubmits job. """ if job.freqopt == 'numforce': newdir = os.path.join(job.indir, 'numforce') else: newdir = job.indir filetoread = os.path.join(newdir, 'control') controlfile = turbogo_helpers.read_clean_file(filetoread) vib1= False vib2 = False for i in range(len(controlfile)): if '$vibrational spectrum' in controlfile[i]: for j in range (i+3, len(controlfile)): col = controlfile[j][15:34].strip() if col != '0.00': try: if not vib1: vib1 = float(col) elif not vib2: vib2 = float(col) except ValueError: pass else: mode = controlfile[j][:6].strip() if vib2: break if vib1 and vib2: if vib1 < 0 and vib2 > 0: return 'ts' elif vib1 > 0: return 'opt' elif vib2 < 0: return 'imaginary' # itvc = 1 SHOULD only ever return 1 img. freq else: logging.warning( 'Error getting vibrational frequencies from job {}.'.format( job.name )) return 'error'
def ensure_not_ts(job): """ This runs to read out the vibrational modes. If there are negatives, runs screwer to adjust the geometry along the imaginary coordinate, and resubmits job. """ if job.freqopt == 'numforce': newdir = os.path.join(job.indir, 'numforce') else: newdir = job.indir filetoread = os.path.join(newdir, 'control') controlfile = turbogo_helpers.read_clean_file(filetoread) vib1 = False for i in range(len(controlfile)): if '$vibrational spectrum' in controlfile[i]: for j in range (i+3, len(controlfile)): col = controlfile[j][15:34].strip() if not (col == '0.00' or col == '-0.00'): try: vib1 = float(col) except ValueError: pass else: mode = controlfile[j][:6].strip() break if vib1: break if vib1: if job.firstfreq == vib1: #Found the same TS as before. End job. return 'same' job.firstfreq = vib1 if vib1 < 0: os.chdir(newdir) screwer = Screwer(mode) try: screwer.run_screwer() except Exception as e: logging.warning("Error '{}' running screwer on job {}.".format( e, job.name)) os.chdir(TOPDIR) return "error" control = turbogo_helpers.read_clean_file('control') newcoord = list() readin = False for line in control: if '$newcoord' in line: readin = -1 elif '$end' in line: readin = False if readin: newcoord.append(line) elif readin == -1: readin = True if job.freqopt == 'numforce': os.chdir(os.pardir) turbogo_helpers.write_file('coord', newcoord) try: # Better to remove numforce, if not no biggie os.remove(os.path.join(os.curdir, 'control')) shutil.rmtree(os.path.join(os.curdir, 'numforce')) except OSError: pass try: job.jobid, job.freqopt, job.name, job.jobtype = jobrunner(job=self.job) job.curstart = time() except Exception as e: logging.warning("Error {} resubmitting job {}.".format( e, job.name)) os.chdir(TOPDIR) return 'error' os.chdir(TOPDIR) return 'opt' else: return 'completed' else: logging.warning( 'Error getting vibrational frequencies from job {}.'.format( job.name )) return 'error'
def jobsetup(infile): """ Read the input file, get the keyword flags & geometry. Utilizes a gaussian type input file. """ lines = turbogo_helpers.read_clean_file(infile) iargs = list() igeom = list() control_add = list() control_remove = list() # first parse %args from top of file lines.reverse() moreargs = True while moreargs: if lines[-1][0] == "%": iargs.append(lines.pop()) else: moreargs = False args = turbogo_helpers.check_args(iargs) logging.debug("{} args processed".format(len(args))) # immediately following %args is the #route card if not lines[-1][0] == "#": logging.error( """Syntax error at route. Must immediately follow arguements ('%') and start with #""" ) raise InputSyntaxError( str(lines[0]), """Syntax error at route. Must immediately follow arguements ('%') and start with #""", ) else: iroute = lines.pop() logging.debug("Parsing input route card.") route = turbogo_helpers.check_route(iroute) logging.debug("{} Route parameters processed".format(len(route))) # specs from gaussian: blank line required if not lines[-1] == "": logging.error( """Syntax error after route. Blank line required before title""" ) raise InputSyntaxError( str(lines[0]), """Syntax error after route. Blank line required before title""", ) else: del lines[-1] # Now is the job title. title = str(lines[-1]) logging.debug("Title: {}".format(title)) del lines[-1] # Gaussian spec another blank line if not lines[-1] == "": logging.error( """Syntax error after title. Blank line required before charge & spin""" ) raise InputSyntaxError( str(lines[0]), """Syntax error after title. Blank line required before charge & spin""", ) else: del lines[-1] # Charge and spin (0 1) ichspin = lines[-1] ch_spin = turbogo_helpers.check_chspin(ichspin) logging.debug("Charge of {} and spin of {}.".format(ch_spin["ch"], ch_spin["spin"])) del lines[-1] # Input Geometry in xyz cartesian format moregeom = True while moregeom: if not lines[-1][:1] == "": igeom.append(lines.pop()) else: moregeom = False geom = turbogo_helpers.check_geom(igeom) logging.debug("{} lines of geometry processed".format(len(geom))) # gaussian spec blankline if not lines[-1] == "": logging.error("Syntax error after geometry. Blank line required.") raise InputSyntaxError( str(lines[0]), """Syntax error after geometry. Blank line required.""", ) else: del lines[-1] # new spec: manual add or subtract from control file with: # $opt to add, or: # -$opt to remove if len(lines) > 0: logging.debug("Parsing additional control arguements") morelines = True while morelines: try: if lines[-1][0] == "$" or lines[-1][0] == "-" and lines[-1][1] == "$": if lines[-1][0] == "$": control_add.append(lines.pop()) else: control_remove.append(lines.pop()) else: morelines = False except IndexError: morelines = False logging.debug("{} additional lines processed".format(len(control_add))) # Set up job.class logging.debug("Setting up Job with collected information.") job = Job() job.name = title job.charge = ch_spin["ch"] job.spin = ch_spin["spin"] if "basis" in route: job.basis = route["basis"] if "functional" in route: job.functional = route["functional"] if "jobtype" in route: job.jobtype = route["jobtype"] else: job.jobtype = "sp" if job.jobtype == "opt" or job.jobtype == "optfreq": # one atom checking - can't opt one atom, so single point it. if len(geom) == 1: logging.debug("One atom job changed to SP") job.jobtype = "sp" if "freqopts" in route and job.jobtype != "sp": job.freqopts = route["freqopts"] elif job.jobtype == "freq" and not "freqopts" in route: job.freqopts = DEFAULT_FREQ elif job.jobtype == "ts" and not "freqopts" in route: job.freqopts = DEFAULT_FREQ if "ri" in route: job.ri = True else: job.ri = False if "marij" in route and "ri" in route: job.marij = True else: job.ri = False if "disp" in route or job.functional == "b97-d": job.disp = True if "freeh" in route: job.freeh = True if job.freeh: job.freqopts += "+freeh" if "iterations" in args: job.iterations = int(args["iterations"]) elif "maxcycles" in args: job.iterations = int(args["maxcycles"]) if "nproc" in args: job.nproc = int(args["nproc"]) if "cosmo" in args: job.cosmo = args["cosmo"] if "rt" in args: job.rt = "{}:00:00".format(args["rt"]) if job.jobtype != "freq": if "arch" in args: job.para_arch = args["arch"] else: job.para_arch = "SMP" if "mod" in args and not args["mod"]: logging.debug("No mod of control requested") else: control_add = turbogo_helpers.auto_control_mod(control_add, job) job.control_add = control_add job.control_remove = control_remove job.geometry = geom return job