def test_runs_assimilate(self): drone = VaspDrone(runs=["relax1", "relax2"]) doc = drone.assimilate(self.relax2) oszicar2 = Oszicar(os.path.join(self.relax2, "OSZICAR.relax2.gz")) outcar1 = Outcar(os.path.join(self.relax2, "OUTCAR.relax1.gz")) outcar2 = Outcar(os.path.join(self.relax2, "OUTCAR.relax2.gz")) outcar1 = outcar1.as_dict() outcar2 = outcar2.as_dict() run_stats1 = outcar1.pop("run_stats") run_stats2 = outcar2.pop("run_stats") self.assertEqual(len(doc["calcs_reversed"]), 2) self.assertEqual(doc["composition_reduced"], {"Si": 1.0}) self.assertEqual(doc["composition_unit_cell"], {"Si": 2.0}) self.assertAlmostEqual(doc["output"]["energy"], oszicar2.ionic_steps[-1]["E0"]) self.assertEqual(doc["formula_pretty"], "Si") self.assertEqual(doc["formula_anonymous"], "A") self.assertEqual(list(doc["calcs_reversed"][0]["input"].keys()), list(doc["calcs_reversed"][1]["input"].keys())) self.assertEqual( list(doc["calcs_reversed"][0]["output"].keys()), list(doc["calcs_reversed"][1]["output"].keys()) ) self.assertEqual(doc["calcs_reversed"][0]["output"]["energy"], doc["output"]["energy"]) self.assertEqual(doc["run_stats"][doc["calcs_reversed"][0]["task"]["name"]], run_stats2) self.assertEqual(doc["run_stats"][doc["calcs_reversed"][1]["task"]["name"]], run_stats1) self.assertEqual(doc["calcs_reversed"][0]["output"]["outcar"], outcar2) self.assertEqual(doc["calcs_reversed"][1]["output"]["outcar"], outcar1)
def test_runs_assimilate(self): drone = VaspDrone(runs=["relax1", "relax2"]) doc = drone.assimilate(self.relax2) oszicar2 = Oszicar(os.path.join(self.relax2, "OSZICAR.relax2.gz")) outcar1 = Outcar(os.path.join(self.relax2, "OUTCAR.relax1.gz")) outcar2 = Outcar(os.path.join(self.relax2, "OUTCAR.relax2.gz")) outcar1 = outcar1.as_dict() outcar2 = outcar2.as_dict() run_stats1 = outcar1.pop("run_stats") run_stats2 = outcar2.pop("run_stats") self.assertEqual(len(doc["calcs_reversed"]), 2) self.assertEqual(doc["composition_reduced"], {"Si": 1.0}) self.assertEqual(doc["composition_unit_cell"], {"Si": 2.0}) self.assertAlmostEqual(doc["output"]["energy"], oszicar2.ionic_steps[-1]["E0"]) self.assertEqual(doc["formula_pretty"], "Si") self.assertEqual(doc["formula_anonymous"], "A") self.assertEqual( list(doc["calcs_reversed"][0]["input"].keys()), list(doc["calcs_reversed"][1]["input"].keys()), ) self.assertEqual( list(doc["calcs_reversed"][0]["output"].keys()), list(doc["calcs_reversed"][1]["output"].keys()), ) self.assertEqual( doc["calcs_reversed"][0]["output"]["energy"], doc["output"]["energy"] ) self.assertEqual( doc["run_stats"][doc["calcs_reversed"][0]["task"]["name"]], run_stats2 ) self.assertEqual( doc["run_stats"][doc["calcs_reversed"][1]["task"]["name"]], run_stats1 ) self.assertEqual(doc["calcs_reversed"][0]["output"]["outcar"], outcar2) self.assertEqual(doc["calcs_reversed"][1]["output"]["outcar"], outcar1)
def process_task(self, path): try: #Override incorrect outcar subdocs for two step relaxations if os.path.exists(os.path.join(path, "relax2")): try: run_stats = {} for i in [1,2]: outcar = Outcar(zpath(os.path.join(path,"relax"+str(i), "OUTCAR"))) m_key = "calculations."+str(i-1)+".output.outcar" self.tasks.update({'dir_name_full': path}, {'$set': {m_key: outcar.as_dict()}}) run_stats["relax"+str(i)] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(path)) try: overall_run_stats = {} for key in ["Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)"]: overall_run_stats[key] = sum([v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(path)) self.tasks.update({'dir_name_full': path}, {'$set': {"run_stats": run_stats}}) print 'FINISHED', path else: print 'SKIPPING', path except: print '-----' print 'ENCOUNTERED AN EXCEPTION!!!', path traceback.print_exc() print '-----'
def process_task(self, path): try: #Override incorrect outcar subdocs for two step relaxations if os.path.exists(os.path.join(path, "relax2")): try: run_stats = {} for i in [1, 2]: outcar = Outcar( zpath( os.path.join(path, "relax" + str(i), "OUTCAR"))) m_key = "calculations." + str(i - 1) + ".output.outcar" self.tasks.update({'dir_name_full': path}, {'$set': { m_key: outcar.as_dict() }}) run_stats["relax" + str(i)] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(path)) try: overall_run_stats = {} for key in [ "Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)" ]: overall_run_stats[key] = sum( [v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(path)) self.tasks.update({'dir_name_full': path}, {'$set': { "run_stats": run_stats }}) print 'FINISHED', path else: print 'SKIPPING', path except: print '-----' print 'ENCOUNTERED AN EXCEPTION!!!', path traceback.print_exc() print '-----'
def post_process(self, dir_name, d): """ Simple post-processing for various files other than the vasprun.xml. Called by generate_task_doc. Modify this if your runs have other kinds of processing requirements. Args: dir_name: The dir_name. d: Current doc generated. """ logger.info("Post-processing dir:{}".format(dir_name)) fullpath = os.path.abspath(dir_name) # VASP input generated by pymatgen's alchemy has a # transformations.json file that keeps track of the origin of a # particular structure. This is extremely useful for tracing back a # result. If such a file is found, it is inserted into the task doc # as d["transformations"] transformations = {} filenames = glob.glob(os.path.join(fullpath, "transformations.json*")) if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: transformations = json.load(f) try: m = re.match("(\d+)-ICSD", transformations["history"][0]["source"]) if m: d["icsd_id"] = int(m.group(1)) except Exception as ex: logger.warning("Cannot parse ICSD from transformations " "file.") pass else: logger.warning("Transformations file does not exist.") other_parameters = transformations.get("other_parameters") new_tags = None if other_parameters: # We don't want to leave tags or authors in the # transformations file because they'd be copied into # every structure generated after this one. new_tags = other_parameters.pop("tags", None) new_author = other_parameters.pop("author", None) if new_author: d["author"] = new_author if not other_parameters: # if dict is now empty remove it transformations.pop("other_parameters") d["transformations"] = transformations # Calculations done using custodian has a custodian.json, # which tracks the jobs performed and any errors detected and fixed. # This is useful for tracking what has actually be done to get a # result. If such a file is found, it is inserted into the task doc # as d["custodian"] filenames = glob.glob(os.path.join(fullpath, "custodian.json*")) if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: d["custodian"] = json.load(f) # Parse OUTCAR for additional information and run stats that are # generally not in vasprun.xml. try: run_stats = {} for filename in glob.glob(os.path.join(fullpath, "OUTCAR*")): outcar = Outcar(filename) i = 1 if re.search("relax2", filename) else 0 taskname = "relax2" if re.search("relax2", filename) else \ "relax1" d["calculations"][i]["output"]["outcar"] = outcar.as_dict() run_stats[taskname] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(fullpath)) try: overall_run_stats = {} for key in [ "Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)" ]: overall_run_stats[key] = sum( [v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(fullpath)) d["run_stats"] = run_stats #Convert to full uri path. if self.use_full_uri: d["dir_name"] = get_uri(dir_name) if new_tags: d["tags"] = new_tags logger.info("Post-processed " + fullpath)
def post_process(self, dir_name, d): """ Simple post-processing for various files other than the vasprun.xml. Called by generate_task_doc. Modify this if your runs have other kinds of processing requirements. Args: dir_name: The dir_name. d: Current doc generated. """ logger.info("Post-processing dir:{}".format(dir_name)) fullpath = os.path.abspath(dir_name) # VASP input generated by pymatgen's alchemy has a # transformations.json file that keeps track of the origin of a # particular structure. This is extremely useful for tracing back a # result. If such a file is found, it is inserted into the task doc # as d["transformations"] transformations = {} filenames = glob.glob(os.path.join(fullpath, "transformations.json*")) if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: transformations = json.load(f) try: m = re.match("(\d+)-ICSD", transformations["history"][0]["source"]) if m: d["icsd_id"] = int(m.group(1)) except Exception as ex: logger.warning("Cannot parse ICSD from transformations " "file.") pass else: logger.warning("Transformations file does not exist.") other_parameters = transformations.get("other_parameters") new_tags = None if other_parameters: # We don't want to leave tags or authors in the # transformations file because they'd be copied into # every structure generated after this one. new_tags = other_parameters.pop("tags", None) new_author = other_parameters.pop("author", None) if new_author: d["author"] = new_author if not other_parameters: # if dict is now empty remove it transformations.pop("other_parameters") d["transformations"] = transformations # Calculations done using custodian has a custodian.json, # which tracks the jobs performed and any errors detected and fixed. # This is useful for tracking what has actually be done to get a # result. If such a file is found, it is inserted into the task doc # as d["custodian"] filenames = glob.glob(os.path.join(fullpath, "custodian.json*")) if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: d["custodian"] = json.load(f) # Parse OUTCAR for additional information and run stats that are # generally not in vasprun.xml. try: run_stats = {} for filename in glob.glob(os.path.join(fullpath, "OUTCAR*")): outcar = Outcar(filename) i = 1 if re.search("relax2", filename) else 0 taskname = "relax2" if re.search("relax2", filename) else \ "relax1" d["calculations"][i]["output"]["outcar"] = outcar.as_dict() run_stats[taskname] = outcar.run_stats except: logger.error("Bad OUTCAR for {}.".format(fullpath)) try: overall_run_stats = {} for key in ["Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)"]: overall_run_stats[key] = sum([v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(fullpath)) d["run_stats"] = run_stats #Convert to full uri path. if self.use_full_uri: d["dir_name"] = get_uri(dir_name) if new_tags: d["tags"] = new_tags logger.info("Post-processed " + fullpath)
def band_structure(): check_matplotlib() step_count=1 filename='vasprun.xml' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') vsr=Vasprun(filename) step_count+=1 filename='KPOINTS' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi) step_count+=1 filename='OUTCAR' check_file(filename) proc_str="Reading Data From "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') outcar=Outcar('OUTCAR') mag=outcar.as_dict()['total_magnetization'] if vsr.is_spin: proc_str="This Is a Spin-polarized Calculation." procs(proc_str,0,sp='-->>') tdos=vsr.tdos SpinUp_gap=tdos.get_gap(spin=Spin.up) cbm_vbm_up=tdos.get_cbm_vbm(spin=Spin.up) SpinDown_gap=tdos.get_gap(spin=Spin.down) cbm_vbm_down=tdos.get_cbm_vbm(spin=Spin.up) if SpinUp_gap > min_gap and SpinDown_gap > min_gap: is_metal=False is_semimetal=False elif SpinUp_gap > min_gap and SpinDown_gap < min_gap: is_metal=False is_semimetal=True elif SpinUp_gap < min_gap and SpinDown_gap > min_gap: is_metal=False is_semimetal=True elif SpinUp_gap < min_gap and SpinDown_gap < min_gap: is_metal=True is_semimetal=False if is_metal: proc_str="This Material Is a Metal." procs(proc_str,0,sp='-->>') if not is_metal and is_semimetal: proc_str="This Material Is a Semimetal." procs(proc_str,0,sp='-->>') else: proc_str="This Material Is a Semiconductor." procs(proc_str,0,sp='-->>') proc_str="Total magnetization is "+str(mag) procs(proc_str,0,sp='-->>') if mag > min_mag: proc_str="SpinUp : vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_up[1],cbm_vbm_up[0],SpinUp_gap) procs(proc_str,0,sp='-->>') proc_str="SpinDown: vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_down[1],cbm_vbm_down[0],SpinUp_gap) procs(proc_str,0,sp='-->>') else: proc_str="SpinUp : vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_up[1],cbm_vbm_up[0],SpinUp_gap) procs(proc_str,0,sp='-->>') step_count+=1 filename="BAND.dat" proc_str="Writting Band Structure Data to "+ filename +" File ..." procs(proc_str,step_count,sp='-->>') band_data_up=bands.bands[Spin.up] band_data_down=bands.bands[Spin.down] y_data_up=band_data_up.reshape(1,band_data_up.shape[0]*band_data_up.shape[1])[0]-vsr.efermi #shift fermi level to 0 y_data_down=band_data_down.reshape(1,band_data_down.shape[0]*band_data_down.shape[1])[0]-vsr.efermi #shift fermi level to 0 x_data=np.array(bands.distance*band_data_up.shape[0]) data=np.vstack((x_data,y_data_up,y_data_down)).T head_line="#%(key1)+12s%(key2)+13s%(key3)+15s"%{'key1':'K-Distance','key2':'UpEnergy(ev)','key3':'DownEnergy(ev)'} write_col_data(filename,data,head_line,band_data_up.shape[1]) else: if vsr.parameters['LNONCOLLINEAR']: proc_str="This Is a Non-Collinear Calculation." else: proc_str="This Is a Non-Spin Calculation." procs(proc_str,0,sp='-->>') cbm=bands.get_cbm()['energy'] vbm=bands.get_vbm()['energy'] gap=bands.get_band_gap()['energy'] if not bands.is_metal(): proc_str="This Material Is a Semiconductor." procs(proc_str,0,sp='-->>') proc_str="vbm=%f eV cbm=%f eV gap=%f eV"%(vbm,cbm,gap) procs(proc_str,0,sp='-->>') else: proc_str="This Material Is a Metal." procs(proc_str,0,sp='-->>') step_count+=1 filename3="BAND.dat" proc_str="Writting Band Structure Data to "+ filename3 +" File ..." procs(proc_str,step_count,sp='-->>') band_data=bands.bands[Spin.up] y_data=band_data.reshape(1,band_data.shape[0]*band_data.shape[1])[0]-vsr.efermi #shift fermi level to 0 x_data=np.array(bands.distance*band_data.shape[0]) data=np.vstack((x_data,y_data)).T head_line="#%(key1)+12s%(key2)+13s"%{'key1':'K-Distance','key2':'Energy(ev)'} write_col_data(filename3,data,head_line,band_data.shape[1]) step_count+=1 bsp=BSPlotter(bands) filename4="HighSymmetricPoints.dat" proc_str="Writting Label infomation to "+ filename4 +" File ..." procs(proc_str,step_count,sp='-->>') head_line="#%(key1)+12s%(key2)+12s%(key3)+12s"%{'key1':'index','key2':'label','key3':'position'} line=head_line+'\n' for i,label in enumerate(bsp.get_ticks()['label']): new_line="%(key1)12d%(key2)+12s%(key3)12f\n"%{'key1':i,'key2':label,'key3':bsp.get_ticks()['distance'][i]} line+=new_line line+='\n' write_col_data(filename4,line,'',str_data=True) try: step_count+=1 filename5="BAND.png" proc_str="Saving Plot to "+ filename5 +" File ..." procs(proc_str,step_count,sp='-->>') bsp.save_plot(filename5, img_format="png") except: print("Figure output fails !!!")