예제 #1
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

    # 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
예제 #2
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
예제 #3
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
예제 #4
0
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
예제 #5
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
예제 #6
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
예제 #7
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
예제 #8
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
예제 #9
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
예제 #10
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
예제 #11
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
예제 #12
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
예제 #13
0
    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
예제 #14
0
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()
예제 #15
0
    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
예제 #16
0
    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
예제 #17
0
    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