def gbrv_plot(options): """Plot results in the database.""" outdb = GbrvOutdb.from_file(options.path) frame = outdb.get_pdframe() #print(frame) #print(frame.describe()) frame.print_summary() frame.plot_errors_for_elements() return 0 # Use seaborn settings. import seaborn as sns sns.set(context=options.seaborn, style='darkgrid', palette='deep', font='sans-serif', font_scale=1, color_codes=False, rc=None) for struct_type in frame.struct_types(): frame.plot_errors_for_structure(struct_type) frame.plot_hist(struct_type) return 0
def gbrv_update(options): """Update the databases in dojo_dir.""" raise NotImplementedError() filepath = os.path.join(options.dojo_dir, options.basename) outdb = GbrvOutdb.from_file(filepath) print("Checking:", outdb.basename) u = outdb.check_update() print("Update report:", u) return 0
def gbrv_rundb(options): """Build flow and run it.""" dbpath = os.path.abspath(options.path) retcode = 0 # Get list of jobs to execute. with FileLock(dbpath): outdb = GbrvOutdb.from_file(dbpath) jobs = outdb.find_jobs_torun(options.max_njobs) if not jobs: cprint("Nothing to do, returning 0", "yellow") return 0 gbrv_factory = GbrvCompoundsFactory(xc=outdb["xc_name"]) # Build workdir. s = "-".join(job.formula for job in jobs) m = hashlib.md5() m.update(s) workdir = os.path.join( os.getcwd(), "GBRV_OUTDB_" + jobs[0].formula + "_" + jobs[-1].formula + "_" + m.hexdigest()) #workdir = os.path.join(os.getcwd(), "GBRV_OUTDB_" + s) flow = GbrvCompoundsFlow(workdir=workdir) for job in jobs: #for accuracy in ("low", "normal", "high"): #for accuracy in ("high",): for accuracy in ("normal", "high"): ecut = max(p.hint_for_accuracy(accuracy).ecut for p in job.pseudos) pawecutdg = max( p.hint_for_accuracy(accuracy).pawecutdg for p in job.pseudos) if ecut <= 0.0: raise RuntimeError("Pseudos do not have hints") # Increase by 10 since many pseudos only have ppgen_hints #ecut += 10 work = gbrv_factory.relax_and_eos_work(accuracy, job.pseudos, job.formula, job.struct_type, ecut=ecut, pawecutdg=pawecutdg) # Attach the database to the work to trigger the storage of the results. flow.register_work(work.set_outdb(dbpath)) print("Working in:", flow.workdir) flow.build_and_pickle_dump() #abivalidate=options.dry_run) if options.dry_run: return 0 # Run the flow with the scheduler (enable smart_io) flow.use_smartio() retcode += flow.make_scheduler().start() return retcode
def gbrv_generate(options): """Generate the GBRV output databases.""" # FIXME bugme with workdir for cls in GbrvOutdb.__subclasses__(): outdb = cls.new_from_dojodir(options.dojo_dir) if os.path.exists(outdb.filepath): print("File %s already exists! " "New file won't be created. Remove it and try again" % outdb.basename) else: outdb.json_write() print("Written new database %s" % outdb.basename) return 0
def gbrv_run(options): """Build flow and run it.""" options.manager = abilab.TaskManager.as_manager(options.manager) outdb = GbrvOutdb.from_file(options.database) jobs = outdb.find_jobs_torun(max_njobs=options.max_njobs, select_formulas=options.formulas) num_jobs = len(jobs) if num_jobs == 0: print("Nothing to do, returning") return 0 else: print("Will run %d works" % num_jobs) import tempfile workdir = tempfile.mkdtemp(dir=os.getcwd(), prefix=outdb.struct_type + "_") # workdir=tempfile.mkdtemp() flow = abilab.Flow(workdir=workdir, manager=options.manager) extra_abivars = {"mem_test": 0, "fband": 2, "nstep": 100, "paral_kgb": options.paral_kgb} gbrv_factory = GbrvCompoundsFactory() for job in jobs: # FIXME this should be taken from the pseudos ecut = 30 if job.accuracy == "normal" else 45 work = gbrv_factory.relax_and_eos_work( job.accuracy, job.pseudos, job.formula, outdb.struct_type, ecut=ecut, pawecutdg=None, **extra_abivars ) # Attach the database to the work to trigger the storage of the results. flow.register_work(work.set_outdb(outdb.filepath)) print("Working in: ", flow.workdir) flow.build_and_pickle_dump() if options.dry_run: print("dry-run mode, will validate input files") isok, results = flow.abivalidate_inputs() if not isok: print(results) return 1 else: # Run the flow with the scheduler (enable smart_io) flow.use_smartio() # flow.make_scheduler(rmflow=True).start() flow.make_scheduler().start() return 0
def gbrv_update(options): """Update the databases in dojo_dir.""" for cls in GbrvOutdb.__subclasses__(): filepath = os.path.join(options.dojo_dir, cls.basename) if not os.path.exists(filepath): continue outdb = cls.from_file(filepath) print("Checking:", outdb.basename) u = outdb.check_update() print("Update report:", u) return 0
def gbrv_reset(options): """Reset entries in the databases.""" status_list = [] if "f" in options.status: status_list.append("failed") if "s" in options.status: status_list.append("scheduled") if not status_list: raise ValueError("Wrong value option %s" % options.status) cprint("Resetting all entries with status in: %s" % str(status_list), "yellow") outdb = GbrvOutdb.from_file(options.path) n = outdb.reset(status_list=status_list) print("%d entrie(s) have been resetted" % (n)) return 0
def gbrv_plot(options): """Plot results in the database.""" outdb = GbrvOutdb.from_file(options.path) frame = outdb.get_pdframe() #print(frame) #print(frame.describe()) frame.print_summary() frame.plot_errors_for_elements() return 0 import seaborn as sns for struct_type in frame.struct_types(): frame.plot_errors_for_structure(struct_type) frame.plot_hist(struct_type) return 0
def gbrv_reset(options): """Reset the failed entries in the list of databases specified by the user.""" status_list = [] if "f" in options.status: status_list.append("failed") if "s" in options.status: status_list.append("scheduled") if not status_list: raise ValueError("Wrong value option %s" % options.status) for path in options.database_list: outdb = GbrvOutdb.from_file(path) n = outdb.reset(status_list=status_list) print("%s: %d has been resetted" % (outdb.basename, n)) outdb.json_write() return 0
def gbrv_gendb(options): """Generate the GBRV output database from a djson file..""" # Build table from djson_path djson_path = os.path.abspath(options.djson_path) table = OfficialDojoTable.from_djson_file(djson_path) if options.verbose > 1: print(table) # Init database and dump it db = GbrvOutdb.new_from_table(table, djson_path) if os.path.exists(db.path): cprint( "File %s already exists. New file won't be created. Remove it and try again" % db.path, "red") return 1 db.json_write() cprint("Written new database %s" % os.path.relpath(db.path), "green") return 0
def gbrv_plot(options): """Plot data with matplotlib.""" for path in options.database_list: outdb = GbrvOutdb.from_file(path) frame = outdb.get_dataframe() print(frame) # import matplotlib.pyplot as plt # frame.plot(frame.index, ["normal_rel_err", "high_rel_err"]) # ax.set_xticks(range(len(data.index))) # ax.set_xticklabels(data.index) # plt.show() # outdb.plot_errors(reference="ae", accuracy="normal") # for formula, records in outdb.values() # records = outdb["NaCl"] # for rec in records: # rec.plot_eos() return 0
def compute_eos(self): """Compute the EOS as describedin the GBRV paper.""" self.history.info("Computing EOS") # Read etotals and fit E(V) with a parabola to find the minimum etotals = self.read_etotals(unit="eV")[1:] assert len(etotals) == len(self.volumes) results = {} results.update(dict( etotals=list(etotals), volumes=list(self.volumes), num_sites=len(self.relaxed_structure), #pseudos=self.pseudos.as_dict(), )) try: eos_fit = EOS.Quadratic().fit(self.volumes, etotals) except EOS.Error as exc: results.push_exceptions(exc) # Function to compute cubic a0 from primitive v0 (depends on struct_type) vol2a = {"fcc": lambda vol: (4 * vol) ** (1/3.), "bcc": lambda vol: (2 * vol) ** (1/3.), "rocksalt": lambda vol: (4 * vol) ** (1/3.), "ABO3": lambda vol: vol ** (1/3.), "hH": lambda vol: (4 * vol) ** (1/3.), }[self.struct_type] a0 = vol2a(eos_fit.v0) results.update(dict( ecut=self.ecut, pawecutdg=self.pawecutdg, struct_type=self.struct_type, v0=eos_fit.v0, b0=eos_fit.b0, #b1=eos_fit.b1, # infinity a0=a0, )) db = gbrv_database(xc=self.xc) entry = db.get_entry(self.formula, stype=self.struct_type) try: pawabs_err = a0 - entry.gbrv_paw pawrel_err = 100 * (a0 - entry.gbrv_paw) / entry.gbrv_paw except: # Some paw_abinit entries are not available. pawabs_err = np.inf pawrel_err = np.inf # If AE results are missing we use GBRV_PAW as reference. if entry.ae is not None: ref_a0 = entry.ae abs_err = a0 - entry.ae rel_err = 100 * (a0 - entry.ae) / entry.ae else: assert pawabs_err is not None assert pawrel_err is not None ref_a0 = entry.gbrv_paw abs_err = pawabs_err rel_err = pawrel_err results["a0_abs_err"] = abs_err results["a0_rel_err"] = rel_err print(80 * "=") print("pseudos:", list(p.basename for p in self.pseudos)) print("for %s (%s): my_a0=%.3f, ref_a0=%.3f Angstrom" % (self.formula, self.struct_type, a0, ref_a0)) print("AE - THIS: abs_err=%f, rel_err=%f %%" % (abs_err, rel_err)) print("GBRV-PAW - THIS: abs_err=%f, rel_err=%f %%" % (pawabs_err, pawrel_err)) print(80 * "=") # Write results in outdir in JSON format. with open(self.outdir.path_in("gbrv_results.json"), "wt") as fh: json.dump(results, fh, indent=-1, sort_keys=True) #, cls=MontyEncoder) # Update the database. if self.outdb_path is not None: GbrvOutdb.insert_results(self.outdb_path, self.struct_type, self.formula, self.accuracy, self.pseudos, results) return results
def compute_eos(self): """Compute the EOS as described in the GBRV paper.""" self.history.info("Computing EOS") # Read etotals and fit E(V) with a parabola to find the minimum etotals = self.read_etotals(unit="eV")[1:] assert len(etotals) == len(self.volumes) results = {} results.update(dict( etotals=list(etotals), volumes=list(self.volumes), num_sites=len(self.relaxed_structure), #pseudos=self.pseudos.as_dict(), )) try: eos_fit = EOS.Quadratic().fit(self.volumes, etotals) except EOS.Error as exc: results.push_exceptions(exc) # Function to compute cubic a0 from primitive v0 (depends on struct_type) vol2a = {"fcc": lambda vol: (4 * vol) ** (1/3.), "bcc": lambda vol: (2 * vol) ** (1/3.), "rocksalt": lambda vol: (4 * vol) ** (1/3.), "ABO3": lambda vol: vol ** (1/3.), "hH": lambda vol: (4 * vol) ** (1/3.), }[self.struct_type] a0 = vol2a(eos_fit.v0) results.update(dict( ecut=self.ecut, pawecutdg=self.pawecutdg, struct_type=self.struct_type, v0=eos_fit.v0, b0=eos_fit.b0, #b1=eos_fit.b1, # infinity a0=a0, )) db = gbrv_database(xc=self.xc) entry = db.get_entry(self.formula, stype=self.struct_type) try: pawabs_err = a0 - entry.gbrv_paw pawrel_err = 100 * (a0 - entry.gbrv_paw) / entry.gbrv_paw except Exception: # Some paw_abinit entries are not available. pawabs_err = np.inf pawrel_err = np.inf # If AE results are missing we use GBRV_PAW as reference. if entry.ae is not None: ref_a0 = entry.ae abs_err = a0 - entry.ae rel_err = 100 * (a0 - entry.ae) / entry.ae else: assert pawabs_err is not None assert pawrel_err is not None ref_a0 = entry.gbrv_paw abs_err = pawabs_err rel_err = pawrel_err results["a0_rel_err"] = rel_err results["a0_abs_err"] = abs_err results["pseudos"] = {p.basename: p.md5 for p in self.pseudos} print(80 * "=") print("pseudos:", list(p.basename for p in self.pseudos)) print("for %s (%s): my_a0=%.3f, ref_a0=%.3f Angstrom" % (self.formula, self.struct_type, a0, ref_a0)) print("AE - THIS: abs_err=%f, rel_err=%f %%" % (abs_err, rel_err)) print("GBRV-PAW - THIS: abs_err=%f, rel_err=%f %%" % (pawabs_err, pawrel_err)) print(80 * "=") # Write results in outdir in JSON format. with open(self.outdir.path_in("gbrv_results.json"), "wt") as fh: json.dump(results, fh, indent=-1, sort_keys=True) # Update the database. if self.outdb_path is not None: GbrvOutdb.insert_results(self.outdb_path, self.struct_type, self.formula, self.accuracy, self.pseudos, results) return results
def gbrv_notebook(options): """ Generate ipython notebook to analyze the results in the database. """ outdb = GbrvOutdb.from_file(options.path) return outdb.make_open_notebook()
def test_rocksalt_outdb(self): """Testing RocksaltOutdb database and its API.""" return dirpath = dojotable_absdir("ONCVPSP-PBE") # Test the initialization of an empty object. outdb = RocksaltOutdb.new_from_dojodir(dirpath) #outdb.dojo_dir = "dummy_dir" #print(outdb) assert outdb.struct_type == "rocksalt" # Check that outdb supports pickle because the works will get a reference to it. self.serialize_with_pickle(outdb, protocols=None, test_eq=True) # Dict protocol assert "LiF" in outdb and "LiF" in outdb.keys() records = outdb["LiF"] # Test records (dict-like objects) supporting __eq__ and __ne__ for rec in records: assert rec.formula == "LiF" assert rec["normal"] is None and rec["high"] is None assert "pseudos_metadata" in rec assert not rec.has_data("normal") d = rec.as_dict() assert isinstance(d, dict) same_rec = GbrvRecord.from_dict(d, outdb.struct_type, rec.dojo_pptable) #print(rec) assert same_rec == rec for formula, records in outdb.items(): # Test find_record for rec in records: same_rec = outdb.find_record(formula, rec.pseudos) #assert rec.matches_pseudos(same_rec.pseudos) assert rec == same_rec # All the records for the same formula should be different! if len(records) > 1: for rec1, rec2 in zip(records[:-1], records[1:]): assert rec1 != rec2 # Here I compare all the records in the database! all_records = [] for records in outdb.values(): all_records.extend(records) for rec1, rec2 in zip(all_records[:-1], all_records[1:]): assert rec1 != rec2 assert not rec1.matches_pseudos(rec2.pseudos) # Test pandas dataframe frame = outdb.get_dataframe() assert frame is not None # Test matplotlib tools if self.has_matplotlib(): outdb.plot_errors() # Test API to extract jobs jobs = outdb.find_jobs_torun(max_njobs=3) assert len(jobs) == 3 # Retrieve the record from the job params and make sure # the entry is set to scheduled. for job in jobs: rec = outdb.find_record(job.formula, job.pseudos) assert rec[job.accuracy] == "scheduled" # Write the object in json format filepath = "dummy.json" outdb.json_write(filepath=filepath) # And new we re-read it from file. new_outdb = GbrvOutdb.from_file(filepath) assert new_outdb.struct_type == outdb.struct_type assert len(new_outdb) == len(outdb) # NB: This works because all values support __eq__ assert new_outdb == outdb
def test_rocksalt_outdb(self): """Testing RocksaltOutdb database and its API.""" return dirpath = dojotable_absdir("ONCVPSP-PBE") # Test the initialization of an empty object. outdb = RocksaltOutdb.new_from_dojodir(dirpath) #outdb.dojo_dir = "dummy_dir" #print(outdb) assert outdb.struct_type == "rocksalt" # Check that outdb supports pickle because the works will get a reference to it. self.serialize_with_pickle(outdb, protocols=None, test_eq=True) # Dict protocol assert "LiF" in outdb and "LiF" in outdb.keys() records = outdb["LiF"] # Test records (dict-like objects) supporting __eq__ and __ne__ for rec in records: assert rec.formula == "LiF" assert rec["normal"] is None and rec["high"] is None assert "pseudos_metadata" in rec assert not rec.has_data("normal") d = rec.as_dict() same_rec = GbrvRecord.from_dict(d, outdb.struct_type, rec.dojo_pptable) #print(rec) assert same_rec == rec for formula, records in outdb.items(): # Test find_record for rec in records: same_rec = outdb.find_record(formula, rec.pseudos) #assert rec.matches_pseudos(same_rec.pseudos) assert rec == same_rec # All the records for the same formula should be different! if len(records) > 1: for rec1, rec2 in zip(records[:-1], records[1:]): assert rec1 != rec2 # Here I compare all the records in the database! all_records = [] for records in outdb.values(): all_records.extend(records) for rec1, rec2 in zip(all_records[:-1], all_records[1:]): assert rec1 != rec2 assert not rec1.matches_pseudos(rec2.pseudos) # Test pandas dataframe frame = outdb.get_dataframe() assert frame is not None # Test matplotlib tools outdb.plot_errors() # Test API to extract jobs jobs = outdb.find_jobs_torun(max_njobs=3) assert len(jobs) == 3 # Retrieve the record from the job params and make sure # the entry is set to scheduled. for job in jobs: rec = outdb.find_record(job.formula, job.pseudos) assert rec[job.accuracy] == "scheduled" # Write the object in json format filepath = "dummy.json" outdb.json_write(filepath=filepath) # And new we re-read it from file. new_outdb = GbrvOutdb.from_file(filepath) assert new_outdb.struct_type == outdb.struct_type assert len(new_outdb) == len(outdb) # NB: This works because all values support __eq__ assert new_outdb == outdb
def compute_eos(self): self.history.info("Computing EOS") #results = self.get_results() # Read etotals and fit E(V) with a parabola to find the minimum etotals = self.read_etotals(unit="eV")[1:] assert len(etotals) == len(self.volumes) results = {} results.update(dict( etotals=list(etotals), volumes=list(self.volumes), num_sites=len(self.relaxed_structure), )) try: eos_fit = EOS.Quadratic().fit(self.volumes, etotals) except EOS.Error as exc: results.push_exceptions(exc) #return results # Function to compute cubic a0 from primitive v0 (depends on struct_type) vol2a = {"fcc": lambda vol: (4 * vol) ** (1/3.), "rocksalt": lambda vol: (4 * vol) ** (1/3.), "bcc": lambda vol: (2 * vol) ** (1/3.), "ABO3": lambda vol: vol ** (1/3.), }[self.struct_type] a0 = vol2a(eos_fit.v0) results.update(dict( v0=eos_fit.v0, b0=eos_fit.b0, b1=eos_fit.b1, a0=a0, ecut=self.ecut, #struct_type=self.struct_type )) # Update the database. # TODO, handle error! if self.outdb_path is not None: GbrvOutdb.update_record(self.outdb_path, self.formula, self.accuracy, self.pseudos, results) db = gbrv_database() entry = db.get_entry(self.formula, stype=self.struct_type) pawabs_err = a0 - entry.gbrv_paw pawrel_err = 100 * (a0 - entry.gbrv_paw) / entry.gbrv_paw # If AE results are missing we use GBRV_PAW as reference. if entry.ae is not None: abs_err = a0 - entry.ae rel_err = 100 * (a0 - entry.ae) / entry.ae else: abs_err = pawabs_err rel_err = pawrel_err print("for %s (%s) a0=%.2f Angstrom" % (self.formula, self.struct_type, a0)) print("AE - THIS: abs_err = %f, rel_err = %f %%" % (abs_err, rel_err)) print("GBRV-PAW - THIS: abs_err = %f, rel_err = %f %%" % (pawabs_err, pawrel_err)) #d = {k: results[k] for k in ("a0", "etotals", "volumes")} #d["a0_abs_err"] = abs_err #d["a0_rel_err"] = rel_err #if results.exceptions: # d["_exceptions"] = str(results.exceptions) return results